Skip to content

internal: Remove SELF_REF hack for self referential SyntaxContexts #16527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ use std::{
panic::{RefUnwindSafe, UnwindSafe},
};

use base_db::{impl_intern_key, salsa, CrateId, Edition};
use base_db::{
impl_intern_key,
salsa::{self, impl_intern_value_trivial},
CrateId, Edition,
};
use hir_expand::{
ast_id_map::{AstIdNode, FileAstId},
builtin_attr_macro::BuiltinAttrExpander,
Expand Down Expand Up @@ -171,6 +175,7 @@ pub trait ItemTreeLoc {
macro_rules! impl_intern {
($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
impl_intern_key!($id);
impl_intern_value_trivial!($loc);
impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup);
};
}
Expand Down Expand Up @@ -490,6 +495,7 @@ pub struct TypeOrConstParamId {
pub parent: GenericDefId,
pub local_id: LocalTypeOrConstParamId,
}
impl_intern_value_trivial!(TypeOrConstParamId);

/// A TypeOrConstParamId with an invariant that it actually belongs to a type
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -551,6 +557,7 @@ pub struct LifetimeParamId {
pub local_id: LocalLifetimeParamId,
}
pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
impl_intern_value_trivial!(LifetimeParamId);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ItemContainerId {
Expand Down
10 changes: 5 additions & 5 deletions crates/hir-def/src/macro_expansion_tests/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ macro_rules! f {
};
}

struct#0:[email protected]#2# MyTraitMap2#0:[email protected]#0# {#0:[email protected]#2#
map#0:[email protected]#2#:#0:[email protected]#2# #0:[email protected]#2#::#0:[email protected]#2#std#0:[email protected]#2#::#0:[email protected]#2#collections#0:[email protected]#2#::#0:[email protected]#2#HashSet#0:[email protected]#2#<#0:[email protected]#2#(#0:[email protected]#2#)#0:[email protected]#2#>#0:[email protected]#2#,#0:[email protected]#2#
}#0:[email protected]#2#
struct#0:[email protected]#1# MyTraitMap2#0:[email protected]#0# {#0:[email protected]#1#
map#0:[email protected]#1#:#0:[email protected]#1# #0:[email protected]#1#::#0:[email protected]#1#std#0:[email protected]#1#::#0:[email protected]#1#collections#0:[email protected]#1#::#0:[email protected]#1#HashSet#0:[email protected]#1#<#0:[email protected]#1#(#0:[email protected]#1#)#0:[email protected]#1#>#0:[email protected]#1#,#0:[email protected]#1#
}#0:[email protected]#1#
"#]],
);
}
Expand Down Expand Up @@ -171,7 +171,7 @@ fn main(foo: ()) {
}

fn main(foo: ()) {
/* error: unresolved macro unresolved */"helloworld!"#0:[email protected]#6#;
/* error: unresolved macro unresolved */"helloworld!"#0:[email protected]#2#;
}
}

Expand All @@ -197,7 +197,7 @@ macro_rules! mk_struct {
#[macro_use]
mod foo;

struct#1:[email protected]#2# Foo#0:[email protected]#0#(#1:[email protected]#2#u32#0:[email protected]#0#)#1:[email protected]#2#;#1:[email protected]#2#
struct#1:[email protected]#1# Foo#0:[email protected]#0#(#1:[email protected]#1#u32#0:[email protected]#0#)#1:[email protected]#1#;#1:[email protected]#1#
"#]],
);
}
Expand Down
71 changes: 35 additions & 36 deletions crates/hir-expand/src/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

use std::iter;

use base_db::salsa::{self, InternValue};
use span::{MacroCallId, Span, SyntaxContextId};

use crate::db::ExpandDatabase;
use crate::db::{ExpandDatabase, InternSyntaxContextQuery};

#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct SyntaxContextData {
Expand All @@ -22,6 +23,14 @@ pub struct SyntaxContextData {
pub opaque_and_semitransparent: SyntaxContextId,
}

