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.rs78
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> {