about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-03-27 16:12:00 +0100
committerlcnr <rust@lcnr.de>2025-03-31 23:58:17 +0200
commit654b7b541300c2d3d497031728b637ab4e457916 (patch)
tree8ad0a8dfe65538e15be3e3af8d128829e5ea81a5
parent0b45675cfcec57f30a3794e1a1e18423aa9cf200 (diff)
downloadrust-654b7b541300c2d3d497031728b637ab4e457916.tar.gz
rust-654b7b541300c2d3d497031728b637ab4e457916.zip
increment depth of nested obligations
-rw-r--r--compiler/rustc_trait_selection/src/traits/effects.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs56
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs12
-rw-r--r--tests/ui/infinite/infinite-autoderef.stderr4
-rw-r--r--tests/ui/occurs-check-2.rs2
-rw-r--r--tests/ui/occurs-check-2.stderr6
-rw-r--r--tests/ui/occurs-check-3.stderr4
-rw-r--r--tests/ui/occurs-check.stderr4
-rw-r--r--tests/ui/traits/mutual-recursion-issue-75860.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs3
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr11
15 files changed, 70 insertions, 72 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index 3c127416cbf..b8e15088853 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -106,10 +106,6 @@ fn match_candidate<'tcx>(
 
     more_nested(selcx, &mut nested);
 
-    for nested in &mut nested {
-        nested.set_depth_from_parent(obligation.recursion_depth);
-    }
-
     Ok(nested)
 }
 
@@ -378,10 +374,6 @@ fn evaluate_host_effect_from_selection_candiate<'tcx>(
                             }),
                     );
 
-                    for nested in &mut nested {
-                        nested.set_depth_from_parent(obligation.recursion_depth);
-                    }
-
                     Ok(nested)
                 }
                 _ => Err(EvaluationFailure::NoSolution),
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index e39f8e673db..e98a240a53f 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -225,9 +225,15 @@ struct FulfillProcessor<'a, 'tcx> {
     selcx: SelectionContext<'a, 'tcx>,
 }
 
-fn mk_pending<'tcx>(os: PredicateObligations<'tcx>) -> PendingPredicateObligations<'tcx> {
+fn mk_pending<'tcx>(
+    parent: &PredicateObligation<'tcx>,
+    os: PredicateObligations<'tcx>,
+) -> PendingPredicateObligations<'tcx> {
     os.into_iter()
-        .map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] })
+        .map(|mut o| {
+            o.set_depth_from_parent(parent.recursion_depth);
+            PendingPredicateObligation { obligation: o, stalled_on: vec![] }
+        })
         .collect()
 }
 
@@ -341,7 +347,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
             );
             if predicate != obligation.predicate {
                 obligations.push(obligation.with(infcx.tcx, predicate));
-                return ProcessResult::Changed(mk_pending(obligations));
+                return ProcessResult::Changed(mk_pending(obligation, obligations));
             }
         }
         let binder = obligation.predicate.kind();
@@ -385,7 +391,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     let mut obligations = PredicateObligations::with_capacity(1);
                     obligations.push(obligation.with(infcx.tcx, pred));
 
-                    ProcessResult::Changed(mk_pending(obligations))
+                    ProcessResult::Changed(mk_pending(obligation, obligations))
                 }
                 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
                 ty::PredicateKind::NormalizesTo(..) => {
@@ -410,6 +416,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     let host_obligation = obligation.with(infcx.tcx, data);
 
                     self.process_host_obligation(
+                        obligation,
                         host_obligation,
                         &mut pending_obligation.stalled_on,
                     )
@@ -486,7 +493,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         // `<lhs_ty as Add<rhs_ty>>::Output` when this is an `Expr` representing
                         // `lhs + rhs`.
                         ty::ConstKind::Expr(_) => {
-                            return ProcessResult::Changed(mk_pending(PredicateObligations::new()));
+                            return ProcessResult::Changed(mk_pending(
+                                obligation,
+                                PredicateObligations::new(),
+                            ));
                         }
                         ty::ConstKind::Placeholder(_) => {
                             bug!("placeholder const {:?} in old solver", ct)
@@ -503,7 +513,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                         ct_ty,
                         ty,
                     ) {
-                        Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
+                        Ok(inf_ok) => ProcessResult::Changed(mk_pending(
+                            obligation,
+                            inf_ok.into_obligations(),
+                        )),
                         Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
                             SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
                         )),
@@ -537,7 +550,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::maybe_from_generic_arg(arg).unwrap()];
                             ProcessResult::Unchanged
                         }
-                        Some(os) => ProcessResult::Changed(mk_pending(os)),
+                        Some(os) => ProcessResult::Changed(mk_pending(obligation, os)),
                     }
                 }
 
@@ -553,11 +566,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
                             ProcessResult::Unchanged
                         }
