diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/display.rs | 2 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 38 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 27 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 9 |
4 files changed, 24 insertions, 52 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 508ac37c2..c5cf803fd 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs | |||
@@ -92,7 +92,7 @@ impl HirDisplay for Function { | |||
92 | &data.ret_type | 92 | &data.ret_type |
93 | } else { | 93 | } else { |
94 | match &*data.ret_type { | 94 | match &*data.ret_type { |
95 | TypeRef::ImplTrait(bounds) => match &bounds[0] { | 95 | TypeRef::ImplTrait(bounds) => match bounds[0].as_ref() { |
96 | TypeBound::Path(path) => { | 96 | TypeBound::Path(path) => { |
97 | path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings | 97 | path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings |
98 | [0] | 98 | [0] |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index a7c42ca1e..cdf65a044 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -513,9 +513,8 @@ impl Field { | |||
513 | } | 513 | } |
514 | 514 | ||
515 | /// Returns the type as in the signature of the struct (i.e., with | 515 | /// Returns the type as in the signature of the struct (i.e., with |
516 | /// placeholder types for type parameters). This is good for showing | 516 | /// placeholder types for type parameters). Only use this in the context of |
517 | /// signature help, but not so good to actually get the type of the field | 517 | /// the field definition. |
518 | /// when you actually have a variable of the struct. | ||
519 | pub fn ty(&self, db: &dyn HirDatabase) -> Type { | 518 | pub fn ty(&self, db: &dyn HirDatabase) -> Type { |
520 | let var_id = self.parent.into(); | 519 | let var_id = self.parent.into(); |
521 | let generic_def_id: GenericDefId = match self.parent { | 520 | let generic_def_id: GenericDefId = match self.parent { |
@@ -552,10 +551,6 @@ impl Struct { | |||
552 | Module { id: self.id.lookup(db.upcast()).container } | 551 | Module { id: self.id.lookup(db.upcast()).container } |
553 | } | 552 | } |
554 | 553 | ||
555 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | ||
556 | Some(self.module(db).krate()) | ||
557 | } | ||
558 | |||
559 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 554 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
560 | db.struct_data(self.id).name.clone() | 555 | db.struct_data(self.id).name.clone() |
561 | } | 556 | } |
@@ -640,10 +635,6 @@ impl Enum { | |||
640 | Module { id: self.id.lookup(db.upcast()).container } | 635 | Module { id: self.id.lookup(db.upcast()).container } |
641 | } | 636 | } |
642 | 637 | ||
643 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | ||
644 | Some(self.module(db).krate()) | ||
645 | } | ||
646 | |||
647 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 638 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
648 | db.enum_data(self.id).name.clone() | 639 | db.enum_data(self.id).name.clone() |
649 | } | 640 | } |
@@ -673,6 +664,7 @@ impl Variant { | |||
673 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 664 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
674 | self.parent.module(db) | 665 | self.parent.module(db) |
675 | } | 666 | } |
667 | |||
676 | pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum { | 668 | pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum { |
677 | self.parent | 669 | self.parent |
678 | } | 670 | } |
@@ -729,10 +721,6 @@ impl Adt { | |||
729 | } | 721 | } |
730 | } | 722 | } |
731 | 723 | ||
732 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { | ||
733 | self.module(db).krate() | ||
734 | } | ||
735 | |||
736 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 724 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
737 | match self { | 725 | match self { |
738 | Adt::Struct(s) => s.name(db), | 726 | Adt::Struct(s) => s.name(db), |
@@ -821,10 +809,6 @@ impl Function { | |||
821 | self.id.lookup(db.upcast()).module(db.upcast()).into() | 809 | self.id.lookup(db.upcast()).module(db.upcast()).into() |
822 | } | 810 | } |
823 | 811 | ||
824 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | ||
825 | Some(self.module(db).krate()) | ||
826 | } | ||
827 | |||
828 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 812 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
829 | db.function_data(self.id).name.clone() | 813 | db.function_data(self.id).name.clone() |
830 | } | 814 | } |
@@ -1014,10 +998,6 @@ impl Const { | |||
1014 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } | 998 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } |
1015 | } | 999 | } |
1016 | 1000 | ||
1017 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | ||
1018 | Some(self.module(db).krate()) | ||
1019 | } | ||
1020 | |||
1021 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 1001 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
1022 | db.const_data(self.id).name.clone() | 1002 | db.const_data(self.id).name.clone() |
1023 | } | 1003 | } |
@@ -1045,10 +1025,6 @@ impl Static { | |||
1045 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } | 1025 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } |
1046 | } | 1026 | } |
1047 | 1027 | ||
1048 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | ||
1049 | Some(self.module(db).krate()) | ||
1050 | } | ||
1051 | |||
1052 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 1028 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
1053 | db.static_data(self.id).name.clone() | 1029 | db.static_data(self.id).name.clone() |
1054 | } | 1030 | } |
@@ -1112,10 +1088,6 @@ impl TypeAlias { | |||
1112 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } | 1088 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } |
1113 | } | 1089 | } |
1114 | 1090 | ||
1115 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { | ||
1116 | self.module(db).krate() | ||
1117 | } | ||
1118 | |||
1119 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1091 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1120 | db.type_alias_data(self.id).type_ref.as_deref().cloned() | 1092 | db.type_alias_data(self.id).type_ref.as_deref().cloned() |
1121 | } | 1093 | } |
@@ -1667,10 +1639,6 @@ impl Impl { | |||
1667 | self.id.lookup(db.upcast()).container.into() | 1639 | self.id.lookup(db.upcast()).container.into() |
1668 | } | 1640 | } |
1669 | 1641 | ||
1670 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { | ||
1671 | Crate { id: self.module(db).id.krate() } | ||
1672 | } | ||
1673 | |||
1674 | pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { | 1642 | pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { |
1675 | let src = self.source(db)?; | 1643 | let src = self.source(db)?; |
1676 | let item = src.file_id.is_builtin_derive(db.upcast())?; | 1644 | let item = src.file_id.is_builtin_derive(db.upcast())?; |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 1b5064b5a..8d3c43d08 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | AsMacroCall, FunctionId, TraitId, VariantId, | 11 | AsMacroCall, FunctionId, TraitId, VariantId, |
12 | }; | 12 | }; |
13 | use hir_expand::{name::AsName, ExpansionInfo}; | 13 | use hir_expand::{name::AsName, ExpansionInfo}; |
14 | use hir_ty::associated_type_shorthand_candidates; | 14 | use hir_ty::{associated_type_shorthand_candidates, Interner}; |
15 | use itertools::Itertools; | 15 | use itertools::Itertools; |
16 | use rustc_hash::{FxHashMap, FxHashSet}; | 16 | use rustc_hash::{FxHashMap, FxHashSet}; |
17 | use syntax::{ | 17 | use syntax::{ |
@@ -120,10 +120,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
120 | pub fn speculative_expand( | 120 | pub fn speculative_expand( |
121 | &self, | 121 | &self, |
122 | actual_macro_call: &ast::MacroCall, | 122 | actual_macro_call: &ast::MacroCall, |
123 | hypothetical_args: &ast::TokenTree, | 123 | speculative_args: &ast::TokenTree, |
124 | token_to_map: SyntaxToken, | 124 | token_to_map: SyntaxToken, |
125 | ) -> Option<(SyntaxNode, SyntaxToken)> { | 125 | ) -> Option<(SyntaxNode, SyntaxToken)> { |
126 | self.imp.speculative_expand(actual_macro_call, hypothetical_args, token_to_map) | 126 | self.imp.speculative_expand(actual_macro_call, speculative_args, token_to_map) |
127 | } | 127 | } |
128 | 128 | ||
129 | pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { | 129 | pub fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { |
@@ -227,7 +227,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
227 | pub fn resolve_record_field( | 227 | pub fn resolve_record_field( |
228 | &self, | 228 | &self, |
229 | field: &ast::RecordExprField, | 229 | field: &ast::RecordExprField, |
230 | ) -> Option<(Field, Option<Local>)> { | 230 | ) -> Option<(Field, Option<Local>, Type)> { |
231 | self.imp.resolve_record_field(field) | 231 | self.imp.resolve_record_field(field) |
232 | } | 232 | } |
233 | 233 | ||
@@ -335,7 +335,7 @@ impl<'db> SemanticsImpl<'db> { | |||
335 | fn speculative_expand( | 335 | fn speculative_expand( |
336 | &self, | 336 | &self, |
337 | actual_macro_call: &ast::MacroCall, | 337 | actual_macro_call: &ast::MacroCall, |
338 | hypothetical_args: &ast::TokenTree, | 338 | speculative_args: &ast::TokenTree, |
339 | token_to_map: SyntaxToken, | 339 | token_to_map: SyntaxToken, |
340 | ) -> Option<(SyntaxNode, SyntaxToken)> { | 340 | ) -> Option<(SyntaxNode, SyntaxToken)> { |
341 | let sa = self.analyze(actual_macro_call.syntax()); | 341 | let sa = self.analyze(actual_macro_call.syntax()); |
@@ -344,10 +344,10 @@ impl<'db> SemanticsImpl<'db> { | |||
344 | let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| { | 344 | let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| { |
345 | sa.resolver.resolve_path_as_macro(self.db.upcast(), &path) | 345 | sa.resolver.resolve_path_as_macro(self.db.upcast(), &path) |
346 | })?; | 346 | })?; |
347 | hir_expand::db::expand_hypothetical( | 347 | hir_expand::db::expand_speculative( |
348 | self.db.upcast(), | 348 | self.db.upcast(), |
349 | macro_call_id, | 349 | macro_call_id, |
350 | hypothetical_args, | 350 | speculative_args, |
351 | token_to_map, | 351 | token_to_map, |
352 | ) | 352 | ) |
353 | } | 353 | } |
@@ -501,14 +501,12 @@ impl<'db> SemanticsImpl<'db> { | |||
501 | } | 501 | } |
502 | 502 | ||
503 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { | 503 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { |
504 | self.analyze(call.syntax()).resolve_method_call(self.db, call) | 504 | self.analyze(call.syntax()).resolve_method_call(self.db, call).map(|(id, _)| id) |
505 | } | 505 | } |
506 | 506 | ||
507 | fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { | 507 | fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { |
508 | // FIXME: this erases Substs, we should instead record the correct | 508 | let (func, subst) = self.analyze(call.syntax()).resolve_method_call(self.db, call)?; |
509 | // substitution during inference and use that | 509 | let ty = self.db.value_ty(func.into()).substitute(&Interner, &subst); |
510 | let func = self.resolve_method_call(call)?; | ||
511 | let ty = hir_ty::TyBuilder::value_ty(self.db, func.into()).fill_with_unknown().build(); | ||
512 | let resolver = self.analyze(call.syntax()).resolver; | 510 | let resolver = self.analyze(call.syntax()).resolver; |
513 | let ty = Type::new_with_resolver(self.db, &resolver, ty)?; | 511 | let ty = Type::new_with_resolver(self.db, &resolver, ty)?; |
514 | let mut res = ty.as_callable(self.db)?; | 512 | let mut res = ty.as_callable(self.db)?; |
@@ -520,7 +518,10 @@ impl<'db> SemanticsImpl<'db> { | |||
520 | self.analyze(field.syntax()).resolve_field(self.db, field) | 518 | self.analyze(field.syntax()).resolve_field(self.db, field) |
521 | } | 519 | } |
522 | 520 | ||
523 | fn resolve_record_field(&self, field: &ast::RecordExprField) -> Option<(Field, Option<Local>)> { | 521 | fn resolve_record_field( |
522 | &self, | ||
523 | field: &ast::RecordExprField, | ||
524 | ) -> Option<(Field, Option<Local>, Type)> { | ||
524 | self.analyze(field.syntax()).resolve_record_field(self.db, field) | 525 | self.analyze(field.syntax()).resolve_record_field(self.db, field) |
525 | } | 526 | } |
526 | 527 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 20753314d..3f940124c 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -143,7 +143,7 @@ impl SourceAnalyzer { | |||
143 | &self, | 143 | &self, |
144 | db: &dyn HirDatabase, | 144 | db: &dyn HirDatabase, |
145 | call: &ast::MethodCallExpr, | 145 | call: &ast::MethodCallExpr, |
146 | ) -> Option<FunctionId> { | 146 | ) -> Option<(FunctionId, Substitution)> { |
147 | let expr_id = self.expr_id(db, &call.clone().into())?; | 147 | let expr_id = self.expr_id(db, &call.clone().into())?; |
148 | self.infer.as_ref()?.method_resolution(expr_id) | 148 | self.infer.as_ref()?.method_resolution(expr_id) |
149 | } | 149 | } |
@@ -161,7 +161,7 @@ impl SourceAnalyzer { | |||
161 | &self, | 161 | &self, |
162 | db: &dyn HirDatabase, | 162 | db: &dyn HirDatabase, |
163 | field: &ast::RecordExprField, | 163 | field: &ast::RecordExprField, |
164 | ) -> Option<(Field, Option<Local>)> { | 164 | ) -> Option<(Field, Option<Local>, Type)> { |
165 | let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; | 165 | let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; |
166 | let expr = ast::Expr::from(record_expr); | 166 | let expr = ast::Expr::from(record_expr); |
167 | let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?; | 167 | let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?; |
@@ -178,10 +178,13 @@ impl SourceAnalyzer { | |||
178 | _ => None, | 178 | _ => None, |
179 | } | 179 | } |
180 | }; | 180 | }; |
181 | let (_, subst) = self.infer.as_ref()?.type_of_expr.get(expr_id)?.as_adt()?; | ||
181 | let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?; | 182 | let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?; |
182 | let variant_data = variant.variant_data(db.upcast()); | 183 | let variant_data = variant.variant_data(db.upcast()); |
183 | let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; | 184 | let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; |
184 | Some((field.into(), local)) | 185 | let field_ty = |
186 | db.field_types(variant).get(field.local_id)?.clone().substitute(&Interner, subst); | ||
187 | Some((field.into(), local, Type::new_with_resolver(db, &self.resolver, field_ty)?)) | ||
185 | } | 188 | } |
186 | 189 | ||
187 | pub(crate) fn resolve_record_pat_field( | 190 | pub(crate) fn resolve_record_pat_field( |