aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-25 17:38:49 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-25 17:38:49 +0000
commitdaaba4be17cae9ee32a2e151e256ef71f600814e (patch)
tree6be4dae706759f94034649a990695df8b274c6bc /crates/ra_hir
parentbce0c6267aab2e8ca33a3e78a1081736abbc1373 (diff)
parent9f2574c97e55e2af1d1b93f60307aa9d41f55f42 (diff)
Merge #645
645: WIP: support goto for fields. r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/adt.rs70
-rw-r--r--crates/ra_hir/src/code_model_api.rs16
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/ty.rs55
4 files changed, 103 insertions, 40 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index ec6a10353..22bbad964 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -11,7 +11,7 @@ use ra_syntax::{
11 11
12use crate::{ 12use crate::{
13 Name, AsName, Struct, Enum, EnumVariant, Crate, 13 Name, AsName, Struct, Enum, EnumVariant, Crate,
14 HirDatabase, HirFileId, 14 HirDatabase, HirFileId, StructField, FieldSource,
15 type_ref::TypeRef, 15 type_ref::TypeRef,
16}; 16};
17 17
@@ -150,7 +150,7 @@ impl VariantData {
150impl VariantData { 150impl VariantData {
151 fn new(flavor: StructFlavor) -> Self { 151 fn new(flavor: StructFlavor) -> Self {
152 let inner = match flavor { 152 let inner = match flavor {
153 StructFlavor::Tuple(fl) => { 153 ast::StructFlavor::Tuple(fl) => {
154 let fields = fl 154 let fields = fl
155 .fields() 155 .fields()
156 .enumerate() 156 .enumerate()
@@ -161,7 +161,7 @@ impl VariantData {
161 .collect(); 161 .collect();
162 VariantDataInner::Tuple(fields) 162 VariantDataInner::Tuple(fields)
163 } 163 }
164 StructFlavor::Named(fl) => { 164 ast::StructFlavor::Named(fl) => {
165 let fields = fl 165 let fields = fl
166 .fields() 166 .fields()
167 .map(|fd| StructFieldData { 167 .map(|fd| StructFieldData {
@@ -171,8 +171,70 @@ impl VariantData {
171 .collect(); 171 .collect();
172 VariantDataInner::Struct(fields) 172 VariantDataInner::Struct(fields)
173 } 173 }
174 StructFlavor::Unit => VariantDataInner::Unit, 174 ast::StructFlavor::Unit => VariantDataInner::Unit,
175 }; 175 };
176 VariantData(inner) 176 VariantData(inner)
177 } 177 }
178} 178}
179
180#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
181pub enum VariantDef {
182 Struct(Struct),
183 EnumVariant(EnumVariant),
184}
185impl_froms!(VariantDef: Struct, EnumVariant);
186
187impl VariantDef {
188 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
189 match self {
190 VariantDef::Struct(it) => it.field(db, name),
191 VariantDef::EnumVariant(it) => it.field(db, name),
192 }
193 }
194 pub(crate) fn variant_data(self, db: &impl HirDatabase) -> Arc<VariantData> {
195 match self {
196 VariantDef::Struct(it) => it.variant_data(db),
197 VariantDef::EnumVariant(it) => it.variant_data(db),
198 }
199 }
200}
201
202impl StructField {
203 pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> (HirFileId, FieldSource) {
204 let var_data = self.parent.variant_data(db);
205 let fields = var_data.fields().unwrap();
206 let ss;
207 let es;
208 let (file_id, struct_flavor) = match self.parent {
209 VariantDef::Struct(s) => {
210 let (file_id, source) = s.source(db);
211 ss = source;
212 (file_id, ss.flavor())
213 }
214 VariantDef::EnumVariant(e) => {
215 let (file_id, source) = e.source(db);
216 es = source;
217 (file_id, es.flavor())
218 }
219 };
220
221 let field_sources = match struct_flavor {
222 ast::StructFlavor::Tuple(fl) => fl
223 .fields()
224 .map(|it| FieldSource::Pos(it.to_owned()))
225 .collect(),
226 ast::StructFlavor::Named(fl) => fl
227 .fields()
228 .map(|it| FieldSource::Named(it.to_owned()))
229 .collect(),
230 ast::StructFlavor::Unit => Vec::new(),
231 };
232 let field = field_sources
233 .into_iter()
234 .zip(fields.iter())
235 .find(|(_syntax, (id, _))| *id == self.id)
236 .unwrap()
237 .0;
238 (file_id, field)
239 }
240}
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 118562984..fdea5be57 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -10,8 +10,8 @@ use crate::{
10 nameres::{ModuleScope, lower::ImportId}, 10 nameres::{ModuleScope, lower::ImportId},
11 db::HirDatabase, 11 db::HirDatabase,
12 expr::BodySyntaxMapping, 12 expr::BodySyntaxMapping,
13 ty::{InferenceResult, VariantDef}, 13 ty::InferenceResult,
14 adt::{EnumVariantId, StructFieldId}, 14 adt::{EnumVariantId, StructFieldId, VariantDef},
15 generics::GenericParams, 15 generics::GenericParams,
16 docs::{Documentation, Docs, docs_from_ast}, 16 docs::{Documentation, Docs, docs_from_ast},
17 module_tree::ModuleId, 17 module_tree::ModuleId,
@@ -179,10 +179,16 @@ impl Module {
179 179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
181pub struct StructField { 181pub struct StructField {
182 parent: VariantDef, 182 pub(crate) parent: VariantDef,
183 pub(crate) id: StructFieldId, 183 pub(crate) id: StructFieldId,
184} 184}
185 185
186#[derive(Debug)]
187pub enum FieldSource {
188 Named(TreeArc<ast::NamedFieldDef>),
189 Pos(TreeArc<ast::PosField>),
190}
191
186impl StructField { 192impl StructField {
187 pub fn name(&self, db: &impl HirDatabase) -> Name { 193 pub fn name(&self, db: &impl HirDatabase) -> Name {
188 self.parent.variant_data(db).fields().unwrap()[self.id] 194 self.parent.variant_data(db).fields().unwrap()[self.id]
@@ -190,6 +196,10 @@ impl StructField {
190 .clone() 196 .clone()
191 } 197 }
192 198
199 pub fn source(&self, db: &impl HirDatabase) -> (HirFileId, FieldSource) {
200 self.source_impl(db)
201 }
202
193 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 203 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
194 db.type_for_field(*self) 204 db.type_for_field(*self)
195 } 205 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 596f9c38c..eaf8565ee 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -68,7 +68,7 @@ pub use self::code_model_api::{
68 Module, ModuleDef, ModuleSource, Problem, 68 Module, ModuleDef, ModuleSource, Problem,
69 Struct, Enum, EnumVariant, 69 Struct, Enum, EnumVariant,
70 Function, FnSignature, ScopeEntryWithSyntax, 70 Function, FnSignature, ScopeEntryWithSyntax,
71 StructField, 71 StructField, FieldSource,
72 Static, Const, 72 Static, Const,
73 Trait, Type, 73 Trait, Type,
74}; 74};
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index c57e222dd..714eaaae5 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -38,7 +38,7 @@ use crate::{
38 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, 38 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat},
39 generics::GenericParams, 39 generics::GenericParams,
40 path::GenericArg, 40 path::GenericArg,
41 adt::VariantData, 41 adt::VariantDef,
42}; 42};
43 43
44/// The ID of a type variable. 44/// The ID of a type variable.
@@ -696,28 +696,6 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty {
696 } 696 }
697} 697}
698 698
699#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
700pub enum VariantDef {
701 Struct(Struct),
702 EnumVariant(EnumVariant),
703}
704impl_froms!(VariantDef: Struct, EnumVariant);
705
706impl VariantDef {
707 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
708 match self {
709 VariantDef::Struct(it) => it.field(db, name),
710 VariantDef::EnumVariant(it) => it.field(db, name),
711 }
712 }
713 pub(crate) fn variant_data(self, db: &impl HirDatabase) -> Arc<VariantData> {
714 match self {
715 VariantDef::Struct(it) => it.variant_data(db),
716 VariantDef::EnumVariant(it) => it.variant_data(db),
717 }
718 }
719}
720
721pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 699pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
722 let parent_def = field.parent_def(db); 700 let parent_def = field.parent_def(db);
723 let (generics, module) = match parent_def { 701 let (generics, module) = match parent_def {
@@ -732,8 +710,10 @@ pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
732/// The result of type inference: A mapping from expressions and patterns to types. 710/// The result of type inference: A mapping from expressions and patterns to types.
733#[derive(Clone, PartialEq, Eq, Debug)] 711#[derive(Clone, PartialEq, Eq, Debug)]
734pub struct InferenceResult { 712pub struct InferenceResult {
735 /// For each method call expr, record the function it resolved to. 713 /// For each method call expr, records the function it resolves to.
736 method_resolutions: FxHashMap<ExprId, Function>, 714 method_resolutions: FxHashMap<ExprId, Function>,
715 /// For each field access expr, records the field it resolves to.
716 field_resolutions: FxHashMap<ExprId, StructField>,
737 type_of_expr: ArenaMap<ExprId, Ty>, 717 type_of_expr: ArenaMap<ExprId, Ty>,
738 type_of_pat: ArenaMap<PatId, Ty>, 718 type_of_pat: ArenaMap<PatId, Ty>,
739} 719}
@@ -742,6 +722,9 @@ impl InferenceResult {
742 pub fn method_resolution(&self, expr: ExprId) -> Option<Function> { 722 pub fn method_resolution(&self, expr: ExprId) -> Option<Function> {
743 self.method_resolutions.get(&expr).map(|it| *it) 723 self.method_resolutions.get(&expr).map(|it| *it)
744 } 724 }
725 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
726 self.field_resolutions.get(&expr).map(|it| *it)
727 }
745} 728}
746 729
747impl Index<ExprId> for InferenceResult { 730impl Index<ExprId> for InferenceResult {
@@ -770,6 +753,7 @@ struct InferenceContext<'a, D: HirDatabase> {
770 impl_block: Option<ImplBlock>, 753 impl_block: Option<ImplBlock>,
771 var_unification_table: InPlaceUnificationTable<TypeVarId>, 754 var_unification_table: InPlaceUnificationTable<TypeVarId>,
772 method_resolutions: FxHashMap<ExprId, Function>, 755 method_resolutions: FxHashMap<ExprId, Function>,
756 field_resolutions: FxHashMap<ExprId, StructField>,
773 type_of_expr: ArenaMap<ExprId, Ty>, 757 type_of_expr: ArenaMap<ExprId, Ty>,
774 type_of_pat: ArenaMap<PatId, Ty>, 758 type_of_pat: ArenaMap<PatId, Ty>,
775 /// The return type of the function being inferred. 759 /// The return type of the function being inferred.
@@ -861,6 +845,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
861 ) -> Self { 845 ) -> Self {
862 InferenceContext { 846 InferenceContext {
863 method_resolutions: FxHashMap::default(), 847 method_resolutions: FxHashMap::default(),
848 field_resolutions: FxHashMap::default(),
864 type_of_expr: ArenaMap::default(), 849 type_of_expr: ArenaMap::default(),
865 type_of_pat: ArenaMap::default(), 850 type_of_pat: ArenaMap::default(),
866 var_unification_table: InPlaceUnificationTable::new(), 851 var_unification_table: InPlaceUnificationTable::new(),
@@ -886,6 +871,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
886 } 871 }
887 InferenceResult { 872 InferenceResult {
888 method_resolutions: mem::replace(&mut self.method_resolutions, Default::default()), 873 method_resolutions: mem::replace(&mut self.method_resolutions, Default::default()),
874 field_resolutions: mem::replace(&mut self.field_resolutions, Default::default()),
889 type_of_expr: expr_types, 875 type_of_expr: expr_types,
890 type_of_pat: pat_types, 876 type_of_pat: pat_types,
891 } 877 }
@@ -899,6 +885,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
899 self.method_resolutions.insert(expr, func); 885 self.method_resolutions.insert(expr, func);
900 } 886 }
901 887
888 fn write_field_resolution(&mut self, expr: ExprId, field: StructField) {
889 self.field_resolutions.insert(expr, field);
890 }
891
902 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { 892 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
903 self.type_of_pat.insert(pat, ty); 893 self.type_of_pat.insert(pat, ty);
904 } 894 }
@@ -1251,9 +1241,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1251 ty 1241 ty
1252 } 1242 }
1253 1243
1254 fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { 1244 fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
1255 let body = Arc::clone(&self.body); // avoid borrow checker problem 1245 let body = Arc::clone(&self.body); // avoid borrow checker problem
1256 let ty = match &body[expr] { 1246 let ty = match &body[tgt_expr] {
1257 Expr::Missing => Ty::Unknown, 1247 Expr::Missing => Ty::Unknown,
1258 Expr::If { 1248 Expr::If {
1259 condition, 1249 condition,
@@ -1344,7 +1334,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1344 let resolved = receiver_ty.clone().lookup_method(self.db, method_name); 1334 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
1345 let method_ty = match resolved { 1335 let method_ty = match resolved {
1346 Some(func) => { 1336 Some(func) => {
1347 self.write_method_resolution(expr, func); 1337 self.write_method_resolution(tgt_expr, func);
1348 self.db.type_for_def(func.into()) 1338 self.db.type_for_def(func.into())
1349 } 1339 }
1350 None => Ty::Unknown, 1340 None => Ty::Unknown,
@@ -1389,7 +1379,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1389 1379
1390 expected.ty 1380 expected.ty
1391 } 1381 }
1392 Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown), 1382 Expr::Path(p) => self.infer_path_expr(tgt_expr, p).unwrap_or(Ty::Unknown),
1393 Expr::Continue => Ty::Never, 1383 Expr::Continue => Ty::Never,
1394 Expr::Break { expr } => { 1384 Expr::Break { expr } => {
1395 if let Some(expr) = expr { 1385 if let Some(expr) = expr {
@@ -1436,9 +1426,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1436 def_id: AdtDef::Struct(s), 1426 def_id: AdtDef::Struct(s),
1437 ref substs, 1427 ref substs,
1438 .. 1428 ..
1439 } => s 1429 } => s.field(self.db, name).map(|field| {
1440 .field(self.db, name) 1430 self.write_field_resolution(tgt_expr, field);
1441 .map(|field| field.ty(self.db).subst(substs)), 1431 field.ty(self.db).subst(substs)
1432 }),
1442 _ => None, 1433 _ => None,
1443 }) 1434 })
1444 .unwrap_or(Ty::Unknown); 1435 .unwrap_or(Ty::Unknown);
@@ -1545,7 +1536,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1545 let ty = self.insert_type_vars_shallow(ty); 1536 let ty = self.insert_type_vars_shallow(ty);
1546 self.unify(&ty, &expected.ty); 1537 self.unify(&ty, &expected.ty);
1547 let ty = self.resolve_ty_as_possible(ty); 1538 let ty = self.resolve_ty_as_possible(ty);
1548 self.write_expr_ty(expr, ty.clone()); 1539 self.write_expr_ty(tgt_expr, ty.clone());
1549 ty 1540 ty
1550 } 1541 }
1551 1542