Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 05f375e

Browse files
committed
hygiene 2.0
1 parent e36b3f7 commit 05f375e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+750
-450
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ authors = ["rust-analyzer team"]
1212
[profile.dev]
1313
# Disabling debug info speeds up builds a bunch,
1414
# and we don't rely on it for debugging that much.
15-
debug = 0
15+
debug = 1
1616

1717
[profile.dev.package]
1818
# These speed up local tests.

crates/base-db/src/span.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,18 @@ pub struct SyntaxContextId(InternId);
1717
crate::impl_intern_key!(SyntaxContextId);
1818

1919
impl SyntaxContext for SyntaxContextId {
20+
const DUMMY: Self = Self::ROOT;
21+
// veykril(HACK): salsa doesn't allow us fetching the id of the current input to be allocated so
22+
// we need a special value that behaves as the current context.
23+
}
24+
// inherent trait impls please tyvm
25+
impl SyntaxContextId {
26+
// FIXME: This is very much UB, salsa exposes no way to create an InternId in a const context
27+
// currently (which kind of makes sense but we need it here!)
28+
pub const ROOT: Self = SyntaxContextId(unsafe { core::mem::transmute(1) });
2029
// FIXME: This is very much UB, salsa exposes no way to create an InternId in a const context
2130
// currently (which kind of makes sense but we need it here!)
22-
const DUMMY: Self = SyntaxContextId(unsafe { core::mem::transmute(1) });
31+
pub const SELF_REF: Self = SyntaxContextId(unsafe { core::mem::transmute(!0u32) });
2332
}
2433

2534
#[derive(Copy, Clone, PartialEq, Eq, Hash)]

