Only the ROOT syntax context has None outer_expn

This commit is contained in:
Lukas Wirth 2024-03-01 15:09:12 +01:00
parent eb7a4f293e
commit 8a5bb9d5ac
3 changed files with 20 additions and 13 deletions

View File

@ -62,7 +62,7 @@ pub(super) fn apply_mark(
transparency: Transparency, transparency: Transparency,
) -> SyntaxContextId { ) -> SyntaxContextId {
if transparency == Transparency::Opaque { 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; 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() { 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 // 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) { for (call_id, transparency) in ctxt.marks(db) {
call_site_ctxt = apply_mark_internal(db, call_site_ctxt, call_id, transparency); 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( fn apply_mark_internal(
db: &dyn ExpandDatabase, db: &dyn ExpandDatabase,
ctxt: SyntaxContextId, ctxt: SyntaxContextId,
call_id: Option<MacroCallId>, call_id: MacroCallId,
transparency: Transparency, transparency: Transparency,
) -> SyntaxContextId { ) -> SyntaxContextId {
use base_db::salsa; use base_db::salsa;
let call_id = Some(call_id);
let syntax_context_data = db.lookup_intern_syntax_context(ctxt); let syntax_context_data = db.lookup_intern_syntax_context(ctxt);
let mut opaque = syntax_context_data.opaque; let mut opaque = syntax_context_data.opaque;
let mut opaque_and_semitransparent = syntax_context_data.opaque_and_semitransparent; 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 parent_ctxt(self, db: &dyn ExpandDatabase) -> Self;
fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency); fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency);
fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency); fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency);
fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option<MacroCallId>, Transparency)>; fn marks(self, db: &dyn ExpandDatabase) -> Vec<(MacroCallId, Transparency)>;
} }
impl SyntaxContextExt for SyntaxContextId { impl SyntaxContextExt for SyntaxContextId {
@ -170,7 +172,7 @@ impl SyntaxContextExt for SyntaxContextId {
*self = data.parent; *self = data.parent;
(data.outer_expn, data.outer_transparency) (data.outer_expn, data.outer_transparency)
} }
fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option<MacroCallId>, Transparency)> { fn marks(self, db: &dyn ExpandDatabase) -> Vec<(MacroCallId, Transparency)> {
let mut marks = marks_rev(self, db).collect::<Vec<_>>(); let mut marks = marks_rev(self, db).collect::<Vec<_>>();
marks.reverse(); marks.reverse();
marks marks
@ -181,11 +183,15 @@ impl SyntaxContextExt for SyntaxContextId {
pub fn marks_rev( pub fn marks_rev(
ctxt: SyntaxContextId, ctxt: SyntaxContextId,
db: &dyn ExpandDatabase, db: &dyn ExpandDatabase,
) -> impl Iterator<Item = (Option<MacroCallId>, Transparency)> + '_ { ) -> impl Iterator<Item = (MacroCallId, Transparency)> + '_ {
iter::successors(Some(ctxt), move |&mark| { iter::successors(Some(ctxt), move |&mark| Some(mark.parent_ctxt(db)))
Some(mark.parent_ctxt(db)).filter(|&it| it != SyntaxContextId::ROOT) .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)
}) })
.map(|ctx| ctx.outer_mark(db))
} }
pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String { pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String {
@ -224,7 +230,7 @@ pub(crate) fn dump_syntax_contexts(db: &dyn ExpandDatabase) -> String {
} }
} }
pub fn fancy_debug( fn fancy_debug(
this: &SyntaxContextData, this: &SyntaxContextData,
self_id: SyntaxContextId, self_id: SyntaxContextId,
db: &dyn ExpandDatabase, db: &dyn ExpandDatabase,

View File

@ -358,7 +358,7 @@ pub fn resolve_crate_root(db: &dyn ExpandDatabase, mut ctxt: SyntaxContextId) ->
result_mark = Some(mark); 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; pub use crate::name as __name;

View File

@ -68,6 +68,7 @@ impl SyntaxContextId {
/// A syntax context describes a hierarchy tracking order of macro definitions. /// A syntax context describes a hierarchy tracking order of macro definitions.
#[derive(Copy, Clone, Hash, PartialEq, Eq)] #[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct SyntaxContextData { pub struct SyntaxContextData {
/// Invariant: Only [`SyntaxContextId::ROOT`] has a [`None`] outer expansion.
pub outer_expn: Option<MacroCallId>, pub outer_expn: Option<MacroCallId>,
pub outer_transparency: Transparency, pub outer_transparency: Transparency,
pub parent: SyntaxContextId, pub parent: SyntaxContextId,