Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/db.rs')
| -rw-r--r-- | crates/hir-expand/src/db.rs | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index d93f3b08d3..afc2be0741 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -9,7 +9,7 @@ use mbe::syntax_node_to_token_tree; use rustc_hash::FxHashSet; use syntax::{ ast::{self, HasAttrs, HasDocComments}, - AstNode, GreenNode, Parse, SyntaxNode, SyntaxToken, T, + AstNode, GreenNode, Parse, SyntaxError, SyntaxNode, SyntaxToken, T, }; use crate::{ @@ -100,7 +100,10 @@ pub trait ExpandDatabase: SourceDatabase { #[salsa::transparent] fn parse_or_expand(&self, file_id: HirFileId) -> Option<SyntaxNode>; #[salsa::transparent] - fn parse_or_expand_with_err(&self, file_id: HirFileId) -> Option<Parse<SyntaxNode>>; + fn parse_or_expand_with_err( + &self, + file_id: HirFileId, + ) -> ExpandResult<Option<Parse<SyntaxNode>>>; /// Implementation for the macro case. fn parse_macro_expansion( &self, @@ -129,15 +132,18 @@ pub trait ExpandDatabase: SourceDatabase { /// just fetches procedural ones. fn macro_def(&self, id: MacroDefId) -> Result<Arc<TokenExpander>, mbe::ParseError>; - /// Expand macro call to a token tree. This query is LRUed (we keep 128 or so results in memory) + /// Expand macro call to a token tree. fn macro_expand(&self, macro_call: MacroCallId) -> ExpandResult<Option<Arc<tt::Subtree>>>; /// Special case of the previous query for procedural macros. We can't LRU /// proc macros, since they are not deterministic in general, and /// non-determinism breaks salsa in a very, very, very bad way. @edwin0cheng /// heroically debugged this once! fn expand_proc_macro(&self, call: MacroCallId) -> ExpandResult<tt::Subtree>; - /// Firewall query that returns the error from the `macro_expand` query. - fn macro_expand_error(&self, macro_call: MacroCallId) -> Option<ExpandError>; + /// Firewall query that returns the errors from the `parse_macro_expansion` query. + fn parse_macro_expansion_error( + &self, + macro_call: MacroCallId, + ) -> ExpandResult<Option<Box<[SyntaxError]>>>; fn hygiene_frame(&self, file_id: HirFileId) -> Arc<HygieneFrame>; } @@ -262,11 +268,11 @@ fn parse_or_expand(db: &dyn ExpandDatabase, file_id: HirFileId) -> Option<Syntax fn parse_or_expand_with_err( db: &dyn ExpandDatabase, file_id: HirFileId, -) -> Option<Parse<SyntaxNode>> { +) -> ExpandResult<Option<Parse<SyntaxNode>>> { match file_id.repr() { - HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).to_syntax()), + HirFileIdRepr::FileId(file_id) => ExpandResult::ok(Some(db.parse(file_id).to_syntax())), HirFileIdRepr::MacroFile(macro_file) => { - db.parse_macro_expansion(macro_file).value.map(|(parse, _)| parse) + db.parse_macro_expansion(macro_file).map(|it| it.map(|(parse, _)| parse)) } } } @@ -279,25 +285,28 @@ fn parse_macro_expansion( let mbe::ValueResult { value, err } = db.macro_expand(macro_file.macro_call_id); if let Some(err) = &err { - // Note: - // The final goal we would like to make all parse_macro success, - // such that the following log will not call anyway. - let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id); - let node = loc.kind.to_node(db); - - // collect parent information for warning log - let parents = - std::iter::successors(loc.kind.file_id().call_node(db), |it| it.file_id.call_node(db)) - .map(|n| format!("{:#}", n.value)) - .collect::<Vec<_>>() - .join("\n"); - - tracing::debug!( - "fail on macro_parse: (reason: {:?} macro_call: {:#}) parents: {}", - err, - node.value, - parents - ); + if tracing::enabled!(tracing::Level::DEBUG) { + // Note: + // The final goal we would like to make all parse_macro success, + // such that the following log will not call anyway. + let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id); + let node = loc.kind.to_node(db); + + // collect parent information for warning log + let parents = std::iter::successors(loc.kind.file_id().call_node(db), |it| { + it.file_id.call_node(db) + }) + .map(|n| format!("{:#}", n.value)) + .collect::<Vec<_>>() + .join("\n"); + + tracing::debug!( + "fail on macro_parse: (reason: {:?} macro_call: {:#}) parents: {}", + err, + node.value, + parents + ); + } } let tt = match value { Some(tt) => tt, @@ -442,14 +451,14 @@ fn macro_def( fn macro_expand( db: &dyn ExpandDatabase, id: MacroCallId, + // FIXME: Remove the OPtion if possible ) -> ExpandResult<Option<Arc<tt::Subtree>>> { let _p = profile::span("macro_expand"); let loc: MacroCallLoc = db.lookup_intern_macro_call(id); if let Some(eager) = &loc.eager { return ExpandResult { value: Some(eager.arg_or_expansion.clone()), - // FIXME: There could be errors here! - err: None, + err: eager.error.clone(), }; } @@ -466,7 +475,8 @@ fn macro_expand( Ok(it) => it, // FIXME: This is weird -- we effectively report macro *definition* // errors lazily, when we try to expand the macro. Instead, they should - // be reported at the definition site (when we construct a def map). + // be reported at the definition site when we construct a def map. + // (Note we do report them also at the definition site in the late diagnostic pass) Err(err) => { return ExpandResult::only_err(ExpandError::Other( format!("invalid macro definition: {err}").into(), @@ -492,8 +502,12 @@ fn macro_expand( ExpandResult { value: Some(Arc::new(tt)), err } } -fn macro_expand_error(db: &dyn ExpandDatabase, macro_call: MacroCallId) -> Option<ExpandError> { - db.macro_expand(macro_call).err +fn parse_macro_expansion_error( + db: &dyn ExpandDatabase, + macro_call_id: MacroCallId, +) -> ExpandResult<Option<Box<[SyntaxError]>>> { + db.parse_macro_expansion(MacroFile { macro_call_id }) + .map(|it| it.map(|(it, _)| it.errors().to_vec().into_boxed_slice())) } fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<tt::Subtree> { |