about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs32
-rw-r--r--src/test/ui/suggestions/issue-89333.rs9
-rw-r--r--src/test/ui/suggestions/issue-89333.stderr23
3 files changed, 48 insertions, 16 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 325126483b9..c74667643c4 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -676,7 +676,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         &self,
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
-        trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
+        poly_trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
         has_custom_message: bool,
     ) -> bool {
         let span = obligation.cause.span;
@@ -705,7 +705,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap());
 
         let param_env = obligation.param_env;
-        let trait_ref = trait_ref.skip_binder();
+        let trait_ref = poly_trait_ref.skip_binder();
 
         let found_ty = trait_ref.self_ty();
         let found_ty_str = found_ty.to_string();
@@ -715,25 +715,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         let mut_substs = self.tcx.mk_substs_trait(mut_borrowed_found_ty, &[]);
 
         // Try to apply the original trait binding obligation by borrowing.
-        let mut try_borrowing = |new_imm_trait_ref: ty::TraitRef<'tcx>,
-                                 new_mut_trait_ref: ty::TraitRef<'tcx>,
-                                 expected_trait_ref: ty::TraitRef<'tcx>,
+        let mut try_borrowing = |new_imm_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
+                                 new_mut_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
+                                 expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
                                  blacklist: &[DefId]|
          -> bool {
-            if blacklist.contains(&expected_trait_ref.def_id) {
+            if blacklist.contains(&expected_trait_ref.def_id()) {
                 return false;
             }
 
             let imm_result = self.predicate_must_hold_modulo_regions(&Obligation::new(
                 ObligationCause::dummy(),
                 param_env,
-                ty::Binder::dummy(new_imm_trait_ref).without_const().to_predicate(self.tcx),
+                new_imm_trait_ref.without_const().to_predicate(self.tcx),
             ));
 
             let mut_result = self.predicate_must_hold_modulo_regions(&Obligation::new(
                 ObligationCause::dummy(),
                 param_env,
-                ty::Binder::dummy(new_mut_trait_ref).without_const().to_predicate(self.tcx),
+                new_mut_trait_ref.without_const().to_predicate(self.tcx),
             ));
 
             if imm_result || mut_result {
@@ -806,19 +806,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         };
 
         if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code {
-            let expected_trait_ref = obligation.parent_trait_ref.skip_binder();
-            let new_imm_trait_ref =
-                ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs);
-            let new_mut_trait_ref =
-                ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs);
+            let expected_trait_ref = obligation.parent_trait_ref;
+            let new_imm_trait_ref = poly_trait_ref
+                .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs));
+            let new_mut_trait_ref = poly_trait_ref
+                .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs));
             return try_borrowing(new_imm_trait_ref, new_mut_trait_ref, expected_trait_ref, &[]);
         } else if let ObligationCauseCode::BindingObligation(_, _)
         | ObligationCauseCode::ItemObligation(_) = &*code
         {
             return try_borrowing(
-                ty::TraitRef::new(trait_ref.def_id, imm_substs),
-                ty::TraitRef::new(trait_ref.def_id, mut_substs),
-                trait_ref,
+                poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, imm_substs)),
+                poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, mut_substs)),
+                *poly_trait_ref,
                 &never_suggest_borrow[..],
             );
         } else {
diff --git a/src/test/ui/suggestions/issue-89333.rs b/src/test/ui/suggestions/issue-89333.rs
new file mode 100644
index 00000000000..a7bb524c421
--- /dev/null
+++ b/src/test/ui/suggestions/issue-89333.rs
@@ -0,0 +1,9 @@
+// check-fail
+// Ensure we don't error when emitting trait bound not satisfied when self type
+// has late bound var
+
+fn main() {
+    test(&|| 0); //~ ERROR the trait bound
+}
+
+fn test<T>(arg: &impl Fn() -> T) where for<'a> &'a T: Default {}
diff --git a/src/test/ui/suggestions/issue-89333.stderr b/src/test/ui/suggestions/issue-89333.stderr
new file mode 100644
index 00000000000..6518114dcdc
--- /dev/null
+++ b/src/test/ui/suggestions/issue-89333.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `for<'a> &'a {integer}: Default` is not satisfied
+  --> $DIR/issue-89333.rs:6:10
+   |
+LL |     test(&|| 0);
+   |     ---- ^^^^^ the trait `for<'a> Default` is not implemented for `&'a {integer}`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the following implementations were found:
+             <&CStr as Default>
+             <&OsStr as Default>
+             <&[T] as Default>
+             <&mut [T] as Default>
+           and 217 others
+note: required by a bound in `test`
+  --> $DIR/issue-89333.rs:9:55
+   |
+LL | fn test<T>(arg: &impl Fn() -> T) where for<'a> &'a T: Default {}
+   |                                                       ^^^^^^^ required by this bound in `test`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.