Unnamed repository; edit this file 'description' to name the repository.
Lowe field defaults to `rustc_type_ir::Const`s
This is needed so that IDE features can find their anon consts and work with them. We lower them in `field_types()`, which seemed appropriate (we need to know the type for the const, and creating another query doesn't seem worth it).
We'll also need them for const eval, but currently default expressions are not handled in MIR.
24 files changed, 119 insertions, 80 deletions
diff --git a/crates/hir-ty/src/builtin_derive.rs b/crates/hir-ty/src/builtin_derive.rs index 928e3da6e8..65a910555d 100644 --- a/crates/hir-ty/src/builtin_derive.rs +++ b/crates/hir-ty/src/builtin_derive.rs @@ -17,12 +17,11 @@ use rustc_type_ir::{ }; use crate::{ - GenericPredicates, + FieldType, GenericPredicates, db::HirDatabase, next_solver::{ AliasTy, Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, ParamEnv, - StoredEarlyBinder, StoredTy, TraitRef, Ty, TyKind, Unnormalized, fold::fold_tys, - generics::Generics, + StoredEarlyBinder, TraitRef, Ty, TyKind, Unnormalized, fold::fold_tys, generics::Generics, }, }; @@ -333,7 +332,7 @@ fn simple_trait_predicates<'db>( fn extend_assoc_type_bounds<'db>( interner: DbInterner<'db>, assoc_type_bounds: &mut Vec<Clause<'db>>, - fields: &ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>, + fields: &ArenaMap<LocalFieldId, FieldType>, trait_id: TraitId, trait_: BuiltinDeriveImplTrait, ) { @@ -365,7 +364,7 @@ fn extend_assoc_type_bounds<'db>( let mut visitor = ProjectionFinder { interner, assoc_type_bounds, trait_id, trait_ }; for (_, field) in fields.iter() { - field.get().instantiate_identity().skip_norm_wip().visit_with(&mut visitor); + field.ty().instantiate_identity().skip_norm_wip().visit_with(&mut visitor); } } diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 511ab85610..b8752e32c8 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -22,8 +22,8 @@ use stdx::impl_from; use triomphe::Arc; use crate::{ - GenericDefaultsRef, GenericPredicates, ImplTraitId, InferBodyId, TyDefId, TyLoweringResult, - ValueTyDefId, + FieldType, GenericDefaultsRef, GenericPredicates, ImplTraitId, InferBodyId, TyDefId, + TyLoweringResult, ValueTyDefId, consteval::ConstEvalError, dyn_compatibility::DynCompatibilityViolation, layout::{Layout, LayoutError}, @@ -225,11 +225,11 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { fn field_types_with_diagnostics( &self, var: VariantId, - ) -> &TyLoweringResult<ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>>; + ) -> &TyLoweringResult<ArenaMap<LocalFieldId, FieldType>>; #[salsa::invoke(crate::lower::field_types_query)] #[salsa::transparent] - fn field_types(&self, var: VariantId) -> &ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>; + fn field_types(&self, var: VariantId) -> &ArenaMap<LocalFieldId, FieldType>; #[salsa::invoke(crate::lower::callable_item_signature)] #[salsa::transparent] diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 984ac1abfb..5994ca2f14 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -148,7 +148,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> { let fields_len = variant.fields(self.db).fields().len() as u32; (0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).map(move |fid| { - let ty = field_tys[fid].get().instantiate(self.infcx.interner, substs).skip_norm_wip(); + let ty = field_tys[fid].ty().instantiate(self.infcx.interner, substs).skip_norm_wip(); let ty = self .infcx .at(&ObligationCause::dummy(), self.env) diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 8edb178cd7..ab290aa57a 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -51,7 +51,7 @@ use span::Edition; use stdx::never; use crate::{ - CallableDefId, ImplTraitId, MemoryMap, ParamEnvAndCrate, consteval, + CallableDefId, FieldType, ImplTraitId, MemoryMap, ParamEnvAndCrate, consteval, db::{GeneralConstId, HirDatabase}, generics::{ProvenanceSplit, generics}, layout::Layout, @@ -60,8 +60,8 @@ use crate::{ next_solver::{ AliasTy, Allocation, Clause, ClauseKind, Const, ConstKind, DbInterner, ExistentialPredicate, FnSig, GenericArg, GenericArgKind, GenericArgs, ParamEnv, PolyFnSig, - Region, StoredEarlyBinder, StoredTy, Term, TermId, TermKind, TraitPredicate, TraitRef, Ty, - TyKind, TypingMode, Unnormalized, ValTree, + Region, Term, TermId, TermKind, TraitPredicate, TraitRef, Ty, TyKind, TypingMode, + Unnormalized, ValTree, abi::Safety, infer::{DbInternerInferExt, traits::ObligationCause}, }, @@ -1198,7 +1198,7 @@ fn render_const_scalar_from_valtree_inner<'db>( fn render_variant_after_name<'db>( data: &VariantFields, f: &mut HirFormatter<'_, 'db>, - field_types: &'db ArenaMap<LocalFieldId, StoredEarlyBinder<StoredTy>>, + field_types: &'db ArenaMap<LocalFieldId, FieldType>, param_env: ParamEnv<'db>, layout: &Layout, args: GenericArgs<'db>, @@ -1210,7 +1210,7 @@ fn render_variant_after_name<'db>( FieldsShape::Record | FieldsShape::Tuple => { let render_field = |f: &mut HirFormatter<'_, 'db>, id: LocalFieldId| { let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize(); - let ty = field_types[id].get().instantiate(f.interner, args).skip_norm_wip(); + let ty = field_types[id].ty().instantiate(f.interner, args).skip_norm_wip(); let Ok(layout) = f.db.layout_of_ty(ty.store(), param_env.store()) else { return f.write_str("<layout-error>"); }; diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs index e1fbc85960..08860e1e45 100644 --- a/crates/hir-ty/src/drop.rs +++ b/crates/hir-ty/src/drop.rs @@ -83,10 +83,10 @@ fn has_drop_glue_impl<'db>( } db.field_types(id.into()) .iter() - .map(|(_, field_ty)| { + .map(|(_, field)| { has_drop_glue_impl( infcx, - field_ty.get().instantiate(infcx.interner, subst).skip_norm_wip(), + field.ty().instantiate(infcx.interner, subst).skip_norm_wip(), env, visited, ) @@ -103,13 +103,10 @@ fn has_drop_glue_impl<'db>( .map(|&(variant, _)| { db.field_types(variant.into()) .iter() - .map(|(_, field_ty)| { + .map(|(_, field)| { has_drop_glue_impl( infcx, - field_ty - .get() - .instantiate(infcx.interner, subst) - .skip_norm_wip(), + field.ty().instantiate(infcx.interner, subst).skip_norm_wip(), env, visited, ) diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 2df2789a2e..0a6e2635bb 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -2046,7 +2046,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { .field_types(struct_id.into()) .values() .next_back() - .map(|it| it.get()) + .map(|it| it.ty()) { Some(field) => { ty = field.instantiate(self.interner(), substs).skip_norm_wip(); diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs index 93aed344d4..da996ccbea 100644 --- a/crates/hir-ty/src/infer/cast.rs +++ b/crates/hir-ty/src/infer/cast.rs @@ -541,7 +541,7 @@ fn pointer_kind<'db>( let struct_data = id.fields(ctx.db); if let Some((last_field, _)) = struct_data.fields().iter().last() { let last_field_ty = ctx.db.field_types(id.into())[last_field] - .get() + .ty() .instantiate(ctx.interner(), subst) .skip_norm_wip(); pointer_kind(expr, last_field_ty, ctx) diff --git a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs index 025d4c138d..34f9508e76 100644 --- a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs +++ b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs @@ -774,7 +774,7 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> { with_expr.into(), with_place.clone(), adt_field_types[f_index] - .get() + .ty() .instantiate(self.cx.interner(), args) .skip_norm_wip(), ProjectionKind::Field { diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 4903a15a08..5f752da3d0 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -1061,14 +1061,14 @@ impl<'db> InferenceContext<'_, 'db> { }); } - variant_field_tys[i].get().instantiate(interner, args).skip_norm_wip() + variant_field_tys[i].ty().instantiate(interner, args).skip_norm_wip() } else { if let Some(field_idx) = seen_fields.get(&name) { self.push_diagnostic(InferenceDiagnostic::DuplicateField { field: field.expr.into(), variant, }); - variant_field_tys[*field_idx].get().instantiate(interner, args).skip_norm_wip() + variant_field_tys[*field_idx].ty().instantiate(interner, args).skip_norm_wip() } else { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: field.expr.into(), @@ -1124,12 +1124,12 @@ impl<'db> InferenceContext<'_, 'db> { // type we expect from the expectation value. for (field_idx, field) in variant_fields.fields().iter() { let fru_ty = variant_field_tys[field_idx] - .get() + .ty() .instantiate(interner, fresh_args) .skip_norm_wip(); if remaining_fields.remove(&field.name).is_some() { let target_ty = variant_field_tys[field_idx] - .get() + .ty() .instantiate(interner, args) .skip_norm_wip(); let cause = ObligationCause::new(expr); @@ -1684,7 +1684,7 @@ impl<'db> InferenceContext<'_, 'db> { return None; } let ty = self.db.field_types(field_id.parent)[field_id.local_id] - .get() + .ty() .instantiate(interner, parameters) .skip_norm_wip(); Some((Either::Left(field_id), ty)) @@ -1703,7 +1703,7 @@ impl<'db> InferenceContext<'_, 'db> { let adjustments = self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok()); let ty = self.db.field_types(field_id.parent)[field_id.local_id] - .get() + .ty() .instantiate(self.interner(), subst) .skip_norm_wip(); let ty = self.process_remote_user_written_ty(ty); diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index c36c29d6c7..915da943ca 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs @@ -1074,7 +1074,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { for (i, &subpat) in subpats.iter().enumerate_and_adjust(variant_fields.len(), ddpos) { let field_id = LocalFieldId::from_raw(la_arena::RawIdx::from_u32(i as u32)); let field_ty = - variant_field_tys[field_id].get().instantiate(interner, args).skip_norm_wip(); + variant_field_tys[field_id].ty().instantiate(interner, args).skip_norm_wip(); self.infer_pat(subpat, field_ty, pat_info); } if let Err(()) = had_err { @@ -1093,7 +1093,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { for (i, &pat) in subpats.iter().enumerate() { let field_id = LocalFieldId::from_raw(la_arena::RawIdx::from_u32(i as u32)); let expected = match variant_field_tys.get(field_id) { - Some(field_ty) => field_ty.get().instantiate(interner, args).skip_norm_wip(), + Some(field_ty) => field_ty.ty().instantiate(interner, args).skip_norm_wip(), None => self.types.types.error, }; self.infer_pat(pat, expected, pat_info); @@ -1208,7 +1208,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { }); } - variant_field_tys[field_idx].get().instantiate(interner, args).skip_norm_wip() + variant_field_tys[field_idx].ty().instantiate(interner, args).skip_norm_wip() } None => { inexistent_fields.push(field); diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs index 26253fbabf..bca91d07a7 100644 --- a/crates/hir-ty/src/inhabitedness.rs +++ b/crates/hir-ty/src/inhabitedness.rs @@ -157,7 +157,7 @@ impl<'a, 'db> UninhabitedFrom<'a, 'db> { }; for (fid, _) in fields.iter() { - self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid].get(), subst)?; + self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid].ty(), subst)?; } CONTINUE_OPAQUELY_INHABITED } diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index 59f1d6e575..ed4775539a 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -148,7 +148,7 @@ fn layout_of_simd_ty<'db>( let mut fields = fields.iter(); let Some(TyKind::Array(e_ty, e_len)) = fields.next().filter(|_| fields.next().is_none()).map(|f| { - (*f.1).get().instantiate(DbInterner::new_no_crate(db), args).skip_norm_wip().kind() + (*f.1).ty().instantiate(DbInterner::new_no_crate(db), args).skip_norm_wip().kind() }) else { return Err(LayoutError::InvalidSimdType); @@ -565,7 +565,7 @@ fn field_ty<'a>( fd: LocalFieldId, args: GenericArgs<'a>, ) -> Ty<'a> { - db.field_types(def)[fd].get().instantiate(DbInterner::new_no_crate(db), args).skip_norm_wip() + db.field_types(def)[fd].ty().instantiate(DbInterner::new_no_crate(db), args).skip_norm_wip() } fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar { diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index f612bdc266..71140ec557 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -110,9 +110,9 @@ pub use infer::{ infer_query_with_inspect, }; pub use lower::{ - GenericDefaults, GenericDefaultsRef, GenericPredicates, ImplTraits, LifetimeElisionKind, - TyDefId, TyLoweringContext, TyLoweringInferVarsCtx, TyLoweringResult, ValueTyDefId, - diagnostics::*, + FieldType, GenericDefaults, GenericDefaultsRef, GenericPredicates, ImplTraits, + LifetimeElisionKind, TyDefId, TyLoweringContext, TyLoweringInferVarsCtx, TyLoweringResult, + ValueTyDefId, diagnostics::*, }; pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db}; pub use target_feature::TargetFeatures; 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(); diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs index 7c5c0ea564..d004e3b5da 100644 --- a/crates/hir-ty/src/mir.rs +++ b/crates/hir-ty/src/mir.rs @@ -1250,7 +1250,7 @@ impl<'db> PlaceTy<'db> { match self_ty.kind() { TyKind::Adt(adt_def, args) if adt_def.is_enum() => { infcx.interner.db().field_types(variant_id)[f.to_local_field_id()] - .get() + .ty() .instantiate(infcx.interner, args) .skip_norm_wip() } @@ -1262,7 +1262,7 @@ impl<'db> PlaceTy<'db> { TyKind::Adt(adt_def, args) if !adt_def.is_enum() => { let variant_id = VariantId::from_non_enum(adt_def.def_id()).unwrap(); infcx.interner.db().field_types(variant_id)[f.to_local_field_id()] - .get() + .ty() .instantiate(infcx.interner, args) .skip_norm_wip() } diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index f0e2218cde..eb0e4c6020 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -1700,7 +1700,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { if let Some(ty) = field_types .iter() .last() - .map(|it| it.1.get().instantiate(self.interner(), subst)) + .map(|it| it.1.ty().instantiate(self.interner(), subst)) { return self.coerce_unsized_look_through_fields(ty.skip_norm_wip(), goal); } @@ -1781,11 +1781,11 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { not_supported!("unsizing struct without field"); }; let target_last_field = self.db.field_types(id.into())[last_field] - .get() + .ty() .instantiate(self.interner(), target_subst) .skip_norm_wip(); let current_last_field = self.db.field_types(id.into())[last_field] - .get() + .ty() .instantiate(self.interner(), current_subst) .skip_norm_wip(); return self.unsizing_ptr_from_addr( @@ -2427,7 +2427,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { .offset(u32::from(f.into_raw()) as usize) .bytes_usize(); let ty = field_types[f] - .get() + .ty() .instantiate(this.interner(), subst) .skip_norm_wip(); let size = this.layout(ty)?.size.bytes_usize(); @@ -2456,7 +2456,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { let offset = l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize(); let ty = field_types[f] - .get() + .ty() .instantiate(this.interner(), subst) .skip_norm_wip(); let size = this.layout(ty)?.size.bytes_usize(); @@ -2542,9 +2542,9 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { } TyKind::Adt(id, args) => match id.def_id() { AdtId::StructId(s) => { - for (i, (_, ty)) in self.db.field_types(s.into()).iter().enumerate() { + for (i, (_, field)) in self.db.field_types(s.into()).iter().enumerate() { let offset = layout.fields.offset(i).bytes_usize(); - let ty = ty.get().instantiate(self.interner(), args).skip_norm_wip(); + let ty = field.ty().instantiate(self.interner(), args).skip_norm_wip(); self.patch_addresses( patch_map, ty_of_bytes, @@ -2563,9 +2563,9 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { self.read_memory(addr, layout.size.bytes_usize())?, e, ) { - for (i, (_, ty)) in self.db.field_types(ev.into()).iter().enumerate() { + for (i, (_, field)) in self.db.field_types(ev.into()).iter().enumerate() { let offset = layout.fields.offset(i).bytes_usize(); - let ty = ty.get().instantiate(self.interner(), args).skip_norm_wip(); + let ty = field.ty().instantiate(self.interner(), args).skip_norm_wip(); self.patch_addresses( patch_map, ty_of_bytes, @@ -3080,7 +3080,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { .bytes_usize(); let addr = addr.offset(offset); let ty = field_types[field] - .get() + .ty() .instantiate(self.interner(), subst) .skip_norm_wip(); self.run_drop_glue_deep(ty, locals, addr, &[], span)?; diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index b4a5aa8a87..b59d6c1cfb 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -1369,7 +1369,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { .next_back() .unwrap() .1 - .get() + .ty() .instantiate(self.interner(), subst) .skip_norm_wip(); let sized_part_size = diff --git a/crates/hir-ty/src/mir/eval/shim/simd.rs b/crates/hir-ty/src/mir/eval/shim/simd.rs index 074c5a9c77..a9d0bee623 100644 --- a/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -20,7 +20,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> { not_supported!("simd type with no field"); }; let field_ty = self.db.field_types(id.into())[first_field] - .get() + .ty() .instantiate(self.interner(), subst) .skip_norm_wip(); return Ok((fields.len(), field_ty)); diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs index 172b1a245f..b466fe0f18 100644 --- a/crates/hir-ty/src/next_solver/interner.rs +++ b/crates/hir-ty/src/next_solver/interner.rs @@ -589,7 +589,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef { let id: VariantId = struct_id.into(); let field_types = interner.db().field_types(id); - field_types.iter().last().map(|f| f.1.get()) + field_types.iter().last().map(|f| f.1.ty()) } fn all_field_tys( @@ -599,7 +599,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef { let db = interner.db(); // FIXME: this is disabled just to match the behavior with chalk right now let _field_tys = |id: VariantId| { - db.field_types(id).iter().map(|(_, ty)| ty.get().skip_binder()).collect::<Vec<_>>() + db.field_types(id).iter().map(|(_, ty)| ty.ty().skip_binder()).collect::<Vec<_>>() }; let field_tys = |_id: VariantId| vec![]; let tys: Vec<_> = match self.def_id() { @@ -1882,7 +1882,7 @@ impl<'db> Interner for DbInterner<'db> { let field_types = self.db().field_types(variant); let mut unsizing_params = DenseBitSet::new_empty(num_params); - let ty = field_types[tail_field.0].get(); + let ty = field_types[tail_field.0].ty(); for arg in ty.instantiate_identity().skip_norm_wip().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); @@ -1892,7 +1892,7 @@ impl<'db> Interner for DbInterner<'db> { // Ensure none of the other fields mention the parameters used // in unsizing. for field in prefix_fields { - for arg in field_types[field.0].get().instantiate_identity().skip_norm_wip().walk() { + for arg in field_types[field.0].ty().instantiate_identity().skip_norm_wip().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.remove(i); } diff --git a/crates/hir-ty/src/representability.rs b/crates/hir-ty/src/representability.rs index 0ea8003e55..828af20b7b 100644 --- a/crates/hir-ty/src/representability.rs +++ b/crates/hir-ty/src/representability.rs @@ -47,7 +47,7 @@ pub(crate) fn representability_cycle( fn variant_representability(db: &dyn HirDatabase, id: VariantId) -> Representability { for ty in db.field_types(id).values() { - rtry!(representability_ty(db, ty.get().instantiate_identity().skip_norm_wip())); + rtry!(representability_ty(db, ty.ty().instantiate_identity().skip_norm_wip())); } Representability::Representable } @@ -96,7 +96,7 @@ fn params_in_repr(db: &dyn HirDatabase, def_id: AdtId) -> Box<[bool]> { for field in db.field_types(variant).values() { params_in_repr_ty( db, - field.get().instantiate_identity().skip_norm_wip(), + field.ty().instantiate_identity().skip_norm_wip(), &mut params_in_repr, ); } diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index 49dacc16eb..0a95416e42 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -126,7 +126,7 @@ impl<'db> Context<'db> { let mut add_constraints_from_variant = |variant| { for (_, field) in db.field_types(variant).iter() { self.add_constraints_from_ty( - field.get().instantiate_identity().skip_norm_wip(), + field.ty().instantiate_identity().skip_norm_wip(), Variance::Covariant, ); } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 85b87c593f..519edaea02 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1406,7 +1406,7 @@ impl Field { /// context of the field definition. pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { let var_id = self.parent.into(); - let ty = db.field_types(var_id)[self.id].get().instantiate_identity().skip_norm_wip(); + let ty = db.field_types(var_id)[self.id].ty().instantiate_identity().skip_norm_wip(); Type::new(var_id.adt_id(db).into(), ty) } @@ -5557,7 +5557,7 @@ impl<'db> Type<'db> { .iter() .map(|(idx, _)| { field_types[idx] - .get() + .ty() .instantiate(self.interner, args) .skip_norm_wip() }) @@ -5978,9 +5978,9 @@ impl<'db> Type<'db> { db.field_types(variant_id) .iter() - .map(|(local_id, ty)| { + .map(|(local_id, field)| { let def = Field { parent: variant_id.into(), id: local_id }; - let ty = ty.get().instantiate(interner, substs).skip_norm_wip(); + let ty = field.ty().instantiate(interner, substs).skip_norm_wip(); (def, self.derived(ty)) }) .collect() @@ -7454,7 +7454,7 @@ pub fn struct_tail_raw<'db>( let last_field = db.field_types(def_id.into()).iter().next_back(); match last_field { Some((_, field)) => { - ty = normalize(field.get().instantiate(interner, args).skip_norm_wip()) + ty = normalize(field.ty().instantiate(interner, args).skip_norm_wip()) } None => break, } diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 1f9520d780..6d265c460e 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -927,7 +927,7 @@ impl<'db> SourceAnalyzer<'db> { let variant_data = variant.fields(db); let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; let field_ty = (*db.field_types(variant).get(field.local_id)?) - .get() + .ty() .instantiate(interner, subst) .skip_norm_wip(); Some(( @@ -952,7 +952,7 @@ impl<'db> SourceAnalyzer<'db> { let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? }; let (adt, subst) = self.infer()?.pat_ty(pat_id.as_pat()?).as_adt()?; let field_ty = (*db.field_types(variant).get(field.local_id)?) - .get() + .ty() .instantiate(interner, subst) .skip_norm_wip(); Some(( @@ -975,9 +975,9 @@ impl<'db> SourceAnalyzer<'db> { Some( db.field_types(variant_id) .iter() - .map(|(local_id, ty)| { + .map(|(local_id, field)| { let def = Field { parent: variant_id.into(), id: local_id }; - let ty = ty.get().instantiate(interner, substs).skip_norm_wip(); + let ty = field.ty().instantiate(interner, substs).skip_norm_wip(); (def, self.ty(ty)) }) .collect(), @@ -1051,7 +1051,7 @@ impl<'db> SourceAnalyzer<'db> { let field = fields.field(&field_name.as_name())?; let field_types = db.field_types(variant); *container = Either::Right( - field_types[field].get().instantiate(interner, subst).skip_norm_wip(), + field_types[field].ty().instantiate(interner, subst).skip_norm_wip(), ); let generic_def = match variant { VariantId::EnumVariantId(it) => it.loc(db).parent.into(), @@ -1530,7 +1530,7 @@ impl<'db> SourceAnalyzer<'db> { .into_iter() .map(|local_id| { let field = FieldId { parent: variant, local_id }; - let ty = field_types[local_id].get().instantiate(interner, substs).skip_norm_wip(); + let ty = field_types[local_id].ty().instantiate(interner, substs).skip_norm_wip(); (field.into(), self.ty(ty)) }) .collect() diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 4890badcbf..991a0b6bee 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -4180,4 +4180,21 @@ fn main() { "#, ); } + + #[test] + fn ide_features_work_in_field_default() { + check( + r#" +struct S; +impl S { + fn foo(&self) {} + // ^^^ +} + +struct Struct { + field: () = S.foo$0(), +} + "#, + ); + } } |