Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/expand_macro.rs')
| -rw-r--r-- | crates/ide/src/expand_macro.rs | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 79fdf75b7f..10a73edd51 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -1,10 +1,11 @@ use hir::db::ExpandDatabase; -use hir::{InFile, MacroFileIdExt, Semantics}; +use hir::{ExpandResult, InFile, MacroFileIdExt, Semantics}; use ide_db::base_db::CrateId; use ide_db::{ helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase, }; use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize}; +use stdx::format_to; use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T}; use crate::FilePosition; @@ -63,10 +64,10 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .take_while(|it| it != &token) .filter(|it| it.kind() == T![,]) .count(); - let expansion = expansions.get(idx)?.clone(); + let ExpandResult { err, value: expansion } = expansions.get(idx)?.clone(); let expansion_file_id = sema.hir_file_for(&expansion).macro_file()?; let expansion_span_map = db.expansion_span_map(expansion_file_id); - let expansion = format( + let mut expansion = format( db, SyntaxKind::MACRO_ITEMS, position.file_id, @@ -74,6 +75,12 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< &expansion_span_map, krate, ); + if let Some(err) = err { + expansion.insert_str( + 0, + &format!("Expansion had errors: {}\n\n", err.render_to_string(sema.db)), + ); + } Some(ExpandedMacro { name, expansion }) }); @@ -83,6 +90,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< let mut anc = tok.parent_ancestors(); let mut span_map = SpanMap::empty(); + let mut error = String::new(); let (name, expanded, kind) = loop { let node = anc.next()?; @@ -97,7 +105,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< .unwrap_or(Edition::CURRENT), ) .to_string(), - expand_macro_recur(&sema, &item, &mut span_map, TextSize::new(0))?, + expand_macro_recur(&sema, &item, &mut error, &mut span_map, TextSize::new(0))?, SyntaxKind::MACRO_ITEMS, ); } @@ -112,6 +120,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< expand_macro_recur( &sema, &ast::Item::MacroCall(mac), + &mut error, &mut span_map, TextSize::new(0), )?, @@ -123,24 +132,31 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< // FIXME: // macro expansion may lose all white space information // But we hope someday we can use ra_fmt for that - let expansion = format(db, kind, position.file_id, expanded, &span_map, krate); + let mut expansion = format(db, kind, position.file_id, expanded, &span_map, krate); + if !error.is_empty() { + expansion.insert_str(0, &format!("Expansion had errors:{error}\n\n")); + } Some(ExpandedMacro { name, expansion }) } fn expand_macro_recur( sema: &Semantics<'_, RootDatabase>, macro_call: &ast::Item, + error: &mut String, result_span_map: &mut SpanMap<SyntaxContextId>, offset_in_original_node: TextSize, ) -> Option<SyntaxNode> { - let expanded = match macro_call { - item @ ast::Item::MacroCall(macro_call) => sema - .expand_attr_macro(item) - .or_else(|| sema.expand_allowed_builtins(macro_call))? - .clone_for_update(), - item => sema.expand_attr_macro(item)?.clone_for_update(), + let ExpandResult { value: expanded, err } = match macro_call { + item @ ast::Item::MacroCall(macro_call) => { + sema.expand_attr_macro(item).or_else(|| sema.expand_allowed_builtins(macro_call))? + } + item => sema.expand_attr_macro(item)?, }; + let expanded = expanded.clone_for_update(); + if let Some(err) = err { + format_to!(error, "\n{}", err.render_to_string(sema.db)); + } let file_id = sema.hir_file_for(&expanded).macro_file().expect("expansion must produce a macro file"); let expansion_span_map = sema.db.expansion_span_map(file_id); @@ -149,12 +165,13 @@ fn expand_macro_recur( expanded.text_range().len(), &expansion_span_map, ); - Some(expand(sema, expanded, result_span_map, u32::from(offset_in_original_node) as i32)) + Some(expand(sema, expanded, error, result_span_map, u32::from(offset_in_original_node) as i32)) } fn expand( sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode, + error: &mut String, result_span_map: &mut SpanMap<SyntaxContextId>, mut offset_in_original_node: i32, ) -> SyntaxNode { @@ -165,6 +182,7 @@ fn expand( if let Some(new_node) = expand_macro_recur( sema, &child, + error, result_span_map, TextSize::new( (offset_in_original_node + (u32::from(child.syntax().text_range().start()) as i32)) @@ -495,6 +513,9 @@ fn main() { "#, expect![[r#" foo! + Expansion had errors: + expected ident: `BAD` + "#]], ); } |