Skip to content

Commit

Permalink
Sort bounds by DefPathHash during astconv
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Aaron1011 committed Mar 11, 2021
1 parent 5c6d3bf commit 9339982
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 64 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let mut bounds = Bounds::default();

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

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

// De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
// `dyn Trait + Send`.
auto_traits.sort_by_key(|i| i.trait_ref().def_id());
// Sort by `DefPathHash` so that the order is stable across compilation sessions
auto_traits.sort_by_key(|i| self.tcx().def_path_hash(i.trait_ref().def_id()));
auto_traits.dedup_by_key(|i| i.trait_ref().def_id());
debug!("regular_traits: {:?}", regular_traits);
debug!("auto_traits: {:?}", auto_traits);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,38 @@ help: consider further restricting the associated type
LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Iterator {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

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

error: aborting due to 3 previous errors
Expand Down
30 changes: 15 additions & 15 deletions src/test/ui/associated-types/defaults-unsound-62211-1.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
error[E0277]: `Self` doesn't implement `std::fmt::Display`
error[E0277]: the trait bound `Self: Copy` is not satisfied
--> $DIR/defaults-unsound-62211-1.rs:20:5
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^
| | |
| | required by this bound in `UncheckedCopy::Output`
| `Self` cannot be formatted with the default formatter
| ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | required by this bound in `UncheckedCopy::Output`
| the trait `Copy` is not implemented for `Self`
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
help: consider further restricting `Self`
|
LL | trait UncheckedCopy: Sized + std::fmt::Display {
| ^^^^^^^^^^^^^^^^^^^
LL | trait UncheckedCopy: Sized + Copy {
| ^^^^^^

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

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

error: aborting due to 4 previous errors

Expand Down
30 changes: 15 additions & 15 deletions src/test/ui/associated-types/defaults-unsound-62211-2.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
error[E0277]: `Self` doesn't implement `std::fmt::Display`
error[E0277]: the trait bound `Self: Copy` is not satisfied
--> $DIR/defaults-unsound-62211-2.rs:20:5
|
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^
| | |
| | required by this bound in `UncheckedCopy::Output`
| `Self` cannot be formatted with the default formatter
| ^^^^^^^^^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | required by this bound in `UncheckedCopy::Output`
| the trait `Copy` is not implemented for `Self`
|
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
help: consider further restricting `Self`
|
LL | trait UncheckedCopy: Sized + std::fmt::Display {
| ^^^^^^^^^^^^^^^^^^^
LL | trait UncheckedCopy: Sized + Copy {
| ^^^^^^

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

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

error: aborting due to 4 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/error-codes/E0225.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
--> $DIR/E0225.rs:8:20
|
LL | trait Foo = std::io::Read + std::io::Write;
| ------------- -------------- additional non-auto trait
| ------------- -------------- first non-auto trait
| |
| first non-auto trait
| additional non-auto trait
...
LL | let _: Box<dyn Foo>;
| ^^^
| |
| trait alias used in trait object type (additional use)
| trait alias used in trait object type (first use)
|
= 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 {}`
= 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 {}`
= 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>

error: aborting due to 2 previous errors
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-40827.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
error[E0277]: `Rc<Foo>` cannot be sent between threads safely
error[E0277]: `Rc<Foo>` cannot be shared between threads safely
--> $DIR/issue-40827.rs:14:5
|
LL | fn f<T: Send>(_: T) {}
| ---- required by this bound in `f`
...
LL | f(Foo(Arc::new(Bar::B(None))));
| ^ `Rc<Foo>` cannot be sent between threads safely
| ^ `Rc<Foo>` cannot be shared between threads safely
|
= help: within `Bar`, the trait `Send` is not implemented for `Rc<Foo>`
= help: within `Bar`, the trait `Sync` is not implemented for `Rc<Foo>`
= note: required because it appears within the type `Bar`
= note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
= note: required because it appears within the type `Foo`

error[E0277]: `Rc<Foo>` cannot be shared between threads safely
error[E0277]: `Rc<Foo>` cannot be sent between threads safely
--> $DIR/issue-40827.rs:14:5
|
LL | fn f<T: Send>(_: T) {}
| ---- required by this bound in `f`
...
LL | f(Foo(Arc::new(Bar::B(None))));
| ^ `Rc<Foo>` cannot be shared between threads safely
| ^ `Rc<Foo>` cannot be sent between threads safely
|
= help: within `Bar`, the trait `Sync` is not implemented for `Rc<Foo>`
= help: within `Bar`, the trait `Send` is not implemented for `Rc<Foo>`
= note: required because it appears within the type `Bar`
= note: required because of the requirements on the impl of `Send` for `Arc<Bar>`
= note: required because it appears within the type `Foo`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ LL | self.foo();
| ^^^ method cannot be called on `&Foo<T>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`T: Bar`
which is required by `Foo<T>: Bar`
`T: Default`
which is required by `Foo<T>: Bar`
`T: Bar`
which is required by `Foo<T>: Bar`
help: consider restricting the type parameters to satisfy the trait bounds
|
LL | struct Foo<T> where T: Bar, T: Default {
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/traits/alias/cross-crate.stderr
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
error[E0277]: `Rc<u32>` cannot be sent between threads safely
error[E0277]: `Rc<u32>` cannot be shared between threads safely
--> $DIR/cross-crate.rs:14:17
|
LL | fn use_alias<T: SendSync>() {}
| -------- required by this bound in `use_alias`
...
LL | use_alias::<Rc<u32>>();
| ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
| ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
|
= help: the trait `Send` is not implemented for `Rc<u32>`
= help: the trait `Sync` is not implemented for `Rc<u32>`

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

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/traits/item-privacy.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ LL | C::A;
| ^^^^ `assoc_const::C` cannot be made into an object
|
= help: consider moving `C` to another trait
= help: consider moving `B` to another trait
= help: consider moving `A` to another trait
= help: consider moving `B` to another trait
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>
--> $DIR/item-privacy.rs:25:15
|
Expand Down

0 comments on commit 9339982

Please sign in to comment.