@@ -9,6 +9,7 @@ use base_db::{
9
9
use either:: Either ;
10
10
use limit:: Limit ;
11
11
use mbe:: { syntax_node_to_token_tree, ValueResult } ;
12
+ use rustc_hash:: FxHashSet ;
12
13
use syntax:: {
13
14
ast:: { self , HasAttrs , HasDocComments } ,
14
15
AstNode , Parse , SyntaxError , SyntaxNode , SyntaxToken , T ,
@@ -20,6 +21,7 @@ use crate::{
20
21
attrs:: RawAttrs ,
21
22
builtin_attr_macro:: pseudo_derive_attr_expansion,
22
23
builtin_fn_macro:: EagerExpander ,
24
+ fixup:: { self , SyntaxFixupUndoInfo } ,
23
25
hygiene:: { self , SyntaxContextData , Transparency } ,
24
26
span:: { RealSpanMap , SpanMap , SpanMapRef } ,
25
27
tt, AstId , BuiltinAttrExpander , BuiltinDeriveExpander , BuiltinFnLikeExpander , EagerCallInfo ,
@@ -135,7 +137,7 @@ pub trait ExpandDatabase: SourceDatabase {
135
137
fn macro_arg (
136
138
& self ,
137
139
id : MacroCallId ,
138
- ) -> ValueResult < Option < Arc < tt:: Subtree > > , Arc < Box < [ SyntaxError ] > > > ;
140
+ ) -> ValueResult < Option < ( Arc < tt:: Subtree > , SyntaxFixupUndoInfo ) > , Arc < Box < [ SyntaxError ] > > > ;
139
141
/// Fetches the expander for this macro.
140
142
#[ salsa:: transparent]
141
143
fn macro_expander ( & self , id : MacroDefId ) -> TokenExpander ;
@@ -189,15 +191,33 @@ pub fn expand_speculative(
189
191
) -> Option < ( SyntaxNode , SyntaxToken ) > {
190
192
let loc = db. lookup_intern_macro_call ( actual_macro_call) ;
191
193
192
- // Build the subtree and token mapping for the speculative args
193
- let _censor = censor_for_macro_input ( & loc, speculative_args) ;
194
194
let span_map = RealSpanMap :: absolute ( SpanAnchor :: DUMMY . file_id ) ;
195
195
let span_map = SpanMapRef :: RealSpanMap ( & span_map) ;
196
- let mut tt = mbe:: syntax_node_to_token_tree (
197
- speculative_args,
198
- // we don't leak these spans into any query so its fine to make them absolute
199
- span_map,
200
- ) ;
196
+
197
+ // Build the subtree and token mapping for the speculative args
198
+ let ( mut tt, undo_info) = match loc. kind {
199
+ MacroCallKind :: FnLike { .. } => {
200
+ ( mbe:: syntax_node_to_token_tree ( speculative_args, span_map) , SyntaxFixupUndoInfo :: NONE )
201
+ }
202
+ MacroCallKind :: Derive { .. } | MacroCallKind :: Attr { .. } => {
203
+ let censor = censor_for_macro_input ( & loc, speculative_args) ;
204
+ let mut fixups = fixup:: fixup_syntax ( span_map, speculative_args) ;
205
+ fixups. append . retain ( |it, _| match it {
206
+ syntax:: NodeOrToken :: Node ( it) => !censor. contains ( it) ,
207
+ syntax:: NodeOrToken :: Token ( _) => true ,
208
+ } ) ;
209
+ fixups. remove . extend ( censor) ;
210
+ (
211
+ mbe:: syntax_node_to_token_tree_modified (
212
+ speculative_args,
213
+ span_map,
214
+ fixups. append ,
215
+ fixups. remove ,
216
+ ) ,
217
+ fixups. undo_info ,
218
+ )
219
+ }
220
+ } ;
201
221
202
222
let attr_arg = match loc. kind {
203
223
MacroCallKind :: Attr { invoc_attr_index, .. } => {
@@ -227,7 +247,7 @@ pub fn expand_speculative(
227
247
228
248
// Do the actual expansion, we need to directly expand the proc macro due to the attribute args
229
249
// Otherwise the expand query will fetch the non speculative attribute args and pass those instead.
230
- let speculative_expansion = match loc. def . kind {
250
+ let mut speculative_expansion = match loc. def . kind {
231
251
MacroDefKind :: ProcMacro ( expander, ..) => {
232
252
tt. delimiter = tt:: Delimiter :: UNSPECIFIED ;
233
253
let call_site = loc. span ( db) ;
@@ -261,6 +281,7 @@ pub fn expand_speculative(
261
281
} ;
262
282
263
283
let expand_to = macro_expand_to ( db, actual_macro_call) ;
284
+ fixup:: reverse_fixups ( & mut speculative_expansion. value , & undo_info) ;
264
285
let ( node, rev_tmap) = token_tree_to_syntax_node ( & speculative_expansion. value , expand_to) ;
265
286
266
287
let syntax_node = node. syntax_node ( ) ;
@@ -347,7 +368,9 @@ fn parse_with_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> (Parse<SyntaxN
347
368
fn macro_arg (
348
369
db : & dyn ExpandDatabase ,
349
370
id : MacroCallId ,
350
- ) -> ValueResult < Option < Arc < tt:: Subtree > > , Arc < Box < [ SyntaxError ] > > > {
371
+ // FIXME: consider the following by putting fixup info into eager call info args
372
+ // ) -> ValueResult<Option<Arc<(tt::Subtree, SyntaxFixupUndoInfo)>>, Arc<Box<[SyntaxError]>>> {
373
+ ) -> ValueResult < Option < ( Arc < tt:: Subtree > , SyntaxFixupUndoInfo ) > , Arc < Box < [ SyntaxError ] > > > {
351
374
let mismatched_delimiters = |arg : & SyntaxNode | {
352
375
let first = arg. first_child_or_token ( ) . map_or ( T ! [ . ] , |it| it. kind ( ) ) ;
353
376
let last = arg. last_child_or_token ( ) . map_or ( T ! [ . ] , |it| it. kind ( ) ) ;
@@ -375,7 +398,7 @@ fn macro_arg(
375
398
. then ( || loc. eager . as_deref ( ) )
376
399
. flatten ( )
377
400
{
378
- ValueResult :: ok ( Some ( arg. clone ( ) ) )
401
+ ValueResult :: ok ( Some ( ( arg. clone ( ) , SyntaxFixupUndoInfo :: NONE ) ) )
379
402
} else {
380
403
let ( parse, map) = parse_with_map ( db, loc. kind . file_id ( ) ) ;
381
404
let root = parse. syntax_node ( ) ;
@@ -404,22 +427,27 @@ fn macro_arg(
404
427
}
405
428
MacroCallKind :: Attr { ast_id, .. } => ast_id. to_ptr ( db) . to_node ( & root) . syntax ( ) . clone ( ) ,
406
429
} ;
407
- let censor = censor_for_macro_input ( & loc, & syntax) ;
408
- let mut tt = match loc. kind {
430
+ let ( mut tt, undo_info) = match loc. kind {
409
431
MacroCallKind :: FnLike { .. } => {
410
- mbe:: syntax_node_to_token_tree_censored ( & syntax, map. as_ref ( ) , censor )
432
+ ( mbe:: syntax_node_to_token_tree ( & syntax, map. as_ref ( ) ) , SyntaxFixupUndoInfo :: NONE )
411
433
}
412
434
MacroCallKind :: Derive { .. } | MacroCallKind :: Attr { .. } => {
413
- // let mut fixups = crate::fixup::fixup_syntax(&syntax);
414
- // fixups.replace.extend(censor.into_iter().map(|node| (node.into(), Vec::new())));
415
- // let (mut tt, tmap, _) = mbe::syntax_node_to_token_tree_with_modifications(
416
- // &node,
417
- // fixups.token_map,
418
- // fixups.next_id,
419
- // fixups.replace,
420
- // fixups.append,
421
- // );
422
- mbe:: syntax_node_to_token_tree_censored ( & syntax, map. as_ref ( ) , censor)
435
+ let censor = censor_for_macro_input ( & loc, & syntax) ;
436
+ let mut fixups = fixup:: fixup_syntax ( map. as_ref ( ) , & syntax) ;
437
+ fixups. append . retain ( |it, _| match it {
438
+ syntax:: NodeOrToken :: Node ( it) => !censor. contains ( it) ,
439
+ syntax:: NodeOrToken :: Token ( _) => true ,
440
+ } ) ;
441
+ fixups. remove . extend ( censor) ;
442
+ (
443
+ mbe:: syntax_node_to_token_tree_modified (
444
+ & syntax,
445
+ map,
446
+ fixups. append ,
447
+ fixups. remove ,
448
+ ) ,
449
+ fixups. undo_info ,
450
+ )
423
451
}
424
452
} ;
425
453
@@ -430,15 +458,15 @@ fn macro_arg(
430
458
431
459
if matches ! ( loc. def. kind, MacroDefKind :: BuiltInEager ( ..) ) {
432
460
match parse. errors ( ) {
433
- [ ] => ValueResult :: ok ( Some ( Arc :: new ( tt) ) ) ,
461
+ [ ] => ValueResult :: ok ( Some ( ( Arc :: new ( tt) , undo_info ) ) ) ,
434
462
errors => ValueResult :: new (
435
- Some ( Arc :: new ( tt) ) ,
463
+ Some ( ( Arc :: new ( tt) , undo_info ) ) ,
436
464
// Box::<[_]>::from(res.errors()), not stable yet
437
465
Arc :: new ( errors. to_vec ( ) . into_boxed_slice ( ) ) ,
438
466
) ,
439
467
}
440
468
} else {
441
- ValueResult :: ok ( Some ( Arc :: new ( tt) ) )
469
+ ValueResult :: ok ( Some ( ( Arc :: new ( tt) , undo_info ) ) )
442
470
}
443
471
}
444
472
}
@@ -447,7 +475,7 @@ fn macro_arg(
447
475
/// Certain macro calls expect some nodes in the input to be preprocessed away, namely:
448
476
/// - derives expect all `#[derive(..)]` invocations up to the currently invoked one to be stripped
449
477
/// - attributes expect the invoking attribute to be stripped
450
- fn censor_for_macro_input ( loc : & MacroCallLoc , node : & SyntaxNode ) -> Vec < SyntaxNode > {
478
+ fn censor_for_macro_input ( loc : & MacroCallLoc , node : & SyntaxNode ) -> FxHashSet < SyntaxNode > {
451
479
// FIXME: handle `cfg_attr`
452
480
( || {
453
481
let censor = match loc. kind {
@@ -574,13 +602,13 @@ fn macro_expand(
574
602
let MacroCallKind :: Derive { ast_id, .. } = loc. kind else { unreachable ! ( ) } ;
575
603
let node = ast_id. to_ptr ( db) . to_node ( & root) ;
576
604
577
- // FIXME: we might need to remove the spans from the input to the derive macro here
605
+ // FIXME: Use censoring
578
606
let _censor = censor_for_macro_input ( & loc, node. syntax ( ) ) ;
579
607
expander. expand ( db, macro_call_id, & node, map. as_ref ( ) )
580
608
}
581
609
_ => {
582
610
let ValueResult { value, err } = db. macro_arg ( macro_call_id) ;
583
- let Some ( macro_arg) = value else {
611
+ let Some ( ( macro_arg, undo_info ) ) = value else {
584
612
return ExpandResult {
585
613
value : Arc :: new ( tt:: Subtree {
586
614
delimiter : tt:: Delimiter :: UNSPECIFIED ,
@@ -608,7 +636,7 @@ fn macro_expand(
608
636
// As such we just return the input subtree here.
609
637
MacroDefKind :: BuiltInEager ( ..) if loc. eager . is_none ( ) => {
610
638
return ExpandResult {
611
- value : Arc :: new ( arg . clone ( ) ) ,
639
+ value : macro_arg . clone ( ) ,
612
640
err : err. map ( |err| {
613
641
let mut buf = String :: new ( ) ;
614
642
for err in & * * err {
@@ -624,7 +652,11 @@ fn macro_expand(
624
652
MacroDefKind :: BuiltInEager ( it, _) => {
625
653
it. expand ( db, macro_call_id, & arg) . map_err ( Into :: into)
626
654
}
627
- MacroDefKind :: BuiltInAttr ( it, _) => it. expand ( db, macro_call_id, & arg) ,
655
+ MacroDefKind :: BuiltInAttr ( it, _) => {
656
+ let mut res = it. expand ( db, macro_call_id, & arg) ;
657
+ fixup:: reverse_fixups ( & mut res. value , & undo_info) ;
658
+ res
659
+ }
628
660
_ => unreachable ! ( ) ,
629
661
}
630
662
}
@@ -647,9 +679,8 @@ fn macro_expand(
647
679
}
648
680
649
681
fn expand_proc_macro ( db : & dyn ExpandDatabase , id : MacroCallId ) -> ExpandResult < Arc < tt:: Subtree > > {
650
- // FIXME: Syntax fix ups
651
682
let loc = db. lookup_intern_macro_call ( id) ;
652
- let Some ( macro_arg) = db. macro_arg ( id) . value else {
683
+ let Some ( ( macro_arg, undo_info ) ) = db. macro_arg ( id) . value else {
653
684
return ExpandResult {
654
685
value : Arc :: new ( tt:: Subtree {
655
686
delimiter : tt:: Delimiter :: UNSPECIFIED ,
@@ -672,7 +703,7 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
672
703
} ;
673
704
674
705
let call_site = loc. span ( db) ;
675
- let ExpandResult { value : tt, err } = expander. expand (
706
+ let ExpandResult { value : mut tt, err } = expander. expand (
676
707
db,
677
708
loc. def . krate ,
678
709
loc. krate ,
@@ -690,6 +721,8 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
690
721
return value;
691
722
}
692
723
724
+ fixup:: reverse_fixups ( & mut tt, & undo_info) ;
725
+
693
726
ExpandResult { value : Arc :: new ( tt) , err }
694
727
}
695
728
0 commit comments