@@ -217,8 +217,14 @@ impl HygieneData {
217
217
218
218
fn adjust ( & self , ctxt : & mut SyntaxContext , expn_id : ExpnId ) -> Option < ExpnId > {
219
219
let mut scope = None ;
220
- while !self . is_descendant_of ( expn_id, self . outer_expn ( * ctxt) ) {
221
- scope = Some ( self . remove_mark ( ctxt) . 0 ) ;
220
+ let mut outer = self . outer_expn ( * ctxt) ;
221
+ while !self . is_descendant_of ( expn_id, outer) {
222
+ if let ExpnData { kind : ExpnKind :: Underscore , call_site, .. } = * self . expn_data ( outer) {
223
+ * ctxt = call_site. ctxt ( ) ;
224
+ } else {
225
+ scope = Some ( self . remove_mark ( ctxt) . 0 ) ;
226
+ }
227
+ outer = self . outer_expn ( * ctxt) ;
222
228
}
223
229
scope
224
230
}
@@ -420,6 +426,21 @@ impl SyntaxContext {
420
426
HygieneData :: with ( |data| data. marks ( self ) )
421
427
}
422
428
429
+ crate fn unique ( base_span : Span ) -> Self {
430
+ HygieneData :: with ( |data| {
431
+ // We store the original span as the call-site so that we can
432
+ // recover it. We call `modern` here to save us calling it when we
433
+ // access `call_site`.
434
+ let modern = base_span. with_ctxt ( data. modern ( base_span. ctxt ( ) ) ) ;
435
+ let expn_id = data. fresh_expn ( Some ( ExpnData :: default (
436
+ ExpnKind :: Underscore ,
437
+ modern,
438
+ data. expn_data ( data. outer_expn ( modern. ctxt ( ) ) ) . edition ,
439
+ ) ) ) ;
440
+ data. apply_mark ( SyntaxContext :: root ( ) , expn_id, Transparency :: Opaque )
441
+ } )
442
+ }
443
+
423
444
/// Adjust this context for resolution in a scope created by the given expansion.
424
445
/// For example, consider the following three resolutions of `f`:
425
446
///
@@ -508,7 +529,7 @@ impl SyntaxContext {
508
529
pub fn reverse_glob_adjust ( & mut self , expn_id : ExpnId , glob_span : Span )
509
530
-> Option < Option < ExpnId > > {
510
531
HygieneData :: with ( |data| {
511
- if data. adjust ( self , expn_id) . is_some ( ) {
532
+ if data. adjust ( & mut { * self } , expn_id) . is_some ( ) {
512
533
return None ;
513
534
}
514
535
@@ -674,6 +695,8 @@ pub enum ExpnKind {
674
695
Macro ( MacroKind , Symbol ) ,
675
696
/// Transform done by the compiler on the AST.
676
697
AstPass ( AstPass ) ,
698
+ /// Generated by name resolution to give underscores unique identifiers.
699
+ Underscore ,
677
700
/// Desugaring done by the compiler during HIR lowering.
678
701
Desugaring ( DesugaringKind )
679
702
}
@@ -684,6 +707,7 @@ impl ExpnKind {
684
707
ExpnKind :: Root => kw:: PathRoot ,
685
708
ExpnKind :: Macro ( _, descr) => descr,
686
709
ExpnKind :: AstPass ( kind) => Symbol :: intern ( kind. descr ( ) ) ,
710
+ ExpnKind :: Underscore => kw:: Underscore ,
687
711
ExpnKind :: Desugaring ( kind) => Symbol :: intern ( kind. descr ( ) ) ,
688
712
}
689
713
}
0 commit comments