From 8a5bb9d5acb664448e2f8410662b59e078c6f0f0 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 1 Mar 2024 15:09:12 +0100 Subject: [PATCH] Only the ROOT syntax context has `None` `outer_expn` --- crates/hir-expand/src/hygiene.rs | 30 ++++++++++++++++++------------ crates/hir-expand/src/mod_path.rs | 2 +- crates/span/src/hygiene.rs | 1 + 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/crates/hir-expand/src/hygiene.rs b/crates/hir-expand/src/hygiene.rs index 7f0174fa5a9..ac2bab280d5 100644 --- a/crates/hir-expand/src/hygiene.rs +++ b/crates/hir-expand/src/hygiene.rs @@ -62,7 +62,7 @@ pub(super) fn apply_mark( transparency: Transparency, ) -> SyntaxContextId { if transparency == Transparency::Opaque { - return apply_mark_internal(db, ctxt, Some(call_id), transparency); + return apply_mark_internal(db, ctxt, call_id, transparency); } let call_site_ctxt = db.lookup_intern_macro_call(call_id).call_site.ctx; @@ -73,7 +73,7 @@ pub(super) fn apply_mark( }; if call_site_ctxt.is_root() { - return apply_mark_internal(db, ctxt, Some(call_id), transparency); + return apply_mark_internal(db, ctxt, call_id, transparency); } // Otherwise, `expn_id` is a macros 1.0 definition and the call site is in a @@ -88,17 +88,19 @@ pub(super) fn apply_mark( for (call_id, transparency) in ctxt.marks(db) { call_site_ctxt = apply_mark_internal(db, call_site_ctxt, call_id, transparency); } - apply_mark_internal(db, call_site_ctxt, Some(call_id), transparency) + apply_mark_internal(db, call_site_ctxt, call_id, transparency) } fn apply_mark_internal( db: &dyn ExpandDatabase, ctxt: SyntaxContextId, - call_id: Option, + call_id: MacroCallId, transparency: Transparency, ) -> SyntaxContextId { use base_db::salsa; + let call_id = Some(call_id); + let syntax_context_data = db.lookup_intern_syntax_context(ctxt); let mut opaque = syntax_context_data.opaque; let mut opaque_and_semitransparent = syntax_context_data.opaque_and_semitransparent; @@ -148,7 +150,7 @@ pub trait SyntaxContextExt { fn parent_ctxt(self, db: &dyn ExpandDatabase) -> Self; fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option, Transparency); fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option, Transparency); - fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option, Transparency)>; + fn marks(self, db: &dyn ExpandDatabase) -> Vec<(MacroCallId, Transparency)>; } impl SyntaxContextExt for SyntaxContextId { @@ -170,7 +172,7 @@ fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option, Tran *self = data.parent; (data.outer_expn, data.outer_transparency) } - fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option, Transparency)> { + fn marks(self, db: &dyn ExpandDatabase) -> Vec<(MacroCallId, Transparency)> { let mut marks = marks_rev(self, db).collect::>(); marks.reverse(); marks @@ -181,11 +183,15 @@ fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option, Transparenc pub fn marks_rev( ctxt: SyntaxContextId, db: &dyn ExpandDatabase, -) -> impl Iterator, Transparency)> + '_ { - iter::successors(Some(ctxt), move |&mark| { - Some(mark.parent_ctxt(db)).filter(|&it| it != SyntaxContextId::ROOT) - }) - .map(|ctx| ctx.outer_mark(db)) +) -> impl Iterator + '_ { + iter::successors(Some(ctxt), move |&mark| Some(mark.parent_ctxt(db))) + .take_while(|&it| !it.is_root()) + .map(|ctx| { + let mark = ctx.outer_mark(db); + // We stop before taking the root expansion, as such we cannot encounter a `None` outer + // expansion, as only the ROOT has it. + (mark.0.unwrap(), mark.1) + }) } pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { @@ -224,7 +230,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { } } - pub fn fancy_debug( + fn fancy_debug( this: &SyntaxContextData, self_id: SyntaxContextId, db: &dyn ExpandDatabase, diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs index 136b0935be2..0cf1fadec97 100644 --- a/crates/hir-expand/src/mod_path.rs +++ b/crates/hir-expand/src/mod_path.rs @@ -358,7 +358,7 @@ pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) -> result_mark = Some(mark); } - result_mark.flatten().map(|call| db.lookup_intern_macro_call(call).def.krate) + result_mark.map(|call| db.lookup_intern_macro_call(call).def.krate) } pub use crate::name as __name; diff --git a/crates/span/src/hygiene.rs b/crates/span/src/hygiene.rs index 18da689922b..4f6d792201b 100644 --- a/crates/span/src/hygiene.rs +++ b/crates/span/src/hygiene.rs @@ -68,6 +68,7 @@ pub fn from_u32(u32: u32) -> Self { /// A syntax context describes a hierarchy tracking order of macro definitions. #[derive(Copy, Clone, Hash, PartialEq, Eq)] pub struct SyntaxContextData { + /// Invariant: Only [`SyntaxContextId::ROOT`] has a [`None`] outer expansion. pub outer_expn: Option, pub outer_transparency: Transparency, pub parent: SyntaxContextId,