@@ -37,6 +37,10 @@ enum Position {
37
37
38
38
struct Context < ' a , ' b : ' a > {
39
39
ecx : & ' a mut ExtCtxt < ' b > ,
40
+ /// The macro's call site. References to unstable formatting internals must
41
+ /// use this span to pass the stability checker.
42
+ macsp : Span ,
43
+ /// The span of the format string literal.
40
44
fmtsp : Span ,
41
45
42
46
/// Parsed argument expressions and the types that we've found so far for
@@ -307,7 +311,7 @@ impl<'a, 'b> Context<'a, 'b> {
307
311
}
308
312
309
313
fn trans_count ( & self , c : parse:: Count ) -> P < ast:: Expr > {
310
- let sp = self . fmtsp ;
314
+ let sp = self . macsp ;
311
315
let count = |c, arg| {
312
316
let mut path = Context :: rtpath ( self . ecx , "Count" ) ;
313
317
path. push ( self . ecx . ident_of ( c) ) ;
@@ -345,7 +349,7 @@ impl<'a, 'b> Context<'a, 'b> {
345
349
/// Translate a `parse::Piece` to a static `rt::Argument` or append
346
350
/// to the `literal` string.
347
351
fn trans_piece ( & mut self , piece : & parse:: Piece ) -> Option < P < ast:: Expr > > {
348
- let sp = self . fmtsp ;
352
+ let sp = self . macsp ;
349
353
match * piece {
350
354
parse:: String ( s) => {
351
355
self . literal . push_str ( s) ;
@@ -441,22 +445,22 @@ impl<'a, 'b> Context<'a, 'b> {
441
445
piece_ty : P < ast:: Ty > ,
442
446
pieces : Vec < P < ast:: Expr > > )
443
447
-> P < ast:: Expr > {
444
- let fmtsp = piece_ty. span ;
445
- let ty = ecx. ty_rptr ( fmtsp ,
446
- ecx. ty ( fmtsp , ast:: TyVec ( piece_ty) ) ,
447
- Some ( ecx. lifetime ( fmtsp , special_idents:: static_lifetime. name ) ) ,
448
+ let sp = piece_ty. span ;
449
+ let ty = ecx. ty_rptr ( sp ,
450
+ ecx. ty ( sp , ast:: TyVec ( piece_ty) ) ,
451
+ Some ( ecx. lifetime ( sp , special_idents:: static_lifetime. name ) ) ,
448
452
ast:: MutImmutable ) ;
449
- let slice = ecx. expr_vec_slice ( fmtsp , pieces) ;
453
+ let slice = ecx. expr_vec_slice ( sp , pieces) ;
450
454
let st = ast:: ItemStatic ( ty, ast:: MutImmutable , slice) ;
451
455
452
456
let name = ecx. ident_of ( name) ;
453
- let item = ecx. item ( fmtsp , name, vec ! [ ] , st) ;
454
- let decl = respan ( fmtsp , ast:: DeclItem ( item) ) ;
457
+ let item = ecx. item ( sp , name, vec ! [ ] , st) ;
458
+ let decl = respan ( sp , ast:: DeclItem ( item) ) ;
455
459
456
460
// Wrap the declaration in a block so that it forms a single expression.
457
- ecx. expr_block ( ecx. block ( fmtsp ,
458
- vec ! [ P ( respan( fmtsp , ast:: StmtDecl ( P ( decl) , ast:: DUMMY_NODE_ID ) ) ) ] ,
459
- Some ( ecx. expr_ident ( fmtsp , name) ) ) )
461
+ ecx. expr_block ( ecx. block ( sp ,
462
+ vec ! [ P ( respan( sp , ast:: StmtDecl ( P ( decl) , ast:: DUMMY_NODE_ID ) ) ) ] ,
463
+ Some ( ecx. expr_ident ( sp , name) ) ) )
460
464
}
461
465
462
466
/// Actually builds the expression which the iformat! block will be expanded
@@ -496,7 +500,7 @@ impl<'a, 'b> Context<'a, 'b> {
496
500
497
501
let name = self . ecx . ident_of ( & format ! ( "__arg{}" , i) ) ;
498
502
pats. push ( self . ecx . pat_ident ( e. span , name) ) ;
499
- locals. push ( Context :: format_arg ( self . ecx , e. span , arg_ty,
503
+ locals. push ( Context :: format_arg ( self . ecx , self . macsp , e. span , arg_ty,
500
504
self . ecx . expr_ident ( e. span , name) ) ) ;
501
505
heads. push ( self . ecx . expr_addr_of ( e. span , e) ) ;
502
506
}
@@ -514,7 +518,7 @@ impl<'a, 'b> Context<'a, 'b> {
514
518
* name) ) ;
515
519
pats. push ( self . ecx . pat_ident ( e. span , lname) ) ;
516
520
names[ * self . name_positions . get ( name) . unwrap ( ) ] =
517
- Some ( Context :: format_arg ( self . ecx , e. span , arg_ty,
521
+ Some ( Context :: format_arg ( self . ecx , self . macsp , e. span , arg_ty,
518
522
self . ecx . expr_ident ( e. span , lname) ) ) ;
519
523
heads. push ( self . ecx . expr_addr_of ( e. span , e) ) ;
520
524
}
@@ -565,7 +569,7 @@ impl<'a, 'b> Context<'a, 'b> {
565
569
// Build up the static array which will store our precompiled
566
570
// nonstandard placeholders, if there are any.
567
571
let piece_ty = self . ecx . ty_path ( self . ecx . path_global (
568
- self . fmtsp ,
572
+ self . macsp ,
569
573
Context :: rtpath ( self . ecx , "Argument" ) ) ) ;
570
574
let fmt = Context :: static_array ( self . ecx ,
571
575
"__STATIC_FMTARGS" ,
@@ -575,14 +579,14 @@ impl<'a, 'b> Context<'a, 'b> {
575
579
( "new_v1_formatted" , vec ! [ pieces, args_slice, fmt] )
576
580
} ;
577
581
578
- self . ecx . expr_call_global ( self . fmtsp , vec ! (
582
+ self . ecx . expr_call_global ( self . macsp , vec ! (
579
583
self . ecx. ident_of_std( "core" ) ,
580
584
self . ecx. ident_of( "fmt" ) ,
581
585
self . ecx. ident_of( "Arguments" ) ,
582
586
self . ecx. ident_of( fn_name) ) , fn_args)
583
587
}
584
588
585
- fn format_arg ( ecx : & ExtCtxt , sp : Span ,
589
+ fn format_arg ( ecx : & ExtCtxt , macsp : Span , sp : Span ,
586
590
ty : & ArgumentType , arg : P < ast:: Expr > )
587
591
-> P < ast:: Expr > {
588
592
let trait_ = match * ty {
@@ -606,7 +610,7 @@ impl<'a, 'b> Context<'a, 'b> {
606
610
}
607
611
}
608
612
Unsigned => {
609
- return ecx. expr_call_global ( sp , vec ! [
613
+ return ecx. expr_call_global ( macsp , vec ! [
610
614
ecx. ident_of_std( "core" ) ,
611
615
ecx. ident_of( "fmt" ) ,
612
616
ecx. ident_of( "ArgumentV1" ) ,
@@ -619,7 +623,7 @@ impl<'a, 'b> Context<'a, 'b> {
619
623
ecx. ident_of( "fmt" ) ,
620
624
ecx. ident_of( trait_) ,
621
625
ecx. ident_of( "fmt" ) ] ) ;
622
- ecx. expr_call_global ( sp , vec ! [
626
+ ecx. expr_call_global ( macsp , vec ! [
623
627
ecx. ident_of_std( "core" ) ,
624
628
ecx. ident_of( "fmt" ) ,
625
629
ecx. ident_of( "ArgumentV1" ) ,
@@ -649,6 +653,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
649
653
names : HashMap < String , P < ast:: Expr > > )
650
654
-> P < ast:: Expr > {
651
655
let arg_types: Vec < _ > = ( 0 ..args. len ( ) ) . map ( |_| None ) . collect ( ) ;
656
+ let macsp = ecx. call_site ( ) ;
652
657
let mut cx = Context {
653
658
ecx : ecx,
654
659
args : args,
@@ -663,9 +668,9 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
663
668
pieces : Vec :: new ( ) ,
664
669
str_pieces : Vec :: new ( ) ,
665
670
all_pieces_simple : true ,
666
- fmtsp : sp,
671
+ macsp : macsp,
672
+ fmtsp : efmt. span ,
667
673
} ;
668
- cx. fmtsp = efmt. span ;
669
674
let fmt = match expr_to_string ( cx. ecx ,
670
675
efmt,
671
676
"format argument must be a string literal." ) {
0 commit comments