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 | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 985a3ddc6a..a997ee5975 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -64,9 +64,9 @@ use crate::{ AliasTy, Binder, BoundExistentialPredicates, Clause, ClauseKind, Clauses, Const, ConstKind, DbInterner, DefaultAny, EarlyBinder, EarlyParamRegion, ErrorGuaranteed, FnSigKind, FxIndexMap, GenericArg, GenericArgs, ParamConst, ParamEnv, PatList, Pattern, PolyFnSig, - Predicate, Region, StoredClauses, StoredEarlyBinder, StoredGenericArg, StoredGenericArgs, - StoredPolyFnSig, StoredTraitRef, StoredTy, TraitPredicate, TraitRef, Ty, Tys, Unnormalized, - abi::Safety, util::BottomUpFolder, + Predicate, Region, StoredClauses, StoredConst, StoredEarlyBinder, StoredGenericArg, + StoredGenericArgs, StoredPolyFnSig, StoredTraitRef, StoredTy, TraitPredicate, TraitRef, Ty, + Tys, Unnormalized, abi::Safety, util::BottomUpFolder, }, }; @@ -1703,16 +1703,34 @@ fn const_param_types_with_diagnostics_cycle_result( pub(crate) fn field_types_query( db: &dyn HirDatabase, variant_id: VariantId, -) -> &ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>> { +) -> &ArenaMap<LocalFieldId, FieldType> { &field_types_with_diagnostics(db, variant_id).value } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FieldType { + ty: StoredEarlyBinder<StoredTy>, + default: Option<StoredEarlyBinder<StoredConst>>, +} + +impl FieldType { + #[inline] + pub fn ty<'db>(&self) -> EarlyBinder<'db, Ty<'db>> { + self.ty.get() + } + + #[inline] + pub fn default<'db>(&self) -> Option<EarlyBinder<'db, Const<'db>>> { + self.default.as_ref().map(|default| default.get_with(|it| it.as_ref())) + } +} + /// Build the type of all specific fields of a struct or enum variant. #[salsa::tracked(returns(ref))] pub(crate) fn field_types_with_diagnostics( db: &dyn HirDatabase, variant_id: VariantId, -) -> TyLoweringResult<ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>> { +) -> TyLoweringResult<ArenaMap<LocalFieldId, FieldType>> { let var_data = variant_id.fields(db); let fields = var_data.fields(); if fields.is_empty() { @@ -1736,7 +1754,15 @@ pub(crate) fn field_types_with_diagnostics( LifetimeElisionKind::AnonymousReportError, ); for (field_id, field_data) in var_data.fields().iter() { - res.insert(field_id, StoredEarlyBinder::bind(ctx.lower_ty(field_data.type_ref).store())); + let ty = ctx.lower_ty(field_data.type_ref); + let default = field_data.default_value.map(|default| ctx.lower_const(default, ty)); + res.insert( + field_id, + FieldType { + ty: StoredEarlyBinder::bind(ty.store()), + default: default.map(|default| StoredEarlyBinder::bind(default.store())), + }, + ); } TyLoweringResult::from_ctx(res, ctx) } @@ -2637,7 +2663,7 @@ fn fn_sig_for_struct_constructor( def: StructId, ) -> StoredEarlyBinder<StoredPolyFnSig> { let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.get().skip_binder()); + let params = field_tys.iter().map(|(_, field)| field.ty().skip_binder()); let ret = type_for_adt(db, def.into()).skip_binder(); let inputs_and_output = @@ -2653,7 +2679,7 @@ fn fn_sig_for_enum_variant_constructor( def: EnumVariantId, ) -> StoredEarlyBinder<StoredPolyFnSig> { let field_tys = db.field_types(def.into()); - let params = field_tys.iter().map(|(_, ty)| ty.get().skip_binder()); + let params = field_tys.iter().map(|(_, field)| field.ty().skip_binder()); let parent = def.lookup(db).parent; let ret = type_for_adt(db, parent.into()).skip_binder(); |