aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/source_analyzer.rs15
-rw-r--r--crates/hir_def/src/lib.rs13
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs9
-rw-r--r--crates/hir_ty/src/infer.rs5
-rw-r--r--crates/hir_ty/src/infer/expr.rs7
-rw-r--r--crates/hir_ty/src/infer/pat.rs8
-rw-r--r--crates/hir_ty/src/lower.rs5
-rw-r--r--crates/hir_ty/src/utils.rs13
8 files changed, 35 insertions, 40 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 4ce1c2080..c013e78d9 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -161,14 +161,15 @@ impl SourceAnalyzer {
161 db: &dyn HirDatabase, 161 db: &dyn HirDatabase,
162 field: &ast::RecordExprField, 162 field: &ast::RecordExprField,
163 ) -> Option<(Field, Option<Local>)> { 163 ) -> Option<(Field, Option<Local>)> {
164 let expr_id = 164 let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
165 self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?; 165 let expr = ast::Expr::from(record_expr);
166 let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?;
166 167
168 let local_name = field.field_name()?.as_name();
167 let local = if field.name_ref().is_some() { 169 let local = if field.name_ref().is_some() {
168 None 170 None
169 } else { 171 } else {
170 let local_name = field.field_name()?.as_name(); 172 let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone()));
171 let path = ModPath::from_segments(PathKind::Plain, once(local_name));
172 match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) { 173 match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
173 Some(ValueNs::LocalBinding(pat_id)) => { 174 Some(ValueNs::LocalBinding(pat_id)) => {
174 Some(Local { pat_id, parent: self.resolver.body_owner()? }) 175 Some(Local { pat_id, parent: self.resolver.body_owner()? })
@@ -176,8 +177,10 @@ impl SourceAnalyzer {
176 _ => None, 177 _ => None,
177 } 178 }
178 }; 179 };
179 let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?; 180 let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?;
180 Some((struct_field.into(), local)) 181 let variant_data = variant.variant_data(db.upcast());
182 let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
183 Some((field.into(), local))
181 } 184 }
182 185
183 pub(crate) fn resolve_record_pat_field( 186 pub(crate) fn resolve_record_pat_field(
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index be9a5e1a0..abd6c553f 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -56,6 +56,7 @@ use std::{
56 sync::Arc, 56 sync::Arc,
57}; 57};
58 58
59use adt::VariantData;
59use base_db::{impl_intern_key, salsa, CrateId}; 60use base_db::{impl_intern_key, salsa, CrateId};
60use hir_expand::{ 61use hir_expand::{
61 ast_id_map::FileAstId, 62 ast_id_map::FileAstId,
@@ -442,6 +443,18 @@ pub enum VariantId {
442} 443}
443impl_from!(EnumVariantId, StructId, UnionId for VariantId); 444impl_from!(EnumVariantId, StructId, UnionId for VariantId);
444 445
446impl VariantId {
447 pub fn variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData> {
448 match self {
449 VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
450 VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
451 VariantId::EnumVariantId(it) => {
452 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
453 }
454 }
455 }
456}
457
445trait Intern { 458trait Intern {
446 type ID; 459 type ID;
447 fn intern(self, db: &dyn db::DefDatabase) -> Self::ID; 460 fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index d7bf9fdf7..79602c3dd 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -14,7 +14,6 @@ use crate::{
14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, 14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
15 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
16 }, 16 },
17 utils::variant_data,
18 AdtId, InferenceResult, Interner, TyExt, TyKind, 17 AdtId, InferenceResult, Interner, TyExt, TyKind,
19}; 18};
20 19
@@ -104,7 +103,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
104 let root = source_ptr.file_syntax(db.upcast()); 103 let root = source_ptr.file_syntax(db.upcast());
105 if let ast::Expr::RecordExpr(record_expr) = &source_ptr.value.to_node(&root) { 104 if let ast::Expr::RecordExpr(record_expr) = &source_ptr.value.to_node(&root) {
106 if let Some(_) = record_expr.record_expr_field_list() { 105 if let Some(_) = record_expr.record_expr_field_list() {
107 let variant_data = variant_data(db.upcast(), variant_def); 106 let variant_data = variant_def.variant_data(db.upcast());
108 let missed_fields = missed_fields 107 let missed_fields = missed_fields
109 .into_iter() 108 .into_iter()
110 .map(|idx| variant_data.fields()[idx].name.clone()) 109 .map(|idx| variant_data.fields()[idx].name.clone())
@@ -135,7 +134,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
135 let root = source_ptr.file_syntax(db.upcast()); 134 let root = source_ptr.file_syntax(db.upcast());
136 if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) { 135 if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
137 if let Some(_) = record_pat.record_pat_field_list() { 136 if let Some(_) = record_pat.record_pat_field_list() {
138 let variant_data = variant_data(db.upcast(), variant_def); 137 let variant_data = variant_def.variant_data(db.upcast());
139 let missed_fields = missed_fields 138 let missed_fields = missed_fields
140 .into_iter() 139 .into_iter()
141 .map(|idx| variant_data.fields()[idx].name.clone()) 140 .map(|idx| variant_data.fields()[idx].name.clone())
@@ -453,7 +452,7 @@ pub fn record_literal_missing_fields(
453 return None; 452 return None;
454 } 453 }
455 454
456 let variant_data = variant_data(db.upcast(), variant_def); 455 let variant_data = variant_def.variant_data(db.upcast());
457 456
458 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 457 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
459 let missed_fields: Vec<LocalFieldId> = variant_data 458 let missed_fields: Vec<LocalFieldId> = variant_data
@@ -483,7 +482,7 @@ pub fn record_pattern_missing_fields(
483 return None; 482 return None;
484 } 483 }
485 484
486 let variant_data = variant_data(db.upcast(), variant_def); 485 let variant_data = variant_def.variant_data(db.upcast());
487 486
488 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 487 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
489 let missed_fields: Vec<LocalFieldId> = variant_data 488 let missed_fields: Vec<LocalFieldId> = variant_data
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 5146d873b..c63878e7a 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -131,8 +131,6 @@ pub struct InferenceResult {
131 method_resolutions: FxHashMap<ExprId, FunctionId>, 131 method_resolutions: FxHashMap<ExprId, FunctionId>,
132 /// For each field access expr, records the field it resolves to. 132 /// For each field access expr, records the field it resolves to.
133 field_resolutions: FxHashMap<ExprId, FieldId>, 133 field_resolutions: FxHashMap<ExprId, FieldId>,
134 /// For each field in record literal, records the field it resolves to.
135 record_field_resolutions: FxHashMap<ExprId, FieldId>,
136 record_pat_field_resolutions: FxHashMap<PatId, FieldId>, 134 record_pat_field_resolutions: FxHashMap<PatId, FieldId>,
137 /// For each struct literal, records the variant it resolves to. 135 /// For each struct literal, records the variant it resolves to.
138 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, 136 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
@@ -153,9 +151,6 @@ impl InferenceResult {
153 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> { 151 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
154 self.field_resolutions.get(&expr).copied() 152 self.field_resolutions.get(&expr).copied()
155 } 153 }
156 pub fn record_field_resolution(&self, expr: ExprId) -> Option<FieldId> {
157 self.record_field_resolutions.get(&expr).copied()
158 }
159 pub fn record_pat_field_resolution(&self, pat: PatId) -> Option<FieldId> { 154 pub fn record_pat_field_resolution(&self, pat: PatId) -> Option<FieldId> {
160 self.record_pat_field_resolutions.get(&pat).copied() 155 self.record_pat_field_resolutions.get(&pat).copied()
161 } 156 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 5b3cdab4e..9ab0fa212 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -21,7 +21,7 @@ use crate::{
21 primitive::{self, UintTy}, 21 primitive::{self, UintTy},
22 static_lifetime, to_chalk_trait_id, 22 static_lifetime, to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait}, 23 traits::{chalk::from_chalk, FnTrait},
24 utils::{generics, variant_data, Generics}, 24 utils::{generics, Generics},
25 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, 25 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, 26 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
27 TypeWalk, 27 TypeWalk,
@@ -414,7 +414,7 @@ impl<'a> InferenceContext<'a> {
414 414
415 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 415 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
416 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 416 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
417 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 417 let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
418 for field in fields.iter() { 418 for field in fields.iter() {
419 let field_def = 419 let field_def =
420 variant_data.as_ref().and_then(|it| match it.field(&field.name) { 420 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
@@ -426,9 +426,6 @@ impl<'a> InferenceContext<'a> {
426 None 426 None
427 } 427 }
428 }); 428 });
429 if let Some(field_def) = field_def {
430 self.result.record_field_resolutions.insert(field.expr, field_def);
431 }
432 let field_ty = field_def.map_or(self.err_ty(), |it| { 429 let field_ty = field_def.map_or(self.err_ty(), |it| {
433 field_types[it.local_id].clone().substitute(&Interner, &substs) 430 field_types[it.local_id].clone().substitute(&Interner, &substs)
434 }); 431 });
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 12431ae07..942f70edf 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,8 +13,8 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, static_lifetime, utils::variant_data, Interner, Substitution, 16 lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
17 Ty, TyBuilder, TyExt, TyKind, 17 TyExt, TyKind,
18}; 18};
19 19
20impl<'a> InferenceContext<'a> { 20impl<'a> InferenceContext<'a> {
@@ -28,7 +28,7 @@ impl<'a> InferenceContext<'a> {
28 ellipsis: Option<usize>, 28 ellipsis: Option<usize>,
29 ) -> Ty { 29 ) -> Ty {
30 let (ty, def) = self.resolve_variant(path); 30 let (ty, def) = self.resolve_variant(path);
31 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 31 let var_data = def.map(|it| it.variant_data(self.db.upcast()));
32 if let Some(variant) = def { 32 if let Some(variant) = def {
33 self.write_variant_resolution(id.into(), variant); 33 self.write_variant_resolution(id.into(), variant);
34 } 34 }
@@ -68,7 +68,7 @@ impl<'a> InferenceContext<'a> {
68 id: PatId, 68 id: PatId,
69 ) -> Ty { 69 ) -> Ty {
70 let (ty, def) = self.resolve_variant(path); 70 let (ty, def) = self.resolve_variant(path);
71 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 71 let var_data = def.map(|it| it.variant_data(self.db.upcast()));
72 if let Some(variant) = def { 72 if let Some(variant) = def {
73 self.write_variant_resolution(id.into(), variant); 73 self.write_variant_resolution(id.into(), variant);
74 } 74 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 8be1bcddb..4ca6aa538 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -30,8 +30,7 @@ use crate::{
30 dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, 30 dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
31 traits::chalk::{Interner, ToChalk}, 31 traits::chalk::{Interner, ToChalk},
32 utils::{ 32 utils::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
34 variant_data, Generics,
35 }, 34 },
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 35 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, 36 FnSubst, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
@@ -879,7 +878,7 @@ pub(crate) fn field_types_query(
879 db: &dyn HirDatabase, 878 db: &dyn HirDatabase,
880 variant_id: VariantId, 879 variant_id: VariantId,
881) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> { 880) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
882 let var_data = variant_data(db.upcast(), variant_id); 881 let var_data = variant_id.variant_data(db.upcast());
883 let (resolver, def): (_, GenericDefId) = match variant_id { 882 let (resolver, def): (_, GenericDefId) = match variant_id {
884 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()), 883 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
885 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()), 884 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index d11708299..0a424f607 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -4,7 +4,6 @@ use std::sync::Arc;
4 4
5use chalk_ir::{BoundVar, DebruijnIndex}; 5use chalk_ir::{BoundVar, DebruijnIndex};
6use hir_def::{ 6use hir_def::{
7 adt::VariantData,
8 db::DefDatabase, 7 db::DefDatabase,
9 generics::{ 8 generics::{
10 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, 9 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
@@ -13,7 +12,7 @@ use hir_def::{
13 path::Path, 12 path::Path,
14 resolver::{HasResolver, TypeNs}, 13 resolver::{HasResolver, TypeNs},
15 type_ref::TypeRef, 14 type_ref::TypeRef,
16 AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, 15 AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId,
17}; 16};
18use hir_expand::name::{name, Name}; 17use hir_expand::name::{name, Name};
19 18
@@ -136,16 +135,6 @@ pub(super) fn associated_type_by_name_including_super_traits(
136 }) 135 })
137} 136}
138 137
139pub(super) fn variant_data(db: &dyn DefDatabase, var: VariantId) -> Arc<VariantData> {
140 match var {
141 VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
142 VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
143 VariantId::EnumVariantId(it) => {
144 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
145 }
146 }
147}
148
149/// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices). 138/// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices).
150/// The underlying values are cloned if there are other strong references. 139/// The underlying values are cloned if there are other strong references.
151pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] { 140pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] {