Simplify include handling

This commit is contained in:
Lukas Wirth 2023-12-01 14:58:57 +01:00
parent 0003e568ca
commit c11737cd63
6 changed files with 46 additions and 43 deletions

View File

@ -17,7 +17,7 @@ use crate::{
hygiene::span_with_def_site_ctxt, hygiene::span_with_def_site_ctxt,
name, quote, name, quote,
tt::{self, DelimSpan}, tt::{self, DelimSpan},
EagerCallInfo, ExpandError, ExpandResult, HirFileIdExt, MacroCallId, MacroCallLoc, ExpandError, ExpandResult, HirFileIdExt, MacroCallId, MacroCallLoc,
}; };
macro_rules! register_builtin { macro_rules! register_builtin {
@ -575,36 +575,32 @@ fn parse_string(tt: &tt::Subtree) -> Result<String, ExpandError> {
fn include_expand( fn include_expand(
db: &dyn ExpandDatabase, db: &dyn ExpandDatabase,
arg_id: MacroCallId, arg_id: MacroCallId,
_tt: &tt::Subtree, tt: &tt::Subtree,
span: SpanData, span: SpanData,
) -> ExpandResult<tt::Subtree> { ) -> ExpandResult<tt::Subtree> {
match db.include_expand(arg_id) { let path = match parse_string(tt) {
Ok((res, _)) => ExpandResult::ok(res.as_ref().clone()), Ok(it) => it,
Err(e) => ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e), Err(e) => {
} return ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e)
} }
// FIXME: Check if this is still needed now after the token map rewrite
pub(crate) fn include_arg_to_tt(
db: &dyn ExpandDatabase,
arg_id: MacroCallId,
) -> Result<(triomphe::Arc<tt::Subtree>, FileId), ExpandError> {
let loc = db.lookup_intern_macro_call(arg_id);
let Some(EagerCallInfo { arg, arg_id, .. }) = loc.eager.as_deref() else {
panic!("include_arg_to_tt called on non include macro call: {:?}", &loc.eager);
}; };
let path = parse_string(&arg)?; let file_id = match relative_file(db, arg_id, &path, false) {
let file_id = relative_file(db, *arg_id, &path, false)?; Ok(file_id) => file_id,
Err(e) => {
// why are we not going through a SyntaxNode here? return ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e);
let subtree = parse_to_token_tree( }
};
match parse_to_token_tree(
SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID },
// FIXME
SyntaxContextId::ROOT, SyntaxContextId::ROOT,
&db.file_text(file_id), &db.file_text(file_id),
) ) {
.ok_or(mbe::ExpandError::ConversionError)?; Some(it) => ExpandResult::ok(it),
Ok((triomphe::Arc::new(subtree), file_id)) None => ExpandResult::new(
tt::Subtree::empty(DelimSpan { open: span, close: span }),
ExpandError::other("failed to parse included file"),
),
}
} }
fn include_bytes_expand( fn include_bytes_expand(
@ -613,9 +609,12 @@ fn include_bytes_expand(
tt: &tt::Subtree, tt: &tt::Subtree,
span: SpanData, span: SpanData,
) -> ExpandResult<tt::Subtree> { ) -> ExpandResult<tt::Subtree> {
if let Err(e) = parse_string(tt) { let _path = match parse_string(tt) {
return ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e); Ok(it) => it,
} Err(e) => {
return ExpandResult::new(tt::Subtree::empty(DelimSpan { open: span, close: span }), e)
}
};
// FIXME: actually read the file here if the user asked for macro expansion // FIXME: actually read the file here if the user asked for macro expansion
let res = tt::Subtree { let res = tt::Subtree {

View File

@ -142,12 +142,6 @@ pub trait ExpandDatabase: SourceDatabase {
def_crate: CrateId, def_crate: CrateId,
id: AstId<ast::Macro>, id: AstId<ast::Macro>,
) -> Arc<DeclarativeMacroExpander>; ) -> Arc<DeclarativeMacroExpander>;
#[salsa::invoke(crate::builtin_fn_macro::include_arg_to_tt)]
fn include_expand(
&self,
arg_id: MacroCallId,
) -> Result<(triomphe::Arc<tt::Subtree>, base_db::FileId), ExpandError>;
/// Special case of the previous query for procedural macros. We can't LRU /// Special case of the previous query for procedural macros. We can't LRU
/// proc macros, since they are not deterministic in general, and /// proc macros, since they are not deterministic in general, and
/// non-determinism breaks salsa in a very, very, very bad way. /// non-determinism breaks salsa in a very, very, very bad way.

View File

@ -208,12 +208,7 @@ impl HirFileIdExt for HirFileId {
match file_id.repr() { match file_id.repr() {
HirFileIdRepr::FileId(id) => break id, HirFileIdRepr::FileId(id) => break id,
HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => { HirFileIdRepr::MacroFile(MacroFileId { macro_call_id }) => {
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_call_id); file_id = db.lookup_intern_macro_call(macro_call_id).kind.file_id();
let is_include_expansion = loc.def.is_include() && loc.eager.is_some();
file_id = match is_include_expansion.then(|| db.include_expand(macro_call_id)) {
Some(Ok((_, file))) => file.into(),
_ => loc.kind.file_id(),
}
} }
} }
} }

View File

@ -23,7 +23,7 @@ pub use hir_def::db::{
}; };
pub use hir_expand::db::{ pub use hir_expand::db::{
AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage, AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage,
ExpandProcMacroQuery, IncludeExpandQuery, InternMacroCallQuery, InternSyntaxContextQuery, ExpandProcMacroQuery, InternMacroCallQuery, InternSyntaxContextQuery, MacroArgQuery,
MacroArgQuery, ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery, RealSpanMapQuery, ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery, RealSpanMapQuery,
}; };
pub use hir_ty::db::*; pub use hir_ty::db::*;

View File

@ -99,7 +99,6 @@ impl RootDatabase {
hir::db::AstIdMapQuery hir::db::AstIdMapQuery
hir::db::DeclMacroExpanderQuery hir::db::DeclMacroExpanderQuery
hir::db::ExpandProcMacroQuery hir::db::ExpandProcMacroQuery
hir::db::IncludeExpandQuery
hir::db::InternMacroCallQuery hir::db::InternMacroCallQuery
hir::db::InternSyntaxContextQuery hir::db::InternSyntaxContextQuery
hir::db::MacroArgQuery hir::db::MacroArgQuery

View File

@ -67,6 +67,22 @@ macro_rules! m { () => {} } }
self::m!(); self::m2!(); self::m!(); self::m2!();
//^^ error: unresolved macro `self::m2!` //^^ error: unresolved macro `self::m2!`
"#,
);
}
#[test]
#[should_panic] // FIXME: https://github.com/rust-lang/rust-analyzer/issues/14968
fn include_does_not_break_diagnostics() {
check_diagnostics(
r#"
//- minicore: include
//- /lib.rs crate:lib
include!("include-me.rs");
//- /include-me.rs
/// long doc that pushes the diagnostic range beyond the first file's text length
#[err]
mod prim_never {}
"#, "#,
); );
} }