@@ -9,6 +9,7 @@ use base_db::{
99use either:: Either ;
1010use limit:: Limit ;
1111use mbe:: { syntax_node_to_token_tree, ValueResult } ;
12+ use rustc_hash:: FxHashSet ;
1213use syntax:: {
1314 ast:: { self , HasAttrs , HasDocComments } ,
1415 AstNode , Parse , SyntaxError , SyntaxNode , SyntaxToken , T ,
@@ -20,6 +21,7 @@ use crate::{
2021 attrs:: RawAttrs ,
2122 builtin_attr_macro:: pseudo_derive_attr_expansion,
2223 builtin_fn_macro:: EagerExpander ,
24+ fixup:: { self , SyntaxFixupUndoInfo } ,
2325 hygiene:: { self , SyntaxContextData , Transparency } ,
2426 span:: { RealSpanMap , SpanMap , SpanMapRef } ,
2527 tt, AstId , BuiltinAttrExpander , BuiltinDeriveExpander , BuiltinFnLikeExpander , EagerCallInfo ,
@@ -135,7 +137,7 @@ pub trait ExpandDatabase: SourceDatabase {
135137 fn macro_arg (
136138 & self ,
137139 id : MacroCallId ,
138- ) -> ValueResult < Option < Arc < tt:: Subtree > > , Arc < Box < [ SyntaxError ] > > > ;
140+ ) -> ValueResult < Option < ( Arc < tt:: Subtree > , SyntaxFixupUndoInfo ) > , Arc < Box < [ SyntaxError ] > > > ;
139141 /// Fetches the expander for this macro.
140142 #[ salsa:: transparent]
141143 fn macro_expander ( & self , id : MacroDefId ) -> TokenExpander ;
@@ -189,15 +191,33 @@ pub fn expand_speculative(
189191) -> Option < ( SyntaxNode , SyntaxToken ) > {
190192 let loc = db. lookup_intern_macro_call ( actual_macro_call) ;
191193
192- // Build the subtree and token mapping for the speculative args
193- let _censor = censor_for_macro_input ( & loc, speculative_args) ;
194194 let span_map = RealSpanMap :: absolute ( SpanAnchor :: DUMMY . file_id ) ;
195195 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+ } ;
201221
202222 let attr_arg = match loc. kind {
203223 MacroCallKind :: Attr { invoc_attr_index, .. } => {
@@ -227,7 +247,7 @@ pub fn expand_speculative(
227247
228248 // Do the actual expansion, we need to directly expand the proc macro due to the attribute args
229249 // 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 {
231251 MacroDefKind :: ProcMacro ( expander, ..) => {
232252 tt. delimiter = tt:: Delimiter :: UNSPECIFIED ;
233253 let call_site = loc. span ( db) ;
@@ -261,6 +281,7 @@ pub fn expand_speculative(
261281 } ;
262282
263283 let expand_to = macro_expand_to ( db, actual_macro_call) ;
284+ fixup:: reverse_fixups ( & mut speculative_expansion. value , & undo_info) ;
264285 let ( node, rev_tmap) = token_tree_to_syntax_node ( & speculative_expansion. value , expand_to) ;
265286
266287 let syntax_node = node. syntax_node ( ) ;
@@ -347,7 +368,9 @@ fn parse_with_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> (Parse<SyntaxN
347368fn macro_arg (
348369 db : & dyn ExpandDatabase ,
349370 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 ] > > > {
351374 let mismatched_delimiters = |arg : & SyntaxNode | {
352375 let first = arg. first_child_or_token ( ) . map_or ( T ! [ . ] , |it| it. kind ( ) ) ;
353376 let last = arg. last_child_or_token ( ) . map_or ( T ! [ . ] , |it| it. kind ( ) ) ;
@@ -375,7 +398,7 @@ fn macro_arg(
375398 . then ( || loc. eager . as_deref ( ) )
376399 . flatten ( )
377400 {
378- ValueResult :: ok ( Some ( arg. clone ( ) ) )
401+ ValueResult :: ok ( Some ( ( arg. clone ( ) , SyntaxFixupUndoInfo :: NONE ) ) )
379402 } else {
380403 let ( parse, map) = parse_with_map ( db, loc. kind . file_id ( ) ) ;
381404 let root = parse. syntax_node ( ) ;
@@ -404,22 +427,27 @@ fn macro_arg(
404427 }
405428 MacroCallKind :: Attr { ast_id, .. } => ast_id. to_ptr ( db) . to_node ( & root) . syntax ( ) . clone ( ) ,
406429 } ;
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 {
409431 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 )
411433 }
412434 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+ )
423451 }
424452 } ;
425453
@@ -430,15 +458,15 @@ fn macro_arg(
430458
431459 if matches ! ( loc. def. kind, MacroDefKind :: BuiltInEager ( ..) ) {
432460 match parse. errors ( ) {
433- [ ] => ValueResult :: ok ( Some ( Arc :: new ( tt) ) ) ,
461+ [ ] => ValueResult :: ok ( Some ( ( Arc :: new ( tt) , undo_info ) ) ) ,
434462 errors => ValueResult :: new (
435- Some ( Arc :: new ( tt) ) ,
463+ Some ( ( Arc :: new ( tt) , undo_info ) ) ,
436464 // Box::<[_]>::from(res.errors()), not stable yet
437465 Arc :: new ( errors. to_vec ( ) . into_boxed_slice ( ) ) ,
438466 ) ,
439467 }
440468 } else {
441- ValueResult :: ok ( Some ( Arc :: new ( tt) ) )
469+ ValueResult :: ok ( Some ( ( Arc :: new ( tt) , undo_info ) ) )
442470 }
443471 }
444472}
@@ -447,7 +475,7 @@ fn macro_arg(
447475/// Certain macro calls expect some nodes in the input to be preprocessed away, namely:
448476/// - derives expect all `#[derive(..)]` invocations up to the currently invoked one to be stripped
449477/// - 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 > {
451479 // FIXME: handle `cfg_attr`
452480 ( || {
453481 let censor = match loc. kind {
@@ -574,13 +602,13 @@ fn macro_expand(
574602 let MacroCallKind :: Derive { ast_id, .. } = loc. kind else { unreachable ! ( ) } ;
575603 let node = ast_id. to_ptr ( db) . to_node ( & root) ;
576604
577- // FIXME: we might need to remove the spans from the input to the derive macro here
605+ // FIXME: Use censoring
578606 let _censor = censor_for_macro_input ( & loc, node. syntax ( ) ) ;
579607 expander. expand ( db, macro_call_id, & node, map. as_ref ( ) )
580608 }
581609 _ => {
582610 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 {
584612 return ExpandResult {
585613 value : Arc :: new ( tt:: Subtree {
586614 delimiter : tt:: Delimiter :: UNSPECIFIED ,
@@ -608,7 +636,7 @@ fn macro_expand(
608636 // As such we just return the input subtree here.
609637 MacroDefKind :: BuiltInEager ( ..) if loc. eager . is_none ( ) => {
610638 return ExpandResult {
611- value : Arc :: new ( arg . clone ( ) ) ,
639+ value : macro_arg . clone ( ) ,
612640 err : err. map ( |err| {
613641 let mut buf = String :: new ( ) ;
614642 for err in & * * err {
@@ -624,7 +652,11 @@ fn macro_expand(
624652 MacroDefKind :: BuiltInEager ( it, _) => {
625653 it. expand ( db, macro_call_id, & arg) . map_err ( Into :: into)
626654 }
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+ }
628660 _ => unreachable ! ( ) ,
629661 }
630662 }
@@ -647,9 +679,8 @@ fn macro_expand(
647679}
648680
649681fn expand_proc_macro ( db : & dyn ExpandDatabase , id : MacroCallId ) -> ExpandResult < Arc < tt:: Subtree > > {
650- // FIXME: Syntax fix ups
651682 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 {
653684 return ExpandResult {
654685 value : Arc :: new ( tt:: Subtree {
655686 delimiter : tt:: Delimiter :: UNSPECIFIED ,
@@ -672,7 +703,7 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
672703 } ;
673704
674705 let call_site = loc. span ( db) ;
675- let ExpandResult { value : tt, err } = expander. expand (
706+ let ExpandResult { value : mut tt, err } = expander. expand (
676707 db,
677708 loc. def . krate ,
678709 loc. krate ,
@@ -690,6 +721,8 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
690721 return value;
691722 }
692723
724+ fixup:: reverse_fixups ( & mut tt, & undo_info) ;
725+
693726 ExpandResult { value : Arc :: new ( tt) , err }
694727}
695728
0 commit comments