From c0e913fdd7f35b197c6da198c25569fc63244b85 Mon Sep 17 00:00:00 2001 From: Noa Date: Fri, 8 Mar 2024 12:27:24 -0600 Subject: [PATCH 01/17] Document overrides of `clone_from()` Specifically, when an override doesn't just forward to an inner type, document the behavior and that it's preferred over simply assigning a clone of source. Also, change instances where the second parameter is "other" to "source". --- library/alloc/src/boxed.rs | 26 +++++++++++--- .../alloc/src/collections/binary_heap/mod.rs | 6 ++++ library/alloc/src/collections/btree/set.rs | 4 +-- library/alloc/src/collections/linked_list.rs | 22 +++++++----- .../alloc/src/collections/vec_deque/mod.rs | 10 ++++-- library/alloc/src/string.rs | 4 +++ library/alloc/src/vec/mod.rs | 26 ++++++++++++-- library/core/src/cell.rs | 4 +-- library/core/src/cmp.rs | 4 +-- library/core/src/task/wake.rs | 36 +++++++++++++++++++ library/std/src/collections/hash/map.rs | 4 +-- library/std/src/collections/hash/set.rs | 4 +++ library/std/src/ffi/os_str.rs | 4 +++ library/std/src/path.rs | 4 +++ 14 files changed, 134 insertions(+), 24 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2736e5ee6c58..91247e7ad4c2 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2084,11 +2084,29 @@ impl Clone for Box<[T], A> { self.to_vec_in(alloc).into_boxed_slice() } - fn clone_from(&mut self, other: &Self) { - if self.len() == other.len() { - self.clone_from_slice(&other); + /// Copies `source`'s contents into `self` without creating a new allocation, + /// so long as the two are of the same length. + /// + /// # Examples + /// + /// ``` + /// let x = Box::new([5, 6, 7]); + /// let mut y = Box::new([8, 9, 10]); + /// let yp: *const [i32] = &*y; + /// + /// y.clone_from(&x); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no allocation occurred + /// assert_eq!(yp, &*y); + /// ``` + fn clone_from(&mut self, source: &Self) { + if self.len() == source.len() { + self.clone_from_slice(&source); } else { - *self = other.clone(); + *self = source.clone(); } } } diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 83b2678f7f52..c54f0062824a 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -385,6 +385,12 @@ impl Clone for BinaryHeap { BinaryHeap { data: self.data.clone() } } + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. + /// + /// See [`Vec::clone_from()`] for more details. fn clone_from(&mut self, source: &Self) { self.data.clone_from(&source.data); } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index ed91ae1a66e3..2d42de4747cb 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -116,8 +116,8 @@ impl Clone for BTreeSet { BTreeSet { map: self.map.clone() } } - fn clone_from(&mut self, other: &Self) { - self.map.clone_from(&other.map); + fn clone_from(&mut self, source: &Self) { + self.map.clone_from(&source.map); } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 6dfb82ac807a..1c90c171a155 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -2126,16 +2126,22 @@ impl Clone for LinkedList { list } - fn clone_from(&mut self, other: &Self) { - let mut iter_other = other.iter(); - if self.len() > other.len() { - self.split_off(other.len()); + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation of the nodes of the linked list. Additionally, + /// if the element type `T` overrides `clone_from()`, this will reuse the + /// resources of `self`'s elements as well. + fn clone_from(&mut self, source: &Self) { + let mut source_iter = source.iter(); + if self.len() > source.len() { + self.split_off(source.len()); } - for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) { - elem.clone_from(elem_other); + for (elem, source_elem) in self.iter_mut().zip(&mut source_iter) { + elem.clone_from(source_elem); } - if !iter_other.is_empty() { - self.extend(iter_other.cloned()); + if !source_iter.is_empty() { + self.extend(source_iter.cloned()); } } } diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index c35bab5ef665..8df7ca3411d6 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -113,9 +113,15 @@ impl Clone for VecDeque { deq } - fn clone_from(&mut self, other: &Self) { + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. Additionally, if the element type + /// `T` overrides `clone_from()`, this will reuse the resources of `self`'s + /// elements as well. + fn clone_from(&mut self, source: &Self) { self.clear(); - self.extend(other.iter().cloned()); + self.extend(source.iter().cloned()); } } diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 98ded7f6cdf5..fd36583ec8e8 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2084,6 +2084,10 @@ impl Clone for String { String { vec: self.vec.clone() } } + /// Clones the contents of `source` into `self`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. fn clone_from(&mut self, source: &Self) { self.vec.clone_from(&source.vec); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index c0e934b3b1fc..b8ed9710839a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2758,8 +2758,30 @@ impl Clone for Vec { crate::slice::to_vec(&**self, alloc) } - fn clone_from(&mut self, other: &Self) { - crate::slice::SpecCloneIntoVec::clone_into(other.as_slice(), self); + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. Additionally, if the element type + /// `T` overrides `clone_from()`, this will reuse the resources of `self`'s + /// elements as well. + /// + /// # Examples + /// + /// ``` + /// let x = vec![5, 6, 7]; + /// let mut y = vec![8, 9, 10]; + /// let yp: *const i32 = y.as_ptr(); + /// + /// y.clone_from(&x); + /// + /// // The value is the same + /// assert_eq!(x, y); + /// + /// // And no reallocation occurred + /// assert_eq!(yp, y.as_ptr()); + /// ``` + fn clone_from(&mut self, source: &Self) { + crate::slice::SpecCloneIntoVec::clone_into(source.as_slice(), self); } } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 19b05448c878..835edc4424d8 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1276,8 +1276,8 @@ impl Clone for RefCell { /// Panics if `other` is currently mutably borrowed. #[inline] #[track_caller] - fn clone_from(&mut self, other: &Self) { - self.get_mut().clone_from(&other.borrow()) + fn clone_from(&mut self, source: &Self) { + self.get_mut().clone_from(&source.borrow()) } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index a2f07814726a..500fd5ef5c3a 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -684,8 +684,8 @@ impl Clone for Reverse { } #[inline] - fn clone_from(&mut self, other: &Self) { - self.0.clone_from(&other.0) + fn clone_from(&mut self, source: &Self) { + self.0.clone_from(&source.0) } } diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 8fc942dedc9b..7ce9693576e7 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -515,6 +515,42 @@ impl Clone for Waker { } } + /// Assigns a clone of `source` to `self`, unless [`self.will_wake(source)`][Waker::will_wake] anyway. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids cloning the waker if `self` is already the same waker. + /// + /// # Examples + /// + /// ``` + /// use std::future::Future; + /// use std::pin::Pin; + /// use std::sync::{Arc, Mutex}; + /// use std::task::{Context, Poll, Waker}; + /// + /// struct Waiter { + /// shared: Arc>, + /// } + /// + /// struct Shared { + /// waker: Waker, + /// // ... + /// } + /// + /// impl Future for Waiter { + /// type Output = (); + /// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + /// let mut shared = self.shared.lock().unwrap(); + /// + /// // update the waker + /// shared.waker.clone_from(cx.waker()); + /// + /// // readiness logic ... + /// # Poll::Ready(()) + /// } + /// } + /// + /// ``` #[inline] fn clone_from(&mut self, source: &Self) { if !self.will_wake(source) { diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 627befb63a1b..7ec4d4829e5b 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1271,8 +1271,8 @@ where } #[inline] - fn clone_from(&mut self, other: &Self) { - self.base.clone_from(&other.base); + fn clone_from(&mut self, source: &Self) { + self.base.clone_from(&source.base); } } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 371201ff44cb..fffbfe477e2b 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -978,6 +978,10 @@ where Self { base: self.base.clone() } } + /// Overwrites the contents of `self` with a clone of the contents of `source`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. #[inline] fn clone_from(&mut self, other: &Self) { self.base.clone_from(&other.base); diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index e44da8e637e9..ef7976d2c501 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -606,6 +606,10 @@ impl Clone for OsString { OsString { inner: self.inner.clone() } } + /// Clones the contents of `source` into `self`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. #[inline] fn clone_from(&mut self, source: &Self) { self.inner.clone_from(&source.inner) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 56ea51226f9d..51cbb1a0f12e 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1628,6 +1628,10 @@ impl Clone for PathBuf { PathBuf { inner: self.inner.clone() } } + /// Clones the contents of `source` into `self`. + /// + /// This method is preferred over simply assigning `source.clone()` to `self`, + /// as it avoids reallocation if possible. #[inline] fn clone_from(&mut self, source: &Self) { self.inner.clone_from(&source.inner) From c8f6e03c1570200dbb99587fb257d371aa7447b3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:19:48 +0000 Subject: [PATCH 02/17] Add regression test --- tests/ui/wf/conflicting-impls.rs | 22 +++++++++++++++ tests/ui/wf/conflicting-impls.stderr | 41 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/ui/wf/conflicting-impls.rs create mode 100644 tests/ui/wf/conflicting-impls.stderr diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs new file mode 100644 index 000000000000..c387199a8bf1 --- /dev/null +++ b/tests/ui/wf/conflicting-impls.rs @@ -0,0 +1,22 @@ +//@ edition: 2021 + +struct Ty; + +impl TryFrom for u8 { + type Error = Ty; + fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed + loop {} + } +} + +impl TryFrom for u8 { + //~^ ERROR conflicting implementations of trait + type Error = Ty; + fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed + loop {} + } +} + +fn main() {} diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr new file mode 100644 index 000000000000..69f48f69bfbf --- /dev/null +++ b/tests/ui/wf/conflicting-impls.stderr @@ -0,0 +1,41 @@ +error[E0119]: conflicting implementations of trait `TryFrom` for type `u8` + --> $DIR/conflicting-impls.rs:12:1 + | +LL | impl TryFrom for u8 { + | ----------------------- first implementation here +... +LL | impl TryFrom for u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` + +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:7:5 + | +LL | fn try_from(_: Ty) -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | +note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: in this trait + ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: this trait's method doesn't have the requirement `_ <: _` + +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:14:5 + | +LL | fn try_from(_: Ty) -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | +note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: in this trait + ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL + | + = note: this trait's method doesn't have the requirement `_ <: _` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0119, E0282. +For more information about an error, try `rustc --explain E0119`. From c0a9c8c9549662ec9199112cb59592ef2c617412 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:23:58 +0000 Subject: [PATCH 03/17] Silence some follow-up errors on trait impls in case the trait has conflicting or otherwise incoherent impls --- .../rustc_hir_analysis/src/check/check.rs | 10 ++++- ...t-conflicts-with-specific-multidispatch.rs | 3 +- ...nflicts-with-specific-multidispatch.stderr | 23 ++--------- tests/ui/coherence/coherence-orphan.rs | 3 -- tests/ui/coherence/coherence-orphan.stderr | 31 ++------------ tests/ui/error-codes/E0117.rs | 1 - tests/ui/error-codes/E0117.stderr | 14 ++----- tests/ui/issues/issue-67535.rs | 6 +-- tests/ui/issues/issue-67535.stderr | 41 +------------------ tests/ui/wf/conflicting-impls.rs | 2 - tests/ui/wf/conflicting-impls.stderr | 33 +-------------- 11 files changed, 25 insertions(+), 142 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8d4ae10d4bfe..b223c590bff6 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -534,8 +534,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } DefKind::Impl { of_trait } => { if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { - check_impl_items_against_trait(tcx, def_id, impl_trait_header); - check_on_unimplemented(tcx, def_id); + if tcx + .ensure() + .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id) + .is_ok() + { + check_impl_items_against_trait(tcx, def_id, impl_trait_header); + check_on_unimplemented(tcx, def_id); + } } } DefKind::Trait => { diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs index 8426748fd52e..fd54fe2b0e8a 100644 --- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs +++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs @@ -22,8 +22,7 @@ struct MyType { impl MyTrait for MyType { //~^ ERROR E0119 fn get(&self) -> usize { (*self).clone() } - //~^ ERROR incompatible type - //~| ERROR mismatched types + //~^ ERROR mismatched types } fn main() { } diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr index 0653009409c5..fc6250dfa026 100644 --- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr +++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr @@ -7,23 +7,6 @@ LL | impl MyTrait for T { LL | impl MyTrait for MyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType` -error[E0053]: method `get` has an incompatible type for trait - --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:22 - | -LL | fn get(&self) -> usize { (*self).clone() } - | ^^^^^ - | | - | expected `MyType`, found `usize` - | help: change the output type to match the trait: `MyType` - | -note: type in trait - --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:8:22 - | -LL | fn get(&self) -> T; - | ^ - = note: expected signature `fn(&MyType) -> MyType` - found signature `fn(&MyType) -> usize` - error[E0308]: mismatched types --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:30 | @@ -32,7 +15,7 @@ LL | fn get(&self) -> usize { (*self).clone() } | | | expected `usize` because of return type -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0053, E0119, E0308. -For more information about an error, try `rustc --explain E0053`. +Some errors have detailed explanations: E0119, E0308. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs index 9c96958f21a1..aee6647a7881 100644 --- a/tests/ui/coherence/coherence-orphan.rs +++ b/tests/ui/coherence/coherence-orphan.rs @@ -9,13 +9,10 @@ struct TheType; impl TheTrait for isize {} //~^ ERROR E0117 -//~| ERROR not all trait items implemented impl TheTrait for isize {} -//~^ ERROR not all trait items implemented impl TheTrait for TheType {} -//~^ ERROR not all trait items implemented impl !Send for Vec {} //~ ERROR E0117 diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr index 48843f7cd181..f6ffae342908 100644 --- a/tests/ui/coherence/coherence-orphan.stderr +++ b/tests/ui/coherence/coherence-orphan.stderr @@ -10,32 +10,8 @@ LL | impl TheTrait for isize {} | = note: define and implement a trait or new type instead -error[E0046]: not all trait items implemented, missing: `the_fn` - --> $DIR/coherence-orphan.rs:10:1 - | -LL | impl TheTrait for isize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation - | - = help: implement the missing item: `fn the_fn(&self) { todo!() }` - -error[E0046]: not all trait items implemented, missing: `the_fn` - --> $DIR/coherence-orphan.rs:14:1 - | -LL | impl TheTrait for isize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation - | - = help: implement the missing item: `fn the_fn(&self) { todo!() }` - -error[E0046]: not all trait items implemented, missing: `the_fn` - --> $DIR/coherence-orphan.rs:17:1 - | -LL | impl TheTrait for TheType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation - | - = help: implement the missing item: `fn the_fn(&self) { todo!() }` - error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate - --> $DIR/coherence-orphan.rs:20:1 + --> $DIR/coherence-orphan.rs:17:1 | LL | impl !Send for Vec {} | ^^^^^^^^^^^^^^^---------- @@ -45,7 +21,6 @@ LL | impl !Send for Vec {} | = note: define and implement a trait or new type instead -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0046, E0117. -For more information about an error, try `rustc --explain E0046`. +For more information about this error, try `rustc --explain E0117`. diff --git a/tests/ui/error-codes/E0117.rs b/tests/ui/error-codes/E0117.rs index 32b9863806c0..406d24e36661 100644 --- a/tests/ui/error-codes/E0117.rs +++ b/tests/ui/error-codes/E0117.rs @@ -1,5 +1,4 @@ impl Drop for u32 {} //~ ERROR E0117 //~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions -//~| ERROR not all trait items implemented fn main() {} diff --git a/tests/ui/error-codes/E0117.stderr b/tests/ui/error-codes/E0117.stderr index 058a64b20d17..f144aa9f72c1 100644 --- a/tests/ui/error-codes/E0117.stderr +++ b/tests/ui/error-codes/E0117.stderr @@ -15,15 +15,7 @@ error[E0120]: the `Drop` trait may only be implemented for local structs, enums, LL | impl Drop for u32 {} | ^^^ must be a struct, enum, or union in the current crate -error[E0046]: not all trait items implemented, missing: `drop` - --> $DIR/E0117.rs:1:1 - | -LL | impl Drop for u32 {} - | ^^^^^^^^^^^^^^^^^ missing `drop` in implementation - | - = help: implement the missing item: `fn drop(&mut self) { todo!() }` +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0046, E0117, E0120. -For more information about an error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0117, E0120. +For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/issues/issue-67535.rs b/tests/ui/issues/issue-67535.rs index 153b95a16743..24f50621310f 100644 --- a/tests/ui/issues/issue-67535.rs +++ b/tests/ui/issues/issue-67535.rs @@ -2,21 +2,21 @@ fn main() {} impl std::ops::AddAssign for () { //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types - fn add_assign(&self, other: ()) -> () { //~ ERROR incompatible type + fn add_assign(&self, other: ()) -> () { () } } impl std::ops::AddAssign for [(); 1] { //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types - fn add_assign(&self, other: [(); 1]) -> [(); 1] { //~ ERROR incompatible type + fn add_assign(&self, other: [(); 1]) -> [(); 1] { [()] } } impl std::ops::AddAssign for &[u8] { //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types - fn add_assign(&self, other: &[u8]) -> &[u8] { //~ ERROR incompatible type + fn add_assign(&self, other: &[u8]) -> &[u8] { self } } diff --git a/tests/ui/issues/issue-67535.stderr b/tests/ui/issues/issue-67535.stderr index c8bde2cb88c7..4d7a02a50969 100644 --- a/tests/ui/issues/issue-67535.stderr +++ b/tests/ui/issues/issue-67535.stderr @@ -34,43 +34,6 @@ LL | impl std::ops::AddAssign for &[u8] { | = note: define and implement a trait or new type instead -error[E0053]: method `add_assign` has an incompatible type for trait - --> $DIR/issue-67535.rs:5:19 - | -LL | fn add_assign(&self, other: ()) -> () { - | ^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&mut self` - | - = note: expected signature `fn(&mut (), ())` - found signature `fn(&(), ())` +error: aborting due to 3 previous errors -error[E0053]: method `add_assign` has an incompatible type for trait - --> $DIR/issue-67535.rs:12:19 - | -LL | fn add_assign(&self, other: [(); 1]) -> [(); 1] { - | ^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&mut self` - | - = note: expected signature `fn(&mut _, _)` - found signature `fn(&_, _) -> [(); 1]` - -error[E0053]: method `add_assign` has an incompatible type for trait - --> $DIR/issue-67535.rs:19:19 - | -LL | fn add_assign(&self, other: &[u8]) -> &[u8] { - | ^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&mut self` - | - = note: expected signature `fn(&mut &_, &_)` - found signature `fn(&&_, &_) -> &[u8]` - -error: aborting due to 6 previous errors - -Some errors have detailed explanations: E0053, E0117. -For more information about an error, try `rustc --explain E0053`. +For more information about this error, try `rustc --explain E0117`. diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs index c387199a8bf1..8054eb7c5943 100644 --- a/tests/ui/wf/conflicting-impls.rs +++ b/tests/ui/wf/conflicting-impls.rs @@ -5,7 +5,6 @@ struct Ty; impl TryFrom for u8 { type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } @@ -14,7 +13,6 @@ impl TryFrom for u8 { //~^ ERROR conflicting implementations of trait type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr index 69f48f69bfbf..d31ae17aa8f7 100644 --- a/tests/ui/wf/conflicting-impls.stderr +++ b/tests/ui/wf/conflicting-impls.stderr @@ -7,35 +7,6 @@ LL | impl TryFrom for u8 { LL | impl TryFrom for u8 { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:7:5 - | -LL | fn try_from(_: Ty) -> Result { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | -note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: in this trait - ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: this trait's method doesn't have the requirement `_ <: _` +error: aborting due to 1 previous error -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:14:5 - | -LL | fn try_from(_: Ty) -> Result { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | -note: the requirement `_ <: _` appears on the `impl`'s method `try_from` but not on the corresponding trait's method - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: in this trait - ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL - | - = note: this trait's method doesn't have the requirement `_ <: _` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0119, E0282. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. From 9ed6e608c92632389b5397744b32e75a24afb884 Mon Sep 17 00:00:00 2001 From: DianQK Date: Tue, 9 Apr 2024 21:44:50 +0800 Subject: [PATCH 04/17] Use `isCI` in `run.sh` --- src/ci/docker/run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 9d72fd8a55a7..30c28a809be3 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -46,7 +46,7 @@ source "$ci_dir/shared.sh" CACHE_DOMAIN="${CACHE_DOMAIN:-ci-caches.rust-lang.org}" if [ -f "$docker_dir/$image/Dockerfile" ]; then - if [ "$CI" != "" ]; then + if isCI; then hash_key=/tmp/.docker-hash-key.txt rm -f "${hash_key}" echo $image >> $hash_key @@ -102,7 +102,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then CACHE_IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci-cache:${cksum} # On non-CI jobs, we don't do any caching. - if [[ "$CI" == "" ]]; + if ! isCI; then retry docker build --rm -t rust-ci -f "$dockerfile" "$context" # On PR CI jobs, we don't have permissions to write to the registry cache, @@ -289,7 +289,7 @@ else command=(/checkout/src/ci/run.sh) fi -if [ "$CI" != "" ]; then +if isCI; then # Get some needed information for $BASE_COMMIT # # This command gets the last merge commit which we'll use as base to list From d92f01a78d1baaf8fc1d8ef49049259b4e2676fc Mon Sep 17 00:00:00 2001 From: DianQK Date: Tue, 9 Apr 2024 21:46:04 +0800 Subject: [PATCH 05/17] Only output to `GITHUB_STEP_SUMMARY` in a CI environment --- src/ci/docker/run.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 30c28a809be3..df90c3875b14 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -339,7 +339,9 @@ docker \ rust-ci \ "${command[@]}" -cat $objdir/${SUMMARY_FILE} >> "${GITHUB_STEP_SUMMARY}" +if isCI; then + cat $objdir/${SUMMARY_FILE} >> "${GITHUB_STEP_SUMMARY}" +fi if [ -f /.dockerenv ]; then rm -rf $objdir From 86e939e9d545a7cac41c74e6650c9c43e7f101c3 Mon Sep 17 00:00:00 2001 From: DianQK Date: Tue, 9 Apr 2024 21:59:36 +0800 Subject: [PATCH 06/17] Change the output artifact path to `$root_dir/obj/$image` when running locally --- src/ci/docker/README.md | 11 ++++------- src/ci/docker/run.sh | 10 +++++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 2e6456837130..9af368ef4450 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -14,7 +14,7 @@ for example: ./src/ci/docker/run.sh x86_64-gnu ``` -Images will output artifacts in an `obj` dir at the root of a repository. Note +Images will output artifacts in an `obj/$image_name` dir at the root of a repository. Note that the script will overwrite the contents of this directory. To match conditions in rusts CI, also set the environment variable `DEPLOY=1`, e.g.: @@ -22,12 +22,9 @@ To match conditions in rusts CI, also set the environment variable `DEPLOY=1`, e DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu ``` -**NOTE**: Re-using the same `obj` dir with different docker images with -the same target triple (e.g. `dist-x86_64-linux` and `dist-various-1`) -may result in strange linker errors, due shared library versions differing between platforms. - -If you encounter any issues when using multiple Docker images, try deleting your `obj` directory -before running your command. +**NOTE**: In CI, the script outputs the artifacts to the `obj` directory, +while locally, to the `obj/$image_name` directory. This is primarily to prevent +strange linker errors when using multiple Docker images. ## Filesystem layout diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index df90c3875b14..fcc507b572c2 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -33,7 +33,13 @@ ci_dir="`dirname $script_dir`" src_dir="`dirname $ci_dir`" root_dir="`dirname $src_dir`" -objdir=$root_dir/obj +source "$ci_dir/shared.sh" + +if isCI; then + objdir=$root_dir/obj +else + objdir=$root_dir/obj/$image +fi dist=$objdir/build/dist @@ -41,8 +47,6 @@ if [ -d "$root_dir/.git" ]; then IS_GIT_SOURCE=1 fi -source "$ci_dir/shared.sh" - CACHE_DOMAIN="${CACHE_DOMAIN:-ci-caches.rust-lang.org}" if [ -f "$docker_dir/$image/Dockerfile" ]; then From 8f3d7fe0388c433008a91da14ef92de9a338b237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 19 Oct 2023 23:15:21 +0200 Subject: [PATCH 07/17] meta: notify #t-rustdoc Zulip stream on backport nominations --- triagebot.toml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index b96225c45205..f92f800ea9eb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -417,6 +417,54 @@ message_on_remove = "Issue #{number}'s prioritization request has been removed." message_on_close = "Issue #{number} has been closed while requested for prioritization." message_on_reopen = "Issue #{number} has been reopened." +# FIXME: Patch triagebot to support `notify-zulip.