diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 85b378483..3af477818 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -17,7 +17,7 @@ use hir_def::{ | |||
17 | nameres::ModuleSource, | 17 | nameres::ModuleSource, |
18 | path::path, | 18 | path::path, |
19 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, | 19 | resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, |
20 | AssocItemId, DefWithBodyId, | 20 | AssocItemId, DefWithBodyId, Expander, |
21 | }; | 21 | }; |
22 | use hir_expand::{ | 22 | use hir_expand::{ |
23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, | 23 | hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, |
@@ -216,7 +216,14 @@ impl SourceAnalyzer { | |||
216 | } | 216 | } |
217 | 217 | ||
218 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { | 218 | pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { |
219 | let expr_id = self.expr_id(expr)?; | 219 | let expr_id = if let Some(macro_call) = ast::MacroCall::cast(expr.syntax().clone()) { |
220 | let mut expander = Expander::new(db, self.file_id, self.body_owner?.module(db).id); | ||
221 | let expr = expand_macro_call_to_expr(db, &mut expander, macro_call)?; | ||
222 | self.body_source_map.as_ref()?.node_expr(expr.as_ref())? | ||
223 | } else { | ||
224 | self.expr_id(expr)? | ||
225 | }; | ||
226 | |||
220 | let ty = self.infer.as_ref()?[expr_id].clone(); | 227 | let ty = self.infer.as_ref()?[expr_id].clone(); |
221 | let environment = TraitEnvironment::lower(db, &self.resolver); | 228 | let environment = TraitEnvironment::lower(db, &self.resolver); |
222 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) | 229 | Some(Type { krate: self.resolver.krate()?, ty: InEnvironment { value: ty, environment } }) |
@@ -501,6 +508,21 @@ fn scope_for_offset( | |||
501 | }) | 508 | }) |
502 | } | 509 | } |
503 | 510 | ||
511 | fn expand_macro_call_to_expr( | ||
512 | db: &impl HirDatabase, | ||
513 | expander: &mut Expander, | ||
514 | macro_call: ast::MacroCall, | ||
515 | ) -> Option<InFile<ast::Expr>> { | ||
516 | let (mark, expr): (_, ast::Expr) = expander.enter_expand(db, macro_call)?; | ||
517 | let expr = if let Some(child) = ast::MacroCall::cast(expr.syntax().clone()) { | ||
518 | expand_macro_call_to_expr(db, expander, child) | ||
519 | } else { | ||
520 | Some(expander.to_source(expr)) | ||
521 | }; | ||
522 | expander.exit(db, mark); | ||
523 | expr | ||
524 | } | ||
525 | |||
504 | // XXX: during completion, cursor might be outside of any particular | 526 | // XXX: during completion, cursor might be outside of any particular |
505 | // expression. Try to figure out the correct scope... | 527 | // expression. Try to figure out the correct scope... |
506 | fn adjust( | 528 | fn adjust( |