Skip to content

Commit 98fc02d

Browse files
committed
check the recursion limit when finding struct tail
1 parent 0d96516 commit 98fc02d

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

Diff for: compiler/rustc_middle/src/ty/util.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_hir as hir;
1818
use rustc_hir::def::DefKind;
1919
use rustc_hir::def_id::DefId;
2020
use rustc_macros::HashStable;
21-
use rustc_span::Span;
21+
use rustc_span::{Span, DUMMY_SP};
2222
use rustc_target::abi::{Integer, Size, TargetDataLayout};
2323
use smallvec::SmallVec;
2424
use std::{cmp, fmt};
@@ -221,7 +221,13 @@ impl<'tcx> TyCtxt<'tcx> {
221221
mut ty: Ty<'tcx>,
222222
normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
223223
) -> Ty<'tcx> {
224-
loop {
224+
for iteration in 0.. {
225+
if !self.sess.recursion_limit().value_within_limit(iteration) {
226+
return self.ty_error_with_message(
227+
DUMMY_SP,
228+
&format!("reached the recursion limit finding the struct tail for {}", ty),
229+
);
230+
}
225231
match *ty.kind() {
226232
ty::Adt(def, substs) => {
227233
if !def.is_struct() {

Diff for: src/test/ui/infinite/infinite-struct.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct Take(Take);
2+
//~^ ERROR has infinite size
3+
//~| ERROR cycle detected
4+
5+
// check that we don't hang trying to find the tail of a recursive struct (#79437)
6+
fn foo() -> Take {
7+
Take(loop {})
8+
}
9+
10+
fn main() {}

Diff for: src/test/ui/infinite/infinite-struct.stderr

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0072]: recursive type `Take` has infinite size
2+
--> $DIR/infinite-struct.rs:1:1
3+
|
4+
LL | struct Take(Take);
5+
| ^^^^^^^^^^^^----^^
6+
| | |
7+
| | recursive without indirection
8+
| recursive type has infinite size
9+
|
10+
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Take` representable
11+
|
12+
LL | struct Take(Box<Take>);
13+
| ^^^^ ^
14+
15+
error[E0391]: cycle detected when computing drop-check constraints for `Take`
16+
--> $DIR/infinite-struct.rs:1:1
17+
|
18+
LL | struct Take(Take);
19+
| ^^^^^^^^^^^^^^^^^^
20+
|
21+
= note: ...which again requires computing drop-check constraints for `Take`, completing the cycle
22+
= note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: Take } }`
23+
24+
error: aborting due to 2 previous errors
25+
26+
Some errors have detailed explanations: E0072, E0391.
27+
For more information about an error, try `rustc --explain E0072`.

0 commit comments

Comments
 (0)