提交 45c78380 编写于 作者: B bors

Auto merge of #71496 - Dylan-DPC:rollup-gwxejmk, r=Dylan-DPC

Rollup of 6 pull requests

Successful merges:

 - #70845 (Make the `structural_match` error diagnostic for const generics clearer)
 - #71063 (Document unsafety in core::{option, hash})
 - #71068 (Stabilize UNICODE_VERSION (feature unicode_version))
 - #71426 (fix error code in E0751.md)
 - #71459 (Add leading 0x to offset in Debug fmt of Pointer)
 - #71492 (Document unsafety in core::{panicking, alloc::layout, hint, iter::adapters::zip})

Failed merges:

r? @ghost
// ignore-tidy-undocumented-unsafe
use crate::cmp;
use crate::fmt;
use crate::mem;
......@@ -77,6 +75,8 @@ pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutEr
return Err(LayoutErr { private: () });
}
// SAFETY: the conditions for `from_size_align_unchecked` have been
// checked above.
unsafe { Ok(Layout::from_size_align_unchecked(size, align)) }
}
......@@ -115,7 +115,7 @@ pub const fn align(&self) -> usize {
#[inline]
pub const fn new<T>() -> Self {
let (size, align) = size_align::<T>();
// Note that the align is guaranteed by rustc to be a power of two and
// SAFETY: the align is guaranteed by Rust to be a power of two and
// the size+align combo is guaranteed to fit in our address space. As a
// result use the unchecked constructor here to avoid inserting code
// that panics if it isn't optimized well enough.
......@@ -129,8 +129,8 @@ pub const fn new<T>() -> Self {
#[inline]
pub fn for_value<T: ?Sized>(t: &T) -> Self {
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
// See rationale in `new` for why this is using an unsafe variant below
debug_assert!(Layout::from_size_align(size, align).is_ok());
// SAFETY: see rationale in `new` for why this is using an unsafe variant below
unsafe { Layout::from_size_align_unchecked(size, align) }
}
......@@ -143,7 +143,7 @@ pub fn for_value<T: ?Sized>(t: &T) -> Self {
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub const fn dangling(&self) -> NonNull<u8> {
// align is non-zero and a power of two
// SAFETY: align is guaranteed to be non-zero
unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
}
......@@ -249,11 +249,9 @@ pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
let padded_size = self.size() + self.padding_needed_for(self.align());
let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?;
unsafe {
// self.align is already known to be valid and alloc_size has been
// padded already.
Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
}
// SAFETY: self.align is already known to be valid and alloc_size has been
// padded already.
unsafe { Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size)) }
}
/// Creates a layout describing the record for `self` followed by
......
......@@ -34,9 +34,7 @@
pub use self::convert::{from_digit, from_u32};
#[stable(feature = "decode_utf16", since = "1.9.0")]
pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
// unstable re-exports
#[unstable(feature = "unicode_version", issue = "49726")]
#[stable(feature = "unicode_version", since = "1.45.0")]
pub use crate::unicode::UNICODE_VERSION;
use crate::fmt::{self, Write};
......
......@@ -79,8 +79,6 @@
//! }
//! ```
// ignore-tidy-undocumented-unsafe
#![stable(feature = "rust1", since = "1.0.0")]
use crate::fmt;
......@@ -572,6 +570,10 @@ fn hash<H: Hasher>(&self, state: &mut H) {
fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
let newlen = data.len() * mem::size_of::<$ty>();
let ptr = data.as_ptr() as *const u8;
// SAFETY: `ptr` is valid and aligned, as this macro is only used
// for numeric primitives which have no padding. The new slice only
// spans across `data` and is never mutated, and its total size is the
// same as the original `data` so it can't be over `isize::MAX`.
state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
}
}
......@@ -691,6 +693,11 @@ fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
// SAFETY: we are accessing the memory occupied by `self`
// which is guaranteed to be valid.
// This assumes a fat pointer can be represented by a `(usize, usize)`,
// which is safe to do in `std` because it is shipped and kept in sync
// with the implementation of fat pointers in `rustc`.
let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
state.write_usize(a);
state.write_usize(b);
......@@ -706,6 +713,11 @@ fn hash<H: Hasher>(&self, state: &mut H) {
state.write_usize(*self as *const () as usize);
} else {
// Fat pointer
// SAFETY: we are accessing the memory occupied by `self`
// which is guaranteed to be valid.
// This assumes a fat pointer can be represented by a `(usize, usize)`,
// which is safe to do in `std` because it is shipped and kept in sync
// with the implementation of fat pointers in `rustc`.
let (a, b) = unsafe { *(self as *const Self as *const (usize, usize)) };
state.write_usize(a);
state.write_usize(b);
......
//! An implementation of SipHash.
// ignore-tidy-undocumented-unsafe
#![allow(deprecated)] // the types in this module are deprecated
use crate::cmp;
......@@ -265,6 +263,7 @@ fn write(&mut self, msg: &[u8]) {
if self.ntail != 0 {
needed = 8 - self.ntail;
// SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length`
self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
if length < needed {
self.ntail += length;
......@@ -279,10 +278,13 @@ fn write(&mut self, msg: &[u8]) {
// Buffered tail is now flushed, process new input.
let len = length - needed;
let left = len & 0x7;
let left = len & 0x7; // len % 8
let mut i = needed;
while i < len - left {
// SAFETY: because `len - left` is the biggest multiple of 8 under
// `len`, and because `i` starts at `needed` where `len` is `length - needed`,
// `i + 8` is guaranteed to be less than or equal to `length`.
let mi = unsafe { load_int_le!(msg, i, u64) };
self.state.v3 ^= mi;
......@@ -292,6 +294,9 @@ fn write(&mut self, msg: &[u8]) {
i += 8;
}
// SAFETY: `i` is now `needed + len.div_euclid(8) * 8`,
// so `i + left` = `needed + len` = `length`, which is by
// definition equal to `msg.len()`.
self.tail = unsafe { u8to64_le(msg, i, left) };
self.ntail = left;
}
......
......@@ -2,8 +2,6 @@
//! Hints to compiler that affects how code should be emitted or optimized.
// ignore-tidy-undocumented-unsafe
use crate::intrinsics;
/// Informs the compiler that this point in the code is not reachable, enabling
......@@ -68,11 +66,13 @@ pub fn spin_loop() {
{
#[cfg(target_arch = "x86")]
{
// SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
unsafe { crate::arch::x86::_mm_pause() };
}
#[cfg(target_arch = "x86_64")]
{
// SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
unsafe { crate::arch::x86_64::_mm_pause() };
}
}
......@@ -81,10 +81,13 @@ pub fn spin_loop() {
{
#[cfg(target_arch = "aarch64")]
{
// SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
unsafe { crate::arch::aarch64::__yield() };
}
#[cfg(target_arch = "arm")]
{
// SAFETY: the `cfg` attr ensures that we only execute this on arm targets
// with support for the v6 feature.
unsafe { crate::arch::arm::__yield() };
}
}
......@@ -112,6 +115,8 @@ pub fn black_box<T>(dummy: T) -> T {
// this. LLVM's interpretation of inline assembly is that it's, well, a black
// box. This isn't the greatest implementation since it probably deoptimizes
// more than we want, but it's so far good enough.
// SAFETY: the inline assembly is a no-op.
unsafe {
llvm_asm!("" : : "r"(&dummy));
dummy
......
// ignore-tidy-undocumented-unsafe
use crate::cmp;
use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen};
......@@ -176,9 +174,11 @@ fn next(&mut self) -> Option<(A::Item, B::Item)> {
if self.index < self.len {
let i = self.index;
self.index += 1;
// SAFETY: `i` is smaller than `self.len`, thus smaller than `self.a.len()` and `self.b.len()`
unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
} else if A::may_have_side_effect() && self.index < self.a.len() {
// match the base implementation's potential side effects
// SAFETY: we just checked that `self.index` < `self.a.len()`
unsafe {
self.a.get_unchecked(self.index);
}
......@@ -203,11 +203,15 @@ fn nth(&mut self, n: usize) -> Option<Self::Item> {
let i = self.index;
self.index += 1;
if A::may_have_side_effect() {
// SAFETY: the usage of `cmp::min` to calculate `delta`
// ensures that `end` is smaller than or equal to `self.len`,
// so `i` is also smaller than `self.len`.
unsafe {
self.a.get_unchecked(i);
}
}
if B::may_have_side_effect() {
// SAFETY: same as above.
unsafe {
self.b.get_unchecked(i);
}
......@@ -243,6 +247,8 @@ fn next_back(&mut self) -> Option<(A::Item, B::Item)>
if self.index < self.len {
self.len -= 1;
let i = self.len;
// SAFETY: `i` is smaller than the previous value of `self.len`,
// which is also smaller than or equal to `self.a.len()` and `self.b.len()`
unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }
} else {
None
......
......@@ -133,8 +133,6 @@
//! [`Box<T>`]: ../../std/boxed/struct.Box.html
//! [`i32`]: ../../std/primitive.i32.html
// ignore-tidy-undocumented-unsafe
#![stable(feature = "rust1", since = "1.0.0")]
use crate::iter::{FromIterator, FusedIterator, TrustedLen};
......@@ -301,6 +299,8 @@ pub fn as_mut(&mut self) -> Option<&mut T> {
#[inline]
#[stable(feature = "pin", since = "1.33.0")]
pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
// SAFETY: `x` is guaranteed to be pinned because it comes from `self`
// which is pinned.
unsafe { Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x)) }
}
......@@ -310,6 +310,8 @@ pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
#[inline]
#[stable(feature = "pin", since = "1.33.0")]
pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
// SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`.
// `x` is guaranteed to be pinned because it comes from `self` which is pinned.
unsafe { Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x)) }
}
......@@ -858,6 +860,8 @@ pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
match *self {
Some(ref mut v) => v,
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
// variant in the code above.
None => unsafe { hint::unreachable_unchecked() },
}
}
......
......@@ -19,8 +19,6 @@
//! necessary lang items for the compiler. All panics are funneled through this
//! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
// ignore-tidy-undocumented-unsafe
#![allow(dead_code, missing_docs)]
#![unstable(
feature = "core_panic",
......@@ -41,6 +39,7 @@
#[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators
pub fn panic(expr: &str) -> ! {
if cfg!(feature = "panic_immediate_abort") {
// SAFETY: the `abort` intrinsic has no requirements to be called.
unsafe { super::intrinsics::abort() }
}
......@@ -63,6 +62,7 @@ pub fn panic(expr: &str) -> ! {
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
fn panic_bounds_check(index: usize, len: usize) -> ! {
if cfg!(feature = "panic_immediate_abort") {
// SAFETY: the `abort` intrinsic has no requirements to be called.
unsafe { super::intrinsics::abort() }
}
......@@ -77,6 +77,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
if cfg!(feature = "panic_immediate_abort") {
// SAFETY: the `abort` intrinsic has no requirements to be called.
unsafe { super::intrinsics::abort() }
}
......@@ -93,6 +94,7 @@ fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
#[cfg_attr(not(bootstrap), track_caller)]
pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<'_>) -> ! {
if cfg!(feature = "panic_immediate_abort") {
// SAFETY: the `abort` intrinsic has no requirements to be called.
unsafe { super::intrinsics::abort() }
}
......@@ -108,5 +110,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, #[cfg(bootstrap)] location: &Location<
#[cfg(not(bootstrap))]
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller());
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
unsafe { panic_impl(&pi) }
}
......@@ -7,9 +7,14 @@
/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of
/// `char` and `str` methods are based on.
///
/// New versions of Unicode are released regularly and subsequently all methods
/// in the standard library depending on Unicode are updated. Therefore the
/// behavior of some `char` and `str` methods and the value of this constant
/// changes over time. This is *not* considered to be a breaking change.
///
/// The version numbering scheme is explained in
/// [Unicode 11.0 or later, Section 3.1 Versions of the Unicode Standard](https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=4).
#[unstable(feature = "unicode_version", issue = "49726")]
#[stable(feature = "unicode_version", since = "1.45.0")]
pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION;
// For use in liballoc, not re-exported in libstd.
......
......@@ -2,7 +2,7 @@ There are both a positive and negative trait implementation for the same type.
Erroneous code example:
```compile_fail,E0748
```compile_fail,E0751
trait MyTrait {}
impl MyTrait for i32 { }
impl !MyTrait for i32 { }
......
......@@ -121,13 +121,13 @@ pub struct Pointer<Tag = (), Id = AllocId> {
impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}+{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
write!(f, "{:?}+0x{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
}
}
// Specialization for no tag
impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}+{:x}", self.alloc_id, self.offset.bytes())
write!(f, "{:?}+0x{:x}", self.alloc_id, self.offset.bytes())
}
}
......
......@@ -345,7 +345,7 @@ fn report_negative_positive_conflict(
let mut err = struct_span_err!(
tcx.sess,
impl_span,
E0748,
E0751,
"found both positive and negative implementation of trait `{}`{}:",
overlap.trait_desc,
overlap.self_desc.clone().map_or(String::new(), |ty| format!(" for type `{}`", ty))
......
......@@ -341,17 +341,45 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty)
.is_some()
{
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"the types of const generic parameters must derive `PartialEq` and `Eq`",
)
.span_label(
hir_ty.span,
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
)
.emit();
// We use the same error code in both branches, because this is really the same
// issue: we just special-case the message for type parameters to make it
// clearer.
if let ty::Param(_) = ty.peel_refs().kind {
// Const parameters may not have type parameters as their types,
// because we cannot be sure that the type parameter derives `PartialEq`
// and `Eq` (just implementing them is not enough for `structural_match`).
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
used as the type of a const parameter",
ty,
)
.span_label(
hir_ty.span,
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
)
.note(
"it is not currently possible to use a type parameter as the type of a \
const parameter",
)
.emit();
} else {
struct_span_err!(
tcx.sess,
hir_ty.span,
E0741,
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
the type of a const parameter",
ty,
)
.span_label(
hir_ty.span,
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
)
.emit();
}
}
ty
}
......
......@@ -16,10 +16,10 @@ fn main() -> () {
_1 = const b"foo"; // bb0[1]: scope 0 at $DIR/byte_slice.rs:5:13: 5:19
// ty::Const
// + ty: &[u8; 3]
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/byte_slice.rs:5:13: 5:19
// + literal: Const { ty: &[u8; 3], val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &[u8; 3], val: Value(Scalar(alloc0+0x0)) }
StorageLive(_2); // bb0[2]: scope 1 at $DIR/byte_slice.rs:6:9: 6:10
_2 = [const 5u8, const 120u8]; // bb0[3]: scope 1 at $DIR/byte_slice.rs:6:13: 6:24
// ty::Const
......
......@@ -7,13 +7,13 @@ promoted[0] in BAR: &[&i32; 1] = {
let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
bb0: {
_3 = const {alloc0+0: &i32}; // bb0[0]: scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
_3 = const {alloc0+0x0: &i32}; // bb0[0]: scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
// ty::Const
// + ty: &i32
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
// + literal: Const { ty: &i32, val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &i32, val: Value(Scalar(alloc0+0x0)) }
_2 = _3; // bb0[1]: scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
_1 = [move _2]; // bb0[2]: scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
_0 = &_1; // bb0[3]: scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
......
......@@ -16,16 +16,16 @@
- StorageLive(_3); // bb0[2]: scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
- StorageLive(_4); // bb0[3]: scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
- StorageLive(_5); // bb0[4]: scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
- _5 = const {alloc0+0: &i32}; // bb0[5]: scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
- _5 = const {alloc0+0x0: &i32}; // bb0[5]: scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
+ _6 = const BAR::promoted[0]; // bb0[2]: scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
// ty::Const
- // + ty: &i32
- // + val: Value(Scalar(alloc0+0))
- // + val: Value(Scalar(alloc0+0x0))
+ // + ty: &[&i32; 1]
+ // + val: Unevaluated(DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), [], Some(promoted[0]))
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc0+0)) }
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc0+0x0)) }
- _4 = &(*_5); // bb0[6]: scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34
- _3 = [move _4]; // bb0[7]: scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
- _2 = &_3; // bb0[8]: scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
......
......@@ -9,13 +9,13 @@ promoted[0] in FOO: &[&i32; 1] = {
}
bb0: {
_3 = const {alloc2+0: &i32}; // bb0[0]: scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
_3 = const {alloc2+0x0: &i32}; // bb0[0]: scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
// ty::Const
// + ty: &i32
// + val: Value(Scalar(alloc2+0))
// + val: Value(Scalar(alloc2+0x0))
// mir::Constant
// + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
// + literal: Const { ty: &i32, val: Value(Scalar(alloc2+0)) }
// + literal: Const { ty: &i32, val: Value(Scalar(alloc2+0x0)) }
_2 = _3; // bb0[1]: scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
_1 = [move _2]; // bb0[2]: scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
_0 = &_1; // bb0[3]: scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
......
......@@ -18,16 +18,16 @@
- StorageLive(_3); // bb0[2]: scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
- StorageLive(_4); // bb0[3]: scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45
- StorageLive(_5); // bb0[4]: scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
- _5 = const {alloc2+0: &i32}; // bb0[5]: scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
- _5 = const {alloc2+0x0: &i32}; // bb0[5]: scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+ _6 = const FOO::promoted[0]; // bb0[2]: scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
// ty::Const
- // + ty: &i32
- // + val: Value(Scalar(alloc2+0))
- // + val: Value(Scalar(alloc2+0x0))
+ // + ty: &[&i32; 1]
+ // + val: Unevaluated(DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), [], Some(promoted[0]))
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc2+0)) }
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc2+0x0)) }
- _4 = &(*_5); // bb0[6]: scope 1 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
- _3 = [move _4]; // bb0[7]: scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
- _2 = &_3; // bb0[8]: scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
......
......@@ -8,13 +8,13 @@ fn main() -> () {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageLive(_2); // bb0[1]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
_2 = const {alloc0+0: &&[(std::option::Option<i32>, &[&str])]}; // bb0[2]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
_2 = const {alloc0+0x0: &&[(std::option::Option<i32>, &[&str])]}; // bb0[2]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
// ty::Const
// + ty: &&[(std::option::Option<i32>, &[&str])]
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const_allocation.rs:8:5: 8:8
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc0+0x0)) }
_1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
......
......@@ -8,13 +8,13 @@ fn main() -> () {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageLive(_2); // bb0[1]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
_2 = const {alloc0+0: &&[(std::option::Option<i32>, &[&str])]}; // bb0[2]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
_2 = const {alloc0+0x0: &&[(std::option::Option<i32>, &[&str])]}; // bb0[2]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
// ty::Const
// + ty: &&[(std::option::Option<i32>, &[&str])]
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const_allocation.rs:8:5: 8:8
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc0+0x0)) }
_1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8
StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9
......
......@@ -8,13 +8,13 @@ fn main() -> () {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageLive(_2); // bb0[1]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
_2 = const {alloc0+0: &&[(std::option::Option<i32>, &[&u8])]}; // bb0[2]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
_2 = const {alloc0+0x0: &&[(std::option::Option<i32>, &[&u8])]}; // bb0[2]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
// ty::Const
// + ty: &&[(std::option::Option<i32>, &[&u8])]
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const_allocation2.rs:5:5: 5:8
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc0+0x0)) }
_1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
......
......@@ -8,13 +8,13 @@ fn main() -> () {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageLive(_2); // bb0[1]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
_2 = const {alloc0+0: &&[(std::option::Option<i32>, &[&u8])]}; // bb0[2]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
_2 = const {alloc0+0x0: &&[(std::option::Option<i32>, &[&u8])]}; // bb0[2]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
// ty::Const
// + ty: &&[(std::option::Option<i32>, &[&u8])]
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const_allocation2.rs:5:5: 5:8
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc0+0x0)) }
_1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
......
......@@ -8,13 +8,13 @@ fn main() -> () {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
StorageLive(_2); // bb0[1]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
_2 = const {alloc0+0: &&Packed}; // bb0[2]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
_2 = const {alloc0+0x0: &&Packed}; // bb0[2]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
// ty::Const
// + ty: &&Packed
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const_allocation3.rs:5:5: 5:8
// + literal: Const { ty: &&Packed, val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &&Packed, val: Value(Scalar(alloc0+0x0)) }
_1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
......
......@@ -8,13 +8,13 @@ fn main() -> () {
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
StorageLive(_2); // bb0[1]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
_2 = const {alloc0+0: &&Packed}; // bb0[2]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
_2 = const {alloc0+0x0: &&Packed}; // bb0[2]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
// ty::Const
// + ty: &&Packed
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/const_allocation3.rs:5:5: 5:8
// + literal: Const { ty: &&Packed, val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &&Packed, val: Value(Scalar(alloc0+0x0)) }
_1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9
......
......@@ -16,13 +16,13 @@
StorageLive(_1); // bb0[0]: scope 0 at $DIR/read_immutable_static.rs:7:9: 7:10
StorageLive(_2); // bb0[1]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
StorageLive(_3); // bb0[2]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
_3 = const {alloc0+0: &u8}; // bb0[3]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
_3 = const {alloc0+0x0: &u8}; // bb0[3]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
// ty::Const
// + ty: &u8
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/read_immutable_static.rs:7:13: 7:16
// + literal: Const { ty: &u8, val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &u8, val: Value(Scalar(alloc0+0x0)) }
- _2 = (*_3); // bb0[4]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
+ _2 = const 2u8; // bb0[4]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
+ // ty::Const
......@@ -33,13 +33,13 @@
+ // + literal: Const { ty: u8, val: Value(Scalar(0x02)) }
StorageLive(_4); // bb0[5]: scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
StorageLive(_5); // bb0[6]: scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
_5 = const {alloc0+0: &u8}; // bb0[7]: scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
_5 = const {alloc0+0x0: &u8}; // bb0[7]: scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
// ty::Const
// + ty: &u8
// + val: Value(Scalar(alloc0+0))
// + val: Value(Scalar(alloc0+0x0))
// mir::Constant
// + span: $DIR/read_immutable_static.rs:7:19: 7:22
// + literal: Const { ty: &u8, val: Value(Scalar(alloc0+0)) }
// + literal: Const { ty: &u8, val: Value(Scalar(alloc0+0x0)) }
- _4 = (*_5); // bb0[8]: scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
- _1 = Add(move _2, move _4); // bb0[9]: scope 0 at $DIR/read_immutable_static.rs:7:13: 7:22
+ _4 = const 2u8; // bb0[8]: scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
......
// run-pass
#![feature(unicode_version)]
/// Tests access to the internal Unicode Version type and value.
/// Tests access to the Unicode version constant.
pub fn main() {
check(std::char::UNICODE_VERSION);
}
......
error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
|
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
......@@ -18,5 +18,5 @@ LL | unsafe impl<T: 'static> Send for TestType<T> {}
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0119, E0748.
Some errors have detailed explanations: E0119, E0751.
For more information about an error, try `rustc --explain E0119`.
use std::marker::PhantomData;
struct B<T, const N: T>(PhantomData<[T; N]>); //~ ERROR const generics are unstable
//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq`
//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
fn main() {}
......@@ -7,11 +7,13 @@ LL | struct B<T, const N: T>(PhantomData<[T; N]>);
= note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
= help: add `#![feature(const_generics)]` to the crate attributes to enable
error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
--> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22
|
LL | struct B<T, const N: T>(PhantomData<[T; N]>);
| ^ `T` doesn't derive both `PartialEq` and `Eq`
| ^ `T` may not derive both `PartialEq` and `Eq`
|
= note: it is not currently possible to use a type parameter as the type of a const parameter
error: aborting due to 2 previous errors
......
......@@ -7,6 +7,6 @@
// details.
pub struct Dependent<T, const X: T>([(); X]);
//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq`
//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]`
fn main() {}
......@@ -6,11 +6,13 @@ LL | #![feature(const_generics)]
|
= note: `#[warn(incomplete_features)]` on by default
error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter
--> $DIR/const-param-type-depends-on-type-param.rs:9:34
|
LL | pub struct Dependent<T, const X: T>([(); X]);
| ^ `T` doesn't derive both `PartialEq` and `Eq`
| ^ `T` may not derive both `PartialEq` and `Eq`
|
= note: it is not currently possible to use a type parameter as the type of a const parameter
error: aborting due to previous error; 1 warning emitted
......
......@@ -8,6 +8,6 @@
struct C;
struct D<const X: C>; //~ ERROR the types of const generic parameters must derive
struct D<const X: C>; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]`
fn main() {}
......@@ -6,7 +6,7 @@ LL | #![feature(const_generics)]
|
= note: `#[warn(incomplete_features)]` on by default
error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq`
error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
--> $DIR/forbid-non-structural_match-types.rs:11:19
|
LL | struct D<const X: C>;
......
......@@ -23,7 +23,7 @@ trait Trait2 {}
impl Trait2 for dyn Send {}
impl !Trait2 for dyn Send {}
//~^ ERROR E0748
//~^ ERROR E0751
// Problem 3: type parameter
trait Trait3<T: ?Sized> {}
......
......@@ -6,7 +6,7 @@ LL | impl Trait1 for dyn Send {}
LL | impl Trait1 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
error[E0748]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
--> $DIR/issue-33140-hack-boundaries.rs:25:1
|
LL | impl Trait2 for dyn Send {}
......@@ -64,5 +64,5 @@ LL | impl Trait5 for dyn Send where u32: Copy {}
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0119, E0748.
Some errors have detailed explanations: E0119, E0751.
For more information about an error, try `rustc --explain E0119`.
......@@ -6,6 +6,6 @@ trait MyTrait {}
struct TestType<T>(::std::marker::PhantomData<T>);
unsafe impl<T: Clone> Send for TestType<T> {}
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0748
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0751
fn main() {}
error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
--> $DIR/specialization-overlap-negative.rs:9:1
|
LL | unsafe impl<T: Clone> Send for TestType<T> {}
......@@ -8,4 +8,4 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
error: aborting due to previous error
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
......@@ -7,11 +7,11 @@
auto trait Foo {}
impl<T> Foo for T {}
impl !Foo for u8 {} //~ ERROR E0748
impl !Foo for u8 {} //~ ERROR E0751
auto trait Bar {}
impl<T> !Bar for T {}
impl Bar for u8 {} //~ ERROR E0748
impl Bar for u8 {} //~ ERROR E0751
fn main() {}
error[E0748]: found both positive and negative implementation of trait `Foo` for type `u8`:
error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`:
--> $DIR/specialization-polarity.rs:10:1
|
LL | impl<T> Foo for T {}
......@@ -6,7 +6,7 @@ LL | impl<T> Foo for T {}
LL | impl !Foo for u8 {}
| ^^^^^^^^^^^^^^^^ negative implementation here
error[E0748]: found both positive and negative implementation of trait `Bar` for type `u8`:
error[E0751]: found both positive and negative implementation of trait `Bar` for type `u8`:
--> $DIR/specialization-polarity.rs:15:1
|
LL | impl<T> !Bar for T {}
......@@ -16,4 +16,4 @@ LL | impl Bar for u8 {}
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
......@@ -8,6 +8,6 @@ trait MyTrait {
impl<T> MyTrait for T {
default fn foo() {}
}
impl !MyTrait for u32 {} //~ ERROR E0748
impl !MyTrait for u32 {} //~ ERROR E0751
fn main() {}
error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
--> $DIR/negative-specializes-positive-item.rs:11:1
|
LL | impl<T> MyTrait for T {
......@@ -9,4 +9,4 @@ LL | impl !MyTrait for u32 {}
error: aborting due to previous error
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
......@@ -4,7 +4,7 @@
// Negative impl for u32 cannot "specialize" the base impl.
trait MyTrait {}
impl<T> MyTrait for T {}
impl !MyTrait for u32 {} //~ ERROR E0748
impl !MyTrait for u32 {} //~ ERROR E0751
// The second impl specializes the first, no error.
trait MyTrait2 {}
......
error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
--> $DIR/negative-specializes-positive.rs:7:1
|
LL | impl<T> MyTrait for T {}
......@@ -8,4 +8,4 @@ LL | impl !MyTrait for u32 {}
error: aborting due to previous error
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
......@@ -5,7 +5,7 @@
struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
impl<'a> Clone for &'a mut MyType<'a> {
//~^ ERROR E0748
//~^ ERROR E0751
fn clone(&self) -> &'a mut MyType<'a> {
self.0.replace(None).unwrap()
}
......
error[E0748]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`:
error[E0751]: found both positive and negative implementation of trait `std::clone::Clone` for type `&mut MyType<'_>`:
--> $DIR/pin-unsound-issue-66544-clone.rs:7:1
|
LL | impl<'a> Clone for &'a mut MyType<'a> {
......@@ -8,4 +8,4 @@ LL | impl<'a> Clone for &'a mut MyType<'a> {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
......@@ -10,7 +10,7 @@
struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
impl<'a> DerefMut for &'a MyType<'a> {
//~^ ERROR E0748
//~^ ERROR E0751
fn deref_mut(&mut self) -> &mut MyType<'a> {
self.0.replace(None).unwrap()
}
......
error[E0748]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`:
error[E0751]: found both positive and negative implementation of trait `std::ops::DerefMut` for type `&MyType<'_>`:
--> $DIR/pin-unsound-issue-66544-derefmut.rs:12:1
|
LL | impl<'a> DerefMut for &'a MyType<'a> {
......@@ -8,4 +8,4 @@ LL | impl<'a> DerefMut for &'a MyType<'a> {
error: aborting due to previous error
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
......@@ -4,6 +4,6 @@
trait MyTrait {}
impl<T> !MyTrait for T {}
impl MyTrait for u32 {} //~ ERROR E0748
impl MyTrait for u32 {} //~ ERROR E0751
fn main() {}
error[E0748]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`:
--> $DIR/positive-specializes-negative.rs:7:1
|
LL | impl<T> !MyTrait for T {}
......@@ -8,4 +8,4 @@ LL | impl MyTrait for u32 {}
error: aborting due to previous error
For more information about this error, try `rustc --explain E0748`.
For more information about this error, try `rustc --explain E0751`.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册