Skip to content

Commit 9339982

Browse files
committed
Sort bounds by DefPathHash during astconv
cc #82920 The value of a `DefId` is not stable across compilation sessions. If we sort by `DefIds`, and then include the sorted list as part of a query result, then the query will no longer be a pure function of its input (e.g. the `DefId` can change while the `DefPathHash` remains the same). For reasons that are not yet clear, this issue lead to segfaults and garbage slice index values when the project in the linked issue was built with a particular incremental cache.
1 parent 5c6d3bf commit 9339982

File tree

9 files changed

+66
-64
lines changed

9 files changed

+66
-64
lines changed

compiler/rustc_typeck/src/astconv/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
942942
let mut bounds = Bounds::default();
943943

944944
self.add_bounds(param_ty, ast_bounds, &mut bounds);
945-
bounds.trait_bounds.sort_by_key(|(t, _, _)| t.def_id());
945+
// Sort by `DefPathHash` so that the order is stable across compilation sessions
946+
bounds.trait_bounds.sort_by_key(|(t, _, _)| self.tcx().def_path_hash(t.def_id()));
946947

947948
bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
948949
if !self.is_unsized(ast_bounds, span) { Some(span) } else { None }
@@ -1318,7 +1319,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13181319

13191320
// De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
13201321
// `dyn Trait + Send`.
1321-
auto_traits.sort_by_key(|i| i.trait_ref().def_id());
1322+
// Sort by `DefPathHash` so that the order is stable across compilation sessions
1323+
auto_traits.sort_by_key(|i| self.tcx().def_path_hash(i.trait_ref().def_id()));
13221324
auto_traits.dedup_by_key(|i| i.trait_ref().def_id());
13231325
debug!("regular_traits: {:?}", regular_traits);
13241326
debug!("auto_traits: {:?}", auto_traits);

src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr

