Skip to content

Commit 8cf6c42

Browse files
committed
Don't lose binders when printing trait bound suggestion
1 parent 8f8092c commit 8cf6c42

File tree

3 files changed

+48
-16
lines changed

3 files changed

+48
-16
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
675675
&self,
676676
obligation: &PredicateObligation<'tcx>,
677677
err: &mut DiagnosticBuilder<'_>,
678-
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
678+
poly_trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
679679
has_custom_message: bool,
680680
) -> bool {
681681
let span = obligation.cause.span;
@@ -704,7 +704,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
704704
never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::send_trait).unwrap());
705705

706706
let param_env = obligation.param_env;
707-
let trait_ref = trait_ref.skip_binder();
707+
let trait_ref = poly_trait_ref.skip_binder();
708708

709709
let found_ty = trait_ref.self_ty();
710710
let found_ty_str = found_ty.to_string();
@@ -714,25 +714,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
714714
let mut_substs = self.tcx.mk_substs_trait(mut_borrowed_found_ty, &[]);
715715

716716
// Try to apply the original trait binding obligation by borrowing.
717-
let mut try_borrowing = |new_imm_trait_ref: ty::TraitRef<'tcx>,
718-
new_mut_trait_ref: ty::TraitRef<'tcx>,
719-
expected_trait_ref: ty::TraitRef<'tcx>,
717+
let mut try_borrowing = |new_imm_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
718+
new_mut_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
719+
expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
720720
blacklist: &[DefId]|
721721
-> bool {
722-
if blacklist.contains(&expected_trait_ref.def_id) {
722+
if blacklist.contains(&expected_trait_ref.def_id()) {
723723
return false;
724724
}
725725

726726
let imm_result = self.predicate_must_hold_modulo_regions(&Obligation::new(
727727
ObligationCause::dummy(),
728728
param_env,
729-
ty::Binder::dummy(new_imm_trait_ref).without_const().to_predicate(self.tcx),
729+
new_imm_trait_ref.without_const().to_predicate(self.tcx),
730730
));
731731

732732
let mut_result = self.predicate_must_hold_modulo_regions(&Obligation::new(
733733
ObligationCause::dummy(),
734734
param_env,
735-
ty::Binder::dummy(new_mut_trait_ref).without_const().to_predicate(self.tcx),
735+
new_mut_trait_ref.without_const().to_predicate(self.tcx),
736736
));
737737

738738
if imm_result || mut_result {
@@ -805,19 +805,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
805805
};
806806

807807
if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code {
808-
let expected_trait_ref = obligation.parent_trait_ref.skip_binder();
809-
let new_imm_trait_ref =
810-
ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs);
811-
let new_mut_trait_ref =
812-
ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs);
808+
let expected_trait_ref = obligation.parent_trait_ref;
809+
let new_imm_trait_ref = poly_trait_ref
810+
.rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs));
811+
let new_mut_trait_ref = poly_trait_ref
812+
.rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs));
813813
return try_borrowing(new_imm_trait_ref, new_mut_trait_ref, expected_trait_ref, &[]);
814814
} else if let ObligationCauseCode::BindingObligation(_, _)
815815
| ObligationCauseCode::ItemObligation(_) = &*code
816816
{
817817
return try_borrowing(
818-
ty::TraitRef::new(trait_ref.def_id, imm_substs),
819-
ty::TraitRef::new(trait_ref.def_id, mut_substs),
820-
trait_ref,
818+
poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, imm_substs)),
819+
poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, mut_substs)),
820+
*poly_trait_ref,
821821
&never_suggest_borrow[..],
822822
);
823823
} else {

Diff for: src/test/ui/suggestions/issue-89333.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// check-fail
2+
// Ensure we don't error when emitting trait bound not satisfied when self type
3+
// has late bound var
4+
5+
fn main() {
6+
test(&|| 0); //~ ERROR the trait bound
7+
}
8+
9+
fn test<T>(arg: &impl Fn() -> T) where for<'a> &'a T: Default {}

Diff for: src/test/ui/suggestions/issue-89333.stderr

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error[E0277]: the trait bound `for<'a> &'a {integer}: Default` is not satisfied
2+
--> $DIR/issue-89333.rs:6:10
3+
|
4+
LL | test(&|| 0);
5+
| ---- ^^^^^ the trait `for<'a> Default` is not implemented for `&'a {integer}`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the following implementations were found:
10+
<&CStr as Default>
11+
<&OsStr as Default>
12+
<&[T] as Default>
13+
<&mut [T] as Default>
14+
and 217 others
15+
note: required by a bound in `test`
16+
--> $DIR/issue-89333.rs:9:55
17+
|
18+
LL | fn test<T>(arg: &impl Fn() -> T) where for<'a> &'a T: Default {}
19+
| ^^^^^^^ required by this bound in `test`
20+
21+
error: aborting due to previous error
22+
23+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)