Skip to content

Commit 440f46d

Browse files
committed
Get rid of infer vars in inherent assoc types selection by using probe
1 parent 4b26bb5 commit 440f46d

File tree

3 files changed

+60
-48
lines changed

3 files changed

+60
-48
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+34-47
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
2626
use rustc_hir::def_id::{DefId, LocalDefId};
2727
use rustc_hir::intravisit::{walk_generics, Visitor as _};
2828
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
29-
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
30-
use rustc_infer::traits::{Obligation, ObligationCause};
29+
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
30+
use rustc_infer::traits::ObligationCause;
3131
use rustc_middle::middle::stability::AllowUnstable;
3232
use rustc_middle::ty::GenericParamDefKind;
3333
use rustc_middle::ty::{
34-
self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, ParamEnv, Predicate, Ty, TyCtxt,
34+
self, Const, GenericArgKind, GenericArgsRef, IsSuggestable, ParamEnv, Ty, TyCtxt,
3535
TypeVisitableExt,
3636
};
3737
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -40,7 +40,7 @@ use rustc_span::symbol::{kw, Ident, Symbol};
4040
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
4141
use rustc_target::spec::abi;
4242
use rustc_trait_selection::traits::wf::object_region_bounds;
43-
use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCtxt};
43+
use rustc_trait_selection::traits::{self, ObligationCtxt};
4444

4545
use std::fmt::Display;
4646
use std::slice;
@@ -1606,52 +1606,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16061606
// FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
16071607
// when inside of an ADT (#108491) or where clause.
16081608
let param_env = tcx.param_env(block.owner);
1609-
let cause = ObligationCause::misc(span, block.owner.def_id);
16101609

16111610
let mut universes = if self_ty.has_escaping_bound_vars() {
16121611
vec![None; self_ty.outer_exclusive_binder().as_usize()]
16131612
} else {
16141613
vec![]
16151614
};
16161615

1617-
crate::traits::project::with_replaced_escaping_bound_vars(
1618-
infcx,
1619-
&mut universes,
1620-
self_ty,
1621-
|self_ty| {
1622-
let tcx = self.tcx();
1623-
let InferOk { value: self_ty, obligations } =
1624-
infcx.at(&cause, param_env).normalize(self_ty);
1625-
1626-
let (impl_, (assoc_item, def_scope)) = self.select_inherent_assoc_type_candidates(
1627-
infcx,
1628-
name,
1629-
span,
1630-
self_ty,
1631-
cause,
1632-
param_env,
1633-
obligations,
1634-
candidates,
1635-
)?;
1636-
1637-
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
1638-
1639-
// FIXME(fmease): Currently creating throwaway `parent_args` to please
1640-
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1641-
// not require the parent args logic.
1642-
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1643-
let args =
1644-
self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
1645-
let args = tcx.mk_args_from_iter(
1646-
std::iter::once(ty::GenericArg::from(self_ty))
1647-
.chain(args.into_iter().skip(parent_args.len())),
1648-
);
1616+
let (impl_, (assoc_item, def_scope)) =
1617+
crate::traits::project::with_replaced_escaping_bound_vars(
1618+
infcx,
1619+
&mut universes,
1620+
self_ty,
1621+
|self_ty| {
1622+
self.select_inherent_assoc_type_candidates(
1623+
infcx, name, span, self_ty, param_env, candidates,
1624+
)
1625+
},
1626+
)?;
1627+
1628+
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
1629+
1630+
// FIXME(fmease): Currently creating throwaway `parent_args` to please
1631+
// `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1632+
// not require the parent args logic.
1633+
let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1634+
let args = self.create_args_for_associated_item(span, assoc_item, segment, parent_args);
1635+
let args = tcx.mk_args_from_iter(
1636+
std::iter::once(ty::GenericArg::from(self_ty))
1637+
.chain(args.into_iter().skip(parent_args.len())),
1638+
);
16491639

1650-
let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args));
1640+
let ty = Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new(tcx, assoc_item, args));
16511641

1652-
Ok(Some((ty, assoc_item)))
1653-
},
1654-
)
1642+
Ok(Some((ty, assoc_item)))
16551643
}
16561644

16571645
fn select_inherent_assoc_type_candidates(
@@ -1660,9 +1648,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16601648
name: Ident,
16611649
span: Span,
16621650
self_ty: Ty<'tcx>,
1663-
cause: ObligationCause<'tcx>,
16641651
param_env: ParamEnv<'tcx>,
1665-
obligations: Vec<Obligation<'tcx, Predicate<'tcx>>>,
16661652
candidates: Vec<(DefId, (DefId, DefId))>,
16671653
) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
16681654
let tcx = self.tcx();
@@ -1674,11 +1660,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16741660
.filter(|&(impl_, _)| {
16751661
infcx.probe(|_| {
16761662
let ocx = ObligationCtxt::new(infcx);
1677-
ocx.register_obligations(obligations.clone());
1663+
let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
16781664

16791665
let impl_args = infcx.fresh_args_for_item(span, impl_);
16801666
let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1681-
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
1667+
let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
16821668

16831669
// Check that the self types can be related.
16841670
if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
@@ -1687,9 +1673,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16871673

16881674
// Check whether the impl imposes obligations we have to worry about.
16891675
let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1690-
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
1676+
let impl_bounds =
1677+
ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
16911678
let impl_obligations = traits::predicates_for_generics(
1692-
|_, _| cause.clone(),
1679+
|_, _| ObligationCause::dummy(),
16931680
param_env,
16941681
impl_bounds,
16951682
);

compiler/rustc_trait_selection/src/traits/project.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,18 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
14541454

14551455
// Infer the generic parameters of the impl by unifying the
14561456
// impl type with the self type of the projection.
1457-
let self_ty = alias_ty.self_ty();
1457+
let mut self_ty = alias_ty.self_ty();
1458+
if !selcx.infcx.next_trait_solver() {
1459+
self_ty = normalize_with_depth_to(
1460+
selcx,
1461+
param_env,
1462+
cause.clone(),
1463+
depth + 1,
1464+
self_ty,
1465+
obligations,
1466+
);
1467+
}
1468+
14581469
match selcx.infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, impl_ty, self_ty) {
14591470
Ok(mut ok) => obligations.append(&mut ok.obligations),
14601471
Err(_) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
3+
#![feature(inherent_associated_types)]
4+
#![allow(incomplete_features)]
5+
6+
struct Foo<T>(T);
7+
8+
impl<'a> Foo<fn(&'a ())> {
9+
type Assoc = &'a ();
10+
}
11+
12+
fn bar(_: for<'a> fn(Foo<fn(Foo<fn(&'static ())>::Assoc)>::Assoc)) {}
13+
14+
fn main() {}

0 commit comments

Comments
 (0)