Skip to content

Commit 3c64ff7

Browse files
authored
Rollup merge of rust-lang#108843 - compiler-errors:non_lifetime_binders-method-probe, r=jackh726
Instantiate instead of erasing binder when probing param methods Fixes rust-lang#108836 There is a really old comment saying that a `WhereClauseCandidate` probe candidate "should not contain any inference variables", but I'm not really confident that that comment applies anymore. In contrast, other candidates that we assemble during method probe contain inference variables in their substitutions (e.g. `InherentImplCandidate`)... Since this change is made only to support a nightly feature, I'm happy to gate the new behavior behind this feature flag or discuss it further. r? types
2 parents 1c39afb + b7a5f3a commit 3c64ff7

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

Diff for: compiler/rustc_hir_typeck/src/method/probe.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
793793
// a `&self` method will wind up with an argument type like `&dyn Trait`.
794794
let trait_ref = principal.with_self_ty(self.tcx, self_ty);
795795
self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
796+
if new_trait_ref.has_non_region_late_bound() {
797+
this.tcx.sess.delay_span_bug(
798+
this.span,
799+
"tried to select method from HRTB with non-lifetime bound vars",
800+
);
801+
return;
802+
}
803+
796804
let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
797805

798806
let (xform_self_ty, xform_ret_ty) =
@@ -843,18 +851,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
843851
});
844852

845853
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
846-
let trait_ref = this.erase_late_bound_regions(poly_trait_ref);
854+
let trait_ref = this.instantiate_binder_with_fresh_vars(
855+
this.span,
856+
infer::LateBoundRegionConversionTime::FnCall,
857+
poly_trait_ref,
858+
);
847859

848860
let (xform_self_ty, xform_ret_ty) =
849861
this.xform_self_ty(item, trait_ref.self_ty(), trait_ref.substs);
850862

851-
// Because this trait derives from a where-clause, it
852-
// should not contain any inference variables or other
853-
// artifacts. This means it is safe to put into the
854-
// `WhereClauseCandidate` and (eventually) into the
855-
// `WhereClausePick`.
856-
assert!(!trait_ref.substs.needs_infer());
857-
858863
this.push_candidate(
859864
Candidate {
860865
xform_self_ty,
@@ -964,7 +969,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
964969
bound_trait_ref.def_id(),
965970
));
966971
} else {
967-
let new_trait_ref = self.erase_late_bound_regions(bound_trait_ref);
972+
let new_trait_ref = self.instantiate_binder_with_fresh_vars(
973+
self.span,
974+
infer::LateBoundRegionConversionTime::FnCall,
975+
bound_trait_ref,
976+
);
968977

969978
let (xform_self_ty, xform_ret_ty) =
970979
self.xform_self_ty(item, new_trait_ref.self_ty(), new_trait_ref.substs);

Diff for: tests/ui/traits/non_lifetime_binders/method-probe.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// check-pass
2+
3+
#![feature(non_lifetime_binders)]
4+
//~^ WARN the feature `non_lifetime_binders` is incomplete
5+
6+
trait Foo: for<T> Bar<T> {}
7+
8+
trait Bar<T> {
9+
fn method() -> T;
10+
}
11+
12+
fn x<T: Foo>() {
13+
let _: i32 = T::method();
14+
}
15+
16+
fn main() {}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/method-probe.rs:3:12
3+
|
4+
LL | #![feature(non_lifetime_binders)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

0 commit comments

Comments
 (0)