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 diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 9fe26711f2102..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_generics): Once more 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 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` 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 /// 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)] diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 43e2af3eb18d2..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] @@ -2144,3 +2145,10 @@ fn test_slice_run_destructors() { assert_eq!(x.get(), 1); } + +#[test] +fn test_slice_fill_with_uninit() { + // This should not UB. See #87891 + let mut a = [MaybeUninit::::uninit(); 10]; + a.fill(MaybeUninit::uninit()); +} 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); /// } 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 }