mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-21 19:33:16 +00:00
Auto merge of #88618 - m-ou-se:rollup-6tss5z6, r=m-ou-se
Rollup of 7 pull requests Successful merges: - #88202 (Add an example for deriving PartialOrd on enums) - #88483 (Fix LLVM libunwind build for non-musl targets) - #88507 (Add test case for using `slice::fill` with MaybeUninit) - #88557 (small const generics cleanup) - #88579 (remove redundant / misplaced sentence from docs) - #88610 (Update outdated docs of array::IntoIter::new.) - #88613 (Update primitive docs for rust 2021.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c5799b2a73
@ -820,10 +820,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: &ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// 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<Self::BreakTy> {
|
||||
// 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<Self::BreakTy> {
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -37,7 +37,7 @@ impl<T, const N: usize> IntoIter<T, N> {
|
||||
/// 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<T, const N: usize> IntoIter<T, N> {
|
||||
/// // 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`
|
||||
|
@ -660,6 +660,18 @@ impl<T: Clone> Clone for Reverse<T> {
|
||||
/// 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
|
||||
///
|
||||
|
@ -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)]
|
||||
|
@ -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::<u8>::uninit(); 10];
|
||||
a.fill(MaybeUninit::uninit());
|
||||
}
|
||||
|
@ -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);
|
||||
/// }
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user