@@ -1354,12 +1354,57 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
1354
1354
}
1355
1355
}
1356
1356
1357
+ self . sort_where_predicates ( & mut existing_predicates) ;
1358
+
1357
1359
Generics {
1358
1360
params : generic_params,
1359
1361
where_predicates : existing_predicates,
1360
1362
}
1361
1363
}
1362
1364
1365
+ // Ensure that the predicates are in a consistent order. The precise
1366
+ // ordering doesn't actually matter, but it's important that
1367
+ // a given set of predicates always appears in the same order -
1368
+ // both for visual consistency between 'rustdoc' runs, and to
1369
+ // make writing tests much easier
1370
+ fn sort_where_predicates ( & self , predicates : & mut Vec < WherePredicate > ) {
1371
+ // We should never have identical bounds - and if we do,
1372
+ // they're visually identical as well. Therefore, using
1373
+ // an unstable sort is fine.
1374
+ predicates. sort_unstable_by ( |first, second| {
1375
+ // This might look horrendously hacky, but it's actually not that bad.
1376
+ //
1377
+ // For performance reasons, we use several different FxHashMaps
1378
+ // in the process of computing the final set of where predicates.
1379
+ // However, the iteration order of a HashMap is completely unspecified.
1380
+ // In fact, the iteration of an FxHashMap can even vary between platforms,
1381
+ // since FxHasher has different behavior for 32-bit and 64-bit platforms.
1382
+ //
1383
+ // Obviously, it's extremely undesireable for documentation rendering
1384
+ // to be depndent on the platform it's run on. Apart from being confusing
1385
+ // to end users, it makes writing tests much more difficult, as predicates
1386
+ // can appear in any order in the final result.
1387
+ //
1388
+ // To solve this problem, we sort WherePredicates by their Debug
1389
+ // string. The thing to keep in mind is that we don't really
1390
+ // care what the final order is - we're synthesizing an impl
1391
+ // ourselves, so any order can be considered equally valid.
1392
+ // By sorting the predicates, however, we ensure that for
1393
+ // a given codebase, all auto-trait impls always render
1394
+ // in exactly the same way.
1395
+ //
1396
+ // Using the Debug impementation for sorting prevents
1397
+ // us from needing to write quite a bit of almost
1398
+ // entirely useless code (e.g. how should two
1399
+ // Types be sorted relative to each other).
1400
+ // This approach is probably somewhat slower, but
1401
+ // the small number of items involved (impls
1402
+ // rarely have more than a few bounds) means
1403
+ // that it shouldn't matter in practice.
1404
+ format ! ( "{:?}" , first) . cmp ( & format ! ( "{:?}" , second) )
1405
+ } ) ;
1406
+ }
1407
+
1363
1408
fn is_fn_ty ( & self , tcx : & TyCtxt , ty : & Type ) -> bool {
1364
1409
match & ty {
1365
1410
& & Type :: ResolvedPath { ref did, .. } => {
0 commit comments