From ac5366b669b5a4f9a6c7e231ac6f99e709c44fe9 Mon Sep 17 00:00:00 2001 From: ricked-twice <39213807+ricked-twice@users.noreply.github.com> Date: Tue, 17 May 2022 22:59:13 +0200 Subject: [PATCH] Taking review into account --- .../src/traits/error_reporting/suggestions.rs | 36 +++++++++---------- src/test/ui/binop/issue-77910-1.stderr | 14 +++----- ...-trait-object-literal-bound-regions.stderr | 1 + 3 files changed, 21 insertions(+), 30 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 becf3fdd5ee4..c3ee849d8571 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -628,15 +628,17 @@ fn suggest_dereferences( if let Some(parent_trait_pred) = parent_trait_pred { real_trait_pred = parent_trait_pred; } - let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else { - continue; - }; + + // Skipping binder here, remapping below + let real_ty = real_trait_pred.self_ty().skip_binder(); if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span); if let Some(steps) = autoderef.find_map(|(ty, steps)| { // Re-add the `&` let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); + + // Remapping bound vars here let real_trait_pred_and_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); let obligation = self @@ -661,6 +663,8 @@ fn suggest_dereferences( } } else if real_trait_pred != trait_pred { // This branch addresses #87437. + + // Remapping bound vars here let real_trait_pred_and_base_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty)); let obligation = self.mk_trait_obligation_with_new_self_ty( @@ -723,6 +727,7 @@ fn suggest_fn_call( err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { + // Skipping binder here, remapping below let self_ty = trait_pred.self_ty().skip_binder(); let (def_id, output_ty, callable) = match *self_ty.kind() { @@ -732,8 +737,11 @@ fn suggest_fn_call( }; let msg = format!("use parentheses to call the {}", callable); + // "We should really create a single list of bound vars from the combined vars + // from the predicate and function, but instead we just liberate the function bound vars" let output_ty = self.tcx.liberate_late_bound_regions(def_id, output_ty); + // Remapping bound vars here let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, output_ty)); let new_obligation = @@ -876,12 +884,7 @@ fn suggest_add_reference_to_arg( // Because of this, we modify the error to refer to the original obligation and // return early in the caller. - let msg = format!( - "the trait bound `{}: {}` is not satisfied", - // Safe to skip binder here - old_pred.self_ty().skip_binder(), - old_pred.print_modifiers_and_trait_path(), - ); + let msg = format!("the trait bound `{}` is not satisfied", old_pred); if has_custom_message { err.note(&msg); } else { @@ -997,7 +1000,7 @@ fn suggest_remove_reference( return false; } - // We skip binder here + // Skipping binder here, remapping below let mut suggested_ty = trait_pred.self_ty().skip_binder(); for refs_remaining in 0..refs_number { @@ -1006,7 +1009,7 @@ fn suggest_remove_reference( }; suggested_ty = *inner_ty; - // We remap bounds here + // Remapping bound vars here let trait_pred_and_suggested_ty = trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty)); @@ -1132,22 +1135,15 @@ fn suggest_change_mut( return; } + // Skipping binder here, remapping below if let ty::Ref(region, t_type, mutability) = *trait_pred.skip_binder().self_ty().kind() { - if region.is_late_bound() || t_type.has_escaping_bound_vars() { - // Avoid debug assertion in `mk_obligation_for_def_id`. - // - // If the self type has escaping bound vars then it's not - // going to be the type of an expression, so the suggestion - // probably won't apply anyway. - return; - } - let suggested_ty = match mutability { hir::Mutability::Mut => self.tcx.mk_imm_ref(region, t_type), hir::Mutability::Not => self.tcx.mk_mut_ref(region, t_type), }; + // Remapping bound vars here let trait_pred_and_suggested_ty = trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty)); diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr index 95ee51a88261..68303b842088 100644 --- a/src/test/ui/binop/issue-77910-1.stderr +++ b/src/test/ui/binop/issue-77910-1.stderr @@ -12,20 +12,14 @@ LL | assert_eq!(foo, y); error[E0277]: `for<'r> fn(&'r i32) -> &'r i32 {foo}` doesn't implement `Debug` --> $DIR/issue-77910-1.rs:8:5 | +LL | fn foo(s: &i32) -> &i32 { + | --- consider calling this function +... LL | assert_eq!(foo, y); | ^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}` - = help: the following other types implement trait `Debug`: - extern "C" fn() -> Ret - extern "C" fn(A) -> Ret - extern "C" fn(A, ...) -> Ret - extern "C" fn(A, B) -> Ret - extern "C" fn(A, B, ...) -> Ret - extern "C" fn(A, B, C) -> Ret - extern "C" fn(A, B, C, ...) -> Ret - extern "C" fn(A, B, C, D) -> Ret - and 68 others + = help: use parentheses to call the function: `foo(s)` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr index 0783f04dc9bd..ba6af8f15fa8 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr @@ -5,6 +5,7 @@ LL | foo::(s); | ^^^^^^^^ the trait `for<'b> Trait` is not implemented for `&'b S` | = help: the trait `Trait` is implemented for `&'a mut S` + = note: `for<'b> Trait` is implemented for `&'b mut S`, but not for `&'b S` note: required by a bound in `foo` --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:11:20 |