Skip to content

Commit 293f21c

Browse files
committed
iat selection: erase regions in self type
1 parent 44f5180 commit 293f21c

File tree

5 files changed

+101
-31
lines changed

5 files changed

+101
-31
lines changed

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;
@@ -2226,47 +2227,66 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22262227

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

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

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

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

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

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

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

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

2265-
// FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2266-
Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
2284+
// FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2285+
Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
2286+
})
22672287
})
2268-
})
2269-
.collect();
2288+
.collect()
2289+
});
22702290

22712291
if applicable_candidates.len() > 1 {
22722292
return Err(self.complain_about_ambiguous_inherent_assoc_type(
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() {}
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`.
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() {}
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)