Uplift the new trait solver

This commit is contained in:
Michael Goulet 2024-06-17 17:59:08 -04:00
parent baf94bddf0
commit 532149eb88
36 changed files with 2014 additions and 1457 deletions

View file

@ -90,46 +90,65 @@ use std::ops::{Bound, Deref};
impl<'tcx> Interner for TyCtxt<'tcx> {
type DefId = DefId;
type LocalDefId = LocalDefId;
type AdtDef = ty::AdtDef<'tcx>;
type GenericArgs = ty::GenericArgsRef<'tcx>;
type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
type GenericArg = ty::GenericArg<'tcx>;
type Term = ty::Term<'tcx>;
type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
type BoundVarKind = ty::BoundVariableKind;
type CanonicalVars = CanonicalVarInfos<'tcx>;
type BoundVarKind = ty::BoundVariableKind;
type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
fn mk_predefined_opaques_in_body(
self,
data: PredefinedOpaquesData<Self>,
) -> Self::PredefinedOpaques {
self.mk_predefined_opaques_in_body(data)
}
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
type ExternalConstraints = ExternalConstraints<'tcx>;
type CanonicalGoalEvaluationStepRef =
&'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>;
type CanonicalVars = CanonicalVarInfos<'tcx>;
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}
type ExternalConstraints = ExternalConstraints<'tcx>;
fn mk_external_constraints(
self,
data: ExternalConstraintsData<Self>,
) -> ExternalConstraints<'tcx> {
self.mk_external_constraints(data)
}
type DepNodeIndex = DepNodeIndex;
fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
}
type Ty = Ty<'tcx>;
type Tys = &'tcx List<Ty<'tcx>>;
type FnInputTys = &'tcx [Ty<'tcx>];
type ParamTy = ParamTy;
type BoundTy = ty::BoundTy;
type PlaceholderTy = ty::PlaceholderType;
type PlaceholderTy = ty::PlaceholderType;
type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
type AllocId = crate::mir::interpret::AllocId;
type AllocId = crate::mir::interpret::AllocId;
type Pat = Pattern<'tcx>;
type Safety = hir::Safety;
type Abi = abi::Abi;
type Const = ty::Const<'tcx>;
type PlaceholderConst = ty::PlaceholderConst;
type ParamConst = ty::ParamConst;
type BoundConst = ty::BoundVar;
type ValueConst = ty::ValTree<'tcx>;
type ExprConst = ty::Expr<'tcx>;
type Region = Region<'tcx>;
type EarlyParamRegion = ty::EarlyParamRegion;
type LateParamRegion = ty::LateParamRegion;
type BoundRegion = ty::BoundRegion;
@ -137,15 +156,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ParamEnv = ty::ParamEnv<'tcx>;
type Predicate = Predicate<'tcx>;
type Clause = Clause<'tcx>;
type Clauses = ty::Clauses<'tcx>;
type DepNodeIndex = DepNodeIndex;
fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
}
type EvaluationCache = &'tcx solve::EvaluationCache<'tcx>;
fn evaluation_cache(self, mode: SolverMode) -> &'tcx solve::EvaluationCache<'tcx> {
match mode {
SolverMode::Normal => &self.new_solver_evaluation_cache,
@ -157,17 +173,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.expand_abstract_consts(t)
}
fn mk_external_constraints(
self,
data: ExternalConstraintsData<Self>,
) -> ExternalConstraints<'tcx> {
self.mk_external_constraints(data)
}
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}
type GenericsOf = &'tcx ty::Generics;
fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
@ -184,6 +189,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.type_of(def_id)
}
type AdtDef = ty::AdtDef<'tcx>;
fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
self.adt_def(adt_def_id)
}
fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
match self.def_kind(alias.def_id) {
DefKind::AssocTy => {
@ -221,8 +231,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn trait_ref_and_own_args_for_alias(
self,
def_id: DefId,
args: Self::GenericArgs,
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
args: ty::GenericArgsRef<'tcx>,
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
let trait_def_id = self.parent(def_id);
assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
@ -233,18 +243,22 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
)
}
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
self.mk_args(args)
}
fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<Self::GenericArg, Self::GenericArgs>,
T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
{
self.mk_args_from_iter(args)
}
fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
self.check_args_compatible(def_id, args)
}
fn check_and_mk_args(
self,
def_id: DefId,
@ -263,7 +277,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<Self::Ty, Self::Tys>,
T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
{
self.mk_type_list_from_iter(args)
}
@ -312,6 +326,24 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
}
fn predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
ty::EarlyBinder::bind(
self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
)
}
fn own_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
ty::EarlyBinder::bind(
self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
)
}
fn super_predicates_of(
self,
def_id: DefId,
@ -326,15 +358,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
}
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
self.require_lang_item(
match lang_item {
TraitSolverLangItem::Future => hir::LangItem::Future,
TraitSolverLangItem::FutureOutput => hir::LangItem::FutureOutput,
TraitSolverLangItem::AsyncFnKindHelper => hir::LangItem::AsyncFnKindHelper,
TraitSolverLangItem::AsyncFnKindUpvars => hir::LangItem::AsyncFnKindUpvars,
},
None,
)
self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
}
fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
}
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
@ -343,6 +371,257 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
.filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
.map(|assoc_item| assoc_item.def_id)
}
fn args_may_unify_deep(
self,
obligation_args: ty::GenericArgsRef<'tcx>,
impl_args: ty::GenericArgsRef<'tcx>,
) -> bool {
ty::fast_reject::DeepRejectCtxt {
treat_obligation_params: ty::fast_reject::TreatParams::ForLookup,
}
.args_may_unify(obligation_args, impl_args)
}
// This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
// since we want to skip over blanket impls for non-rigid aliases, and also we
// only want to consider types that *actually* unify with float/int vars.
fn for_each_relevant_impl(
self,
trait_def_id: DefId,
self_ty: Ty<'tcx>,
mut f: impl FnMut(DefId),
) {
let tcx = self;
let trait_impls = tcx.trait_impls_of(trait_def_id);
let mut consider_impls_for_simplified_type = |simp| {
if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
for &impl_def_id in impls_for_type {
f(impl_def_id);
}
}
};
match self_ty.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Adt(_, _)
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(_)
| ty::Dynamic(_, _, _)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(_, _)
| ty::Never
| ty::Tuple(_) => {
let simp = ty::fast_reject::simplify_type(
tcx,
self_ty,
ty::fast_reject::TreatParams::ForLookup,
)
.unwrap();
consider_impls_for_simplified_type(simp);
}
// HACK: For integer and float variables we have to manually look at all impls
// which have some integer or float as a self type.
ty::Infer(ty::IntVar(_)) => {
use ty::IntTy::*;
use ty::UintTy::*;
// This causes a compiler error if any new integer kinds are added.
let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
let possible_integers = [
// signed integers
ty::SimplifiedType::Int(I8),
ty::SimplifiedType::Int(I16),
ty::SimplifiedType::Int(I32),
ty::SimplifiedType::Int(I64),
ty::SimplifiedType::Int(I128),
ty::SimplifiedType::Int(Isize),
// unsigned integers
ty::SimplifiedType::Uint(U8),
ty::SimplifiedType::Uint(U16),
ty::SimplifiedType::Uint(U32),
ty::SimplifiedType::Uint(U64),
ty::SimplifiedType::Uint(U128),
ty::SimplifiedType::Uint(Usize),
];
for simp in possible_integers {
consider_impls_for_simplified_type(simp);
}
}
ty::Infer(ty::FloatVar(_)) => {
// This causes a compiler error if any new float kinds are added.
let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
let possible_floats = [
ty::SimplifiedType::Float(ty::FloatTy::F16),
ty::SimplifiedType::Float(ty::FloatTy::F32),
ty::SimplifiedType::Float(ty::FloatTy::F64),
ty::SimplifiedType::Float(ty::FloatTy::F128),
];
for simp in possible_floats {
consider_impls_for_simplified_type(simp);
}
}
// The only traits applying to aliases and placeholders are blanket impls.
//
// Impls which apply to an alias after normalization are handled by
// `assemble_candidates_after_normalizing_self_ty`.
ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
// FIXME: These should ideally not exist as a self type. It would be nice for
// the builtin auto trait impls of coroutines to instead directly recurse
// into the witness.
ty::CoroutineWitness(..) => (),
// These variants should not exist as a self type.
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
| ty::Param(_)
| ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
}
let trait_impls = tcx.trait_impls_of(trait_def_id);
for &impl_def_id in trait_impls.blanket_impls() {
f(impl_def_id);
}
}
fn has_item_definition(self, def_id: DefId) -> bool {
self.defaultness(def_id).has_value()
}
fn impl_is_default(self, impl_def_id: DefId) -> bool {
self.defaultness(impl_def_id).is_default()
}
fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
self.impl_trait_ref(impl_def_id).unwrap()
}
fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
self.impl_polarity(impl_def_id)
}
fn trait_is_auto(self, trait_def_id: DefId) -> bool {
self.trait_is_auto(trait_def_id)
}
fn trait_is_alias(self, trait_def_id: DefId) -> bool {
self.trait_is_alias(trait_def_id)
}
fn trait_is_object_safe(self, trait_def_id: DefId) -> bool {
self.is_object_safe(trait_def_id)
}
fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).implement_via_object
}
fn fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
self.fn_trait_kind_from_def_id(trait_def_id)
}
fn async_fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
self.async_fn_trait_kind_from_def_id(trait_def_id)
}
fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> {
self.supertrait_def_ids(trait_def_id)
}
fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
}
fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
self.is_general_coroutine(coroutine_def_id)
}
fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
self.coroutine_is_async(coroutine_def_id)
}
fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
self.coroutine_is_gen(coroutine_def_id)
}
fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
self.coroutine_is_async_gen(coroutine_def_id)
}
fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
self.layout_of(self.erase_regions(param_env.and(ty)))
.is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
}
type UnsizingParams = &'tcx rustc_index::bit_set::BitSet<u32>;
fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
self.unsizing_params_for_adt(adt_def_id)
}
fn find_const_ty_from_env(
self,
param_env: ty::ParamEnv<'tcx>,
placeholder: Self::PlaceholderConst,
) -> Ty<'tcx> {
placeholder.find_const_ty_from_env(param_env)
}
}
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
match lang_item {
TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct,
TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper,
TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars,
TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator,
TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture,
TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture,
TraitSolverLangItem::Clone => LangItem::Clone,
TraitSolverLangItem::Copy => LangItem::Copy,
TraitSolverLangItem::Coroutine => LangItem::Coroutine,
TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn,
TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield,
TraitSolverLangItem::Destruct => LangItem::Destruct,
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
TraitSolverLangItem::FusedIterator => LangItem::FusedIterator,
TraitSolverLangItem::Future => LangItem::Future,
TraitSolverLangItem::FutureOutput => LangItem::FutureOutput,
TraitSolverLangItem::Iterator => LangItem::Iterator,
TraitSolverLangItem::Metadata => LangItem::Metadata,
TraitSolverLangItem::Option => LangItem::Option,
TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait,
TraitSolverLangItem::PointerLike => LangItem::PointerLike,
TraitSolverLangItem::Poll => LangItem::Poll,
TraitSolverLangItem::Sized => LangItem::Sized,
TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait,
TraitSolverLangItem::Tuple => LangItem::Tuple,
TraitSolverLangItem::Unpin => LangItem::Unpin,
TraitSolverLangItem::Unsize => LangItem::Unsize,
}
}
impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
fn as_local(self) -> Option<LocalDefId> {
self.as_local()
}
}
impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
@ -377,6 +656,10 @@ impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_featu
fn coroutine_clone(self) -> bool {
self.coroutine_clone
}
fn associated_const_equality(self) -> bool {
self.associated_const_equality
}
}
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;