diff options
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 5 | ||||
-rw-r--r-- | crates/hir_ty/src/utils.rs | 13 |
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 | ||
59 | use adt::VariantData; | ||
59 | use base_db::{impl_intern_key, salsa, CrateId}; | 60 | use base_db::{impl_intern_key, salsa, CrateId}; |
60 | use hir_expand::{ | 61 | use hir_expand::{ |
61 | ast_id_map::FileAstId, | 62 | ast_id_map::FileAstId, |
@@ -442,6 +443,18 @@ pub enum VariantId { | |||
442 | } | 443 | } |
443 | impl_from!(EnumVariantId, StructId, UnionId for VariantId); | 444 | impl_from!(EnumVariantId, StructId, UnionId for VariantId); |
444 | 445 | ||
446 | impl 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 | |||
445 | trait Intern { | 458 | trait 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 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{ | 15 | use 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 | ||
20 | impl<'a> InferenceContext<'a> { | 20 | impl<'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 | ||
5 | use chalk_ir::{BoundVar, DebruijnIndex}; | 5 | use chalk_ir::{BoundVar, DebruijnIndex}; |
6 | use hir_def::{ | 6 | use 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 | }; |
18 | use hir_expand::name::{name, Name}; | 17 | use 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 | ||
139 | pub(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. |
151 | pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] { | 140 | pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] { |