Skip to content

Commit b47c63a

Browse files
Merge #7137
7137: Revert "Proper handling $crate and local_inner_macros" r=jonas-schievink a=jonas-schievink Reverts #7133 It caused a fairly significant performance regression. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 354c1da + 85cc3cf commit b47c63a

File tree

7 files changed

+52
-176
lines changed

7 files changed

+52
-176
lines changed

crates/hir_def/src/path/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
123123
// We follow what it did anyway :)
124124
if segments.len() == 1 && kind == PathKind::Plain {
125125
if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
126-
if let Some(crate_id) = hygiene.local_inner_macros(path) {
126+
if let Some(crate_id) = hygiene.local_inner_macros() {
127127
kind = PathKind::DollarCrate(crate_id);
128128
}
129129
}

crates/hir_expand/src/hygiene.rs

Lines changed: 25 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -2,94 +2,30 @@
22
//!
33
//! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at
44
//! this moment, this is horribly incomplete and handles only `$crate`.
5-
use std::sync::Arc;
6-
7-
use arena::{Arena, Idx};
85
use base_db::CrateId;
96
use either::Either;
10-
use mbe::Origin;
11-
use syntax::{ast, AstNode};
7+
use syntax::ast;
128

139
use crate::{
1410
db::AstDatabase,
1511
name::{AsName, Name},
16-
ExpansionInfo, HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind,
12+
HirFileId, HirFileIdRepr, MacroCallId, MacroDefKind,
1713
};
1814

1915
#[derive(Clone, Debug)]
2016
pub struct Hygiene {
21-
frames: Option<Arc<HygieneFrames>>,
22-
}
23-
24-
impl Hygiene {
25-
pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene {
26-
Hygiene { frames: Some(Arc::new(HygieneFrames::new(db, file_id.clone()))) }
27-
}
28-
29-
pub fn new_unhygienic() -> Hygiene {
30-
Hygiene { frames: None }
31-
}
32-
33-
// FIXME: this should just return name
34-
pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> {
35-
if let Some(frames) = &self.frames {
36-
if name_ref.text() == "$crate" {
37-
if let Some(krate) = frames.root_crate(&name_ref) {
38-
return Either::Right(krate);
39-
}
40-
}
41-
}
42-
43-
Either::Left(name_ref.as_name())
44-
}
45-
46-
pub fn local_inner_macros(&self, path: ast::Path) -> Option<CrateId> {
47-
let frames = self.frames.as_ref()?;
48-
49-
let mut token = path.syntax().first_token()?;
50-
let mut current = frames.first();
51-
52-
while let Some((frame, data)) =
53-
current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?)))
54-
{
55-
let (mapped, origin) = data;
56-
if origin == Origin::Def {
57-
return if frame.local_inner { frame.krate } else { None };
58-
}
59-
current = Some(&frames.0[frame.call_site?]);
60-
token = mapped.value;
61-
}
62-
None
63-
}
64-
}
65-
66-
#[derive(Default, Debug)]
67-
struct HygieneFrames(Arena<HygieneFrame>);
68-
69-
#[derive(Clone, Debug)]
70-
struct HygieneFrame {
71-
expansion: Option<ExpansionInfo>,
17+
// This is what `$crate` expands to
18+
def_crate: Option<CrateId>,
7219

7320
// Indicate this is a local inner macro
7421
local_inner: bool,
75-
krate: Option<CrateId>,
76-
77-
call_site: Option<Idx<HygieneFrame>>,
78-
def_site: Option<Idx<HygieneFrame>>,
7922
}
8023