impl InternValue for SyntaxContextData {
type Key = (SyntaxContextId, Option<MacroCallId>, Transparency);

fn into_key(&self) -> Self::Key {
(self.parent, self.outer_expn, self.outer_transparency)
}
}

impl std::fmt::Debug for SyntaxContextData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SyntaxContextData")
Expand Down Expand Up @@ -149,38 +158,36 @@ fn apply_mark_internal(
transparency: Transparency,
) -> SyntaxContextId {
let syntax_context_data = db.lookup_intern_syntax_context(ctxt);
let mut opaque = handle_self_ref(ctxt, syntax_context_data.opaque);
let mut opaque_and_semitransparent =
handle_self_ref(ctxt, syntax_context_data.opaque_and_semitransparent);
let mut opaque = syntax_context_data.opaque;
let mut opaque_and_semitransparent = syntax_context_data.opaque_and_semitransparent;

if transparency >= Transparency::Opaque {
let parent = opaque;
// Unlike rustc, with salsa we can't prefetch the to be allocated ID to create cycles with
// salsa when interning, so we use a sentinel value that effectively means the current
// syntax context.
let new_opaque = SyntaxContextId::SELF_REF;
opaque = db.intern_syntax_context(SyntaxContextData {
outer_expn: call_id,
outer_transparency: transparency,
parent,
opaque: new_opaque,
opaque_and_semitransparent: new_opaque,
});
opaque = salsa::plumbing::get_query_table::<InternSyntaxContextQuery>(db).get_or_insert(
(parent, call_id, transparency),
|new_opaque| SyntaxContextData {
outer_expn: call_id,
outer_transparency: transparency,
parent,
opaque: new_opaque,
opaque_and_semitransparent: new_opaque,
},
);
}

if transparency >= Transparency::SemiTransparent {
let parent = opaque_and_semitransparent;
// Unlike rustc, with salsa we can't prefetch the to be allocated ID to create cycles with
// salsa when interning, so we use a sentinel value that effectively means the current
// syntax context.
let new_opaque_and_semitransparent = SyntaxContextId::SELF_REF;
opaque_and_semitransparent = db.intern_syntax_context(SyntaxContextData {
outer_expn: call_id,
outer_transparency: transparency,
parent,
opaque,
opaque_and_semitransparent: new_opaque_and_semitransparent,
});
opaque_and_semitransparent =
salsa::plumbing::get_query_table::<InternSyntaxContextQuery>(db).get_or_insert(
(parent, call_id, transparency),
|new_opaque_and_semitransparent| SyntaxContextData {
outer_expn: call_id,
outer_transparency: transparency,
parent,
opaque,
opaque_and_semitransparent: new_opaque_and_semitransparent,
},
);
}

let parent = ctxt;
Expand All @@ -201,20 +208,12 @@ pub trait SyntaxContextExt {
fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option<MacroCallId>, Transparency)>;
}

#[inline(always)]
fn handle_self_ref(p: SyntaxContextId, n: SyntaxContextId) -> SyntaxContextId {
match n {
SyntaxContextId::SELF_REF => p,
_ => n,
}
}