crates/hir-def/src/data.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ impl<'a> AssocItemCollector<'a> {
706706
}
707707
AssocItem::MacroCall(call) => {
708708
let file_id = self.expander.current_file_id();
709-
let MacroCall { ast_id, expand_to, ref path } = item_tree[call];
709+
let MacroCall { ast_id, expand_to, call_site, ref path } = item_tree[call];
710710
let module = self.expander.module.local_id;
711711

712712
let resolver = |path| {
@@ -725,6 +725,7 @@ impl<'a> AssocItemCollector<'a> {
725725
match macro_call_as_call_id(
726726
self.db.upcast(),
727727
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
728+
call_site,
728729
expand_to,
729730
self.expander.module.krate(),
730731
resolver,

crates/hir-def/src/expander.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ use base_db::{
77
use cfg::CfgOptions;
88
use drop_bomb::DropBomb;
99
use hir_expand::{
10-
attrs::RawAttrs, hygiene::Hygiene, mod_path::ModPath, ExpandError, ExpandResult, HirFileId,
11-
InFile, MacroCallId, UnresolvedMacro,
10+
attrs::RawAttrs, mod_path::ModPath, ExpandError, ExpandResult, HirFileId, InFile, MacroCallId,
11+
SpanMap, UnresolvedMacro,
1212
};
1313
use limit::Limit;
1414
use syntax::{ast, Parse, SyntaxNode};
15+
use triomphe::Arc;
1516

1617
use crate::{
1718
attr::Attrs, db::DefDatabase, lower::LowerCtx, macro_id_to_def_id, path::Path, AsMacroCall,
@@ -21,7 +22,7 @@ use crate::{
2122
#[derive(Debug)]
2223
pub struct Expander {
2324
cfg_options: CfgOptions,
24-
hygiene: Hygiene,
25+
hygiene: Arc<SpanMap>,
2526
krate: CrateId,
2627
pub(crate) current_file_id: HirFileId,
2728
pub(crate) module: ModuleId,
@@ -44,7 +45,7 @@ impl Expander {
4445
recursion_depth: 0,
4546
recursion_limit,
4647
cfg_options: db.crate_graph()[module.krate].cfg_options.clone(),
47-
hygiene: Hygiene::new(db.upcast(), current_file_id),
48+
hygiene: db.span_map(current_file_id),
4849
krate: module.krate,
4950
}
5051
}
@@ -98,7 +99,7 @@ impl Expander {
9899
}
99100

100101
pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) {
101-
self.hygiene = Hygiene::new(db.upcast(), mark.file_id);
102+
self.hygiene = db.span_map(mark.file_id);
102103
self.current_file_id = mark.file_id;
103104
if self.recursion_depth == u32::MAX {
104105
// Recursion limit has been reached somewhere in the macro expansion tree. Reset the
@@ -113,7 +114,7 @@ impl Expander {
113114
}
114115

115116
pub fn ctx<'a>(&self, db: &'a dyn DefDatabase) -> LowerCtx<'a> {
116-
LowerCtx::new(db, &self.hygiene, self.current_file_id)
117+
LowerCtx::new(db, self.hygiene.clone(), self.current_file_id)
117118
}
118119

119120
pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> {
@@ -143,7 +144,7 @@ impl Expander {
143144
}
144145

145146
pub(crate) fn parse_path(&mut self, db: &dyn DefDatabase, path: ast::Path) -> Option<Path> {
146-
let ctx = LowerCtx::new(db, &self.hygiene, self.current_file_id);
147+
let ctx = LowerCtx::new(db, self.hygiene.clone(), self.current_file_id);
147148
Path::from_src(path, &ctx)
148149
}
149150

@@ -187,7 +188,7 @@ impl Expander {
187188
let parse = value.cast::<T>()?;
188189

189190
self.recursion_depth += 1;
190-
self.hygiene = Hygiene::new(db.upcast(), file_id);
191+
self.hygiene = db.span_map(file_id);
191192
let old_file_id = std::mem::replace(&mut self.current_file_id, file_id);
192193
let mark = Mark {
193194
file_id: old_file_id,

crates/hir-def/src/find_path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ fn find_local_import_locations(
586586
#[cfg(test)]
587587
mod tests {
588588
use base_db::fixture::WithFixture;
589-
use hir_expand::hygiene::Hygiene;
589+
use hir_expand::SpanMap;
590590
use syntax::ast::AstNode;
591591

592592
use crate::test_db::TestDB;
@@ -608,7 +608,7 @@ mod tests {
608608
let parsed_path_file = syntax::SourceFile::parse(&format!("use {path};"));
609609
let ast_path =
610610
parsed_path_file.syntax_node().descendants().find_map(syntax::ast::Path::cast).unwrap();
611-
let mod_path = ModPath::from_src(&db, ast_path, &Hygiene::new_unhygienic()).unwrap();
611+
let mod_path = ModPath::from_src(&db, ast_path, &SpanMap::default()).unwrap();
612612

613613
let def_map = module.def_map(&db);
614614
let resolved = def_map

crates/hir-def/src/item_tree.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,13 @@ use std::{
4444

4545
use ast::{AstNode, HasName, StructKind};
4646
use base_db::{
47-
span::{SpanAnchor, ROOT_ERASED_FILE_AST_ID},
47+
span::{SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID},
4848
CrateId,
4949
};
5050
use either::Either;
5151
use hir_expand::{
5252
ast_id_map::{AstIdNode, FileAstId},
5353
attrs::RawAttrs,
54-
hygiene::Hygiene,
5554
name::{name, AsName, Name},
5655
ExpandTo, HirFileId, InFile,
5756
};
@@ -122,7 +121,7 @@ impl ItemTree {
122121
let mut item_tree = match_ast! {
123122
match syntax {
124123
ast::SourceFile(file) => {
125-
top_attrs = Some(RawAttrs::new(db.upcast(), SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, &file, ctx.hygiene()));
124+
top_attrs = Some(RawAttrs::new(db.upcast(), SpanAnchor { file_id, ast_id: ROOT_ERASED_FILE_AST_ID }, &file, ctx.span_map()));
126125
ctx.lower_module_items(&file)
127126
},
128127
ast::MacroItems(items) => {
@@ -750,6 +749,7 @@ pub struct MacroCall {
750749
pub path: Interned<ModPath>,
751750
pub ast_id: FileAstId<ast::MacroCall>,
752751
pub expand_to: ExpandTo,
752+
pub call_site: SyntaxContextId,
753753
}
754754

755755
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -779,7 +779,7 @@ impl Use {
779779
// Note: The AST unwraps are fine, since if they fail we should have never obtained `index`.
780780
let ast = InFile::new(file_id, self.ast_id).to_node(db.upcast());
781781
let ast_use_tree = ast.use_tree().expect("missing `use_tree`");
782-
let hygiene = Hygiene::new(db.upcast(), file_id);
782+
let hygiene = db.span_map(file_id);
783783
let (_, source_map) =
784784
lower::lower_use_tree(db, &hygiene, ast_use_tree).expect("failed to lower use tree");
785785
source_map[index].clone()
@@ -794,7 +794,7 @@ impl Use {
794794
// Note: The AST unwraps are fine, since if they fail we should have never obtained `index`.
795795
let ast = InFile::new(file_id, self.ast_id).to_node(db.upcast());
796796
let ast_use_tree = ast.use_tree().expect("missing `use_tree`");
797-
let hygiene = Hygiene::new(db.upcast(), file_id);
797+
let hygiene = db.span_map(file_id);
798798
lower::lower_use_tree(db, &hygiene, ast_use_tree).expect("failed to lower use tree").1
799799
}
800800
}

crates/hir-def/src/item_tree/lower.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::collections::hash_map::Entry;
44

55
use base_db::span::ErasedFileAstId;
6-
use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, HirFileId};
6+
use hir_expand::{ast_id_map::AstIdMap, HirFileId, SpanMap};
77
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
88

99
use crate::{
@@ -37,8 +37,8 @@ impl<'a> Ctx<'a> {
3737
}
3838
}
3939

40-
pub(super) fn hygiene(&self) -> &Hygiene {
41-
self.body_ctx.hygiene()
40+
pub(super) fn span_map(&self) -> &SpanMap {
41+
self.body_ctx.span_map()
4242
}
4343

4444
pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> ItemTree {
@@ -90,7 +90,7 @@ impl<'a> Ctx<'a> {
9090
ast_id: self.source_ast_id_map.ast_id(block).erase(),
9191
},
9292
block,
93-
self.hygiene(),
93+
self.span_map(),
9494
),
9595
);
9696
self.tree.top_level = block
@@ -145,7 +145,7 @@ impl<'a> Ctx<'a> {
145145
self.db.upcast(),
146146
SpanAnchor { file_id: self.file, ast_id: mod_item.ast_id(&self.tree).erase() },
147147
item,
148-
self.hygiene(),
148+
self.span_map(),
149149
);
150150
self.add_attrs(mod_item.into(), attrs);
151151

@@ -174,7 +174,7 @@ impl<'a> Ctx<'a> {
174174
self.db.upcast(),
175175
SpanAnchor { file_id: self.file, ast_id: item.ast_id(&self.tree).erase() },
176176
item_node,
177-
self.hygiene(),
177+
self.span_map(),
178178
);
179179
self.add_attrs(
180180
match item {
@@ -227,7 +227,7 @@ impl<'a> Ctx<'a> {
227227
self.db.upcast(),
228228
SpanAnchor { file_id: self.file, ast_id },
229229
&field,
230-
self.hygiene(),
230+
self.span_map(),
231231
),
232232
);
233233
}
@@ -260,7 +260,7 @@ impl<'a> Ctx<'a> {
260260
self.db.upcast(),
261261
SpanAnchor { file_id: self.file, ast_id },
262262
&field,
263-
self.hygiene(),
263+
self.span_map(),
264264
),
265265
);
266266
}
@@ -314,7 +314,7 @@ impl<'a> Ctx<'a> {
314314
self.db.upcast(),
315315
SpanAnchor { file_id: self.file, ast_id },
316316
&variant,
317-
self.hygiene(),
317+
self.span_map(),
318318
),
319319
);
320320
}
@@ -370,7 +370,7 @@ impl<'a> Ctx<'a> {
370370
self.db.upcast(),
371371
SpanAnchor { file_id: self.file, ast_id: ast_id.erase() },
372372
&self_param,
373-
self.hygiene(),
373+
self.span_map(),
374374
),
375375
);
376376
has_self_param = true;
@@ -396,7 +396,7 @@ impl<'a> Ctx<'a> {
396396
self.db.upcast(),
397397
SpanAnchor { file_id: self.file, ast_id: ast_id.erase() },
398398
&param,
399-
self.hygiene(),
399+
self.span_map(),
400400
),
401401
);
402402
}
@@ -585,7 +585,7 @@ impl<'a> Ctx<'a> {
585585
fn lower_use(&mut self, use_item: &ast::Use) -> Option<FileItemTreeId<Use>> {
586586
let visibility = self.lower_visibility(use_item);
587587
let ast_id = self.source_ast_id_map.ast_id(use_item);
588-
let (use_tree, _) = lower_use_tree(self.db, self.hygiene(), use_item.use_tree()?)?;
588+
let (use_tree, _) = lower_use_tree(self.db, self.span_map(), use_item.use_tree()?)?;
589589

590590
let res = Use { visibility, ast_id, use_tree };
591591
Some(id(self.data().uses.alloc(res)))
@@ -607,10 +607,18 @@ impl<'a> Ctx<'a> {
607607
}
608608

609609
fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
610-
let path = Interned::new(ModPath::from_src(self.db.upcast(), m.path()?, self.hygiene())?);
610+
let span_map = self.span_map();
611+
let path = Interned::new(ModPath::from_src(self.db.upcast(), m.path()?, span_map)?);
611612
let ast_id = self.source_ast_id_map.ast_id(m);
612613
let expand_to = hir_expand::ExpandTo::from_call_site(m);
613-
let res = MacroCall { path, ast_id, expand_to };
614+
let res = MacroCall {
615+
path,
616+
ast_id,
617+
expand_to,
618+
call_site: span_map
619+
.span_for_range(m.syntax().text_range())
620+
.map_or(SyntaxContextId::ROOT, |s| s.ctx),
621+
};
614622
Some(id(self.data().macro_calls.alloc(res)))
615623
}
616624

@@ -655,7 +663,7 @@ impl<'a> Ctx<'a> {
655663
ast_id: mod_item.ast_id(&self.tree).erase(),
656664
},
657665
&item,
658-
self.hygiene(),
666+
self.span_map(),
659667
);
660668
self.add_attrs(mod_item.into(), attrs);
661669
Some(mod_item)
@@ -697,7 +705,7 @@ impl<'a> Ctx<'a> {
697705
self.db.upcast(),
698706
SpanAnchor { file_id: self.file, ast_id: owner_ast_id },
699707
&param,
700-
self.body_ctx.hygiene(),
708+
self.body_ctx.span_map(),
701709
);
702710
// This is identical to the body of `Ctx::add_attrs()` but we can't call that here
703711
// because it requires `&mut self` and the call to `generics.fill()` below also
@@ -731,7 +739,7 @@ impl<'a> Ctx<'a> {
731739
}
732740

733741
fn lower_visibility(&mut self, item: &dyn ast::HasVisibility) -> RawVisibilityId {
734-
let vis = RawVisibility::from_ast_with_hygiene(self.db, item.visibility(), self.hygiene());
742+
let vis = RawVisibility::from_ast_with_hygiene(self.db, item.visibility(), self.span_map());
735743
self.data().vis.alloc(vis)
736744
}
737745

@@ -809,7 +817,7 @@ fn lower_abi(abi: ast::Abi) -> Interned<str> {
809817

810818
struct UseTreeLowering<'a> {
811819
db: &'a dyn DefDatabase,
812-
hygiene: &'a Hygiene,
820+
hygiene: &'a SpanMap,
813821
mapping: Arena<ast::UseTree>,
814822
}
815823

@@ -877,7 +885,7 @@ impl UseTreeLowering<'_> {
877885

878886
pub(crate) fn lower_use_tree(
879887
db: &dyn DefDatabase,
880-
hygiene: &Hygiene,
888+
hygiene: &SpanMap,
881889
tree: ast::UseTree,
882890
) -> Option<(UseTree, Arena<ast::UseTree>)> {
883891
let mut lowering = UseTreeLowering { db, hygiene, mapping: Arena::new() };

crates/hir-def/src/item_tree/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ impl Printer<'_> {
457457
}
458458
}
459459
ModItem::MacroCall(it) => {
460-
let MacroCall { path, ast_id: _, expand_to: _ } = &self.tree[it];
460+
let MacroCall { path, ast_id: _, expand_to: _, call_site: _ } = &self.tree[it];
461461
wln!(self, "{}!(...);", path.display(self.db.upcast()));
462462
}
463463
ModItem::MacroRules(it) => {

0 commit comments

Comments
 (0)