Skip to content

Clean fix for #96223 #97123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Taking review into account
  • Loading branch information
ricked-twice committed May 17, 2022
commit ac5366b669b5a4f9a6c7e231ac6f99e709c44fe9
Original file line number Diff line number Diff line change
Expand Up @@ -628,15 +628,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
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
Expand All @@ -661,6 +663,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
} 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(
Expand Down Expand Up @@ -723,6 +727,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
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() {
Expand All @@ -732,8 +737,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
};
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 =
Expand Down Expand Up @@ -876,12 +884,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// 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 {
Expand Down Expand Up @@ -997,7 +1000,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
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 {
Expand All @@ -1006,7 +1009,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
};
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));

Expand Down Expand Up @@ -1132,22 +1135,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
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));

Expand Down
14 changes: 4 additions & 10 deletions src/test/ui/binop/issue-77910-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ LL | foo::<S>(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`
Comment on lines 7 to +8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is less than ideal, but I think it should be left for a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I was not really able to understand why line 7 is printing only not satisfied trait and a different name for the lifetime from the one use in the code ('a instead of 'b) and note due to change is using binder and the same name for lifetime than the one in the code.

note: required by a bound in `foo`
--> $DIR/imm-ref-trait-object-literal-bound-regions.rs:11:20
|
Expand Down