impl SyntaxContextExt for SyntaxContextId {
fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> Self {
handle_self_ref(self, db.lookup_intern_syntax_context(self).opaque_and_semitransparent)
db.lookup_intern_syntax_context(self).opaque_and_semitransparent
}
fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> Self {
handle_self_ref(self, db.lookup_intern_syntax_context(self).opaque)
db.lookup_intern_syntax_context(self).opaque
}
fn parent_ctxt(self, db: &dyn ExpandDatabase) -> Self {
db.lookup_intern_syntax_context(self).parent
Expand Down
3 changes: 2 additions & 1 deletion crates/hir-expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use triomphe::Arc;

use std::{fmt, hash::Hash};

use base_db::{CrateId, Edition, FileId};
use base_db::{salsa::impl_intern_value_trivial, CrateId, Edition, FileId};
use either::Either;
use span::{FileRange, HirFileIdRepr, Span, SyntaxContextId};
use syntax::{
Expand Down Expand Up @@ -176,6 +176,7 @@ pub struct MacroCallLoc {
pub kind: MacroCallKind,
pub call_site: Span,
}
impl_intern_value_trivial!(MacroCallLoc);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroDefId {
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use hir_def::{
use hir_expand::name::name;

use crate::{
db::HirDatabase,
db::{HirDatabase, InternedCoroutine},
display::HirDisplay,
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, make_binders,
make_single_type_binders,
Expand Down Expand Up @@ -428,7 +428,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
&self,
id: chalk_ir::CoroutineId<Interner>,
) -> Arc<chalk_solve::rust_ir::CoroutineDatum<Interner>> {
let (parent, expr) = self.db.lookup_intern_coroutine(id.into());
let InternedCoroutine(parent, expr) = self.db.lookup_intern_coroutine(id.into());

// We fill substitution with unknown type, because we only need to know whether the generic
// params are types or consts to build `Binders` and those being filled up are for
Expand Down Expand Up @@ -473,7 +473,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
let inner_types =
rust_ir::CoroutineWitnessExistential { types: wrap_empty_binders(vec![]) };

let (parent, _) = self.db.lookup_intern_coroutine(id.into());
let InternedCoroutine(parent, _) = self.db.lookup_intern_coroutine(id.into());
// See the comment in `coroutine_datum()` for unknown types.
let subst = TyBuilder::subst_for_coroutine(self.db, parent).fill_with_unknown().build();
let it = subst
Expand Down
18 changes: 15 additions & 3 deletions crates/hir-ty/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

use std::sync;

use base_db::{impl_intern_key, salsa, CrateId, Upcast};
use base_db::{
impl_intern_key,
salsa::{self, impl_intern_value_trivial},
CrateId, Upcast,
};
use hir_def::{
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, ConstParamId,
DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
Expand Down Expand Up @@ -199,9 +203,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::interned]
fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
#[salsa::interned]
fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
fn intern_closure(&self, id: InternedClosure) -> InternedClosureId;
#[salsa::interned]
fn intern_coroutine(&self, id: (DefWithBodyId, ExprId)) -> InternedCoroutineId;
fn intern_coroutine(&self, id: InternedCoroutine) -> InternedCoroutineId;

#[salsa::invoke(chalk_db::associated_ty_data_query)]
fn associated_ty_data(
Expand Down Expand Up @@ -337,10 +341,18 @@ impl_intern_key!(InternedOpaqueTyId);
pub struct InternedClosureId(salsa::InternId);
impl_intern_key!(InternedClosureId);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InternedClosure(pub DefWithBodyId, pub ExprId);
impl_intern_value_trivial!(InternedClosure);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InternedCoroutineId(salsa::InternId);
impl_intern_key!(InternedCoroutineId);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InternedCoroutine(pub DefWithBodyId, pub ExprId);
impl_intern_value_trivial!(InternedCoroutine);

/// This exists just for Chalk, because Chalk just has a single `FnDefId` where
/// we have different IDs for struct and enum variant constructors.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use triomphe::Arc;

use crate::{
consteval::try_const_usize,
db::HirDatabase,
db::{HirDatabase, InternedClosure},
from_assoc_type_id, from_foreign_def_id, from_placeholder_idx,
layout::Layout,
lt_from_placeholder_idx,
Expand Down Expand Up @@ -1085,7 +1085,7 @@ impl HirDisplay for Ty {
}
let sig = ClosureSubst(substs).sig_ty().callable_sig(db);
if let Some(sig) = sig {
let (def, _) = db.lookup_intern_closure((*id).into());
let InternedClosure(def, _) = db.lookup_intern_closure((*id).into());
let infer = db.infer(def);
let (_, kind) = infer.closure_info(id);
match f.closure_style {
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use smallvec::SmallVec;
use stdx::never;

use crate::{
db::HirDatabase,
db::{HirDatabase, InternedClosure},
from_placeholder_idx, make_binders,
mir::{BorrowKind, MirSpan, ProjectionElem},
static_lifetime, to_chalk_trait_id,
Expand Down Expand Up @@ -716,7 +716,7 @@ impl InferenceContext<'_> {

fn is_upvar(&self, place: &HirPlace) -> bool {
if let Some(c) = self.current_closure {
let (_, root) = self.db.lookup_intern_closure(c.into());
let InternedClosure(_, root) = self.db.lookup_intern_closure(c.into());
return self.body.is_binding_upvar(place.local, root);
}
false
Expand Down Expand Up @@ -938,7 +938,7 @@ impl InferenceContext<'_> {
}

fn analyze_closure(&mut self, closure: ClosureId) -> FnTrait {
let (_, root) = self.db.lookup_intern_closure(closure.into());
let InternedClosure(_, root) = self.db.lookup_intern_closure(closure.into());
self.current_closure = Some(closure);
let Expr::Closure { body, capture_by, .. } = &self.body[root] else {
unreachable!("Closure expression id is always closure");
Expand Down
9 changes: 7 additions & 2 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use syntax::ast::RangeOp;
use crate::{
autoderef::{builtin_deref, deref_by_trait, Autoderef},
consteval,
db::{InternedClosure, InternedCoroutine},
infer::{
coerce::{CoerceMany, CoercionCause},
find_continuable,
Expand Down Expand Up @@ -253,13 +254,17 @@ impl InferenceContext<'_> {
.push(ret_ty.clone())
.build();

let coroutine_id = self.db.intern_coroutine((self.owner, tgt_expr)).into();
let coroutine_id = self
.db
.intern_coroutine(InternedCoroutine(self.owner, tgt_expr))
.into();
let coroutine_ty = TyKind::Coroutine(coroutine_id, subst).intern(Interner);

(None, coroutine_ty, Some((resume_ty, yield_ty)))
}
ClosureKind::Closure | ClosureKind::Async => {
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
let closure_id =
self.db.intern_closure(InternedClosure(self.owner, tgt_expr)).into();
let closure_ty = TyKind::Closure(
closure_id,
TyBuilder::subst_for_closure(self.db, self.owner, sig_ty.clone()),
Expand Down
10 changes: 7 additions & 3 deletions crates/hir-ty/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ use stdx::never;
use triomphe::Arc;

use crate::{
consteval::try_const_usize, db::HirDatabase, infer::normalize, layout::adt::struct_variant_idx,
utils::ClosureSubst, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
consteval::try_const_usize,
db::{HirDatabase, InternedClosure},
infer::normalize,
layout::adt::struct_variant_idx,
utils::ClosureSubst,
Interner, ProjectionTy, Substitution, TraitEnvironment, Ty,
};

pub use self::{
Expand Down Expand Up @@ -391,7 +395,7 @@ pub fn layout_of_ty_query(
}
}
TyKind::Closure(c, subst) => {
let (def, _) = db.lookup_intern_closure((*c).into());
let InternedClosure(def, _) = db.lookup_intern_closure((*c).into());
let infer = db.infer(def);
let (captures, _) = infer.closure_info(c);
let fields = captures
Expand Down
2 changes: 2 additions & 0 deletions crates/hir-ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use std::{
hash::{BuildHasherDefault, Hash},
};

use base_db::salsa::impl_intern_value_trivial;
use chalk_ir::{
fold::{Shift, TypeFoldable},
interner::HasInterner,
Expand Down Expand Up @@ -586,6 +587,7 @@ pub enum ImplTraitId {
ReturnTypeImplTrait(hir_def::FunctionId, RpitId),
AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
}
impl_intern_value_trivial!(ImplTraitId);

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct ReturnTypeImplTraits {
Expand Down
Loading