From 9339982e8f46f07bff86f232e7831b63c61e3608 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 11 Mar 2021 01:03:56 -0500 Subject: [PATCH 1/2] 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. --- compiler/rustc_typeck/src/astconv/mod.rs | 6 ++-- .../bad-bounds-on-assoc-in-trait.stderr | 28 ++++++++--------- .../defaults-unsound-62211-1.stderr | 30 +++++++++---------- .../defaults-unsound-62211-2.stderr | 30 +++++++++---------- src/test/ui/error-codes/E0225.stderr | 6 ++-- src/test/ui/issues/issue-40827.stderr | 12 ++++---- ...issing-trait-bounds-for-method-call.stderr | 4 +-- src/test/ui/traits/alias/cross-crate.stderr | 12 ++++---- src/test/ui/traits/item-privacy.stderr | 2 +- 9 files changed, 66 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 947363fc3ed0..a4a07f484a8f 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -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 } @@ -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); diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index 1c493581bc95..d34fc99f85ca 100644 --- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -10,38 +10,38 @@ help: consider further restricting the associated type LL | trait Case1 where <::C as Iterator>::Item: Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: `<::C as Iterator>::Item` cannot be sent between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:27:36 +error[E0277]: `<::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 Lam<&'a u8, App: Debug>> + Sync>; - | ^^^^ `<::C as Iterator>::Item` cannot be sent between threads safely + | ^^^^ `<::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 `<::C as Iterator>::Item` + = help: the trait `Sync` is not implemented for `<::C as Iterator>::Item` help: consider further restricting the associated type | -LL | trait Case1 where <::C as Iterator>::Item: Send { +LL | trait Case1 where <::C as Iterator>::Item: Sync { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: `<::C as Iterator>::Item` cannot be shared between threads safely - --> $DIR/bad-bounds-on-assoc-in-trait.rs:27:93 +error[E0277]: `<::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 Lam<&'a u8, App: Debug>> + Sync>; - | ^^^^ `<::C as Iterator>::Item` cannot be shared between threads safely + | ^^^^ `<::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 `<::C as Iterator>::Item` + = help: the trait `Send` is not implemented for `<::C as Iterator>::Item` help: consider further restricting the associated type | -LL | trait Case1 where <::C as Iterator>::Item: Sync { +LL | trait Case1 where <::C as Iterator>::Item: Send { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr index 8e446cf051f4..135ef87d2902 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr @@ -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 + AddAssign<&'static str> + From + 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 @@ -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 + AddAssign<&'static str> + From + 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 diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr index 93f4f497b38a..1c8f32be6dbf 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr @@ -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 + AddAssign<&'static str> + From + 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 @@ -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 + AddAssign<&'static str> + From + 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 diff --git a/src/test/ui/error-codes/E0225.stderr b/src/test/ui/error-codes/E0225.stderr index 435a2c939627..56dfb6427e7e 100644 --- a/src/test/ui/error-codes/E0225.stderr +++ b/src/test/ui/error-codes/E0225.stderr @@ -13,9 +13,9 @@ 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; | ^^^ @@ -23,7 +23,7 @@ LL | let _: Box; | 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 error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-40827.stderr b/src/test/ui/issues/issue-40827.stderr index 5ea795d13971..95cacbc32ab6 100644 --- a/src/test/ui/issues/issue-40827.stderr +++ b/src/test/ui/issues/issue-40827.stderr @@ -1,27 +1,27 @@ -error[E0277]: `Rc` cannot be sent between threads safely +error[E0277]: `Rc` cannot be shared between threads safely --> $DIR/issue-40827.rs:14:5 | LL | fn f(_: T) {} | ---- required by this bound in `f` ... LL | f(Foo(Arc::new(Bar::B(None)))); - | ^ `Rc` cannot be sent between threads safely + | ^ `Rc` cannot be shared between threads safely | - = help: within `Bar`, the trait `Send` is not implemented for `Rc` + = help: within `Bar`, the trait `Sync` is not implemented for `Rc` = note: required because it appears within the type `Bar` = note: required because of the requirements on the impl of `Send` for `Arc` = note: required because it appears within the type `Foo` -error[E0277]: `Rc` cannot be shared between threads safely +error[E0277]: `Rc` cannot be sent between threads safely --> $DIR/issue-40827.rs:14:5 | LL | fn f(_: T) {} | ---- required by this bound in `f` ... LL | f(Foo(Arc::new(Bar::B(None)))); - | ^ `Rc` cannot be shared between threads safely + | ^ `Rc` cannot be sent between threads safely | - = help: within `Bar`, the trait `Sync` is not implemented for `Rc` + = help: within `Bar`, the trait `Send` is not implemented for `Rc` = note: required because it appears within the type `Bar` = note: required because of the requirements on the impl of `Send` for `Arc` = note: required because it appears within the type `Foo` diff --git a/src/test/ui/suggestions/missing-trait-bounds-for-method-call.stderr b/src/test/ui/suggestions/missing-trait-bounds-for-method-call.stderr index c7376b0007f9..0a64a0d7d5eb 100644 --- a/src/test/ui/suggestions/missing-trait-bounds-for-method-call.stderr +++ b/src/test/ui/suggestions/missing-trait-bounds-for-method-call.stderr @@ -8,10 +8,10 @@ LL | self.foo(); | ^^^ method cannot be called on `&Foo` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: - `T: Bar` - which is required by `Foo: Bar` `T: Default` which is required by `Foo: Bar` + `T: Bar` + which is required by `Foo: Bar` help: consider restricting the type parameters to satisfy the trait bounds | LL | struct Foo where T: Bar, T: Default { diff --git a/src/test/ui/traits/alias/cross-crate.stderr b/src/test/ui/traits/alias/cross-crate.stderr index 3b8fee8e8dfa..ac86329fb8d0 100644 --- a/src/test/ui/traits/alias/cross-crate.stderr +++ b/src/test/ui/traits/alias/cross-crate.stderr @@ -1,24 +1,24 @@ -error[E0277]: `Rc` cannot be sent between threads safely +error[E0277]: `Rc` cannot be shared between threads safely --> $DIR/cross-crate.rs:14:17 | LL | fn use_alias() {} | -------- required by this bound in `use_alias` ... LL | use_alias::>(); - | ^^^^^^^ `Rc` cannot be sent between threads safely + | ^^^^^^^ `Rc` cannot be shared between threads safely | - = help: the trait `Send` is not implemented for `Rc` + = help: the trait `Sync` is not implemented for `Rc` -error[E0277]: `Rc` cannot be shared between threads safely +error[E0277]: `Rc` cannot be sent between threads safely --> $DIR/cross-crate.rs:14:17 | LL | fn use_alias() {} | -------- required by this bound in `use_alias` ... LL | use_alias::>(); - | ^^^^^^^ `Rc` cannot be shared between threads safely + | ^^^^^^^ `Rc` cannot be sent between threads safely | - = help: the trait `Sync` is not implemented for `Rc` + = help: the trait `Send` is not implemented for `Rc` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/item-privacy.stderr b/src/test/ui/traits/item-privacy.stderr index 6fd82142d61f..bb73c1d28bb2 100644 --- a/src/test/ui/traits/item-privacy.stderr +++ b/src/test/ui/traits/item-privacy.stderr @@ -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 --> $DIR/item-privacy.rs:25:15 | From 651a6d16904ba48a2333740f0c58f1b860d77a22 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 12 Mar 2021 14:17:26 -0500 Subject: [PATCH 2/2] Try deduplicating by def path hash --- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index a4a07f484a8f..cf0a313e1876 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1321,7 +1321,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // `dyn Trait + Send`. // 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()); + auto_traits.dedup_by_key(|i| self.tcx().def_path_hash(i.trait_ref().def_id())); debug!("regular_traits: {:?}", regular_traits); debug!("auto_traits: {:?}", auto_traits);