Skip to content

internal: Refactor SyntaxContext to not reimplement Salsa macros - #23308

Open
ChayimFriedman2 wants to merge 1 commit into
rust-lang:masterfrom
ChayimFriedman2:syntaxcontext-refactor
Open

internal: Refactor SyntaxContext to not reimplement Salsa macros#23308
ChayimFriedman2 wants to merge 1 commit into
rust-lang:masterfrom
ChayimFriedman2:syntaxcontext-refactor

Conversation

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

Instead store Options for the self-referential parts.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 7, 2026
opaque: SyntaxContext,
opaque_and_semiopaque: SyntaxContext,
opaque_if_not_self: Option<SyntaxContext>,
opaque_and_semiopaque_if_not_self: Option<SyntaxContext>,

@Veykril Veykril Sep 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still don't need to partial_eq and hash these two fields, the way apply_mark_internal works the first 4 fields will never be interned equally with differing fields for these two

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't, but I feel safer this way, and the perf impact shouldn't be large.

Comment on lines +60 to +66
#[salsa::interned(unsafe(no_lifetime), revisions = usize::MAX)]
struct SyntaxContextImpl {
data: SyntaxContextData,
}

zalsa_::register_jar! {
zalsa_::ErasedJar::erase::<SyntaxContext>()
}

/// Key to use during hash lookups. Each field is some type that implements `Lookup<T>`
/// for the owned type. This permits interning with an `&str` when a `String` is required and so forth.
#[derive(Hash)]
struct StructKey<'db, T0, T1, T2, T3>(T0, T1, T2, T3, std::marker::PhantomData<&'db ()>);

impl<'db, T0, T1, T2, T3> zalsa_::HashEqLike<StructKey<'db, T0, T1, T2, T3>> for SyntaxContextData
where
Option<MacroCallId>: zalsa_::HashEqLike<T0>,
Transparency: zalsa_::HashEqLike<T1>,
Edition: zalsa_::HashEqLike<T2>,
SyntaxContext: zalsa_::HashEqLike<T3>,
{
fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
zalsa_::HashEqLike::<T0>::hash(&self.outer_expn, &mut *h);
zalsa_::HashEqLike::<T1>::hash(&self.outer_transparency, &mut *h);
zalsa_::HashEqLike::<T2>::hash(&self.edition, &mut *h);
zalsa_::HashEqLike::<T3>::hash(&self.parent, &mut *h);
}
fn eq(&self, data: &StructKey<'db, T0, T1, T2, T3>) -> bool {
zalsa_::HashEqLike::<T0>::eq(&self.outer_expn, &data.0)
&& zalsa_::HashEqLike::<T1>::eq(&self.outer_transparency, &data.1)
&& zalsa_::HashEqLike::<T2>::eq(&self.edition, &data.2)
&& zalsa_::HashEqLike::<T3>::eq(&self.parent, &data.3)
}
}

// SAFETY: `Self::Fields`, i.e. `SyntaxContextData`, doesn't contain any lifetimes.
unsafe impl zalsa_struct_::Configuration for SyntaxContext {
const LOCATION: salsa::plumbing::Location =
salsa::plumbing::Location { file: file!(), line: line!() };
const DEBUG_NAME: &'static str = "SyntaxContextData";
const REVISIONS: std::num::NonZeroUsize = std::num::NonZeroUsize::MAX;
const PERSIST: bool = false;

type Fields<'a> = SyntaxContextData;
type Struct<'a> = SyntaxContext;

fn serialize<S>(_: &Self::Fields<'_>, _: S) -> Result<S::Ok, S::Error>
where
S: zalsa_::serde::Serializer,
{
unimplemented!("attempted to serialize value that set `PERSIST` to false")
}

fn deserialize<'de, D>(_: D) -> Result<Self::Fields<'static>, D::Error>
where
D: zalsa_::serde::Deserializer<'de>,
{
unimplemented!("attempted to deserialize value that cannot set `PERSIST` to false");
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct SyntaxContext(NonZeroU32);

@Veykril Veykril Sep 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the split here? And if there is a reason for it, why aren't we just embedding newtyping like SyntaxContext(SyntaxContextImpl)

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's easier because there are many methods. But it doesn't really matter.

Instead store `Option`s for the self-referential parts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants