Instantiate instead of erasing binder when probing param methods

This commit is contained in:
Michael Goulet 2023-03-07 05:40:55 +00:00
parent f63ccaf25f
commit b7a5f3a41c
3 changed files with 45 additions and 9 deletions

View File

@ -792,6 +792,14 @@ fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) {
// a `&self` method will wind up with an argument type like `&dyn Trait`.
let trait_ref = principal.with_self_ty(self.tcx, self_ty);
self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
if new_trait_ref.has_non_region_late_bound() {
this.tcx.sess.delay_span_bug(
this.span,
"tried to select method from HRTB with non-lifetime bound vars",
);
return;
}
let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
let (xform_self_ty, xform_ret_ty) =
@ -842,18 +850,15 @@ fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
});
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
let trait_ref = this.erase_late_bound_regions(poly_trait_ref);
let trait_ref = this.instantiate_binder_with_fresh_vars(
this.span,
infer::LateBoundRegionConversionTime::FnCall,
poly_trait_ref,
);
let (xform_self_ty, xform_ret_ty) =
this.xform_self_ty(item, trait_ref.self_ty(), trait_ref.substs);
// Because this trait derives from a where-clause, it
// should not contain any inference variables or other
// artifacts. This means it is safe to put into the
// `WhereClauseCandidate` and (eventually) into the
// `WhereClausePick`.
assert!(!trait_ref.substs.needs_infer());
this.push_candidate(
Candidate {
xform_self_ty,
@ -963,7 +968,11 @@ fn assemble_extension_candidates_for_trait(
bound_trait_ref.def_id(),
));
} else {
let new_trait_ref = self.erase_late_bound_regions(bound_trait_ref);
let new_trait_ref = self.instantiate_binder_with_fresh_vars(
self.span,
infer::LateBoundRegionConversionTime::FnCall,
bound_trait_ref,
);
let (xform_self_ty, xform_ret_ty) =
self.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs);

View File

@ -0,0 +1,16 @@
// check-pass
#![feature(non_lifetime_binders)]
//~^ WARN the feature `non_lifetime_binders` is incomplete
trait Foo: for<T> Bar<T> {}
trait Bar<T> {
fn method() -> T;
}
fn x<T: Foo>() {
let _: i32 = T::method();
}
fn main() {}

View File

@ -0,0 +1,11 @@
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/method-probe.rs:3:12
|
LL | #![feature(non_lifetime_binders)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted