aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_binder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r--crates/ra_hir/src/source_binder.rs26
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};
22use hir_expand::{ 22use 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
511fn 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...
506fn adjust( 528fn adjust(