From 003a636e760d50f4e1e96101f8e9994ac3758135 Mon Sep 17 00:00:00 2001 From: Ariel Davis Date: Fri, 20 Aug 2021 22:24:22 -0400 Subject: [PATCH 01/10] Add an example for deriving PartialOrd on enums For some reason, I always forget which variants are smaller and which are larger when you derive PartialOrd on an enum. And the wording in the current docs is not entirely clear to me. So, I often end up making a small enum, deriving PartialOrd on it, and then writing a `#[test]` with an assert that the top one is smaller than the bottom one (or the other way around) to figure out which way the deriving goes. So then I figured, it would be great if the standard library docs just had that example, so if I keep forgetting, at least I can figure it out quickly by looking at std's docs. --- library/core/src/cmp.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 79610bb409d37..4e82b65539460 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -660,6 +660,18 @@ impl Clone for Reverse { /// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a /// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the top-to-bottom declaration order of the struct's members. /// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order. +/// This means variants at the top are less than variants at the bottom. +/// Here's an example: +/// +/// ``` +/// #[derive(PartialEq, PartialOrd)] +/// enum Size { +/// Small, +/// Large, +/// } +/// +/// assert!(Size::Small < Size::Large); +/// ``` /// /// ## Lexicographical comparison /// From 446c42945d7518e848ba9b9f7c844d6b3cc7b892 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 30 Aug 2021 11:37:02 +0200 Subject: [PATCH 02/10] Fix LLVM libunwind build for non-musl targets Broken in #85600 --- src/bootstrap/compile.rs | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8f27adaed8453..df9e9bce41527 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -142,6 +142,14 @@ fn copy_and_stamp( target_deps.push((target, dependency_type)); } +fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: &Path) -> PathBuf { + let libunwind_path = builder.ensure(native::Libunwind { target }); + let libunwind_source = libunwind_path.join("libunwind.a"); + let libunwind_target = libdir.join("libunwind.a"); + builder.copy(&libunwind_source, &libunwind_target); + libunwind_target +} + /// Copies third party objects needed by various targets. fn copy_third_party_objects( builder: &Builder<'_>, @@ -167,6 +175,15 @@ fn copy_third_party_objects( ); } + if target == "x86_64-fortanix-unknown-sgx" + || builder.config.llvm_libunwind == LlvmLibunwind::InTree + && (target.contains("linux") || target.contains("fuchsia")) + { + let libunwind_path = + copy_llvm_libunwind(builder, target, &builder.sysroot_libdir(*compiler, target)); + target_deps.push((libunwind_path, DependencyType::Target)); + } + target_deps } @@ -208,6 +225,9 @@ fn copy_self_contained_objects( builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained)); } + + let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained); + target_deps.push((libunwind_path, DependencyType::TargetSelfContained)); } else if target.ends_with("-wasi") { let srcdir = builder .wasi_root(target) @@ -234,18 +254,6 @@ fn copy_self_contained_objects( } } - if target.contains("musl") - || target.contains("x86_64-fortanix-unknown-sgx") - || builder.config.llvm_libunwind == LlvmLibunwind::InTree - && (target.contains("linux") || target.contains("fuchsia")) - { - let libunwind_path = builder.ensure(native::Libunwind { target }); - let libunwind_source = libunwind_path.join("libunwind.a"); - let libunwind_target = libdir_self_contained.join("libunwind.a"); - builder.copy(&libunwind_source, &libunwind_target); - target_deps.push((libunwind_target, DependencyType::TargetSelfContained)); - } - target_deps } From 8cecac260298a9b096e347a0489c64aafcd07ca1 Mon Sep 17 00:00:00 2001 From: Katherine Philip Date: Mon, 30 Aug 2021 13:19:50 -0700 Subject: [PATCH 03/10] Add test case for using `slice::fill` with MaybeUninit --- library/core/tests/slice.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 43e2af3eb18d2..a6c7794c15021 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -2144,3 +2144,12 @@ fn test_slice_run_destructors() { assert_eq!(x.get(), 1); } + +#[test] +fn test_slice_fill_with_uninit() { + // This should not UB. See #87891 + use core::mem::MaybeUninit; + + let mut a = [MaybeUninit::::uninit(); 10]; + a.fill(MaybeUninit::uninit()); +} From 5390ea46440d051085c0cf06f64cb2720bb41678 Mon Sep 17 00:00:00 2001 From: Katherine Philip Date: Tue, 31 Aug 2021 08:28:51 -0700 Subject: [PATCH 04/10] Move to the top of file --- library/core/tests/slice.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index a6c7794c15021..c591dd3e1a6db 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,5 +1,6 @@ use core::cell::Cell; use core::cmp::Ordering; +use core::mem::MaybeUninit; use core::result::Result::{Err, Ok}; #[test] @@ -2148,8 +2149,6 @@ fn test_slice_run_destructors() { #[test] fn test_slice_fill_with_uninit() { // This should not UB. See #87891 - use core::mem::MaybeUninit; - let mut a = [MaybeUninit::::uninit(); 10]; a.fill(MaybeUninit::uninit()); } From fc2a2650e2e8d86a9eab06eb1a03ff1a0641cd58 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 Sep 2021 11:41:06 +0200 Subject: [PATCH 05/10] cleanup const generics FIXME --- .../src/traits/object_safety.rs | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 041fd65e8fa49..57b8a84300ff9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -820,10 +820,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( } } - fn visit_const(&mut self, ct: &ty::Const<'tcx>) -> ControlFlow { - // First check if the type of this constant references `Self`. - self.visit_ty(ct.ty)?; - + fn visit_unevaluated_const( + &mut self, + uv: ty::Unevaluated<'tcx>, + ) -> ControlFlow { // Constants can only influence object safety if they reference `Self`. // This is only possible for unevaluated constants, so we walk these here. // @@ -837,7 +837,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // This shouldn't really matter though as we can't really use any // constants which are not considered const evaluatable. use rustc_middle::mir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::from_const(self.tcx, ct) { + if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() { Node::Leaf(leaf) => { let leaf = leaf.subst(self.tcx, ct.substs); @@ -852,31 +852,6 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( ControlFlow::CONTINUE } } - - fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow { - if let ty::PredicateKind::ConstEvaluatable(ct) = pred.kind().skip_binder() { - // FIXME(generic_const_exprs): We should probably deduplicate the logic for - // `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to - // take a `ty::Const` instead. - use rustc_middle::mir::abstract_const::Node; - if let Ok(Some(ct)) = AbstractConst::new(self.tcx, ct) { - const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() { - Node::Leaf(leaf) => { - let leaf = leaf.subst(self.tcx, ct.substs); - self.visit_const(leaf) - } - Node::Cast(_, _, ty) => self.visit_ty(ty), - Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => { - ControlFlow::CONTINUE - } - }) - } else { - ControlFlow::CONTINUE - } - } else { - pred.super_visit_with(self) - } - } } value From 7207194dbbeb92a27dcfae0f7d1143ec3d6506d3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 Sep 2021 11:42:52 +0200 Subject: [PATCH 06/10] update FIXME --- compiler/rustc_typeck/src/outlives/implicit_infer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 9fe26711f2102..3f7a350b11c31 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -120,7 +120,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( // Luckily the only types contained in default substs are type // parameters which don't matter here. // - // FIXME(const_generics): Once more complex const parameter types + // FIXME(const_param_types): Once complex const parameter types // are allowed, this might be incorrect. I think that we will still be // fine, as all outlives relations of the const param types should also // be part of the adt containing it, but we should still both update the From d18ff40a3d9de01dbff4fe7f6ba7fa6db7c65752 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 1 Sep 2021 17:43:07 +0200 Subject: [PATCH 07/10] use the correct feature gate Co-authored-by: Boxy --- compiler/rustc_typeck/src/outlives/implicit_infer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 3f7a350b11c31..0e96601d89fd8 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -120,7 +120,7 @@ fn insert_required_predicates_to_be_wf<'tcx>( // Luckily the only types contained in default substs are type // parameters which don't matter here. // - // FIXME(const_param_types): Once complex const parameter types + // FIXME(adt_const_params): Once complex const parameter types // are allowed, this might be incorrect. I think that we will still be // fine, as all outlives relations of the const param types should also // be part of the adt containing it, but we should still both update the From 9da8e2a2fa902e644b4de143a379e339ed054afe Mon Sep 17 00:00:00 2001 From: ast-ral Date: Wed, 1 Sep 2021 20:52:30 -0700 Subject: [PATCH 08/10] remove redundant / misplaced sentence from docs --- library/core/src/ptr/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 02c9dadc0868d..014170604ecaa 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -182,10 +182,6 @@ mod mut_ptr; /// // Ensure that the last item was dropped. /// assert!(weak.upgrade().is_none()); /// ``` -/// -/// Notice that the compiler performs this copy automatically when dropping packed structs, -/// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` -/// manually. #[stable(feature = "drop_in_place", since = "1.8.0")] #[lang = "drop_in_place"] #[allow(unconditional_recursion)] From 5ea45f35c07ff8a52483ecdd697e9d23fdf53666 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 3 Sep 2021 11:24:52 +0200 Subject: [PATCH 09/10] Update outdated docs of array::IntoIter::new. --- library/core/src/array/iter.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 77c52e51abb2e..ecdbf09881985 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -37,7 +37,7 @@ impl IntoIter { /// Creates a new iterator over the given `array`. /// /// *Note*: this method might be deprecated in the future, - /// after [`IntoIterator` is implemented for arrays][array-into-iter]. + /// since [`IntoIterator`] is now implemented for arrays. /// /// # Examples /// @@ -48,8 +48,13 @@ impl IntoIter { /// // The type of `value` is an `i32` here, instead of `&i32` /// let _: i32 = value; /// } + /// + /// // Since Rust 1.53, arrays implement IntoIterator directly: + /// for value in [1, 2, 3, 4, 5] { + /// // The type of `value` is an `i32` here, instead of `&i32` + /// let _: i32 = value; + /// } /// ``` - /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819 #[stable(feature = "array_value_iter", since = "1.51.0")] pub fn new(array: [T; N]) -> Self { // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit` From 00c8da145cb013e3ead0dba457a09404665feca9 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 3 Sep 2021 12:49:37 +0200 Subject: [PATCH 10/10] Update primitive docs for rust 2021. --- library/std/src/primitive_docs.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index dc4572cd9363b..261d0e648e2ef 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -581,6 +581,8 @@ mod prim_pointer {} /// might be made consistent to the behavior of later editions. /// /// ```rust,edition2018 +/// // Rust 2015 and 2018: +/// /// # #![allow(array_into_iter)] // override our `deny(warnings)` /// let array: [i32; 3] = [0; 3]; /// @@ -604,11 +606,13 @@ mod prim_pointer {} /// } /// ``` /// -/// Starting in the 2021 edition, `array.into_iter()` will use `IntoIterator` normally to iterate +/// Starting in the 2021 edition, `array.into_iter()` uses `IntoIterator` normally to iterate /// by value, and `iter()` should be used to iterate by reference like previous editions. /// -/// ```rust,edition2021,ignore -/// # // FIXME: ignored because 2021 testing is still unstable +#[cfg_attr(bootstrap, doc = "```rust,edition2021,ignore")] +#[cfg_attr(not(bootstrap), doc = "```rust,edition2021")] +/// // Rust 2021: +/// /// let array: [i32; 3] = [0; 3]; /// /// // This iterates by reference: @@ -631,12 +635,12 @@ mod prim_pointer {} /// avoid the `into_iter` syntax on those editions. If an edition update is not /// viable/desired, there are multiple alternatives: /// * use `iter`, equivalent to the old behavior, creating references -/// * use [`array::IntoIter`], equivalent to the post-2021 behavior (Rust 1.51+) +/// * use [`IntoIterator::into_iter`], equivalent to the post-2021 behavior (Rust 1.53+) /// * replace `for ... in array.into_iter() {` with `for ... in array {`, /// equivalent to the post-2021 behavior (Rust 1.53+) /// /// ```rust,edition2018 -/// use std::array::IntoIter; +/// // Rust 2015 and 2018: /// /// let array: [i32; 3] = [0; 3]; /// @@ -647,7 +651,7 @@ mod prim_pointer {} /// } /// /// // This iterates by value: -/// for item in IntoIter::new(array) { +/// for item in IntoIterator::into_iter(array) { /// let x: i32 = item; /// println!("{}", x); /// } @@ -660,7 +664,7 @@ mod prim_pointer {} /// /// // IntoIter can also start a chain. /// // This iterates by value: -/// for item in IntoIter::new(array).enumerate() { +/// for item in IntoIterator::into_iter(array).enumerate() { /// let (i, x): (usize, i32) = item; /// println!("array[{}] = {}", i, x); /// }