diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-21 22:28:06 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-21 22:28:06 +0100 |
commit | bbc5c1d24e1a641b134f634516828301e8cfc320 (patch) | |
tree | f10fe8412874714edcc2d317ab7822b9bbf80a74 /crates/ra_hir/src | |
parent | ee94edc722c9649bd16bb754959ad349593045e2 (diff) | |
parent | 120bfde3c22ed662cd4d3c35e91a739a86d0e990 (diff) |
Merge #1189
1189: Fix #1178 r=matklad a=edwin0cheng
This PR improves / fixes mbe :
1. Fixed a offest bug in `SourceTreeWalker`
2. Handle `*+` matcher properly
3. Add missing separator in rhs macro expansion.
4. Fixed bug in single token with empty delimiter subtree case. It is because the current `mbe_expander` will create an delimiter subtree for each expansion. But in `tt` case, all puncts expansion will be incorrect because of it.
5. Fixed lifetime bug
6. Add more information on parse_macro fail
7. Add tests for above.
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 2a1ed9b81..e771a311c 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -63,11 +63,15 @@ impl HirFileId { | |||
63 | match file_id.0 { | 63 | match file_id.0 { |
64 | HirFileIdRepr::File(file_id) => db.parse(file_id), | 64 | HirFileIdRepr::File(file_id) => db.parse(file_id), |
65 | HirFileIdRepr::Macro(macro_call_id) => { | 65 | HirFileIdRepr::Macro(macro_call_id) => { |
66 | parse_macro(db, macro_call_id).unwrap_or_else(|| { | 66 | parse_macro(db, macro_call_id).unwrap_or_else(|err| { |
67 | // Note: | 67 | // Note: |
68 | // The final goal we would like to make all parse_macro success, | 68 | // The final goal we would like to make all parse_macro success, |
69 | // such that the following log will not call anyway. | 69 | // such that the following log will not call anyway. |
70 | log::warn!("fail on macro_parse: {}", macro_call_id.debug_dump(db)); | 70 | log::warn!( |
71 | "fail on macro_parse: (reason: {}) {}", | ||
72 | err, | ||
73 | macro_call_id.debug_dump(db) | ||
74 | ); | ||
71 | 75 | ||
72 | // returning an empty string looks fishy... | 76 | // returning an empty string looks fishy... |
73 | SourceFile::parse("") | 77 | SourceFile::parse("") |
@@ -77,14 +81,20 @@ impl HirFileId { | |||
77 | } | 81 | } |
78 | } | 82 | } |
79 | 83 | ||
80 | fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { | 84 | fn parse_macro( |
85 | db: &impl DefDatabase, | ||
86 | macro_call_id: MacroCallId, | ||
87 | ) -> Result<TreeArc<SourceFile>, String> { | ||
81 | let loc = macro_call_id.loc(db); | 88 | let loc = macro_call_id.loc(db); |
82 | let macro_call = loc.ast_id.to_node(db); | 89 | let macro_call = loc.ast_id.to_node(db); |
83 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; | 90 | let (macro_arg, _) = macro_call |
84 | 91 | .token_tree() | |
85 | let macro_rules = db.macro_def(loc.def)?; | 92 | .and_then(mbe::ast_to_token_tree) |
86 | let tt = macro_rules.expand(¯o_arg).ok()?; | 93 | .ok_or("Fail to args in to tt::TokenTree")?; |
87 | Some(mbe::token_tree_to_ast_item_list(&tt)) | 94 | |
95 | let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?; | ||
96 | let tt = macro_rules.expand(¯o_arg).map_err(|err| format!("{:?}", err))?; | ||
97 | Ok(mbe::token_tree_to_ast_item_list(&tt)) | ||
88 | } | 98 | } |
89 | 99 | ||
90 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 100 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -311,11 +321,18 @@ impl MacroCallId { | |||
311 | pub fn debug_dump(&self, db: &impl DefDatabase) -> String { | 321 | pub fn debug_dump(&self, db: &impl DefDatabase) -> String { |
312 | let loc = self.clone().loc(db); | 322 | let loc = self.clone().loc(db); |
313 | let node = loc.ast_id.to_node(db); | 323 | let node = loc.ast_id.to_node(db); |
314 | let syntax_str = node.syntax().to_string(); | 324 | let syntax_str = node.syntax().text().chunks().collect::<Vec<_>>().join(" "); |
315 | 325 | ||
316 | // dump the file name | 326 | // dump the file name |
317 | let file_id: HirFileId = self.clone().into(); | 327 | let file_id: HirFileId = self.clone().into(); |
318 | let original = file_id.original_file(db); | 328 | let original = file_id.original_file(db); |
319 | format!("macro call [file: {:#?}] : {}", db.file_relative_path(original), syntax_str) | 329 | let macro_rules = db.macro_def(loc.def); |
330 | |||
331 | format!( | ||
332 | "macro call [file: {:#?}] : {}\nhas rules: {}", | ||
333 | db.file_relative_path(original), | ||
334 | syntax_str, | ||
335 | macro_rules.is_some() | ||
336 | ) | ||
320 | } | 337 | } |
321 | } | 338 | } |