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 | 443 |
1 files changed, 25 insertions, 418 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 4d5172fd4f..0c197b2703 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -24,19 +24,18 @@ use chalk_ir::{ use either::Either; use hir_def::{ - AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, - FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LocalFieldId, - Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, UnionId, VariantId, + AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, + GenericParamId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId, + TypeOrConstParamId, UnionId, VariantId, builtin_type::BuiltinType, expr_store::{ExpressionStore, path::Path}, hir::generics::{GenericParamDataRef, TypeOrConstParamData, WherePredicate}, - item_tree::FieldsShape, lang_item::LangItem, resolver::{HasResolver, LifetimeNs, Resolver, TypeNs}, - signatures::{FunctionSignature, TraitFlags, TypeAliasFlags}, + signatures::{FunctionSignature, TraitFlags}, type_ref::{ - ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier, - TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId, + ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier, TypeBound, TypeRef, + TypeRefId, }, }; use hir_expand::name::Name; @@ -46,11 +45,10 @@ use stdx::{impl_from, never}; use triomphe::{Arc, ThinArc}; use crate::{ - AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DomainGoal, DynTy, FnAbi, - FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, - LifetimeData, LifetimeOutlives, PolyFnSig, QuantifiedWhereClause, QuantifiedWhereClauses, - Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, - all_super_traits, + AliasTy, Binders, BoundVar, Const, DebruijnIndex, DynTy, FnAbi, FnPointer, FnSig, FnSubst, + ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime, LifetimeData, LifetimeOutlives, + QuantifiedWhereClause, QuantifiedWhereClauses, Substitution, TraitRef, TraitRefExt, Ty, + TyBuilder, TyKind, WhereClause, all_super_traits, consteval::{intern_const_ref, path_to_const, unknown_const, unknown_const_as_generic}, db::HirDatabase, error_lifetime, @@ -60,7 +58,11 @@ use crate::{ path::{PathDiagnosticCallback, PathLoweringContext}, }, make_binders, - mapping::{ToChalk, from_chalk_trait_id, lt_to_placeholder_idx}, + mapping::{from_chalk_trait_id, lt_to_placeholder_idx}, + next_solver::{ + DbInterner, + mapping::{ChalkToNextSolver, NextSolverToChalk}, + }, static_lifetime, to_chalk_trait_id, to_placeholder_idx, utils::all_super_trait_refs, variable_kinds_from_iter, @@ -567,14 +569,6 @@ impl<'a> TyLoweringContext<'a> { Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty, false), ctx)) } - fn lower_trait_ref( - &mut self, - trait_ref: &HirTraitRef, - explicit_self_ty: Ty, - ) -> Option<TraitRef> { - self.lower_trait_ref_from_path(trait_ref.path, explicit_self_ty).map(|it| it.0) - } - /// When lowering predicates from parents (impl, traits) for children defs (fns, consts, types), `generics` should /// contain the `Generics` for the **child**, while `predicate_owner` should contain the `GenericDefId` of the /// **parent**. This is important so we generate the correct bound var/placeholder. @@ -826,15 +820,6 @@ impl<'a> TyLoweringContext<'a> { } } -/// Build the signature of a callable item (function, struct or enum variant). -pub(crate) fn callable_item_signature_query(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig { - 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 named_associated_type_shorthand_candidates<R>( db: &dyn HirDatabase, // If the type parameter is defined in an impl and we're in a method, there @@ -862,21 +847,21 @@ fn named_associated_type_shorthand_candidates<R>( }) }; + let interner = DbInterner::new_with(db, None, None); match res { TypeNs::SelfType(impl_id) => { - // we're _in_ the impl -- the binders get added back later. Correct, - // but it would be nice to make this more explicit - let trait_ref = db.impl_trait(impl_id)?.into_value_and_skipped_binders().0; + let trait_ref = db.impl_trait(impl_id)?; let impl_id_as_generic_def: GenericDefId = impl_id.into(); if impl_id_as_generic_def != def { let subst = TyBuilder::subst_for_def(db, impl_id, None) .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) .build(); - let trait_ref = subst.apply(trait_ref, Interner); + let args: crate::next_solver::GenericArgs<'_> = subst.to_nextsolver(interner); + let trait_ref = trait_ref.instantiate(interner, args).to_chalk(interner); search(trait_ref) } else { - search(trait_ref) + search(trait_ref.skip_binder().to_chalk(interner)) } } TypeNs::GenericParam(param_id) => { @@ -919,7 +904,7 @@ pub(crate) fn field_types_query( db: &dyn HirDatabase, variant_id: VariantId, ) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> { - db.field_types_with_diagnostics(variant_id).0 + field_types_with_diagnostics_query(db, variant_id).0 } /// Build the type of all specific fields of a struct or enum variant. @@ -1086,102 +1071,6 @@ pub(crate) fn generic_predicates_for_param_cycle_result( GenericPredicates(None) } -pub(crate) fn trait_environment_for_body_query( - db: &dyn HirDatabase, - def: DefWithBodyId, -) -> Arc<TraitEnvironment> { - let Some(def) = def.as_generic_def_id(db) else { - let krate = def.module(db).krate(); - return TraitEnvironment::empty(krate); - }; - db.trait_environment(def) -} - -pub(crate) fn trait_environment_query( - db: &dyn HirDatabase, - def: GenericDefId, -) -> Arc<TraitEnvironment> { - let generics = generics(db, def); - if generics.has_no_predicates() && generics.is_empty() { - return TraitEnvironment::empty(def.krate(db)); - } - - let resolver = def.resolver(db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - generics.store(), - def, - LifetimeElisionKind::AnonymousReportError, - ) - .with_type_param_mode(ParamLoweringMode::Placeholder); - let mut traits_in_scope = Vec::new(); - let mut clauses = Vec::new(); - for maybe_parent_generics in - std::iter::successors(Some(&generics), |generics| generics.parent_generics()) - { - ctx.store = maybe_parent_generics.store(); - for pred in maybe_parent_generics.where_predicates() { - for pred in ctx.lower_where_predicate(pred, false) { - if let WhereClause::Implemented(tr) = pred.skip_binders() { - traits_in_scope - .push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id())); - } - let program_clause: Binders<DomainGoal> = - pred.map(|pred| pred.into_from_env_goal(Interner).cast(Interner)); - clauses.push(program_clause); - } - } - } - - if let Some(trait_id) = def.assoc_trait_container(db) { - // add `Self: Trait<T1, T2, ...>` to the environment in trait - // function default implementations (and speculative code - // inside consts or type aliases) - cov_mark::hit!(trait_self_implements_self); - let substs = TyBuilder::placeholder_subst(db, trait_id); - let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; - let pred = WhereClause::Implemented(trait_ref); - clauses.push(Binders::empty( - Interner, - pred.cast::<DomainGoal>(Interner).into_from_env_goal(Interner), - )); - } - - let subst = generics.placeholder_subst(db); - if !subst.is_empty(Interner) { - let explicitly_unsized_tys = ctx.unsized_types; - if let Some(implicitly_sized_clauses) = - implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver) - { - clauses.extend(implicitly_sized_clauses.map(|pred| { - Binders::empty( - Interner, - pred.into_from_env_goal(Interner).cast::<DomainGoal>(Interner), - ) - })); - }; - } - - let clauses = chalk_ir::ProgramClauses::from_iter( - Interner, - clauses.into_iter().map(|g| { - chalk_ir::ProgramClause::new( - Interner, - chalk_ir::ProgramClauseData(g.map(|g| chalk_ir::ProgramClauseImplication { - consequence: g, - conditions: chalk_ir::Goals::empty(Interner), - constraints: chalk_ir::Constraints::empty(Interner), - priority: chalk_ir::ClausePriority::High, - })), - ) - }), - ); - let env = chalk_ir::Environment { clauses }; - - TraitEnvironment::new(resolver.krate(), None, traits_in_scope.into_boxed_slice(), env) -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>); @@ -1410,208 +1299,6 @@ pub(crate) fn generic_defaults_with_diagnostics_cycle_result( (GenericDefaults(None), None) } -fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { - let data = db.function_signature(def); - let resolver = def.resolver(db); - let mut ctx_params = TyLoweringContext::new( - db, - &resolver, - &data.store, - def.into(), - LifetimeElisionKind::for_fn_params(&data), - ) - .with_type_param_mode(ParamLoweringMode::Variable); - let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr)); - - let ret = match data.ret_type { - Some(ret_type) => { - let mut ctx_ret = TyLoweringContext::new( - db, - &resolver, - &data.store, - def.into(), - LifetimeElisionKind::for_fn_ret(), - ) - .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) - .with_type_param_mode(ParamLoweringMode::Variable); - ctx_ret.lower_ty(ret_type) - } - None => TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner), - }; - let generics = generics(db, def.into()); - let sig = CallableSig::from_params_and_return( - params, - ret, - data.is_varargs(), - if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe }, - data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), - ); - make_binders(db, &generics, sig) -} - -/// Build the declared type of a function. This should not need to look at the -/// function body. -fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { - let generics = generics(db, def.into()); - let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST); - make_binders( - db, - &generics, - TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner), - ) -} - -/// Build the declared type of a const. -fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> { - let data = db.const_signature(def); - let generics = generics(db, def.into()); - let resolver = def.resolver(db); - let parent = def.loc(db).container; - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &data.store, - def.into(), - LifetimeElisionKind::for_const(parent), - ) - .with_type_param_mode(ParamLoweringMode::Variable); - - make_binders(db, &generics, ctx.lower_ty(data.type_ref)) -} - -/// Build the declared type of a static. -fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> { - let data = db.static_signature(def); - let resolver = def.resolver(db); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &data.store, - def.into(), - LifetimeElisionKind::Elided(static_lifetime()), - ); - - Binders::empty(Interner, ctx.lower_ty(data.type_ref)) -} - -fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { - let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.skip_binders().clone()); - let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders(); - Binders::new( - binders, - CallableSig::from_params_and_return(params, ret, false, Safety::Safe, FnAbi::RustCall), - ) -} - -/// Build the type of a tuple struct constructor. -fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> { - 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 generics = generics(db, AdtId::from(def).into()); - let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST); - Some(make_binders( - db, - &generics, - TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner), - )) - } - } -} - -fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { - let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.skip_binders().clone()); - let parent = def.lookup(db).parent; - let (ret, binders) = type_for_adt(db, parent.into()).into_value_and_skipped_binders(); - Binders::new( - binders, - CallableSig::from_params_and_return(params, ret, false, Safety::Safe, FnAbi::RustCall), - ) -} - -/// Build the type of a tuple enum variant constructor. -fn type_for_enum_variant_constructor( - db: &dyn HirDatabase, - def: EnumVariantId, -) -> Option<Binders<Ty>> { - let e = def.lookup(db).parent; - match def.fields(db).shape { - FieldsShape::Record => None, - FieldsShape::Unit => Some(type_for_adt(db, e.into())), - FieldsShape::Tuple => { - let generics = generics(db, e.into()); - let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST); - Some(make_binders( - db, - &generics, - TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs) - .intern(Interner), - )) - } - } -} - -#[salsa_macros::tracked(cycle_result = type_for_adt_cycle_result)] -fn type_for_adt_tracked(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { - type_for_adt(db, adt) -} - -fn type_for_adt_cycle_result(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { - let generics = generics(db, adt.into()); - make_binders(db, &generics, TyKind::Error.intern(Interner)) -} - -fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { - let generics = generics(db, adt.into()); - let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST); - let ty = TyKind::Adt(crate::AdtId(adt), subst).intern(Interner); - make_binders(db, &generics, ty) -} - -pub(crate) fn type_for_type_alias_with_diagnostics_query( - db: &dyn HirDatabase, - t: TypeAliasId, -) -> (Binders<Ty>, Diagnostics) { - let generics = generics(db, t.into()); - let type_alias_data = db.type_alias_signature(t); - let mut diags = None; - let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) { - TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner) - } else { - let resolver = t.resolver(db); - let alias = db.type_alias_signature(t); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &alias.store, - t.into(), - LifetimeElisionKind::AnonymousReportError, - ) - .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) - .with_type_param_mode(ParamLoweringMode::Variable); - let res = alias - .ty - .map(|type_ref| ctx.lower_ty(type_ref)) - .unwrap_or_else(|| TyKind::Error.intern(Interner)); - diags = create_diagnostics(ctx.diagnostics); - res - }; - - (make_binders(db, &generics, inner), diags) -} - -pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result( - db: &dyn HirDatabase, - adt: TypeAliasId, -) -> (Binders<Ty>, Diagnostics) { - let generics = generics(db, adt.into()); - (make_binders(db, &generics, TyKind::Error.intern(Interner)), None) -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum TyDefId { BuiltinType(BuiltinType), @@ -1644,64 +1331,8 @@ impl ValueTyDefId { } } -/// Build the declared type of an item. This depends on the namespace; e.g. for -/// `struct Foo(usize)`, we have two types: The type of the struct itself, and -/// the constructor function `(usize) -> Foo` which lives in the values -/// namespace. -pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { - match def { - TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)), - TyDefId::AdtId(it) => type_for_adt_tracked(db, it), - TyDefId::TypeAliasId(it) => db.type_for_type_alias_with_diagnostics(it).0, - } -} - -pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Option<Binders<Ty>> { - 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 impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> { - db.impl_self_ty_with_diagnostics(impl_id).0 -} - -pub(crate) fn impl_self_ty_with_diagnostics_query( - db: &dyn HirDatabase, - impl_id: ImplId, -) -> (Binders<Ty>, Diagnostics) { - let impl_data = db.impl_signature(impl_id); - let resolver = impl_id.resolver(db); - let generics = generics(db, impl_id.into()); - let mut ctx = TyLoweringContext::new( - db, - &resolver, - &impl_data.store, - impl_id.into(), - LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, - ) - .with_type_param_mode(ParamLoweringMode::Variable); - ( - make_binders(db, &generics, ctx.lower_ty(impl_data.self_ty)), - create_diagnostics(ctx.diagnostics), - ) -} - -pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( - db: &dyn HirDatabase, - impl_id: ImplId, -) -> (Binders<Ty>, Diagnostics) { - let generics = generics(db, impl_id.into()); - (make_binders(db, &generics, TyKind::Error.intern(Interner)), None) -} - pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { - db.const_param_ty_with_diagnostics(def).0 + const_param_ty_with_diagnostics_query(db, def).0 } // returns None if def is a type arg @@ -1729,36 +1360,12 @@ pub(crate) fn const_param_ty_with_diagnostics_query( (ty, create_diagnostics(ctx.diagnostics)) } -pub(crate) fn const_param_ty_with_diagnostics_cycle_result( +pub(crate) fn const_param_ty_cycle_result( _: &dyn HirDatabase, _: crate::db::HirDatabaseData, _: ConstParamId, -) -> (Ty, Diagnostics) { - (TyKind::Error.intern(Interner), None) -} - -pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { - db.impl_trait_with_diagnostics(impl_id).map(|it| it.0) -} - -pub(crate) fn impl_trait_with_diagnostics_query( - db: &dyn HirDatabase, - impl_id: ImplId, -) -> Option<(Binders<TraitRef>, 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 }, - ) - .with_type_param_mode(ParamLoweringMode::Variable); - let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders(); - let target_trait = impl_data.target_trait.as_ref()?; - let trait_ref = Binders::new(binders, ctx.lower_trait_ref(target_trait, self_ty)?); - Some((trait_ref, create_diagnostics(ctx.diagnostics))) +) -> Ty { + TyKind::Error.intern(Interner) } pub(crate) fn return_type_impl_traits( |