@@ -43,9 +43,13 @@ struct Context<'a> {
43
43
// them.
44
44
args : ~[ @ast:: Expr ] ,
45
45
arg_types : ~[ Option < ArgumentType > ] ,
46
- // Parsed named expressions and the types that we've found for them so far
46
+ // Parsed named expressions and the types that we've found for them so far.
47
+ // Note that we keep a side-array of the ordering of the named arguments
48
+ // found to be sure that we can translate them in the same order that they
49
+ // were declared in.
47
50
names : HashMap < ~str , @ast:: Expr > ,
48
51
name_types : HashMap < ~str , ArgumentType > ,
52
+ name_ordering : ~[ ~str ] ,
49
53
50
54
// Collection of the compiled `rt::Piece` structures
51
55
pieces : ~[ @ast:: Expr ] ,
@@ -63,12 +67,15 @@ struct Context<'a> {
63
67
///
64
68
/// If parsing succeeds, the second return value is:
65
69
///
66
- /// Some((fmtstr, unnamed arguments, named arguments))
67
- fn parse_args ( ecx : & mut ExtCtxt , sp : Span ,
68
- tts : & [ ast:: TokenTree ] ) -> ( @ast:: Expr , Option < ( @ast:: Expr , ~[ @ast:: Expr ] ,
69
- HashMap < ~str , @ast:: Expr > ) > ) {
70
+ /// Some((fmtstr, unnamed arguments, ordering of named arguments,
71
+ /// named arguments))
72
+ fn parse_args ( ecx : & mut ExtCtxt , sp : Span , tts : & [ ast:: TokenTree ] )
73
+ -> ( @ast:: Expr , Option < ( @ast:: Expr , ~[ @ast:: Expr ] , ~[ ~str ] ,
74
+ HashMap < ~str , @ast:: Expr > ) > )
75
+ {
70
76
let mut args = ~[ ] ;
71
77
let mut names = HashMap :: < ~str , @ast:: Expr > :: new ( ) ;
78
+ let mut order = ~[ ] ;
72
79
73
80
let mut p = rsparse:: new_parser_from_tts ( ecx. parse_sess ( ) ,
74
81
ecx. cfg ( ) ,
@@ -125,12 +132,13 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span,
125
132
continue
126
133
}
127
134
}
135
+ order. push ( name. to_str ( ) ) ;
128
136
names. insert ( name. to_str ( ) , e) ;
129
137
} else {
130
138
args. push ( p. parse_expr ( ) ) ;
131
139
}
132
140
}
133
- return ( extra, Some ( ( fmtstr, args, names) ) ) ;
141
+ return ( extra, Some ( ( fmtstr, args, order , names) ) ) ;
134
142
}
135
143
136
144
impl < ' a > Context < ' a > {
@@ -661,10 +669,11 @@ impl<'a> Context<'a> {
661
669
locals. push ( self . format_arg ( e. span , Exact ( i) ,
662
670
self . ecx . expr_ident ( e. span , name) ) ) ;
663
671
}
664
- for ( name, & e) in self . names . iter ( ) {
665
- if !self . name_types . contains_key ( name) {
666
- continue
667
- }
672
+ for name in self . name_ordering . iter ( ) {
673
+ let e = match self . names . find ( name) {
674
+ Some ( & e) if self . name_types . contains_key ( name) => e,
675
+ Some ( ..) | None => continue
676
+ } ;
668
677
669
678
let lname = self . ecx . ident_of ( format ! ( "__arg{}" , * name) ) ;
670
679
pats. push ( self . ecx . pat_ident ( e. span , lname) ) ;
@@ -810,8 +819,9 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
810
819
tts : & [ ast:: TokenTree ] ) -> base:: MacResult {
811
820
812
821
match parse_args ( ecx, sp, tts) {
813
- ( extra, Some ( ( efmt, args, names) ) ) => {
814
- MRExpr ( expand_preparsed_format_args ( ecx, sp, extra, efmt, args, names) )
822
+ ( extra, Some ( ( efmt, args, order, names) ) ) => {
823
+ MRExpr ( expand_preparsed_format_args ( ecx, sp, extra, efmt, args,
824
+ order, names) )
815
825
}
816
826
( _, None ) => MRExpr ( ecx. expr_uint ( sp, 2 ) )
817
827
}
@@ -823,6 +833,7 @@ pub fn expand_args(ecx: &mut ExtCtxt, sp: Span,
823
833
pub fn expand_preparsed_format_args ( ecx : & mut ExtCtxt , sp : Span ,
824
834
extra : @ast:: Expr ,
825
835
efmt : @ast:: Expr , args : ~[ @ast:: Expr ] ,
836
+ name_ordering : ~[ ~str ] ,
826
837
names : HashMap < ~str , @ast:: Expr > ) -> @ast:: Expr {
827
838
let arg_types = vec:: from_fn ( args. len ( ) , |_| None ) ;
828
839
let mut cx = Context {
@@ -832,6 +843,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
832
843
names : names,
833
844
name_positions : HashMap :: new ( ) ,
834
845
name_types : HashMap :: new ( ) ,
846
+ name_ordering : name_ordering,
835
847
nest_level : 0 ,
836
848
next_arg : 0 ,
837
849
pieces : ~[ ] ,
0 commit comments