Skip to content

Commit b22db3f

Browse files
authored
Rollup merge of rust-lang#109423 - fmease:iat-selection-erase-regions-in-self-ty, r=compiler-errors
Use region-erased self type during IAT selection Split off from rust-lang#109410 as discussed. Fixes rust-lang#109299. Re UI test: I use a reproducer of rust-lang#109299 that contains a name resolution error instead of reproducer [`regionck-2.rs`](https://github.com/rust-lang/rust/blob/fc7ed4af165c27ab5914b93251194f826920cc65/tests/ui/associated-inherent-types/regionck-2.rs) (as found in the `AliasKind::Inherent` PR) since it would (incorrectly) pass typeck in this PR due to the lack of regionck and I'd rather not make *that* a regression test (with or without `known-bug`). ``@rustbot`` label F-inherent_associated_types r? ``@compiler-errors``
2 parents 2ee07a1 + 293f21c commit b22db3f

File tree

5 files changed

+101
-31
lines changed

5 files changed

+101
-31
lines changed

Diff for: compiler/rustc_hir_analysis/src/astconv/mod.rs

+51-31
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3131
use rustc_infer::traits::ObligationCause;
3232
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
3333
use rustc_middle::middle::stability::AllowUnstable;
34+
use rustc_middle::ty::fold::FnMutDelegate;
3435
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
3536
use rustc_middle::ty::DynKind;
3637
use rustc_middle::ty::GenericParamDefKind;
@@ -2225,47 +2226,66 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22252226

22262227
let param_env = tcx.param_env(block.owner.to_def_id());
22272228
let cause = ObligationCause::misc(span, block.owner.def_id);
2229+
22282230
let mut fulfillment_errors = Vec::new();
2229-
let mut applicable_candidates: Vec<_> = candidates
2230-
.iter()
2231-
.filter_map(|&(impl_, (assoc_item, def_scope))| {
2232-
infcx.probe(|_| {
2233-
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
2231+
let mut applicable_candidates: Vec<_> = infcx.probe(|_| {
2232+
let universe = infcx.create_next_universe();
2233+
2234+
// Regions are not considered during selection.
2235+
let self_ty = tcx.replace_escaping_bound_vars_uncached(
2236+
self_ty,
2237+
FnMutDelegate {
2238+
regions: &mut |_| tcx.lifetimes.re_erased,
2239+
types: &mut |bv| {
2240+
tcx.mk_placeholder(ty::PlaceholderType { universe, name: bv.kind })
2241+
},
2242+
consts: &mut |bv, ty| {
2243+
tcx.mk_const(ty::PlaceholderConst { universe, name: bv }, ty)
2244+
},
2245+
},
2246+
);
22342247

2235-
let impl_ty = tcx.type_of(impl_);
2236-
let impl_substs = infcx.fresh_item_substs(impl_);
2237-
let impl_ty = impl_ty.subst(tcx, impl_substs);
2238-
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
2248+
candidates
2249+
.iter()
2250+
.filter_map(|&(impl_, (assoc_item, def_scope))| {
2251+
infcx.probe(|_| {
2252+
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
22392253

2240-
// Check that the Self-types can be related.
2241-
// FIXME(fmease): Should we use `eq` here?
2242-
ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?;
2254+
let impl_ty = tcx.type_of(impl_);
2255+
let impl_substs = infcx.fresh_item_substs(impl_);
2256+
let impl_ty = impl_ty.subst(tcx, impl_substs);
2257+
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
22432258

2244-
// Check whether the impl imposes obligations we have to worry about.
2245-
let impl_bounds = tcx.predicates_of(impl_);
2246-
let impl_bounds = impl_bounds.instantiate(tcx, impl_substs);
2259+
// Check that the Self-types can be related.
2260+
// FIXME(fmease): Should we use `eq` here?
2261+
ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?;
22472262

2248-
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
2263+
// Check whether the impl imposes obligations we have to worry about.
2264+
let impl_bounds = tcx.predicates_of(impl_);
2265+
let impl_bounds = impl_bounds.instantiate(tcx, impl_substs);
22492266

2250-
let impl_obligations = traits::predicates_for_generics(
2251-
|_, _| cause.clone(),
2252-
param_env,
2253-
impl_bounds,
2254-
);
2267+
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
22552268

2256-
ocx.register_obligations(impl_obligations);
2269+
let impl_obligations = traits::predicates_for_generics(
2270+
|_, _| cause.clone(),
2271+
param_env,
2272+
impl_bounds,
2273+
);
22572274

2258-
let mut errors = ocx.select_where_possible();
2259-
if !errors.is_empty() {
2260-
fulfillment_errors.append(&mut errors);
2261-
return None;
2262-
}
2275+
ocx.register_obligations(impl_obligations);
2276+
2277+
let mut errors = ocx.select_where_possible();
2278+
if !errors.is_empty() {
2279+
fulfillment_errors.append(&mut errors);
2280+
return None;
2281+
}
22632282

2264-
// FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2265-
Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
2283+
// FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2284+
Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
2285+
})
22662286
})
2267-
})
2268-
.collect();
2287+
.collect()
2288+
});
22692289

22702290
if applicable_candidates.len() > 1 {
22712291
return Err(self.complain_about_ambiguous_inherent_assoc_type(

Diff for: tests/ui/associated-inherent-types/issue-109299-1.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(inherent_associated_types, non_lifetime_binders, type_alias_impl_trait)]
2+
#![allow(incomplete_features)]
3+
4+
struct Lexer<T>(T);
5+
6+
impl Lexer<i32> {
7+
type Cursor = ();
8+
}
9+
10+
type X = impl for<T> Fn() -> Lexer<T>::Cursor; //~ ERROR associated type `Cursor` not found for `Lexer<T>` in the current scope
11+
12+
fn main() {}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0220]: associated type `Cursor` not found for `Lexer<T>` in the current scope
2+
--> $DIR/issue-109299-1.rs:10:40
3+
|
4+
LL | struct Lexer<T>(T);
5+
| --------------- associated item `Cursor` not found for this struct
6+
...
7+
LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
8+
| ^^^^^^ associated item not found in `Lexer<T>`
9+
|
10+
= note: the associated type was found for
11+
- `Lexer<i32>`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0220`.

Diff for: tests/ui/associated-inherent-types/issue-109299.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(inherent_associated_types)]
2+
#![allow(incomplete_features)]
3+
4+
struct Lexer<'d>(&'d ());
5+
6+
impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d`
7+
type Cursor = ();
8+
}
9+
10+
fn test(_: Lexer::Cursor) {}
11+
12+
fn main() {}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0261]: use of undeclared lifetime name `'d`
2+
--> $DIR/issue-109299.rs:6:12
3+
|
4+
LL | impl Lexer<'d> {
5+
| - ^^ undeclared lifetime
6+
| |
7+
| help: consider introducing lifetime `'d` here: `<'d>`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0261`.

0 commit comments

Comments
 (0)