-                        Ok(Ok(mut ok)) => {
-                            for subobligation in &mut ok.obligations {
-                                subobligation.set_depth_from_parent(obligation.recursion_depth);
-                            }
-                            ProcessResult::Changed(mk_pending(ok.obligations))
+                        Ok(Ok(ok)) => {
+                            ProcessResult::Changed(mk_pending(obligation, ok.obligations))
                         }
                         Ok(Err(err)) => {
                             let expected_found = if subtype.a_is_expected {
@@ -582,7 +592,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
                             ProcessResult::Unchanged
                         }
-                        Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)),
+                        Ok(Ok(ok)) => {
+                            ProcessResult::Changed(mk_pending(obligation, ok.obligations))
+                        }
                         Ok(Err(err)) => {
                             let expected_found = ExpectedFound::new(coerce.b, coerce.a);
                             ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
@@ -645,6 +657,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                     )
                                 {
                                     return ProcessResult::Changed(mk_pending(
+                                        obligation,
                                         new_obligations.into_obligations(),
                                     ));
                                 }
@@ -659,6 +672,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                     .eq(DefineOpaqueTypes::Yes, c1, c2)
                                 {
                                     return ProcessResult::Changed(mk_pending(
+                                        obligation,
                                         new_obligations.into_obligations(),
                                     ));
                                 }
@@ -704,9 +718,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 c1,
                                 c2,
                             ) {
-                                Ok(inf_ok) => {
-                                    ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
-                                }
+                                Ok(inf_ok) => ProcessResult::Changed(mk_pending(
+                                    obligation,
+                                    inf_ok.into_obligations(),
+                                )),
                                 Err(err) => {
                                     ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
                                         ExpectedFound::new(c1, c2),
@@ -790,7 +805,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
         match self.selcx.poly_select(&trait_obligation) {
             Ok(Some(impl_source)) => {
                 debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
-                ProcessResult::Changed(mk_pending(impl_source.nested_obligations()))
+                ProcessResult::Changed(mk_pending(obligation, impl_source.nested_obligations()))
             }
             Ok(None) => {
                 debug!("selecting trait at depth {} yielded Ok(None)", obligation.recursion_depth);
@@ -854,7 +869,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
         }
 
         match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) {
-            ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
+            ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(obligation, os)),
             ProjectAndUnifyResult::FailedNormalization => {
                 stalled_on.clear();
                 stalled_on.extend(args_infer_vars(
@@ -868,7 +883,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
                 let mut obligations = PredicateObligations::with_capacity(1);
                 obligations.push(project_obligation.with(tcx, project_obligation.predicate));
 
-                ProcessResult::Changed(mk_pending(obligations))
+                ProcessResult::Changed(mk_pending(obligation, obligations))
             }
             ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
                 ProcessResult::Error(FulfillmentErrorCode::Project(e))
@@ -878,11 +893,12 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
 
     fn process_host_obligation(
         &mut self,
+        obligation: &PredicateObligation<'tcx>,
         host_obligation: HostEffectObligation<'tcx>,
         stalled_on: &mut Vec<TyOrConstInferVar>,
     ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
         match effects::evaluate_host_effect_obligation(&mut self.selcx, &host_obligation) {
-            Ok(nested) => ProcessResult::Changed(mk_pending(nested)),
+            Ok(nested) => ProcessResult::Changed(mk_pending(obligation, nested)),
             Err(effects::EvaluationFailure::Ambiguous) => {
                 stalled_on.clear();
                 stalled_on.extend(args_infer_vars(
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 630241725fd..2cb7d2d8931 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -39,7 +39,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PolyTraitObligation<'tcx>,
         candidate: SelectionCandidate<'tcx>,
     ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
-        let mut impl_src = match candidate {
+        Ok(match candidate {
             SizedCandidate { has_nested } => {
                 let data = self.confirm_builtin_candidate(obligation, has_nested);
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
@@ -139,15 +139,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             BikeshedGuaranteedNoDropCandidate => {
                 self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation)
             }
-        };
-
-        // The obligations returned by confirmation are recursively evaluated
-        // so we need to make sure they have the correct depth.
-        for subobligation in impl_src.borrow_nested_obligations_mut() {
-            subobligation.set_depth_from_parent(obligation.recursion_depth);
-        }
-
-        Ok(impl_src)
+        })
     }
 
     fn confirm_projection_candidate(
diff --git a/tests/ui/infinite/infinite-autoderef.stderr b/tests/ui/infinite/infinite-autoderef.stderr
index 7d09af9a7d4..7770cc8a720 100644
--- a/tests/ui/infinite/infinite-autoderef.stderr
+++ b/tests/ui/infinite/infinite-autoderef.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Box<_>` to `_`
-  --> $DIR/infinite-autoderef.rs:16:13
+  --> $DIR/infinite-autoderef.rs:16:22
    |
 LL |         x = Box::new(x);
-   |             ^^^^^^^^^^^
+   |                      ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/occurs-check-2.rs b/tests/ui/occurs-check-2.rs
index 1ec460a8735..9289a8e870a 100644
--- a/tests/ui/occurs-check-2.rs
+++ b/tests/ui/occurs-check-2.rs
@@ -4,6 +4,6 @@ fn main() {
     let g;
 
     g = f;
-    f = Box::new(g);
     //~^ ERROR overflow assigning `Box<_>` to `_`
+    f = Box::new(g);
 }
diff --git a/tests/ui/occurs-check-2.stderr b/tests/ui/occurs-check-2.stderr
index 54307a6c547..5f296967f30 100644
--- a/tests/ui/occurs-check-2.stderr
+++ b/tests/ui/occurs-check-2.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Box<_>` to `_`
-  --> $DIR/occurs-check-2.rs:7:9
+  --> $DIR/occurs-check-2.rs:6:9
    |
-LL |     f = Box::new(g);
-   |         ^^^^^^^^^^^
+LL |     g = f;
+   |         ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/occurs-check-3.stderr b/tests/ui/occurs-check-3.stderr
index 77b67ec1a62..eb05c94957c 100644
--- a/tests/ui/occurs-check-3.stderr
+++ b/tests/ui/occurs-check-3.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Clam<_>` to `_`
-  --> $DIR/occurs-check-3.rs:6:9
+  --> $DIR/occurs-check-3.rs:6:17
    |
 LL |     c = Clam::A(c);
-   |         ^^^^^^^^^^
+   |                 ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/occurs-check.stderr b/tests/ui/occurs-check.stderr
index 30468d68cbd..ea7c541abc1 100644
--- a/tests/ui/occurs-check.stderr
+++ b/tests/ui/occurs-check.stderr
@@ -1,8 +1,8 @@
 error[E0275]: overflow assigning `Box<_>` to `_`
-  --> $DIR/occurs-check.rs:3:9
+  --> $DIR/occurs-check.rs:3:18
    |
 LL |     f = Box::new(f);
-   |         ^^^^^^^^^^^
+   |                  ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/mutual-recursion-issue-75860.stderr b/tests/ui/traits/mutual-recursion-issue-75860.stderr
index 272c56301bc..9e8eb1adb11 100644
--- a/tests/ui/traits/mutual-recursion-issue-75860.stderr
+++ b/tests/ui/traits/mutual-recursion-issue-75860.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow assigning `_` to `Option<_>`
   --> $DIR/mutual-recursion-issue-75860.rs:9:33
    |
 LL |     let left = |o_a: Option<_>| o_a.unwrap();
-   |                                 ^^^
+   |                                 ^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs
index 19986247d40..53b7667aa9f 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.rs
@@ -1,9 +1,10 @@
 #![feature(type_alias_impl_trait)]
-//@ known-bug: #109268
 
 type Foo = impl Fn() -> Foo;
 
+#[define_opaque(Foo)]
 fn crash(x: Foo) -> Foo {
+    //~^ ERROR overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
index ad96a0eeb87..ee8922b673e 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-1.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:4:12
+error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
+  --> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:6:21
    |
-LL | type Foo = impl Fn() -> Foo;
-   |            ^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same crate
+LL | fn crash(x: Foo) -> Foo {
+   |                     ^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs
index 761cc83af51..d0c62d29069 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.rs
@@ -1,13 +1,13 @@
 #![feature(type_alias_impl_trait)]
-//@ known-bug: #109268
 
 pub trait Bar<T> {
     type Item;
 }
 
 type Foo = impl Bar<Foo, Item = Foo>;
-
+#[define_opaque(Foo)]
 fn crash(x: Foo) -> Foo {
+    //~^ ERROR overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
index e5bb8163a81..40bd6517c06 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-2.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:8:12
+error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
+  --> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:9:21
    |
-LL | type Foo = impl Bar<Foo, Item = Foo>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same crate
+LL | fn crash(x: Foo) -> Foo {
+   |                     ^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs
index 52942afd639..de3d23b83a2 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.rs
@@ -1,9 +1,9 @@
 #![feature(type_alias_impl_trait)]
-//@ known-bug: #109268
 
 type Foo<'a> = impl Fn() -> Foo<'a>;
-
+#[define_opaque(Foo)]
 fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
+    //~^ ERROR overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
     x
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
index 157310bf623..f9e26fde1bd 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error-3.stderr
@@ -1,10 +1,9 @@
-error: unconstrained opaque type
-  --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:4:16
+error[E0275]: overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
+  --> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:5:40
    |
-LL | type Foo<'a> = impl Fn() -> Foo<'a>;
-   |                ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same crate
+LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
+   |                                        ^^^^^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0275`.