Skip to content

Commit

Permalink
Auto merge of rust-lang#89345 - jackh726:89333, r=estebank
Browse files Browse the repository at this point in the history
Don't lose binders when printing trait bound suggestion

Fixes rust-lang#89333
  • Loading branch information
bors committed Oct 2, 2021
2 parents f03eb6b + 4bd1751 commit 2801a77
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/suggestions/issue-89333.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// 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
}

trait Trait {}

fn test<T>(arg: &impl Fn() -> T) where for<'a> &'a T: Trait {}
15 changes: 15 additions & 0 deletions src/test/ui/suggestions/issue-89333.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0277]: the trait bound `for<'a> &'a _: Trait` is not satisfied
--> $DIR/issue-89333.rs:6:5
|
LL | test(&|| 0);
| ^^^^ the trait `for<'a> Trait` is not implemented for `&'a _`
|
note: required by a bound in `test`
--> $DIR/issue-89333.rs:11:55
|
LL | fn test<T>(arg: &impl Fn() -> T) where for<'a> &'a T: Trait {}
| ^^^^^ required by this bound in `test`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit 2801a77

Please sign in to comment.