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.rs45
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`
+
"#]],
);
}