aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs61
-rw-r--r--crates/ra_hir/src/lib.rs3
-rw-r--r--crates/ra_hir/src/semantics.rs49
-rw-r--r--crates/ra_hir/src/semantics/source_to_def.rs2
-rw-r--r--crates/ra_hir/src/source_analyzer.rs3
5 files changed, 92 insertions, 26 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 3f645a1dd..5f480c304 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -19,7 +19,7 @@ use hir_def::{
19use hir_expand::{ 19use hir_expand::{
20 diagnostics::DiagnosticSink, 20 diagnostics::DiagnosticSink,
21 name::{name, AsName}, 21 name::{name, AsName},
22 MacroDefId, 22 MacroDefId, MacroDefKind,
23}; 23};
24use hir_ty::{ 24use hir_ty::{
25 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, 25 autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy,
@@ -762,13 +762,12 @@ impl MacroDef {
762 762
763 /// Indicate it is a proc-macro 763 /// Indicate it is a proc-macro
764 pub fn is_proc_macro(&self) -> bool { 764 pub fn is_proc_macro(&self) -> bool {
765 match self.id.kind { 765 matches!(self.id.kind, MacroDefKind::CustomDerive(_))
766 hir_expand::MacroDefKind::Declarative => false, 766 }
767 hir_expand::MacroDefKind::BuiltIn(_) => false, 767
768 hir_expand::MacroDefKind::BuiltInDerive(_) => false, 768 /// Indicate it is a derive macro
769 hir_expand::MacroDefKind::BuiltInEager(_) => false, 769 pub fn is_derive_macro(&self) -> bool {
770 hir_expand::MacroDefKind::CustomDerive(_) => true, 770 matches!(self.id.kind, MacroDefKind::CustomDerive(_) | MacroDefKind::BuiltInDerive(_))
771 }
772 } 771 }
773} 772}
774 773
@@ -953,6 +952,16 @@ impl TypeParam {
953 pub fn module(self, db: &dyn HirDatabase) -> Module { 952 pub fn module(self, db: &dyn HirDatabase) -> Module {
954 self.id.parent.module(db.upcast()).into() 953 self.id.parent.module(db.upcast()).into()
955 } 954 }
955
956 pub fn ty(self, db: &dyn HirDatabase) -> Type {
957 let resolver = self.id.parent.resolver(db.upcast());
958 let environment = TraitEnvironment::lower(db, &resolver);
959 let ty = Ty::Placeholder(self.id);
960 Type {
961 krate: self.id.parent.module(db.upcast()).krate,
962 ty: InEnvironment { value: ty, environment },
963 }
964 }
956} 965}
957 966
958// FIXME: rename from `ImplDef` to `Impl` 967// FIXME: rename from `ImplDef` to `Impl`
@@ -1136,6 +1145,13 @@ impl Type {
1136 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) 1145 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. }))
1137 } 1146 }
1138 1147
1148 pub fn is_fn(&self) -> bool {
1149 matches!(&self.ty.value,
1150 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) |
1151 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. })
1152 )
1153 }
1154
1139 pub fn contains_unknown(&self) -> bool { 1155 pub fn contains_unknown(&self) -> bool {
1140 return go(&self.ty.value); 1156 return go(&self.ty.value);
1141 1157
@@ -1150,18 +1166,21 @@ impl Type {
1150 1166
1151 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1167 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1152 if let Ty::Apply(a_ty) = &self.ty.value { 1168 if let Ty::Apply(a_ty) = &self.ty.value {
1153 if let TypeCtor::Adt(AdtId::StructId(s)) = a_ty.ctor { 1169 let variant_id = match a_ty.ctor {
1154 let var_def = s.into(); 1170 TypeCtor::Adt(AdtId::StructId(s)) => s.into(),
1155 return db 1171 TypeCtor::Adt(AdtId::UnionId(u)) => u.into(),
1156 .field_types(var_def) 1172 _ => return Vec::new(),
1157 .iter() 1173 };
1158 .map(|(local_id, ty)| { 1174
1159 let def = Field { parent: var_def.into(), id: local_id }; 1175 return db
1160 let ty = ty.clone().subst(&a_ty.parameters); 1176 .field_types(variant_id)
1161 (def, self.derived(ty)) 1177 .iter()
1162 }) 1178 .map(|(local_id, ty)| {
1163 .collect(); 1179 let def = Field { parent: variant_id.into(), id: local_id };
1164 } 1180 let ty = ty.clone().subst(&a_ty.parameters);
1181 (def, self.derived(ty))
1182 })
1183 .collect();
1165 }; 1184 };
1166 Vec::new() 1185 Vec::new()
1167 } 1186 }
@@ -1192,7 +1211,7 @@ impl Type {
1192 1211
1193 // This would be nicer if it just returned an iterator, but that runs into 1212 // This would be nicer if it just returned an iterator, but that runs into
1194 // lifetime problems, because we need to borrow temp `CrateImplDefs`. 1213 // lifetime problems, because we need to borrow temp `CrateImplDefs`.
1195 pub fn iterate_impl_items<T>( 1214 pub fn iterate_assoc_items<T>(
1196 self, 1215 self,
1197 db: &dyn HirDatabase, 1216 db: &dyn HirDatabase,
1198 krate: Crate, 1217 krate: Crate,
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 312ef3814..c5df4ac24 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -70,6 +70,7 @@ pub use hir_def::{
70 type_ref::Mutability, 70 type_ref::Mutability,
71}; 71};
72pub use hir_expand::{ 72pub use hir_expand::{
73 name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, 73 hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId,
74 MacroFile, Origin,
74}; 75};
75pub use hir_ty::{display::HirDisplay, CallableDef}; 76pub use hir_ty::{display::HirDisplay, CallableDef};
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index 86bfb416c..515e5eb17 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -8,7 +8,8 @@ use hir_def::{
8 resolver::{self, HasResolver, Resolver}, 8 resolver::{self, HasResolver, Resolver},
9 AsMacroCall, TraitId, 9 AsMacroCall, TraitId,
10}; 10};
11use hir_expand::ExpansionInfo; 11use hir_expand::{hygiene::Hygiene, ExpansionInfo};
12use hir_ty::associated_type_shorthand_candidates;
12use itertools::Itertools; 13use itertools::Itertools;
13use ra_db::{FileId, FileRange}; 14use ra_db::{FileId, FileRange};
14use ra_prof::profile; 15use ra_prof::profile;
@@ -24,8 +25,9 @@ use crate::{
24 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
25 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, SourceAnalyzer},
26 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, 27 AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef,
27 Name, Origin, Path, ScopeDef, Trait, Type, TypeParam, 28 Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
28}; 29};
30use resolver::TypeNs;
29 31
30#[derive(Debug, Clone, PartialEq, Eq)] 32#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum PathResolution { 33pub enum PathResolution {
@@ -40,6 +42,44 @@ pub enum PathResolution {
40 AssocItem(AssocItem), 42 AssocItem(AssocItem),
41} 43}
42 44
45impl PathResolution {
46 fn in_type_ns(&self) -> Option<TypeNs> {
47 match self {
48 PathResolution::Def(ModuleDef::Adt(adt)) => Some(TypeNs::AdtId((*adt).into())),
49 PathResolution::Def(ModuleDef::BuiltinType(builtin)) => {
50 Some(TypeNs::BuiltinType(*builtin))
51 }
52 PathResolution::Def(ModuleDef::Const(_))
53 | PathResolution::Def(ModuleDef::EnumVariant(_))
54 | PathResolution::Def(ModuleDef::Function(_))
55 | PathResolution::Def(ModuleDef::Module(_))
56 | PathResolution::Def(ModuleDef::Static(_))
57 | PathResolution::Def(ModuleDef::Trait(_)) => None,
58 PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
59 Some(TypeNs::TypeAliasId((*alias).into()))
60 }
61 PathResolution::Local(_) | PathResolution::Macro(_) => None,
62 PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
63 PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
64 PathResolution::AssocItem(AssocItem::Const(_))
65 | PathResolution::AssocItem(AssocItem::Function(_)) => None,
66 PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
67 Some(TypeNs::TypeAliasId((*alias).into()))
68 }
69 }
70 }
71
72 /// Returns an iterator over associated types that may be specified after this path (using
73 /// `Ty::Assoc` syntax).
74 pub fn assoc_type_shorthand_candidates<R>(
75 &self,
76 db: &dyn HirDatabase,
77 mut cb: impl FnMut(TypeAlias) -> Option<R>,
78 ) -> Option<R> {
79 associated_type_shorthand_candidates(db, self.in_type_ns()?, |_, _, id| cb(id.into()))
80 }
81}
82
43/// Primary API to get semantic information, like types, from syntax trees. 83/// Primary API to get semantic information, like types, from syntax trees.
44pub struct Semantics<'db, DB> { 84pub struct Semantics<'db, DB> {
45 pub db: &'db DB, 85 pub db: &'db DB,
@@ -206,6 +246,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
206 self.analyze(path.syntax()).resolve_path(self.db, path) 246 self.analyze(path.syntax()).resolve_path(self.db, path)
207 } 247 }
208 248
249 pub fn lower_path(&self, path: &ast::Path) -> Option<Path> {
250 let src = self.find_file(path.syntax().clone());
251 Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into()))
252 }
253
209 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { 254 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
210 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) 255 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
211 } 256 }
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs
index 6f3b5b2da..8af64fdc1 100644
--- a/crates/ra_hir/src/semantics/source_to_def.rs
+++ b/crates/ra_hir/src/semantics/source_to_def.rs
@@ -151,7 +151,7 @@ impl SourceToDefCtx<'_, '_> {
151 let krate = self.file_to_def(file_id)?.krate; 151 let krate = self.file_to_def(file_id)?.krate;
152 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); 152 let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
153 let ast_id = Some(AstId::new(src.file_id, file_ast_id)); 153 let ast_id = Some(AstId::new(src.file_id, file_ast_id));
154 Some(MacroDefId { krate: Some(krate), ast_id, kind }) 154 Some(MacroDefId { krate: Some(krate), ast_id, kind, local_inner: false })
155 } 155 }
156 156
157 pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { 157 pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index 74d64c97d..c63d1b847 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -224,7 +224,8 @@ impl SourceAnalyzer {
224 } 224 }
225 } 225 }
226 // This must be a normal source file rather than macro file. 226 // This must be a normal source file rather than macro file.
227 let hir_path = crate::Path::from_ast(path.clone())?; 227 let hir_path =
228 crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?;
228 resolve_hir_path(db, &self.resolver, &hir_path) 229 resolve_hir_path(db, &self.resolver, &hir_path)
229 } 230 }
230 231