From b7a5f3a41c6613033f0e6be9307c40e3174a9381 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 Mar 2023 05:40:55 +0000 Subject: [PATCH] Instantiate instead of erasing binder when probing param methods --- compiler/rustc_hir_typeck/src/method/probe.rs | 27 ++++++++++++------- .../non_lifetime_binders/method-probe.rs | 16 +++++++++++ .../non_lifetime_binders/method-probe.stderr | 11 ++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 tests/ui/traits/non_lifetime_binders/method-probe.rs create mode 100644 tests/ui/traits/non_lifetime_binders/method-probe.stderr diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3bef5cfcd780e..2c8c9ed69d31c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -792,6 +792,14 @@ impl<'a, 'tcx> ProbeContext<'a, '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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }); 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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { 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); diff --git a/tests/ui/traits/non_lifetime_binders/method-probe.rs b/tests/ui/traits/non_lifetime_binders/method-probe.rs new file mode 100644 index 0000000000000..8df240c2082b7 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/method-probe.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait Foo: for Bar {} + +trait Bar { + fn method() -> T; +} + +fn x() { + let _: i32 = T::method(); +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/method-probe.stderr b/tests/ui/traits/non_lifetime_binders/method-probe.stderr new file mode 100644 index 0000000000000..8f61792e6ce7f --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/method-probe.stderr @@ -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 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted +