diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 857e4f66489ab..3c4eb99b5a885 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -792,7 +792,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { self.fcx.set_tainted_by_errors(guar); } } - Ok(Some(impl_source)) => queue.extend(impl_source.nested_obligations()), + Ok(Some(impl_source)) => { + let nested = impl_source.nested_obligations(); + if nested.len() == 1 && &obligation == &nested[0] { + // Avoid hang when expanding the current obligation to the same obligation. + // This doesn't occur under normal circumstances, only on incorrect + // recursive type definitions. Issue #148653. + } else { + queue.extend(nested); + } + } } } diff --git a/tests/ui/traits/solver-cycles/148653-recursive-struct-infinte-cycle.rs b/tests/ui/traits/solver-cycles/148653-recursive-struct-infinte-cycle.rs new file mode 100644 index 0000000000000..1ef6754e3589e --- /dev/null +++ b/tests/ui/traits/solver-cycles/148653-recursive-struct-infinte-cycle.rs @@ -0,0 +1,11 @@ +// Issue #148653. +struct Vec { //~ ERROR recursive type `Vec` has infinite size + data: Vec, //~ ERROR type parameter `T` is only used recursively +} +impl Vec { + pub fn push(&mut self) -> &mut Self { + self + } +} + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/148653-recursive-struct-infinte-cycle.stderr b/tests/ui/traits/solver-cycles/148653-recursive-struct-infinte-cycle.stderr new file mode 100644 index 0000000000000..b0f02f1ba0838 --- /dev/null +++ b/tests/ui/traits/solver-cycles/148653-recursive-struct-infinte-cycle.stderr @@ -0,0 +1,27 @@ +error: type parameter `T` is only used recursively + --> $DIR/148653-recursive-struct-infinte-cycle.rs:3:15 + | +LL | struct Vec { + | - type parameter must be used non-recursively in the definition +LL | data: Vec, + | ^ + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = note: all type parameters must be used in a non-recursive way in order to constrain their variance + +error[E0072]: recursive type `Vec` has infinite size + --> $DIR/148653-recursive-struct-infinte-cycle.rs:2:1 + | +LL | struct Vec { + | ^^^^^^^^^^^^^ +LL | data: Vec, + | ------ recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | data: Box>, + | ++++ + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0072`.