Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower.rs')
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 703 |
1 files changed, 403 insertions, 300 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index dd34bbe2fd..62a5837f34 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -15,8 +15,8 @@ use either::Either; use hir_def::{ AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, - LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UnionId, VariantId, + LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UnionId, VariantId, builtin_type::BuiltinType, expr_store::{ExpressionStore, HygieneId, path::Path}, hir::generics::{ @@ -61,36 +61,38 @@ use crate::{ AliasTy, Binder, BoundExistentialPredicates, Clause, ClauseKind, Clauses, Const, DbInterner, EarlyBinder, EarlyParamRegion, ErrorGuaranteed, FxIndexMap, GenericArg, GenericArgs, ParamConst, ParamEnv, PolyFnSig, Predicate, Region, SolverDefId, - TraitPredicate, TraitRef, Ty, Tys, UnevaluatedConst, abi::Safety, util::BottomUpFolder, + StoredClauses, StoredEarlyBinder, StoredGenericArg, StoredGenericArgs, StoredPolyFnSig, + StoredTy, TraitPredicate, TraitRef, Ty, Tys, UnevaluatedConst, abi::Safety, + util::BottomUpFolder, }, }; pub(crate) struct PathDiagnosticCallbackData(pub(crate) TypeRefId); #[derive(PartialEq, Eq, Debug, Hash)] -pub struct ImplTraits<'db> { - pub(crate) impl_traits: Arena<ImplTrait<'db>>, +pub struct ImplTraits { + pub(crate) impl_traits: Arena<ImplTrait>, } #[derive(PartialEq, Eq, Debug, Hash)] -pub struct ImplTrait<'db> { - pub(crate) predicates: Box<[Clause<'db>]>, +pub struct ImplTrait { + pub(crate) predicates: StoredClauses, } -pub type ImplTraitIdx<'db> = Idx<ImplTrait<'db>>; +pub type ImplTraitIdx = Idx<ImplTrait>; #[derive(Debug, Default)] -struct ImplTraitLoweringState<'db> { +struct ImplTraitLoweringState { /// When turning `impl Trait` into opaque types, we have to collect the /// bounds at the same time to get the IDs correct (without becoming too /// complicated). mode: ImplTraitLoweringMode, // This is structured as a struct with fields and not as an enum because it helps with the borrow checker. - opaque_type_data: Arena<ImplTrait<'db>>, + opaque_type_data: Arena<ImplTrait>, } -impl<'db> ImplTraitLoweringState<'db> { - fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState<'db> { +impl ImplTraitLoweringState { + fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState { Self { mode, opaque_type_data: Arena::new() } } } @@ -168,13 +170,14 @@ impl<'db> LifetimeElisionKind<'db> { pub struct TyLoweringContext<'db, 'a> { pub db: &'db dyn HirDatabase, interner: DbInterner<'db>, + types: &'db crate::next_solver::DefaultAny<'db>, lang_items: &'db LangItems, resolver: &'a Resolver<'db>, store: &'a ExpressionStore, def: GenericDefId, generics: OnceCell<Generics>, in_binders: DebruijnIndex, - impl_trait_mode: ImplTraitLoweringState<'db>, + impl_trait_mode: ImplTraitLoweringState, /// Tracks types with explicit `?Sized` bounds. pub(crate) unsized_types: FxHashSet<Ty<'db>>, pub(crate) diagnostics: Vec<TyLoweringDiagnostic>, @@ -199,6 +202,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { db, // Can provide no block since we don't use it for trait solving. interner, + types: crate::next_solver::default_types(db), lang_items: interner.lang_items(), resolver, def, @@ -337,7 +341,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } } Some(ValueNs::ConstId(c)) => { - let args = GenericArgs::new_from_iter(self.interner, []); + let args = GenericArgs::empty(self.interner); Some(Const::new( self.interner, rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new( @@ -397,7 +401,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let type_ref = &self.store[type_ref_id]; tracing::debug!(?type_ref); let ty = match type_ref { - TypeRef::Never => Ty::new(interner, TyKind::Never), + TypeRef::Never => self.types.types.never, TypeRef::Tuple(inner) => { let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr)); Ty::new_tup_from_iter(interner, inner_tys) @@ -476,7 +480,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let idx = self .impl_trait_mode .opaque_type_data - .alloc(ImplTrait { predicates: Box::default() }); + .alloc(ImplTrait { predicates: Clauses::empty(interner).store() }); let impl_trait_id = origin.either( |f| ImplTraitId::ReturnTypeImplTrait(f, idx), @@ -989,7 +993,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } } - fn lower_impl_trait(&mut self, def_id: SolverDefId, bounds: &[TypeBound]) -> ImplTrait<'db> { + fn lower_impl_trait(&mut self, def_id: SolverDefId, bounds: &[TypeBound]) -> ImplTrait { let interner = self.interner; cov_mark::hit!(lower_rpit); let args = GenericArgs::identity_for_item(interner, def_id); @@ -1010,7 +1014,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let trait_ref = TraitRef::new_from_args( interner, trait_id.into(), - GenericArgs::new_from_iter(interner, [self_ty.into()]), + GenericArgs::new_from_slice(&[self_ty.into()]), ); Clause(Predicate::new( interner, @@ -1024,9 +1028,9 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { }); predicates.extend(sized_clause); } - predicates.into_boxed_slice() + predicates }); - ImplTrait { predicates } + ImplTrait { predicates: Clauses::new_from_slice(&predicates).store() } } pub(crate) fn lower_lifetime(&mut self, lifetime: LifetimeRefId) -> Region<'db> { @@ -1090,28 +1094,50 @@ pub(crate) fn impl_trait_query<'db>( db.impl_trait_with_diagnostics(impl_id).map(|it| it.0) } -pub(crate) fn impl_trait_with_diagnostics_query<'db>( +pub(crate) fn impl_trait_with_diagnostics<'db>( db: &'db dyn HirDatabase, impl_id: ImplId, ) -> Option<(EarlyBinder<'db, TraitRef<'db>>, Diagnostics)> { - let impl_data = db.impl_signature(impl_id); - let resolver = impl_id.resolver(db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &impl_data.store, - impl_id.into(), - LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, - ); - let self_ty = db.impl_self_ty(impl_id).skip_binder(); - let target_trait = impl_data.target_trait.as_ref()?; - let trait_ref = EarlyBinder::bind(ctx.lower_trait_ref(target_trait, self_ty)?); - Some((trait_ref, create_diagnostics(ctx.diagnostics))) + return impl_trait_with_diagnostics_query(db, impl_id).as_ref().map(|(binder, diags)| { + ( + binder.get_with(|(trait_id, args)| { + TraitRef::new_from_args( + DbInterner::new_no_crate(db), + (*trait_id).into(), + args.as_ref(), + ) + }), + diags.clone(), + ) + }); + + #[salsa::tracked(returns(ref))] + pub(crate) fn impl_trait_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + impl_id: ImplId, + ) -> Option<(StoredEarlyBinder<(TraitId, StoredGenericArgs)>, Diagnostics)> { + let impl_data = db.impl_signature(impl_id); + let resolver = impl_id.resolver(db); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &impl_data.store, + impl_id.into(), + LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, + ); + let self_ty = db.impl_self_ty(impl_id).skip_binder(); + let target_trait = impl_data.target_trait.as_ref()?; + let trait_ref = ctx.lower_trait_ref(target_trait, self_ty)?; + Some(( + StoredEarlyBinder::bind((trait_ref.def_id.0, trait_ref.args.store())), + create_diagnostics(ctx.diagnostics), + )) + } } -impl<'db> ImplTraitId<'db> { +impl ImplTraitId { #[inline] - pub fn predicates(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> { + pub fn predicates<'db>(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> { let (impl_traits, idx) = match self { ImplTraitId::ReturnTypeImplTrait(owner, idx) => { (ImplTraits::return_type_impl_traits(db, owner), idx) @@ -1123,8 +1149,7 @@ impl<'db> ImplTraitId<'db> { impl_traits .as_deref() .expect("owner should have opaque type") - .as_ref() - .map_bound(|it| &*it.impl_traits[idx].predicates) + .get_with(|it| it.impl_traits[idx].predicates.as_ref().as_slice()) } } @@ -1136,12 +1161,12 @@ impl InternedOpaqueTyId { } #[salsa::tracked] -impl<'db> ImplTraits<'db> { - #[salsa::tracked(returns(ref), unsafe(non_update_return_type))] +impl ImplTraits { + #[salsa::tracked(returns(ref))] pub(crate) fn return_type_impl_traits( - db: &'db dyn HirDatabase, + db: &dyn HirDatabase, def: hir_def::FunctionId, - ) -> Option<Box<EarlyBinder<'db, ImplTraits<'db>>>> { + ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe let data = db.function_signature(def); let resolver = def.resolver(db); @@ -1162,15 +1187,15 @@ impl<'db> ImplTraits<'db> { None } else { return_type_impl_traits.impl_traits.shrink_to_fit(); - Some(Box::new(EarlyBinder::bind(return_type_impl_traits))) + Some(Box::new(StoredEarlyBinder::bind(return_type_impl_traits))) } } - #[salsa::tracked(returns(ref), unsafe(non_update_return_type))] + #[salsa::tracked(returns(ref))] pub(crate) fn type_alias_impl_traits( - db: &'db dyn HirDatabase, + db: &dyn HirDatabase, def: hir_def::TypeAliasId, - ) -> Option<Box<EarlyBinder<'db, ImplTraits<'db>>>> { + ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { let data = db.type_alias_signature(def); let resolver = def.resolver(db); let mut ctx = TyLoweringContext::new( @@ -1190,7 +1215,7 @@ impl<'db> ImplTraits<'db> { None } else { type_alias_impl_traits.impl_traits.shrink_to_fit(); - Some(Box::new(EarlyBinder::bind(type_alias_impl_traits))) + Some(Box::new(StoredEarlyBinder::bind(type_alias_impl_traits))) } } } @@ -1246,17 +1271,20 @@ pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBind /// Build the declared type of a function. This should not need to look at the /// function body. -fn type_for_fn<'db>(db: &'db dyn HirDatabase, def: FunctionId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<StoredTy> { let interner = DbInterner::new_no_crate(db); - EarlyBinder::bind(Ty::new_fn_def( - interner, - CallableDefId::FunctionId(def).into(), - GenericArgs::identity_for_item(interner, def.into()), - )) + StoredEarlyBinder::bind( + Ty::new_fn_def( + interner, + CallableDefId::FunctionId(def).into(), + GenericArgs::identity_for_item(interner, def.into()), + ) + .store(), + ) } /// Build the declared type of a const. -fn type_for_const<'db>(db: &'db dyn HirDatabase, def: ConstId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<StoredTy> { let resolver = def.resolver(db); let data = db.const_signature(def); let parent = def.loc(db).container; @@ -1268,11 +1296,11 @@ fn type_for_const<'db>(db: &'db dyn HirDatabase, def: ConstId) -> EarlyBinder<'d LifetimeElisionKind::AnonymousReportError, ); ctx.set_lifetime_elision(LifetimeElisionKind::for_const(ctx.interner, parent)); - EarlyBinder::bind(ctx.lower_ty(data.type_ref)) + StoredEarlyBinder::bind(ctx.lower_ty(data.type_ref).store()) } /// Build the declared type of a static. -fn type_for_static<'db>(db: &'db dyn HirDatabase, def: StaticId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> StoredEarlyBinder<StoredTy> { let resolver = def.resolver(db); let data = db.static_signature(def); let mut ctx = TyLoweringContext::new( @@ -1283,99 +1311,129 @@ fn type_for_static<'db>(db: &'db dyn HirDatabase, def: StaticId) -> EarlyBinder< LifetimeElisionKind::AnonymousReportError, ); ctx.set_lifetime_elision(LifetimeElisionKind::Elided(Region::new_static(ctx.interner))); - EarlyBinder::bind(ctx.lower_ty(data.type_ref)) + StoredEarlyBinder::bind(ctx.lower_ty(data.type_ref).store()) } /// Build the type of a tuple struct constructor. -fn type_for_struct_constructor<'db>( - db: &'db dyn HirDatabase, +fn type_for_struct_constructor( + db: &dyn HirDatabase, def: StructId, -) -> Option<EarlyBinder<'db, Ty<'db>>> { +) -> Option<StoredEarlyBinder<StoredTy>> { let struct_data = def.fields(db); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.into())), FieldsShape::Tuple => { let interner = DbInterner::new_no_crate(db); - Some(EarlyBinder::bind(Ty::new_fn_def( - interner, - CallableDefId::StructId(def).into(), - GenericArgs::identity_for_item(interner, def.into()), - ))) + Some(StoredEarlyBinder::bind( + Ty::new_fn_def( + interner, + CallableDefId::StructId(def).into(), + GenericArgs::identity_for_item(interner, def.into()), + ) + .store(), + )) } } } /// Build the type of a tuple enum variant constructor. -fn type_for_enum_variant_constructor<'db>( - db: &'db dyn HirDatabase, +fn type_for_enum_variant_constructor( + db: &dyn HirDatabase, def: EnumVariantId, -) -> Option<EarlyBinder<'db, Ty<'db>>> { +) -> Option<StoredEarlyBinder<StoredTy>> { let struct_data = def.fields(db); match struct_data.shape { FieldsShape::Record => None, FieldsShape::Unit => Some(type_for_adt(db, def.loc(db).parent.into())), FieldsShape::Tuple => { let interner = DbInterner::new_no_crate(db); - Some(EarlyBinder::bind(Ty::new_fn_def( - interner, - CallableDefId::EnumVariantId(def).into(), - GenericArgs::identity_for_item(interner, def.loc(db).parent.into()), - ))) + Some(StoredEarlyBinder::bind( + Ty::new_fn_def( + interner, + CallableDefId::EnumVariantId(def).into(), + GenericArgs::identity_for_item(interner, def.loc(db).parent.into()), + ) + .store(), + )) } } } -pub(crate) fn value_ty_query<'db>( +pub(crate) fn value_ty<'db>( db: &'db dyn HirDatabase, def: ValueTyDefId, ) -> Option<EarlyBinder<'db, Ty<'db>>> { - match def { - ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)), - ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), - ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())), - ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), - ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)), - ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)), + return value_ty_query(db, def).as_ref().map(|it| it.get()); + + #[salsa::tracked(returns(ref))] + pub(crate) fn value_ty_query<'db>( + db: &'db dyn HirDatabase, + def: ValueTyDefId, + ) -> Option<StoredEarlyBinder<StoredTy>> { + match def { + ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)), + ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), + ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())), + ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it), + ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)), + ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)), + } } } -pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>( +pub(crate) fn type_for_type_alias_with_diagnostics<'db>( db: &'db dyn HirDatabase, t: TypeAliasId, ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { - let type_alias_data = db.type_alias_signature(t); - let mut diags = None; - let resolver = t.resolver(db); - let interner = DbInterner::new_no_crate(db); - let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) { - EarlyBinder::bind(Ty::new_foreign(interner, t.into())) - } else { - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &type_alias_data.store, - t.into(), - LifetimeElisionKind::AnonymousReportError, - ) - .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); - let res = EarlyBinder::bind( - type_alias_data - .ty - .map(|type_ref| ctx.lower_ty(type_ref)) - .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed)), - ); - diags = create_diagnostics(ctx.diagnostics); - res - }; - (inner, diags) -} + let (ty, diags) = type_for_type_alias_with_diagnostics_query(db, t); + return (ty.get(), diags.clone()); -pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result<'db>( - db: &'db dyn HirDatabase, - _adt: TypeAliasId, -) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { - (EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None) + #[salsa::tracked(returns(ref), cycle_result = type_for_type_alias_with_diagnostics_cycle_result)] + pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + t: TypeAliasId, + ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { + let type_alias_data = db.type_alias_signature(t); + let mut diags = None; + let resolver = t.resolver(db); + let interner = DbInterner::new_no_crate(db); + let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) { + StoredEarlyBinder::bind(Ty::new_foreign(interner, t.into()).store()) + } else { + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &type_alias_data.store, + t.into(), + LifetimeElisionKind::AnonymousReportError, + ) + .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); + let res = StoredEarlyBinder::bind( + type_alias_data + .ty + .map(|type_ref| ctx.lower_ty(type_ref)) + .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed)) + .store(), + ); + diags = create_diagnostics(ctx.diagnostics); + res + }; + (inner, diags) + } + + pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _adt: TypeAliasId, + ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { + ( + StoredEarlyBinder::bind( + Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed).store(), + ), + None, + ) + } } pub(crate) fn impl_self_ty_query<'db>( @@ -1385,30 +1443,45 @@ pub(crate) fn impl_self_ty_query<'db>( db.impl_self_ty_with_diagnostics(impl_id).0 } -pub(crate) fn impl_self_ty_with_diagnostics_query<'db>( +pub(crate) fn impl_self_ty_with_diagnostics<'db>( db: &'db dyn HirDatabase, impl_id: ImplId, ) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) { - let resolver = impl_id.resolver(db); + let (ty, diags) = impl_self_ty_with_diagnostics_query(db, impl_id); + return (ty.get(), diags.clone()); - let impl_data = db.impl_signature(impl_id); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &impl_data.store, - impl_id.into(), - LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, - ); - let ty = ctx.lower_ty(impl_data.self_ty); - assert!(!ty.has_escaping_bound_vars()); - (EarlyBinder::bind(ty), create_diagnostics(ctx.diagnostics)) -} + #[salsa::tracked(returns(ref), cycle_result = impl_self_ty_with_diagnostics_cycle_result)] + pub(crate) fn impl_self_ty_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + impl_id: ImplId, + ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { + let resolver = impl_id.resolver(db); -pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( - db: &dyn HirDatabase, - _impl_id: ImplId, -) -> (EarlyBinder<'_, Ty<'_>>, Diagnostics) { - (EarlyBinder::bind(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)), None) + let impl_data = db.impl_signature(impl_id); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &impl_data.store, + impl_id.into(), + LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, + ); + let ty = ctx.lower_ty(impl_data.self_ty); + assert!(!ty.has_escaping_bound_vars()); + (StoredEarlyBinder::bind(ty.store()), create_diagnostics(ctx.diagnostics)) + } + + pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _impl_id: ImplId, + ) -> (StoredEarlyBinder<StoredTy>, Diagnostics) { + ( + StoredEarlyBinder::bind( + Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed).store(), + ), + None, + ) + } } pub(crate) fn const_param_ty_query<'db>(db: &'db dyn HirDatabase, def: ConstParamId) -> Ty<'db> { @@ -1416,56 +1489,69 @@ pub(crate) fn const_param_ty_query<'db>(db: &'db dyn HirDatabase, def: ConstPara } // returns None if def is a type arg -pub(crate) fn const_param_ty_with_diagnostics_query<'db>( +pub(crate) fn const_param_ty_with_diagnostics<'db>( db: &'db dyn HirDatabase, def: ConstParamId, ) -> (Ty<'db>, Diagnostics) { - let (parent_data, store) = db.generic_params_and_store(def.parent()); - let data = &parent_data[def.local_id()]; - let resolver = def.parent().resolver(db); - let interner = DbInterner::new_no_crate(db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &store, - def.parent(), - LifetimeElisionKind::AnonymousReportError, - ); - let ty = match data { - TypeOrConstParamData::TypeParamData(_) => { - never!(); - Ty::new_error(interner, ErrorGuaranteed) - } - TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty), - }; - (ty, create_diagnostics(ctx.diagnostics)) -} + let (ty, diags) = const_param_ty_with_diagnostics_query(db, (), def); + return (ty.as_ref(), diags.clone()); -pub(crate) fn const_param_ty_with_diagnostics_cycle_result<'db>( - db: &'db dyn HirDatabase, - _: crate::db::HirDatabaseData, - _def: ConstParamId, -) -> (Ty<'db>, Diagnostics) { - let interner = DbInterner::new_no_crate(db); - (Ty::new_error(interner, ErrorGuaranteed), None) + // FIXME: Make this query non-interned. + #[salsa::tracked(returns(ref), cycle_result = const_param_ty_with_diagnostics_cycle_result)] + pub(crate) fn const_param_ty_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + _: (), + def: ConstParamId, + ) -> (StoredTy, Diagnostics) { + let (parent_data, store) = db.generic_params_and_store(def.parent()); + let data = &parent_data[def.local_id()]; + let resolver = def.parent().resolver(db); + let interner = DbInterner::new_no_crate(db); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &store, + def.parent(), + LifetimeElisionKind::AnonymousReportError, + ); + let ty = match data { + TypeOrConstParamData::TypeParamData(_) => { + never!(); + Ty::new_error(interner, ErrorGuaranteed) + } + TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty), + }; + (ty.store(), create_diagnostics(ctx.diagnostics)) + } + + pub(crate) fn const_param_ty_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _: (), + _def: ConstParamId, + ) -> (StoredTy, Diagnostics) { + let interner = DbInterner::new_no_crate(db); + (Ty::new_error(interner, ErrorGuaranteed).store(), None) + } } -pub(crate) fn field_types_query<'db>( - db: &'db dyn HirDatabase, +pub(crate) fn field_types_query( + db: &dyn HirDatabase, variant_id: VariantId, -) -> Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>> { - db.field_types_with_diagnostics(variant_id).0 +) -> &ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>> { + &db.field_types_with_diagnostics(variant_id).0 } /// Build the type of all specific fields of a struct or enum variant. +#[salsa::tracked(returns(ref))] pub(crate) fn field_types_with_diagnostics_query<'db>( db: &'db dyn HirDatabase, variant_id: VariantId, -) -> (Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>>, Diagnostics) { +) -> (ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>, Diagnostics) { let var_data = variant_id.fields(db); let fields = var_data.fields(); if fields.is_empty() { - return (Arc::new(ArenaMap::default()), None); + return (ArenaMap::default(), None); } let (resolver, def): (_, GenericDefId) = match variant_id { @@ -1482,9 +1568,9 @@ pub(crate) fn field_types_with_diagnostics_query<'db>( LifetimeElisionKind::AnonymousReportError, ); for (field_id, field_data) in var_data.fields().iter() { - res.insert(field_id, EarlyBinder::bind(ctx.lower_ty(field_data.type_ref))); + res.insert(field_id, StoredEarlyBinder::bind(ctx.lower_ty(field_data.type_ref).store())); } - (Arc::new(res), create_diagnostics(ctx.diagnostics)) + (res, create_diagnostics(ctx.diagnostics)) } /// This query exists only to be used when resolving short-hand associated types @@ -1496,13 +1582,13 @@ pub(crate) fn field_types_with_diagnostics_query<'db>( /// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but /// these are fine: `T: Foo<U::Item>, U: Foo<()>`. #[tracing::instrument(skip(db), ret)] -#[salsa::tracked(returns(ref), unsafe(non_update_return_type), cycle_result = generic_predicates_for_param_cycle_result)] +#[salsa::tracked(returns(ref), cycle_result = generic_predicates_for_param_cycle_result)] pub(crate) fn generic_predicates_for_param<'db>( db: &'db dyn HirDatabase, def: GenericDefId, param_id: TypeOrConstParamId, assoc_name: Option<Name>, -) -> EarlyBinder<'db, Box<[Clause<'db>]>> { +) -> StoredEarlyBinder<StoredClauses> { let generics = generics(db, def); let interner = DbInterner::new_no_crate(db); let resolver = def.resolver(db); @@ -1604,16 +1690,17 @@ pub(crate) fn generic_predicates_for_param<'db>( predicates.extend(implicitly_sized_predicates); }; } - EarlyBinder::bind(predicates.into_boxed_slice()) + StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()) } -pub(crate) fn generic_predicates_for_param_cycle_result<'db>( - _db: &'db dyn HirDatabase, +pub(crate) fn generic_predicates_for_param_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, _def: GenericDefId, _param_id: TypeOrConstParamId, _assoc_name: Option<Name>, -) -> EarlyBinder<'db, Box<[Clause<'db>]>> { - EarlyBinder::bind(Box::new([])) +) -> StoredEarlyBinder<StoredClauses> { + StoredEarlyBinder::bind(Clauses::empty(DbInterner::new_no_crate(db)).store()) } #[inline] @@ -1621,84 +1708,95 @@ pub(crate) fn type_alias_bounds<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { - type_alias_bounds_with_diagnostics(db, type_alias).0.as_ref().map_bound(|it| &**it) + type_alias_bounds_with_diagnostics(db, type_alias).0.map_bound(|it| it.as_slice()) } -#[salsa::tracked(returns(ref), unsafe(non_update_return_type))] -pub fn type_alias_bounds_with_diagnostics<'db>( +pub(crate) fn type_alias_bounds_with_diagnostics<'db>( db: &'db dyn HirDatabase, type_alias: TypeAliasId, -) -> (EarlyBinder<'db, Box<[Clause<'db>]>>, Diagnostics) { - let type_alias_data = db.type_alias_signature(type_alias); - let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &type_alias_data.store, - type_alias.into(), - LifetimeElisionKind::AnonymousReportError, - ); - let interner = ctx.interner; - let def_id = type_alias.into(); +) -> (EarlyBinder<'db, Clauses<'db>>, Diagnostics) { + let (bounds, diags) = type_alias_bounds_with_diagnostics_query(db, type_alias); + return (bounds.get(), diags.clone()); - let item_args = GenericArgs::identity_for_item(interner, def_id); - let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args); + #[salsa::tracked(returns(ref))] + pub fn type_alias_bounds_with_diagnostics_query<'db>( + db: &'db dyn HirDatabase, + type_alias: TypeAliasId, + ) -> (StoredEarlyBinder<StoredClauses>, Diagnostics) { + let type_alias_data = db.type_alias_signature(type_alias); + let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + &type_alias_data.store, + type_alias.into(), + LifetimeElisionKind::AnonymousReportError, + ); + let interner = ctx.interner; + let def_id = type_alias.into(); - let mut bounds = Vec::new(); - for bound in &type_alias_data.bounds { - ctx.lower_type_bound(bound, interner_ty, false).for_each(|pred| { - bounds.push(pred); - }); - } + let item_args = GenericArgs::identity_for_item(interner, def_id); + let interner_ty = Ty::new_projection_from_args(interner, def_id, item_args); - if !ctx.unsized_types.contains(&interner_ty) { - let sized_trait = ctx.lang_items.Sized; - if let Some(sized_trait) = sized_trait { - let trait_ref = TraitRef::new_from_args( - interner, - sized_trait.into(), - GenericArgs::new_from_iter(interner, [interner_ty.into()]), - ); - bounds.push(trait_ref.upcast(interner)); - }; - } + let mut bounds = Vec::new(); + for bound in &type_alias_data.bounds { + ctx.lower_type_bound(bound, interner_ty, false).for_each(|pred| { + bounds.push(pred); + }); + } - (EarlyBinder::bind(bounds.into_boxed_slice()), create_diagnostics(ctx.diagnostics)) + if !ctx.unsized_types.contains(&interner_ty) { + let sized_trait = ctx.lang_items.Sized; + if let Some(sized_trait) = sized_trait { + let trait_ref = TraitRef::new_from_args( + interner, + sized_trait.into(), + GenericArgs::new_from_slice(&[interner_ty.into()]), + ); + bounds.push(trait_ref.upcast(interner)); + }; + } + + ( + StoredEarlyBinder::bind(Clauses::new_from_slice(&bounds).store()), + create_diagnostics(ctx.diagnostics), + ) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericPredicates<'db> { +pub struct GenericPredicates { // The order is the following: first, if `parent_is_trait == true`, comes the implicit trait predicate for the // parent. Then come the explicit predicates for the parent, then the explicit trait predicate for the child, // then the implicit trait predicate for the child, if `is_trait` is `true`. - predicates: EarlyBinder<'db, Box<[Clause<'db>]>>, + predicates: StoredEarlyBinder<StoredClauses>, own_predicates_start: u32, is_trait: bool, parent_is_trait: bool, } #[salsa::tracked] -impl<'db> GenericPredicates<'db> { +impl<'db> GenericPredicates { /// Resolve the where clause(s) of an item with generics. /// /// Diagnostics are computed only for this item's predicates, not for parents. - #[salsa::tracked(returns(ref), unsafe(non_update_return_type))] + #[salsa::tracked(returns(ref))] pub fn query_with_diagnostics( db: &'db dyn HirDatabase, def: GenericDefId, - ) -> (GenericPredicates<'db>, Diagnostics) { + ) -> (GenericPredicates, Diagnostics) { generic_predicates_filtered_by(db, def, PredicateFilter::All, |_| true) } } -impl<'db> GenericPredicates<'db> { +impl GenericPredicates { #[inline] - pub fn query(db: &'db dyn HirDatabase, def: GenericDefId) -> &'db GenericPredicates<'db> { + pub fn query(db: &dyn HirDatabase, def: GenericDefId) -> &GenericPredicates { &Self::query_with_diagnostics(db, def).0 } #[inline] - pub fn query_all( + pub fn query_all<'db>( db: &'db dyn HirDatabase, def: GenericDefId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { @@ -1706,7 +1804,7 @@ impl<'db> GenericPredicates<'db> { } #[inline] - pub fn query_own( + pub fn query_own<'db>( db: &'db dyn HirDatabase, def: GenericDefId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { @@ -1714,7 +1812,7 @@ impl<'db> GenericPredicates<'db> { } #[inline] - pub fn query_explicit( + pub fn query_explicit<'db>( db: &'db dyn HirDatabase, def: GenericDefId, ) -> EarlyBinder<'db, &'db [Clause<'db>]> { @@ -1722,20 +1820,20 @@ impl<'db> GenericPredicates<'db> { } #[inline] - pub fn all_predicates(&self) -> EarlyBinder<'db, &[Clause<'db>]> { - self.predicates.as_ref().map_bound(|it| &**it) + pub fn all_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| it.as_slice()) } #[inline] - pub fn own_predicates(&self) -> EarlyBinder<'db, &[Clause<'db>]> { - self.predicates.as_ref().map_bound(|it| &it[self.own_predicates_start as usize..]) + pub fn own_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| &it.as_slice()[self.own_predicates_start as usize..]) } /// Returns the predicates, minus the implicit `Self: Trait` predicate for a trait. #[inline] - pub fn explicit_predicates(&self) -> EarlyBinder<'db, &[Clause<'db>]> { - self.predicates.as_ref().map_bound(|it| { - &it[usize::from(self.parent_is_trait)..it.len() - usize::from(self.is_trait)] + pub fn explicit_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> { + self.predicates.get().map_bound(|it| { + &it.as_slice()[usize::from(self.parent_is_trait)..it.len() - usize::from(self.is_trait)] }) } } @@ -1750,18 +1848,24 @@ pub(crate) fn trait_environment_for_body_query( db.trait_environment(def) } -pub(crate) fn trait_environment_query<'db>( - db: &'db dyn HirDatabase, - def: GenericDefId, -) -> ParamEnv<'db> { - let module = def.module(db); - let interner = DbInterner::new_with(db, module.krate(db)); - let predicates = GenericPredicates::query_all(db, def); - let clauses = rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); - let clauses = Clauses::new_from_iter(interner, clauses); +pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> { + return ParamEnv { clauses: trait_environment_query(db, def).as_ref() }; + + #[salsa::tracked(returns(ref))] + pub(crate) fn trait_environment_query<'db>( + db: &'db dyn HirDatabase, + def: GenericDefId, + ) -> StoredClauses { + let module = def.module(db); + let interner = DbInterner::new_with(db, module.krate(db)); + let predicates = GenericPredicates::query_all(db, def); + let clauses = + rustc_type_ir::elaborate::elaborate(interner, predicates.iter_identity_copied()); + let clauses = Clauses::new_from_iter(interner, clauses); - // FIXME: We should normalize projections here, like rustc does. - ParamEnv { clauses } + // FIXME: We should normalize projections here, like rustc does. + clauses.store() + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -1773,12 +1877,12 @@ pub(crate) enum PredicateFilter { /// Resolve the where clause(s) of an item with generics, /// with a given filter #[tracing::instrument(skip(db, filter), ret)] -pub(crate) fn generic_predicates_filtered_by<'db, F>( - db: &'db dyn HirDatabase, +pub(crate) fn generic_predicates_filtered_by<F>( + db: &dyn HirDatabase, def: GenericDefId, predicate_filter: PredicateFilter, filter: F, -) -> (GenericPredicates<'db>, Diagnostics) +) -> (GenericPredicates, Diagnostics) where F: Fn(GenericDefId) -> bool, { @@ -1852,7 +1956,7 @@ where let trait_ref = TraitRef::new_from_args( interner, sized_trait.into(), - GenericArgs::new_from_iter(interner, [param_ty.into()]), + GenericArgs::new_from_slice(&[param_ty.into()]), ); let clause = Clause(Predicate::new( interner, @@ -1895,7 +1999,7 @@ where own_predicates_start, is_trait, parent_is_trait, - predicates: EarlyBinder::bind(predicates.into_boxed_slice()), + predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()), }; return (predicates, diagnostics); @@ -1984,7 +2088,7 @@ fn implicitly_sized_clauses<'a, 'subst, 'db>( let trait_ref = TraitRef::new_from_args( interner, sized_trait.into(), - GenericArgs::new_from_iter(interner, [self_ty.into()]), + GenericArgs::new_from_slice(&[self_ty.into()]), ); Clause(Predicate::new( interner, @@ -2000,19 +2104,16 @@ fn implicitly_sized_clauses<'a, 'subst, 'db>( } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct GenericDefaults<'db>(Option<Arc<[Option<EarlyBinder<'db, GenericArg<'db>>>]>>); +pub struct GenericDefaults(Option<Arc<[Option<StoredEarlyBinder<StoredGenericArg>>]>>); -impl<'db> GenericDefaults<'db> { +impl GenericDefaults { #[inline] - pub fn get(&self, idx: usize) -> Option<EarlyBinder<'db, GenericArg<'db>>> { - self.0.as_ref()?[idx] + pub fn get<'db>(&self, idx: usize) -> Option<EarlyBinder<'db, GenericArg<'db>>> { + Some(self.0.as_ref()?[idx].as_ref()?.get_with(|it| it.as_ref())) } } -pub(crate) fn generic_defaults_query( - db: &dyn HirDatabase, - def: GenericDefId, -) -> GenericDefaults<'_> { +pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaults { db.generic_defaults_with_diagnostics(def).0 } @@ -2022,7 +2123,7 @@ pub(crate) fn generic_defaults_query( pub(crate) fn generic_defaults_with_diagnostics_query( db: &dyn HirDatabase, def: GenericDefId, -) -> (GenericDefaults<'_>, Diagnostics) { +) -> (GenericDefaults, Diagnostics) { let generic_params = generics(db, def); if generic_params.is_empty() { return (GenericDefaults(None), None); @@ -2068,20 +2169,23 @@ pub(crate) fn generic_defaults_with_diagnostics_query( ctx: &mut TyLoweringContext<'db, '_>, idx: usize, p: GenericParamDataRef<'_>, - ) -> (Option<EarlyBinder<'db, GenericArg<'db>>>, bool) { + ) -> (Option<StoredEarlyBinder<StoredGenericArg>>, bool) { ctx.lowering_param_default(idx as u32); match p { GenericParamDataRef::TypeParamData(p) => { let ty = p.default.map(|ty| ctx.lower_ty(ty)); - (ty.map(|ty| EarlyBinder::bind(ty.into())), p.default.is_some()) + ( + ty.map(|ty| StoredEarlyBinder::bind(GenericArg::from(ty).store())), + p.default.is_some(), + ) } GenericParamDataRef::ConstParamData(p) => { let val = p.default.map(|c| { let param_ty = ctx.lower_ty(p.ty); let c = ctx.lower_const(c, param_ty); - c.into() + GenericArg::from(c).store() }); - (val.map(EarlyBinder::bind), p.default.is_some()) + (val.map(StoredEarlyBinder::bind), p.default.is_some()) } GenericParamDataRef::LifetimeParamData(_) => (None, false), } @@ -2090,27 +2194,33 @@ pub(crate) fn generic_defaults_with_diagnostics_query( pub(crate) fn generic_defaults_with_diagnostics_cycle_result( _db: &dyn HirDatabase, + _: salsa::Id, _def: GenericDefId, -) -> (GenericDefaults<'_>, Diagnostics) { +) -> (GenericDefaults, Diagnostics) { (GenericDefaults(None), None) } /// Build the signature of a callable item (function, struct or enum variant). -pub(crate) fn callable_item_signature_query<'db>( +pub(crate) fn callable_item_signature<'db>( db: &'db dyn HirDatabase, def: CallableDefId, ) -> EarlyBinder<'db, PolyFnSig<'db>> { - match def { - CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f), - CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s), - CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), + return callable_item_signature_query(db, def).get_with(|sig| sig.get()); + + #[salsa::tracked(returns(ref))] + pub(crate) fn callable_item_signature_query<'db>( + db: &'db dyn HirDatabase, + def: CallableDefId, + ) -> StoredEarlyBinder<StoredPolyFnSig> { + match def { + CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f), + CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s), + CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e), + } } } -fn fn_sig_for_fn<'db>( - db: &'db dyn HirDatabase, - def: FunctionId, -) -> EarlyBinder<'db, PolyFnSig<'db>> { +fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<StoredPolyFnSig> { let data = db.function_signature(def); let resolver = def.resolver(db); let interner = DbInterner::new_no_crate(db); @@ -2140,56 +2250,56 @@ fn fn_sig_for_fn<'db>( let inputs_and_output = Tys::new_from_iter(interner, params.chain(Some(ret))); // If/when we track late bound vars, we need to switch this to not be `dummy` - EarlyBinder::bind(rustc_type_ir::Binder::dummy(FnSig { + StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { abi: data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), c_variadic: data.is_varargs(), safety: if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe }, inputs_and_output, - })) + }))) } -fn type_for_adt<'db>(db: &'db dyn HirDatabase, adt: AdtId) -> EarlyBinder<'db, Ty<'db>> { +fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> StoredEarlyBinder<StoredTy> { let interner = DbInterner::new_no_crate(db); let args = GenericArgs::identity_for_item(interner, adt.into()); let ty = Ty::new_adt(interner, adt, args); - EarlyBinder::bind(ty) + StoredEarlyBinder::bind(ty.store()) } -fn fn_sig_for_struct_constructor<'db>( - db: &'db dyn HirDatabase, +fn fn_sig_for_struct_constructor( + db: &dyn HirDatabase, def: StructId, -) -> EarlyBinder<'db, PolyFnSig<'db>> { +) -> StoredEarlyBinder<StoredPolyFnSig> { let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.skip_binder()); + let params = field_tys.iter().map(|(_, ty)| ty.get().skip_binder()); let ret = type_for_adt(db, def.into()).skip_binder(); let inputs_and_output = - Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret))); - EarlyBinder::bind(Binder::dummy(FnSig { + Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret.as_ref()))); + StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { abi: FnAbi::RustCall, c_variadic: false, safety: Safety::Safe, inputs_and_output, - })) + }))) } -fn fn_sig_for_enum_variant_constructor<'db>( - db: &'db dyn HirDatabase, +fn fn_sig_for_enum_variant_constructor( + db: &dyn HirDatabase, def: EnumVariantId, -) -> EarlyBinder<'db, PolyFnSig<'db>> { +) -> StoredEarlyBinder<StoredPolyFnSig> { let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.skip_binder()); + let params = field_tys.iter().map(|(_, ty)| ty.get().skip_binder()); let parent = def.lookup(db).parent; let ret = type_for_adt(db, parent.into()).skip_binder(); let inputs_and_output = - Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret))); - EarlyBinder::bind(Binder::dummy(FnSig { + Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret.as_ref()))); + StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { abi: FnAbi::RustCall, c_variadic: false, safety: Safety::Safe, inputs_and_output, - })) + }))) } // FIXME(next-solver): should merge this with `explicit_item_bounds` in some way @@ -2226,10 +2336,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( Some(ExistentialPredicate::Trait(ExistentialTraitRef::new_from_args( interner, t.def_id(), - GenericArgs::new_from_iter( - interner, - t.trait_ref.args.iter().skip(1), - ), + GenericArgs::new_from_slice(&t.trait_ref.args[1..]), ))) } } @@ -2237,10 +2344,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( ExistentialPredicate::Projection(ExistentialProjection::new_from_args( interner, p.def_id(), - GenericArgs::new_from_iter( - interner, - p.projection_term.args.iter().skip(1), - ), + GenericArgs::new_from_slice(&p.projection_term.args[1..]), p.term, )), ), @@ -2270,7 +2374,7 @@ pub(crate) fn associated_ty_item_bounds<'db>( bounds.push(sized_clause); } - EarlyBinder::bind(BoundExistentialPredicates::new_from_iter(interner, bounds)) + EarlyBinder::bind(BoundExistentialPredicates::new_from_slice(&bounds)) } pub(crate) fn associated_type_by_name_including_super_traits<'db>( @@ -2336,7 +2440,7 @@ fn named_associated_type_shorthand_candidates<'db, R>( if let Some(alias) = check_trait(trait_ref) { return Some(alias); } - for pred in generic_predicates_filtered_by( + let predicates = generic_predicates_filtered_by( db, GenericDefId::TraitId(trait_ref.def_id.0), PredicateFilter::SelfTrait, @@ -2347,9 +2451,8 @@ fn named_associated_type_shorthand_candidates<'db, R>( |pred| pred != def && pred == GenericDefId::TraitId(trait_ref.def_id.0), ) .0 - .predicates - .instantiate_identity() - { + .predicates; + for pred in predicates.get().instantiate_identity() { tracing::debug!(?pred); let sup_trait_ref = match pred.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(pred) => pred.trait_ref, @@ -2396,8 +2499,8 @@ fn named_associated_type_shorthand_candidates<'db, R>( let predicates = generic_predicates_for_param(db, def, param_id.into(), assoc_name.clone()); predicates - .as_ref() - .iter_identity_copied() + .get() + .iter_identity() .find_map(|pred| match pred.kind().skip_binder() { rustc_type_ir::ClauseKind::Trait(trait_predicate) => Some(trait_predicate), _ => None, |