+14-14
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,38 @@ help: consider further restricting the associated type
1010
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Iterator {
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

13-
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
14-
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:36
13+
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
14+
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:93
1515
|
1616
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
17-
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
17+
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
1818
|
1919
::: $SRC_DIR/core/src/marker.rs:LL:COL
2020
|
21-
LL | pub unsafe auto trait Send {
22-
| -------------------------- required by this bound in `Send`
21+
LL | pub unsafe auto trait Sync {
22+
| -------------------------- required by this bound in `Sync`
2323
|
24-
= help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
24+
= help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
2525
help: consider further restricting the associated type
2626
|
27-
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
27+
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {
2828
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2929

30-
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
31-
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:93
30+
error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
31+
--> $DIR/bad-bounds-on-assoc-in-trait.rs:27:36
3232
|
3333
LL | type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
34-
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
34+
| ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
3535
|
3636
::: $SRC_DIR/core/src/marker.rs:LL:COL
3737
|
38-
LL | pub unsafe auto trait Sync {
39-
| -------------------------- required by this bound in `Sync`
38+
LL | pub unsafe auto trait Send {
39+
| -------------------------- required by this bound in `Send`
4040
|
41-
= help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
41+
= help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
4242
help: consider further restricting the associated type
4343
|
44-
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {
44+
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
4545
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4646

4747
error: aborting due to 3 previous errors

src/test/ui/associated-types/defaults-unsound-62211-1.stderr

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
error[E0277]: `Self` doesn't implement `std::fmt::Display`
1+
error[E0277]: the trait bound `Self: Copy` is not satisfied
22
--> $DIR/defaults-unsound-62211-1.rs:20:5
33
|
44
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^
6-
| | |
7-
| | required by this bound in `UncheckedCopy::Output`
8-
| `Self` cannot be formatted with the default formatter
5+
| ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| | |
7+
| | required by this bound in `UncheckedCopy::Output`
8+
| the trait `Copy` is not implemented for `Self`
99
|
10-
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
1110
help: consider further restricting `Self`
1211
|
13-
LL | trait UncheckedCopy: Sized + std::fmt::Display {
14-
| ^^^^^^^^^^^^^^^^^^^
12+
LL | trait UncheckedCopy: Sized + Copy {
13+
| ^^^^^^
1514

1615
error[E0277]: the trait bound `Self: Deref` is not satisfied
1716
--> $DIR/defaults-unsound-62211-1.rs:20:5
@@ -41,19 +40,20 @@ help: consider further restricting `Self`
4140
LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
4241
| ^^^^^^^^^^^^^^^^^^^^^^^^^
4342

44-
error[E0277]: the trait bound `Self: Copy` is not satisfied
43+
error[E0277]: `Self` doesn't implement `std::fmt::Display`
4544
--> $DIR/defaults-unsound-62211-1.rs:20:5
4645
|
4746
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
48-
| ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49-
| | |
50-
| | required by this bound in `UncheckedCopy::Output`
51-
| the trait `Copy` is not implemented for `Self`
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^
48+
| | |
49+
| | required by this bound in `UncheckedCopy::Output`
50+
| `Self` cannot be formatted with the default formatter
5251
|
52+
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
5353
help: consider further restricting `Self`
5454
|
55-
LL | trait UncheckedCopy: Sized + Copy {
56-
| ^^^^^^
55+
LL | trait UncheckedCopy: Sized + std::fmt::Display {
56+
| ^^^^^^^^^^^^^^^^^^^
5757

5858
error: aborting due to 4 previous errors
5959

src/test/ui/associated-types/defaults-unsound-62211-2.stderr

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
error[E0277]: `Self` doesn't implement `std::fmt::Display`
1+
error[E0277]: the trait bound `Self: Copy` is not satisfied
22
--> $DIR/defaults-unsound-62211-2.rs:20:5
33
|
44
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^
6-
| | |
7-
| | required by this bound in `UncheckedCopy::Output`
8-
| `Self` cannot be formatted with the default formatter
5+
| ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| | |
7+
| | required by this bound in `UncheckedCopy::Output`
8+
| the trait `Copy` is not implemented for `Self`
99
|
10-
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
1110
help: consider further restricting `Self`
1211
|
13-
LL | trait UncheckedCopy: Sized + std::fmt::Display {
14-
| ^^^^^^^^^^^^^^^^^^^
12+
LL | trait UncheckedCopy: Sized + Copy {
13+
| ^^^^^^
1514

1615
error[E0277]: the trait bound `Self: Deref` is not satisfied
1716
--> $DIR/defaults-unsound-62211-2.rs:20:5
@@ -41,19 +40,20 @@ help: consider further restricting `Self`
4140
LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
4241
| ^^^^^^^^^^^^^^^^^^^^^^^^^
4342

44-
error[E0277]: the trait bound `Self: Copy` is not satisfied
43+
error[E0277]: `Self` doesn't implement `std::fmt::Display`
4544
--> $DIR/defaults-unsound-62211-2.rs:20:5
4645
|
4746
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
48-
| ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49-
| | |
50-
| | required by this bound in `UncheckedCopy::Output`
51-
| the trait `Copy` is not implemented for `Self`
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^
48+
| | |
49+
| | required by this bound in `UncheckedCopy::Output`
50+
| `Self` cannot be formatted with the default formatter
5251
|
52+
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
5353
help: consider further restricting `Self`
5454
|
55-
LL | trait UncheckedCopy: Sized + Copy {
56-
| ^^^^^^
55+
LL | trait UncheckedCopy: Sized + std::fmt::Display {
56+
| ^^^^^^^^^^^^^^^^^^^
5757

5858
error: aborting due to 4 previous errors
5959

src/test/ui/error-codes/E0225.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
1313
--> $DIR/E0225.rs:8:20
1414
|
1515
LL | trait Foo = std::io::Read + std::io::Write;
16-
| ------------- -------------- additional non-auto trait
16+
| ------------- -------------- first non-auto trait
1717
| |
18-
| first non-auto trait
18+
| additional non-auto trait
1919
...
2020
LL | let _: Box<dyn Foo>;
2121
| ^^^
2222
| |
2323
| trait alias used in trait object type (additional use)
2424
| trait alias used in trait object type (first use)
2525
|
26-
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}`
26+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::io::Write + std::io::Read {}`
2727
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
2828

2929
error: aborting due to 2 previous errors

src/test/ui/issues/issue-40827.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
error[E0277]: `Rc<Foo>` cannot be sent between threads safely
1+
error[E0277]: `Rc<Foo>` cannot be shared between threads safely
22
--> $DIR/issue-40827.rs:14:5
33
|
44
LL | fn f<T: Send>(_: T) {}
55
| ---- required by this bound in `f`
66
...
77
LL | f(Foo(Arc::new(Bar::B(None))));
8-
| ^ `Rc<Foo>` cannot be sent between threads safely
8+
| ^ `Rc<Foo>` cannot be shared between threads safely
99
|
10-
= help: within `Bar`, the trait `Send` is not implemented for `Rc<Foo>`
10+
= help: within `Bar`, the trait `Sync` is not implemented for `Rc<Foo>`
1111
= note: required because it appears within the type `Bar`
1212
= note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
1313
= note: required because it appears within the type `Foo`
1414

15-
error[E0277]: `Rc<Foo>` cannot be shared between threads safely
15+
error[E0277]: `Rc<Foo>` cannot be sent between threads safely
1616
--> $DIR/issue-40827.rs:14:5
1717
|
1818
LL | fn f<T: Send>(_: T) {}
1919
| ---- required by this bound in `f`
2020
...
2121
LL | f(Foo(Arc::new(Bar::B(None))));
22-
| ^ `Rc<Foo>` cannot be shared between threads safely
22+
| ^ `Rc<Foo>` cannot be sent between threads safely
2323
|
24-
= help: within `Bar`, the trait `Sync` is not implemented for `Rc<Foo>`
24+
= help: within `Bar`, the trait `Send` is not implemented for `Rc<Foo>`
2525
= note: required because it appears within the type `Bar`
2626
= note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
2727
= note: required because it appears within the type `Foo`

src/test/ui/suggestions/missing-trait-bounds-for-method-call.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | self.foo();
88
| ^^^ method cannot be called on `&Foo<T>` due to unsatisfied trait bounds
99
|
1010
= note: the following trait bounds were not satisfied:
11-
`T: Bar`
12-
which is required by `Foo<T>: Bar`
1311
`T: Default`
1412
which is required by `Foo<T>: Bar`
13+
`T: Bar`
14+
which is required by `Foo<T>: Bar`
1515
help: consider restricting the type parameters to satisfy the trait bounds
1616
|
1717
LL | struct Foo<T> where T: Bar, T: Default {

src/test/ui/traits/alias/cross-crate.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
error[E0277]: `Rc<u32>` cannot be sent between threads safely
1+
error[E0277]: `Rc<u32>` cannot be shared between threads safely
22
--> $DIR/cross-crate.rs:14:17
33
|
44
LL | fn use_alias<T: SendSync>() {}
55
| -------- required by this bound in `use_alias`
66
...
77
LL | use_alias::<Rc<u32>>();
8-
| ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
8+
| ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
99
|
10-
= help: the trait `Send` is not implemented for `Rc<u32>`
10+
= help: the trait `Sync` is not implemented for `Rc<u32>`
1111

12-
error[E0277]: `Rc<u32>` cannot be shared between threads safely
12+
error[E0277]: `Rc<u32>` cannot be sent between threads safely
1313
--> $DIR/cross-crate.rs:14:17
1414
|
1515
LL | fn use_alias<T: SendSync>() {}
1616
| -------- required by this bound in `use_alias`
1717
...
1818
LL | use_alias::<Rc<u32>>();
19-
| ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
19+
| ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
2020
|
21-
= help: the trait `Sync` is not implemented for `Rc<u32>`
21+
= help: the trait `Send` is not implemented for `Rc<u32>`
2222

2323
error: aborting due to 2 previous errors
2424

src/test/ui/traits/item-privacy.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ LL | C::A;
116116
| ^^^^ `assoc_const::C` cannot be made into an object
117117
|
118118
= help: consider moving `C` to another trait
119-
= help: consider moving `B` to another trait
120119
= help: consider moving `A` to another trait
120+
= help: consider moving `B` to another trait
121121
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
122122
--> $DIR/item-privacy.rs:25:15
123123
|

0 commit comments

Comments
 (0)