From b1c687be4746943293530206337a11220f892d46 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 28 May 2026 23:56:36 +0300 Subject: [PATCH] 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. --- crates/hir-ty/src/builtin_derive.rs | 9 ++-- crates/hir-ty/src/db.rs | 8 ++-- .../diagnostics/match_check/pat_analysis.rs | 2 +- crates/hir-ty/src/display.rs | 10 ++--- crates/hir-ty/src/drop.rs | 11 ++--- crates/hir-ty/src/infer.rs | 2 +- crates/hir-ty/src/infer/cast.rs | 2 +- .../closure/analysis/expr_use_visitor.rs | 2 +- crates/hir-ty/src/infer/expr.rs | 12 +++--- crates/hir-ty/src/infer/pat.rs | 6 +-- crates/hir-ty/src/inhabitedness.rs | 2 +- crates/hir-ty/src/layout.rs | 4 +- crates/hir-ty/src/lib.rs | 6 +-- crates/hir-ty/src/lower.rs | 42 +++++++++++++++---- crates/hir-ty/src/mir.rs | 2 +- crates/hir-ty/src/mir/eval.rs | 20 ++++----- crates/hir-ty/src/mir/eval/shim.rs | 2 +- crates/hir-ty/src/mir/eval/shim/simd.rs | 2 +- crates/hir-ty/src/next_solver/interner.rs | 8 ++-- crates/hir-ty/src/representability.rs | 4 +- crates/hir-ty/src/variance.rs | 2 +- crates/hir/src/lib.rs | 10 ++--- crates/hir/src/source_analyzer.rs | 12 +++--- crates/ide/src/goto_definition.rs | 17 ++++++++ 24 files changed, 118 insertions(+), 79 deletions(-) diff --git a/crates/hir-ty/src/builtin_derive.rs b/crates/hir-ty/src/builtin_derive.rs index 928e3da6e8c9..65a910555d92 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>, - fields: &ArenaMap>, + fields: &ArenaMap, 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 511ab856107f..b8752e32c8b1 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>>; + ) -> &TyLoweringResult>; #[salsa::invoke(crate::lower::field_types_query)] #[salsa::transparent] - fn field_types(&self, var: VariantId) -> &ArenaMap>; + fn field_types(&self, var: VariantId) -> &ArenaMap; #[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 984ac1abfbb3..5994ca2f14fb 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 8edb178cd74f..ab290aa57a7b 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>, + field_types: &'db ArenaMap, 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(""); }; diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs index e1fbc8596089..08860e1e456c 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 2df2789a2eee..0a6e2635bb8a 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 93aed344d4f6..da996ccbea86 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 2642844e3840..724f3145927d 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 @@ -772,7 +772,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 c7562567efec..adbf03f8dd5a 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -1049,14 +1049,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(), @@ -1112,12 +1112,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); @@ -1659,7 +1659,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)) @@ -1678,7 +1678,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 c36c29d6c729..915da943ca11 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 26253fbabf1d..bca91d07a74f 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 2b0a93e61d59..538fffe24dd8 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); @@ -567,7 +567,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 f612bdc26697..71140ec557ef 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 df83b2abb870..f511b15fff07 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, }, }; @@ -1694,16 +1694,34 @@ fn const_param_types_with_diagnostics_cycle_result( pub(crate) fn field_types_query( db: &dyn HirDatabase, variant_id: VariantId, -) -> &ArenaMap> { +) -> &ArenaMap { &field_types_with_diagnostics(db, variant_id).value } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FieldType { + ty: StoredEarlyBinder, + default: Option>, +} + +impl FieldType { + #[inline] + pub fn ty<'db>(&self) -> EarlyBinder<'db, Ty<'db>> { + self.ty.get() + } + + #[inline] + pub fn default<'db>(&self) -> Option>> { + 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>> { +) -> TyLoweringResult> { let var_data = variant_id.fields(db); let fields = var_data.fields(); if fields.is_empty() { @@ -1727,7 +1745,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) } @@ -2628,7 +2654,7 @@ fn fn_sig_for_struct_constructor( def: StructId, ) -> StoredEarlyBinder { 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 = @@ -2644,7 +2670,7 @@ fn fn_sig_for_enum_variant_constructor( def: EnumVariantId, ) -> StoredEarlyBinder { 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 5f61b1defb8c..0cf7c7456084 100644 --- a/crates/hir-ty/src/mir.rs +++ b/crates/hir-ty/src/mir.rs @@ -198,7 +198,7 @@ impl ProjectionElem { }, ProjectionElem::Field(Either::Left(f)) => match base.kind() { TyKind::Adt(_, subst) => db.field_types(f.parent)[f.local_id] - .get() + .ty() .instantiate(interner, subst) .skip_norm_wip(), ty => { diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 1ee18e09ba89..ffdf9031927d 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -1715,7 +1715,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); } @@ -1796,11 +1796,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( @@ -2442,7 +2442,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(); @@ -2471,7 +2471,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(); @@ -2557,9 +2557,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, @@ -2578,9 +2578,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, @@ -3095,7 +3095,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 b4a5aa8a87e2..b59d6c1cfbe7 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 074c5a9c7707..a9d0bee62325 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 5ca0e67d292e..1704a067b1e3 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> 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> 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::>() + db.field_types(id).iter().map(|(_, ty)| ty.ty().skip_binder()).collect::>() }; 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 0ea8003e5507..828af20b7b10 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 49dacc16eb2c..0a95416e4256 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 d187763151a2..2a40b0d3364f 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) } @@ -5549,7 +5549,7 @@ impl<'db> Type<'db> { .iter() .map(|(idx, _)| { field_types[idx] - .get() + .ty() .instantiate(self.interner, args) .skip_norm_wip() }) @@ -5970,9 +5970,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() @@ -7446,7 +7446,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 32e6acb6c58d..ae681aa8fbb4 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -898,7 +898,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(( @@ -923,7 +923,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(( @@ -946,9 +946,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(), @@ -1022,7 +1022,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(), @@ -1501,7 +1501,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 4890badcbf5b..991a0b6bee22 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(), +} + "#, + ); + } }