) -> Result<(), SelectionError<'tcx>> {
debug!("assemble_candidates_from_impls(obligation={:?})", obligation);
+ // Essentially any user-written impl will match with an error type,
+ // so creating `ImplCandidates` isn't useful. However, we might
+ // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized)
+ // This helps us avoid overflow: see issue #72839
+ // Since compilation is already guarnateed to fail, this is just
+ // to try to show the 'nicest' possible errors to the user.
+ if obligation.references_error() {
+ return Ok(());
+ }
+
self.tcx().for_each_relevant_impl(
obligation.predicate.def_id(),
obligation.predicate.skip_binder().trait_ref.self_ty(),
--- /dev/null
+// Regression test for issue #72839
+// Tests that we do not overflow during trait selection after
+// a type error occurs
+use std::ops::Rem;
+trait Foo {}
+struct MyStruct<T>(T);
+
+impl<T, U> Rem<MyStruct<T>> for MyStruct<U> where MyStruct<U>: Rem<MyStruct<T>> {
+ type Output = u8;
+ fn rem(self, _: MyStruct<T>) -> Self::Output {
+ panic!()
+ }
+}
+
+fn main() {}
+
+fn foo() {
+ if missing_var % 8 == 0 {} //~ ERROR cannot find
+}
--- /dev/null
+error[E0425]: cannot find value `missing_var` in this scope
+ --> $DIR/issue-72839-error-overflow.rs:18:8
+ |
+LL | if missing_var % 8 == 0 {}
+ | ^^^^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.