check the recursion limit when finding struct tail
This commit is contained in:
parent
0d9651648d
commit
98fc02d6fa
@ -18,7 +18,7 @@
|
|||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::abi::{Integer, Size, TargetDataLayout};
|
use rustc_target::abi::{Integer, Size, TargetDataLayout};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{cmp, fmt};
|
use std::{cmp, fmt};
|
||||||
@ -221,7 +221,13 @@ pub fn struct_tail_with_normalize(
|
|||||||
mut ty: Ty<'tcx>,
|
mut ty: Ty<'tcx>,
|
||||||
normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
|
normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
loop {
|
for iteration in 0.. {
|
||||||
|
if !self.sess.recursion_limit().value_within_limit(iteration) {
|
||||||
|
return self.ty_error_with_message(
|
||||||
|
DUMMY_SP,
|
||||||
|
&format!("reached the recursion limit finding the struct tail for {}", ty),
|
||||||
|
);
|
||||||
|
}
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, substs) => {
|
||||||
if !def.is_struct() {
|
if !def.is_struct() {
|
||||||
|
10
src/test/ui/infinite/infinite-struct.rs
Normal file
10
src/test/ui/infinite/infinite-struct.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
struct Take(Take);
|
||||||
|
//~^ ERROR has infinite size
|
||||||
|
//~| ERROR cycle detected
|
||||||
|
|
||||||
|
// check that we don't hang trying to find the tail of a recursive struct (#79437)
|
||||||
|
fn foo() -> Take {
|
||||||
|
Take(loop {})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
27
src/test/ui/infinite/infinite-struct.stderr
Normal file
27
src/test/ui/infinite/infinite-struct.stderr
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
error[E0072]: recursive type `Take` has infinite size
|
||||||
|
--> $DIR/infinite-struct.rs:1:1
|
||||||
|
|
|
||||||
|
LL | struct Take(Take);
|
||||||
|
| ^^^^^^^^^^^^----^^
|
||||||
|
| | |
|
||||||
|
| | recursive without indirection
|
||||||
|
| recursive type has infinite size
|
||||||
|
|
|
||||||
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Take` representable
|
||||||
|
|
|
||||||
|
LL | struct Take(Box<Take>);
|
||||||
|
| ^^^^ ^
|
||||||
|
|
||||||
|
error[E0391]: cycle detected when computing drop-check constraints for `Take`
|
||||||
|
--> $DIR/infinite-struct.rs:1:1
|
||||||
|
|
|
||||||
|
LL | struct Take(Take);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: ...which again requires computing drop-check constraints for `Take`, completing the cycle
|
||||||
|
= note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: Take } }`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0072, E0391.
|
||||||
|
For more information about an error, try `rustc --explain E0072`.
|
Loading…
Reference in New Issue
Block a user