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_id::DefId;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::abi::{Integer, Size, TargetDataLayout};
|
||||
use smallvec::SmallVec;
|
||||
use std::{cmp, fmt};
|
||||
@ -221,7 +221,13 @@ pub fn struct_tail_with_normalize(
|
||||
mut ty: Ty<'tcx>,
|
||||
normalize: impl Fn(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() {
|
||||
ty::Adt(def, substs) => {
|
||||
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