Skip to content

Commit 785eb32

Browse files
bors[bot]matklad
andauthored
Merge #3717
3717: Always expand macros during analysis r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 8d667bb + 2ccfb49 commit 785eb32

File tree

3 files changed

+51
-23
lines changed

3 files changed

+51
-23
lines changed

crates/ra_hir/src/semantics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
173173
}
174174

175175
pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
176-
self.analyze(call.syntax()).resolve_method_call(call)
176+
self.analyze(call.syntax()).resolve_method_call(self.db, call)
177177
}
178178

179179
pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<StructField> {
180-
self.analyze(field.syntax()).resolve_field(field)
180+
self.analyze(field.syntax()).resolve_field(self.db, field)
181181
}
182182

183183
pub fn resolve_record_field(
@@ -188,7 +188,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
188188
}
189189

190190
pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<VariantDef> {
191-
self.analyze(record_lit.syntax()).resolve_record_literal(record_lit)
191+
self.analyze(record_lit.syntax()).resolve_record_literal(self.db, record_lit)
192192
}
193193

194194
pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option<VariantDef> {

crates/ra_hir/src/source_analyzer.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,15 @@ impl SourceAnalyzer {
7878
}
7979
}
8080

81-
fn expr_id(&self, expr: &ast::Expr) -> Option<ExprId> {
82-
let src = InFile { file_id: self.file_id, value: expr };
83-
self.body_source_map.as_ref()?.node_expr(src)
81+
fn expr_id(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<ExprId> {
82+
let src = match expr {
83+
ast::Expr::MacroCall(call) => {
84+
self.expand_expr(db, InFile::new(self.file_id, call.clone()))?
85+
}
86+
_ => InFile::new(self.file_id, expr.clone()),
87+
};
88+
let sm = self.body_source_map.as_ref()?;
89+
sm.node_expr(src.as_ref())
8490
}
8591

8692
fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
@@ -104,14 +110,7 @@ impl SourceAnalyzer {
104110
}
105111

106112
pub(crate) fn type_of(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<Type> {
107-
let expr_id = match expr {
108-
ast::Expr::MacroCall(call) => {
109-
let expr = self.expand_expr(db, InFile::new(self.file_id, call.clone()))?;
110-
self.body_source_map.as_ref()?.node_expr(expr.as_ref())
111-
}
112-
_ => self.expr_id(expr),
113-
}?;
114-
113+
let expr_id = self.expr_id(db, expr)?;
115114
let ty = self.infer.as_ref()?[expr_id].clone();
116115
Type::new_with_resolver(db, &self.resolver, ty)
117116
}
@@ -122,13 +121,21 @@ impl SourceAnalyzer {
122121
Type::new_with_resolver(db, &self.resolver, ty)
123122
}
124123

125-
pub(crate) fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
126-
let expr_id = self.expr_id(&call.clone().into())?;
124+
pub(crate) fn resolve_method_call(
125+
&self,
126+
db: &dyn HirDatabase,
127+
call: &ast::MethodCallExpr,
128+
) -> Option<Function> {
129+
let expr_id = self.expr_id(db, &call.clone().into())?;
127130
self.infer.as_ref()?.method_resolution(expr_id).map(Function::from)
128131
}
129132

130-
pub(crate) fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> {
131-
let expr_id = self.expr_id(&field.clone().into())?;
133+
pub(crate) fn resolve_field(
134+
&self,
135+
db: &dyn HirDatabase,
136+
field: &ast::FieldExpr,
137+
) -> Option<crate::StructField> {
138+
let expr_id = self.expr_id(db, &field.clone().into())?;
132139
self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into())
133140
}
134141

@@ -138,7 +145,7 @@ impl SourceAnalyzer {
138145
field: &ast::RecordField,
139146
) -> Option<(crate::StructField, Option<Local>)> {
140147
let (expr_id, local) = match field.expr() {
141-
Some(it) => (self.expr_id(&it)?, None),
148+
Some(it) => (self.expr_id(db, &it)?, None),
142149
None => {
143150
let src = InFile { file_id: self.file_id, value: field };
144151
let expr_id = self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?;
@@ -159,9 +166,10 @@ impl SourceAnalyzer {
159166

160167
pub(crate) fn resolve_record_literal(
161168
&self,
169+
db: &dyn HirDatabase,
162170
record_lit: &ast::RecordLit,
163171
) -> Option<crate::VariantDef> {
164-
let expr_id = self.expr_id(&record_lit.clone().into())?;
172+
let expr_id = self.expr_id(db, &record_lit.clone().into())?;
165173
self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into())
166174
}
167175

@@ -207,7 +215,7 @@ impl SourceAnalyzer {
207215
path: &ast::Path,
208216
) -> Option<PathResolution> {
209217
if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) {
210-
let expr_id = self.expr_id(&path_expr.into())?;
218+
let expr_id = self.expr_id(db, &path_expr.into())?;
211219
if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) {
212220
return Some(PathResolution::AssocItem(assoc.into()));
213221
}

crates/ra_ide/src/goto_definition.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ mod tests {
104104
let (analysis, pos) = analysis_and_position(ra_fixture);
105105

106106
let mut navs = analysis.goto_definition(pos).unwrap().unwrap().info;
107+
if navs.len() == 0 {
108+
panic!("unresolved reference")
109+
}
107110
assert_eq!(navs.len(), 1);
108111

109112
let nav = navs.pop().unwrap();
@@ -359,7 +362,7 @@ mod tests {
359362
fn goto_def_for_fields() {
360363
covers!(ra_ide_db::goto_def_for_fields);
361364
check_goto(
362-
"
365+
r"
363366
//- /lib.rs
364367
struct Foo {
365368
spam: u32,
@@ -378,7 +381,7 @@ mod tests {
378381
fn goto_def_for_record_fields() {
379382
covers!(ra_ide_db::goto_def_for_record_fields);
380383
check_goto(
381-
"
384+
r"
382385
//- /lib.rs
383386
struct Foo {
384387
spam: u32,
@@ -395,6 +398,23 @@ mod tests {
395398
);
396399
}
397400

401+
#[test]
402+
fn goto_def_for_record_fields_macros() {
403+
check_goto(
404+
r"
405+
//- /lib.rs
406+
macro_rules! m { () => { 92 };}
407+
struct Foo { spam: u32 }
408+
409+
fn bar() -> Foo {
410+
Foo { spam<|>: m!() }
411+
}
412+
",
413+
"spam RECORD_FIELD_DEF FileId(1) [45; 54) [45; 49)",
414+
"spam: u32|spam",
415+
);
416+
}
417+
398418
#[test]
399419
fn goto_for_tuple_fields() {
400420
check_goto(

0 commit comments

Comments
 (0)