81-
impl HygieneFrames {
82-
fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self {
83-
let mut frames = HygieneFrames::default();
84-
frames.add(db, file_id);
85-
frames
86-
}
87-
88-
fn add(&mut self, db: &dyn AstDatabase, file_id: HirFileId) -> Option<Idx<HygieneFrame>> {
89-
let (krate, local_inner) = match file_id.0 {
24+
impl Hygiene {
25+
pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene {
26+
let (def_crate, local_inner) = match file_id.0 {
9027
HirFileIdRepr::FileId(_) => (None, false),
9128
HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
92-
MacroCallId::EagerMacro(_id) => (None, false),
9329
MacroCallId::LazyMacro(id) => {
9430
let loc = db.lookup_intern_macro(id);
9531
match loc.def.kind {
@@ -100,68 +36,31 @@ impl HygieneFrames {
10036
MacroDefKind::ProcMacro(_) => (None, false),
10137
}
10238
}
39+
MacroCallId::EagerMacro(_id) => (None, false),
10340
},
10441
};
105-
106-
let expansion = file_id.expansion_info(db);
107-
let expansion = match expansion {
108-
None => {
109-
return Some(self.0.alloc(HygieneFrame {
110-
expansion: None,
111-
local_inner,
112-
krate,
113-
call_site: None,
114-
def_site: None,
115-
}));
116-
}
117-
Some(it) => it,
118-
};
119-
120-
let def_site = expansion.def.clone();
121-
let call_site = expansion.arg.file_id;
122-
let idx = self.0.alloc(HygieneFrame {
123-
expansion: Some(expansion),
124-
local_inner,
125-
krate,
126-
call_site: None,
127-
def_site: None,
128-
});
129-
130-
self.0[idx].call_site = self.add(db, call_site);
131-
self.0[idx].def_site = def_site.and_then(|it| self.add(db, it.file_id));
132-
133-
Some(idx)
42+
Hygiene { def_crate, local_inner }
13443
}
13544

136-
fn first(&self) -> Option<&HygieneFrame> {
137-
self.0.iter().next().map(|it| it.1)
45+
pub fn new_unhygienic() -> Hygiene {
46+
Hygiene { def_crate: None, local_inner: false }
13847
}
13948

140-
fn root_crate(&self, name_ref: &ast::NameRef) -> Option<CrateId> {
141-
let mut token = name_ref.syntax().first_token()?;
142-
let first = self.first()?;
143-
let mut result = first.krate;
144-
let mut current = Some(first);
145-
146-
while let Some((frame, (mapped, origin))) =
147-
current.and_then(|it| Some((it, it.expansion.as_ref()?.map_token_up(&token)?)))
148-
{
149-
result = frame.krate;
150-
151-
let site = match origin {
152-
Origin::Def => frame.def_site,
153-
Origin::Call => frame.call_site,
154-
};
155-
156-
let site = match site {
157-
None => break,
158-
Some(it) => it,
159-
};
160-
161-
current = Some(&self.0[site]);
162-
token = mapped.value;
49+
// FIXME: this should just return name
50+
pub fn name_ref_to_name(&self, name_ref: ast::NameRef) -> Either<Name, CrateId> {
51+
if let Some(def_crate) = self.def_crate {
52+
if name_ref.text() == "$crate" {
53+
return Either::Right(def_crate);
54+
}
16355
}
56+
Either::Left(name_ref.as_name())
57+
}
16458

165-
result
59+
pub fn local_inner_macros(&self) -> Option<CrateId> {
60+
if self.local_inner {
61+
self.def_crate
62+
} else {
63+
None
64+
}
16665
}
16766
}

crates/hir_expand/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,11 @@ impl ExpansionInfo {
340340
Some(self.expanded.with_value(token))
341341
}
342342

343-
pub fn map_token_up(&self, token: &SyntaxToken) -> Option<(InFile<SyntaxToken>, Origin)> {
344-
let token_id = self.exp_map.token_by_range(token.text_range())?;
343+
pub fn map_token_up(
344+
&self,
345+
token: InFile<&SyntaxToken>,
346+
) -> Option<(InFile<SyntaxToken>, Origin)> {
347+
let token_id = self.exp_map.token_by_range(token.value.text_range())?;
345348

346349
let (token_id, origin) = self.macro_def.0.map_id_up(token_id);
347350
let (token_map, tt) = match origin {
@@ -356,7 +359,7 @@ impl ExpansionInfo {
356359
),
357360
};
358361

359-
let range = token_map.range_by_token(token_id)?.by_kind(token.kind())?;
362+
let range = token_map.range_by_token(token_id)?.by_kind(token.value.kind())?;
360363
let token = algo::find_covering_element(&tt.value, range + tt.value.text_range().start())
361364
.into_token()?;
362365
Some((tt.with_value(token), origin))
@@ -492,7 +495,7 @@ fn ascend_call_token(
492495
expansion: &ExpansionInfo,
493496
token: InFile<SyntaxToken>,
494497
) -> Option<InFile<SyntaxToken>> {
495-
let (mapped, origin) = expansion.map_token_up(&token.value)?;
498+
let (mapped, origin) = expansion.map_token_up(token.as_ref())?;
496499
if origin != Origin::Call {
497500
return None;
498501
}

crates/hir_ty/src/tests/macros.rs

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -370,37 +370,6 @@ expand!();
370370
);
371371
}
372372

373-
#[test]
374-
fn infer_macro_with_dollar_crate_in_def_site() {
375-
check_types(
376-
r#"
377-
//- /main.rs crate:main deps:foo
378-
use foo::expand;
379-
380-
macro_rules! list {
381-
($($tt:tt)*) => { $($tt)* }
382-
}
383-
384-
fn test() {
385-
let r = expand!();
386-
r;
387-
//^ u128
388-
}
389-
390-
//- /lib.rs crate:foo
391-
#[macro_export]
392-
macro_rules! expand {
393-
() => { list!($crate::m!()) };
394-
}
395-
396-
#[macro_export]
397-
macro_rules! m {
398-
() => { 0u128 };
399-
}
400-
"#,
401-
);
402-
}
403-
404373
#[test]
405374
fn infer_type_value_non_legacy_macro_use_as() {
406375
check_infer(

crates/mbe/src/mbe_expander/matcher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ fn match_subtree(
150150
res.add_err(err!("leftover tokens"));
151151
}
152152
}
153-
Op::Var { name, kind, .. } => {
153+
Op::Var { name, kind } => {
154154
let kind = match kind {
155155
Some(k) => k,
156156
None => {

crates/mbe/src/mbe_expander/transcriber.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ fn expand_subtree(
100100
err = err.or(e);
101101
arena.push(tt.into());
102102
}
103-
Op::Var { name, id, .. } => {
104-
let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name, *id);
103+
Op::Var { name, .. } => {
104+
let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name);
105105
err = err.or(e);
106106
push_fragment(arena, fragment);
107107
}
@@ -118,10 +118,12 @@ fn expand_subtree(
118118
ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err }
119119
}
120120

121-
fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> {
121+
fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
122122
if v == "crate" {
123123
// We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path.
124-
let tt = tt::Leaf::from(tt::Ident { text: "$crate".into(), id }).into();
124+
let tt =
125+
tt::Leaf::from(tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() })
126+
.into();
125127
ExpandResult::ok(Fragment::Tokens(tt))
126128
} else if !ctx.bindings.contains(v) {
127129
// Note that it is possible to have a `$var` inside a macro which is not bound.
@@ -140,8 +142,14 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult
140142
let tt = tt::Subtree {
141143
delimiter: None,
142144
token_trees: vec![
143-
tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone, id }).into(),
144-
tt::Leaf::from(tt::Ident { text: v.clone(), id }).into(),
145+
tt::Leaf::from(tt::Punct {
146+
char: '$',
147+
spacing: tt::Spacing::Alone,
148+
id: tt::TokenId::unspecified(),
149+
})
150+
.into(),
151+
tt::Leaf::from(tt::Ident { text: v.clone(), id: tt::TokenId::unspecified() })
152+
.into(),
145153
],
146154
}
147155
.into();

crates/mbe/src/parser.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{tt_iter::TtIter, ExpandError, MetaTemplate};
88

99
#[derive(Clone, Debug, PartialEq, Eq)]
1010
pub(crate) enum Op {
11-
Var { name: SmolStr, kind: Option<SmolStr>, id: tt::TokenId },
11+
Var { name: SmolStr, kind: Option<SmolStr> },
1212
Repeat { subtree: MetaTemplate, kind: RepeatKind, separator: Option<Separator> },
1313
Leaf(tt::Leaf),
1414
Subtree(MetaTemplate),
@@ -106,21 +106,18 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
106106
}
107107
let name = UNDERSCORE.clone();
108108
let kind = eat_fragment_kind(src, mode)?;
109-
let id = punct.id;
110-
Op::Var { name, kind, id }
109+
Op::Var { name, kind }
111110
}
112111
tt::Leaf::Ident(ident) => {
113112
let name = ident.text.clone();
114113
let kind = eat_fragment_kind(src, mode)?;
115-
let id = ident.id;
116-
Op::Var { name, kind, id }
114+
Op::Var { name, kind }
117115
}
118116
tt::Leaf::Literal(lit) => {
119117
if is_boolean_literal(&lit) {
120118
let name = lit.text.clone();
121119
let kind = eat_fragment_kind(src, mode)?;
122-
let id = lit.id;
123-
Op::Var { name, kind, id }
120+
Op::Var { name, kind }
124121
} else {
125122
bail!("bad var 2");
126123
}

0 commit comments

Comments
 (0)