From abe31774459740d12c1d25ec4a8a85a54ba96f60 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 13 Mar 2024 18:05:27 +0100 Subject: [PATCH] Shrink MacroCallLoc --- crates/hir-def/src/data.rs | 2 + crates/hir-def/src/lib.rs | 4 +- crates/hir-def/src/nameres/attr_resolution.rs | 4 +- crates/hir-def/src/nameres/collector.rs | 6 +- crates/hir-expand/src/db.rs | 57 +++++++++++-------- crates/hir-expand/src/eager.rs | 23 ++++++-- crates/hir-expand/src/lib.rs | 18 +++--- 7 files changed, 69 insertions(+), 45 deletions(-) diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index d4c1db8b95b..f84852b2629 100644 --- a/crates/hir-def/src/data.rs +++ b/crates/hir-def/src/data.rs @@ -745,6 +745,7 @@ fn collect_item( self.collect_macro_items(res, &|| hir_expand::MacroCallKind::FnLike { ast_id: InFile::new(file_id, ast_id), expand_to: hir_expand::ExpandTo::Items, + eager: None, }); } Ok(None) => (), @@ -754,6 +755,7 @@ fn collect_item( MacroCallKind::FnLike { ast_id: InFile::new(file_id, ast_id), expand_to, + eager: None, }, Clone::clone(path), )); diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index d63f2268aa4..ae2959dff62 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -1410,10 +1410,10 @@ fn macro_call_as_call_id_with_eager( }) } _ if def.is_fn_like() => ExpandResult { - value: Some(def.as_lazy_macro( + value: Some(def.make_call( db, krate, - MacroCallKind::FnLike { ast_id: call.ast_id, expand_to }, + MacroCallKind::FnLike { ast_id: call.ast_id, expand_to, eager: None }, call_site, )), err: None, diff --git a/crates/hir-def/src/nameres/attr_resolution.rs b/crates/hir-def/src/nameres/attr_resolution.rs index 1cadae8c87c..25744e9570e 100644 --- a/crates/hir-def/src/nameres/attr_resolution.rs +++ b/crates/hir-def/src/nameres/attr_resolution.rs @@ -116,7 +116,7 @@ pub(super) fn attr_macro_as_call_id( _ => None, }; - def.as_lazy_macro( + def.make_call( db.upcast(), krate, MacroCallKind::Attr { @@ -140,7 +140,7 @@ pub(super) fn derive_macro_as_call_id( let (macro_id, def_id) = resolver(item_attr.path.clone()) .filter(|(_, def_id)| def_id.is_derive()) .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?; - let call_id = def_id.as_lazy_macro( + let call_id = def_id.make_call( db.upcast(), krate, MacroCallKind::Derive { diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index f9fe6d3b903..593a88af694 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -1451,7 +1451,11 @@ fn finish(mut self) -> DefMap { if let Err(UnresolvedMacro { path }) = macro_call_as_call_id { self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( directive.module_id, - MacroCallKind::FnLike { ast_id: ast_id.ast_id, expand_to: *expand_to }, + MacroCallKind::FnLike { + ast_id: ast_id.ast_id, + expand_to: *expand_to, + eager: None, + }, path, )); } diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index 632d8f2bcb8..1639ce189e0 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -332,15 +332,16 @@ pub(crate) fn parse_with_map( fn macro_arg( db: &dyn ExpandDatabase, id: MacroCallId, - // FIXME: consider the following by putting fixup info into eager call info args - // ) -> ValueResult, Arc>> { ) -> ValueResult<(Arc, SyntaxFixupUndoInfo), Arc>> { let loc = db.lookup_intern_macro_call(id); - if let Some(EagerCallInfo { arg, .. }) = matches!(loc.def.kind, MacroDefKind::BuiltInEager(..)) - .then(|| loc.eager.as_deref()) - .flatten() + + if let MacroCallLoc { + def: MacroDefId { kind: MacroDefKind::BuiltInEager(..), .. }, + kind: MacroCallKind::FnLike { eager: Some(eager), .. }, + .. + } = &loc { - return ValueResult::ok((arg.clone(), SyntaxFixupUndoInfo::NONE)); + return ValueResult::ok((eager.arg.clone(), SyntaxFixupUndoInfo::NONE)); } let (parse, map) = parse_with_map(db, loc.kind.file_id()); @@ -518,7 +519,7 @@ fn macro_expand( ) -> ExpandResult> { let _p = tracing::span!(tracing::Level::INFO, "macro_expand").entered(); - let ExpandResult { value: tt, mut err } = match loc.def.kind { + let ExpandResult { value: tt, err } = match loc.def.kind { MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(macro_call_id).map(CowArc::Arc), _ => { let ValueResult { value: (macro_arg, undo_info), err } = db.macro_arg(macro_call_id); @@ -541,23 +542,34 @@ fn macro_expand( MacroDefKind::BuiltIn(it, _) => { it.expand(db, macro_call_id, arg).map_err(Into::into) } - // This might look a bit odd, but we do not expand the inputs to eager macros here. - // Eager macros inputs are expanded, well, eagerly when we collect the macro calls. - // That kind of expansion uses the ast id map of an eager macros input though which goes through - // the HirFileId machinery. As eager macro inputs are assigned a macro file id that query - // will end up going through here again, whereas we want to just want to inspect the raw input. - // As such we just return the input subtree here. - MacroDefKind::BuiltInEager(..) if loc.eager.is_none() => { - return ExpandResult { - value: CowArc::Arc(macro_arg.clone()), - err: err.map(format_parse_err), - }; - } MacroDefKind::BuiltInDerive(it, _) => { it.expand(db, macro_call_id, arg).map_err(Into::into) } MacroDefKind::BuiltInEager(it, _) => { - it.expand(db, macro_call_id, arg).map_err(Into::into) + // This might look a bit odd, but we do not expand the inputs to eager macros here. + // Eager macros inputs are expanded, well, eagerly when we collect the macro calls. + // That kind of expansion uses the ast id map of an eager macros input though which goes through + // the HirFileId machinery. As eager macro inputs are assigned a macro file id that query + // will end up going through here again, whereas we want to just want to inspect the raw input. + // As such we just return the input subtree here. + let eager = match &loc.kind { + MacroCallKind::FnLike { eager: None, .. } => { + return ExpandResult { + value: CowArc::Arc(macro_arg.clone()), + err: err.map(format_parse_err), + }; + } + MacroCallKind::FnLike { eager: Some(eager), .. } => Some(&**eager), + _ => None, + }; + + let mut res = it.expand(db, macro_call_id, arg).map_err(Into::into); + + if let Some(EagerCallInfo { error, .. }) = eager { + // FIXME: We should report both errors! + res.err = error.clone().or(res.err); + } + res } MacroDefKind::BuiltInAttr(it, _) => { let mut res = it.expand(db, macro_call_id, arg); @@ -574,11 +586,6 @@ fn macro_expand( } }; - if let Some(EagerCallInfo { error, .. }) = loc.eager.as_deref() { - // FIXME: We should report both errors! - err = error.clone().or(err); - } - // Skip checking token tree limit for include! macro call if !loc.def.is_include() { // Set a hard limit for the expanded tt diff --git a/crates/hir-expand/src/eager.rs b/crates/hir-expand/src/eager.rs index 5337a5bb028..e8ca4315eaf 100644 --- a/crates/hir-expand/src/eager.rs +++ b/crates/hir-expand/src/eager.rs @@ -40,7 +40,6 @@ pub fn expand_eager_macro_input( resolver: &dyn Fn(ModPath) -> Option, ) -> ExpandResult> { let ast_map = db.ast_id_map(macro_call.file_id); - // the expansion which the ast id map is built upon has no whitespace, so the offsets are wrong as macro_call is from the token tree that has whitespace! let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(¯o_call.value)); let expand_to = ExpandTo::from_call_site(¯o_call.value); @@ -51,8 +50,7 @@ pub fn expand_eager_macro_input( let arg_id = MacroCallLoc { def, krate, - eager: None, - kind: MacroCallKind::FnLike { ast_id: call_id, expand_to: ExpandTo::Expr }, + kind: MacroCallKind::FnLike { ast_id: call_id, expand_to: ExpandTo::Expr, eager: None }, call_site, } .intern(db); @@ -89,8 +87,16 @@ pub fn expand_eager_macro_input( let loc = MacroCallLoc { def, krate, - eager: Some(Arc::new(EagerCallInfo { arg: Arc::new(subtree), arg_id, error: err.clone() })), - kind: MacroCallKind::FnLike { ast_id: call_id, expand_to }, + + kind: MacroCallKind::FnLike { + ast_id: call_id, + expand_to, + eager: Some(Arc::new(EagerCallInfo { + arg: Arc::new(subtree), + arg_id, + error: err.clone(), + })), + }, call_site, }; @@ -108,7 +114,12 @@ fn lazy_expand( let expand_to = ExpandTo::from_call_site(¯o_call.value); let ast_id = macro_call.with_value(ast_id); - let id = def.as_lazy_macro(db, krate, MacroCallKind::FnLike { ast_id, expand_to }, call_site); + let id = def.make_call( + db, + krate, + MacroCallKind::FnLike { ast_id, expand_to, eager: None }, + call_site, + ); let macro_file = id.as_macro_file(); db.parse_macro_expansion(macro_file) diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index 838cb4f38fc..cf1bdce7ed3 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -170,11 +170,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub struct MacroCallLoc { pub def: MacroDefId, pub krate: CrateId, - /// Some if this is a macro call for an eager macro. Note that this is `None` - /// for the eager input macro file. - // FIXME: This is being interned, subtrees can vary quickly differ just slightly causing - // leakage problems here - eager: Option>, pub kind: MacroCallKind, // FIXME: Spans while relative to an anchor, are still rather unstable pub call_site: Span, @@ -215,6 +210,11 @@ pub enum MacroCallKind { FnLike { ast_id: AstId, expand_to: ExpandTo, + /// Some if this is a macro call for an eager macro. Note that this is `None` + /// for the eager input macro file. + // FIXME: This is being interned, subtrees can vary quickly differ just slightly causing + // leakage problems here + eager: Option>, }, Derive { ast_id: AstId, @@ -276,7 +276,7 @@ fn original_file_respecting_includes(mut self, db: &dyn ExpandDatabase) -> FileI HirFileIdRepr::MacroFile(file) => { let loc = db.lookup_intern_macro_call(file.macro_call_id); if loc.def.is_include() { - if let Some(eager) = &loc.eager { + if let MacroCallKind::FnLike { eager: Some(eager), .. } = &loc.kind { if let Ok(it) = builtin_fn_macro::include_input_to_file_id( db, file.macro_call_id, @@ -406,14 +406,14 @@ fn is_derive_attr_pseudo_expansion(&self, db: &dyn ExpandDatabase) -> bool { } impl MacroDefId { - pub fn as_lazy_macro( + pub fn make_call( self, db: &dyn ExpandDatabase, krate: CrateId, kind: MacroCallKind, call_site: Span, ) -> MacroCallId { - MacroCallLoc { def: self, krate, eager: None, kind, call_site }.intern(db) + MacroCallLoc { def: self, krate, kind, call_site }.intern(db) } pub fn definition_range(&self, db: &dyn ExpandDatabase) -> InFile { @@ -535,7 +535,7 @@ pub fn include_file_id( macro_call_id: MacroCallId, ) -> Option { if self.def.is_include() { - if let Some(eager) = &self.eager { + if let MacroCallKind::FnLike { eager: Some(eager), .. } = &self.kind { if let Ok(it) = builtin_fn_macro::include_input_to_file_id(db, macro_call_id, &eager.arg) {