@@ -124,7 +124,9 @@ use rustc::hir::map::DefPathData;
124124use rustc:: session:: config:: NUMBERED_CODEGEN_UNIT_MARKER ;
125125use rustc:: ty:: TyCtxt ;
126126use rustc:: ty:: item_path:: characteristic_def_id_of_type;
127+ use std:: cmp:: Ordering ;
127128use symbol_map:: SymbolMap ;
129+ use syntax:: ast:: NodeId ;
128130use syntax:: parse:: token:: { self , InternedString } ;
129131use trans_item:: TransItem ;
130132use util:: nodemap:: { FnvHashMap , FnvHashSet , NodeSet } ;
@@ -144,18 +146,52 @@ pub struct CodegenUnit<'tcx> {
144146
145147impl < ' tcx > CodegenUnit < ' tcx > {
146148 pub fn items_in_deterministic_order ( & self ,
149+ tcx : TyCtxt ,
147150 symbol_map : & SymbolMap )
148151 -> Vec < ( TransItem < ' tcx > , llvm:: Linkage ) > {
149152 let mut items: Vec < ( TransItem < ' tcx > , llvm:: Linkage ) > =
150153 self . items . iter ( ) . map ( |( item, linkage) | ( * item, * linkage) ) . collect ( ) ;
151154
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
152157 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+ }
156182 } ) ;
157183
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+ }
159195 }
160196}
161197
0 commit comments