Skip to content

Commit bd675c8

Browse files
Merge #8460
8460: Revert "Rewrite `#[derive]` removal code to be based on AST" r=jonas-schievink a=jonas-schievink It breaks some function-like proc macros: https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Proc.20macro.20expansion/near/233971916 It also uses attribute indices incorrectly, which causes insufficient attributes to be removed. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents dea3ff6 + 44b04eb commit bd675c8

File tree

4 files changed

+105
-100
lines changed

4 files changed

+105
-100
lines changed

crates/hir_expand/src/db.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ use syntax::{
1414
};
1515

1616
use crate::{
17-
ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinDeriveExpander,
18-
BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, HirFileId, HirFileIdRepr, LazyMacroId,
19-
MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander,
17+
ast_id_map::AstIdMap, hygiene::HygieneFrame, BuiltinDeriveExpander, BuiltinFnLikeExpander,
18+
EagerCallLoc, EagerMacroId, HirFileId, HirFileIdRepr, LazyMacroId, MacroCallId, MacroCallLoc,
19+
MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander,
2020
};
2121

2222
/// Total limit on the number of tokens produced by any macro invocation.
@@ -191,7 +191,6 @@ fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
191191
};
192192
let loc = db.lookup_intern_macro(id);
193193
let arg = loc.kind.arg(db)?;
194-
let arg = process_macro_input(db, arg, id);
195194
Some(arg.green())
196195
}
197196

crates/hir_expand/src/input.rs

Lines changed: 0 additions & 95 deletions
This file was deleted.

crates/hir_expand/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub mod builtin_macro;
1414
pub mod proc_macro;
1515
pub mod quote;
1616
pub mod eager;
17-
mod input;
1817

1918
use either::Either;
2019
pub use mbe::{ExpandError, ExpandResult};

crates/hir_expand/src/proc_macro.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::db::AstDatabase;
44
use base_db::{CrateId, ProcMacroId};
5+
use tt::buffer::{Cursor, TokenBuffer};
56

67
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
78
pub struct ProcMacroExpander {
@@ -43,6 +44,9 @@ impl ProcMacroExpander {
4344
.clone()
4445
.ok_or_else(|| err!("No derive macro found."))?;
4546

47+
let tt = remove_derive_attrs(tt)
48+
.ok_or_else(|| err!("Fail to remove derive for custom derive"))?;
49+
4650
// Proc macros have access to the environment variables of the invoking crate.
4751
let env = &krate_graph[calling_crate].env;
4852

@@ -52,3 +56,101 @@ impl ProcMacroExpander {
5256
}
5357
}
5458
}
59+
60+
fn eat_punct(cursor: &mut Cursor, c: char) -> bool {
61+
if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(punct), _)) = cursor.token_tree() {
62+
if punct.char == c {
63+
*cursor = cursor.bump();
64+
return true;
65+
}
66+
}
67+
false
68+
}
69+
70+
fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool {
71+
if let Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) = cursor.token_tree() {
72+
if Some(kind) == subtree.delimiter_kind() {
73+
*cursor = cursor.bump_subtree();
74+
return true;
75+
}
76+
}
77+
false
78+
}
79+
80+
fn eat_ident(cursor: &mut Cursor, t: &str) -> bool {
81+
if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Ident(ident), _)) = cursor.token_tree() {
82+
if t == ident.text.as_str() {
83+
*cursor = cursor.bump();
84+
return true;
85+
}
86+
}
87+
false
88+
}
89+
90+
fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> {
91+
let buffer = TokenBuffer::from_tokens(&tt.token_trees);
92+
let mut p = buffer.begin();
93+
let mut result = tt::Subtree::default();
94+
95+
while !p.eof() {
96+
let curr = p;
97+
98+
if eat_punct(&mut p, '#') {
99+
eat_punct(&mut p, '!');
100+
let parent = p;
101+
if eat_subtree(&mut p, tt::DelimiterKind::Bracket) {
102+
if eat_ident(&mut p, "derive") {
103+
p = parent.bump();
104+
continue;
105+
}
106+
}
107+
}
108+
109+
result.token_trees.push(curr.token_tree()?.cloned());
110+
p = curr.bump();
111+
}
112+
113+
Some(result)
114+
}
115+
116+
#[cfg(test)]
117+
mod tests {
118+
use super::*;
119+
use test_utils::assert_eq_text;
120+
121+
#[test]
122+
fn test_remove_derive_attrs() {
123+
let tt = mbe::parse_to_token_tree(
124+
r#"
125+
#[allow(unused)]
126+
#[derive(Copy)]
127+
#[derive(Hello)]
128+
struct A {
129+
bar: u32
130+
}
131+
"#,
132+
)
133+
.unwrap()
134+
.0;
135+
let result = format!("{:#?}", remove_derive_attrs(&tt).unwrap());
136+
137+
assert_eq_text!(
138+
r#"
139+
SUBTREE $
140+
PUNCH # [alone] 0
141+
SUBTREE [] 1
142+
IDENT allow 2
143+
SUBTREE () 3
144+
IDENT unused 4
145+
IDENT struct 15
146+
IDENT A 16
147+
SUBTREE {} 17
148+
IDENT bar 18
149+
PUNCH : [alone] 19
150+
IDENT u32 20
151+
"#
152+
.trim(),
153+
&result
154+
);
155+
}
156+
}

0 commit comments

Comments
 (0)