diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-20 13:36:19 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-20 13:36:19 +0000 |
commit | 4ef9cab41a9d8a0a9a683c327f022b6ca9524a37 (patch) | |
tree | fc8009de0176c6904c3dd0484775e85592c9464d | |
parent | b568bcfe6d94d5f4c6cdc012b766473e5b771a26 (diff) | |
parent | 0a9c80053ffcd72d076ca3792bf4a9ddb94eaf95 (diff) |
Merge #2318
2318: Fix panic when use `Expand Macro` on `assert_eq` r=matklad a=edwin0cheng
The cause of this [bug](https://github.com/rust-analyzer/rust-analyzer/pull/2291#issuecomment-555651542) is, when calling `SourceAnalyzer::expand` when an `ast::MacroCall` which is outside of `SourceAnalyzer::node`.
Note that if we use a node in `SourceAnalyzer::new` with a `MacroFile` file id, the resolver inside `SourceAnalyzer` still will not work properly. Another PR will need to fix it.
Co-authored-by: Edwin Cheng <[email protected]>
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 13 | ||||
-rw-r--r-- | crates/ra_ide_api/src/expand.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/expand_macro.rs | 10 |
3 files changed, 16 insertions, 9 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 5d9e22ee2..caa8d0082 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -405,9 +405,16 @@ impl SourceAnalyzer { | |||
405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) | 405 | implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) |
406 | } | 406 | } |
407 | 407 | ||
408 | pub fn expand(&self, db: &impl HirDatabase, macro_call: &ast::MacroCall) -> Option<Expansion> { | 408 | pub fn expand( |
409 | let def = self.resolve_macro_call(db, macro_call)?.id; | 409 | &self, |
410 | let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(macro_call)); | 410 | db: &impl HirDatabase, |
411 | macro_call: Source<&ast::MacroCall>, | ||
412 | ) -> Option<Expansion> { | ||
413 | let def = self.resolve_macro_call(db, macro_call.value)?.id; | ||
414 | let ast_id = AstId::new( | ||
415 | macro_call.file_id, | ||
416 | db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), | ||
417 | ); | ||
411 | let macro_call_loc = MacroCallLoc { def, ast_id }; | 418 | let macro_call_loc = MacroCallLoc { def, ast_id }; |
412 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) | 419 | Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) |
413 | } | 420 | } |
diff --git a/crates/ra_ide_api/src/expand.rs b/crates/ra_ide_api/src/expand.rs index 0ad125a9e..2f1abf509 100644 --- a/crates/ra_ide_api/src/expand.rs +++ b/crates/ra_ide_api/src/expand.rs | |||
@@ -55,7 +55,7 @@ pub(crate) fn descend_into_macros( | |||
55 | } | 55 | } |
56 | let source_analyzer = | 56 | let source_analyzer = |
57 | hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None); | 57 | hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None); |
58 | let exp = source_analyzer.expand(db, ¯o_call)?; | 58 | let exp = source_analyzer.expand(db, token.with_value(¯o_call))?; |
59 | exp.map_token_down(db, token.as_ref()) | 59 | exp.map_token_down(db, token.as_ref()) |
60 | }) | 60 | }) |
61 | .last() | 61 | .last() |
diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 2d478ec09..7f39262dc 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs | |||
@@ -23,7 +23,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< | |||
23 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; | 23 | let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?; |
24 | 24 | ||
25 | let source = hir::Source::new(position.file_id.into(), mac.syntax()); | 25 | let source = hir::Source::new(position.file_id.into(), mac.syntax()); |
26 | let expanded = expand_macro_recur(db, source, &mac)?; | 26 | let expanded = expand_macro_recur(db, source, source.with_value(&mac))?; |
27 | 27 | ||
28 | // FIXME: | 28 | // FIXME: |
29 | // macro expansion may lose all white space information | 29 | // macro expansion may lose all white space information |
@@ -35,10 +35,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< | |||
35 | fn expand_macro_recur( | 35 | fn expand_macro_recur( |
36 | db: &RootDatabase, | 36 | db: &RootDatabase, |
37 | source: hir::Source<&SyntaxNode>, | 37 | source: hir::Source<&SyntaxNode>, |
38 | macro_call: &ast::MacroCall, | 38 | macro_call: hir::Source<&ast::MacroCall>, |
39 | ) -> Option<SyntaxNode> { | 39 | ) -> Option<SyntaxNode> { |
40 | let analyzer = hir::SourceAnalyzer::new(db, source, None); | 40 | let analyzer = hir::SourceAnalyzer::new(db, source, None); |
41 | let expansion = analyzer.expand(db, ¯o_call)?; | 41 | let expansion = analyzer.expand(db, macro_call)?; |
42 | let macro_file_id = expansion.file_id(); | 42 | let macro_file_id = expansion.file_id(); |
43 | let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; | 43 | let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?; |
44 | 44 | ||
@@ -46,8 +46,8 @@ fn expand_macro_recur( | |||
46 | let mut replaces = FxHashMap::default(); | 46 | let mut replaces = FxHashMap::default(); |
47 | 47 | ||
48 | for child in children.into_iter() { | 48 | for child in children.into_iter() { |
49 | let source = hir::Source::new(macro_file_id, source.value); | 49 | let node = hir::Source::new(macro_file_id, &child); |
50 | let new_node = expand_macro_recur(db, source, &child)?; | 50 | let new_node = expand_macro_recur(db, source, node)?; |
51 | 51 | ||
52 | replaces.insert(child.syntax().clone().into(), new_node.into()); | 52 | replaces.insert(child.syntax().clone().into(), new_node.into()); |
53 | } | 53 | } |