@@ -124,7 +124,9 @@ use rustc::hir::map::DefPathData;
124
124
use rustc:: session:: config:: NUMBERED_CODEGEN_UNIT_MARKER ;
125
125
use rustc:: ty:: TyCtxt ;
126
126
use rustc:: ty:: item_path:: characteristic_def_id_of_type;
127
+ use std:: cmp:: Ordering ;
127
128
use symbol_map:: SymbolMap ;
129
+ use syntax:: ast:: NodeId ;
128
130
use syntax:: parse:: token:: { self , InternedString } ;
129
131
use trans_item:: TransItem ;
130
132
use util:: nodemap:: { FnvHashMap , FnvHashSet , NodeSet } ;
@@ -144,18 +146,52 @@ pub struct CodegenUnit<'tcx> {
144
146
145
147
impl < ' tcx > CodegenUnit < ' tcx > {
146
148
pub fn items_in_deterministic_order ( & self ,
149
+ tcx : TyCtxt ,
147
150
symbol_map : & SymbolMap )
148
151
-> Vec < ( TransItem < ' tcx > , llvm:: Linkage ) > {
149
152
let mut items: Vec < ( TransItem < ' tcx > , llvm:: Linkage ) > =
150
153
self . items . iter ( ) . map ( |( item, linkage) | ( * item, * linkage) ) . collect ( ) ;
151
154
155
+ // The codegen tests rely on items being process in the same order as
156
+ // they appear in the file, so for local items, we sort by node_id first
152
157
items. as_mut_slice ( ) . sort_by ( |& ( trans_item1, _) , & ( trans_item2, _) | {
153
- let symbol_name1 = symbol_map. get ( trans_item1) . unwrap ( ) ;
154
- let symbol_name2 = symbol_map. get ( trans_item2) . unwrap ( ) ;
155
- symbol_name1. cmp ( symbol_name2)
158
+
159
+ let node_id1 = local_node_id ( tcx, trans_item1) ;
160
+ let node_id2 = local_node_id ( tcx, trans_item2) ;
161
+
162
+ match ( node_id1, node_id2) {
163
+ ( None , None ) => {
164
+ let symbol_name1 = symbol_map. get ( trans_item1) . unwrap ( ) ;
165
+ let symbol_name2 = symbol_map. get ( trans_item2) . unwrap ( ) ;
166
+ symbol_name1. cmp ( symbol_name2)
167
+ }
168
+ ( None , Some ( _) ) => Ordering :: Less ,
169
+ ( Some ( _) , None ) => Ordering :: Greater ,
170
+ ( Some ( node_id1) , Some ( node_id2) ) => {
171
+ let ordering = node_id1. cmp ( & node_id2) ;
172
+
173
+ if ordering != Ordering :: Equal {
174
+ return ordering;
175
+ }
176
+
177
+ let symbol_name1 = symbol_map. get ( trans_item1) . unwrap ( ) ;
178
+ let symbol_name2 = symbol_map. get ( trans_item2) . unwrap ( ) ;
179
+ symbol_name1. cmp ( symbol_name2)
180
+ }
181
+ }
156
182
} ) ;
157
183
158
- items
184
+ return items;
185
+
186
+ fn local_node_id ( tcx : TyCtxt , trans_item : TransItem ) -> Option < NodeId > {
187
+ match trans_item {
188
+ TransItem :: Fn ( instance) => {
189
+ tcx. map . as_local_node_id ( instance. def )
190
+ }
191
+ TransItem :: Static ( node_id) => Some ( node_id) ,
192
+ TransItem :: DropGlue ( _) => None ,
193
+ }
194
+ }
159
195
}
160
196
}
161
197
0 commit comments