diff options
Diffstat (limited to 'tests')
666 files changed, 9022 insertions, 3992 deletions
diff --git a/tests/assembly/cstring-merging.rs b/tests/assembly/cstring-merging.rs index f7d0775f7af..03688e0068b 100644 --- a/tests/assembly/cstring-merging.rs +++ b/tests/assembly/cstring-merging.rs @@ -2,7 +2,7 @@ // other architectures (including ARM and x86-64) use the prefix `.Lanon.` //@ only-linux //@ assembly-output: emit-asm -//@ compile-flags: --crate-type=lib -Copt-level=3 +//@ compile-flags: --crate-type=lib -Copt-level=3 -Cllvm-args=-enable-global-merge=0 //@ edition: 2024 use std::ffi::CStr; diff --git a/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs b/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs index b3b623b509b..f9966a23446 100644 --- a/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs +++ b/tests/assembly/sanitizer/kcfi/emit-arity-indicator.rs @@ -8,6 +8,14 @@ //@ min-llvm-version: 21.0.0 #![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; + +unsafe extern "C" { + safe fn add(x: i32, y: i32) -> i32; +} pub fn add_one(x: i32) -> i32 { // CHECK-LABEL: __cfi__{{.*}}7add_one{{.*}}: @@ -23,7 +31,7 @@ pub fn add_one(x: i32) -> i32 { // CHECK-NEXT: nop // CHECK-NEXT: nop // CHECK-NEXT: mov ecx, 2628068948 - x + 1 + add(x, 1) } pub fn add_two(x: i32, _y: i32) -> i32 { @@ -40,7 +48,7 @@ pub fn add_two(x: i32, _y: i32) -> i32 { // CHECK-NEXT: nop // CHECK-NEXT: nop // CHECK-NEXT: mov edx, 2505940310 - x + 2 + add(x, 2) } pub fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { @@ -57,5 +65,5 @@ pub fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { // CHECK-NEXT: nop // CHECK-NEXT: nop // CHECK-NEXT: mov edx, 653723426 - f(arg) + f(arg) + add(f(arg), f(arg)) } diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs index f05ccfadc58..704e8026f3f 100644 --- a/tests/assembly/wasm_exceptions.rs +++ b/tests/assembly/wasm_exceptions.rs @@ -2,7 +2,6 @@ //@ assembly-output: emit-asm //@ compile-flags: -C target-feature=+exception-handling //@ compile-flags: -C panic=unwind -//@ compile-flags: -C llvm-args=-wasm-enable-eh #![crate_type = "lib"] #![feature(core_intrinsics)] diff --git a/tests/auxiliary/minisimd.rs b/tests/auxiliary/minisimd.rs new file mode 100644 index 00000000000..ff0c996de1c --- /dev/null +++ b/tests/auxiliary/minisimd.rs @@ -0,0 +1,160 @@ +//! Auxiliary crate for tests that need SIMD types. +//! +//! Historically the tests just made their own, but projections into simd types +//! was banned by <https://github.com/rust-lang/compiler-team/issues/838>, which +//! breaks `derive(Clone)`, so this exists to give easily-usable types that can +//! be used without copy-pasting the definitions of the helpers everywhere. +//! +//! This makes no attempt to guard against ICEs. Using it with proper types +//! and such is your responsibility in the tests you write. + +#![allow(unused)] +#![allow(non_camel_case_types)] + +// The field is currently left `pub` for convenience in porting tests, many of +// which attempt to just construct it directly. That still works; it's just the +// `.0` projection that doesn't. +#[repr(simd)] +#[derive(Copy, Eq)] +pub struct Simd<T, const N: usize>(pub [T; N]); + +impl<T: Copy, const N: usize> Clone for Simd<T, N> { + fn clone(&self) -> Self { + *self + } +} + +impl<T: PartialEq, const N: usize> PartialEq for Simd<T, N> { + fn eq(&self, other: &Self) -> bool { + self.as_array() == other.as_array() + } +} + +impl<T: core::fmt::Debug, const N: usize> core::fmt::Debug for Simd<T, N> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <[T; N] as core::fmt::Debug>::fmt(self.as_array(), f) + } +} + +impl<T, const N: usize> core::ops::Index<usize> for Simd<T, N> { + type Output = T; + fn index(&self, i: usize) -> &T { + &self.as_array()[i] + } +} + +impl<T, const N: usize> Simd<T, N> { + pub const fn from_array(a: [T; N]) -> Self { + Simd(a) + } + pub fn as_array(&self) -> &[T; N] { + let p: *const Self = self; + unsafe { &*p.cast::<[T; N]>() } + } + pub fn into_array(self) -> [T; N] + where + T: Copy, + { + *self.as_array() + } +} + +pub type u8x2 = Simd<u8, 2>; +pub type u8x4 = Simd<u8, 4>; +pub type u8x8 = Simd<u8, 8>; +pub type u8x16 = Simd<u8, 16>; +pub type u8x32 = Simd<u8, 32>; +pub type u8x64 = Simd<u8, 64>; + +pub type u16x2 = Simd<u16, 2>; +pub type u16x4 = Simd<u16, 4>; +pub type u16x8 = Simd<u16, 8>; +pub type u16x16 = Simd<u16, 16>; +pub type u16x32 = Simd<u16, 32>; + +pub type u32x2 = Simd<u32, 2>; +pub type u32x4 = Simd<u32, 4>; +pub type u32x8 = Simd<u32, 8>; +pub type u32x16 = Simd<u32, 16>; + +pub type u64x2 = Simd<u64, 2>; +pub type u64x4 = Simd<u64, 4>; +pub type u64x8 = Simd<u64, 8>; + +pub type u128x2 = Simd<u128, 2>; +pub type u128x4 = Simd<u128, 4>; + +pub type i8x2 = Simd<i8, 2>; +pub type i8x4 = Simd<i8, 4>; +pub type i8x8 = Simd<i8, 8>; +pub type i8x16 = Simd<i8, 16>; +pub type i8x32 = Simd<i8, 32>; +pub type i8x64 = Simd<i8, 64>; + +pub type i16x2 = Simd<i16, 2>; +pub type i16x4 = Simd<i16, 4>; +pub type i16x8 = Simd<i16, 8>; +pub type i16x16 = Simd<i16, 16>; +pub type i16x32 = Simd<i16, 32>; + +pub type i32x2 = Simd<i32, 2>; +pub type i32x4 = Simd<i32, 4>; +pub type i32x8 = Simd<i32, 8>; +pub type i32x16 = Simd<i32, 16>; + +pub type i64x2 = Simd<i64, 2>; +pub type i64x4 = Simd<i64, 4>; +pub type i64x8 = Simd<i64, 8>; + +pub type i128x2 = Simd<i128, 2>; +pub type i128x4 = Simd<i128, 4>; + +pub type f32x2 = Simd<f32, 2>; +pub type f32x4 = Simd<f32, 4>; +pub type f32x8 = Simd<f32, 8>; +pub type f32x16 = Simd<f32, 16>; + +pub type f64x2 = Simd<f64, 2>; +pub type f64x4 = Simd<f64, 4>; +pub type f64x8 = Simd<f64, 8>; + +// The field is currently left `pub` for convenience in porting tests, many of +// which attempt to just construct it directly. That still works; it's just the +// `.0` projection that doesn't. +#[repr(simd, packed)] +#[derive(Copy)] +pub struct PackedSimd<T, const N: usize>(pub [T; N]); + +impl<T: Copy, const N: usize> Clone for PackedSimd<T, N> { + fn clone(&self) -> Self { + *self + } +} + +impl<T: PartialEq, const N: usize> PartialEq for PackedSimd<T, N> { + fn eq(&self, other: &Self) -> bool { + self.as_array() == other.as_array() + } +} + +impl<T: core::fmt::Debug, const N: usize> core::fmt::Debug for PackedSimd<T, N> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <[T; N] as core::fmt::Debug>::fmt(self.as_array(), f) + } +} + +impl<T, const N: usize> PackedSimd<T, N> { + pub const fn from_array(a: [T; N]) -> Self { + PackedSimd(a) + } + pub fn as_array(&self) -> &[T; N] { + let p: *const Self = self; + unsafe { &*p.cast::<[T; N]>() } + } + pub fn into_array(self) -> [T; N] + where + T: Copy, + { + *self.as_array() + } +} diff --git a/tests/codegen/const-vector.rs b/tests/codegen/const-vector.rs index 42921442e03..a2249f4fff7 100644 --- a/tests/codegen/const-vector.rs +++ b/tests/codegen/const-vector.rs @@ -16,18 +16,9 @@ #![feature(mips_target_feature)] #![allow(non_camel_case_types)] -// Setting up structs that can be used as const vectors -#[repr(simd)] -#[derive(Clone)] -pub struct i8x2([i8; 2]); - -#[repr(simd)] -#[derive(Clone)] -pub struct f32x2([f32; 2]); - -#[repr(simd, packed)] -#[derive(Copy, Clone)] -pub struct Simd<T, const N: usize>([T; N]); +#[path = "../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::{PackedSimd as Simd, f32x2, i8x2}; // The following functions are required for the tests to ensure // that they are called with a const vector @@ -45,7 +36,7 @@ extern "unadjusted" { // Ensure the packed variant of the simd struct does not become a const vector // if the size is not a power of 2 -// CHECK: %"Simd<i32, 3>" = type { [3 x i32] } +// CHECK: %"minisimd::PackedSimd<i32, 3>" = type { [3 x i32] } #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))] #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))] @@ -54,27 +45,34 @@ extern "unadjusted" { pub fn do_call() { unsafe { // CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64> - test_i8x2(const { i8x2([32, 64]) }); + test_i8x2(const { i8x2::from_array([32, 64]) }); // CHECK: call void @test_i8x2_two_args(<2 x i8> <i8 32, i8 64>, <2 x i8> <i8 8, i8 16> - test_i8x2_two_args(const { i8x2([32, 64]) }, const { i8x2([8, 16]) }); + test_i8x2_two_args( + const { i8x2::from_array([32, 64]) }, + const { i8x2::from_array([8, 16]) }, + ); // CHECK: call void @test_i8x2_mixed_args(<2 x i8> <i8 32, i8 64>, i32 43, <2 x i8> <i8 8, i8 16> - test_i8x2_mixed_args(const { i8x2([32, 64]) }, 43, const { i8x2([8, 16]) }); + test_i8x2_mixed_args( + const { i8x2::from_array([32, 64]) }, + 43, + const { i8x2::from_array([8, 16]) }, + ); // CHECK: call void @test_i8x2_arr(<2 x i8> <i8 32, i8 64> - test_i8x2_arr(const { i8x2([32, 64]) }); + test_i8x2_arr(const { i8x2::from_array([32, 64]) }); // CHECK: call void @test_f32x2(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000> - test_f32x2(const { f32x2([0.32, 0.64]) }); + test_f32x2(const { f32x2::from_array([0.32, 0.64]) }); // CHECK: void @test_f32x2_arr(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000> - test_f32x2_arr(const { f32x2([0.32, 0.64]) }); + test_f32x2_arr(const { f32x2::from_array([0.32, 0.64]) }); // CHECK: call void @test_simd(<4 x i32> <i32 2, i32 4, i32 6, i32 8> test_simd(const { Simd::<i32, 4>([2, 4, 6, 8]) }); - // CHECK: call void @test_simd_unaligned(%"Simd<i32, 3>" %1 + // CHECK: call void @test_simd_unaligned(%"minisimd::PackedSimd<i32, 3>" %1 test_simd_unaligned(const { Simd::<i32, 3>([2, 4, 6]) }); } } diff --git a/tests/codegen/enum/enum-discriminant-eq.rs b/tests/codegen/enum/enum-discriminant-eq.rs new file mode 100644 index 00000000000..0494c5f551b --- /dev/null +++ b/tests/codegen/enum/enum-discriminant-eq.rs @@ -0,0 +1,223 @@ +//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled +//@ min-llvm-version: 20 +//@ only-64bit + +// The `derive(PartialEq)` on enums with field-less variants compares discriminants, +// so make sure we emit that in some reasonable way. + +#![crate_type = "lib"] +#![feature(ascii_char)] +#![feature(core_intrinsics)] +#![feature(repr128)] + +use std::ascii::Char as AC; +use std::cmp::Ordering; +use std::intrinsics::discriminant_value; +use std::num::NonZero; + +// A type that's bigger than `isize`, unlike the usual cases that have small tags. +#[repr(u128)] +pub enum Giant { + Two = 2, + Three = 3, + Four = 4, +} + +#[unsafe(no_mangle)] +pub fn opt_bool_eq_discr(a: Option<bool>, b: Option<bool>) -> bool { + // CHECK-LABEL: @opt_bool_eq_discr( + // CHECK: %[[A:.+]] = icmp ne i8 %a, 2 + // CHECK: %[[B:.+]] = icmp eq i8 %b, 2 + // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] + // CHECK: ret i1 %[[R]] + + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn opt_ord_eq_discr(a: Option<Ordering>, b: Option<Ordering>) -> bool { + // CHECK-LABEL: @opt_ord_eq_discr( + // CHECK: %[[A:.+]] = icmp ne i8 %a, 2 + // CHECK: %[[B:.+]] = icmp eq i8 %b, 2 + // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] + // CHECK: ret i1 %[[R]] + + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn opt_nz32_eq_discr(a: Option<NonZero<u32>>, b: Option<NonZero<u32>>) -> bool { + // CHECK-LABEL: @opt_nz32_eq_discr( + // CHECK: %[[A:.+]] = icmp ne i32 %a, 0 + // CHECK: %[[B:.+]] = icmp eq i32 %b, 0 + // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] + // CHECK: ret i1 %[[R]] + + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn opt_ac_eq_discr(a: Option<AC>, b: Option<AC>) -> bool { + // CHECK-LABEL: @opt_ac_eq_discr( + // CHECK: %[[A:.+]] = icmp ne i8 %a, -128 + // CHECK: %[[B:.+]] = icmp eq i8 %b, -128 + // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] + // CHECK: ret i1 %[[R]] + + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn opt_giant_eq_discr(a: Option<Giant>, b: Option<Giant>) -> bool { + // CHECK-LABEL: @opt_giant_eq_discr( + // CHECK: %[[A:.+]] = icmp ne i128 %a, 1 + // CHECK: %[[B:.+]] = icmp eq i128 %b, 1 + // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] + // CHECK: ret i1 %[[R]] + + discriminant_value(&a) == discriminant_value(&b) +} + +pub enum Mid<T> { + Before, + Thing(T), + After, +} + +#[unsafe(no_mangle)] +pub fn mid_bool_eq_discr(a: Mid<bool>, b: Mid<bool>) -> bool { + // CHECK-LABEL: @mid_bool_eq_discr( + + // CHECK: %[[A_REL_DISCR:.+]] = add nsw i8 %a, -2 + // CHECK: %[[A_IS_NICHE:.+]] = icmp samesign ugt i8 %a, 1 + // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %[[A_REL_DISCR]], 1 + // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) + // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1 + + // CHECK: %[[B_REL_DISCR:.+]] = add nsw i8 %b, -2 + // CHECK: %[[B_IS_NICHE:.+]] = icmp samesign ugt i8 %b, 1 + // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %[[B_REL_DISCR]], 1 + // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) + // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1 + + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn mid_ord_eq_discr(a: Mid<Ordering>, b: Mid<Ordering>) -> bool { + // CHECK-LABEL: @mid_ord_eq_discr( + + // CHECK: %[[A_REL_DISCR:.+]] = add nsw i8 %a, -2 + // CHECK: %[[A_IS_NICHE:.+]] = icmp sgt i8 %a, 1 + // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %[[A_REL_DISCR]], 1 + // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) + // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1 + + // CHECK: %[[B_REL_DISCR:.+]] = add nsw i8 %b, -2 + // CHECK: %[[B_IS_NICHE:.+]] = icmp sgt i8 %b, 1 + // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %[[B_REL_DISCR]], 1 + // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) + // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1 + + // CHECK: %[[R:.+]] = icmp eq i8 %[[A_DISCR]], %[[B_DISCR]] + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn mid_nz32_eq_discr(a: Mid<NonZero<u32>>, b: Mid<NonZero<u32>>) -> bool { + // CHECK-LABEL: @mid_nz32_eq_discr( + // CHECK: %[[R:.+]] = icmp eq i32 %a.0, %b.0 + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == discriminant_value(&b) +} + +#[unsafe(no_mangle)] +pub fn mid_ac_eq_discr(a: Mid<AC>, b: Mid<AC>) -> bool { + // CHECK-LABEL: @mid_ac_eq_discr( + + // CHECK: %[[A_REL_DISCR:.+]] = xor i8 %a, -128 + // CHECK: %[[A_IS_NICHE:.+]] = icmp slt i8 %a, 0 + // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %a, -127 + // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) + // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1 + + // CHECK: %[[B_REL_DISCR:.+]] = xor i8 %b, -128 + // CHECK: %[[B_IS_NICHE:.+]] = icmp slt i8 %b, 0 + // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %b, -127 + // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) + // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1 + + // CHECK: %[[R:.+]] = icmp eq i8 %[[A_DISCR]], %[[B_DISCR]] + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == discriminant_value(&b) +} + +// FIXME: This should be improved once our LLVM fork picks up the fix for +// <https://github.com/llvm/llvm-project/issues/134024> +#[unsafe(no_mangle)] +pub fn mid_giant_eq_discr(a: Mid<Giant>, b: Mid<Giant>) -> bool { + // CHECK-LABEL: @mid_giant_eq_discr( + + // CHECK: %[[A_TRUNC:.+]] = trunc nuw nsw i128 %a to i64 + // CHECK: %[[A_REL_DISCR:.+]] = add nsw i64 %[[A_TRUNC]], -5 + // CHECK: %[[A_IS_NICHE:.+]] = icmp samesign ugt i128 %a, 4 + // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i64 %[[A_REL_DISCR]], 1 + // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) + // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i64 %[[A_REL_DISCR]], i64 1 + + // CHECK: %[[B_TRUNC:.+]] = trunc nuw nsw i128 %b to i64 + // CHECK: %[[B_REL_DISCR:.+]] = add nsw i64 %[[B_TRUNC]], -5 + // CHECK: %[[B_IS_NICHE:.+]] = icmp samesign ugt i128 %b, 4 + // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i64 %[[B_REL_DISCR]], 1 + // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) + // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i64 %[[B_REL_DISCR]], i64 1 + + // CHECK: %[[R:.+]] = icmp eq i64 %[[A_DISCR]], %[[B_DISCR]] + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == discriminant_value(&b) +} + +// In niche-encoded enums, testing for the untagged variant should optimize to a +// straight-forward comparison looking for the natural range of the payload value. + +#[unsafe(no_mangle)] +pub fn mid_bool_is_thing(a: Mid<bool>) -> bool { + // CHECK-LABEL: @mid_bool_is_thing( + // CHECK: %[[R:.+]] = icmp samesign ult i8 %a, 2 + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == 1 +} + +#[unsafe(no_mangle)] +pub fn mid_ord_is_thing(a: Mid<Ordering>) -> bool { + // CHECK-LABEL: @mid_ord_is_thing( + // CHECK: %[[R:.+]] = icmp slt i8 %a, 2 + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == 1 +} + +#[unsafe(no_mangle)] +pub fn mid_nz32_is_thing(a: Mid<NonZero<u32>>) -> bool { + // CHECK-LABEL: @mid_nz32_is_thing( + // CHECK: %[[R:.+]] = icmp eq i32 %a.0, 1 + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == 1 +} + +#[unsafe(no_mangle)] +pub fn mid_ac_is_thing(a: Mid<AC>) -> bool { + // CHECK-LABEL: @mid_ac_is_thing( + // CHECK: %[[R:.+]] = icmp sgt i8 %a, -1 + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == 1 +} + +#[unsafe(no_mangle)] +pub fn mid_giant_is_thing(a: Mid<Giant>) -> bool { + // CHECK-LABEL: @mid_giant_is_thing( + // CHECK: %[[R:.+]] = icmp samesign ult i128 %a, 5 + // CHECK: ret i1 %[[R]] + discriminant_value(&a) == 1 +} diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs index 98635008d06..57db44ec74e 100644 --- a/tests/codegen/enum/enum-match.rs +++ b/tests/codegen/enum/enum-match.rs @@ -41,7 +41,7 @@ pub enum Enum1 { // CHECK-NEXT: start: // CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %0, -2 // CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp ult i8 %[[REL_VAR]], 2 +// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp{{( samesign)?}} ugt i8 %0, 1 // CHECK-NEXT: %[[NICHE_DISCR:.+]] = add nuw nsw i64 %[[REL_VAR_WIDE]], 1 // CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i64 %[[NICHE_DISCR]], i64 0 // CHECK-NEXT: switch i64 %[[DISCR]] @@ -148,10 +148,10 @@ pub enum MiddleNiche { // CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 -?[0-9]+, -?[0-9]+\))?}} i8 @match4(i8{{.+}}%0) // CHECK-NEXT: start: // CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %0, -2 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp ult i8 %[[REL_VAR]], 5 // CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %[[REL_VAR]], 2 // CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) -// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i8 %[[REL_VAR]], i8 2 +// CHECK-NEXT: %[[NOT_NICHE:.+]] = icmp{{( samesign)?}} ult i8 %0, 2 +// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[NOT_NICHE]], i8 2, i8 %[[REL_VAR]] // CHECK-NEXT: switch i8 %[[DISCR]] #[no_mangle] pub fn match4(e: MiddleNiche) -> u8 { @@ -167,11 +167,10 @@ pub fn match4(e: MiddleNiche) -> u8 { // CHECK-LABEL: define{{.+}}i1 @match4_is_c(i8{{.+}}%e) // CHECK-NEXT: start -// CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %e, -2 -// CHECK-NEXT: %[[NOT_NICHE:.+]] = icmp ugt i8 %[[REL_VAR]], 4 -// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %[[REL_VAR]], 2 +// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %e, 4 // CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) -// CHECK-NEXT: ret i1 %[[NOT_NICHE]] +// CHECK-NEXT: %[[IS_C:.+]] = icmp{{( samesign)?}} ult i8 %e, 2 +// CHECK-NEXT: ret i1 %[[IS_C]] #[no_mangle] pub fn match4_is_c(e: MiddleNiche) -> bool { // Before #139098, this couldn't optimize out the `select` because it looked @@ -453,10 +452,10 @@ pub enum HugeVariantIndex { // CHECK-NEXT: start: // CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %0, -2 // CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp ult i8 %[[REL_VAR]], 3 -// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %[[REL_VAR]], 1 -// CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) +// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp{{( samesign)?}} ugt i8 %0, 1 // CHECK-NEXT: %[[NICHE_DISCR:.+]] = add nuw nsw i64 %[[REL_VAR_WIDE]], 257 +// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i64 %[[NICHE_DISCR]], 258 +// CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) // CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i64 %[[NICHE_DISCR]], i64 258 // CHECK-NEXT: switch i64 %[[DISCR]], // CHECK-NEXT: i64 257, @@ -471,3 +470,310 @@ pub fn match5(e: HugeVariantIndex) -> u8 { Possible259 => 100, } } + +// Make an enum where the niche tags wrap both as signed and as unsigned, to hit +// the most-fallback case where there's just nothing smart to do. + +pub enum E10Through65 { + D10 = 10, + D11 = 11, + D12 = 12, + D13 = 13, + D14 = 14, + D15 = 15, + D16 = 16, + D17 = 17, + D18 = 18, + D19 = 19, + D20 = 20, + D21 = 21, + D22 = 22, + D23 = 23, + D24 = 24, + D25 = 25, + D26 = 26, + D27 = 27, + D28 = 28, + D29 = 29, + D30 = 30, + D31 = 31, + D32 = 32, + D33 = 33, + D34 = 34, + D35 = 35, + D36 = 36, + D37 = 37, + D38 = 38, + D39 = 39, + D40 = 40, + D41 = 41, + D42 = 42, + D43 = 43, + D44 = 44, + D45 = 45, + D46 = 46, + D47 = 47, + D48 = 48, + D49 = 49, + D50 = 50, + D51 = 51, + D52 = 52, + D53 = 53, + D54 = 54, + D55 = 55, + D56 = 56, + D57 = 57, + D58 = 58, + D59 = 59, + D60 = 60, + D61 = 61, + D62 = 62, + D63 = 63, + D64 = 64, + D65 = 65, +} + +pub enum Tricky { + Untagged(E10Through65), + V001, + V002, + V003, + V004, + V005, + V006, + V007, + V008, + V009, + V010, + V011, + V012, + V013, + V014, + V015, + V016, + V017, + V018, + V019, + V020, + V021, + V022, + V023, + V024, + V025, + V026, + V027, + V028, + V029, + V030, + V031, + V032, + V033, + V034, + V035, + V036, + V037, + V038, + V039, + V040, + V041, + V042, + V043, + V044, + V045, + V046, + V047, + V048, + V049, + V050, + V051, + V052, + V053, + V054, + V055, + V056, + V057, + V058, + V059, + V060, + V061, + V062, + V063, + V064, + V065, + V066, + V067, + V068, + V069, + V070, + V071, + V072, + V073, + V074, + V075, + V076, + V077, + V078, + V079, + V080, + V081, + V082, + V083, + V084, + V085, + V086, + V087, + V088, + V089, + V090, + V091, + V092, + V093, + V094, + V095, + V096, + V097, + V098, + V099, + V100, + V101, + V102, + V103, + V104, + V105, + V106, + V107, + V108, + V109, + V110, + V111, + V112, + V113, + V114, + V115, + V116, + V117, + V118, + V119, + V120, + V121, + V122, + V123, + V124, + V125, + V126, + V127, + V128, + V129, + V130, + V131, + V132, + V133, + V134, + V135, + V136, + V137, + V138, + V139, + V140, + V141, + V142, + V143, + V144, + V145, + V146, + V147, + V148, + V149, + V150, + V151, + V152, + V153, + V154, + V155, + V156, + V157, + V158, + V159, + V160, + V161, + V162, + V163, + V164, + V165, + V166, + V167, + V168, + V169, + V170, + V171, + V172, + V173, + V174, + V175, + V176, + V177, + V178, + V179, + V180, + V181, + V182, + V183, + V184, + V185, + V186, + V187, + V188, + V189, + V190, + V191, + V192, + V193, + V194, + V195, + V196, + V197, + V198, + V199, + V200, +} + +const _: () = assert!(std::intrinsics::discriminant_value(&Tricky::V100) == 100); + +// CHECK-LABEL: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @discriminant6(i8 noundef %e) +// CHECK-NEXT: start: +// CHECK-NEXT: %[[REL_VAR:.+]] = add i8 %e, -66 +// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp ult i8 %[[REL_VAR]], -56 +// CHECK-NEXT: %[[TAGGED_DISCR:.+]] = add i8 %e, -65 +// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i8 %[[TAGGED_DISCR]], i8 0 +// CHECK-NEXT: ret i8 %[[DISCR]] +#[no_mangle] +pub fn discriminant6(e: Tricky) -> u8 { + std::intrinsics::discriminant_value(&e) as _ +} + +// Case from <https://github.com/rust-lang/rust/issues/104519>, +// where sign-extension is important. + +pub enum OpenResult { + Ok(()), + Err(()), + TransportErr(TransportErr), +} + +#[repr(i32)] +pub enum TransportErr { + UnknownMethod = -2, +} + +#[no_mangle] +pub fn match7(result: OpenResult) -> u8 { + // CHECK-LABEL: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match7(i32{{.+}}%result) + // CHECK-NEXT: start: + // CHECK-NEXT: %[[NOT_OK:.+]] = icmp ne i32 %result, -1 + // CHECK-NEXT: %[[RET:.+]] = zext i1 %[[NOT_OK]] to i8 + // CHECK-NEXT: ret i8 %[[RET]] + match result { + OpenResult::Ok(()) => 0, + _ => 1, + } +} diff --git a/tests/codegen/fn-parameters-on-different-lines-debuginfo.rs b/tests/codegen/fn-parameters-on-different-lines-debuginfo.rs new file mode 100644 index 00000000000..2097567f322 --- /dev/null +++ b/tests/codegen/fn-parameters-on-different-lines-debuginfo.rs @@ -0,0 +1,22 @@ +//! Make sure that line debuginfo of function parameters are correct even if +//! they are not on the same line. Regression test for +// <https://github.com/rust-lang/rust/issues/45010>. + +//@ compile-flags: -g -Copt-level=0 + +#[rustfmt::skip] // Having parameters on different lines is crucial for this test. +pub fn foo( + x_parameter_not_in_std: i32, + y_parameter_not_in_std: i32, +) -> i32 { + x_parameter_not_in_std + y_parameter_not_in_std +} + +fn main() { + foo(42, 43); // Ensure `wasm32-wasip1` keeps `foo()` (even if `-Copt-level=0`) +} + +// CHECK: !DILocalVariable(name: "x_parameter_not_in_std", arg: 1, +// CHECK-SAME: line: 9 +// CHECK: !DILocalVariable(name: "y_parameter_not_in_std", arg: 2, +// CHECK-SAME: line: 10 diff --git a/tests/codegen/repeat-operand-zero-len.rs b/tests/codegen/repeat-operand-zero-len.rs new file mode 100644 index 00000000000..b4cec42a07c --- /dev/null +++ b/tests/codegen/repeat-operand-zero-len.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes + +// This test is here to hit the `Rvalue::Repeat` case in `codegen_rvalue_operand`. +// It only applies when the resulting array is a ZST, so the test is written in +// such a way as to keep MIR optimizations from seeing that fact and removing +// the local and statement altogether. (At the time of writing, no other codegen +// test hit that code path, nor did a stage 2 build of the compiler.) + +#![crate_type = "lib"] + +#[repr(transparent)] +pub struct Wrapper<T, const N: usize>([T; N]); + +// CHECK-LABEL: define {{.+}}do_repeat{{.+}}(i32 noundef %x) +// CHECK-NEXT: start: +// CHECK-NOT: alloca +// CHECK-NEXT: ret void +#[inline(never)] +pub fn do_repeat<T: Copy, const N: usize>(x: T) -> Wrapper<T, N> { + Wrapper([x; N]) +} + +// CHECK-LABEL: @trigger_repeat_zero_len +#[no_mangle] +pub fn trigger_repeat_zero_len() -> Wrapper<u32, 0> { + // CHECK: call void {{.+}}do_repeat{{.+}}(i32 noundef 4) + do_repeat(4) +} diff --git a/tests/codegen/repeat-operand-zst-elem.rs b/tests/codegen/repeat-operand-zst-elem.rs new file mode 100644 index 00000000000..c3637759afa --- /dev/null +++ b/tests/codegen/repeat-operand-zst-elem.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Copt-level=1 -Cno-prepopulate-passes + +// This test is here to hit the `Rvalue::Repeat` case in `codegen_rvalue_operand`. +// It only applies when the resulting array is a ZST, so the test is written in +// such a way as to keep MIR optimizations from seeing that fact and removing +// the local and statement altogether. (At the time of writing, no other codegen +// test hit that code path, nor did a stage 2 build of the compiler.) + +#![crate_type = "lib"] + +#[repr(transparent)] +pub struct Wrapper<T, const N: usize>([T; N]); + +// CHECK-LABEL: define {{.+}}do_repeat{{.+}}() +// CHECK-NEXT: start: +// CHECK-NOT: alloca +// CHECK-NEXT: ret void +#[inline(never)] +pub fn do_repeat<T: Copy, const N: usize>(x: T) -> Wrapper<T, N> { + Wrapper([x; N]) +} + +// CHECK-LABEL: @trigger_repeat_zst_elem +#[no_mangle] +pub fn trigger_repeat_zst_elem() -> Wrapper<(), 8> { + // CHECK: call void {{.+}}do_repeat{{.+}}() + do_repeat(()) +} diff --git a/tests/codegen/sanitizer/kcfi/naked-function.rs b/tests/codegen/sanitizer/kcfi/naked-function.rs new file mode 100644 index 00000000000..2c8cdc919b8 --- /dev/null +++ b/tests/codegen/sanitizer/kcfi/naked-function.rs @@ -0,0 +1,47 @@ +//@ add-core-stubs +//@ revisions: aarch64 x86_64 +//@ [aarch64] compile-flags: --target aarch64-unknown-none +//@ [aarch64] needs-llvm-components: aarch64 +//@ [x86_64] compile-flags: --target x86_64-unknown-none +//@ [x86_64] needs-llvm-components: x86 +//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Cno-prepopulate-passes -Copt-level=0 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct Thing; +trait MyTrait { + #[unsafe(naked)] + extern "C" fn my_naked_function() { + // the real function is defined + // CHECK: .globl + // CHECK-SAME: my_naked_function + naked_asm!("ret") + } +} +impl MyTrait for Thing {} + +// the shim calls the real function +// CHECK-LABEL: define +// CHECK-SAME: my_naked_function +// CHECK-SAME: reify.shim.fnptr + +// CHECK-LABEL: main +#[unsafe(no_mangle)] +pub fn main() { + // Trick the compiler into generating an indirect call. + const F: extern "C" fn() = Thing::my_naked_function; + + // main calls the shim function + // CHECK: call void + // CHECK-SAME: my_naked_function + // CHECK-SAME: reify.shim.fnptr + (F)(); +} + +// CHECK: declare !kcfi_type +// CHECK-SAME: my_naked_function diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs index 485ba92272d..baf445d0a1b 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fabs; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fabs; // CHECK-LABEL: @fabs_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn fabs_32x16(a: f32x16) -> f32x16 { simd_fabs(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @fabs_64x4 #[no_mangle] pub unsafe fn fabs_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs index e8bda7c29c4..096de569274 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_ceil; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_ceil; // CHECK-LABEL: @ceil_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn ceil_32x16(a: f32x16) -> f32x16 { simd_ceil(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @ceil_64x4 #[no_mangle] pub unsafe fn ceil_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs index 8dc967bc3ad..5b2197924bc 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fcos; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fcos; // CHECK-LABEL: @fcos_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn fcos_32x16(a: f32x16) -> f32x16 { simd_fcos(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @fcos_64x4 #[no_mangle] pub unsafe fn fcos_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs index 00caca2f294..d4eadb36c65 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fexp; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fexp; // CHECK-LABEL: @exp_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn exp_32x16(a: f32x16) -> f32x16 { simd_fexp(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @exp_64x4 #[no_mangle] pub unsafe fn exp_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs index eda4053189c..d32015b7990 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fexp2; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fexp2; // CHECK-LABEL: @exp2_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn exp2_32x16(a: f32x16) -> f32x16 { simd_fexp2(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @exp2_64x4 #[no_mangle] pub unsafe fn exp2_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs index ad69d4cdd88..1e1c8ce0c35 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_floor; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_floor; // CHECK-LABEL: @floor_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn floor_32x16(a: f32x16) -> f32x16 { simd_floor(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @floor_64x4 #[no_mangle] pub unsafe fn floor_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs index cbeefdc31c0..982077d81f9 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fma; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fma; // CHECK-LABEL: @fma_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn fma_32x16(a: f32x16, b: f32x16, c: f32x16) -> f32x16 { simd_fma(a, b, c) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @fma_64x4 #[no_mangle] pub unsafe fn fma_64x4(a: f64x4, b: f64x4, c: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs index 618daa4b44d..e20a591f573 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fsqrt; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fsqrt; // CHECK-LABEL: @fsqrt_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn fsqrt_32x16(a: f32x16) -> f32x16 { simd_fsqrt(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @fsqrt_64x4 #[no_mangle] pub unsafe fn fsqrt_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs index 98a481e4004..bf1ffc76330 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_flog; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_flog; // CHECK-LABEL: @log_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn log_32x16(a: f32x16) -> f32x16 { simd_flog(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @log_64x4 #[no_mangle] pub unsafe fn log_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs index 9108cd963f0..ccf484e0e41 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_flog10; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_flog10; // CHECK-LABEL: @log10_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn log10_32x16(a: f32x16) -> f32x16 { simd_flog10(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @log10_64x4 #[no_mangle] pub unsafe fn log10_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs index 2b20850dbd9..677d8b01e84 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_flog2; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_flog2; // CHECK-LABEL: @log2_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn log2_32x16(a: f32x16) -> f32x16 { simd_flog2(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @log2_64x4 #[no_mangle] pub unsafe fn log2_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs index ce07b212e84..8dd464a1bff 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs @@ -4,11 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::{simd_fmax, simd_fmin}; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); +use std::intrinsics::simd::{simd_fmax, simd_fmin}; // CHECK-LABEL: @fmin #[no_mangle] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs index 7de26b415bb..48becc72c0b 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs @@ -4,23 +4,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_fsin; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); +use std::intrinsics::simd::simd_fsin; // CHECK-LABEL: @fsin_32x2 #[no_mangle] @@ -50,18 +38,6 @@ pub unsafe fn fsin_32x16(a: f32x16) -> f32x16 { simd_fsin(a) } -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - // CHECK-LABEL: @fsin_64x4 #[no_mangle] pub unsafe fn fsin_64x4(a: f64x4) -> f64x4 { diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index ecf5eb24ee5..06d46889715 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -5,66 +5,11 @@ #![allow(non_camel_case_types)] #![deny(unused)] -use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; - -#[rustfmt::skip] -mod types { - // signed integer types - - #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x2([i8; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x4([i8; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x8([i8; 8]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x16([i8; 16]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x32([i8; 32]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i8x64([i8; 64]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x2([i16; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x4([i16; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x8([i16; 8]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x16([i16; 16]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i16x32([i16; 32]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x2([i32; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4([i32; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x8([i32; 8]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i32x16([i32; 16]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct i64x2([i64; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i64x4([i64; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i64x8([i64; 8]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct i128x2([i128; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct i128x4([i128; 4]); - - // unsigned integer types +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; - #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x2([u8; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x4([u8; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x8([u8; 8]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x16([u8; 16]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x32([u8; 32]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u8x64([u8; 64]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x2([u16; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x4([u16; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x8([u16; 8]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x16([u16; 16]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u16x32([u16; 32]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2([u32; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x4([u32; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x8([u32; 8]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u32x16([u32; 16]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct u64x2([u64; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u64x4([u64; 4]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u64x8([u64; 8]); - - #[repr(simd)] #[derive(Copy, Clone)] pub struct u128x2([u128; 2]); - #[repr(simd)] #[derive(Copy, Clone)] pub struct u128x4([u128; 4]); -} - -use types::*; +use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; // NOTE(eddyb) `%{{x|0}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs index a2c40aa91b5..294262d8152 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -5,19 +5,11 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_bitmask; - -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct u32x2([u32; 2]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct i32x2([i32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct i8x16([i8; 16]); +use std::intrinsics::simd::simd_bitmask; // NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs index c06b36d68b9..690bfb432f9 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -6,15 +6,14 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_gather; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec2<T>(pub [T; 2]); +use std::intrinsics::simd::simd_gather; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec4<T>(pub [T; 4]); +pub type Vec2<T> = Simd<T, 2>; +pub type Vec4<T> = Simd<T, 4>; // CHECK-LABEL: @gather_f32x2 #[no_mangle] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index 21578e67cff..fda315dc66c 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -4,15 +4,14 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_masked_load; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec2<T>(pub [T; 2]); +use std::intrinsics::simd::simd_masked_load; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec4<T>(pub [T; 4]); +pub type Vec2<T> = Simd<T, 2>; +pub type Vec4<T> = Simd<T, 4>; // CHECK-LABEL: @load_f32x2 #[no_mangle] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index 22a8f7e54bd..6ca7388d464 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -4,15 +4,14 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_masked_store; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec2<T>(pub [T; 2]); +use std::intrinsics::simd::simd_masked_store; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec4<T>(pub [T; 4]); +pub type Vec2<T> = Simd<T, 2>; +pub type Vec4<T> = Simd<T, 4>; // CHECK-LABEL: @store_f32x2 #[no_mangle] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs index 0cc9e6ae59a..743652966e1 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -6,15 +6,14 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_scatter; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec2<T>(pub [T; 2]); +use std::intrinsics::simd::simd_scatter; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct Vec4<T>(pub [T; 4]); +pub type Vec2<T> = Simd<T, 2>; +pub type Vec4<T> = Simd<T, 4>; // CHECK-LABEL: @scatter_f32x2 #[no_mangle] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs index f6531c1b23a..2c0bad21f44 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -4,27 +4,13 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::{simd_select, simd_select_bitmask}; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8([f32; 8]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct b8x4(pub [i8; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct i32x4([i32; 4]); +use std::intrinsics::simd::{simd_select, simd_select_bitmask}; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct u32x4([u32; 4]); +pub type b8x4 = i8x4; // CHECK-LABEL: @select_m8 #[no_mangle] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs index 269fe41225e..79f00a6ed60 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-mask-reduce.rs @@ -4,15 +4,14 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::{simd_reduce_all, simd_reduce_any}; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct mask32x2([i32; 2]); +use std::intrinsics::simd::{simd_reduce_all, simd_reduce_any}; -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct mask8x16([i8; 16]); +pub type mask32x2 = Simd<i32, 2>; +pub type mask8x16 = Simd<i8, 16>; // NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index 301f06c2d74..05c2f7e1bdf 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -8,13 +8,12 @@ #![allow(non_camel_case_types)] #![feature(repr_simd, core_intrinsics)] -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct S<const N: usize>([f32; N]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct T([f32; 4]); +pub type S<const N: usize> = Simd<f32, N>; +pub type T = Simd<f32, 4>; // CHECK-LABEL: @array_align( #[no_mangle] @@ -34,7 +33,7 @@ pub fn vector_align() -> usize { #[no_mangle] pub fn build_array_s(x: [f32; 4]) -> S<4> { // CHECK: call void @llvm.memcpy.{{.+}}({{.*}} align [[VECTOR_ALIGN]] {{.*}} align [[ARRAY_ALIGN]] {{.*}}, [[USIZE]] 16, i1 false) - S::<4>(x) + Simd(x) } // CHECK-LABEL: @build_array_transmute_s @@ -48,7 +47,7 @@ pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> { #[no_mangle] pub fn build_array_t(x: [f32; 4]) -> T { // CHECK: call void @llvm.memcpy.{{.+}}({{.*}} align [[VECTOR_ALIGN]] {{.*}} align [[ARRAY_ALIGN]] {{.*}}, [[USIZE]] 16, i1 false) - T(x) + Simd(x) } // CHECK-LABEL: @build_array_transmute_t diff --git a/tests/codegen/simd/aggregate-simd.rs b/tests/codegen/simd/aggregate-simd.rs index 065e429a4c7..57a301d634c 100644 --- a/tests/codegen/simd/aggregate-simd.rs +++ b/tests/codegen/simd/aggregate-simd.rs @@ -5,15 +5,11 @@ #![no_std] #![crate_type = "lib"] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; use core::intrinsics::simd::{simd_add, simd_extract}; -#[repr(simd)] -#[derive(Clone, Copy)] -pub struct Simd<T, const N: usize>([T; N]); - -#[repr(simd, packed)] -#[derive(Clone, Copy)] -pub struct PackedSimd<T, const N: usize>([T; N]); +use minisimd::*; #[repr(transparent)] pub struct Transparent<T>(T); diff --git a/tests/codegen/simd/packed-simd.rs b/tests/codegen/simd/packed-simd.rs index 73e0d29d7d6..70c03fcc955 100644 --- a/tests/codegen/simd/packed-simd.rs +++ b/tests/codegen/simd/packed-simd.rs @@ -9,18 +9,14 @@ use core::intrinsics::simd as intrinsics; use core::{mem, ptr}; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::{PackedSimd, Simd as FullSimd}; + // Test codegen for not only "packed" but also "fully aligned" SIMD types, and conversion between // them. A repr(packed,simd) type with 3 elements can't exceed its element alignment, whereas the // same type as repr(simd) will instead have padding. -#[repr(simd, packed)] -#[derive(Copy, Clone)] -pub struct PackedSimd<T, const N: usize>([T; N]); - -#[repr(simd)] -#[derive(Copy, Clone)] -pub struct FullSimd<T, const N: usize>([T; N]); - // non-powers-of-two have padding and need to be expanded to full vectors fn load<T, const N: usize>(v: PackedSimd<T, N>) -> FullSimd<T, N> { unsafe { diff --git a/tests/codegen/simd/project-to-simd-array-field.rs b/tests/codegen/simd/project-to-simd-array-field.rs deleted file mode 100644 index 29fab640633..00000000000 --- a/tests/codegen/simd/project-to-simd-array-field.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@compile-flags: -Copt-level=3 - -#![crate_type = "lib"] -#![feature(repr_simd, core_intrinsics)] - -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(simd)] -struct i32x4([i32; 4]); - -#[inline(always)] -fn to_array4(a: i32x4) -> [i32; 4] { - a.0 -} - -// CHECK-LABEL: simd_add_self_then_return_array( -// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]], -// CHECK-SAME: ptr{{.+}}%a) -#[no_mangle] -pub fn simd_add_self_then_return_array(a: &i32x4) -> [i32; 4] { - // It would be nice to just ban `.0` into simd types, - // but until we do this has to keep working. - // See also <https://github.com/rust-lang/rust/issues/105439> - - // CHECK: %[[T1:.+]] = load <4 x i32>, ptr %a - // CHECK: %[[T2:.+]] = shl <4 x i32> %[[T1]], {{splat \(i32 1\)|<i32 1, i32 1, i32 1, i32 1>}} - // CHECK: store <4 x i32> %[[T2]], ptr %[[RET]] - let a = *a; - let b = unsafe { core::intrinsics::simd::simd_add(a, a) }; - to_array4(b) -} diff --git a/tests/codegen/simd/simd_arith_offset.rs b/tests/codegen/simd/simd_arith_offset.rs index b8af6fce332..210b4e9bb50 100644 --- a/tests/codegen/simd/simd_arith_offset.rs +++ b/tests/codegen/simd/simd_arith_offset.rs @@ -5,16 +5,14 @@ #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; use std::intrinsics::simd::simd_arith_offset; -/// A vector of *const T. -#[derive(Debug, Copy, Clone)] -#[repr(simd)] -pub struct SimdConstPtr<T, const LANES: usize>([*const T; LANES]); +use minisimd::*; -#[derive(Debug, Copy, Clone)] -#[repr(simd)] -pub struct Simd<T, const LANES: usize>([T; LANES]); +/// A vector of *const T. +pub type SimdConstPtr<T, const LANES: usize> = Simd<*const T, LANES>; // CHECK-LABEL: smoke #[no_mangle] diff --git a/tests/crashes/117629.rs b/tests/crashes/117629.rs index d8b5f328545..f63365395c6 100644 --- a/tests/crashes/117629.rs +++ b/tests/crashes/117629.rs @@ -3,8 +3,7 @@ #![feature(const_trait_impl)] -#[const_trait] -trait Tr { +const trait Tr { async fn ft1() {} } diff --git a/tests/crashes/133275-1.rs b/tests/crashes/133275-1.rs deleted file mode 100644 index 73c04f5d6e4..00000000000 --- a/tests/crashes/133275-1.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #133275 -#![feature(const_trait_impl)] -#![feature(associated_type_defaults)] - -#[const_trait] -trait Foo3<T> -where - Self::Baz: Clone, -{ - type Baz = T; -} - -pub fn main() {} diff --git a/tests/crashes/133275-2.rs b/tests/crashes/133275-2.rs deleted file mode 100644 index a774b3cdb69..00000000000 --- a/tests/crashes/133275-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #133275 -#![feature(const_trait_impl)] -#[const_trait] -pub trait Owo<X = <IntEnum as Uwu>::T> {} - -#[const_trait] -trait Foo3<T> -where - Self::Bar: Clone, - Self::Baz: Clone, -{ - type Bar = Vec<Self::Baz>; - type Baz = T; - //~^ ERROR the trait bound `T: Clone` is not satisfied -} diff --git a/tests/crashes/const_mut_ref_check_bypass.rs b/tests/crashes/const_mut_ref_check_bypass.rs deleted file mode 100644 index 6234536c72b..00000000000 --- a/tests/crashes/const_mut_ref_check_bypass.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Version of `tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs` without the flag that -// suppresses the ICE. -//@ known-bug: #129233 -#![feature(core_intrinsics)] -#![feature(const_heap)] -#![feature(const_mut_refs)] -use std::intrinsics; - -const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 }; - -fn main() {} diff --git a/tests/mir-opt/const_prop/transmute.rs b/tests/mir-opt/const_prop/transmute.rs index 892b91a5414..33cbefbf053 100644 --- a/tests/mir-opt/const_prop/transmute.rs +++ b/tests/mir-opt/const_prop/transmute.rs @@ -56,7 +56,7 @@ pub unsafe fn undef_union_as_integer() -> u32 { pub unsafe fn unreachable_direct() -> ! { // CHECK-LABEL: fn unreachable_direct( // CHECK: = const (); - // CHECK: = const () as Never (Transmute); + // CHECK: = const ZeroSized: Never; let x: Never = unsafe { transmute(()) }; match x {} } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff index 3364782022d..5aeb55a5a6a 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff @@ -15,7 +15,7 @@ - _2 = (); - _1 = move _2 as Never (Transmute); + _2 = const (); -+ _1 = const () as Never (Transmute); ++ _1 = const ZeroSized: Never; unreachable; } } diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff index 3364782022d..5aeb55a5a6a 100644 --- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff +++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff @@ -15,7 +15,7 @@ - _2 = (); - _1 = move _2 as Never (Transmute); + _2 = const (); -+ _1 = const () as Never (Transmute); ++ _1 = const ZeroSized: Never; unreachable; } } diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff index 770c6730775..ffe4a0272b4 100644 --- a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-abort.diff @@ -18,7 +18,8 @@ bb0: { _4 = copy _1 as *const T (PtrToPtr); - _5 = PtrMetadata(copy _4); +- _5 = PtrMetadata(copy _4); ++ _5 = const (); _6 = copy _1 as *const (&A, [T]) (PtrToPtr); - _7 = PtrMetadata(copy _6); + _7 = PtrMetadata(copy _1); diff --git a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff index 770c6730775..ffe4a0272b4 100644 --- a/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.generic_cast_metadata.GVN.panic-unwind.diff @@ -18,7 +18,8 @@ bb0: { _4 = copy _1 as *const T (PtrToPtr); - _5 = PtrMetadata(copy _4); +- _5 = PtrMetadata(copy _4); ++ _5 = const (); _6 = copy _1 as *const (&A, [T]) (PtrToPtr); - _7 = PtrMetadata(copy _6); + _7 = PtrMetadata(copy _1); diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 6ef320c90de..5d348bc3c1e 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -869,7 +869,7 @@ fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, // Metadata usize -> (), do not optimize. // CHECK: [[T:_.+]] = copy _1 as - // CHECK-NEXT: PtrMetadata(copy [[T]]) + // CHECK-NEXT: const (); let t1 = CastPtrToPtr::<_, *const T>(ps); let m1 = PtrMetadata(t1); diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs index 383d0796a88..6e0f45bb3e9 100644 --- a/tests/mir-opt/inline/cycle.rs +++ b/tests/mir-opt/inline/cycle.rs @@ -13,7 +13,7 @@ fn f(g: impl Fn()) { #[inline(always)] fn g() { // CHECK-LABEL: fn g( - // CHECK-NOT: (inlined f::<fn() {main}>) + // CHECK-NOT: inlined f(main); } diff --git a/tests/mir-opt/inline_double_cycle.a.Inline.panic-abort.diff b/tests/mir-opt/inline_double_cycle.a.Inline.panic-abort.diff new file mode 100644 index 00000000000..90a4a509ac1 --- /dev/null +++ b/tests/mir-opt/inline_double_cycle.a.Inline.panic-abort.diff @@ -0,0 +1,48 @@ +- // MIR for `a` before Inline ++ // MIR for `a` after Inline + + fn a() -> () { + let mut _0: (); + let _1: (); + let mut _2: (); + let _3: (); + let mut _4: (); ++ let mut _5: fn() {a}; ++ let mut _6: fn() {b}; ++ scope 1 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) { ++ } ++ scope 2 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) { ++ } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = (); +- _1 = <fn() {a} as FnOnce<()>>::call_once(a, move _2) -> [return: bb1, unwind unreachable]; ++ StorageLive(_5); ++ _5 = a; ++ _1 = move _5() -> [return: bb1, unwind unreachable]; + } + + bb1: { ++ StorageDead(_5); + StorageDead(_2); + StorageDead(_1); + StorageLive(_3); + StorageLive(_4); + _4 = (); +- _3 = <fn() {b} as FnOnce<()>>::call_once(b, move _4) -> [return: bb2, unwind unreachable]; ++ StorageLive(_6); ++ _6 = b; ++ _3 = move _6() -> [return: bb2, unwind unreachable]; + } + + bb2: { ++ StorageDead(_6); + StorageDead(_4); + StorageDead(_3); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline_double_cycle.a.Inline.panic-unwind.diff b/tests/mir-opt/inline_double_cycle.a.Inline.panic-unwind.diff new file mode 100644 index 00000000000..55da685a3d4 --- /dev/null +++ b/tests/mir-opt/inline_double_cycle.a.Inline.panic-unwind.diff @@ -0,0 +1,48 @@ +- // MIR for `a` before Inline ++ // MIR for `a` after Inline + + fn a() -> () { + let mut _0: (); + let _1: (); + let mut _2: (); + let _3: (); + let mut _4: (); ++ let mut _5: fn() {a}; ++ let mut _6: fn() {b}; ++ scope 1 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) { ++ } ++ scope 2 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) { ++ } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = (); +- _1 = <fn() {a} as FnOnce<()>>::call_once(a, move _2) -> [return: bb1, unwind continue]; ++ StorageLive(_5); ++ _5 = a; ++ _1 = move _5() -> [return: bb1, unwind continue]; + } + + bb1: { ++ StorageDead(_5); + StorageDead(_2); + StorageDead(_1); + StorageLive(_3); + StorageLive(_4); + _4 = (); +- _3 = <fn() {b} as FnOnce<()>>::call_once(b, move _4) -> [return: bb2, unwind continue]; ++ StorageLive(_6); ++ _6 = b; ++ _3 = move _6() -> [return: bb2, unwind continue]; + } + + bb2: { ++ StorageDead(_6); + StorageDead(_4); + StorageDead(_3); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline_double_cycle.b.Inline.panic-abort.diff b/tests/mir-opt/inline_double_cycle.b.Inline.panic-abort.diff new file mode 100644 index 00000000000..2090411276c --- /dev/null +++ b/tests/mir-opt/inline_double_cycle.b.Inline.panic-abort.diff @@ -0,0 +1,48 @@ +- // MIR for `b` before Inline ++ // MIR for `b` after Inline + + fn b() -> () { + let mut _0: (); + let _1: (); + let mut _2: (); + let _3: (); + let mut _4: (); ++ let mut _5: fn() {b}; ++ let mut _6: fn() {a}; ++ scope 1 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) { ++ } ++ scope 2 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) { ++ } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = (); +- _1 = <fn() {b} as FnOnce<()>>::call_once(b, move _2) -> [return: bb1, unwind unreachable]; ++ StorageLive(_5); ++ _5 = b; ++ _1 = move _5() -> [return: bb1, unwind unreachable]; + } + + bb1: { ++ StorageDead(_5); + StorageDead(_2); + StorageDead(_1); + StorageLive(_3); + StorageLive(_4); + _4 = (); +- _3 = <fn() {a} as FnOnce<()>>::call_once(a, move _4) -> [return: bb2, unwind unreachable]; ++ StorageLive(_6); ++ _6 = a; ++ _3 = move _6() -> [return: bb2, unwind unreachable]; + } + + bb2: { ++ StorageDead(_6); + StorageDead(_4); + StorageDead(_3); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline_double_cycle.b.Inline.panic-unwind.diff b/tests/mir-opt/inline_double_cycle.b.Inline.panic-unwind.diff new file mode 100644 index 00000000000..9e6eef1fa30 --- /dev/null +++ b/tests/mir-opt/inline_double_cycle.b.Inline.panic-unwind.diff @@ -0,0 +1,48 @@ +- // MIR for `b` before Inline ++ // MIR for `b` after Inline + + fn b() -> () { + let mut _0: (); + let _1: (); + let mut _2: (); + let _3: (); + let mut _4: (); ++ let mut _5: fn() {b}; ++ let mut _6: fn() {a}; ++ scope 1 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) { ++ } ++ scope 2 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) { ++ } + + bb0: { + StorageLive(_1); + StorageLive(_2); + _2 = (); +- _1 = <fn() {b} as FnOnce<()>>::call_once(b, move _2) -> [return: bb1, unwind continue]; ++ StorageLive(_5); ++ _5 = b; ++ _1 = move _5() -> [return: bb1, unwind continue]; + } + + bb1: { ++ StorageDead(_5); + StorageDead(_2); + StorageDead(_1); + StorageLive(_3); + StorageLive(_4); + _4 = (); +- _3 = <fn() {a} as FnOnce<()>>::call_once(a, move _4) -> [return: bb2, unwind continue]; ++ StorageLive(_6); ++ _6 = a; ++ _3 = move _6() -> [return: bb2, unwind continue]; + } + + bb2: { ++ StorageDead(_6); + StorageDead(_4); + StorageDead(_3); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline_double_cycle.rs b/tests/mir-opt/inline_double_cycle.rs new file mode 100644 index 00000000000..cf3b87cf0ad --- /dev/null +++ b/tests/mir-opt/inline_double_cycle.rs @@ -0,0 +1,22 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +// skip-filecheck +//@ test-mir-pass: Inline +//@ edition: 2021 +//@ compile-flags: -Zinline-mir --crate-type=lib + +// EMIT_MIR inline_double_cycle.a.Inline.diff +// EMIT_MIR inline_double_cycle.b.Inline.diff + +#![feature(fn_traits)] + +#[inline] +pub fn a() { + FnOnce::call_once(a, ()); + FnOnce::call_once(b, ()); +} + +#[inline] +pub fn b() { + FnOnce::call_once(b, ()); + FnOnce::call_once(a, ()); +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 3b58f1d61f4..8c5fbda6392 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -109,7 +109,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb4: { - StorageLive(_15); _14 = &mut _13; _15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; } @@ -120,7 +119,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb6: { - StorageDead(_15); StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -135,14 +133,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { StorageLive(_19); _19 = &_2; StorageLive(_20); - _20 = (copy _17, copy _18); + _20 = copy ((_15 as Some).0: (usize, &T)); _21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11]; } bb9: { StorageDead(_20); StorageDead(_19); - StorageDead(_15); goto -> bb4; } diff --git a/tests/run-make/autodiff/type-trees/type-analysis/README.md b/tests/run-make/autodiff/type-trees/type-analysis/README.md new file mode 100644 index 00000000000..c712edfaf50 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/README.md @@ -0,0 +1,13 @@ +# Autodiff Type-Trees Type Analysis Tests + +This directory contains run-make tests for the autodiff type-trees type analysis functionality. These tests verify that the autodiff compiler correctly analyzes and tracks type information for different Rust types during automatic differentiation. + +## What These Tests Do + +Each test compiles a simple Rust function with the `#[autodiff_reverse]` attribute and verifies that the compiler: + +1. **Correctly identifies type information** in the generated LLVM IR +2. **Tracks type annotations** for variables and operations +3. **Preserves type context** through the autodiff transformation process + +The tests capture the stdout from the autodiff compiler (which contains type analysis information) and verify it matches expected patterns using FileCheck. diff --git a/tests/run-make/autodiff/type-trees/type-analysis/array/array.check b/tests/run-make/autodiff/type-trees/type-analysis/array/array.check new file mode 100644 index 00000000000..6e4197692a7 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/array/array.check @@ -0,0 +1,26 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 4, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 4, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/array/array.rs b/tests/run-make/autodiff/type-trees/type-analysis/array/array.rs new file mode 100644 index 00000000000..9a859418b10 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/array/array.rs @@ -0,0 +1,20 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &[f32; 3]) -> f32 { + x[0] * x[0] + x[1] * x[1] + x[2] * x[2] +} + +fn main() { + let x = [1.0f32, 2.0, 3.0]; + let mut df_dx = [0.0f32; 3]; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(2.0, df_dx[0]); + assert_eq!(4.0, df_dx[1]); + assert_eq!(6.0, df_dx[2]); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/array/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/array/rmake.rs new file mode 100644 index 00000000000..d68ab46bb94 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/array/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("array.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("array.stdout", stdout); + rfs::write("array.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("array.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.check b/tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.check new file mode 100644 index 00000000000..ed81ad4869a --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.check @@ -0,0 +1,54 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ 0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x [2 x float]], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x float], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ 0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x [2 x float]], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x float], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.rs b/tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.rs new file mode 100644 index 00000000000..a95111a0dae --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.rs @@ -0,0 +1,32 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &[[[f32; 2]; 2]; 2]) -> f32 { + let mut sum = 0.0; + for i in 0..2 { + for j in 0..2 { + for k in 0..2 { + sum += x[i][j][k] * x[i][j][k]; + } + } + } + sum +} + +fn main() { + let x = [[[1.0f32, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]]; + let mut df_dx = [[[0.0f32; 2]; 2]; 2]; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + for i in 0..2 { + for j in 0..2 { + for k in 0..2 { + assert_eq!(df_dx[i][j][k], 2.0 * x[i][j][k]); + } + } + } +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/array3d/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/array3d/rmake.rs new file mode 100644 index 00000000000..8e75c21c9d6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/array3d/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("array3d.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("array3d.stdout", stdout); + rfs::write("array3d.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("array3d.check").stdin_buf(rfs::read("array3d.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/box/box.check b/tests/run-make/autodiff/type-trees/type-analysis/box/box.check new file mode 100644 index 00000000000..1911e18a137 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/box/box.check @@ -0,0 +1,12 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/box/box.rs b/tests/run-make/autodiff/type-trees/type-analysis/box/box.rs new file mode 100644 index 00000000000..658ccffc74e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/box/box.rs @@ -0,0 +1,18 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &Box<f32>) -> f32 { + **x * **x +} + +fn main() { + let x = Box::new(7.0f32); + let mut df_dx = Box::new(0.0f32); + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, *df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/box/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/box/rmake.rs new file mode 100644 index 00000000000..1e8c8f9ccbd --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/box/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("box.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("box.stdout", stdout); + rfs::write("box.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("box.check").stdin_buf(rfs::read("box.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.check b/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.check new file mode 100644 index 00000000000..e7503453f8e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.rs b/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.rs new file mode 100644 index 00000000000..8c877bfec05 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.rs @@ -0,0 +1,18 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: *const f32) -> f32 { + unsafe { *x * *x } +} + +fn main() { + let x: f32 = 7.0; + let out = callee(&x as *const f32); + let mut df_dx: f32 = 0.0; + let out_ = d_square(&x as *const f32, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/rmake.rs new file mode 100644 index 00000000000..ce38c6bd2ae --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/const_pointer/rmake.rs @@ -0,0 +1,31 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("const_pointer.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("const_pointer.stdout", stdout); + rfs::write("const_pointer.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck() + .patterns("const_pointer.check") + .stdin_buf(rfs::read("const_pointer.stdout")) + .run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/f32/f32.check b/tests/run-make/autodiff/type-trees/type-analysis/f32/f32.check new file mode 100644 index 00000000000..0cc0ffda43d --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/f32/f32.check @@ -0,0 +1,12 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} + +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} + +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/f32/f32.rs b/tests/run-make/autodiff/type-trees/type-analysis/f32/f32.rs new file mode 100644 index 00000000000..b945821934a --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/f32/f32.rs @@ -0,0 +1,19 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &f32) -> f32 { + *x * *x +} + +fn main() { + let x: f32 = 7.0; + let mut df_dx: f32 = 0.0; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/f32/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/f32/rmake.rs new file mode 100644 index 00000000000..d7e49219da6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/f32/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("f32.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("f32.stdout", stdout); + rfs::write("f32.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("f32.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/f64/f64.check b/tests/run-make/autodiff/type-trees/type-analysis/f64/f64.check new file mode 100644 index 00000000000..efc49da5ffc --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/f64/f64.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@double} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double} +// CHECK-DAG: %{{[0-9]+}} = load double, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@double} +// CHECK-DAG: %{{[0-9]+}} = fmul double %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@double} +// CHECK-DAG: ret double %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@double} |{[-1]:Pointer, [-1,0]:Float@double}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double} +// CHECK-DAG: %{{[0-9]+}} = load double, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@double} +// CHECK-DAG: %{{[0-9]+}} = fmul double %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@double} +// CHECK-DAG: ret double %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/f64/f64.rs b/tests/run-make/autodiff/type-trees/type-analysis/f64/f64.rs new file mode 100644 index 00000000000..9b47569652e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/f64/f64.rs @@ -0,0 +1,20 @@ +#![feature(autodiff)] +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_callee, Duplicated, Active)] +#[no_mangle] +fn callee(x: &f64) -> f64 { + x * x +} + +fn main() { + let x = std::hint::black_box(3.0); + + let output = callee(&x); + assert_eq!(9.0, output); + + let mut df_dx = 0.0; + let output_ = d_callee(&x, &mut df_dx, 1.0); + assert_eq!(output, output_); + assert_eq!(6.0, df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/f64/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/f64/rmake.rs new file mode 100644 index 00000000000..8bf92b8c1bd --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/f64/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("f64.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("f64.stdout", stdout); + rfs::write("f64.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("f64.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i128/i128.check b/tests/run-make/autodiff/type-trees/type-analysis/i128/i128.check new file mode 100644 index 00000000000..31a07219e74 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i128/i128.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i128/i128.rs b/tests/run-make/autodiff/type-trees/type-analysis/i128/i128.rs new file mode 100644 index 00000000000..19dfbbb22db --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i128/i128.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i128) -> i128 { + *x * *x +} + +fn main() { + let x: i128 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i128/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/i128/rmake.rs new file mode 100644 index 00000000000..21e8698634f --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i128/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("i128.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("i128.stdout", stdout); + rfs::write("i128.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("i128.check").stdin_buf(rfs::read("i128.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i16/i16.check b/tests/run-make/autodiff/type-trees/type-analysis/i16/i16.check new file mode 100644 index 00000000000..8cc299532c5 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i16/i16.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i16/i16.rs b/tests/run-make/autodiff/type-trees/type-analysis/i16/i16.rs new file mode 100644 index 00000000000..82099198a2e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i16/i16.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i16) -> i16 { + *x * *x +} + +fn main() { + let x: i16 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i16/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/i16/rmake.rs new file mode 100644 index 00000000000..a2875a8c573 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i16/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("i16.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("i16.stdout", stdout); + rfs::write("i16.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("i16.check").stdin_buf(rfs::read("i16.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i32/i32.check b/tests/run-make/autodiff/type-trees/type-analysis/i32/i32.check new file mode 100644 index 00000000000..4df982887d7 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i32/i32.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i32/i32.rs b/tests/run-make/autodiff/type-trees/type-analysis/i32/i32.rs new file mode 100644 index 00000000000..e95068d5c49 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i32/i32.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i32) -> i32 { + *x * *x +} + +fn main() { + let x: i32 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i32/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/i32/rmake.rs new file mode 100644 index 00000000000..857017feeab --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i32/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("i32.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("i32.stdout", stdout); + rfs::write("i32.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("i32.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i8/i8.check b/tests/run-make/autodiff/type-trees/type-analysis/i8/i8.check new file mode 100644 index 00000000000..651a2085bc6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i8/i8.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i8/i8.rs b/tests/run-make/autodiff/type-trees/type-analysis/i8/i8.rs new file mode 100644 index 00000000000..afc0cad703c --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i8/i8.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &i8) -> i8 { + *x * *x +} + +fn main() { + let x: i8 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/i8/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/i8/rmake.rs new file mode 100644 index 00000000000..6551e2d6c4e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/i8/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("i8.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("i8.stdout", stdout); + rfs::write("i8.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("i8.check").stdin_buf(rfs::read("i8.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/isize/isize.check b/tests/run-make/autodiff/type-trees/type-analysis/isize/isize.check new file mode 100644 index 00000000000..40ee6edc02c --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/isize/isize.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/isize/isize.rs b/tests/run-make/autodiff/type-trees/type-analysis/isize/isize.rs new file mode 100644 index 00000000000..dd160984a4e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/isize/isize.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &isize) -> isize { + *x * *x +} + +fn main() { + let x: isize = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/isize/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/isize/rmake.rs new file mode 100644 index 00000000000..09277f63ed4 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/isize/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("isize.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("isize.stdout", stdout); + rfs::write("isize.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("isize.check").stdin_buf(rfs::read("isize.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.check b/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.check new file mode 100644 index 00000000000..e7503453f8e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.rs b/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.rs new file mode 100644 index 00000000000..2b672f6d3f8 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.rs @@ -0,0 +1,18 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: *mut f32) -> f32 { + unsafe { *x * *x } +} + +fn main() { + let mut x: f32 = 7.0; + let out = callee(&mut x as *mut f32); + let mut df_dx: f32 = 0.0; + let out_ = d_square(&mut x as *mut f32, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/rmake.rs new file mode 100644 index 00000000000..4d5a5042141 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("mut_pointer.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("mut_pointer.stdout", stdout); + rfs::write("mut_pointer.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("mut_pointer.check").stdin_buf(rfs::read("mut_pointer.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.check b/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.check new file mode 100644 index 00000000000..e7503453f8e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.rs b/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.rs new file mode 100644 index 00000000000..7019e3f71ed --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.rs @@ -0,0 +1,18 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &mut f32) -> f32 { + *x * *x +} + +fn main() { + let mut x: f32 = 7.0; + let mut df_dx: f32 = 0.0; + let out = callee(&mut x); + let out_ = d_square(&mut x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/rmake.rs new file mode 100644 index 00000000000..13668c54e78 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/mut_ref/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("mut_ref.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("mut_ref.stdout", stdout); + rfs::write("mut_ref.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("mut_ref.check").stdin_buf(rfs::read("mut_ref.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/ref/ref.check b/tests/run-make/autodiff/type-trees/type-analysis/ref/ref.check new file mode 100644 index 00000000000..e7503453f8e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/ref/ref.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/ref/ref.rs b/tests/run-make/autodiff/type-trees/type-analysis/ref/ref.rs new file mode 100644 index 00000000000..3ced164b86f --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/ref/ref.rs @@ -0,0 +1,18 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &f32) -> f32 { + *x * *x +} + +fn main() { + let x: f32 = 7.0; + let mut df_dx: f32 = 0.0; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/ref/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/ref/rmake.rs new file mode 100644 index 00000000000..b68e4e5b8ac --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/ref/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("ref.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("ref.stdout", stdout); + rfs::write("ref.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("ref.check").stdin_buf(rfs::read("ref.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/struct/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/struct/rmake.rs new file mode 100644 index 00000000000..4073f7554cc --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/struct/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("struct.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("struct.stdout", stdout); + rfs::write("struct.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("struct.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/struct/struct.check b/tests/run-make/autodiff/type-trees/type-analysis/struct/struct.check new file mode 100644 index 00000000000..e7503453f8e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/struct/struct.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/struct/struct.rs b/tests/run-make/autodiff/type-trees/type-analysis/struct/struct.rs new file mode 100644 index 00000000000..52cb6a9a6b9 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/struct/struct.rs @@ -0,0 +1,23 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[derive(Copy, Clone)] +struct MyStruct { + f: f32, +} + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &MyStruct) -> f32 { + x.f * x.f +} + +fn main() { + let x = MyStruct { f: 7.0 }; + let mut df_dx = MyStruct { f: 0.0 }; + let out = callee(&x); + let out_ = d_square(&x, &mut df_dx, 1.0); + assert_eq!(out, out_); + assert_eq!(14.0, df_dx.f); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u128/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/u128/rmake.rs new file mode 100644 index 00000000000..3f605d47c68 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u128/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("u128.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("u128.stdout", stdout); + rfs::write("u128.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("u128.check").stdin_buf(rfs::read("u128.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u128/u128.check b/tests/run-make/autodiff/type-trees/type-analysis/u128/u128.check new file mode 100644 index 00000000000..31a07219e74 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u128/u128.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u128/u128.rs b/tests/run-make/autodiff/type-trees/type-analysis/u128/u128.rs new file mode 100644 index 00000000000..d19d2faa51b --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u128/u128.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u128) -> u128 { + *x * *x +} + +fn main() { + let x: u128 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u16/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/u16/rmake.rs new file mode 100644 index 00000000000..0051f6f9795 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u16/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("u16.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("u16.stdout", stdout); + rfs::write("u16.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("u16.check").stdin_buf(rfs::read("u16.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u16/u16.check b/tests/run-make/autodiff/type-trees/type-analysis/u16/u16.check new file mode 100644 index 00000000000..8cc299532c5 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u16/u16.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u16/u16.rs b/tests/run-make/autodiff/type-trees/type-analysis/u16/u16.rs new file mode 100644 index 00000000000..f5f5b50622b --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u16/u16.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u16) -> u16 { + *x * *x +} + +fn main() { + let x: u16 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u32/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/u32/rmake.rs new file mode 100644 index 00000000000..0882230b1c6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u32/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("u32.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("u32.stdout", stdout); + rfs::write("u32.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("u32.check").stdin_buf(rfs::read("u32.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u32/u32.check b/tests/run-make/autodiff/type-trees/type-analysis/u32/u32.check new file mode 100644 index 00000000000..4df982887d7 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u32/u32.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u32/u32.rs b/tests/run-make/autodiff/type-trees/type-analysis/u32/u32.rs new file mode 100644 index 00000000000..66b4c222c51 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u32/u32.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u32) -> u32 { + *x * *x +} + +fn main() { + let x: u32 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u8/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/u8/rmake.rs new file mode 100644 index 00000000000..100b4f498f2 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u8/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("u8.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("u8.stdout", stdout); + rfs::write("u8.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("u8.check").stdin_buf(rfs::read("u8.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u8/u8.check b/tests/run-make/autodiff/type-trees/type-analysis/u8/u8.check new file mode 100644 index 00000000000..651a2085bc6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u8/u8.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/u8/u8.rs b/tests/run-make/autodiff/type-trees/type-analysis/u8/u8.rs new file mode 100644 index 00000000000..de9cdeb631e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/u8/u8.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &u8) -> u8 { + *x * *x +} + +fn main() { + let x: u8 = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/union/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/union/rmake.rs new file mode 100644 index 00000000000..67f0fe18481 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/union/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("union.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("union.stdout", stdout); + rfs::write("union.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("union.check").stdin_buf(rfs::read("union.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/union/union.check b/tests/run-make/autodiff/type-trees/type-analysis/union/union.check new file mode 100644 index 00000000000..e7503453f8e --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/union/union.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/union/union.rs b/tests/run-make/autodiff/type-trees/type-analysis/union/union.rs new file mode 100644 index 00000000000..8d997f8c839 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/union/union.rs @@ -0,0 +1,20 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[allow(dead_code)] +union MyUnion { + f: f32, + i: i32, +} + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &MyUnion) -> f32 { + unsafe { x.f * x.f } +} + +fn main() { + let x = MyUnion { f: 7.0 }; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/usize/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/usize/rmake.rs new file mode 100644 index 00000000000..d5cfd708c3a --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/usize/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("usize.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("usize.stdout", stdout); + rfs::write("usize.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("usize.check").stdin_buf(rfs::read("usize.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/usize/usize.check b/tests/run-make/autodiff/type-trees/type-analysis/usize/usize.check new file mode 100644 index 00000000000..40ee6edc02c --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/usize/usize.check @@ -0,0 +1,10 @@ +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer} +// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/usize/usize.rs b/tests/run-make/autodiff/type-trees/type-analysis/usize/usize.rs new file mode 100644 index 00000000000..8e758be57d4 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/usize/usize.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(x: &usize) -> usize { + *x * *x +} + +fn main() { + let x: usize = 7; + let _ = callee(&x); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/vec/rmake.rs b/tests/run-make/autodiff/type-trees/type-analysis/vec/rmake.rs new file mode 100644 index 00000000000..94491fab8d6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/vec/rmake.rs @@ -0,0 +1,28 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use std::fs; + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile the Rust file with the required flags, capturing both stdout and stderr + let output = rustc() + .input("vec.rs") + .arg("-Zautodiff=Enable,PrintTAFn=callee") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + + // Write the outputs to files + rfs::write("vec.stdout", stdout); + rfs::write("vec.stderr", stderr); + + // Run FileCheck on the stdout using the check file + llvm_filecheck().patterns("vec.check").stdin_buf(rfs::read("vec.stdout")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check new file mode 100644 index 00000000000..dcf9508b69d --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check @@ -0,0 +1,18 @@ +// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} +// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer} +// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !102, !noundef !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 16, !dbg !{{[0-9]+}}: {[-1]:Pointer} +// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, 0, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ -0.000000e+00, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: %{{[0-9]+}} = add nuw i64 %{{[0-9]+}}, 1, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer} +// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = phi float [ -0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float} +// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.rs b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.rs new file mode 100644 index 00000000000..b60c2a88064 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.rs @@ -0,0 +1,14 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn callee(arg: &std::vec::Vec<f32>) -> f32 { + arg.iter().sum() +} + +fn main() { + let v = vec![1.0f32, 2.0, 3.0]; + let _ = callee(&v); +} diff --git a/tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs b/tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs new file mode 100644 index 00000000000..73826214aac --- /dev/null +++ b/tests/run-make/compiletest-self-test/symbols-helpers/rmake.rs @@ -0,0 +1,92 @@ +//! `run_make_support::symbols` helpers self test. + +// Only intended as a basic smoke test, does not try to account for platform or calling convention +// specific symbol decorations. +//@ only-x86_64-unknown-linux-gnu +//@ ignore-cross-compile + +use std::collections::BTreeSet; + +use object::{Object, ObjectSymbol}; +use run_make_support::symbols::{ + ContainsAllSymbolSubstringsOutcome, ContainsAllSymbolsOutcome, + object_contains_all_symbol_substring, object_contains_all_symbols, object_contains_any_symbol, + object_contains_any_symbol_substring, +}; +use run_make_support::{object, rfs, rust_lib_name, rustc}; + +fn main() { + rustc().input("sample.rs").emit("obj").edition("2024").run(); + + // `sample.rs` has two `no_mangle` functions, `eszett` and `beta`, in addition to `main`. + // + // These two symbol names and the test substrings used below are carefully picked to make sure + // they do not overlap with `sample` and contain non-hex characters, to avoid accidentally + // matching against CGU names like `sample.dad0f15d00c84e70-cgu.0`. + + let obj_filename = "sample.o"; + let blob = rfs::read(obj_filename); + let obj = object::File::parse(&*blob).unwrap(); + eprintln!("found symbols:"); + for sym in obj.symbols() { + eprintln!("symbol = {}", sym.name().unwrap()); + } + + // `hello` contains `hel` + assert!(object_contains_any_symbol_substring(obj_filename, &["zett"])); + assert!(object_contains_any_symbol_substring(obj_filename, &["zett", "does_not_exist"])); + assert!(!object_contains_any_symbol_substring(obj_filename, &["does_not_exist"])); + + assert!(object_contains_any_symbol(obj_filename, &["eszett"])); + assert!(object_contains_any_symbol(obj_filename, &["eszett", "beta"])); + assert!(!object_contains_any_symbol(obj_filename, &["zett"])); + assert!(!object_contains_any_symbol(obj_filename, &["does_not_exist"])); + + assert_eq!( + object_contains_all_symbol_substring(obj_filename, &["zett"]), + ContainsAllSymbolSubstringsOutcome::Ok + ); + assert_eq!( + object_contains_all_symbol_substring(obj_filename, &["zett", "bet"]), + ContainsAllSymbolSubstringsOutcome::Ok + ); + assert_eq!( + object_contains_all_symbol_substring(obj_filename, &["does_not_exist"]), + ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(BTreeSet::from([ + "does_not_exist" + ])) + ); + assert_eq!( + object_contains_all_symbol_substring(obj_filename, &["zett", "does_not_exist"]), + ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(BTreeSet::from([ + "does_not_exist" + ])) + ); + assert_eq!( + object_contains_all_symbol_substring(obj_filename, &["zett", "bet", "does_not_exist"]), + ContainsAllSymbolSubstringsOutcome::MissingSymbolSubstrings(BTreeSet::from([ + "does_not_exist" + ])) + ); + + assert_eq!( + object_contains_all_symbols(obj_filename, &["eszett"]), + ContainsAllSymbolsOutcome::Ok + ); + assert_eq!( + object_contains_all_symbols(obj_filename, &["eszett", "beta"]), + ContainsAllSymbolsOutcome::Ok + ); + assert_eq!( + object_contains_all_symbols(obj_filename, &["zett"]), + ContainsAllSymbolsOutcome::MissingSymbols(BTreeSet::from(["zett"])) + ); + assert_eq!( + object_contains_all_symbols(obj_filename, &["zett", "beta"]), + ContainsAllSymbolsOutcome::MissingSymbols(BTreeSet::from(["zett"])) + ); + assert_eq!( + object_contains_all_symbols(obj_filename, &["does_not_exist"]), + ContainsAllSymbolsOutcome::MissingSymbols(BTreeSet::from(["does_not_exist"])) + ); +} diff --git a/tests/run-make/compiletest-self-test/symbols-helpers/sample.rs b/tests/run-make/compiletest-self-test/symbols-helpers/sample.rs new file mode 100644 index 00000000000..3566d299766 --- /dev/null +++ b/tests/run-make/compiletest-self-test/symbols-helpers/sample.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] + +#[unsafe(no_mangle)] +pub extern "C" fn eszett() -> i8 { + 42 +} + +#[unsafe(no_mangle)] +pub extern "C" fn beta() -> u32 { + 1 +} + +fn main() {} diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr index 5ce815b9aed..464208f989e 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-disabled.stderr @@ -4,7 +4,7 @@ error: `[const]` is not allowed here LL | trait Bar: ~const Foo {} | ^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> const-super-trait.rs:7:1 | LL | trait Bar: ~const Foo {} @@ -30,24 +30,24 @@ LL | const fn foo<T: ~const Bar>(x: &T) { = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:7:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ can't be applied to `Foo` | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:9:17 | LL | const fn foo<T: ~const Bar>(x: &T) { | ^^^^^^ can't be applied to `Bar` | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: ~const Foo {} | ++++++++++++++ diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr index ef764a62b06..569e559186f 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-nightly-enabled.stderr @@ -4,30 +4,30 @@ error: `[const]` is not allowed here LL | trait Bar: ~const Foo {} | ^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> const-super-trait.rs:7:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:7:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ can't be applied to `Foo` | -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:9:17 | LL | const fn foo<T: ~const Bar>(x: &T) { | ^^^^^^ can't be applied to `Bar` | -help: mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: ~const Foo {} | ++++++++++++++ diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr index 3dc147e076f..694e06fb6ea 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-disabled.stderr @@ -4,7 +4,7 @@ error: `[const]` is not allowed here 7 | trait Bar: ~const Foo {} | ^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> const-super-trait.rs:7:1 | 7 | trait Bar: ~const Foo {} @@ -26,25 +26,25 @@ error[E0658]: const trait impls are experimental | = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:7:12 | 7 | trait Bar: ~const Foo {} | ^^^^^^ can't be applied to `Foo` | -note: `Foo` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Foo` can't be used with `[const]` because it isn't `const` --> const-super-trait.rs:3:1 | 3 | trait Foo { | ^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:9:17 | 9 | const fn foo<T: ~const Bar>(x: &T) { | ^^^^^^ can't be applied to `Bar` | -note: `Bar` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Bar` can't be used with `[const]` because it isn't `const` --> const-super-trait.rs:7:1 | 7 | trait Bar: ~const Foo {} diff --git a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr index 2cdeb277ca4..2109f0deb72 100644 --- a/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr +++ b/tests/run-make/const-trait-stable-toolchain/const-super-trait-stable-enabled.stderr @@ -4,7 +4,7 @@ error: `[const]` is not allowed here 7 | trait Bar: ~const Foo {} | ^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> const-super-trait.rs:7:1 | 7 | trait Bar: ~const Foo {} @@ -16,25 +16,25 @@ error[E0554]: `#![feature]` may not be used on the NIGHTLY release channel 1 | #![cfg_attr(feature_enabled, feature(const_trait_impl))] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:7:12 | 7 | trait Bar: ~const Foo {} | ^^^^^^ can't be applied to `Foo` | -note: `Foo` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Foo` can't be used with `[const]` because it isn't `const` --> const-super-trait.rs:3:1 | 3 | trait Foo { | ^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> const-super-trait.rs:9:17 | 9 | const fn foo<T: ~const Bar>(x: &T) { | ^^^^^^ can't be applied to `Bar` | -note: `Bar` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Bar` can't be used with `[const]` because it isn't `const` --> const-super-trait.rs:7:1 | 7 | trait Bar: ~const Foo {} diff --git a/tests/run-make/const-trait-stable-toolchain/rmake.rs b/tests/run-make/const-trait-stable-toolchain/rmake.rs index 09a7c27a106..729b71457e9 100644 --- a/tests/run-make/const-trait-stable-toolchain/rmake.rs +++ b/tests/run-make/const-trait-stable-toolchain/rmake.rs @@ -11,9 +11,7 @@ fn main() { .env("RUSTC_BOOTSTRAP", "-1") .cfg("feature_enabled") .run_fail() - .assert_stderr_not_contains( - "as `#[const_trait]` to allow it to have `const` implementations", - ) + .assert_stderr_not_contains("as `const` to allow it to have `const` implementations") .stderr_utf8(); diff() .expected_file("const-super-trait-stable-enabled.stderr") @@ -29,7 +27,7 @@ fn main() { .ui_testing() .run_fail() .assert_stderr_not_contains("enable `#![feature(const_trait_impl)]` in your crate and mark") - .assert_stderr_contains("as `#[const_trait]` to allow it to have `const` implementations") + .assert_stderr_contains("as `const` to allow it to have `const` implementations") .stderr_utf8(); diff() .expected_file("const-super-trait-nightly-enabled.stderr") @@ -40,9 +38,7 @@ fn main() { .env("RUSTC_BOOTSTRAP", "-1") .run_fail() .assert_stderr_not_contains("enable `#![feature(const_trait_impl)]` in your crate and mark") - .assert_stderr_not_contains( - "as `#[const_trait]` to allow it to have `const` implementations", - ) + .assert_stderr_not_contains("as `const` to allow it to have `const` implementations") .stderr_utf8(); diff() .expected_file("const-super-trait-stable-disabled.stderr") diff --git a/tests/run-make/export-executable-symbols/rmake.rs b/tests/run-make/export-executable-symbols/rmake.rs index 884c7362822..aa130b0855b 100644 --- a/tests/run-make/export-executable-symbols/rmake.rs +++ b/tests/run-make/export-executable-symbols/rmake.rs @@ -4,20 +4,22 @@ // symbol. // See https://github.com/rust-lang/rust/pull/85673 -//@ only-unix -// Reason: the export-executable-symbols flag only works on Unix -// due to hardcoded platform-specific implementation -// (See #85673) -//@ ignore-cross-compile //@ ignore-wasm +//@ ignore-cross-compile -use run_make_support::{bin_name, llvm_readobj, rustc}; +use run_make_support::object::Object; +use run_make_support::{bin_name, is_darwin, object, rustc}; fn main() { - rustc().arg("-Zexport-executable-symbols").input("main.rs").crate_type("bin").run(); - llvm_readobj() - .symbols() - .input(bin_name("main")) - .run() - .assert_stdout_contains("exported_symbol"); + rustc() + .arg("-Ctarget-feature=-crt-static") + .arg("-Zexport-executable-symbols") + .input("main.rs") + .crate_type("bin") + .run(); + let name: &[u8] = if is_darwin() { b"_exported_symbol" } else { b"exported_symbol" }; + let contents = std::fs::read(bin_name("main")).unwrap(); + let object = object::File::parse(contents.as_slice()).unwrap(); + let found = object.exports().unwrap().iter().any(|x| x.name() == name); + assert!(found); } diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs index af6ff6c2983..b7f18b384cb 100644 --- a/tests/run-make/fmt-write-bloat/rmake.rs +++ b/tests/run-make/fmt-write-bloat/rmake.rs @@ -20,7 +20,7 @@ use run_make_support::artifact_names::bin_name; use run_make_support::env::std_debug_assertions_enabled; use run_make_support::rustc; -use run_make_support::symbols::any_symbol_contains; +use run_make_support::symbols::object_contains_any_symbol_substring; fn main() { rustc().input("main.rs").opt().run(); @@ -31,5 +31,5 @@ fn main() { // otherwise, add them to the list of symbols to deny. panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]); } - assert!(!any_symbol_contains(bin_name("main"), &panic_syms)); + assert!(!object_contains_any_symbol_substring(bin_name("main"), &panic_syms)); } diff --git a/tests/run-make/link-eh-frame-terminator/rmake.rs b/tests/run-make/link-eh-frame-terminator/rmake.rs index 6bfae386ea1..06b77f011ec 100644 --- a/tests/run-make/link-eh-frame-terminator/rmake.rs +++ b/tests/run-make/link-eh-frame-terminator/rmake.rs @@ -9,6 +9,7 @@ //@ ignore-32bit // Reason: the usage of a large array in the test causes an out-of-memory // error on 32 bit systems. +//@ ignore-cross-compile use run_make_support::{bin_name, llvm_objdump, run, rustc}; diff --git a/tests/run-make/mte-ffi/bar.h b/tests/run-make/mte-ffi/bar.h index 9b030c618d1..a2292ae02a3 100644 --- a/tests/run-make/mte-ffi/bar.h +++ b/tests/run-make/mte-ffi/bar.h @@ -1,5 +1,3 @@ -// FIXME(#141600) the mte-ffi test doesn't fail in aarch64-gnu - #ifndef __BAR_H #define __BAR_H diff --git a/tests/run-make/mte-ffi/bar_float.c b/tests/run-make/mte-ffi/bar_float.c index acc2f5d9266..a1590f62765 100644 --- a/tests/run-make/mte-ffi/bar_float.c +++ b/tests/run-make/mte-ffi/bar_float.c @@ -3,9 +3,9 @@ #include <stdint.h> #include "bar.h" -extern void foo(float*); +extern void foo(char*); -void bar(float *ptr) { +void bar(char *ptr) { if (((uintptr_t)ptr >> 56) != 0x1f) { fprintf(stderr, "Top byte corrupted on Rust -> C FFI boundary!\n"); exit(1); diff --git a/tests/run-make/mte-ffi/bar_int.c b/tests/run-make/mte-ffi/bar_int.c index c92e765302c..d1c79e95dc9 100644 --- a/tests/run-make/mte-ffi/bar_int.c +++ b/tests/run-make/mte-ffi/bar_int.c @@ -5,7 +5,7 @@ extern void foo(unsigned int *); -void bar(unsigned int *ptr) { +void bar(char *ptr) { if (((uintptr_t)ptr >> 56) != 0x1f) { fprintf(stderr, "Top byte corrupted on Rust -> C FFI boundary!\n"); exit(1); diff --git a/tests/run-make/mte-ffi/bar_string.c b/tests/run-make/mte-ffi/bar_string.c index 8e1202f6fd1..5669ffd6695 100644 --- a/tests/run-make/mte-ffi/bar_string.c +++ b/tests/run-make/mte-ffi/bar_string.c @@ -1,7 +1,6 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> -#include <string.h> #include "bar.h" extern void foo(char*); @@ -33,7 +32,7 @@ int main(void) // Store an arbitrary tag in bits 56-59 of the pointer (where an MTE tag may be), // and a different value in the ignored top 4 bits. - ptr = (char *)((uintptr_t)ptr | 0x1fl << 56); + ptr = (unsigned int *)((uintptr_t)ptr | 0x1fl << 56); if (mte_enabled()) { set_tag(ptr); diff --git a/tests/run-make/mte-ffi/rmake.rs b/tests/run-make/mte-ffi/rmake.rs index a8da0dc0ee0..71d8318d946 100644 --- a/tests/run-make/mte-ffi/rmake.rs +++ b/tests/run-make/mte-ffi/rmake.rs @@ -2,6 +2,13 @@ //! FFI boundaries (C <-> Rust). This test does not require MTE: whilst the test will use MTE if //! available, if it is not, arbitrary tag bits are set using TBI. +//@ ignore-test (FIXME #141600) +// +// FIXME(#141600): this test is broken in two ways: +// 1. This test triggers `-Wincompatible-pointer-types` on GCC 14. +// 2. This test requires ARMv8.5+ w/ MTE extensions enabled, but GHA CI runner hardware do not have +// this enabled. + //@ only-aarch64-unknown-linux-gnu // Reason: this test is only valid for AArch64 with `gcc`. The linker must be explicitly specified // when cross-compiling, so it is limited to `aarch64-unknown-linux-gnu`. diff --git a/tests/run-make/option-output-no-space/main.rs b/tests/run-make/option-output-no-space/main.rs new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/tests/run-make/option-output-no-space/main.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/run-make/option-output-no-space/rmake.rs b/tests/run-make/option-output-no-space/rmake.rs new file mode 100644 index 00000000000..2c42f15aa89 --- /dev/null +++ b/tests/run-make/option-output-no-space/rmake.rs @@ -0,0 +1,95 @@ +// This test is to check if the warning is emitted when no space +// between `-o` and arg is applied, see issue #142812 + +//@ ignore-cross-compile +use run_make_support::rustc; + +fn main() { + // test fake args + rustc() + .input("main.rs") + .arg("-optimize") + .run() + .assert_stderr_contains( + "warning: option `-o` has no space between flag name and value, which can be confusing", + ) + .assert_stderr_contains( + "note: output filename `-o ptimize` is applied instead of a flag named `optimize`", + ); + rustc() + .input("main.rs") + .arg("-o0") + .run() + .assert_stderr_contains( + "warning: option `-o` has no space between flag name and value, which can be confusing", + ) + .assert_stderr_contains( + "note: output filename `-o 0` is applied instead of a flag named `o0`", + ); + rustc().input("main.rs").arg("-o1").run(); + // test real args by iter optgroups + rustc() + .input("main.rs") + .arg("-out-dir") + .run() + .assert_stderr_contains( + "warning: option `-o` has no space between flag name and value, which can be confusing", + ) + .assert_stderr_contains( + "note: output filename `-o ut-dir` is applied instead of a flag named `out-dir`", + ) + .assert_stderr_contains( + "help: insert a space between `-o` and `ut-dir` if this is intentional: `-o ut-dir`", + ); + // test real args by iter CG_OPTIONS + rustc() + .input("main.rs") + .arg("-opt_level") + .run() + .assert_stderr_contains( + "warning: option `-o` has no space between flag name and value, which can be confusing", + ) + .assert_stderr_contains( + "note: output filename `-o pt_level` is applied instead of a flag named `opt_level`", + ) + .assert_stderr_contains( + "help: insert a space between `-o` and `pt_level` if this is intentional: `-o pt_level`" + ); + // separater in-sensitive + rustc() + .input("main.rs") + .arg("-opt-level") + .run() + .assert_stderr_contains( + "warning: option `-o` has no space between flag name and value, which can be confusing", + ) + .assert_stderr_contains( + "note: output filename `-o pt-level` is applied instead of a flag named `opt-level`", + ) + .assert_stderr_contains( + "help: insert a space between `-o` and `pt-level` if this is intentional: `-o pt-level`" + ); + rustc() + .input("main.rs") + .arg("-overflow-checks") + .run() + .assert_stderr_contains( + "warning: option `-o` has no space between flag name and value, which can be confusing", + ) + .assert_stderr_contains( + "note: output filename `-o verflow-checks` \ + is applied instead of a flag named `overflow-checks`", + ) + .assert_stderr_contains( + "help: insert a space between `-o` and `verflow-checks` \ + if this is intentional: `-o verflow-checks`", + ); + + // No warning for Z_OPTIONS + rustc().input("main.rs").arg("-oom").run().assert_stderr_equals(""); + + // test no warning when there is space between `-o` and arg + rustc().input("main.rs").arg("-o").arg("ptimize").run().assert_stderr_equals(""); + rustc().input("main.rs").arg("--out-dir").arg("xxx").run().assert_stderr_equals(""); + rustc().input("main.rs").arg("-o").arg("out-dir").run().assert_stderr_equals(""); +} diff --git a/tests/run-make/used/rmake.rs b/tests/run-make/used/rmake.rs index bcdb84132d3..456321e2f56 100644 --- a/tests/run-make/used/rmake.rs +++ b/tests/run-make/used/rmake.rs @@ -8,9 +8,9 @@ // https://rust-lang.github.io/rfcs/2386-used.html use run_make_support::rustc; -use run_make_support::symbols::any_symbol_contains; +use run_make_support::symbols::object_contains_any_symbol_substring; fn main() { rustc().opt_level("3").emit("obj").input("used.rs").run(); - assert!(any_symbol_contains("used.o", &["FOO"])); + assert!(object_contains_any_symbol_substring("used.o", &["FOO"])); } diff --git a/tests/rustdoc-js-std/alias-lev.js b/tests/rustdoc-js-std/alias-lev.js new file mode 100644 index 00000000000..17f3dc25d76 --- /dev/null +++ b/tests/rustdoc-js-std/alias-lev.js @@ -0,0 +1,11 @@ +// This test ensures that aliases are also allowed to be partially matched. + +// ignore-order + +const EXPECTED = { + // The full alias name is `getcwd`. + 'query': 'getcw', + 'others': [ + { 'path': 'std::env', 'name': 'current_dir', 'alias': 'getcwd' }, + ], +}; diff --git a/tests/rustdoc-js/non-english-identifier.js b/tests/rustdoc-js/non-english-identifier.js index f2180b4c755..3d50bd3ee90 100644 --- a/tests/rustdoc-js/non-english-identifier.js +++ b/tests/rustdoc-js/non-english-identifier.js @@ -115,11 +115,10 @@ const EXPECTED = [ query: 'åŠ æ³•', others: [ { - name: "add", + name: "åŠ æ³•", path: "non_english_identifier", - is_alias: true, - alias: "åŠ æ³•", - href: "../non_english_identifier/macro.add.html" + href: "../non_english_identifier/trait.åŠ æ³•.html", + desc: "Add" }, { name: "add", @@ -129,11 +128,13 @@ const EXPECTED = [ href: "../non_english_identifier/fn.add.html" }, { - name: "åŠ æ³•", + name: "add", path: "non_english_identifier", - href: "../non_english_identifier/trait.åŠ æ³•.html", - desc: "Add" - }], + is_alias: true, + alias: "åŠ æ³•", + href: "../non_english_identifier/macro.add.html" + }, + ], in_args: [{ name: "åŠ ä¸Š", path: "non_english_identifier::åŠ æ³•", diff --git a/tests/rustdoc-json/attrs/automatically_derived.rs b/tests/rustdoc-json/attrs/automatically_derived.rs index 4e1ab3d145e..9ba310d3655 100644 --- a/tests/rustdoc-json/attrs/automatically_derived.rs +++ b/tests/rustdoc-json/attrs/automatically_derived.rs @@ -9,5 +9,5 @@ impl Default for Manual { } } -//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["#[automatically_derived]"]' +//@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Derive" && @.inner.impl.trait.path == "Default")].attrs' '["automatically_derived"]' //@ is '$.index[?(@.inner.impl.for.resolved_path.path == "Manual" && @.inner.impl.trait.path == "Default")].attrs' '[]' diff --git a/tests/rustdoc-json/attrs/cold.rs b/tests/rustdoc-json/attrs/cold.rs index e219345d669..ec1926e894e 100644 --- a/tests/rustdoc-json/attrs/cold.rs +++ b/tests/rustdoc-json/attrs/cold.rs @@ -1,3 +1,3 @@ -//@ is "$.index[?(@.name=='cold_fn')].attrs" '["#[attr = Cold]"]' +//@ is "$.index[?(@.name=='cold_fn')].attrs" '[{"other": "#[attr = Cold]"}]' #[cold] pub fn cold_fn() {} diff --git a/tests/rustdoc-json/attrs/export_name_2021.rs b/tests/rustdoc-json/attrs/export_name_2021.rs index 254e9f6ef5b..451d9b9eb37 100644 --- a/tests/rustdoc-json/attrs/export_name_2021.rs +++ b/tests/rustdoc-json/attrs/export_name_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +//@ is "$.index[?(@.name=='example')].attrs" '[{"export_name": "altered"}]' #[export_name = "altered"] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/export_name_2024.rs b/tests/rustdoc-json/attrs/export_name_2024.rs index 8129c109306..7e398db92ab 100644 --- a/tests/rustdoc-json/attrs/export_name_2024.rs +++ b/tests/rustdoc-json/attrs/export_name_2024.rs @@ -2,8 +2,8 @@ #![no_std] // The representation of `#[unsafe(export_name = ..)]` in rustdoc in edition 2024 -// is still `#[export_name = ..]` without the `unsafe` attribute wrapper. +// doesn't mention the `unsafe`. -//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +//@ is "$.index[?(@.name=='example')].attrs" '[{"export_name": "altered"}]' #[unsafe(export_name = "altered")] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/inline.rs b/tests/rustdoc-json/attrs/inline.rs index b9ea6ab1d10..2aed49a48a5 100644 --- a/tests/rustdoc-json/attrs/inline.rs +++ b/tests/rustdoc-json/attrs/inline.rs @@ -1,11 +1,11 @@ -//@ is "$.index[?(@.name=='just_inline')].attrs" '["#[attr = Inline(Hint)]"]' +//@ is "$.index[?(@.name=='just_inline')].attrs" '[{"other": "#[attr = Inline(Hint)]"}]' #[inline] pub fn just_inline() {} -//@ is "$.index[?(@.name=='inline_always')].attrs" '["#[attr = Inline(Always)]"]' +//@ is "$.index[?(@.name=='inline_always')].attrs" '[{"other": "#[attr = Inline(Always)]"}]' #[inline(always)] pub fn inline_always() {} -//@ is "$.index[?(@.name=='inline_never')].attrs" '["#[attr = Inline(Never)]"]' +//@ is "$.index[?(@.name=='inline_never')].attrs" '[{"other": "#[attr = Inline(Never)]"}]' #[inline(never)] pub fn inline_never() {} diff --git a/tests/rustdoc-json/attrs/link_section_2021.rs b/tests/rustdoc-json/attrs/link_section_2021.rs index a1312f4210b..acd8ecd0e30 100644 --- a/tests/rustdoc-json/attrs/link_section_2021.rs +++ b/tests/rustdoc-json/attrs/link_section_2021.rs @@ -1,6 +1,7 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[link_section = \".text\"]"]' +//@ count "$.index[?(@.name=='example')].attrs[*]" 1 +//@ is "$.index[?(@.name=='example')].attrs[*].link_section" '".text"' #[link_section = ".text"] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/link_section_2024.rs b/tests/rustdoc-json/attrs/link_section_2024.rs index edb028451a8..8107493229b 100644 --- a/tests/rustdoc-json/attrs/link_section_2024.rs +++ b/tests/rustdoc-json/attrs/link_section_2024.rs @@ -4,6 +4,7 @@ // Since the 2024 edition the link_section attribute must use the unsafe qualification. // However, the unsafe qualification is not shown by rustdoc. -//@ is "$.index[?(@.name=='example')].attrs" '["#[link_section = \".text\"]"]' +//@ count "$.index[?(@.name=='example')].attrs[*]" 1 +//@ is "$.index[?(@.name=='example')].attrs[*].link_section" '".text"' #[unsafe(link_section = ".text")] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/must_use.rs b/tests/rustdoc-json/attrs/must_use.rs index 3ca6f5a75a5..3f924c5169c 100644 --- a/tests/rustdoc-json/attrs/must_use.rs +++ b/tests/rustdoc-json/attrs/must_use.rs @@ -1,9 +1,9 @@ #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[attr = MustUse]"]' +//@ is "$.index[?(@.name=='example')].attrs[*].must_use.reason" null #[must_use] pub fn example() -> impl Iterator<Item = i64> {} -//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[attr = MustUse {reason: \"does nothing if you do not use it\"}]"]' +//@ is "$.index[?(@.name=='explicit_message')].attrs[*].must_use.reason" '"does nothing if you do not use it"' #[must_use = "does nothing if you do not use it"] pub fn explicit_message() -> impl Iterator<Item = i64> {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2021.rs b/tests/rustdoc-json/attrs/no_mangle_2021.rs index 588be7256db..703dcb56491 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2021.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["no_mangle"]' #[no_mangle] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2024.rs b/tests/rustdoc-json/attrs/no_mangle_2024.rs index 0d500e20e6c..8af00eeda6b 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2024.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(no_mangle)]` in rustdoc in edition 2024 // is still `#[no_mangle]` without the `unsafe` attribute wrapper. -//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["no_mangle"]' #[unsafe(no_mangle)] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/non_exhaustive.rs b/tests/rustdoc-json/attrs/non_exhaustive.rs index b95f1a8171f..e4e6c8fd53b 100644 --- a/tests/rustdoc-json/attrs/non_exhaustive.rs +++ b/tests/rustdoc-json/attrs/non_exhaustive.rs @@ -1,18 +1,18 @@ #![no_std] -//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]' +//@ is "$.index[?(@.name=='MyEnum')].attrs" '["non_exhaustive"]' #[non_exhaustive] pub enum MyEnum { First, } pub enum NonExhaustiveVariant { - //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]' + //@ is "$.index[?(@.name=='Variant')].attrs" '["non_exhaustive"]' #[non_exhaustive] Variant(i64), } -//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]' +//@ is "$.index[?(@.name=='MyStruct')].attrs" '["non_exhaustive"]' #[non_exhaustive] pub struct MyStruct { pub x: i64, diff --git a/tests/rustdoc-json/attrs/optimize.rs b/tests/rustdoc-json/attrs/optimize.rs index 0bed0ad18c3..5988120ab2f 100644 --- a/tests/rustdoc-json/attrs/optimize.rs +++ b/tests/rustdoc-json/attrs/optimize.rs @@ -1,13 +1,13 @@ #![feature(optimize_attribute)] -//@ is "$.index[?(@.name=='speed')].attrs" '["#[attr = Optimize(Speed)]"]' +//@ is "$.index[?(@.name=='speed')].attrs" '[{"other": "#[attr = Optimize(Speed)]"}]' #[optimize(speed)] pub fn speed() {} -//@ is "$.index[?(@.name=='size')].attrs" '["#[attr = Optimize(Size)]"]' +//@ is "$.index[?(@.name=='size')].attrs" '[{"other": "#[attr = Optimize(Size)]"}]' #[optimize(size)] pub fn size() {} -//@ is "$.index[?(@.name=='none')].attrs" '["#[attr = Optimize(DoNotOptimize)]"]' +//@ is "$.index[?(@.name=='none')].attrs" '[{"other": "#[attr = Optimize(DoNotOptimize)]"}]' #[optimize(none)] pub fn none() {} diff --git a/tests/rustdoc-json/attrs/repr_align.rs b/tests/rustdoc-json/attrs/repr_align.rs index c6debda7f1c..f9d3417c485 100644 --- a/tests/rustdoc-json/attrs/repr_align.rs +++ b/tests/rustdoc-json/attrs/repr_align.rs @@ -1,6 +1,7 @@ #![no_std] -//@ is "$.index[?(@.name=='Aligned')].attrs" '["#[repr(align(4))]"]' +//@ count "$.index[?(@.name=='Aligned')].attrs[*]" 1 +//@ is "$.index[?(@.name=='Aligned')].attrs[*].repr.align" 4 #[repr(align(4))] pub struct Aligned { a: i8, diff --git a/tests/rustdoc-json/attrs/repr_c.rs b/tests/rustdoc-json/attrs/repr_c.rs index e6219413f30..89dbc16cb2a 100644 --- a/tests/rustdoc-json/attrs/repr_c.rs +++ b/tests/rustdoc-json/attrs/repr_c.rs @@ -1,16 +1,28 @@ #![no_std] -//@ is "$.index[?(@.name=='ReprCStruct')].attrs" '["#[repr(C)]"]' +//@ count "$.index[?(@.name=='ReprCStruct')].attrs" 1 +//@ is "$.index[?(@.name=='ReprCStruct')].attrs[*].repr.kind" '"c"' +//@ is "$.index[?(@.name=='ReprCStruct')].attrs[*].repr.int" null +//@ is "$.index[?(@.name=='ReprCStruct')].attrs[*].repr.packed" null +//@ is "$.index[?(@.name=='ReprCStruct')].attrs[*].repr.align" null #[repr(C)] pub struct ReprCStruct(pub i64); -//@ is "$.index[?(@.name=='ReprCEnum')].attrs" '["#[repr(C)]"]' +//@ count "$.index[?(@.name=='ReprCEnum')].attrs" 1 +//@ is "$.index[?(@.name=='ReprCEnum')].attrs[*].repr.kind" '"c"' +//@ is "$.index[?(@.name=='ReprCEnum')].attrs[*].repr.int" null +//@ is "$.index[?(@.name=='ReprCEnum')].attrs[*].repr.packed" null +//@ is "$.index[?(@.name=='ReprCEnum')].attrs[*].repr.align" null #[repr(C)] pub enum ReprCEnum { First, } -//@ is "$.index[?(@.name=='ReprCUnion')].attrs" '["#[repr(C)]"]' +//@ count "$.index[?(@.name=='ReprCUnion')].attrs" 1 +//@ is "$.index[?(@.name=='ReprCUnion')].attrs[*].repr.kind" '"c"' +//@ is "$.index[?(@.name=='ReprCUnion')].attrs[*].repr.int" null +//@ is "$.index[?(@.name=='ReprCUnion')].attrs[*].repr.packed" null +//@ is "$.index[?(@.name=='ReprCUnion')].attrs[*].repr.align" null #[repr(C)] pub union ReprCUnion { pub left: i64, diff --git a/tests/rustdoc-json/attrs/repr_c_int_enum.rs b/tests/rustdoc-json/attrs/repr_c_int_enum.rs new file mode 100644 index 00000000000..e90bcf2b5c6 --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_c_int_enum.rs @@ -0,0 +1,11 @@ +//@ count "$.index[?(@.name=='Foo')].attrs" 1 +//@ is "$.index[?(@.name=='Foo')].attrs[*].repr.kind" '"c"' +//@ is "$.index[?(@.name=='Foo')].attrs[*].repr.int" '"u8"' +//@ is "$.index[?(@.name=='Foo')].attrs[*].repr.packed" null +//@ is "$.index[?(@.name=='Foo')].attrs[*].repr.align" 16 +#[repr(C, u8)] +#[repr(align(16))] +pub enum Foo { + A(bool) = b'A', + B(char) = b'C', +} diff --git a/tests/rustdoc-json/attrs/repr_combination.rs b/tests/rustdoc-json/attrs/repr_combination.rs index 6fe29c5eac0..bd4a8563b6f 100644 --- a/tests/rustdoc-json/attrs/repr_combination.rs +++ b/tests/rustdoc-json/attrs/repr_combination.rs @@ -1,35 +1,34 @@ #![no_std] // Combinations of `#[repr(..)]` attributes. -// Rustdoc JSON emits normalized output, regardless of the original source. -//@ is "$.index[?(@.name=='ReprCI8')].attrs" '["#[repr(C, i8)]"]' +//@ is "$.index[?(@.name=='ReprCI8')].attrs" '[{"repr":{"align":null,"int":"i8","kind":"c","packed":null}}]' #[repr(C, i8)] pub enum ReprCI8 { First, } -//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '["#[repr(C, i16)]"]' +//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '[{"repr":{"align":null,"int":"i16","kind":"c","packed":null}}]' #[repr(C)] #[repr(i16)] pub enum SeparateReprCI16 { First, } -//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '["#[repr(C, usize)]"]' +//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '[{"repr":{"align":null,"int":"usize","kind":"c","packed":null}}]' #[repr(usize, C)] pub enum ReversedReprCUsize { First, } -//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '["#[repr(C, packed(1))]"]' +//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '[{"repr":{"align":null,"int":null,"kind":"c","packed":1}}]' #[repr(C, packed)] pub struct ReprCPacked { a: i8, b: i64, } -//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '["#[repr(C, packed(2))]"]' +//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '[{"repr":{"align":null,"int":null,"kind":"c","packed":2}}]' #[repr(C)] #[repr(packed(2))] pub struct SeparateReprCPacked { @@ -37,21 +36,21 @@ pub struct SeparateReprCPacked { b: i64, } -//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '["#[repr(C, packed(2))]"]' +//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '[{"repr":{"align":null,"int":null,"kind":"c","packed":2}}]' #[repr(packed(2), C)] pub struct ReversedReprCPacked { a: i8, b: i64, } -//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '["#[repr(C, align(16))]"]' +//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '[{"repr":{"align":16,"int":null,"kind":"c","packed":null}}]' #[repr(C, align(16))] pub struct ReprCAlign { a: i8, b: i64, } -//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '["#[repr(C, align(2))]"]' +//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '[{"repr":{"align":2,"int":null,"kind":"c","packed":null}}]' #[repr(C)] #[repr(align(2))] pub struct SeparateReprCAlign { @@ -59,25 +58,25 @@ pub struct SeparateReprCAlign { b: i64, } -//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '["#[repr(C, align(2))]"]' +//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '[{"repr":{"align":2,"int":null,"kind":"c","packed":null}}]' #[repr(align(2), C)] pub struct ReversedReprCAlign { a: i8, b: i64, } -//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]' +//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '[{"repr":{"align":16,"int":"isize","kind":"c","packed":null}}]' #[repr(C, align(16), isize)] pub enum AlignedExplicitRepr { First, } -//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]' +//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '[{"repr":{"align":16,"int":"isize","kind":"c","packed":null}}]' #[repr(isize, C, align(16))] pub enum ReorderedAlignedExplicitRepr { First, } -//@ is "$.index[?(@.name=='Transparent')].attrs" '["#[repr(transparent)]"]' +//@ is "$.index[?(@.name=='Transparent')].attrs" '[{"repr":{"align":null,"int":null,"kind":"transparent","packed":null}}]' #[repr(transparent)] pub struct Transparent(i64); diff --git a/tests/rustdoc-json/attrs/repr_int_enum.rs b/tests/rustdoc-json/attrs/repr_int_enum.rs index 9b09f341d4f..79e17f53ad9 100644 --- a/tests/rustdoc-json/attrs/repr_int_enum.rs +++ b/tests/rustdoc-json/attrs/repr_int_enum.rs @@ -1,18 +1,27 @@ #![no_std] -//@ is "$.index[?(@.name=='I8')].attrs" '["#[repr(i8)]"]' +//@ is "$.index[?(@.name=='I8')].attrs[*].repr.int" '"i8"' +//@ is "$.index[?(@.name=='I8')].attrs[*].repr.kind" '"rust"' +//@ is "$.index[?(@.name=='I8')].attrs[*].repr.align" null +//@ is "$.index[?(@.name=='I8')].attrs[*].repr.packed" null #[repr(i8)] pub enum I8 { First, } -//@ is "$.index[?(@.name=='I32')].attrs" '["#[repr(i32)]"]' +//@ is "$.index[?(@.name=='I32')].attrs[*].repr.int" '"i32"' +//@ is "$.index[?(@.name=='I32')].attrs[*].repr.kind" '"rust"' +//@ is "$.index[?(@.name=='I32')].attrs[*].repr.align" null +//@ is "$.index[?(@.name=='I32')].attrs[*].repr.packed" null #[repr(i32)] pub enum I32 { First, } -//@ is "$.index[?(@.name=='Usize')].attrs" '["#[repr(usize)]"]' +//@ is "$.index[?(@.name=='Usize')].attrs[*].repr.int" '"usize"' +//@ is "$.index[?(@.name=='Usize')].attrs[*].repr.kind" '"rust"' +//@ is "$.index[?(@.name=='Usize')].attrs[*].repr.align" null +//@ is "$.index[?(@.name=='Usize')].attrs[*].repr.packed" null #[repr(usize)] pub enum Usize { First, diff --git a/tests/rustdoc-json/attrs/repr_packed.rs b/tests/rustdoc-json/attrs/repr_packed.rs index 9f3fd86c4b0..ab573835b45 100644 --- a/tests/rustdoc-json/attrs/repr_packed.rs +++ b/tests/rustdoc-json/attrs/repr_packed.rs @@ -1,16 +1,18 @@ #![no_std] // Note the normalization: -// `#[repr(packed)]` in source becomes `#[repr(packed(1))]` in rustdoc JSON. +// `#[repr(packed)]` in source becomes `{"repr": {"packed": 1, ...}}` in rustdoc JSON. // -//@ is "$.index[?(@.name=='Packed')].attrs" '["#[repr(packed(1))]"]' +//@ is "$.index[?(@.name=='Packed')].attrs[*].repr.packed" 1 +//@ is "$.index[?(@.name=='Packed')].attrs[*].repr.kind" '"rust"' #[repr(packed)] pub struct Packed { a: i8, b: i64, } -//@ is "$.index[?(@.name=='PackedAligned')].attrs" '["#[repr(packed(4))]"]' +//@ is "$.index[?(@.name=='PackedAligned')].attrs[*].repr.packed" 4 +//@ is "$.index[?(@.name=='PackedAligned')].attrs[*].repr.kind" '"rust"' #[repr(packed(4))] pub struct PackedAligned { a: i8, diff --git a/tests/rustdoc-json/attrs/target_feature.rs b/tests/rustdoc-json/attrs/target_feature.rs index 01bc4f54d32..efe3752c166 100644 --- a/tests/rustdoc-json/attrs/target_feature.rs +++ b/tests/rustdoc-json/attrs/target_feature.rs @@ -1,38 +1,49 @@ -//@ is "$.index[?(@.name=='test1')].attrs" '["#[target_feature(enable=\"avx\")]"]' //@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ count "$.index[?(@.name=='test1')].attrs[*]" 1 +//@ is "$.index[?(@.name=='test1')].attrs[*].target_feature.enable" '["avx"]' #[target_feature(enable = "avx")] pub fn test1() {} -//@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' //@ is "$.index[?(@.name=='test2')].inner.function.header.is_unsafe" false +//@ count "$.index[?(@.name=='test2')].attrs[*]" 1 +//@ is "$.index[?(@.name=='test2')].attrs[*].target_feature.enable" '["avx", "avx2"]' #[target_feature(enable = "avx,avx2")] pub fn test2() {} -//@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' //@ is "$.index[?(@.name=='test3')].inner.function.header.is_unsafe" false +//@ count "$.index[?(@.name=='test3')].attrs[*]" 1 +//@ is "$.index[?(@.name=='test3')].attrs[*].target_feature.enable" '["avx", "avx2"]' #[target_feature(enable = "avx", enable = "avx2")] pub fn test3() {} -//@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]' //@ is "$.index[?(@.name=='test4')].inner.function.header.is_unsafe" false +//@ count "$.index[?(@.name=='test4')].attrs[*]" 1 +//@ is "$.index[?(@.name=='test4')].attrs[*].target_feature.enable" '["avx", "avx2", "avx512f"]' #[target_feature(enable = "avx", enable = "avx2,avx512f")] pub fn test4() {} -//@ is "$.index[?(@.name=='test_unsafe_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]' +//@ count "$.index[?(@.name=='test5')].attrs[*]" 1 +//@ is "$.index[?(@.name=='test5')].attrs[*].target_feature.enable" '["avx", "avx2"]' +#[target_feature(enable = "avx")] +#[target_feature(enable = "avx2")] +pub fn test5() {} + //@ is "$.index[?(@.name=='test_unsafe_fn')].inner.function.header.is_unsafe" true +//@ count "$.index[?(@.name=='test_unsafe_fn')].attrs[*]" 1 +//@ is "$.index[?(@.name=='test_unsafe_fn')].attrs[*].target_feature.enable" '["avx"]' #[target_feature(enable = "avx")] pub unsafe fn test_unsafe_fn() {} pub struct Example; impl Example { - //@ is "$.index[?(@.name=='safe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]' //@ is "$.index[?(@.name=='safe_assoc_fn')].inner.function.header.is_unsafe" false + //@ is "$.index[?(@.name=='safe_assoc_fn')].attrs[*].target_feature.enable" '["avx"]' #[target_feature(enable = "avx")] pub fn safe_assoc_fn() {} - //@ is "$.index[?(@.name=='unsafe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]' //@ is "$.index[?(@.name=='unsafe_assoc_fn')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='unsafe_assoc_fn')].attrs[*].target_feature.enable" '["avx"]' #[target_feature(enable = "avx")] pub unsafe fn unsafe_assoc_fn() {} } diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs index ea669e6a0b3..fed0e545798 100644 --- a/tests/rustdoc-json/enums/discriminant/struct.rs +++ b/tests/rustdoc-json/enums/discriminant/struct.rs @@ -1,5 +1,5 @@ #[repr(i32)] -//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(i32)]"]' +//@ is "$.index[?(@.name=='Foo')].attrs[*].repr.int" '"i32"' pub enum Foo { //@ is "$.index[?(@.name=='Struct')].inner.variant.discriminant" null //@ count "$.index[?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0 diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs index 1b8e791eb23..54bba76a063 100644 --- a/tests/rustdoc-json/enums/discriminant/tuple.rs +++ b/tests/rustdoc-json/enums/discriminant/tuple.rs @@ -1,5 +1,5 @@ #[repr(u32)] -//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(u32)]"]' +//@ is "$.index[?(@.name=='Foo')].attrs[*].repr.int" '"u32"' pub enum Foo { //@ is "$.index[?(@.name=='Tuple')].inner.variant.discriminant" null //@ count "$.index[?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0 diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs index fea546c9fb6..3198fc2529e 100644 --- a/tests/rustdoc-json/keyword_private.rs +++ b/tests/rustdoc-json/keyword_private.rs @@ -5,7 +5,7 @@ //@ !has "$.index[?(@.name=='match')]" //@ has "$.index[?(@.name=='foo')]" -//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]' +//@ is "$.index[?(@.name=='foo')].attrs[*].other" '"#[doc(keyword = \"match\")]"' //@ is "$.index[?(@.name=='foo')].docs" '"this is a test!"' #[doc(keyword = "match")] /// this is a test! @@ -13,7 +13,7 @@ pub mod foo {} //@ !has "$.index[?(@.name=='break')]" //@ has "$.index[?(@.name=='bar')]" -//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]"]' +//@ is "$.index[?(@.name=='bar')].attrs[*].other" '"#[doc(keyword = \"break\")]"' //@ is "$.index[?(@.name=='bar')].docs" '"hello"' #[doc(keyword = "break")] /// hello diff --git a/tests/rustdoc-json/visibility/doc_hidden_documented.rs b/tests/rustdoc-json/visibility/doc_hidden_documented.rs index 6e9ef48680b..f05e4f9d92d 100644 --- a/tests/rustdoc-json/visibility/doc_hidden_documented.rs +++ b/tests/rustdoc-json/visibility/doc_hidden_documented.rs @@ -1,15 +1,15 @@ //@ compile-flags: --document-hidden-items #![no_std] -//@ is "$.index[?(@.name=='func')].attrs" '["#[doc(hidden)]"]' +//@ is "$.index[?(@.name=='func')].attrs" '[{"other": "#[doc(hidden)]"}]' #[doc(hidden)] pub fn func() {} -//@ is "$.index[?(@.name=='Unit')].attrs" '["#[doc(hidden)]"]' +//@ is "$.index[?(@.name=='Unit')].attrs" '[{"other": "#[doc(hidden)]"}]' #[doc(hidden)] pub struct Unit; -//@ is "$.index[?(@.name=='hidden')].attrs" '["#[doc(hidden)]"]' +//@ is "$.index[?(@.name=='hidden')].attrs" '[{"other": "#[doc(hidden)]"}]' #[doc(hidden)] pub mod hidden { //@ is "$.index[?(@.name=='Inner')].attrs" '[]' diff --git a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr index 85c9516236c..9d3ce5e63ef 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -4,13 +4,13 @@ error: `#[doc(alias = "...")]` isn't allowed on foreign module LL | #[doc(alias = "foo")] | ^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on implementation block +error: `#[doc(alias = "...")]` isn't allowed on inherent implementation block --> $DIR/check-doc-alias-attr-location.rs:10:7 | LL | #[doc(alias = "bar")] | ^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on implementation block +error: `#[doc(alias = "...")]` isn't allowed on trait implementation block --> $DIR/check-doc-alias-attr-location.rs:16:7 | LL | #[doc(alias = "foobar")] diff --git a/tests/rustdoc/reexport/auxiliary/reexports-attrs.rs b/tests/rustdoc/reexport/auxiliary/reexports-attrs.rs new file mode 100644 index 00000000000..96fa8209cde --- /dev/null +++ b/tests/rustdoc/reexport/auxiliary/reexports-attrs.rs @@ -0,0 +1,14 @@ +#[unsafe(no_mangle)] +pub fn f0() {} + +#[unsafe(link_section = ".here")] +pub fn f1() {} + +#[unsafe(export_name = "f2export")] +pub fn f2() {} + +#[repr(u8)] +pub enum T0 { V1 } + +#[non_exhaustive] +pub enum T1 {} diff --git a/tests/rustdoc/reexport/reexport-attrs.rs b/tests/rustdoc/reexport/reexport-attrs.rs new file mode 100644 index 00000000000..0ec645841f0 --- /dev/null +++ b/tests/rustdoc/reexport/reexport-attrs.rs @@ -0,0 +1,20 @@ +//@ aux-build: reexports-attrs.rs + +#![crate_name = "foo"] + +extern crate reexports_attrs; + +//@ has 'foo/fn.f0.html' '//pre[@class="rust item-decl"]' '#[no_mangle]' +pub use reexports_attrs::f0; + +//@ has 'foo/fn.f1.html' '//pre[@class="rust item-decl"]' '#[link_section = ".here"]' +pub use reexports_attrs::f1; + +//@ has 'foo/fn.f2.html' '//pre[@class="rust item-decl"]' '#[export_name = "f2export"]' +pub use reexports_attrs::f2; + +//@ has 'foo/enum.T0.html' '//pre[@class="rust item-decl"]' '#[repr(u8)]' +pub use reexports_attrs::T0; + +//@ has 'foo/enum.T1.html' '//pre[@class="rust item-decl"]' '#[non_exhaustive]' +pub use reexports_attrs::T1; diff --git a/tests/ui/asm/naked-function-shim.rs b/tests/ui/asm/naked-function-shim.rs new file mode 100644 index 00000000000..4694d0cd963 --- /dev/null +++ b/tests/ui/asm/naked-function-shim.rs @@ -0,0 +1,31 @@ +// The indirect call will generate a shim that then calls the actual function. Test that +// this is handled correctly. See also https://github.com/rust-lang/rust/issues/143266. + +//@ build-pass +//@ add-core-stubs +//@ revisions: aarch64 x86_64 +//@ [aarch64] compile-flags: --target aarch64-unknown-none +//@ [aarch64] needs-llvm-components: aarch64 +//@ [x86_64] compile-flags: --target x86_64-unknown-none +//@ [x86_64] needs-llvm-components: x86 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +extern crate minicore; +use minicore::*; + +trait MyTrait { + #[unsafe(naked)] + extern "C" fn foo(&self) { + naked_asm!("ret") + } +} + +impl MyTrait for i32 {} + +fn main() { + let x: extern "C" fn(&_) = <dyn MyTrait as MyTrait>::foo; + x(&1); +} diff --git a/tests/ui/asm/naked-invalid-attr.stderr b/tests/ui/asm/naked-invalid-attr.stderr index 915b54b3fc2..2571c8fa989 100644 --- a/tests/ui/asm/naked-invalid-attr.stderr +++ b/tests/ui/asm/naked-invalid-attr.stderr @@ -8,7 +8,7 @@ error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/naked-invalid-attr.rs:56:3 | LL | #[::a] - | ^^^ the `{{root}}::a` attribute is incompatible with `#[unsafe(naked)]` + | ^^^ the `::a` attribute is incompatible with `#[unsafe(naked)]` ... LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here diff --git a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs index b90bb9ea4dd..029ce7d0e7e 100644 --- a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs +++ b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.rs @@ -1,8 +1,7 @@ // Regression test for <https://github.com/rust-lang/rust/issues/137554>. fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { - //~^ ERROR `?Trait` is not permitted in trait object types - //~| ERROR expected trait, found associated function `Iterator::advance_by` - //~| ERROR the value of the associated type `Item` in `Iterator` must be specified + //~^ ERROR expected trait, found associated function `Iterator::advance_by` + //~| ERROR relaxed bounds are not permitted in trait object types todo!() } diff --git a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr index 7f0fbc800ed..ffe0b14a030 100644 --- a/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr +++ b/tests/ui/associated-item/missing-associated_item_or_field_def_ids.stderr @@ -1,25 +1,15 @@ -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/missing-associated_item_or_field_def_ids.rs:3:29 - | -LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error[E0404]: expected trait, found associated function `Iterator::advance_by` --> $DIR/missing-associated_item_or_field_def_ids.rs:3:30 | LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a trait -error[E0191]: the value of the associated type `Item` in `Iterator` must be specified - --> $DIR/missing-associated_item_or_field_def_ids.rs:3:18 +error: relaxed bounds are not permitted in trait object types + --> $DIR/missing-associated_item_or_field_def_ids.rs:3:29 | LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) { - | ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0191, E0404, E0658. -For more information about an error, try `rustc --explain E0191`. +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs index f6b749a5100..bac4e608867 100644 --- a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs +++ b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.rs @@ -6,7 +6,6 @@ trait Tr { fn main() { let _: dyn Tr + ?Foo<Assoc = ()>; - //~^ ERROR: `?Trait` is not permitted in trait object types - //~| ERROR: cannot find trait `Foo` in this scope - //~| ERROR: the value of the associated type `Item` in `Tr` must be specified + //~^ ERROR: cannot find trait `Foo` in this scope + //~| ERROR: relaxed bounds are not permitted in trait object types } diff --git a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr index f31a1de76a7..3660fcece62 100644 --- a/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr +++ b/tests/ui/associated-types/avoid-getting-associated-items-of-undefined-trait.stderr @@ -1,28 +1,15 @@ -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21 - | -LL | let _: dyn Tr + ?Foo<Assoc = ()>; - | ^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error[E0405]: cannot find trait `Foo` in this scope --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:22 | LL | let _: dyn Tr + ?Foo<Assoc = ()>; | ^^^ not found in this scope -error[E0191]: the value of the associated type `Item` in `Tr` must be specified - --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:16 +error: relaxed bounds are not permitted in trait object types + --> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21 | -LL | type Item; - | --------- `Item` defined here -... LL | let _: dyn Tr + ?Foo<Assoc = ()>; - | ^^ help: specify the associated type: `Tr<Item = Type>` + | ^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0191, E0405, E0658. -For more information about an error, try `rustc --explain E0191`. +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index b50e353b698..58a5b0b79c4 100644 --- a/tests/ui/async-await/async-closures/def-path.stderr +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -5,11 +5,11 @@ LL | let x = async || {}; | -- the expected `async` closure body LL | LL | let () = x(); - | ^^ --- this expression has type `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}` + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}` | | | expected `async` closure body, found `()` | - = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}` + = note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}` found unit type `()` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-drop/foreign-fundamental.rs b/tests/ui/async-await/async-drop/foreign-fundamental.rs new file mode 100644 index 00000000000..1c192fccd9f --- /dev/null +++ b/tests/ui/async-await/async-drop/foreign-fundamental.rs @@ -0,0 +1,21 @@ +//@ edition: 2018 + +#![feature(async_drop)] +//~^ WARN the feature `async_drop` is incomplete + +use std::future::AsyncDrop; +use std::pin::Pin; + +struct Foo; + +impl AsyncDrop for &Foo { + //~^ ERROR the `AsyncDrop` trait may only be implemented for + async fn drop(self: Pin<&mut Self>) {} +} + +impl AsyncDrop for Pin<Foo> { + //~^ ERROR the `AsyncDrop` trait may only be implemented for + async fn drop(self: Pin<&mut Self>) {} +} + +fn main() {} diff --git a/tests/ui/async-await/async-drop/foreign-fundamental.stderr b/tests/ui/async-await/async-drop/foreign-fundamental.stderr new file mode 100644 index 00000000000..7b52329ac99 --- /dev/null +++ b/tests/ui/async-await/async-drop/foreign-fundamental.stderr @@ -0,0 +1,24 @@ +warning: the feature `async_drop` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/foreign-fundamental.rs:3:12 + | +LL | #![feature(async_drop)] + | ^^^^^^^^^^ + | + = note: see issue #126482 <https://github.com/rust-lang/rust/issues/126482> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0120]: the `AsyncDrop` trait may only be implemented for local structs, enums, and unions + --> $DIR/foreign-fundamental.rs:11:20 + | +LL | impl AsyncDrop for &Foo { + | ^^^^ must be a struct, enum, or union in the current crate + +error[E0120]: the `AsyncDrop` trait may only be implemented for local structs, enums, and unions + --> $DIR/foreign-fundamental.rs:16:20 + | +LL | impl AsyncDrop for Pin<Foo> { + | ^^^^^^^^ must be a struct, enum, or union in the current crate + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0120`. diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.no_assumptions.stderr index 0d3ee8a9377..d5560bf8920 100644 --- a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr +++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.no_assumptions.stderr @@ -1,9 +1,7 @@ error: implementation of `FnOnce` is not general enough - --> $DIR/drop-tracking-unresolved-typeck-results.rs:98:5 + --> $DIR/drop-tracking-unresolved-typeck-results.rs:102:5 | LL | / send(async { -LL | | -LL | | LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await LL | | }); | |______^ implementation of `FnOnce` is not general enough @@ -12,11 +10,9 @@ LL | | }); = note: ...but it actually implements `FnOnce<(&(),)>` error: implementation of `FnOnce` is not general enough - --> $DIR/drop-tracking-unresolved-typeck-results.rs:98:5 + --> $DIR/drop-tracking-unresolved-typeck-results.rs:102:5 | LL | / send(async { -LL | | -LL | | LL | | Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await LL | | }); | |______^ implementation of `FnOnce` is not general enough diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs index e6c295405e2..16f929331cb 100644 --- a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs +++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs @@ -1,5 +1,9 @@ //@ incremental //@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 use std::future::*; use std::marker::PhantomData; @@ -96,8 +100,6 @@ impl<St: ?Sized + Stream + Unpin> Future for Next<'_, St> { fn main() { send(async { - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await }); } diff --git a/tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr new file mode 100644 index 00000000000..b298a3bf215 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-1.no_assumptions.stderr @@ -0,0 +1,38 @@ +error[E0308]: mismatched types + --> $DIR/higher-ranked-auto-trait-1.rs:37:5 + | +LL | / async { +LL | | let _y = &(); +LL | | let _x = filter(FilterMap { +LL | | f: || async move { *_y }, +... | +LL | | drop(_x); +LL | | } + | |_____^ one type is more general than the other + | + = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}` + found `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object + +error[E0308]: mismatched types + --> $DIR/higher-ranked-auto-trait-1.rs:37:5 + | +LL | / async { +LL | | let _y = &(); +LL | | let _x = filter(FilterMap { +LL | | f: || async move { *_y }, +... | +LL | | drop(_x); +LL | | } + | |_____^ one type is more general than the other + | + = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}` + found `async` block `{async block@$DIR/higher-ranked-auto-trait-1.rs:40:19: 40:29}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/higher-ranked-auto-trait-1.rs b/tests/ui/async-await/higher-ranked-auto-trait-1.rs new file mode 100644 index 00000000000..740f7e29245 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-1.rs @@ -0,0 +1,48 @@ +// Repro for <https://github.com/rust-lang/rust/issues/79648#issuecomment-749127947>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::future::Future; +use std::marker::PhantomData; + +trait Stream { + type Item; +} + +struct Filter<St: Stream> { + pending_item: St::Item, +} + +fn filter<St: Stream>(_: St) -> Filter<St> { + unimplemented!(); +} + +struct FilterMap<Fut, F> { + f: F, + pending: PhantomData<Fut>, +} + +impl<Fut, F> Stream for FilterMap<Fut, F> +where + F: FnMut() -> Fut, + Fut: Future, +{ + type Item = (); +} + +pub fn get_foo() -> impl Future + Send { + async { + let _y = &(); + let _x = filter(FilterMap { + f: || async move { *_y }, + pending: PhantomData, + }); + async {}.await; + drop(_x); + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr new file mode 100644 index 00000000000..6fcf1b1eac1 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-10.assumptions.stderr @@ -0,0 +1,21 @@ +error: implementation of `Foo` is not general enough + --> $DIR/higher-ranked-auto-trait-10.rs:32:5 + | +LL | Box::new(async move { get_foo(x).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2` + +error: implementation of `Foo` is not general enough + --> $DIR/higher-ranked-auto-trait-10.rs:32:5 + | +LL | Box::new(async move { get_foo(x).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr new file mode 100644 index 00000000000..6fcf1b1eac1 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-10.no_assumptions.stderr @@ -0,0 +1,21 @@ +error: implementation of `Foo` is not general enough + --> $DIR/higher-ranked-auto-trait-10.rs:32:5 + | +LL | Box::new(async move { get_foo(x).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2` + +error: implementation of `Foo` is not general enough + --> $DIR/higher-ranked-auto-trait-10.rs:32:5 + | +LL | Box::new(async move { get_foo(x).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'1>` would have to be implemented for the type `&'0 str`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo<'2>` is actually implemented for the type `&'2 str`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-10.rs b/tests/ui/async-await/higher-ranked-auto-trait-10.rs new file mode 100644 index 00000000000..4bfa27961ab --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-10.rs @@ -0,0 +1,35 @@ +// Repro for <https://github.com/rust-lang/rust/issues/92415#issue-1090723521>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] known-bug: unknown +//@[no_assumptions] known-bug: #110338 + +use std::any::Any; +use std::future::Future; + +trait Foo<'a>: Sized { + type Error; + fn foo(x: &'a str) -> Result<Self, Self::Error>; +} + +impl<'a> Foo<'a> for &'a str { + type Error = (); + + fn foo(x: &'a str) -> Result<Self, Self::Error> { + Ok(x) + } +} + +async fn get_foo<'a, T>(x: &'a str) -> Result<T, <T as Foo<'a>>::Error> +where + T: Foo<'a>, +{ + Foo::foo(x) +} + +fn bar<'a>(x: &'a str) -> Box<dyn Future<Output = Result<&'a str, ()>> + Send + 'a> { + Box::new(async move { get_foo(x).await }) +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr new file mode 100644 index 00000000000..d39843f628c --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-11.assumptions.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/higher-ranked-auto-trait-11.rs:27:9 + | +LL | impl<'a, T> Foo<'a> for MyType<T> + | -- lifetime `'a` defined here +... +LL | Box::pin(async move { <T as Foo<'a>>::foo().await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'a` must outlive `'static` + +error: implementation of `Send` is not general enough + --> $DIR/higher-ranked-auto-trait-11.rs:27:9 + | +LL | Box::pin(async move { <T as Foo<'a>>::foo().await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Send` is not general enough + | + = note: `Send` would have to be implemented for the type `<T as Foo<'0>>::Future`, for any lifetime `'0`... + = note: ...but `Send` is actually implemented for the type `<T as Foo<'1>>::Future`, for some specific lifetime `'1` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr new file mode 100644 index 00000000000..d39843f628c --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-11.no_assumptions.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/higher-ranked-auto-trait-11.rs:27:9 + | +LL | impl<'a, T> Foo<'a> for MyType<T> + | -- lifetime `'a` defined here +... +LL | Box::pin(async move { <T as Foo<'a>>::foo().await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ coercion requires that `'a` must outlive `'static` + +error: implementation of `Send` is not general enough + --> $DIR/higher-ranked-auto-trait-11.rs:27:9 + | +LL | Box::pin(async move { <T as Foo<'a>>::foo().await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Send` is not general enough + | + = note: `Send` would have to be implemented for the type `<T as Foo<'0>>::Future`, for any lifetime `'0`... + = note: ...but `Send` is actually implemented for the type `<T as Foo<'1>>::Future`, for some specific lifetime `'1` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-11.rs b/tests/ui/async-await/higher-ranked-auto-trait-11.rs new file mode 100644 index 00000000000..3aebdd8224d --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-11.rs @@ -0,0 +1,31 @@ +// Repro for <https://github.com/rust-lang/rust/issues/60658#issuecomment-1509321859>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] known-bug: unknown +//@[no_assumptions] known-bug: #110338 + +use core::pin::Pin; +use std::future::Future; + +pub trait Foo<'a> { + type Future: Future<Output = ()>; + + fn foo() -> Self::Future; +} + +struct MyType<T>(T); + +impl<'a, T> Foo<'a> for MyType<T> +where + T: Foo<'a>, + T::Future: Send, +{ + type Future = Pin<Box<dyn Future<Output = ()> + Send + 'a>>; + + fn foo() -> Self::Future { + Box::pin(async move { <T as Foo<'a>>::foo().await }) + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr new file mode 100644 index 00000000000..63e71cbc40c --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-12.no_assumptions.stderr @@ -0,0 +1,18 @@ +error: implementation of `Robot` is not general enough + --> $DIR/higher-ranked-auto-trait-12.rs:31:20 + | +LL | let _my_task = this_is_send(async move { + | ____________________^ +LL | | let _my_iter = IRobot { +LL | | id: 32, +LL | | robot: source, +LL | | }; +LL | | yield_now().await; +LL | | }); + | |______^ implementation of `Robot` is not general enough + | + = note: `Box<(dyn Robot<Id = u32> + Send + '0)>` must implement `Robot`, for any lifetime `'0`... + = note: ...but `Robot` is actually implemented for the type `Box<(dyn Robot<Id = u32> + Send + 'static)>` + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-12.rs b/tests/ui/async-await/higher-ranked-auto-trait-12.rs new file mode 100644 index 00000000000..b1cca5cbb00 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-12.rs @@ -0,0 +1,40 @@ +// Repro for <https://github.com/rust-lang/rust/issues/71671#issuecomment-848994782>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +pub trait Robot { + type Id; +} + +pub type DynRobot = Box<dyn Robot<Id = u32> + Send>; + +impl Robot for DynRobot { + type Id = u32; +} + +struct IRobot<R: Robot> { + id: R::Id, + robot: R, +} + +// stand-in for tokio::spawn +fn this_is_send<T: Send>(value: T) -> T { + value +} + +async fn yield_now() {} + +fn test(source: DynRobot) { + let _my_task = this_is_send(async move { + let _my_iter = IRobot { + id: 32, + robot: source, + }; + yield_now().await; + }); +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr new file mode 100644 index 00000000000..f69218740dc --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-13.assumptions.stderr @@ -0,0 +1,41 @@ +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr new file mode 100644 index 00000000000..cfbdaa8ad4b --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-13.no_assumptions.stderr @@ -0,0 +1,60 @@ +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: implementation of `Callable` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Callable` is not general enough + | + = note: `Callable<'_>` would have to be implemented for the type `ConstructableImpl<'0>`, for any lifetime `'0`... + = note: ...but `Callable<'1>` is actually implemented for the type `ConstructableImpl<'1>`, for some specific lifetime `'1` + +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: implementation of `Getter` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Getter` is not general enough + | + = note: `Getter<'1>` would have to be implemented for the type `GetterImpl<'0, ConstructableImpl<'_>>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Getter<'2>` is actually implemented for the type `GetterImpl<'2, ConstructableImpl<'_>>`, for some specific lifetime `'2` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: implementation of `Callable` is not general enough + --> $DIR/higher-ranked-auto-trait-13.rs:65:5 + | +LL | assert_send(my_send_async_method(struct_with_lifetime, data)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Callable` is not general enough + | + = note: `Callable<'_>` would have to be implemented for the type `ConstructableImpl<'0>`, for any lifetime `'0`... + = note: ...but `Callable<'1>` is actually implemented for the type `ConstructableImpl<'1>`, for some specific lifetime `'1` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-13.rs b/tests/ui/async-await/higher-ranked-auto-trait-13.rs new file mode 100644 index 00000000000..4bce0f5197f --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-13.rs @@ -0,0 +1,68 @@ +// Repro for <https://github.com/rust-lang/rust/issues/114046#issue-1819720359>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] known-bug: unknown +//@[no_assumptions] known-bug: #110338 + +use std::marker::PhantomData; + +trait Callable<'a>: Send + Sync { + fn callable(data: &'a [u8]); +} + +trait Getter<'a>: Send + Sync { + type ItemSize: Send + Sync; + + fn get(data: &'a [u8]); +} + +struct List<'a, A: Getter<'a>> { + data: &'a [u8], + item_size: A::ItemSize, // Removing this member causes the code to compile + phantom: PhantomData<A>, +} + +struct GetterImpl<'a, T: Callable<'a> + 'a> { + p: PhantomData<&'a T>, +} + +impl<'a, T: Callable<'a> + 'a> Getter<'a> for GetterImpl<'a, T> { + type ItemSize = (); + + fn get(data: &'a [u8]) { + <T>::callable(data); + } +} + +struct ConstructableImpl<'a> { + _data: &'a [u8], +} + +impl<'a> Callable<'a> for ConstructableImpl<'a> { + fn callable(_: &'a [u8]) {} +} + +struct StructWithLifetime<'a> { + marker: &'a PhantomData<u8>, +} + +async fn async_method() {} + +fn assert_send(_: impl Send + Sync) {} + +// This async method ought to be send, but is not +async fn my_send_async_method(_struct_with_lifetime: &mut StructWithLifetime<'_>, data: &Vec<u8>) { + let _named = + List::<'_, GetterImpl<ConstructableImpl<'_>>> { data, item_size: (), phantom: PhantomData }; + // Moving the await point above the constructed of _named, causes + // the method to become send, even though _named is Send + Sync + async_method().await; + assert_send(_named); +} + +fn dummy(struct_with_lifetime: &mut StructWithLifetime<'_>, data: &Vec<u8>) { + assert_send(my_send_async_method(struct_with_lifetime, data)); +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr new file mode 100644 index 00000000000..b47db2b19ff --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr @@ -0,0 +1,33 @@ +error: implementation of `FnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-14.rs:20:5 + | +LL | / async move { +LL | | let xs = unique_x.union(&cached) +LL | | // .copied() // works +LL | | .map(|x| *x) // error +LL | | ; +LL | | let blah = val.blah(xs.into_iter()).await; +LL | | } + | |_____^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `FnOnce<(&u32,)>` + +error: implementation of `FnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-14.rs:20:5 + | +LL | / async move { +LL | | let xs = unique_x.union(&cached) +LL | | // .copied() // works +LL | | .map(|x| *x) // error +LL | | ; +LL | | let blah = val.blah(xs.into_iter()).await; +LL | | } + | |_____^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `FnOnce<(&u32,)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-14.rs b/tests/ui/async-await/higher-ranked-auto-trait-14.rs new file mode 100644 index 00000000000..5ed12cd6e38 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-14.rs @@ -0,0 +1,29 @@ +// Repro for <https://github.com/rust-lang/rust/issues/124757#issue-2279603232>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::collections::HashSet; +use std::future::Future; + +trait MyTrait { + fn blah(&self, x: impl Iterator<Item = u32>) -> impl Future<Output = ()> + Send; +} + +fn foo<T: MyTrait + Send + Sync>( + val: T, + unique_x: HashSet<u32>, +) -> impl Future<Output = ()> + Send { + let cached = HashSet::new(); + async move { + let xs = unique_x.union(&cached) + // .copied() // works + .map(|x| *x) // error + ; + let blah = val.blah(xs.into_iter()).await; + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr new file mode 100644 index 00000000000..b4f3570d9f2 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-15.no_assumptions.stderr @@ -0,0 +1,21 @@ +error: implementation of `FnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-15.rs:20:5 + | +LL | require_send(future); + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'0 Vec<i32>) -> std::slice::Iter<'_, i32>` must implement `FnOnce<(&'1 Vec<i32>,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `FnOnce<(&Vec<i32>,)>` + +error: implementation of `FnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-15.rs:20:5 + | +LL | require_send(future); + | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'0 Vec<i32>) -> std::slice::Iter<'_, i32>` must implement `FnOnce<(&'1 Vec<i32>,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `FnOnce<(&Vec<i32>,)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-15.rs b/tests/ui/async-await/higher-ranked-auto-trait-15.rs new file mode 100644 index 00000000000..153fcac4c3a --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-15.rs @@ -0,0 +1,21 @@ +// Repro for <https://github.com/rust-lang/rust/issues/126044#issuecomment-2154313449>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +async fn listen() { + let things: Vec<Vec<i32>> = vec![]; + for _ in things.iter().map(|n| n.iter()).flatten() { + // comment this line and everything compiles + async {}.await; + } +} + +fn require_send<T: Send>(_x: T) {} + +fn main() { + let future = listen(); + require_send(future); +} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr new file mode 100644 index 00000000000..412c31b1bd8 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-16.assumptions.stderr @@ -0,0 +1,25 @@ +error: implementation of `AsyncFnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-16.rs:18:5 + | +LL | / assert_send(async { +LL | | commit_if_ok(&mut ctxt, async |_| todo!()).await; +LL | | }); + | |______^ implementation of `AsyncFnOnce` is not general enough + | + = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>` + +error: implementation of `AsyncFnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-16.rs:18:5 + | +LL | / assert_send(async { +LL | | commit_if_ok(&mut ctxt, async |_| todo!()).await; +LL | | }); + | |______^ implementation of `AsyncFnOnce` is not general enough + | + = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr new file mode 100644 index 00000000000..412c31b1bd8 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-16.no_assumptions.stderr @@ -0,0 +1,25 @@ +error: implementation of `AsyncFnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-16.rs:18:5 + | +LL | / assert_send(async { +LL | | commit_if_ok(&mut ctxt, async |_| todo!()).await; +LL | | }); + | |______^ implementation of `AsyncFnOnce` is not general enough + | + = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>` + +error: implementation of `AsyncFnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-16.rs:18:5 + | +LL | / assert_send(async { +LL | | commit_if_ok(&mut ctxt, async |_| todo!()).await; +LL | | }); + | |______^ implementation of `AsyncFnOnce` is not general enough + | + = note: `{async closure@$DIR/higher-ranked-auto-trait-16.rs:19:33: 19:42}` must implement `AsyncFnOnce<(&mut Ctxt<'1>,)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `AsyncFnOnce<(&mut Ctxt<'_>,)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-16.rs b/tests/ui/async-await/higher-ranked-auto-trait-16.rs new file mode 100644 index 00000000000..2b206f0a4c5 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-16.rs @@ -0,0 +1,23 @@ +// Repro for <https://github.com/rust-lang/rust/issues/126350#issue-2349492101>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] known-bug: unknown +//@[no_assumptions] known-bug: #110338 + +fn assert_send<T: Send>(_: T) {} + +#[derive(Clone)] +struct Ctxt<'a>(&'a ()); + +async fn commit_if_ok<'a>(ctxt: &mut Ctxt<'a>, f: impl AsyncFnOnce(&mut Ctxt<'a>)) { + f(&mut ctxt.clone()).await; +} + +fn operation(mut ctxt: Ctxt<'_>) { + assert_send(async { + commit_if_ok(&mut ctxt, async |_| todo!()).await; + }); +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr new file mode 100644 index 00000000000..152900ca1ae --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-17.no_assumptions.stderr @@ -0,0 +1,29 @@ +error: implementation of `FnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-17.rs:12:5 + | +LL | / async move { +LL | | let iter = Adaptor::new(a.iter().map(|_: &()| {})); +LL | | std::future::pending::<()>().await; +LL | | drop(iter); +LL | | } + | |_____^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'0 ())` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `FnOnce<(&(),)>` + +error: implementation of `FnOnce` is not general enough + --> $DIR/higher-ranked-auto-trait-17.rs:12:5 + | +LL | / async move { +LL | | let iter = Adaptor::new(a.iter().map(|_: &()| {})); +LL | | std::future::pending::<()>().await; +LL | | drop(iter); +LL | | } + | |_____^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'0 ())` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `FnOnce<(&(),)>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-17.rs b/tests/ui/async-await/higher-ranked-auto-trait-17.rs new file mode 100644 index 00000000000..152432466c0 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-17.rs @@ -0,0 +1,30 @@ +// Repro for <https://github.com/rust-lang/rust/issues/114177#issue-1826550174>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +// Using `impl Future` instead of `async to ensure that the Future is Send. +// +// In the original code `a` would be `&[T]`. For more minimization I've removed the reference. +fn foo(a: [(); 0]) -> impl std::future::Future<Output = ()> + Send { + async move { + let iter = Adaptor::new(a.iter().map(|_: &()| {})); + std::future::pending::<()>().await; + drop(iter); + } +} + +struct Adaptor<T: Iterator> { + iter: T, + v: T::Item, +} + +impl<T: Iterator> Adaptor<T> { + pub fn new(_: T) -> Self { + Self { iter: todo!(), v: todo!() } + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr new file mode 100644 index 00000000000..2fc44412b9d --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr @@ -0,0 +1,49 @@ +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-2.rs:16:9 + | +LL | / async move { +LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics +LL | | self.run(t).await; +LL | | } + | |_________^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-2.rs:16:9 + | +LL | / async move { +LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics +LL | | self.run(t).await; +LL | | } + | |_________^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-2.rs:16:9 + | +LL | / async move { +LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics +LL | | self.run(t).await; +LL | | } + | |_________^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-2.rs:16:9 + | +LL | / async move { +LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics +LL | | self.run(t).await; +LL | | } + | |_________^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-2.rs b/tests/ui/async-await/higher-ranked-auto-trait-2.rs new file mode 100644 index 00000000000..6c75597265b --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-2.rs @@ -0,0 +1,23 @@ +// Repro for <https://github.com/rust-lang/rust/issues/111105#issue-1692860759>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::future::Future; + +pub trait Foo: Sync { + fn run<'a, 'b: 'a, T: Sync>(&'a self, _: &'b T) -> impl Future<Output = ()> + 'a + Send; +} + +pub trait FooExt: Foo { + fn run_via<'a, 'b: 'a, T: Sync>(&'a self, t: &'b T) -> impl Future<Output = ()> + 'a + Send { + async move { + // asks for an unspecified lifetime to outlive itself? weird diagnostics + self.run(t).await; + } + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr new file mode 100644 index 00000000000..c5c98ac807e --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr @@ -0,0 +1,12 @@ +error: lifetime bound not satisfied + --> $DIR/higher-ranked-auto-trait-3.rs:66:9 + | +LL | / async { +LL | | self.fi_2.get_iter(cx).await; +LL | | } + | |_________^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.rs b/tests/ui/async-await/higher-ranked-auto-trait-3.rs new file mode 100644 index 00000000000..d42d4236680 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-3.rs @@ -0,0 +1,72 @@ +// Repro for <https://github.com/rust-lang/rust/issues/100013#issue-1323807923>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +#![feature(impl_trait_in_assoc_type)] + +use std::future::Future; + +pub trait FutureIterator: 'static { + type Iterator; + + type Future<'s, 'cx>: Future<Output = Self::Iterator> + Send + 'cx + where + 's: 'cx; + + fn get_iter<'s, 'cx>(&'s self, info: &'cx ()) -> Self::Future<'s, 'cx>; +} + +trait IterCaller: 'static { + type Future1<'cx>: Future<Output = ()> + Send + 'cx; + type Future2<'cx>: Future<Output = ()> + Send + 'cx; + + fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx> + where + 's: 'cx; + fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx> + where + 's: 'cx; +} + +struct UseIter<FI1, FI2> { + fi_1: FI1, + fi_2: FI2, +} + +impl<FI1, FI2> IterCaller for UseIter<FI1, FI2> +where + FI1: FutureIterator + 'static + Send + Sync, + for<'s, 'cx> FI1::Future<'s, 'cx>: Send, + FI2: FutureIterator + 'static + Send + Sync, +{ + type Future1<'cx> = impl Future<Output = ()> + Send + 'cx + where + Self: 'cx; + + type Future2<'cx> = impl Future<Output = ()> + Send + 'cx + where + Self: 'cx; + + fn call_1<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future1<'cx> + where + 's: 'cx, + { + async { + self.fi_1.get_iter(cx).await; + } + } + + fn call_2<'s, 'cx>(&'s self, cx: &'cx ()) -> Self::Future2<'cx> + where + 's: 'cx, + { + async { + self.fi_2.get_iter(cx).await; + } + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr new file mode 100644 index 00000000000..5aa5b83655a --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-4.no_assumptions.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/higher-ranked-auto-trait-4.rs:29:5 + | +LL | / async { +LL | | let _ = evil_function::<dyn BoringTrait, _>().await; +LL | | } + | |_____^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-4.rs b/tests/ui/async-await/higher-ranked-auto-trait-4.rs new file mode 100644 index 00000000000..0586af41e9e --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-4.rs @@ -0,0 +1,34 @@ +// Repro for <https://github.com/rust-lang/rust/issues/102211#issuecomment-2891975128>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::future::Future; + +trait BoringTrait {} + +trait TraitWithAssocType<I> { + type Assoc; +} + +impl<T> TraitWithAssocType<()> for T +where + T: ?Sized + 'static, +{ + type Assoc = (); +} + +fn evil_function<T: TraitWithAssocType<I> + ?Sized, I>() +-> impl Future<Output = Result<(), T::Assoc>> { + async { Ok(()) } +} + +fn fails_to_compile() -> impl std::future::Future<Output = ()> + Send { + async { + let _ = evil_function::<dyn BoringTrait, _>().await; + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr new file mode 100644 index 00000000000..8fa3c7483c8 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-5.no_assumptions.stderr @@ -0,0 +1,13 @@ +error: implementation of `Send` is not general enough + --> $DIR/higher-ranked-auto-trait-5.rs:13:5 + | +LL | / assert_send(async { +LL | | call_me.call().await; +LL | | }); + | |______^ implementation of `Send` is not general enough + | + = note: `Send` would have to be implemented for the type `&'0 str`, for any lifetime `'0`... + = note: ...but `Send` is actually implemented for the type `&'1 str`, for some specific lifetime `'1` + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-5.rs b/tests/ui/async-await/higher-ranked-auto-trait-5.rs new file mode 100644 index 00000000000..9a8b3f4357c --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-5.rs @@ -0,0 +1,54 @@ +// Repro for <https://github.com/rust-lang/rust/issues/130113#issue-2512517191>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::future::Future; + +fn main() { + let call_me = Wrap(CallMeImpl { value: "test" }); + + assert_send(async { + call_me.call().await; + }); +} + +pub fn assert_send<F>(_future: F) +where + F: Future + Send, +{ +} + +pub trait CallMe { + fn call(&self) -> impl Future<Output = ()> + Send; +} + +struct Wrap<T>(T); + +impl<S> CallMe for Wrap<S> +where + S: CallMe + Send, +{ + // adding `+ Send` to this RPIT fixes the issue + fn call(&self) -> impl Future<Output = ()> { + self.0.call() + } +} + +#[derive(Debug, Clone, Copy)] +pub struct CallMeImpl<T> { + value: T, +} + +impl<T> CallMe for CallMeImpl<T> +where + // Can replace `Send` by `ToString`, `Clone`, whatever. When removing the + // `Send` bound, the compiler produces a higher-ranked lifetime error. + T: Send + 'static, +{ + fn call(&self) -> impl Future<Output = ()> { + async {} + } +} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr new file mode 100644 index 00000000000..d1f2d9a0753 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-6.no_assumptions.stderr @@ -0,0 +1,50 @@ +error[E0308]: mismatched types + --> $DIR/higher-ranked-auto-trait-6.rs:16:5 + | +LL | Box::new(async { new(|| async { f().await }).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object + +error[E0308]: mismatched types + --> $DIR/higher-ranked-auto-trait-6.rs:16:5 + | +LL | Box::new(async { new(|| async { f().await }).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0308]: mismatched types + --> $DIR/higher-ranked-auto-trait-6.rs:16:5 + | +LL | Box::new(async { new(|| async { f().await }).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0308]: mismatched types + --> $DIR/higher-ranked-auto-trait-6.rs:16:5 + | +LL | Box::new(async { new(|| async { f().await }).await }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + found `async` block `{async block@$DIR/higher-ranked-auto-trait-6.rs:16:29: 16:34}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/higher-ranked-auto-trait-6.rs b/tests/ui/async-await/higher-ranked-auto-trait-6.rs new file mode 100644 index 00000000000..2c6adf8938d --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-6.rs @@ -0,0 +1,59 @@ +// Repro for <https://github.com/rust-lang/rust/issues/82921#issue-825114180>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use core::future::Future; +use core::marker::PhantomData; +use core::pin::Pin; +use core::task::{Context, Poll}; + +async fn f() {} + +pub fn fail<'a>() -> Box<dyn Future<Output = ()> + Send + 'a> { + Box::new(async { new(|| async { f().await }).await }) +} + +fn new<A, B>(_a: A) -> F<A, B> +where + A: Fn() -> B, +{ + F { _i: PhantomData } +} + +trait Stream { + type Item; +} + +struct T<A, B> { + _a: PhantomData<A>, + _b: PhantomData<B>, +} + +impl<A, B> Stream for T<A, B> +where + A: Fn() -> B, +{ + type Item = B; +} + +struct F<A, B> +where + A: Fn() -> B, +{ + _i: PhantomData<<T<A, B> as Stream>::Item>, +} + +impl<A, B> Future for F<A, B> +where + A: Fn() -> B, +{ + type Output = (); + fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> { + unimplemented!() + } +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr new file mode 100644 index 00000000000..dcb8075566e --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr @@ -0,0 +1,8 @@ +error: `S` does not live long enough + --> $DIR/higher-ranked-auto-trait-7.rs:26:5 + | +LL | future::<'a, S, _>(async move { + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-7.rs b/tests/ui/async-await/higher-ranked-auto-trait-7.rs new file mode 100644 index 00000000000..abded5a88d3 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-7.rs @@ -0,0 +1,33 @@ +// Repro for <https://github.com/rust-lang/rust/issues/90696#issuecomment-963375847>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +#![allow(dropping_copy_types)] + +use std::{future::Future, marker::PhantomData}; + +trait Trait { + type Associated<'a>: Send + where + Self: 'a; +} + +fn future<'a, S: Trait + 'a, F>(f: F) -> F +where + F: Future<Output = ()> + Send, +{ + f +} + +fn foo<'a, S: Trait + 'a>() { + future::<'a, S, _>(async move { + let result: PhantomData<S::Associated<'a>> = PhantomData; + async {}.await; + drop(result); + }); +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr new file mode 100644 index 00000000000..6208675117b --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-8.no_assumptions.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/higher-ranked-auto-trait-8.rs:26:5 + | +LL | needs_send(use_my_struct(second_struct)); // ERROR + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: could not prove `impl Future<Output = ()>: Send` + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-8.rs b/tests/ui/async-await/higher-ranked-auto-trait-8.rs new file mode 100644 index 00000000000..91cef204e44 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-8.rs @@ -0,0 +1,27 @@ +// Repro for <https://github.com/rust-lang/rust/issues/64552#issuecomment-532801232>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +fn needs_send<T: Send>(_val: T) {} +async fn use_async<T>(_val: T) {} + +struct MyStruct<'a, T: 'a> { + val: &'a T, +} + +unsafe impl<'a, T: 'a> Send for MyStruct<'a, T> {} + +async fn use_my_struct(val: MyStruct<'static, &'static u8>) { + use_async(val).await; +} + +fn main() { + let first_struct: MyStruct<'static, &'static u8> = MyStruct { val: &&26 }; + let second_struct: MyStruct<'static, &'static u8> = MyStruct { val: &&27 }; + + needs_send(first_struct); + needs_send(use_my_struct(second_struct)); // ERROR +} diff --git a/tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr new file mode 100644 index 00000000000..809cbcf0cad --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-9.no_assumptions.stderr @@ -0,0 +1,11 @@ +error: implementation of `Debug` is not general enough + --> $DIR/higher-ranked-auto-trait-9.rs:43:50 + | +LL | let fut: &(dyn Future<Output = ()> + Send) = &fut as _; + | ^^^^^^^^^ implementation of `Debug` is not general enough + | + = note: `(dyn Any + '0)` must implement `Debug`, for any lifetime `'0`... + = note: ...but `Debug` is actually implemented for the type `(dyn Any + 'static)` + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/higher-ranked-auto-trait-9.rs b/tests/ui/async-await/higher-ranked-auto-trait-9.rs new file mode 100644 index 00000000000..66edbf23f2b --- /dev/null +++ b/tests/ui/async-await/higher-ranked-auto-trait-9.rs @@ -0,0 +1,44 @@ +// Repro for <https://github.com/rust-lang/rust/issues/87425#issue-952059416>. +//@ edition: 2021 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::any::Any; +use std::fmt; +use std::future::Future; + +pub trait Foo { + type Item; +} + +impl<F, I> Foo for F +where + Self: FnOnce() -> I, + I: fmt::Debug, +{ + type Item = I; +} + +async fn foo_item<F: Foo>(_: F) -> F::Item { + unimplemented!() +} + +fn main() { + let fut = async { + let callback = || -> Box<dyn Any> { unimplemented!() }; + + // Using plain fn instead of a closure fixes the error, + // though you obviously can't capture any state... + // fn callback() -> Box<dyn Any> { + // todo!() + // } + + foo_item(callback).await; + }; + + // Removing `+ Send` bound also fixes the error, + // though at the cost of loosing `Send`ability... + let fut: &(dyn Future<Output = ()> + Send) = &fut as _; +} diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.no_assumptions.stderr index d6c3bd12aee..bb436364924 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.no_assumptions.stderr @@ -1,5 +1,5 @@ error: implementation of `Send` is not general enough - --> $DIR/issue-110963-early.rs:14:5 + --> $DIR/issue-110963-early.rs:17:5 | LL | / spawn(async move { LL | | let mut hc = hc; @@ -13,7 +13,7 @@ LL | | }); = note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>(..) }`, for some specific lifetime `'2` error: implementation of `Send` is not general enough - --> $DIR/issue-110963-early.rs:14:5 + --> $DIR/issue-110963-early.rs:17:5 | LL | / spawn(async move { LL | | let mut hc = hc; diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.rs b/tests/ui/async-await/return-type-notation/issue-110963-early.rs index 46b8fbf6f86..8c3180c0119 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.rs +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.rs @@ -1,5 +1,8 @@ //@ edition: 2021 -//@ known-bug: #110963 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 #![feature(return_type_notation)] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 56f2be353e7..0d0c338d302 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -37,19 +37,6 @@ error: malformed `crate_name` attribute input LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` -error: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:90:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL | #[coverage(off)] - | +++++ -LL | #[coverage(on)] - | ++++ - error: malformed `no_sanitize` attribute input --> $DIR/malformed-attrs.rs:92:1 | @@ -460,6 +447,19 @@ error[E0539]: malformed `link_section` attribute input LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` +error[E0539]: malformed `coverage` attribute input + --> $DIR/malformed-attrs.rs:90:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument + | +help: try changing it to one of the following valid forms of the attribute + | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ + error[E0565]: malformed `no_implicit_prelude` attribute input --> $DIR/malformed-attrs.rs:97:1 | diff --git a/tests/ui/attributes/positions/used.stderr b/tests/ui/attributes/positions/used.stderr index 96dd43a3a93..64460c178cb 100644 --- a/tests/ui/attributes/positions/used.stderr +++ b/tests/ui/attributes/positions/used.stderr @@ -28,7 +28,7 @@ error: attribute must be applied to a `static` variable LL | #[used] | ^^^^^^^ LL | impl Bar for Foo {} - | ------------------- but this is a implementation block + | ------------------- but this is a trait implementation block error: attribute must be applied to a `static` variable --> $DIR/used.rs:21:5 diff --git a/tests/ui/cast/cast-char.rs b/tests/ui/cast/cast-char.rs index 9634ed56f7b..5bf05072253 100644 --- a/tests/ui/cast/cast-char.rs +++ b/tests/ui/cast/cast-char.rs @@ -1,10 +1,58 @@ #![deny(overflowing_literals)] fn main() { - const XYZ: char = 0x1F888 as char; + // Valid cases - should suggest char literal + + // u8 range (0-255) + const VALID_U8_1: char = 0x41 as char; // 'A' + const VALID_U8_2: char = 0xFF as char; // maximum u8 + const VALID_U8_3: char = 0x00 as char; // minimum u8 + + // Valid Unicode in lower range [0x0, 0xD7FF] + const VALID_LOW_1: char = 0x1000 as char; // 4096 + //~^ ERROR: only `u8` can be cast into `char` + const VALID_LOW_2: char = 0xD7FF as char; // last valid in lower range + //~^ ERROR: only `u8` can be cast into `char` + const VALID_LOW_3: char = 0x0500 as char; // cyrillic range + //~^ ERROR: only `u8` can be cast into `char` + + // Valid Unicode in upper range [0xE000, 0x10FFFF] + const VALID_HIGH_1: char = 0xE000 as char; // first valid in upper range + //~^ ERROR only `u8` can be cast into `char` + const VALID_HIGH_2: char = 0x1F888 as char; // 129160 - example from issue + //~^ ERROR only `u8` can be cast into `char` + const VALID_HIGH_3: char = 0x10FFFF as char; // maximum valid Unicode + //~^ ERROR only `u8` can be cast into `char` + const VALID_HIGH_4: char = 0xFFFD as char; // replacement character + //~^ ERROR only `u8` can be cast into `char` + const VALID_HIGH_5: char = 0x1F600 as char; // emoji + //~^ ERROR only `u8` can be cast into `char` + + // Invalid cases - should show InvalidCharCast + + // Surrogate range [0xD800, 0xDFFF] - reserved for UTF-16 + const INVALID_SURROGATE_1: char = 0xD800 as char; // first surrogate + //~^ ERROR: surrogate values are not valid + const INVALID_SURROGATE_2: char = 0xDFFF as char; // last surrogate + //~^ ERROR: surrogate values are not valid + const INVALID_SURROGATE_3: char = 0xDB00 as char; // middle of surrogate range + //~^ ERROR: surrogate values are not valid + + // Too large values (> 0x10FFFF) + const INVALID_TOO_BIG_1: char = 0x110000 as char; // one more than maximum + //~^ ERROR: value exceeds maximum `char` value + const INVALID_TOO_BIG_2: char = 0xEF8888 as char; // example from issue + //~^ ERROR: value exceeds maximum `char` value + const INVALID_TOO_BIG_3: char = 0x1FFFFF as char; // much larger + //~^ ERROR: value exceeds maximum `char` value + const INVALID_TOO_BIG_4: char = 0xFFFFFF as char; // 24-bit maximum + //~^ ERROR: value exceeds maximum `char` value + + // Boundary cases + const BOUNDARY_1: char = 0xD7FE as char; // valid, before surrogate + //~^ ERROR only `u8` can be cast into `char` + const BOUNDARY_2: char = 0xE001 as char; // valid, after surrogate //~^ ERROR only `u8` can be cast into `char` - const XY: char = 129160 as char; + const BOUNDARY_3: char = 0x10FFFE as char; // valid, near maximum //~^ ERROR only `u8` can be cast into `char` - const ZYX: char = '\u{01F888}'; - println!("{}", XYZ); } diff --git a/tests/ui/cast/cast-char.stderr b/tests/ui/cast/cast-char.stderr index 211937c9d6f..a8d0b3b04b0 100644 --- a/tests/ui/cast/cast-char.stderr +++ b/tests/ui/cast/cast-char.stderr @@ -1,8 +1,8 @@ error: only `u8` can be cast into `char` - --> $DIR/cast-char.rs:4:23 + --> $DIR/cast-char.rs:12:31 | -LL | const XYZ: char = 0x1F888 as char; - | ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'` +LL | const VALID_LOW_1: char = 0x1000 as char; // 4096 + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1000}'` | note: the lint level is defined here --> $DIR/cast-char.rs:1:9 @@ -11,10 +11,120 @@ LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ error: only `u8` can be cast into `char` - --> $DIR/cast-char.rs:6:22 + --> $DIR/cast-char.rs:14:31 | -LL | const XY: char = 129160 as char; - | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'` +LL | const VALID_LOW_2: char = 0xD7FF as char; // last valid in lower range + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{D7FF}'` -error: aborting due to 2 previous errors +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:16:31 + | +LL | const VALID_LOW_3: char = 0x0500 as char; // cyrillic range + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{500}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:20:32 + | +LL | const VALID_HIGH_1: char = 0xE000 as char; // first valid in upper range + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{E000}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:22:32 + | +LL | const VALID_HIGH_2: char = 0x1F888 as char; // 129160 - example from issue + | ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:24:32 + | +LL | const VALID_HIGH_3: char = 0x10FFFF as char; // maximum valid Unicode + | ^^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{10FFFF}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:26:32 + | +LL | const VALID_HIGH_4: char = 0xFFFD as char; // replacement character + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{FFFD}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:28:32 + | +LL | const VALID_HIGH_5: char = 0x1F600 as char; // emoji + | ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F600}'` + +error: surrogate values are not valid for `char` + --> $DIR/cast-char.rs:34:39 + | +LL | const INVALID_SURROGATE_1: char = 0xD800 as char; // first surrogate + | ^^^^^^^^^^^^^^ + | + = note: `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values + +error: surrogate values are not valid for `char` + --> $DIR/cast-char.rs:36:39 + | +LL | const INVALID_SURROGATE_2: char = 0xDFFF as char; // last surrogate + | ^^^^^^^^^^^^^^ + | + = note: `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values + +error: surrogate values are not valid for `char` + --> $DIR/cast-char.rs:38:39 + | +LL | const INVALID_SURROGATE_3: char = 0xDB00 as char; // middle of surrogate range + | ^^^^^^^^^^^^^^ + | + = note: `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values + +error: value exceeds maximum `char` value + --> $DIR/cast-char.rs:42:37 + | +LL | const INVALID_TOO_BIG_1: char = 0x110000 as char; // one more than maximum + | ^^^^^^^^^^^^^^^^ + | + = note: maximum valid `char` value is `0x10FFFF` + +error: value exceeds maximum `char` value + --> $DIR/cast-char.rs:44:37 + | +LL | const INVALID_TOO_BIG_2: char = 0xEF8888 as char; // example from issue + | ^^^^^^^^^^^^^^^^ + | + = note: maximum valid `char` value is `0x10FFFF` + +error: value exceeds maximum `char` value + --> $DIR/cast-char.rs:46:37 + | +LL | const INVALID_TOO_BIG_3: char = 0x1FFFFF as char; // much larger + | ^^^^^^^^^^^^^^^^ + | + = note: maximum valid `char` value is `0x10FFFF` + +error: value exceeds maximum `char` value + --> $DIR/cast-char.rs:48:37 + | +LL | const INVALID_TOO_BIG_4: char = 0xFFFFFF as char; // 24-bit maximum + | ^^^^^^^^^^^^^^^^ + | + = note: maximum valid `char` value is `0x10FFFF` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:52:30 + | +LL | const BOUNDARY_1: char = 0xD7FE as char; // valid, before surrogate + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{D7FE}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:54:30 + | +LL | const BOUNDARY_2: char = 0xE001 as char; // valid, after surrogate + | ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{E001}'` + +error: only `u8` can be cast into `char` + --> $DIR/cast-char.rs:56:30 + | +LL | const BOUNDARY_3: char = 0x10FFFE as char; // valid, near maximum + | ^^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{10FFFE}'` + +error: aborting due to 18 previous errors diff --git a/tests/ui/cfg/crt-static-with-target-features-works.rs b/tests/ui/cfg/crt-static-with-target-features-works.rs new file mode 100644 index 00000000000..bce02229624 --- /dev/null +++ b/tests/ui/cfg/crt-static-with-target-features-works.rs @@ -0,0 +1,24 @@ +// Test to ensure that specifying a value for crt-static in target features +// does not result in skipping the features following it. +// This is a regression test for #144143 + +//@ add-core-stubs +//@ needs-llvm-components: x86 +//@ compile-flags: --target=x86_64-unknown-linux-gnu +//@ compile-flags: -Ctarget-feature=+crt-static,+avx2 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[rustc_builtin_macro] +macro_rules! compile_error { + () => {}; +} + +#[cfg(target_feature = "avx2")] +compile_error!("+avx2"); +//~^ ERROR: +avx2 diff --git a/tests/ui/cfg/crt-static-with-target-features-works.stderr b/tests/ui/cfg/crt-static-with-target-features-works.stderr new file mode 100644 index 00000000000..6f265c685bb --- /dev/null +++ b/tests/ui/cfg/crt-static-with-target-features-works.stderr @@ -0,0 +1,8 @@ +error: +avx2 + --> $DIR/crt-static-with-target-features-works.rs:23:1 + | +LL | compile_error!("+avx2"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/check-cfg/cfg-crate-features.rs b/tests/ui/check-cfg/cfg-crate-features.rs new file mode 100644 index 00000000000..16be8aaeeaa --- /dev/null +++ b/tests/ui/check-cfg/cfg-crate-features.rs @@ -0,0 +1,13 @@ +// https://github.com/rust-lang/rust/issues/143977 +// Check that features are available when an attribute is applied to a crate + +#![cfg(version("1.0"))] +//~^ ERROR `cfg(version)` is experimental and subject to change + +// Using invalid value `does_not_exist`, +// so we don't accidentally configure out the crate for any certain OS +#![cfg(not(target(os = "does_not_exist")))] +//~^ ERROR compact `cfg(target(..))` is experimental and subject to change +//~| WARN unexpected `cfg` condition value: `does_not_exist` + +fn main() {} diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr new file mode 100644 index 00000000000..60a5404c073 --- /dev/null +++ b/tests/ui/check-cfg/cfg-crate-features.stderr @@ -0,0 +1,33 @@ +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/cfg-crate-features.rs:4:8 + | +LL | #![cfg(version("1.0"))] + | ^^^^^^^^^^^^^^ + | + = note: see issue #64796 <https://github.com/rust-lang/rust/issues/64796> for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: compact `cfg(target(..))` is experimental and subject to change + --> $DIR/cfg-crate-features.rs:9:12 + | +LL | #![cfg(not(target(os = "does_not_exist")))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #96901 <https://github.com/rust-lang/rust/issues/96901> for more information + = help: add `#![feature(cfg_target_compact)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: unexpected `cfg` condition value: `does_not_exist` + --> $DIR/cfg-crate-features.rs:9:19 + | +LL | #![cfg(not(target(os = "does_not_exist")))] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, and `uefi` and 9 more + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/codegen/duplicated-path-in-error.stderr b/tests/ui/codegen/duplicated-path-in-error.gnu.stderr index d0d34e2f934..d0d34e2f934 100644 --- a/tests/ui/codegen/duplicated-path-in-error.stderr +++ b/tests/ui/codegen/duplicated-path-in-error.gnu.stderr diff --git a/tests/ui/codegen/duplicated-path-in-error.musl.stderr b/tests/ui/codegen/duplicated-path-in-error.musl.stderr new file mode 100644 index 00000000000..2892ebffdde --- /dev/null +++ b/tests/ui/codegen/duplicated-path-in-error.musl.stderr @@ -0,0 +1,2 @@ +error: couldn't load codegen backend /non-existing-one.so: Error loading shared library /non-existing-one.so: No such file or directory + diff --git a/tests/ui/codegen/duplicated-path-in-error.rs b/tests/ui/codegen/duplicated-path-in-error.rs index a446395de20..fed93828ee2 100644 --- a/tests/ui/codegen/duplicated-path-in-error.rs +++ b/tests/ui/codegen/duplicated-path-in-error.rs @@ -1,8 +1,15 @@ +//@ revisions: musl gnu //@ only-linux +//@ ignore-cross-compile because this relies on host libc behaviour //@ compile-flags: -Zcodegen-backend=/non-existing-one.so +//@[gnu] only-gnu +//@[musl] only-musl // This test ensures that the error of the "not found dylib" doesn't duplicate // the path of the dylib. +// +// glibc and musl have different dlopen error messages, so the expected error +// message differs between the two. fn main() {} diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr index 92b226fe0f7..0c57eddbe93 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr @@ -1,8 +1,12 @@ -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | LL | get_flag::<false, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#7}` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + ff __ __ __ │ .â–‘â–‘â–‘ + } error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean --> $DIR/invalid-patterns.rs:42:14 @@ -26,11 +30,15 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character 42 │ B } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:44:58 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#11}` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + ff __ __ __ │ .â–‘â–‘â–‘ + } error[E0308]: mismatched types --> $DIR/invalid-patterns.rs:31:21 diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index 92b226fe0f7..0c57eddbe93 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr @@ -1,8 +1,12 @@ -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | LL | get_flag::<false, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#7}` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + ff __ __ __ │ .â–‘â–‘â–‘ + } error[E0080]: constructing invalid value: encountered 0x42, but expected a boolean --> $DIR/invalid-patterns.rs:42:14 @@ -26,11 +30,15 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character 42 │ B } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:44:58 | LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); | ^^^^^^^^^^^^^^^^^^ evaluation of `main::{constant#11}` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + ff __ __ __ │ .â–‘â–‘â–‘ + } error[E0308]: mismatched types --> $DIR/invalid-patterns.rs:31:21 diff --git a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr index f68fdb3b651..32fa46b92b3 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.full.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.full.stderr @@ -1,14 +1,15 @@ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: hiding a lifetime that's named elsewhere is confusing --> $DIR/issue-71348.rs:18:40 | LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target - | ^^ -- ------------------------ the lifetimes get resolved as `'a` + | ^^ -- ------------------------ the same lifetime is hidden here | | | - | | the lifetimes get resolved as `'a` - | this lifetime flows to the output + | | the same lifetime is named here + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default -help: one option is to consistently use `'a` +help: consistently use `'a` | LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<'a, N>>::Target | +++ diff --git a/tests/ui/const-generics/type-dependent/issue-71348.rs b/tests/ui/const-generics/type-dependent/issue-71348.rs index c6563c80305..9053f362ce4 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.rs +++ b/tests/ui/const-generics/type-dependent/issue-71348.rs @@ -17,7 +17,7 @@ trait Get<'a, const N: &'static str> { impl Foo { fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Target //[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter - //[full]~^^ WARNING lifetime flowing from input to output with different syntax + //[full]~^^ WARNING hiding a lifetime that's named elsewhere is confusing where Self: Get<'a, N>, { diff --git a/tests/ui/consts/const-compare-bytes-ub.rs b/tests/ui/consts/const-compare-bytes-ub.rs index 0bc8585a4ee..7e3df92a2bf 100644 --- a/tests/ui/consts/const-compare-bytes-ub.rs +++ b/tests/ui/consts/const-compare-bytes-ub.rs @@ -1,6 +1,6 @@ //@ check-fail -#![feature(core_intrinsics)] +#![feature(core_intrinsics, const_cmp)] use std::intrinsics::compare_bytes; use std::mem::MaybeUninit; diff --git a/tests/ui/consts/const-compare-bytes-ub.stderr b/tests/ui/consts/const-compare-bytes-ub.stderr index c1706a8c4b0..770a55cc726 100644 --- a/tests/ui/consts/const-compare-bytes-ub.stderr +++ b/tests/ui/consts/const-compare-bytes-ub.stderr @@ -33,12 +33,20 @@ error[E0080]: reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at | LL | compare_bytes(MaybeUninit::uninit().as_ptr(), [1].as_ptr(), 1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::LHS_UNINIT` failed here + | + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ â–‘ + } error[E0080]: reading memory at ALLOC3[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory --> $DIR/const-compare-bytes-ub.rs:33:9 | LL | compare_bytes([1].as_ptr(), MaybeUninit::uninit().as_ptr(), 1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::RHS_UNINIT` failed here + | + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ â–‘ + } error[E0080]: unable to turn pointer into integer --> $DIR/const-compare-bytes-ub.rs:37:9 diff --git a/tests/ui/consts/const-compare-bytes.rs b/tests/ui/consts/const-compare-bytes.rs index cd5cdfd0400..9563375555c 100644 --- a/tests/ui/consts/const-compare-bytes.rs +++ b/tests/ui/consts/const-compare-bytes.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(core_intrinsics)] +#![feature(core_intrinsics, const_cmp)] use std::intrinsics::compare_bytes; fn main() { diff --git a/tests/ui/consts/const-err-enum-discriminant.32bit.stderr b/tests/ui/consts/const-err-enum-discriminant.32bit.stderr new file mode 100644 index 00000000000..cc786108f64 --- /dev/null +++ b/tests/ui/consts/const-err-enum-discriminant.32bit.stderr @@ -0,0 +1,13 @@ +error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x0..0x4], and this operation requires initialized memory + --> $DIR/const-err-enum-discriminant.rs:10:21 + | +LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], + | ^^^^^^^^^^^^^^^ evaluation of `Bar::Boo::{constant#0}` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ â–‘â–‘â–‘â–‘ + } + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-err-enum-discriminant.64bit.stderr b/tests/ui/consts/const-err-enum-discriminant.64bit.stderr new file mode 100644 index 00000000000..1d32851aac1 --- /dev/null +++ b/tests/ui/consts/const-err-enum-discriminant.64bit.stderr @@ -0,0 +1,13 @@ +error[E0080]: reading memory at ALLOC0[0x0..0x8], but memory is uninitialized at [0x0..0x8], and this operation requires initialized memory + --> $DIR/const-err-enum-discriminant.rs:10:21 + | +LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], + | ^^^^^^^^^^^^^^^ evaluation of `Bar::Boo::{constant#0}` failed here + | + = note: the raw bytes of the constant (size: 8, align: 8) { + __ __ __ __ __ __ __ __ │ â–‘â–‘â–‘â–‘â–‘â–‘â–‘â–‘ + } + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-err-enum-discriminant.rs b/tests/ui/consts/const-err-enum-discriminant.rs index 190ef47f436..55674600584 100644 --- a/tests/ui/consts/const-err-enum-discriminant.rs +++ b/tests/ui/consts/const-err-enum-discriminant.rs @@ -1,3 +1,5 @@ +//@ stderr-per-bitwidth + #[derive(Copy, Clone)] union Foo { a: isize, diff --git a/tests/ui/consts/const-err-enum-discriminant.stderr b/tests/ui/consts/const-err-enum-discriminant.stderr deleted file mode 100644 index 8724333ad7a..00000000000 --- a/tests/ui/consts/const-err-enum-discriminant.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/const-err-enum-discriminant.rs:8:21 - | -LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], - | ^^^^^^^^^^^^^^^ evaluation of `Bar::Boo::{constant#0}` failed here - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/auxiliary/stability.rs b/tests/ui/consts/const-eval/auxiliary/stability.rs index e6159551860..48ced3bc51e 100644 --- a/tests/ui/consts/const-eval/auxiliary/stability.rs +++ b/tests/ui/consts/const-eval/auxiliary/stability.rs @@ -1,10 +1,11 @@ // Crate that exports a const fn. Used for testing cross-crate. -#![crate_type="rlib"] +#![crate_type = "rlib"] #![stable(feature = "rust1", since = "1.0.0")] - #![feature(staged_api)] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature="foo", issue = "none")] -pub const fn foo() -> u32 { 42 } +#[rustc_const_unstable(feature = "foo", issue = "none")] +pub const fn foo() -> u32 { + 42 +} diff --git a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr index d28d6841ca9..60f6ef0f64b 100644 --- a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr +++ b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr @@ -43,11 +43,15 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC2[0x0..0x10], but memory is uninitialized at [0x8..0x10], and this operation requires initialized memory --> $DIR/const-pointer-values-in-various-types.rs:42:47 | LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_U128_UNION` failed here + | + = note: the raw bytes of the constant (size: 16, align: 16) { + ╾ALLOC0<imm>╼ __ __ __ __ __ __ __ __ │ ╾──────╼░░░░░░░░ + } error[E0080]: unable to turn pointer into integer --> $DIR/const-pointer-values-in-various-types.rs:45:43 @@ -85,11 +89,15 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC3[0x0..0x10], but memory is uninitialized at [0x8..0x10], and this operation requires initialized memory --> $DIR/const-pointer-values-in-various-types.rs:57:47 | LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::I32_REF_I128_UNION` failed here + | + = note: the raw bytes of the constant (size: 16, align: 16) { + ╾ALLOC1<imm>╼ __ __ __ __ __ __ __ __ │ ╾──────╼░░░░░░░░ + } error[E0080]: unable to turn pointer into integer --> $DIR/const-pointer-values-in-various-types.rs:60:45 diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs index 83ed496ac2c..af24e463b50 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs @@ -8,11 +8,11 @@ const FOO_RAW: *const i32 = foo(); const fn foo() -> &'static i32 { let t = unsafe { - let i = intrinsics::const_allocate(4, 4) as * mut i32; + let i = intrinsics::const_allocate(4, 4) as *mut i32; *i = 20; i }; - unsafe { &*t } + unsafe { &*(intrinsics::const_make_global(t as *mut u8) as *const i32) } } fn main() { assert_eq!(*FOO, 20); diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr index 11ed0841a00..a8c7ee93971 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr @@ -1,7 +1,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer --> $DIR/alloc_intrinsic_uninit.rs:7:1 | -LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; +LL | const BAR: &i32 = unsafe { | ^^^^^^^^^^^^^^^ it is undefined behavior to use this value | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr index 691bde87d2f..47e1c22cc2c 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr @@ -1,7 +1,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer --> $DIR/alloc_intrinsic_uninit.rs:7:1 | -LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; +LL | const BAR: &i32 = unsafe { | ^^^^^^^^^^^^^^^ it is undefined behavior to use this value | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs index ffc35ca1ddc..c54115de204 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs @@ -4,6 +4,8 @@ #![feature(const_heap)] use std::intrinsics; -const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) }; -//~^ ERROR: uninitialized memory +const BAR: &i32 = unsafe { //~ ERROR: uninitialized memory + // Make the pointer immutable to avoid errors related to mutable pointers in constants. + &*(intrinsics::const_make_global(intrinsics::const_allocate(4, 4)) as *const i32) +}; fn main() {} diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs deleted file mode 100644 index 26cb69e458b..00000000000 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs +++ /dev/null @@ -1,11 +0,0 @@ -// We unleash Miri here since this test demonstrates code that bypasses the checks against interning -// mutable pointers, which currently ICEs. Unleashing Miri silences the ICE. -//@ compile-flags: -Zunleash-the-miri-inside-of-you -#![feature(core_intrinsics)] -#![feature(const_heap)] -use std::intrinsics; - -const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 }; -//~^ error: mutable pointer in final value of constant - -fn main() {} diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr deleted file mode 100644 index 0dc49dc3cd8..00000000000 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: encountered mutable pointer in final value of constant - --> $DIR/alloc_intrinsic_untyped.rs:8:1 - | -LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 }; - | ^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs index 3cc035c66d3..515e12d2b77 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs @@ -12,7 +12,7 @@ const _X: () = unsafe { const Y: &u32 = unsafe { let ptr = intrinsics::const_allocate(4, 4) as *mut u32; *ptr = 42; - &*ptr + &*(intrinsics::const_make_global(ptr as *mut u8) as *const u32) }; const Z: &u32 = &42; diff --git a/tests/ui/consts/const-eval/heap/make-global-dangling.rs b/tests/ui/consts/const-eval/heap/make-global-dangling.rs new file mode 100644 index 00000000000..f4c5929bc41 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global-dangling.rs @@ -0,0 +1,18 @@ +// Ensure that we can't call `const_make_global` on dangling pointers. + +#![feature(core_intrinsics)] +#![feature(const_heap)] + +use std::intrinsics; + +const Y: &u32 = unsafe { + &*(intrinsics::const_make_global(std::ptr::null_mut()) as *const u32) + //~^ error: pointer not dereferenceable +}; + +const Z: &u32 = unsafe { + &*(intrinsics::const_make_global(std::ptr::dangling_mut()) as *const u32) + //~^ error: pointer not dereferenceable +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/make-global-dangling.stderr b/tests/ui/consts/const-eval/heap/make-global-dangling.stderr new file mode 100644 index 00000000000..48c2796d0bf --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global-dangling.stderr @@ -0,0 +1,15 @@ +error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got null pointer + --> $DIR/make-global-dangling.rs:9:8 + | +LL | &*(intrinsics::const_make_global(std::ptr::null_mut()) as *const u32) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Y` failed here + +error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got 0x1[noalloc] which is a dangling pointer (it has no provenance) + --> $DIR/make-global-dangling.rs:14:8 + | +LL | &*(intrinsics::const_make_global(std::ptr::dangling_mut()) as *const u32) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Z` failed here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/heap/make-global-other.rs b/tests/ui/consts/const-eval/heap/make-global-other.rs new file mode 100644 index 00000000000..4e2a59de13e --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global-other.rs @@ -0,0 +1,15 @@ +// Ensure that we can't call `const_make_global` on pointers not in the current interpreter. + +#![feature(core_intrinsics)] +#![feature(const_heap)] + +use std::intrinsics; + +const X: &i32 = &0; + +const Y: &i32 = unsafe { + &*(intrinsics::const_make_global(X as *const i32 as *mut u8) as *const i32) + //~^ error: pointer passed to `const_make_global` does not point to a heap allocation: ALLOC0<imm> +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/make-global-other.stderr b/tests/ui/consts/const-eval/heap/make-global-other.stderr new file mode 100644 index 00000000000..ed0d768cf37 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global-other.stderr @@ -0,0 +1,9 @@ +error[E0080]: pointer passed to `const_make_global` does not point to a heap allocation: ALLOC0<imm> + --> $DIR/make-global-other.rs:11:8 + | +LL | &*(intrinsics::const_make_global(X as *const i32 as *mut u8) as *const i32) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Y` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/heap/make-global-twice.rs b/tests/ui/consts/const-eval/heap/make-global-twice.rs new file mode 100644 index 00000000000..0cd617cea3e --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global-twice.rs @@ -0,0 +1,18 @@ +// Ensure that we can't call `const_make_global` twice. + +#![feature(core_intrinsics)] +#![feature(const_heap)] + +use std::intrinsics; + +const Y: &i32 = unsafe { + let ptr = intrinsics::const_allocate(4, 4); + let i = ptr as *mut i32; + *i = 20; + intrinsics::const_make_global(ptr); + intrinsics::const_make_global(ptr); + //~^ error: attempting to call `const_make_global` twice on the same allocation ALLOC0 + &*i +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/make-global-twice.stderr b/tests/ui/consts/const-eval/heap/make-global-twice.stderr new file mode 100644 index 00000000000..95cdb9694d8 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global-twice.stderr @@ -0,0 +1,9 @@ +error[E0080]: attempting to call `const_make_global` twice on the same allocation ALLOC0 + --> $DIR/make-global-twice.rs:13:5 + | +LL | intrinsics::const_make_global(ptr); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `Y` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/heap/make-global.rs b/tests/ui/consts/const-eval/heap/make-global.rs new file mode 100644 index 00000000000..b26fe2434ab --- /dev/null +++ b/tests/ui/consts/const-eval/heap/make-global.rs @@ -0,0 +1,21 @@ +//@ run-pass +#![feature(core_intrinsics)] +#![feature(const_heap)] +use std::intrinsics; + +const FOO: &i32 = foo(); +const FOO_RAW: *const i32 = foo(); + +const fn foo() -> &'static i32 { + unsafe { + let ptr = intrinsics::const_allocate(4, 4); + let t = ptr as *mut i32; + *t = 20; + intrinsics::const_make_global(ptr); + &*t + } +} +fn main() { + assert_eq!(*FOO, 20); + assert_eq!(unsafe { *FOO_RAW }, 20); +} diff --git a/tests/ui/consts/const-eval/heap/ptr_made_global_mutated.rs b/tests/ui/consts/const-eval/heap/ptr_made_global_mutated.rs new file mode 100644 index 00000000000..bea2a5949c2 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/ptr_made_global_mutated.rs @@ -0,0 +1,15 @@ +// Ensure that once an allocation is "made global", we can no longer mutate it. +#![feature(core_intrinsics)] +#![feature(const_heap)] +use std::intrinsics; + +const A: &u8 = unsafe { + let ptr = intrinsics::const_allocate(1, 1); + *ptr = 1; + let ptr: *const u8 = intrinsics::const_make_global(ptr); + *(ptr as *mut u8) = 2; + //~^ error: writing to ALLOC0 which is read-only + &*ptr +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/ptr_made_global_mutated.stderr b/tests/ui/consts/const-eval/heap/ptr_made_global_mutated.stderr new file mode 100644 index 00000000000..0e88ea77d1c --- /dev/null +++ b/tests/ui/consts/const-eval/heap/ptr_made_global_mutated.stderr @@ -0,0 +1,9 @@ +error[E0080]: writing to ALLOC0 which is read-only + --> $DIR/ptr_made_global_mutated.rs:10:5 + | +LL | *(ptr as *mut u8) = 2; + | ^^^^^^^^^^^^^^^^^^^^^ evaluation of `A` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/heap/ptr_not_made_global.rs b/tests/ui/consts/const-eval/heap/ptr_not_made_global.rs new file mode 100644 index 00000000000..6980e92c218 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/ptr_not_made_global.rs @@ -0,0 +1,24 @@ +// Ensure that we reject interning `const_allocate`d allocations in the final value of constants +// if they have not been made global through `const_make_global`. The pointers are made *immutable* +// to focus the test on the missing `make_global`; `ptr_not_made_global_mut.rs` covers the case +// where the pointer remains mutable. + +#![feature(core_intrinsics)] +#![feature(const_heap)] +use std::intrinsics; + +const FOO: &i32 = foo(); +//~^ error: encountered `const_allocate` pointer in final value that was not made global +const FOO_RAW: *const i32 = foo(); +//~^ error: encountered `const_allocate` pointer in final value that was not made global + +const fn foo() -> &'static i32 { + let t = unsafe { + let i = intrinsics::const_allocate(4, 4) as *mut i32; + *i = 20; + i + }; + unsafe { &*t } +} + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr b/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr new file mode 100644 index 00000000000..cb2bb1e8cd8 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/ptr_not_made_global.stderr @@ -0,0 +1,18 @@ +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/ptr_not_made_global.rs:10:1 + | +LL | const FOO: &i32 = foo(); + | ^^^^^^^^^^^^^^^ + | + = note: use `const_make_global` to make allocated pointers immutable before returning + +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/ptr_not_made_global.rs:12:1 + | +LL | const FOO_RAW: *const i32 = foo(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: use `const_make_global` to make allocated pointers immutable before returning + +error: aborting due to 2 previous errors + diff --git a/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.rs b/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.rs new file mode 100644 index 00000000000..e44a3f7a23c --- /dev/null +++ b/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.rs @@ -0,0 +1,11 @@ +// Ensure that we reject interning `const_allocate`d allocations in the final value of constants +// if they have not been made global through `const_make_global`. This covers the case where the +// pointer is even still mutable, which used to ICE. +#![feature(core_intrinsics)] +#![feature(const_heap)] +use std::intrinsics; + +const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 }; +//~^ error: encountered `const_allocate` pointer in final value that was not made global + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr b/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr new file mode 100644 index 00000000000..2445ce633d6 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/ptr_not_made_global_mut.stderr @@ -0,0 +1,10 @@ +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/ptr_not_made_global_mut.rs:8:1 + | +LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: use `const_make_global` to make allocated pointers immutable before returning + +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/const-eval/ub-enum-overwrite.stderr b/tests/ui/consts/const-eval/ub-enum-overwrite.stderr index 52af52d3236..2fd01b67c49 100644 --- a/tests/ui/consts/const-eval/ub-enum-overwrite.stderr +++ b/tests/ui/consts/const-eval/ub-enum-overwrite.stderr @@ -1,8 +1,12 @@ -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x1..0x2], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory --> $DIR/ub-enum-overwrite.rs:11:14 | LL | unsafe { *p } | ^^ evaluation of `_` failed here + | + = note: the raw bytes of the constant (size: 2, align: 1) { + 01 __ │ .â–‘ + } error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 52fc9945068..9c78bb6efed 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -1,7 +1,8 @@ // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr: "0x0+" -> "0x0" +//@ normalize-stderr: "0x[0-9](\.\.|\])" -> "0x%$1" //@ dont-require-annotations: NOTE #![feature(never_type)] diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr index 29f7a1f051a..5cbd6176c92 100644 --- a/tests/ui/consts/const-eval/ub-enum.stderr +++ b/tests/ui/consts/const-eval/ub-enum.stderr @@ -1,5 +1,5 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x01, but expected a valid enum tag - --> $DIR/ub-enum.rs:29:1 + --> $DIR/ub-enum.rs:30:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -10,7 +10,7 @@ LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-enum.rs:32:1 + --> $DIR/ub-enum.rs:33:1 | LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM_PTR` failed here @@ -19,7 +19,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: unable to turn pointer into integer - --> $DIR/ub-enum.rs:35:1 + --> $DIR/ub-enum.rs:36:1 | LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM_WRAPPED` failed here @@ -28,7 +28,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x0, but expected a valid enum tag - --> $DIR/ub-enum.rs:47:1 + --> $DIR/ub-enum.rs:48:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -39,7 +39,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-enum.rs:49:1 + --> $DIR/ub-enum.rs:50:1 | LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_PTR` failed here @@ -48,7 +48,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: unable to turn pointer into integer - --> $DIR/ub-enum.rs:52:1 + --> $DIR/ub-enum.rs:53:1 | LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_WRAPPED` failed here @@ -56,14 +56,18 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/ub-enum.rs:61:41 +error[E0080]: reading memory at ALLOC0[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-enum.rs:62:41 | LL | const BAD_ENUM2_UNDEF: Enum2 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_UNDEF` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-enum.rs:65:1 + --> $DIR/ub-enum.rs:66:1 | LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_ENUM2_OPTION_PTR` failed here @@ -72,7 +76,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant - --> $DIR/ub-enum.rs:82:1 + --> $DIR/ub-enum.rs:83:1 | LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -83,7 +87,7 @@ LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant - --> $DIR/ub-enum.rs:84:1 + --> $DIR/ub-enum.rs:85:1 | LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -94,7 +98,7 @@ LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute } error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) - --> $DIR/ub-enum.rs:92:1 + --> $DIR/ub-enum.rs:93:1 | LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -105,19 +109,19 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran } error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant - --> $DIR/ub-enum.rs:97:77 + --> $DIR/ub-enum.rs:98:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA1` failed here error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant - --> $DIR/ub-enum.rs:99:77 + --> $DIR/ub-enum.rs:100:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINHABITED_WITH_DATA2` failed here error[E0080]: read discriminant of an uninhabited enum variant - --> $DIR/ub-enum.rs:105:9 + --> $DIR/ub-enum.rs:106:9 | LL | std::mem::discriminant(&*(&() as *const () as *const Never)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `TEST_ICE_89765` failed inside this call diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index 314141e4837..19ae66cf3c6 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -37,11 +37,15 @@ LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory --> $DIR/ub-nonnull.rs:36:38 | LL | const UNINIT: NonZero<u8> = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + __ │ â–‘ + } error[E0080]: constructing invalid value: encountered 42, but expected something in the range 10..=30 --> $DIR/ub-nonnull.rs:44:1 diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 64b48939be6..d8e5102fcbe 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -1,8 +1,9 @@ // ignore-tidy-linelength // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" //@ dont-require-annotations: NOTE +//@ normalize-stderr: "0x[0-9](\.\.|\])" -> "0x%$1" #![allow(invalid_value)] diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index d5ccc396b90..451ebb6eba1 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -1,5 +1,5 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1) - --> $DIR/ub-ref-ptr.rs:17:1 + --> $DIR/ub-ref-ptr.rs:18:1 | LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -10,7 +10,7 @@ LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1) - --> $DIR/ub-ref-ptr.rs:20:1 + --> $DIR/ub-ref-ptr.rs:21:1 | LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -21,7 +21,7 @@ LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; } error[E0080]: constructing invalid value: encountered a null reference - --> $DIR/ub-ref-ptr.rs:23:1 + --> $DIR/ub-ref-ptr.rs:24:1 | LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -32,7 +32,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) }; } error[E0080]: constructing invalid value: encountered a null box - --> $DIR/ub-ref-ptr.rs:26:1 + --> $DIR/ub-ref-ptr.rs:27:1 | LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -43,7 +43,7 @@ LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) }; } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:33:1 + --> $DIR/ub-ref-ptr.rs:34:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE` failed here @@ -52,7 +52,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:36:39 + --> $DIR/ub-ref-ptr.rs:37:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_SLICE` failed here @@ -61,13 +61,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:36:38 + --> $DIR/ub-ref-ptr.rs:37:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:39:86 + --> $DIR/ub-ref-ptr.rs:40:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_BOX_SLICE` failed here @@ -76,13 +76,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:39:85 + --> $DIR/ub-ref-ptr.rs:40:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) - --> $DIR/ub-ref-ptr.rs:42:1 + --> $DIR/ub-ref-ptr.rs:43:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -93,7 +93,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) - --> $DIR/ub-ref-ptr.rs:45:1 + --> $DIR/ub-ref-ptr.rs:46:1 | LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -103,14 +103,18 @@ LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) }; HEX_DUMP } -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/ub-ref-ptr.rs:48:41 +error[E0080]: reading memory at ALLOC3[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-ref-ptr.rs:49:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_PTR` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:51:1 + --> $DIR/ub-ref-ptr.rs:52:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -120,14 +124,18 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/ub-ref-ptr.rs:53:38 +error[E0080]: reading memory at ALLOC4[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-ref-ptr.rs:54:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_FN_PTR` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer - --> $DIR/ub-ref-ptr.rs:55:1 + --> $DIR/ub-ref-ptr.rs:56:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -138,7 +146,7 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; } error[E0080]: constructing invalid value: encountered ALLOC2<imm>, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:57:1 + --> $DIR/ub-ref-ptr.rs:58:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -149,7 +157,7 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; } error[E0080]: accessing memory based on pointer with alignment 1, but alignment 4 is required - --> $DIR/ub-ref-ptr.rs:64:5 + --> $DIR/ub-ref-ptr.rs:65:5 | LL | ptr.read(); | ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here diff --git a/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs b/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs index e805ac01c9d..ad2b49e6049 100644 --- a/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs +++ b/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs @@ -1,9 +1,10 @@ -//@ known-bug: #110395 +#![feature(const_index, const_trait_impl)] const A: [(); 5] = [(), (), (), (), ()]; // Since the indexing is on a ZST, the addresses are all fine, // but we should still catch the bad range. const B: &[()] = unsafe { A.get_unchecked(3..1) }; +//~^ ERROR: slice::get_unchecked requires that the range is within the slice fn main() {} diff --git a/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr b/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr index 6e428079afe..88ea310f19c 100644 --- a/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr +++ b/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const method `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` in constants - --> $DIR/ub-slice-get-unchecked.rs:7:29 +error[E0080]: evaluation panicked: unsafe precondition(s) violated: slice::get_unchecked requires that the range is within the slice + + This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety. + --> $DIR/ub-slice-get-unchecked.rs:7:27 | LL | const B: &[()] = unsafe { A.get_unchecked(3..1) }; - | ^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants + | ^^^^^^^^^^^^^^^^^^^^^ evaluation of `B` failed here error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index 86235897e7e..0bbb104c032 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -6,9 +6,10 @@ use std::{ptr, mem}; // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr: "offset \d+" -> "offset N" //@ normalize-stderr: "size \d+" -> "size N" +//@ normalize-stderr: "0x[0-9](\.\.|\])" -> "0x%$1" //@ dont-require-annotations: NOTE /// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error @@ -61,7 +62,7 @@ const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // bad slice: length uninit const SLICE_LENGTH_UNINIT: &[u8] = unsafe { -//~^ ERROR uninitialized + //~^ ERROR uninitialized let uninit_len = MaybeUninit::<usize> { uninit: () }; mem::transmute((42, uninit_len)) }; @@ -99,7 +100,7 @@ const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { -//~^ ERROR uninitialized + //~^ ERROR uninitialized let uninit_len = MaybeUninit::<usize> { uninit: () }; mem::transmute((42, uninit_len)) }; diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr index 8724dd9a3c0..ab15ba826a5 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr @@ -1,5 +1,5 @@ error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) - --> $DIR/ub-wide-ptr.rs:39:1 + --> $DIR/ub-wide-ptr.rs:40:1 | LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -10,7 +10,7 @@ LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object - --> $DIR/ub-wide-ptr.rs:41:1 + --> $DIR/ub-wide-ptr.rs:42:1 | LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -21,7 +21,7 @@ LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, us } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-wide-ptr.rs:44:1 + --> $DIR/ub-wide-ptr.rs:45:1 | LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `STR_LENGTH_PTR` failed here @@ -30,7 +30,7 @@ LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: unable to turn pointer into integer - --> $DIR/ub-wide-ptr.rs:47:1 + --> $DIR/ub-wide-ptr.rs:48:1 | LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MY_STR_LENGTH_PTR` failed here @@ -39,7 +39,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object - --> $DIR/ub-wide-ptr.rs:49:1 + --> $DIR/ub-wide-ptr.rs:50:1 | LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -50,7 +50,7 @@ LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize: } error[E0080]: constructing invalid value at .<deref>: encountered uninitialized memory, but expected a string - --> $DIR/ub-wide-ptr.rs:53:1 + --> $DIR/ub-wide-ptr.rs:54:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -61,7 +61,7 @@ LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit: } error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialized memory, but expected a string - --> $DIR/ub-wide-ptr.rs:56:1 + --> $DIR/ub-wide-ptr.rs:57:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -71,14 +71,18 @@ LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUni HEX_DUMP } -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/ub-wide-ptr.rs:63:1 +error[E0080]: reading memory at ALLOC32[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-wide-ptr.rs:64:1 | LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SLICE_LENGTH_UNINIT` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) - --> $DIR/ub-wide-ptr.rs:69:1 + --> $DIR/ub-wide-ptr.rs:70:1 | LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -89,7 +93,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; } error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object - --> $DIR/ub-wide-ptr.rs:72:1 + --> $DIR/ub-wide-ptr.rs:73:1 | LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -100,7 +104,7 @@ LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, is } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-wide-ptr.rs:75:1 + --> $DIR/ub-wide-ptr.rs:76:1 | LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SLICE_LENGTH_PTR` failed here @@ -109,7 +113,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation) - --> $DIR/ub-wide-ptr.rs:78:1 + --> $DIR/ub-wide-ptr.rs:79:1 | LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -120,7 +124,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us } error[E0080]: unable to turn pointer into integer - --> $DIR/ub-wide-ptr.rs:81:1 + --> $DIR/ub-wide-ptr.rs:82:1 | LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SLICE_LENGTH_PTR_BOX` failed here @@ -129,7 +133,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3) = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean - --> $DIR/ub-wide-ptr.rs:85:1 + --> $DIR/ub-wide-ptr.rs:86:1 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -140,13 +144,13 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; } note: erroneous constant encountered - --> $DIR/ub-wide-ptr.rs:85:40 + --> $DIR/ub-wide-ptr.rs:86:40 | LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean - --> $DIR/ub-wide-ptr.rs:91:1 + --> $DIR/ub-wide-ptr.rs:92:1 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -157,13 +161,13 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3 } note: erroneous constant encountered - --> $DIR/ub-wide-ptr.rs:91:42 + --> $DIR/ub-wide-ptr.rs:92:42 | LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean - --> $DIR/ub-wide-ptr.rs:94:1 + --> $DIR/ub-wide-ptr.rs:95:1 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -174,19 +178,23 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::tran } note: erroneous constant encountered - --> $DIR/ub-wide-ptr.rs:94:42 + --> $DIR/ub-wide-ptr.rs:95:42 | LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/ub-wide-ptr.rs:101:1 +error[E0080]: reading memory at ALLOC33[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-wide-ptr.rs:102:1 | LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `RAW_SLICE_LENGTH_UNINIT` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } error[E0080]: constructing invalid value at .0: encountered ALLOC12<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:109:1 + --> $DIR/ub-wide-ptr.rs:110:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -197,7 +205,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: constructing invalid value at .0: encountered ALLOC14<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:112:1 + --> $DIR/ub-wide-ptr.rs:113:1 | LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -208,7 +216,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W(( } error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:115:1 + --> $DIR/ub-wide-ptr.rs:116:1 | LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -219,7 +227,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u } error[E0080]: constructing invalid value: encountered ALLOC17<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:117:1 + --> $DIR/ub-wide-ptr.rs:118:1 | LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -230,7 +238,7 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92 } error[E0080]: constructing invalid value: encountered ALLOC19<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:119:1 + --> $DIR/ub-wide-ptr.rs:120:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -241,7 +249,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92 } error[E0080]: constructing invalid value: encountered ALLOC21<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:121:1 + --> $DIR/ub-wide-ptr.rs:122:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -252,7 +260,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u } error[E0080]: constructing invalid value at .0: encountered ALLOC23<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:123:1 + --> $DIR/ub-wide-ptr.rs:124:1 | LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -263,7 +271,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans } error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean - --> $DIR/ub-wide-ptr.rs:127:1 + --> $DIR/ub-wide-ptr.rs:128:1 | LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -274,7 +282,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, } error[E0080]: constructing invalid value: encountered null pointer, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:131:1 + --> $DIR/ub-wide-ptr.rs:132:1 | LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -285,7 +293,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute } error[E0080]: constructing invalid value: encountered ALLOC28<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:133:1 + --> $DIR/ub-wide-ptr.rs:134:1 | LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -296,7 +304,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm } error[E0080]: constructing invalid value: encountered null pointer, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:140:1 + --> $DIR/ub-wide-ptr.rs:141:1 | LL | static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -307,7 +315,7 @@ LL | static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe } error[E0080]: constructing invalid value: encountered ALLOC31<imm>, but expected a vtable pointer - --> $DIR/ub-wide-ptr.rs:144:1 + --> $DIR/ub-wide-ptr.rs:145:1 | LL | static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value diff --git a/tests/ui/consts/const-eval/union-const-eval-field.rs b/tests/ui/consts/const-eval/union-const-eval-field.rs index 0ad94eee7f4..719e59b007c 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.rs +++ b/tests/ui/consts/const-eval/union-const-eval-field.rs @@ -1,4 +1,5 @@ //@ dont-require-annotations: NOTE +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" type Field1 = i32; type Field2 = f32; diff --git a/tests/ui/consts/const-eval/union-const-eval-field.stderr b/tests/ui/consts/const-eval/union-const-eval-field.stderr index 07ff4c3ca36..1843ce273ac 100644 --- a/tests/ui/consts/const-eval/union-const-eval-field.stderr +++ b/tests/ui/consts/const-eval/union-const-eval-field.stderr @@ -1,17 +1,21 @@ -error[E0080]: using uninitialized data, but this operation requires initialized memory - --> $DIR/union-const-eval-field.rs:28:37 +error[E0080]: reading memory at ALLOC0[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory + --> $DIR/union-const-eval-field.rs:29:37 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^ evaluation of `read_field3::FIELD3` failed here + | + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + 00 00 80 3f __ __ __ __ │ ...?â–‘â–‘â–‘â–‘ + } note: erroneous constant encountered - --> $DIR/union-const-eval-field.rs:30:5 + --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 | ^^^^^^ note: erroneous constant encountered - --> $DIR/union-const-eval-field.rs:30:5 + --> $DIR/union-const-eval-field.rs:31:5 | LL | FIELD3 | ^^^^^^ diff --git a/tests/ui/consts/const-eval/union-ice.stderr b/tests/ui/consts/const-eval/union-ice.stderr index b00fcc91d68..0506be63ea6 100644 --- a/tests/ui/consts/const-eval/union-ice.stderr +++ b/tests/ui/consts/const-eval/union-ice.stderr @@ -1,20 +1,32 @@ -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory --> $DIR/union-ice.rs:14:33 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; | ^^^^^^^^^^^^ evaluation of `FIELD3` failed here + | + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 80 3f __ __ __ __ │ ...?â–‘â–‘â–‘â–‘ + } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC1[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory --> $DIR/union-ice.rs:19:17 | LL | b: unsafe { UNION.field3 }, | ^^^^^^^^^^^^ evaluation of `FIELD_PATH` failed here + | + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 80 3f __ __ __ __ │ ...?â–‘â–‘â–‘â–‘ + } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC2[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory --> $DIR/union-ice.rs:31:18 | LL | unsafe { UNION.field3 }, | ^^^^^^^^^^^^ evaluation of `FIELD_PATH2` failed here + | + = note: the raw bytes of the constant (size: 8, align: 8) { + 00 00 80 3f __ __ __ __ │ ...?â–‘â–‘â–‘â–‘ + } error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const-eval/union-ub.32bit.stderr b/tests/ui/consts/const-eval/union-ub.32bit.stderr index 9f0697984e4..757bcea91c3 100644 --- a/tests/ui/consts/const-eval/union-ub.32bit.stderr +++ b/tests/ui/consts/const-eval/union-ub.32bit.stderr @@ -9,11 +9,15 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool }; 2a │ * } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory --> $DIR/union-ub.rs:35:36 | LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_BOOL` failed here + | + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ â–‘ + } error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/union-ub.64bit.stderr b/tests/ui/consts/const-eval/union-ub.64bit.stderr index 9f0697984e4..757bcea91c3 100644 --- a/tests/ui/consts/const-eval/union-ub.64bit.stderr +++ b/tests/ui/consts/const-eval/union-ub.64bit.stderr @@ -9,11 +9,15 @@ LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool }; 2a │ * } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory --> $DIR/union-ub.rs:35:36 | LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_BOOL` failed here + | + = note: the raw bytes of the constant (size: 1, align: 1) { + __ │ â–‘ + } error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs index 2372d1c3e3d..fd3ed8f1826 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -8,8 +8,8 @@ extern "C" { } const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; -//~^ ERROR the size for values of type `Opaque` cannot be known +//~^ ERROR `extern type` does not have known layout const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; -//~^ ERROR the size for values of type `Opaque` cannot be known +//~^ ERROR `extern type` does not have known layout fn main() {} diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index 825b9e94158..23f7aaf538e 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -1,39 +1,15 @@ -error[E0277]: the size for values of type `Opaque` cannot be known - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43 +error[E0080]: `extern type` does not have known layout + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; - | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` - | | - | required by a bound introduced by this call - | - = note: the trait bound `Opaque: MetaSized` is not satisfied -note: required by a bound in `std::intrinsics::size_of_val` - --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL -help: consider borrowing here - | -LL | const _SIZE: usize = unsafe { size_of_val(&(&4 as *const i32 as *const Opaque)) }; - | ++ + -LL | const _SIZE: usize = unsafe { size_of_val(&mut (&4 as *const i32 as *const Opaque)) }; - | ++++++ + + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_SIZE` failed here -error[E0277]: the size for values of type `Opaque` cannot be known - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45 +error[E0080]: `extern type` does not have known layout + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:32 | LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` - | | - | required by a bound introduced by this call - | - = note: the trait bound `Opaque: MetaSized` is not satisfied -note: required by a bound in `std::intrinsics::align_of_val` - --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL -help: consider borrowing here - | -LL | const _ALIGN: usize = unsafe { align_of_val(&(&4 as *const i32 as *const Opaque)) }; - | ++ + -LL | const _ALIGN: usize = unsafe { align_of_val(&mut (&4 as *const i32 as *const Opaque)) }; - | ++++++ + + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_ALIGN` failed here error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index 26aa9230a39..e13fad78441 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -13,14 +13,14 @@ struct TryMe; struct Error; impl const FromResidual<Error> for TryMe { - //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + //~^ ERROR const `impl` for trait `FromResidual` which is not `const` fn from_residual(residual: Error) -> Self { TryMe } } impl const Try for TryMe { - //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]` + //~^ ERROR const `impl` for trait `Try` which is not `const` type Output = (); type Residual = Error; fn from_output(output: Self::Output) -> Self { diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 4209ca1d526..7004ea3e6db 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,19 +1,19 @@ -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +error: const `impl` for trait `FromResidual` which is not `const` --> $DIR/const-try.rs:15:12 | LL | impl const FromResidual<Error> for TryMe { | ^^^^^^^^^^^^^^^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` +error: const `impl` for trait `Try` which is not `const` --> $DIR/const-try.rs:22:12 | LL | impl const Try for TryMe { | ^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0015]: `?` is not allowed on `TryMe` in constant functions diff --git a/tests/ui/consts/const_transmute_type_id3.rs b/tests/ui/consts/const_transmute_type_id3.rs index ed5ff769701..f1bb8cddf77 100644 --- a/tests/ui/consts/const_transmute_type_id3.rs +++ b/tests/ui/consts/const_transmute_type_id3.rs @@ -1,3 +1,6 @@ +//! Test that all bytes of a TypeId must have the +//! TypeId marker provenance. + #![feature(const_type_id, const_trait_impl, const_cmp)] use std::any::TypeId; @@ -10,7 +13,7 @@ const _: () = { std::ptr::write(ptr.offset(1), 999); } assert!(a == b); - //~^ ERROR: one of the TypeId arguments is invalid, the hash does not match the type it represents + //~^ ERROR: pointer must point to some allocation }; fn main() {} diff --git a/tests/ui/consts/const_transmute_type_id3.stderr b/tests/ui/consts/const_transmute_type_id3.stderr index 8cfdcfebaa4..e731f496652 100644 --- a/tests/ui/consts/const_transmute_type_id3.stderr +++ b/tests/ui/consts/const_transmute_type_id3.stderr @@ -1,5 +1,5 @@ -error[E0080]: type_id_eq: one of the TypeId arguments is invalid, the hash does not match the type it represents - --> $DIR/const_transmute_type_id3.rs:12:13 +error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got 0x3e7[noalloc] which is a dangling pointer (it has no provenance) + --> $DIR/const_transmute_type_id3.rs:15:13 | LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call diff --git a/tests/ui/consts/const_transmute_type_id4.rs b/tests/ui/consts/const_transmute_type_id4.rs index 22a607e9e0e..0ea75f2a2f4 100644 --- a/tests/ui/consts/const_transmute_type_id4.rs +++ b/tests/ui/consts/const_transmute_type_id4.rs @@ -10,7 +10,7 @@ const _: () = { std::ptr::write(ptr.offset(0), main as fn() as *const ()); } assert!(a == b); - //~^ ERROR: type_id_eq: `TypeId` provenance is not a type id + //~^ ERROR: invalid `TypeId` value }; fn main() {} diff --git a/tests/ui/consts/const_transmute_type_id4.stderr b/tests/ui/consts/const_transmute_type_id4.stderr index b418a79d7f0..b224227cf35 100644 --- a/tests/ui/consts/const_transmute_type_id4.stderr +++ b/tests/ui/consts/const_transmute_type_id4.stderr @@ -1,4 +1,4 @@ -error[E0080]: type_id_eq: `TypeId` provenance is not a type id +error[E0080]: invalid `TypeId` value: not all bytes carry type id metadata --> $DIR/const_transmute_type_id4.rs:12:13 | LL | assert!(a == b); diff --git a/tests/ui/consts/const_transmute_type_id5.rs b/tests/ui/consts/const_transmute_type_id5.rs new file mode 100644 index 00000000000..ae0429f8dbb --- /dev/null +++ b/tests/ui/consts/const_transmute_type_id5.rs @@ -0,0 +1,20 @@ +//! Test that we require an equal TypeId to have an integer part that properly +//! reflects the type id hash. + +#![feature(const_type_id, const_trait_impl, const_cmp)] + +use std::any::TypeId; + +const _: () = { + let mut b = TypeId::of::<()>(); + unsafe { + let ptr = &mut b as *mut TypeId as *mut *const (); + // Copy the ptr at index 0 to index 1 + let val = std::ptr::read(ptr); + std::ptr::write(ptr.offset(1), val); + } + assert!(b == b); + //~^ ERROR: invalid `TypeId` value +}; + +fn main() {} diff --git a/tests/ui/consts/const_transmute_type_id5.stderr b/tests/ui/consts/const_transmute_type_id5.stderr new file mode 100644 index 00000000000..6205679ebb6 --- /dev/null +++ b/tests/ui/consts/const_transmute_type_id5.stderr @@ -0,0 +1,15 @@ +error[E0080]: invalid `TypeId` value: the hash does not match the type id metadata + --> $DIR/const_transmute_type_id5.rs:16:13 + | +LL | assert!(b == b); + | ^^^^^^ evaluation of `_` failed inside this call + | +note: inside `<TypeId as PartialEq>::eq` + --> $SRC_DIR/core/src/any.rs:LL:COL +note: inside `<TypeId as PartialEq>::eq::compiletime` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index 87c8b04452b..22791e7d15e 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -7,7 +7,9 @@ struct Foo<'a> { impl<'a> Foo<'a> { const fn spam(&mut self, baz: &mut Vec<u32>) { self.bar[0] = baz.len(); - //~^ ERROR: cannot call + //~^ ERROR: `Vec<usize>: [const] Index<_>` is not satisfied + //~| ERROR: `Vec<usize>: [const] Index<usize>` is not satisfied + //~| ERROR: `Vec<usize>: [const] IndexMut<usize>` is not satisfied } } diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index 63a86b45633..608ce0cfef0 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -1,13 +1,24 @@ -error[E0015]: cannot call non-const operator in constant functions - --> $DIR/issue-94675.rs:9:17 +error[E0277]: the trait bound `Vec<usize>: [const] Index<_>` is not satisfied + --> $DIR/issue-94675.rs:9:9 | LL | self.bar[0] = baz.len(); - | ^^^ + | ^^^^^^^^^^^ + +error[E0277]: the trait bound `Vec<usize>: [const] IndexMut<usize>` is not satisfied + --> $DIR/issue-94675.rs:9:9 + | +LL | self.bar[0] = baz.len(); + | ^^^^^^^^^^^ + +error[E0277]: the trait bound `Vec<usize>: [const] Index<usize>` is not satisfied + --> $DIR/issue-94675.rs:9:9 + | +LL | self.bar[0] = baz.len(); + | ^^^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +note: required by a bound in `std::ops::IndexMut::index_mut` + --> $SRC_DIR/core/src/ops/index.rs:LL:COL -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/offset_ub.rs b/tests/ui/consts/offset_ub.rs index 8c52586c485..98a50156a94 100644 --- a/tests/ui/consts/offset_ub.rs +++ b/tests/ui/consts/offset_ub.rs @@ -5,17 +5,17 @@ use std::ptr; //@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" -pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~ ERROR -pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; //~ ERROR -pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; //~ ERROR +pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~ ERROR: is at the beginning of the allocation +pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; //~ ERROR: only 1 byte from the end of the allocation +pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; //~ ERROR: only 100 bytes from the end of the allocation -pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; //~ ERROR -pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; //~ ERROR +pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; //~ ERROR: does not fit in an `isize` +pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; //~ ERROR: does not fit in an `isize` pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; //~ ERROR pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; //~ ERROR -pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; //~ ERROR +pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; //~ ERROR: before the beginning of the allocation -pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; //~ ERROR +pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; //~ ERROR: at or beyond the end of the allocation pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) }; //~ ERROR // Make sure that we don't panic when computing abs(offset*size_of::<T>()) diff --git a/tests/ui/consts/offset_ub.stderr b/tests/ui/consts/offset_ub.stderr index 255583ce91c..d92ca09223d 100644 --- a/tests/ui/consts/offset_ub.stderr +++ b/tests/ui/consts/offset_ub.stderr @@ -40,11 +40,11 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNDERFLOW_ADDRESS_SPACE` failed here -error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by -$BYTES bytes, but got ALLOC3-0x2 which is only $BYTES bytes from the beginning of the allocation +error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by -$BYTES bytes, but got ALLOC3-0x2 which points to before the beginning of the allocation --> $DIR/offset_ub.rs:16:49 | -LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NEGATIVE_OFFSET` failed here +LL | ...*const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NEGATIVE_OFFSET` failed here error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 1 byte, but got ALLOC4 which is at or beyond the end of the allocation of size $BYTES bytes --> $DIR/offset_ub.rs:18:50 diff --git a/tests/ui/consts/rustc-const-stability-require-const.stderr b/tests/ui/consts/rustc-const-stability-require-const.stderr index 4b13826584d..8d10bddaa45 100644 --- a/tests/ui/consts/rustc-const-stability-require-const.stderr +++ b/tests/ui/consts/rustc-const-stability-require-const.stderr @@ -23,30 +23,6 @@ LL | pub fn bar() {} | ^^^^^^^^^^^^ error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` - --> $DIR/rustc-const-stability-require-const.rs:21:5 - | -LL | pub fn salad(&self) -> &'static str { "mmmmmm" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: make the function or method const - --> $DIR/rustc-const-stability-require-const.rs:21:5 - | -LL | pub fn salad(&self) -> &'static str { "mmmmmm" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` - --> $DIR/rustc-const-stability-require-const.rs:26:5 - | -LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: make the function or method const - --> $DIR/rustc-const-stability-require-const.rs:26:5 - | -LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` --> $DIR/rustc-const-stability-require-const.rs:32:1 | LL | pub extern "C" fn bar_c() {} @@ -86,5 +62,29 @@ LL | #[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")] LL | pub const fn barfoo_unstable() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:21:5 + | +LL | pub fn salad(&self) -> &'static str { "mmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:21:5 + | +LL | pub fn salad(&self) -> &'static str { "mmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` + --> $DIR/rustc-const-stability-require-const.rs:26:5 + | +LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function or method const + --> $DIR/rustc-const-stability-require-const.rs:26:5 + | +LL | pub fn roasted(&self) -> &'static str { "mmmmmmmmmm" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 8 previous errors diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index a3ef4031a13..55c08539688 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -1,10 +1,10 @@ -error: const `impl` for trait `Debug` which is not marked with `#[const_trait]` +error: const `impl` for trait `Debug` which is not `const` --> $DIR/rustc-impl-const-stability.rs:15:12 | LL | impl const std::fmt::Debug for Data { | ^^^^^^^^^^^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error: aborting due to 1 previous error diff --git a/tests/ui/contracts/contract-attributes-generics.rs b/tests/ui/contracts/contract-attributes-generics.rs index fd79c6abedd..3763ce116f8 100644 --- a/tests/ui/contracts/contract-attributes-generics.rs +++ b/tests/ui/contracts/contract-attributes-generics.rs @@ -5,9 +5,9 @@ //@ [unchk_pass] run-pass //@ [chk_pass] run-pass // -//@ [chk_fail_pre] run-fail -//@ [chk_fail_post] run-fail -//@ [chk_const_fail] run-fail +//@ [chk_fail_pre] run-crash +//@ [chk_fail_post] run-crash +//@ [chk_const_fail] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no // diff --git a/tests/ui/contracts/contract-attributes-nest.rs b/tests/ui/contracts/contract-attributes-nest.rs index e1e61b88f28..d367687b84e 100644 --- a/tests/ui/contracts/contract-attributes-nest.rs +++ b/tests/ui/contracts/contract-attributes-nest.rs @@ -5,8 +5,8 @@ //@ [unchk_fail_post] run-pass //@ [chk_pass] run-pass // -//@ [chk_fail_pre] run-fail -//@ [chk_fail_post] run-fail +//@ [chk_fail_pre] run-crash +//@ [chk_fail_post] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no diff --git a/tests/ui/contracts/contract-attributes-tail.rs b/tests/ui/contracts/contract-attributes-tail.rs index ce4a6be5b82..43edfe5e803 100644 --- a/tests/ui/contracts/contract-attributes-tail.rs +++ b/tests/ui/contracts/contract-attributes-tail.rs @@ -5,8 +5,8 @@ //@ [unchk_fail_post] run-pass //@ [chk_pass] run-pass // -//@ [chk_fail_pre] run-fail -//@ [chk_fail_post] run-fail +//@ [chk_fail_pre] run-crash +//@ [chk_fail_post] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.rs b/tests/ui/contracts/contract-captures-via-closure-copy.rs index 32c6d2bf4fe..bc7e5b9b6f1 100644 --- a/tests/ui/contracts/contract-captures-via-closure-copy.rs +++ b/tests/ui/contracts/contract-captures-via-closure-copy.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Zcontract-checks=yes #![feature(contracts)] diff --git a/tests/ui/contracts/contract-const-fn.rs b/tests/ui/contracts/contract-const-fn.rs index 733a06ae570..fe8dd37b1f5 100644 --- a/tests/ui/contracts/contract-const-fn.rs +++ b/tests/ui/contracts/contract-const-fn.rs @@ -8,8 +8,8 @@ // //@ [all_pass] run-pass // -//@ [runtime_fail_pre] run-fail -//@ [runtime_fail_post] run-fail +//@ [runtime_fail_pre] run-crash +//@ [runtime_fail_post] run-crash // //@ [all_pass] compile-flags: -Zcontract-checks=yes //@ [runtime_fail_pre] compile-flags: -Zcontract-checks=yes diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs index 034cead3b4e..44ae07d8c95 100644 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs +++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs @@ -2,9 +2,9 @@ // //@ [unchk_pass] run-pass //@ [chk_pass] run-pass -//@ [chk_fail_try] run-fail -//@ [chk_fail_ret] run-fail -//@ [chk_fail_yeet] run-fail +//@ [chk_fail_try] run-crash +//@ [chk_fail_ret] run-crash +//@ [chk_fail_yeet] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [chk_pass] compile-flags: -Zcontract-checks=yes diff --git a/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs b/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs index 6d8cd3949ee..4da0480f8bc 100644 --- a/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs +++ b/tests/ui/contracts/internal_machinery/contract-ast-extensions-nest.rs @@ -5,8 +5,8 @@ //@ [unchk_fail_post] run-pass //@ [chk_pass] run-pass // -//@ [chk_fail_pre] run-fail -//@ [chk_fail_post] run-fail +//@ [chk_fail_pre] run-crash +//@ [chk_fail_post] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no diff --git a/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs b/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs index 07ec26f921b..f3cf5ce082c 100644 --- a/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs +++ b/tests/ui/contracts/internal_machinery/contract-ast-extensions-tail.rs @@ -5,8 +5,8 @@ //@ [unchk_fail_post] run-pass //@ [chk_pass] run-pass // -//@ [chk_fail_pre] run-fail -//@ [chk_fail_post] run-fail +//@ [chk_fail_pre] run-crash +//@ [chk_fail_post] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [unchk_fail_pre] compile-flags: -Zcontract-checks=no diff --git a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs index c62b8cca75a..6e613b53fc9 100644 --- a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs +++ b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs @@ -3,8 +3,8 @@ //@ [default] run-pass //@ [unchk_pass] run-pass //@ [chk_pass] run-pass -//@ [chk_fail_requires] run-fail -//@ [chk_fail_ensures] run-fail +//@ [chk_fail_requires] run-crash +//@ [chk_fail_ensures] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [chk_pass] compile-flags: -Zcontract-checks=yes diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.rs b/tests/ui/contracts/internal_machinery/contract-lang-items.rs index 73c59194531..ac72d233bf6 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.rs +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.rs @@ -4,7 +4,7 @@ //@ [unchk_fail_post] run-pass //@ [chk_pass] run-pass // -//@ [chk_fail_post] run-fail +//@ [chk_fail_post] run-crash // //@ [unchk_pass] compile-flags: -Zcontract-checks=no //@ [unchk_fail_post] compile-flags: -Zcontract-checks=no diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs index b07fad18aee..e528f031d52 100644 --- a/tests/ui/coroutine/clone-impl.rs +++ b/tests/ui/coroutine/clone-impl.rs @@ -38,39 +38,40 @@ fn test2() { check_clone(&gen_copy_1); } -fn test3() { +fn test3_upvars() { let clonable_0: Vec<u32> = Vec::new(); let gen_clone_0 = #[coroutine] move || { - let v = vec!['a']; - yield; - drop(v); drop(clonable_0); }; check_copy(&gen_clone_0); //~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied - //~| ERROR the trait bound `Vec<char>: Copy` is not satisfied check_clone(&gen_clone_0); } +fn test3_witness() { + let gen_clone_1 = #[coroutine] + move || { + let v = vec!['a']; + yield; + drop(v); + }; + check_copy(&gen_clone_1); + //~^ ERROR the trait bound `Vec<char>: Copy` is not satisfied + check_clone(&gen_clone_1); +} + fn test4() { let clonable_1: Vec<u32> = Vec::new(); let gen_clone_1 = #[coroutine] move || { - let v = vec!['a']; - /* - let n = NonClone; - drop(n); - */ yield; let n = NonClone; drop(n); - drop(v); drop(clonable_1); }; check_copy(&gen_clone_1); //~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied - //~| ERROR the trait bound `Vec<char>: Copy` is not satisfied check_clone(&gen_clone_1); } diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr index ed933fe784e..714e5aa3d9e 100644 --- a/tests/ui/coroutine/clone-impl.stderr +++ b/tests/ui/coroutine/clone-impl.stderr @@ -1,104 +1,59 @@ error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` - --> $DIR/clone-impl.rs:50:5 + --> $DIR/clone-impl.rs:47:16 | LL | move || { | ------- within this `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<u32>` + | ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<u32>` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:48:14 + --> $DIR/clone-impl.rs:45:14 | LL | drop(clonable_0); | ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:90:18 + --> $DIR/clone-impl.rs:91:18 | LL | fn check_copy<T: Copy>(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` - --> $DIR/clone-impl.rs:50:5 +error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}` + --> $DIR/clone-impl.rs:73:16 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` -... -LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec<char>` - | -note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:46:9 - | -LL | let v = vec!['a']; - | - has type `Vec<char>` which does not implement `Copy` -LL | yield; - | ^^^^^ yield occurs here, with `v` maybe used later -note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:90:18 - | -LL | fn check_copy<T: Copy>(_x: &T) {} - | ^^^^ required by this bound in `check_copy` - -error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` - --> $DIR/clone-impl.rs:71:5 - | -LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`, the trait `Copy` is not implemented for `Vec<u32>` + | ^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:67:5: 67:12}`, the trait `Copy` is not implemented for `Vec<u32>` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:69:14 + --> $DIR/clone-impl.rs:71:14 | LL | drop(clonable_1); | ^^^^^^^^^^ has type `Vec<u32>` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:90:18 - | -LL | fn check_copy<T: Copy>(_x: &T) {} - | ^^^^ required by this bound in `check_copy` - -error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` - --> $DIR/clone-impl.rs:71:5 - | -LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` -... -LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`, the trait `Copy` is not implemented for `Vec<char>` - | -note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:65:9 - | -LL | let v = vec!['a']; - | - has type `Vec<char>` which does not implement `Copy` -... -LL | yield; - | ^^^^^ yield occurs here, with `v` maybe used later -note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:90:18 + --> $DIR/clone-impl.rs:91:18 | LL | fn check_copy<T: Copy>(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` - --> $DIR/clone-impl.rs:84:5 +error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}` + --> $DIR/clone-impl.rs:85:16 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}` ... LL | check_copy(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`, the trait `Copy` is not implemented for `NonClone` + | ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Copy` is not implemented for `NonClone` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:82:14 + --> $DIR/clone-impl.rs:83:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:90:18 + --> $DIR/clone-impl.rs:91:18 | LL | fn check_copy<T: Copy>(_x: &T) {} | ^^^^ required by this bound in `check_copy` @@ -108,22 +63,22 @@ LL + #[derive(Copy)] LL | struct NonClone; | -error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` - --> $DIR/clone-impl.rs:86:5 +error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}` + --> $DIR/clone-impl.rs:87:17 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}` ... LL | check_clone(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`, the trait `Clone` is not implemented for `NonClone` + | ^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:81:5: 81:12}`, the trait `Clone` is not implemented for `NonClone` | note: captured value does not implement `Clone` - --> $DIR/clone-impl.rs:82:14 + --> $DIR/clone-impl.rs:83:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone` note: required by a bound in `check_clone` - --> $DIR/clone-impl.rs:91:19 + --> $DIR/clone-impl.rs:92:19 | LL | fn check_clone<T: Clone>(_x: &T) {} | ^^^^^ required by this bound in `check_clone` @@ -133,6 +88,28 @@ LL + #[derive(Clone)] LL | struct NonClone; | -error: aborting due to 6 previous errors +error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}` + --> $DIR/clone-impl.rs:59:5 + | +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}` +... +LL | check_copy(&gen_clone_1); + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:5: 54:12}`, the trait `Copy` is not implemented for `Vec<char>` + | +note: coroutine does not implement `Copy` as this value is used across a yield + --> $DIR/clone-impl.rs:56:9 + | +LL | let v = vec!['a']; + | - has type `Vec<char>` which does not implement `Copy` +LL | yield; + | ^^^^^ yield occurs here, with `v` maybe used later +note: required by a bound in `check_copy` + --> $DIR/clone-impl.rs:91:18 + | +LL | fn check_copy<T: Copy>(_x: &T) {} + | ^^^^ required by this bound in `check_copy` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr index 2f9f20cf1ff..4a1e5b078a8 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr +++ b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr @@ -11,7 +11,7 @@ LL | | }; | |_____^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str witness=?6t}` + found coroutine `{main::{closure#0} upvar_tys=?4t resume_ty=() yield_ty=i32 return_ty=&'?1 str witness={main::{closure#0}}}` error: aborting due to 1 previous error diff --git a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr index dc84394fe3c..5a003af42da 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr +++ b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr @@ -1,10 +1,10 @@ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/bad-attr-ice.rs:11:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ @@ -13,3 +13,4 @@ LL | #[coverage(on)] error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr index 49b8974bfdf..4501e5e9dc8 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr +++ b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr @@ -1,26 +1,27 @@ -error: malformed `coverage` attribute input +error[E0658]: the `#[coverage]` attribute is an experimental feature --> $DIR/bad-attr-ice.rs:11:1 | LL | #[coverage] | ^^^^^^^^^^^ | -help: the following are the possible correct uses - | -LL | #[coverage(off)] - | +++++ -LL | #[coverage(on)] - | ++++ + = note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information + = help: add `#![feature(coverage_attribute)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: the `#[coverage]` attribute is an experimental feature +error[E0539]: malformed `coverage` attribute input --> $DIR/bad-attr-ice.rs:11:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | - = note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information - = help: add `#![feature(coverage_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +help: try changing it to one of the following valid forms of the attribute + | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0539, E0658. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index fa500b54209..927f61da08d 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr @@ -1,23 +1,59 @@ -error: malformed `coverage` attribute input +error: expected identifier, found `,` + --> $DIR/bad-syntax.rs:44:12 + | +LL | #[coverage(,off)] + | ^ expected identifier + | +help: remove this comma + | +LL - #[coverage(,off)] +LL + #[coverage(off)] + | + +error: multiple `coverage` attributes + --> $DIR/bad-syntax.rs:9:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:10:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ + +error: multiple `coverage` attributes + --> $DIR/bad-syntax.rs:13:1 + | +LL | #[coverage(off)] + | ^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/bad-syntax.rs:14:1 + | +LL | #[coverage(on)] + | ^^^^^^^^^^^^^^^ + +error[E0539]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:17:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:20:1 | LL | #[coverage = true] - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = true] LL + #[coverage(off)] @@ -26,26 +62,30 @@ LL - #[coverage = true] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0805]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:23:1 | LL | #[coverage()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^--^ + | | + | expected a single argument here | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++ LL | #[coverage(on)] | ++ -error: malformed `coverage` attribute input +error[E0805]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:26:1 | LL | #[coverage(off, off)] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^----------^ + | | + | expected a single argument here | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(off, off)] LL + #[coverage(off)] @@ -54,13 +94,15 @@ LL - #[coverage(off, off)] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0805]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:29:1 | LL | #[coverage(off, on)] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^---------^ + | | + | expected a single argument here | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(off, on)] LL + #[coverage(off)] @@ -69,13 +111,15 @@ LL - #[coverage(off, on)] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:32:1 | LL | #[coverage(bogus)] - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^-----^^ + | | + | valid arguments are `on` or `off` | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(bogus)] LL + #[coverage(off)] @@ -84,13 +128,15 @@ LL - #[coverage(bogus)] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0805]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:35:1 | LL | #[coverage(bogus, off)] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^------------^ + | | + | expected a single argument here | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(bogus, off)] LL + #[coverage(off)] @@ -99,13 +145,15 @@ LL - #[coverage(bogus, off)] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0805]: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:38:1 | LL | #[coverage(off, bogus)] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^------------^ + | | + | expected a single argument here | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(off, bogus)] LL + #[coverage(off)] @@ -114,41 +162,7 @@ LL - #[coverage(off, bogus)] LL + #[coverage(on)] | -error: expected identifier, found `,` - --> $DIR/bad-syntax.rs:44:12 - | -LL | #[coverage(,off)] - | ^ expected identifier - | -help: remove this comma - | -LL - #[coverage(,off)] -LL + #[coverage(off)] - | - -error: multiple `coverage` attributes - --> $DIR/bad-syntax.rs:9:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/bad-syntax.rs:10:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ - -error: multiple `coverage` attributes - --> $DIR/bad-syntax.rs:13:1 - | -LL | #[coverage(off)] - | ^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/bad-syntax.rs:14:1 - | -LL | #[coverage(on)] - | ^^^^^^^^^^^^^^^ - error: aborting due to 11 previous errors +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/coverage-attr/name-value.rs b/tests/ui/coverage-attr/name-value.rs index ffd9afe2ce1..8171dbbf692 100644 --- a/tests/ui/coverage-attr/name-value.rs +++ b/tests/ui/coverage-attr/name-value.rs @@ -20,7 +20,6 @@ mod my_mod_inner { #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input -//~| ERROR [E0788] struct MyStruct; #[coverage = "off"] @@ -28,22 +27,18 @@ struct MyStruct; impl MyStruct { #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] const X: u32 = 7; } #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input -//~| ERROR [E0788] trait MyTrait { #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] const X: u32; #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] type T; } @@ -52,12 +47,10 @@ trait MyTrait { impl MyTrait for MyStruct { #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] const X: u32 = 8; #[coverage = "off"] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] type T = (); } diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr index f24db78415e..a838ec5df8e 100644 --- a/tests/ui/coverage-attr/name-value.stderr +++ b/tests/ui/coverage-attr/name-value.stderr @@ -1,10 +1,10 @@ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:12:1 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -13,28 +13,28 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:17:5 | LL | #![coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #![coverage = "off"] -LL + #![coverage(off)] +LL + #[coverage(off)] | LL - #![coverage = "off"] -LL + #![coverage(on)] +LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:21:1 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -43,13 +43,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:26:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:25:1 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -58,13 +58,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:29:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:28:5 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -73,13 +73,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:35:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:33:1 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -88,13 +88,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:39:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:36:5 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -103,13 +103,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:44:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:40:5 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -118,13 +118,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:50:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:45:1 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -133,13 +133,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:53:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:48:5 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -148,13 +148,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:58:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:52:5 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -163,13 +163,13 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error: malformed `coverage` attribute input - --> $DIR/name-value.rs:64:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/name-value.rs:57:1 | LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage = "off"] LL + #[coverage(off)] @@ -178,87 +178,6 @@ LL - #[coverage = "off"] LL + #[coverage(on)] | -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:21:1 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | struct MyStruct; - | ---------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:35:1 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | / trait MyTrait { -LL | | #[coverage = "off"] -... | -LL | | type T; -LL | | } - | |_- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:39:5 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | const X: u32; - | ------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:44:5 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | type T; - | ------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:29:5 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | const X: u32 = 7; - | ----------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:53:5 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | const X: u32 = 8; - | ----------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/name-value.rs:58:5 - | -LL | #[coverage = "off"] - | ^^^^^^^^^^^^^^^^^^^ -... -LL | type T = (); - | ------------ not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error: aborting due to 19 previous errors +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0788`. +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/coverage-attr/subword.stderr b/tests/ui/coverage-attr/subword.stderr index a5d1a492181..32a09a10c84 100644 --- a/tests/ui/coverage-attr/subword.stderr +++ b/tests/ui/coverage-attr/subword.stderr @@ -1,10 +1,12 @@ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/subword.rs:8:1 | LL | #[coverage(yes(milord))] - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^-----------^^ + | | + | valid arguments are `on` or `off` | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(yes(milord))] LL + #[coverage(off)] @@ -13,13 +15,15 @@ LL - #[coverage(yes(milord))] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/subword.rs:11:1 | LL | #[coverage(no(milord))] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^----------^^ + | | + | valid arguments are `on` or `off` | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(no(milord))] LL + #[coverage(off)] @@ -28,13 +32,15 @@ LL - #[coverage(no(milord))] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/subword.rs:14:1 | LL | #[coverage(yes = "milord")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^--------------^^ + | | + | valid arguments are `on` or `off` | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(yes = "milord")] LL + #[coverage(off)] @@ -43,13 +49,15 @@ LL - #[coverage(yes = "milord")] LL + #[coverage(on)] | -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/subword.rs:17:1 | LL | #[coverage(no = "milord")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^-------------^^ + | | + | valid arguments are `on` or `off` | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL - #[coverage(no = "milord")] LL + #[coverage(off)] @@ -60,3 +68,4 @@ LL + #[coverage(on)] error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/coverage-attr/word-only.rs b/tests/ui/coverage-attr/word-only.rs index d0f743938f3..81bd558b8b0 100644 --- a/tests/ui/coverage-attr/word-only.rs +++ b/tests/ui/coverage-attr/word-only.rs @@ -20,7 +20,6 @@ mod my_mod_inner { #[coverage] //~^ ERROR malformed `coverage` attribute input -//~| ERROR [E0788] struct MyStruct; #[coverage] @@ -28,22 +27,18 @@ struct MyStruct; impl MyStruct { #[coverage] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] const X: u32 = 7; } #[coverage] //~^ ERROR malformed `coverage` attribute input -//~| ERROR [E0788] trait MyTrait { #[coverage] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] const X: u32; #[coverage] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] type T; } @@ -52,12 +47,10 @@ trait MyTrait { impl MyTrait for MyStruct { #[coverage] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] const X: u32 = 8; #[coverage] //~^ ERROR malformed `coverage` attribute input - //~| ERROR [E0788] type T = (); } diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index 2773db9c857..dd161360a5c 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -1,240 +1,161 @@ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:12:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:17:5 | LL | #![coverage] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute + | +LL - #![coverage] +LL + #[coverage(off)] + | +LL - #![coverage] +LL + #[coverage(on)] | -LL | #![coverage(off)] - | +++++ -LL | #![coverage(on)] - | ++++ -error: malformed `coverage` attribute input +error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:21:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:26:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:25:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:29:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:28:5 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:35:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:33:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:39:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:36:5 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:44:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:40:5 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:50:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:45:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:53:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:48:5 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:58:5 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:52:5 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error: malformed `coverage` attribute input - --> $DIR/word-only.rs:64:1 +error[E0539]: malformed `coverage` attribute input + --> $DIR/word-only.rs:57:1 | LL | #[coverage] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument | -help: the following are the possible correct uses +help: try changing it to one of the following valid forms of the attribute | LL | #[coverage(off)] | +++++ LL | #[coverage(on)] | ++++ -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:21:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | struct MyStruct; - | ---------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:35:1 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | / trait MyTrait { -LL | | #[coverage] -... | -LL | | type T; -LL | | } - | |_- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:39:5 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | const X: u32; - | ------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:44:5 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | type T; - | ------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:29:5 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | const X: u32 = 7; - | ----------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:53:5 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | const X: u32 = 8; - | ----------------- not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error[E0788]: coverage attribute not allowed here - --> $DIR/word-only.rs:58:5 - | -LL | #[coverage] - | ^^^^^^^^^^^ -... -LL | type T = (); - | ------------ not a function, impl block, or module - | - = help: coverage attribute can be applied to a function (with body), impl block, or module - -error: aborting due to 19 previous errors +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0788`. +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/deduplicate-diagnostics.deduplicate.stderr b/tests/ui/diagnostic-flags/deduplicate-diagnostics.deduplicate.stderr index 5df2c687bdd..c0d568eb538 100644 --- a/tests/ui/deduplicate-diagnostics.deduplicate.stderr +++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics.deduplicate.stderr @@ -1,11 +1,11 @@ error[E0452]: malformed lint attribute input - --> $DIR/deduplicate-diagnostics.rs:8:8 + --> $DIR/deduplicate-diagnostics.rs:10:8 | LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument error: cannot find derive macro `Unresolved` in this scope - --> $DIR/deduplicate-diagnostics.rs:4:10 + --> $DIR/deduplicate-diagnostics.rs:6:10 | LL | #[derive(Unresolved)] | ^^^^^^^^^^ diff --git a/tests/ui/deduplicate-diagnostics.duplicate.stderr b/tests/ui/diagnostic-flags/deduplicate-diagnostics.duplicate.stderr index 48e2ba7b86a..74d7066293f 100644 --- a/tests/ui/deduplicate-diagnostics.duplicate.stderr +++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics.duplicate.stderr @@ -1,17 +1,17 @@ error[E0452]: malformed lint attribute input - --> $DIR/deduplicate-diagnostics.rs:8:8 + --> $DIR/deduplicate-diagnostics.rs:10:8 | LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument error: cannot find derive macro `Unresolved` in this scope - --> $DIR/deduplicate-diagnostics.rs:4:10 + --> $DIR/deduplicate-diagnostics.rs:6:10 | LL | #[derive(Unresolved)] | ^^^^^^^^^^ error: cannot find derive macro `Unresolved` in this scope - --> $DIR/deduplicate-diagnostics.rs:4:10 + --> $DIR/deduplicate-diagnostics.rs:6:10 | LL | #[derive(Unresolved)] | ^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | #[derive(Unresolved)] = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input - --> $DIR/deduplicate-diagnostics.rs:8:8 + --> $DIR/deduplicate-diagnostics.rs:10:8 | LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument @@ -27,7 +27,7 @@ LL | #[deny("literal")] = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input - --> $DIR/deduplicate-diagnostics.rs:8:8 + --> $DIR/deduplicate-diagnostics.rs:10:8 | LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument diff --git a/tests/ui/deduplicate-diagnostics.rs b/tests/ui/diagnostic-flags/deduplicate-diagnostics.rs index 299c1f5f461..48705266e35 100644 --- a/tests/ui/deduplicate-diagnostics.rs +++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics.rs @@ -1,3 +1,5 @@ +//! Test that `-Z deduplicate-diagnostics` flag properly deduplicates diagnostic messages. + //@ revisions: duplicate deduplicate //@[deduplicate] compile-flags: -Z deduplicate-diagnostics=yes diff --git a/tests/ui/error-codes/E0120.rs b/tests/ui/error-codes/E0120.rs index 35f544fddfb..4e5cc7d6833 100644 --- a/tests/ui/error-codes/E0120.rs +++ b/tests/ui/error-codes/E0120.rs @@ -1,4 +1,4 @@ -trait MyTrait { fn foo() {} } +trait MyTrait { fn foo(&self) {} } impl Drop for dyn MyTrait { //~^ ERROR E0120 diff --git a/tests/ui/expr/syntax-edge-cases-lint-clean.rs b/tests/ui/expr/weird-exprs.rs index 7db92d46067..7db92d46067 100644 --- a/tests/ui/expr/syntax-edge-cases-lint-clean.rs +++ b/tests/ui/expr/weird-exprs.rs diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs index 75f3eab3e27..035f063cd50 100644 --- a/tests/ui/extern/extern-types-field-offset.rs +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 //@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs index 3ff51b9b6b0..875ae9a535a 100644 --- a/tests/ui/extern/extern-types-size_of_val.rs +++ b/tests/ui/extern/extern-types-size_of_val.rs @@ -1,4 +1,4 @@ -//@ check-fail +//@ check-pass #![feature(extern_types)] use std::mem::{align_of_val, size_of_val}; @@ -11,7 +11,5 @@ fn main() { let x: &A = unsafe { &*(1usize as *const A) }; size_of_val(x); - //~^ ERROR the size for values of type `A` cannot be known align_of_val(x); - //~^ ERROR the size for values of type `A` cannot be known } diff --git a/tests/ui/extern/extern-types-size_of_val.stderr b/tests/ui/extern/extern-types-size_of_val.stderr deleted file mode 100644 index 8678c6c3d60..00000000000 --- a/tests/ui/extern/extern-types-size_of_val.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0277]: the size for values of type `A` cannot be known - --> $DIR/extern-types-size_of_val.rs:13:17 - | -LL | size_of_val(x); - | ----------- ^ the trait `MetaSized` is not implemented for `A` - | | - | required by a bound introduced by this call - | - = note: the trait bound `A: MetaSized` is not satisfied -note: required by a bound in `std::mem::size_of_val` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -help: consider borrowing here - | -LL | size_of_val(&x); - | + -LL | size_of_val(&mut x); - | ++++ - -error[E0277]: the size for values of type `A` cannot be known - --> $DIR/extern-types-size_of_val.rs:15:18 - | -LL | align_of_val(x); - | ------------ ^ the trait `MetaSized` is not implemented for `A` - | | - | required by a bound introduced by this call - | - = note: the trait bound `A: MetaSized` is not satisfied -note: required by a bound in `std::mem::align_of_val` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -help: consider borrowing here - | -LL | align_of_val(&x); - | + -LL | align_of_val(&mut x); - | ++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/extern-types-unsized.rs b/tests/ui/extern/extern-types-unsized.rs index 46cdc24e083..94a222a7e7e 100644 --- a/tests/ui/extern/extern-types-unsized.rs +++ b/tests/ui/extern/extern-types-unsized.rs @@ -27,9 +27,7 @@ fn main() { assert_sized::<Bar<A>>(); //~^ ERROR the size for values of type - //~| ERROR the size for values of type assert_sized::<Bar<Bar<A>>>(); //~^ ERROR the size for values of type - //~| ERROR the size for values of type } diff --git a/tests/ui/extern/extern-types-unsized.stderr b/tests/ui/extern/extern-types-unsized.stderr index 43dd9800d6d..a587d4dda55 100644 --- a/tests/ui/extern/extern-types-unsized.stderr +++ b/tests/ui/extern/extern-types-unsized.stderr @@ -59,21 +59,8 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_sized<T: ?Sized>() {} | ++++++++ -error[E0277]: the size for values of type `A` cannot be known - --> $DIR/extern-types-unsized.rs:28:20 - | -LL | assert_sized::<Bar<A>>(); - | ^^^^^^ doesn't have a known size - | - = help: the trait `MetaSized` is not implemented for `A` -note: required by a bound in `Bar` - --> $DIR/extern-types-unsized.rs:14:12 - | -LL | struct Bar<T: ?Sized> { - | ^ required by this bound in `Bar` - error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:32:20 + --> $DIR/extern-types-unsized.rs:31:20 | LL | assert_sized::<Bar<Bar<A>>>(); | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -94,19 +81,6 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_sized<T: ?Sized>() {} | ++++++++ -error[E0277]: the size for values of type `A` cannot be known - --> $DIR/extern-types-unsized.rs:32:20 - | -LL | assert_sized::<Bar<Bar<A>>>(); - | ^^^^^^^^^^^ doesn't have a known size - | - = help: the trait `MetaSized` is not implemented for `A` -note: required by a bound in `Bar` - --> $DIR/extern-types-unsized.rs:14:12 - | -LL | struct Bar<T: ?Sized> { - | ^ required by this bound in `Bar` - -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/unsized-extern-derefmove.rs b/tests/ui/extern/unsized-extern-derefmove.rs index c02375266ab..39597a12fe1 100644 --- a/tests/ui/extern/unsized-extern-derefmove.rs +++ b/tests/ui/extern/unsized-extern-derefmove.rs @@ -7,14 +7,10 @@ extern "C" { } unsafe fn make_device() -> Box<Device> { -//~^ ERROR the size for values of type `Device` cannot be known Box::from_raw(0 as *mut _) -//~^ ERROR the size for values of type `Device` cannot be known -//~| ERROR the size for values of type `Device` cannot be known } fn main() { let d: Device = unsafe { *make_device() }; //~^ ERROR the size for values of type `Device` cannot be known -//~| ERROR the size for values of type `Device` cannot be known } diff --git a/tests/ui/extern/unsized-extern-derefmove.stderr b/tests/ui/extern/unsized-extern-derefmove.stderr index a9efc2e66e3..c43184d94e1 100644 --- a/tests/ui/extern/unsized-extern-derefmove.stderr +++ b/tests/ui/extern/unsized-extern-derefmove.stderr @@ -1,43 +1,5 @@ -error[E0277]: the size for values of type `Device` cannot be known - --> $DIR/unsized-extern-derefmove.rs:9:28 - | -LL | unsafe fn make_device() -> Box<Device> { - | ^^^^^^^^^^^ doesn't have a known size - | - = help: the trait `MetaSized` is not implemented for `Device` -note: required by a bound in `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - -error[E0277]: the size for values of type `Device` cannot be known - --> $DIR/unsized-extern-derefmove.rs:11:19 - | -LL | Box::from_raw(0 as *mut _) - | ------------- ^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Device` - | | - | required by a bound introduced by this call - | - = note: the trait bound `Device: MetaSized` is not satisfied -note: required by a bound in `Box::<T>::from_raw` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -help: consider borrowing here - | -LL | Box::from_raw(&(0 as *mut _)) - | ++ + -LL | Box::from_raw(&mut (0 as *mut _)) - | ++++++ + - -error[E0277]: the size for values of type `Device` cannot be known - --> $DIR/unsized-extern-derefmove.rs:11:5 - | -LL | Box::from_raw(0 as *mut _) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size - | - = help: the trait `MetaSized` is not implemented for `Device` -note: required by a bound in `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - error[E0277]: the size for values of type `Device` cannot be known at compilation time - --> $DIR/unsized-extern-derefmove.rs:17:9 + --> $DIR/unsized-extern-derefmove.rs:14:9 | LL | let d: Device = unsafe { *make_device() }; | ^ doesn't have a size known at compile-time @@ -49,16 +11,6 @@ help: consider borrowing here LL | let d: &Device = unsafe { *make_device() }; | + -error[E0277]: the size for values of type `Device` cannot be known - --> $DIR/unsized-extern-derefmove.rs:17:31 - | -LL | let d: Device = unsafe { *make_device() }; - | ^^^^^^^^^^^^^ doesn't have a known size - | - = help: the trait `MetaSized` is not implemented for `Device` -note: required by a bound in `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - -error: aborting due to 5 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs index 6a832744e3e..9c727ae3aad 100644 --- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs @@ -2,23 +2,13 @@ trait Trait1 {} auto trait Trait2 {} -trait Trait3: ?Trait1 {} -//~^ ERROR `?Trait` is not permitted in supertraits -trait Trait4 where Self: ?Trait1 {} -//~^ ERROR ?Trait` bounds are only permitted at the point where a type parameter is declared +trait Trait3: ?Trait1 {} //~ ERROR relaxed bounds are not permitted in supertrait bounds +trait Trait4 where Self: ?Trait1 {} //~ ERROR this relaxed bound is not permitted here fn foo(_: Box<dyn Trait1 + ?Trait2>) {} -//~^ ERROR `?Trait` is not permitted in trait object types +//~^ ERROR relaxed bounds are not permitted in trait object types fn bar<T: ?Trait1 + ?Trait2>(_: T) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - -trait Trait {} -// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions -fn baz<T: ?Trait + ?Trait>(_ : T) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~^ ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr index 729df4eb37c..da6ad5f16e2 100644 --- a/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr @@ -1,71 +1,34 @@ -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/feature-gate-more-maybe-bounds.rs:5:15 | LL | trait Trait3: ?Trait1 {} | ^^^^^^^ - | - = note: traits are `?Trait1` by default - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/feature-gate-more-maybe-bounds.rs:10:28 - | -LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {} - | ^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/feature-gate-more-maybe-bounds.rs:7:26 +error: this relaxed bound is not permitted here + --> $DIR/feature-gate-more-maybe-bounds.rs:6:26 | LL | trait Trait4 where Self: ?Trait1 {} | ^^^^^^^ | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/feature-gate-more-maybe-bounds.rs:12:11 - | -LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {} - | ^^^^^^^ ^^^^^^^ +error: relaxed bounds are not permitted in trait object types + --> $DIR/feature-gate-more-maybe-bounds.rs:8:28 | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {} + | ^^^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/feature-gate-more-maybe-bounds.rs:12:11 +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/feature-gate-more-maybe-bounds.rs:10:11 | LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {} | ^^^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/feature-gate-more-maybe-bounds.rs:12:21 +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/feature-gate-more-maybe-bounds.rs:10:21 | LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {} | ^^^^^^^ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/feature-gate-more-maybe-bounds.rs:19:11 - | -LL | fn baz<T: ?Trait + ?Trait>(_ : T) {} - | ^^^^^^ ^^^^^^ - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/feature-gate-more-maybe-bounds.rs:19:11 - | -LL | fn baz<T: ?Trait + ?Trait>(_ : T) {} - | ^^^^^^ - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/feature-gate-more-maybe-bounds.rs:19:20 - | -LL | fn baz<T: ?Trait + ?Trait>(_ : T) {} - | ^^^^^^ - -error: aborting due to 9 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0203, E0658. -For more information about an error, try `rustc --explain E0203`. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index d07201ebbd1..9740eaaf1e9 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -269,7 +269,13 @@ mod automatically_derived { #[automatically_derived] type T = S; //~^ WARN `#[automatically_derived] + #[automatically_derived] trait W { } + //~^ WARN `#[automatically_derived] + #[automatically_derived] impl S { } + //~^ WARN `#[automatically_derived] + + #[automatically_derived] impl W for S { } } #[no_mangle] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 5d7d1caeeab..9016ca1efa7 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -1,5 +1,5 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:391:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:17 | LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | mod inner { #![macro_escape] } = help: try an outer attribute: `#[macro_use]` warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:388:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ @@ -198,14 +198,14 @@ note: the lint level is defined here LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on implementation blocks +warning: `#[automatically_derived]` only has an effect on trait implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:281:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ @@ -220,31 +220,31 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: `#[should_panic]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:315:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:1 | LL | #[should_panic] | ^^^^^^^^^^^^^^^ warning: `#[ignore]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:339:1 | LL | #[ignore] | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:368:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:1 | LL | #[reexport_test_harness_main = "2900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:1 | LL | #[no_std] | ^^^^^^^^^ warning: attribute should be applied to a function definition - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:444:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:1 | LL | #[cold] | ^^^^^^^ @@ -260,7 +260,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:1 | LL | #[link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -276,7 +276,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:518:1 | LL | #[link_section = "1800"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -292,7 +292,7 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:550:1 | LL | #[link()] | ^^^^^^^^^ @@ -308,55 +308,55 @@ LL | | } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: `#[must_use]` has no effect when applied to a module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:595:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:601:1 | LL | #[must_use] | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:608:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:1 | LL | #[windows_subsystem = "windows"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:629:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:648:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:654:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:1 | LL | #[no_main] | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:1 | LL | #[no_builtins] | ^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -417,6 +417,14 @@ LL | #![cold] | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:85:12 + | +LL | #![feature(rust1)] + | ^^^^^ + | + = note: `#[warn(stable_features)]` on by default + warning: `#[macro_use]` only has an effect on `extern crate` and modules --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:5 | @@ -495,32 +503,44 @@ warning: `#[path]` only has an effect on modules LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on implementation blocks +warning: `#[automatically_derived]` only has an effect on trait implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:17 | LL | mod inner { #![automatically_derived] } | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on implementation blocks +warning: `#[automatically_derived]` only has an effect on trait implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:5 | LL | #[automatically_derived] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on implementation blocks +warning: `#[automatically_derived]` only has an effect on trait implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:5 | LL | #[automatically_derived] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on implementation blocks +warning: `#[automatically_derived]` only has an effect on trait implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:269:5 | LL | #[automatically_derived] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ +warning: `#[automatically_derived]` only has an effect on trait implementation blocks + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:272:5 + | +LL | #[automatically_derived] trait W { } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[automatically_derived]` only has an effect on trait implementation blocks + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:5 + | +LL | #[automatically_derived] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:280:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:286:17 | LL | mod inner { #![no_mangle] } | ------------^^^^^^^^^^^^^-- not a free function, impl method or static @@ -528,7 +548,7 @@ LL | mod inner { #![no_mangle] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:287:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:293:5 | LL | #[no_mangle] struct S; | ^^^^^^^^^^^^ --------- not a free function, impl method or static @@ -536,7 +556,7 @@ LL | #[no_mangle] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:292:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:298:5 | LL | #[no_mangle] type T = S; | ^^^^^^^^^^^^ ----------- not a free function, impl method or static @@ -544,7 +564,7 @@ LL | #[no_mangle] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:297:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:303:5 | LL | #[no_mangle] impl S { } | ^^^^^^^^^^^^ ---------- not a free function, impl method or static @@ -552,7 +572,7 @@ LL | #[no_mangle] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:303:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:309:9 | LL | #[no_mangle] fn foo(); | ^^^^^^^^^^^^ --------- not a free function, impl method or static @@ -560,7 +580,7 @@ LL | #[no_mangle] fn foo(); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:308:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:9 | LL | #[no_mangle] fn bar() {} | ^^^^^^^^^^^^ ----------- not a free function, impl method or static @@ -568,163 +588,163 @@ LL | #[no_mangle] fn bar() {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: `#[should_panic]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:17 | LL | mod inner { #![should_panic] } | ^^^^^^^^^^^^^^^^ warning: `#[should_panic]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:323:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:329:5 | LL | #[should_panic] struct S; | ^^^^^^^^^^^^^^^ warning: `#[should_panic]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5 | LL | #[should_panic] type T = S; | ^^^^^^^^^^^^^^^ warning: `#[should_panic]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:329:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5 | LL | #[should_panic] impl S { } | ^^^^^^^^^^^^^^^ warning: `#[ignore]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:336:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:17 | LL | mod inner { #![ignore] } | ^^^^^^^^^^ warning: `#[ignore]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:347:5 | LL | #[ignore] struct S; | ^^^^^^^^^ warning: `#[ignore]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:5 | LL | #[ignore] type T = S; | ^^^^^^^^^ warning: `#[ignore]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:347:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:353:5 | LL | #[ignore] impl S { } | ^^^^^^^^^ warning: `#[no_implicit_prelude]` only has an effect on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5 | LL | #[no_implicit_prelude] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: `#[no_implicit_prelude]` only has an effect on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5 | LL | #[no_implicit_prelude] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: `#[no_implicit_prelude]` only has an effect on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5 | LL | #[no_implicit_prelude] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: `#[no_implicit_prelude]` only has an effect on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5 | LL | #[no_implicit_prelude] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:17 | LL | mod inner { #![reexport_test_harness_main="2900"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5 | LL | #[reexport_test_harness_main = "2900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:5 | LL | #[reexport_test_harness_main = "2900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5 | LL | #[reexport_test_harness_main = "2900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:5 | LL | #[reexport_test_harness_main = "2900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[macro_escape]` only has an effect on `extern crate` and modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:395:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:5 | LL | #[macro_escape] fn f() { } | ^^^^^^^^^^^^^^^ warning: `#[macro_escape]` only has an effect on `extern crate` and modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5 | LL | #[macro_escape] struct S; | ^^^^^^^^^^^^^^^ warning: `#[macro_escape]` only has an effect on `extern crate` and modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:5 | LL | #[macro_escape] type T = S; | ^^^^^^^^^^^^^^^ warning: `#[macro_escape]` only has an effect on `extern crate` and modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5 | LL | #[macro_escape] impl S { } | ^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5 | LL | #[no_std] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5 | LL | #[no_std] type T = S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ warning: attribute should be applied to a function definition - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:456:17 | LL | mod inner { #![cold] } | ------------^^^^^^^^-- not a function definition @@ -732,7 +752,7 @@ LL | mod inner { #![cold] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function definition - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5 | LL | #[cold] struct S; | ^^^^^^^ --------- not a function definition @@ -740,7 +760,7 @@ LL | #[cold] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function definition - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:5 | LL | #[cold] type T = S; | ^^^^^^^ ----------- not a function definition @@ -748,7 +768,7 @@ LL | #[cold] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function definition - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:5 | LL | #[cold] impl S { } | ^^^^^^^ ---------- not a function definition @@ -756,7 +776,7 @@ LL | #[cold] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5 | LL | #[link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -766,13 +786,13 @@ LL | extern "C" { } | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! help: try `#[link(name = "1900")]` instead - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5 | LL | #[link_name = "1900"] | ^^^^^^^^^^^^^^^^^^^^^ warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:17 | LL | mod inner { #![link_name="1900"] } | ------------^^^^^^^^^^^^^^^^^^^^-- not a foreign function or static @@ -780,7 +800,7 @@ LL | mod inner { #![link_name="1900"] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:491:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:497:5 | LL | #[link_name = "1900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static @@ -788,7 +808,7 @@ LL | #[link_name = "1900"] fn f() { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5 | LL | #[link_name = "1900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^ --------- not a foreign function or static @@ -796,7 +816,7 @@ LL | #[link_name = "1900"] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:501:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:507:5 | LL | #[link_name = "1900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^ ----------- not a foreign function or static @@ -804,7 +824,7 @@ LL | #[link_name = "1900"] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:506:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:5 | LL | #[link_name = "1900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static @@ -812,7 +832,7 @@ LL | #[link_name = "1900"] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:518:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:17 | LL | mod inner { #![link_section="1800"] } | ------------^^^^^^^^^^^^^^^^^^^^^^^-- not a function or static @@ -820,7 +840,7 @@ LL | mod inner { #![link_section="1800"] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:531:5 | LL | #[link_section = "1800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static @@ -828,7 +848,7 @@ LL | #[link_section = "1800"] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:530:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:5 | LL | #[link_section = "1800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static @@ -836,7 +856,7 @@ LL | #[link_section = "1800"] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a function or static - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:541:5 | LL | #[link_section = "1800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static @@ -844,7 +864,7 @@ LL | #[link_section = "1800"] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:550:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:556:17 | LL | mod inner { #![link()] } | ------------^^^^^^^^^^-- not an `extern` block @@ -852,7 +872,7 @@ LL | mod inner { #![link()] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:561:5 | LL | #[link()] fn f() { } | ^^^^^^^^^ ---------- not an `extern` block @@ -860,7 +880,7 @@ LL | #[link()] fn f() { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:560:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:566:5 | LL | #[link()] struct S; | ^^^^^^^^^ --------- not an `extern` block @@ -868,7 +888,7 @@ LL | #[link()] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:565:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:571:5 | LL | #[link()] type T = S; | ^^^^^^^^^ ----------- not an `extern` block @@ -876,7 +896,7 @@ LL | #[link()] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:570:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:576:5 | LL | #[link()] impl S { } | ^^^^^^^^^ ---------- not an `extern` block @@ -884,7 +904,7 @@ LL | #[link()] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:575:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:5 | LL | #[link()] extern "Rust" {} | ^^^^^^^^^ @@ -892,270 +912,262 @@ LL | #[link()] extern "Rust" {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: `#[must_use]` has no effect when applied to a module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:597:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:603:17 | LL | mod inner { #![must_use] } | ^^^^^^^^^^^^ warning: `#[must_use]` has no effect when applied to a type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:603:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:609:5 | LL | #[must_use] type T = S; | ^^^^^^^^^^^ -warning: `#[must_use]` has no effect when applied to an implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:605:5 +warning: `#[must_use]` has no effect when applied to an inherent implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:611:5 | LL | #[must_use] impl S { } | ^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:611:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:617:17 | LL | mod inner { #![windows_subsystem="windows"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:620:5 | LL | #[windows_subsystem = "windows"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:617:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:623:5 | LL | #[windows_subsystem = "windows"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:620:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:626:5 | LL | #[windows_subsystem = "windows"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:623:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:629:5 | LL | #[windows_subsystem = "windows"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:632:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:638:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:641:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:638:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:641:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:650:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:654:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:666:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:669:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:670:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:17 | LL | mod inner { #![no_builtins] } | ^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5 | LL | #[no_builtins] fn f() { } | ^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 | LL | #[no_builtins] struct S; | ^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 | LL | #[no_builtins] type T = S; | ^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 | LL | #[no_builtins] impl S { } | ^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:85:12 - | -LL | #![feature(rust1)] - | ^^^^^ - | - = note: `#[warn(stable_features)]` on by default - -warning: 171 warnings emitted +warning: 173 warnings emitted diff --git a/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr b/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr index 319056a9c88..d599523c727 100644 --- a/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr +++ b/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr @@ -1,31 +1,31 @@ error: can't mark as unstable using an already stable feature - --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1 + --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 | -LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable LL | const fn my_fun() {} | -------------------- the stability attribute annotates this item | help: consider removing the attribute - --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1 + --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 | -LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: can't mark as unstable using an already stable feature - --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 + --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1 | +LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable LL | const fn my_fun() {} | -------------------- the stability attribute annotates this item | help: consider removing the attribute - --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 + --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1 | -LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/log-poly.rs b/tests/ui/fmt/println-debug-different-types.rs index 64994a55817..9e21be1f03f 100644 --- a/tests/ui/log-poly.rs +++ b/tests/ui/fmt/println-debug-different-types.rs @@ -1,8 +1,10 @@ +//! Smoke test for println!() with debug format specifiers. + //@ run-pass #[derive(Debug)] enum Numbers { - Three + Three, } pub fn main() { diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.stderr b/tests/ui/generic-associated-types/bugs/issue-100013.stderr deleted file mode 100644 index ff82aebfef9..00000000000 --- a/tests/ui/generic-associated-types/bugs/issue-100013.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error: lifetime bound not satisfied - --> $DIR/issue-100013.rs:15:5 - | -LL | / async { // a coroutine checked for autotrait impl `Send` -LL | | let x = None::<I::Future<'_, '_>>; // a type referencing GAT -LL | | async {}.await; // a yield point -LL | | } - | |_____^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) - -error: lifetime bound not satisfied - --> $DIR/issue-100013.rs:22:5 - | -LL | / async { // a coroutine checked for autotrait impl `Send` -LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT -LL | | async {}.await; // a yield point -LL | | } - | |_____^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) - -error: lifetime may not live long enough - --> $DIR/issue-100013.rs:23:17 - | -LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | async { // a coroutine checked for autotrait impl `Send` -LL | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT - | ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b` - | - = help: consider adding the following bound: `'a: 'b` - -error: lifetime bound not satisfied - --> $DIR/issue-100013.rs:29:5 - | -LL | / async { // a coroutine checked for autotrait impl `Send` -LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT -LL | | async {}.await; // a yield point -LL | | } - | |_____^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) - -error: aborting due to 4 previous errors - diff --git a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr new file mode 100644 index 00000000000..8b62fb6a254 --- /dev/null +++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.no_assumptions.stderr @@ -0,0 +1,24 @@ +error: lifetime bound not satisfied + --> $DIR/higher-ranked-coroutine-param-outlives-2.rs:14:5 + | +LL | / async { // a coroutine checked for autotrait impl `Send` +LL | | let x = None::<I::Future<'_, '_>>; // a type referencing GAT +LL | | async {}.await; // a yield point +LL | | } + | |_____^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + +error: lifetime bound not satisfied + --> $DIR/higher-ranked-coroutine-param-outlives-2.rs:21:5 + | +LL | / async { // a coroutine checked for autotrait impl `Send` +LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT +LL | | async {}.await; // a yield point +LL | | } + | |_____^ + | + = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) + +error: aborting due to 2 previous errors + diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.rs b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs index ac72c29c03b..a5ed162d62c 100644 --- a/tests/ui/generic-associated-types/bugs/issue-100013.rs +++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives-2.rs @@ -1,9 +1,8 @@ -//@ check-fail -//@ known-bug: #100013 //@ edition: 2021 - -// We really should accept this, but we need implied bounds between the regions -// in a coroutine interior. +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 pub trait FutureIterator { type Future<'s, 'cx>: Send @@ -18,14 +17,7 @@ fn call<I: FutureIterator>() -> impl Send { } } -fn call2<'a, 'b, I: FutureIterator>() -> impl Send { - async { // a coroutine checked for autotrait impl `Send` - let x = None::<I::Future<'a, 'b>>; // a type referencing GAT - async {}.await; // a yield point - } -} - -fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { +fn call2<'a: 'b, 'b, I: FutureIterator>() -> impl Send { async { // a coroutine checked for autotrait impl `Send` let x = None::<I::Future<'a, 'b>>; // a type referencing GAT async {}.await; // a yield point diff --git a/tests/ui/generic-associated-types/issue-92096.stderr b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.no_assumptions.stderr index b9a16cf184e..f747ba9a733 100644 --- a/tests/ui/generic-associated-types/issue-92096.stderr +++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.no_assumptions.stderr @@ -1,5 +1,5 @@ error: `C` does not live long enough - --> $DIR/issue-92096.rs:17:5 + --> $DIR/higher-ranked-coroutine-param-outlives.rs:21:5 | LL | async move { c.connect().await } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs new file mode 100644 index 00000000000..5f683bd82fa --- /dev/null +++ b/tests/ui/generic-associated-types/higher-ranked-coroutine-param-outlives.rs @@ -0,0 +1,24 @@ +//@ edition:2018 +//@ revisions: assumptions no_assumptions +//@[assumptions] compile-flags: -Zhigher-ranked-assumptions +//@[assumptions] check-pass +//@[no_assumptions] known-bug: #110338 + +use std::future::Future; + +trait Client { + type Connecting<'a>: Future + Send + where + Self: 'a; + + fn connect(&'_ self) -> Self::Connecting<'_>; +} + +fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send +where + C: Client + Send + Sync, +{ + async move { c.connect().await } +} + +fn main() {} diff --git a/tests/ui/generic-associated-types/issue-92096.rs b/tests/ui/generic-associated-types/issue-92096.rs deleted file mode 100644 index a34c4179584..00000000000 --- a/tests/ui/generic-associated-types/issue-92096.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ edition:2018 - -use std::future::Future; - -trait Client { - type Connecting<'a>: Future + Send - where - Self: 'a; - - fn connect(&'_ self) -> Self::Connecting<'_>; -} - -fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send -where - C: Client + Send + Sync, -{ - async move { c.connect().await } - //~^ ERROR `C` does not live long enough - // - // FIXME(#71723). This is because we infer at some point a value of - // - // impl Future<Output = <C as Client>::Connection<'_>> - // - // and then we somehow fail the WF check because `where C: 'a` is not known, - // but I'm not entirely sure how that comes about. -} - -fn main() {} diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr index e59409ea27e..dbac74b2247 100644 --- a/tests/ui/impl-trait/call_method_without_import.no_import.stderr +++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr @@ -22,15 +22,10 @@ LL | x.fmt(f); = help: items from traits can only be used if the trait is in scope help: the following traits which provide `fmt` are implemented but not in scope; perhaps you want to import one of them | -LL + use std::fmt::Binary; - | LL + use std::fmt::Debug; | -LL + use std::fmt::Display; - | -LL + use std::fmt::LowerExp; +LL + use std::fmt::Pointer; | - = and 5 other candidates error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-bindings/implicit-sized.rs b/tests/ui/impl-trait/in-bindings/implicit-sized.rs new file mode 100644 index 00000000000..2f16db94189 --- /dev/null +++ b/tests/ui/impl-trait/in-bindings/implicit-sized.rs @@ -0,0 +1,19 @@ +#![feature(impl_trait_in_bindings)] + +trait Trait {} +impl<T: ?Sized> Trait for T {} + +fn doesnt_work() { + let x: &impl Trait = "hi"; + //~^ ERROR the size for values of type `str` cannot be known at compilation time +} + +fn works() { + let x: &(impl Trait + ?Sized) = "hi"; + // No implicit sized. + + let x: &impl Trait = &(); + // Is actually sized. +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-bindings/implicit-sized.stderr b/tests/ui/impl-trait/in-bindings/implicit-sized.stderr new file mode 100644 index 00000000000..465a928cf86 --- /dev/null +++ b/tests/ui/impl-trait/in-bindings/implicit-sized.stderr @@ -0,0 +1,11 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/implicit-sized.rs:7:13 + | +LL | let x: &impl Trait = "hi"; + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/issues/issue-55872-3.rs b/tests/ui/impl-trait/issues/issue-55872-3.rs index 698e7f36234..763b4b9fd32 100644 --- a/tests/ui/impl-trait/issues/issue-55872-3.rs +++ b/tests/ui/impl-trait/issues/issue-55872-3.rs @@ -14,6 +14,7 @@ impl<S> Bar for S { fn foo<T>() -> Self::E { //~^ ERROR : Copy` is not satisfied [E0277] //~| ERROR type parameter `T` is part of concrete type + //~| ERROR type parameter `T` is part of concrete type async {} } } diff --git a/tests/ui/impl-trait/issues/issue-55872-3.stderr b/tests/ui/impl-trait/issues/issue-55872-3.stderr index 3281dcc3501..ce2dd7f02b4 100644 --- a/tests/ui/impl-trait/issues/issue-55872-3.stderr +++ b/tests/ui/impl-trait/issues/issue-55872-3.stderr @@ -1,11 +1,11 @@ -error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}: Copy` is not satisfied +error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}: Copy` is not satisfied --> $DIR/issue-55872-3.rs:14:20 | LL | fn foo<T>() -> Self::E { - | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}` + | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}` ... LL | async {} - | -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:17:9: 17:14}` here + | -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:18:9: 18:14}` here error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias --> $DIR/issue-55872-3.rs:14:20 @@ -13,6 +13,14 @@ error: type parameter `T` is part of concrete type but not used in parameter lis LL | fn foo<T>() -> Self::E { | ^^^^^^^ -error: aborting due to 2 previous errors +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/issue-55872-3.rs:14:20 + | +LL | fn foo<T>() -> Self::E { + | ^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/no-method-suggested-traits.stderr b/tests/ui/impl-trait/no-method-suggested-traits.stderr index 061c9bd8f35..b376f205411 100644 --- a/tests/ui/impl-trait/no-method-suggested-traits.stderr +++ b/tests/ui/impl-trait/no-method-suggested-traits.stderr @@ -9,12 +9,8 @@ help: the following traits which provide `method` are implemented but not in sco | LL + use foo::Bar; | -LL + use no_method_suggested_traits::Reexported; - | LL + use no_method_suggested_traits::foo::PubPub; | -LL + use no_method_suggested_traits::qux::PrivPub; - | help: there is a method `method2` with a similar name | LL | 1u32.method2(); @@ -31,12 +27,8 @@ help: the following traits which provide `method` are implemented but not in sco | LL + use foo::Bar; | -LL + use no_method_suggested_traits::Reexported; - | LL + use no_method_suggested_traits::foo::PubPub; | -LL + use no_method_suggested_traits::qux::PrivPub; - | help: there is a method `method2` with a similar name | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method2(); diff --git a/tests/ui/impl-trait/opt-out-bound-not-satisfied.rs b/tests/ui/impl-trait/opt-out-bound-not-satisfied.rs index 27c493a13bf..7e0e1eadf9c 100644 --- a/tests/ui/impl-trait/opt-out-bound-not-satisfied.rs +++ b/tests/ui/impl-trait/opt-out-bound-not-satisfied.rs @@ -3,8 +3,8 @@ use std::future::Future; fn foo() -> impl ?Future<Output = impl Send> { - //~^ ERROR: relaxing a default bound only does something for `?Sized` - //~| ERROR: relaxing a default bound only does something for `?Sized` + //~^ ERROR: bound modifier `?` can only be applied to `Sized` + //~| ERROR: bound modifier `?` can only be applied to `Sized` () } diff --git a/tests/ui/impl-trait/opt-out-bound-not-satisfied.stderr b/tests/ui/impl-trait/opt-out-bound-not-satisfied.stderr index dc4314c58ad..f99d6a7e5f6 100644 --- a/tests/ui/impl-trait/opt-out-bound-not-satisfied.stderr +++ b/tests/ui/impl-trait/opt-out-bound-not-satisfied.stderr @@ -1,10 +1,10 @@ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/opt-out-bound-not-satisfied.rs:5:18 | LL | fn foo() -> impl ?Future<Output = impl Send> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/opt-out-bound-not-satisfied.rs:5:18 | LL | fn foo() -> impl ?Future<Output = impl Send> { diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs index 1ac3c593dbe..1b8a5d4ca99 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.rs @@ -1,7 +1,7 @@ //@ check-pass pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> { - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing v.into_iter() } diff --git a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr index b9d8674992c..3651226e0c3 100644 --- a/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr +++ b/tests/ui/impl-trait/rpit-assoc-pair-with-lifetime.stderr @@ -1,11 +1,12 @@ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/rpit-assoc-pair-with-lifetime.rs:3:31 | LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &u32)> { - | ^^ this lifetime flows to the output ---- the lifetime gets resolved as `'a` + | ^^ the lifetime is named here ---- the same lifetime is elided here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default -help: one option is to consistently use `'a` +help: consistently use `'a` | LL | pub fn iter<'a>(v: Vec<(u32, &'a u32)>) -> impl DoubleEndedIterator<Item = (u32, &'a u32)> { | ++ diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr index 10f4d8d1a71..5f4ef14d586 100644 --- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr +++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr @@ -3,6 +3,10 @@ error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at | LL | std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `RAW_EQ_PADDING` failed here + | + = note: the raw bytes of the constant (size: 4, align: 2) { + 01 __ 02 00 │ .â–‘.. + } error[E0080]: unable to turn pointer into integer --> $DIR/intrinsic-raw_eq-const-bad.rs:9:5 diff --git a/tests/ui/issues/issue-37534.rs b/tests/ui/issues/issue-37534.rs index 09d60b7786b..63f6479ae2e 100644 --- a/tests/ui/issues/issue-37534.rs +++ b/tests/ui/issues/issue-37534.rs @@ -1,5 +1,5 @@ struct Foo<T: ?Hash> {} //~^ ERROR expected trait, found derive macro `Hash` -//~| ERROR relaxing a default bound only does something for `?Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` fn main() {} diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr index 3219854bc70..08607354203 100644 --- a/tests/ui/issues/issue-37534.stderr +++ b/tests/ui/issues/issue-37534.stderr @@ -9,7 +9,7 @@ help: consider importing this trait instead LL + use std::hash::Hash; | -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/issue-37534.rs:1:15 | LL | struct Foo<T: ?Hash> {} diff --git a/tests/ui/issues/issue-50571.fixed b/tests/ui/issues/issue-50571.fixed deleted file mode 100644 index 6d73f17cca4..00000000000 --- a/tests/ui/issues/issue-50571.fixed +++ /dev/null @@ -1,10 +0,0 @@ -//@ edition: 2015 -//@ run-rustfix - -#![allow(dead_code)] -trait Foo { - fn foo(_: [i32; 2]) {} - //~^ ERROR: patterns aren't allowed in methods without bodies -} - -fn main() {} diff --git a/tests/ui/issues/issue-50571.rs b/tests/ui/issues/issue-50571.rs deleted file mode 100644 index dd840ffe4d1..00000000000 --- a/tests/ui/issues/issue-50571.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ edition: 2015 -//@ run-rustfix - -#![allow(dead_code)] -trait Foo { - fn foo([a, b]: [i32; 2]) {} - //~^ ERROR: patterns aren't allowed in methods without bodies -} - -fn main() {} diff --git a/tests/ui/issues/issue-50571.stderr b/tests/ui/issues/issue-50571.stderr deleted file mode 100644 index 9b00fe0f5db..00000000000 --- a/tests/ui/issues/issue-50571.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0642]: patterns aren't allowed in methods without bodies - --> $DIR/issue-50571.rs:6:12 - | -LL | fn foo([a, b]: [i32; 2]) {} - | ^^^^^^ - | -help: give this argument a name or use an underscore to ignore it - | -LL - fn foo([a, b]: [i32; 2]) {} -LL + fn foo(_: [i32; 2]) {} - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0642`. diff --git a/tests/ui/issues/issue-87199.rs b/tests/ui/issues/issue-87199.rs index 4e4e35c6a71..dd9dfc74ca3 100644 --- a/tests/ui/issues/issue-87199.rs +++ b/tests/ui/issues/issue-87199.rs @@ -6,12 +6,12 @@ // Check that these function definitions only emit warnings, not errors fn arg<T: ?Send>(_: T) {} -//~^ ERROR: relaxing a default bound only does something for `?Sized` +//~^ ERROR: bound modifier `?` can only be applied to `Sized` fn ref_arg<T: ?Send>(_: &T) {} -//~^ ERROR: relaxing a default bound only does something for `?Sized` +//~^ ERROR: bound modifier `?` can only be applied to `Sized` fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() } -//~^ ERROR: relaxing a default bound only does something for `?Sized` -//~| ERROR: relaxing a default bound only does something for `?Sized` +//~^ ERROR: bound modifier `?` can only be applied to `Sized` +//~| ERROR: bound modifier `?` can only be applied to `Sized` // Check that there's no `?Sized` relaxation! fn main() { diff --git a/tests/ui/issues/issue-87199.stderr b/tests/ui/issues/issue-87199.stderr index acc4e84779c..8a930a3d704 100644 --- a/tests/ui/issues/issue-87199.stderr +++ b/tests/ui/issues/issue-87199.stderr @@ -1,22 +1,22 @@ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/issue-87199.rs:8:11 | LL | fn arg<T: ?Send>(_: T) {} | ^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/issue-87199.rs:10:15 | LL | fn ref_arg<T: ?Send>(_: &T) {} | ^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/issue-87199.rs:12:40 | LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() } | ^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/issue-87199.rs:12:40 | LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() } diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index 03b7e759960..d05e6e1fd3f 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -17,4 +17,3 @@ impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained #[rustc_layout(debug)] struct S([u8; <u8 as A>::B]); //~^ ERROR: the type has an unknown layout -//~| ERROR: type annotations needed diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 82cd1217c49..615c131eb90 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -4,19 +4,12 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self LL | impl<C: ?Sized> A for u8 { | ^ unconstrained type parameter -error[E0282]: type annotations needed - --> $DIR/unconstrained-param-ice-137308.rs:18:16 - | -LL | struct S([u8; <u8 as A>::B]); - | ^^ cannot infer type for type parameter `C` - error: the type has an unknown layout --> $DIR/unconstrained-param-ice-137308.rs:18:1 | LL | struct S([u8; <u8 as A>::B]); | ^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0207, E0282. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/lazy-type-alias/opaq-ty-collection-infinite-recur.rs b/tests/ui/lazy-type-alias/opaq-ty-collection-infinite-recur.rs new file mode 100644 index 00000000000..34803c8c103 --- /dev/null +++ b/tests/ui/lazy-type-alias/opaq-ty-collection-infinite-recur.rs @@ -0,0 +1,18 @@ +// The opaque type collector used to expand free alias types (in situ) without guarding against +// endlessly recursing aliases which lead to the compiler overflowing its stack in certain +// situations. +// +// In most situations we wouldn't even reach the collector when there's an overflow because we +// would've already bailed out early during the item's wfcheck due to the normalization failure. +// +// In the case below however, while collecting the opaque types defined by the AnonConst, we +// descend into its nested items (here: type alias `Recur`) to acquire their opaque types -- +// meaning we get there before we wfcheck `Recur`. +// +// issue: <https://github.com/rust-lang/rust/issues/131994> +#![feature(lazy_type_alias)] +#![expect(incomplete_features)] + +struct Hold([(); { type Recur = Recur; 0 }]); //~ ERROR overflow normalizing the type alias `Recur` + +fn main() {} diff --git a/tests/ui/lazy-type-alias/opaq-ty-collection-infinite-recur.stderr b/tests/ui/lazy-type-alias/opaq-ty-collection-infinite-recur.stderr new file mode 100644 index 00000000000..e93fcd03a96 --- /dev/null +++ b/tests/ui/lazy-type-alias/opaq-ty-collection-infinite-recur.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow normalizing the type alias `Recur` + --> $DIR/opaq-ty-collection-infinite-recur.rs:16:20 + | +LL | struct Hold([(); { type Recur = Recur; 0 }]); + | ^^^^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs index 1804003d367..9162a38f510 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.rs @@ -4,7 +4,7 @@ struct Foo; impl Foo { pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing unsafe { &mut *(x as *mut _) } } } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr index 7c7411651d0..5a7a5a6ebf9 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/example-from-issue48686.stderr @@ -1,17 +1,18 @@ -error: lifetime flowing from input to output with different syntax can be confusing +error: eliding a lifetime that's named elsewhere is confusing --> $DIR/example-from-issue48686.rs:6:21 | LL | pub fn get_mut(&'static self, x: &mut u8) -> &mut u8 { - | ^^^^^^^ ------- the lifetime gets resolved as `'static` + | ^^^^^^^ ------- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing note: the lint level is defined here --> $DIR/example-from-issue48686.rs:1:9 | LL | #![deny(mismatched_lifetime_syntaxes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: one option is to consistently use `'static` +help: consistently use `'static` | LL | pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 { | +++++++ diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs index 3d5aab5c829..ecc790be5a0 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.rs @@ -1,26 +1,26 @@ #![deny(mismatched_lifetime_syntaxes)] fn ampersand<'a>(x: &'a u8) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing x } struct Brackets<'a>(&'a u8); fn brackets<'a>(x: &'a u8) -> Brackets { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing Brackets(x) } struct Comma<'a, T>(&'a T); fn comma<'a>(x: &'a u8) -> Comma<u8> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing Comma(x) } fn underscore<'a>(x: &'a u8) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing x } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr index 681b3c97052..af56a0a0ea5 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/missing-lifetime-kind.stderr @@ -1,56 +1,60 @@ -error: lifetime flowing from input to output with different syntax can be confusing +error: eliding a lifetime that's named elsewhere is confusing --> $DIR/missing-lifetime-kind.rs:3:22 | LL | fn ampersand<'a>(x: &'a u8) -> &u8 { - | ^^ --- the lifetime gets resolved as `'a` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing note: the lint level is defined here --> $DIR/missing-lifetime-kind.rs:1:9 | LL | #![deny(mismatched_lifetime_syntaxes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: one option is to consistently use `'a` +help: consistently use `'a` | LL | fn ampersand<'a>(x: &'a u8) -> &'a u8 { | ++ -error: lifetime flowing from input to output with different syntax can be confusing +error: hiding a lifetime that's named elsewhere is confusing --> $DIR/missing-lifetime-kind.rs:10:21 | LL | fn brackets<'a>(x: &'a u8) -> Brackets { - | ^^ -------- the lifetime gets resolved as `'a` + | ^^ -------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn brackets<'a>(x: &'a u8) -> Brackets<'a> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing +error: hiding a lifetime that's named elsewhere is confusing --> $DIR/missing-lifetime-kind.rs:17:18 | LL | fn comma<'a>(x: &'a u8) -> Comma<u8> { - | ^^ --------- the lifetime gets resolved as `'a` + | ^^ --------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn comma<'a>(x: &'a u8) -> Comma<'a, u8> { | +++ -error: lifetime flowing from input to output with different syntax can be confusing +error: eliding a lifetime that's named elsewhere is confusing --> $DIR/missing-lifetime-kind.rs:22:23 | LL | fn underscore<'a>(x: &'a u8) -> &'_ u8 { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn underscore<'a>(x: &'a u8) -> &'_ u8 { LL + fn underscore<'a>(x: &'a u8) -> &'a u8 { diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs index cc398ab7888..449b2a3c0a8 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.rs @@ -6,13 +6,13 @@ #[warn(mismatched_lifetime_syntaxes)] mod foo { fn bar(x: &'static u8) -> &u8 { - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing x } #[deny(mismatched_lifetime_syntaxes)] fn baz(x: &'static u8) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing x } } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr index da691225c17..cf0a29678fa 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/not-tied-to-crate.stderr @@ -1,35 +1,37 @@ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/not-tied-to-crate.rs:8:16 | LL | fn bar(x: &'static u8) -> &u8 { - | ^^^^^^^ --- the lifetime gets resolved as `'static` + | ^^^^^^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing note: the lint level is defined here --> $DIR/not-tied-to-crate.rs:6:8 | LL | #[warn(mismatched_lifetime_syntaxes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: one option is to consistently use `'static` +help: consistently use `'static` | LL | fn bar(x: &'static u8) -> &'static u8 { | +++++++ -error: lifetime flowing from input to output with different syntax can be confusing +error: eliding a lifetime that's named elsewhere is confusing --> $DIR/not-tied-to-crate.rs:14:16 | LL | fn baz(x: &'static u8) -> &u8 { - | ^^^^^^^ --- the lifetime gets resolved as `'static` + | ^^^^^^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing note: the lint level is defined here --> $DIR/not-tied-to-crate.rs:13:12 | LL | #[deny(mismatched_lifetime_syntaxes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: one option is to consistently use `'static` +help: consistently use `'static` | LL | fn baz(x: &'static u8) -> &'static u8 { | +++++++ diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs index 47ae258f138..c41cf44e1c5 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.rs @@ -14,26 +14,26 @@ impl Trait for () { } fn ampersand(x: &'static u8) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing x } struct Brackets<'a>(&'a u8); fn brackets(x: &'static u8) -> Brackets { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing Brackets(x) } struct Comma<'a, T>(&'a T); fn comma(x: &'static u8) -> Comma<u8> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing Comma(x) } fn underscore(x: &'static u8) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing x } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr index 5b9a986bcbe..d60bec6f7e4 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes-details/static.stderr @@ -1,56 +1,60 @@ -error: lifetime flowing from input to output with different syntax can be confusing +error: eliding a lifetime that's named elsewhere is confusing --> $DIR/static.rs:16:18 | LL | fn ampersand(x: &'static u8) -> &u8 { - | ^^^^^^^ --- the lifetime gets resolved as `'static` + | ^^^^^^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing note: the lint level is defined here --> $DIR/static.rs:1:9 | LL | #![deny(mismatched_lifetime_syntaxes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: one option is to consistently use `'static` +help: consistently use `'static` | LL | fn ampersand(x: &'static u8) -> &'static u8 { | +++++++ -error: lifetime flowing from input to output with different syntax can be confusing +error: hiding a lifetime that's named elsewhere is confusing --> $DIR/static.rs:23:17 | LL | fn brackets(x: &'static u8) -> Brackets { - | ^^^^^^^ -------- the lifetime gets resolved as `'static` + | ^^^^^^^ -------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL | fn brackets(x: &'static u8) -> Brackets<'static> { | +++++++++ -error: lifetime flowing from input to output with different syntax can be confusing +error: hiding a lifetime that's named elsewhere is confusing --> $DIR/static.rs:30:14 | LL | fn comma(x: &'static u8) -> Comma<u8> { - | ^^^^^^^ --------- the lifetime gets resolved as `'static` + | ^^^^^^^ --------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL | fn comma(x: &'static u8) -> Comma<'static, u8> { | ++++++++ -error: lifetime flowing from input to output with different syntax can be confusing +error: eliding a lifetime that's named elsewhere is confusing --> $DIR/static.rs:35:19 | LL | fn underscore(x: &'static u8) -> &'_ u8 { - | ^^^^^^^ -- the lifetime gets resolved as `'static` + | ^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL - fn underscore(x: &'static u8) -> &'_ u8 { LL + fn underscore(x: &'static u8) -> &'static u8 { diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs index b98423afb17..f6260c47202 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.rs @@ -5,109 +5,111 @@ struct ContainsLifetime<'a>(&'a u8); struct S(u8); +// ref to ref + fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing v } fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing v } -// --- +// path to path fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing v } fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing v } fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing v } fn explicit_bound_path_to_explicit_anonymous_path<'a>( v: ContainsLifetime<'a>, - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing ) -> ContainsLifetime<'_> { v } -// --- +// ref to path fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing ContainsLifetime(v) } fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing ContainsLifetime(v) } fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing ContainsLifetime(v) } fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing ContainsLifetime(v) } -// --- +// path to ref fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing v.0 } fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing v.0 } fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing v.0 } fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing v.0 } impl S { fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing &self.0 } fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing &self.0 } // --- fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing ContainsLifetime(&self.0) } fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing ContainsLifetime(&self.0) } fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing ContainsLifetime(&self.0) } } @@ -122,43 +124,43 @@ mod static_suggestions { struct S(u8); fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing v } fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing v } fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing ContainsLifetime(v) } fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing ContainsLifetime(v) } impl S { fn static_ref_to_implicit_ref(&'static self) -> &u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing &self.0 } fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing &self.0 } fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing ContainsLifetime(&self.0) } fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing ContainsLifetime(&self.0) } } @@ -170,23 +172,23 @@ mod impl_trait { struct ContainsLifetime<'a>(&'a u8); fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing move || _ = v } fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing move || _ = v } fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing move || _ = v } fn explicit_bound_path_to_impl_trait_precise_capture<'a>( v: ContainsLifetime<'a>, - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing ) -> impl FnOnce() + use<'_> { move || _ = v } @@ -200,13 +202,13 @@ mod dyn_trait { struct ContainsLifetime<'a>(&'a u8); fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &u8> + '_> { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing Box::new(iter::once(v)) } fn explicit_bound_path_to_dyn_trait_bound<'a>( v: ContainsLifetime<'a>, - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's named elsewhere is confusing ) -> Box<dyn Iterator<Item = ContainsLifetime> + '_> { Box::new(iter::once(v)) } @@ -214,10 +216,28 @@ mod dyn_trait { /// These tests serve to exercise edge cases of the lint formatting mod diagnostic_output { + #[derive(Copy, Clone)] + struct ContainsLifetime<'a>(&'a u8); + + fn multiple_inputs<'a>(v: (&'a u8, &'a u8)) -> &u8 { + //~^ ERROR eliding a lifetime that's named elsewhere is confusing + v.0 + } + fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR eliding a lifetime that's named elsewhere is confusing (v, v) } + + fn all_three_categories<'a>(v: ContainsLifetime<'a>) -> (&u8, ContainsLifetime) { + //~^ ERROR hiding or eliding a lifetime that's named elsewhere is confusing + (v.0, v) + } + + fn explicit_bound_output<'a>(v: &'a u8) -> (&u8, &'a u8, ContainsLifetime<'a>) { + //~^ ERROR eliding a lifetime that's named elsewhere is confusing + (v, v, ContainsLifetime(v)) + } } /// Trait functions are represented differently in the HIR. Make sure @@ -228,20 +248,20 @@ mod trait_functions { trait TheTrait { fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime; - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime; - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing } impl TheTrait for &u8 { fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing ContainsLifetime(v) } fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime { - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing ContainsLifetime(self) } } @@ -255,7 +275,7 @@ mod foreign_functions { extern "Rust" { fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime; - //~^ ERROR lifetime flowing from input to output with different syntax + //~^ ERROR hiding a lifetime that's elided elsewhere is confusing } } diff --git a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr index 108b3f14169..20b7561c594 100644 --- a/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr +++ b/tests/ui/lifetimes/mismatched-lifetime-syntaxes.stderr @@ -1,538 +1,613 @@ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:8:47 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:10:47 | LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &u8 { - | ^^ --- the lifetime gets resolved as `'a` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing note: the lint level is defined here --> $DIR/mismatched-lifetime-syntaxes.rs:1:9 | LL | #![deny(mismatched_lifetime_syntaxes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: one option is to consistently use `'a` +help: consistently use `'a` | LL | fn explicit_bound_ref_to_implicit_ref<'a>(v: &'a u8) -> &'a u8 { | ++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:13:57 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:15:57 | LL | fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'_ u8 { LL + fn explicit_bound_ref_to_explicit_anonymous_ref<'a>(v: &'a u8) -> &'a u8 { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:20:48 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:22:48 | LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime) -> ContainsLifetime<'_> { - | ^^^^^^^^^^^^^^^^ -- the lifetime gets resolved as `'_` + | ^^^^^^^^^^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is hidden here | -help: one option is to consistently use `'_` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'_` | LL | fn implicit_path_to_explicit_anonymous_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:25:65 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:27:65 | LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime { - | ^^ ---------------- the lifetime gets resolved as `'_` + | ^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to consistently use `'_` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'_` | LL | fn explicit_anonymous_path_to_implicit_path(v: ContainsLifetime<'_>) -> ContainsLifetime<'_> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:30:65 +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:32:65 | LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime { - | ^^ ---------------- the lifetime gets resolved as `'a` + | ^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn explicit_bound_path_to_implicit_path<'a>(v: ContainsLifetime<'a>) -> ContainsLifetime<'a> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:36:25 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:38:25 | LL | v: ContainsLifetime<'a>, - | ^^ this lifetime flows to the output + | ^^ the lifetime is named here LL | LL | ) -> ContainsLifetime<'_> { - | -- the lifetime gets resolved as `'a` + | -- the same lifetime is elided here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - ) -> ContainsLifetime<'_> { LL + ) -> ContainsLifetime<'a> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:44:37 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:46:37 | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime { - | ^^^ ---------------- the lifetime gets resolved as `'_` + | ^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:49:48 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:51:48 | LL | fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime { - | ^^ ---------------- the lifetime gets resolved as `'_` + | ^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths - | -LL - fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime { -LL + fn explicit_anonymous_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> { + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | +LL | fn explicit_anonymous_ref_to_implicit_path(v: &'_ u8) -> ContainsLifetime<'_> { + | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:54:48 +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:56:48 | LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime { - | ^^ ---------------- the lifetime gets resolved as `'a` + | ^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn explicit_bound_ref_to_implicit_path<'a>(v: &'a u8) -> ContainsLifetime<'a> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:59:58 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:61:58 | LL | fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'_> { LL + fn explicit_bound_ref_to_explicit_anonymous_path<'a>(v: &'a u8) -> ContainsLifetime<'a> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:66:37 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:68:37 | LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime) -> &u8 { - | ^^^^^^^^^^^^^^^^ --- the lifetime gets resolved as `'_` + | ^^^^^^^^^^^^^^^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is hidden here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn implicit_path_to_implicit_ref(v: ContainsLifetime<'_>) -> &u8 { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:71:47 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:73:47 | LL | fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 { - | ^^^^^^^^^^^^^^^^ -- the lifetime gets resolved as `'_` + | ^^^^^^^^^^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output - | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + | the lifetime is hidden here | -LL - fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime) -> &'_ u8 { -LL + fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &u8 { + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | +LL | fn implicit_path_to_explicit_anonymous_ref(v: ContainsLifetime<'_>) -> &'_ u8 { + | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:76:64 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:78:64 | LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &u8 { - | ^^ --- the lifetime gets resolved as `'a` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn explicit_bound_path_to_implicit_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 { | ++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:81:74 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:83:74 | LL | fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'_ u8 { LL + fn explicit_bound_path_to_explicit_anonymous_ref<'a>(v: ContainsLifetime<'a>) -> &'a u8 { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:87:55 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:89:55 | LL | fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &u8 { - | ^^ --- the lifetime gets resolved as `'a` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn method_explicit_bound_ref_to_implicit_ref<'a>(&'a self) -> &'a u8 { | ++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:92:65 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:94:65 | LL | fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'_ u8 { LL + fn method_explicit_bound_ref_to_explicit_anonymous_ref<'a>(&'a self) -> &'a u8 { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:99:56 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:101:56 | LL | fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime { - | ^^ ---------------- the lifetime gets resolved as `'_` + | ^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths - | -LL - fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime { -LL + fn method_explicit_anonymous_ref_to_implicit_path(&self) -> ContainsLifetime<'_> { + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | +LL | fn method_explicit_anonymous_ref_to_implicit_path(&'_ self) -> ContainsLifetime<'_> { + | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:104:56 +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:106:56 | LL | fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime { - | ^^ ---------------- the lifetime gets resolved as `'a` + | ^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn method_explicit_bound_ref_to_implicit_path<'a>(&'a self) -> ContainsLifetime<'a> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:109:66 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:111:66 | LL | fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'_> { LL + fn method_explicit_bound_ref_to_explicit_anonymous_path<'a>(&'a self) -> ContainsLifetime<'a> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:124:39 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:126:39 | LL | fn static_ref_to_implicit_ref(v: &'static u8) -> &u8 { - | ^^^^^^^ --- the lifetime gets resolved as `'static` + | ^^^^^^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL | fn static_ref_to_implicit_ref(v: &'static u8) -> &'static u8 { | +++++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:129:49 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:131:49 | LL | fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 { - | ^^^^^^^ -- the lifetime gets resolved as `'static` + | ^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL - fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'_ u8 { LL + fn static_ref_to_explicit_anonymous_ref(v: &'static u8) -> &'static u8 { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:134:40 +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:136:40 | LL | fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime { - | ^^^^^^^ ---------------- the lifetime gets resolved as `'static` + | ^^^^^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL | fn static_ref_to_implicit_path(v: &'static u8) -> ContainsLifetime<'static> { | +++++++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:139:50 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:141:50 | LL | fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> { - | ^^^^^^^ -- the lifetime gets resolved as `'static` + | ^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL - fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'_> { LL + fn static_ref_to_explicit_anonymous_path(v: &'static u8) -> ContainsLifetime<'static> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:145:40 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:147:40 | LL | fn static_ref_to_implicit_ref(&'static self) -> &u8 { - | ^^^^^^^ --- the lifetime gets resolved as `'static` + | ^^^^^^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL | fn static_ref_to_implicit_ref(&'static self) -> &'static u8 { | +++++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:150:50 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:152:50 | LL | fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 { - | ^^^^^^^ -- the lifetime gets resolved as `'static` + | ^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL - fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'_ u8 { LL + fn static_ref_to_explicit_anonymous_ref(&'static self) -> &'static u8 { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:155:41 +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:157:41 | LL | fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime { - | ^^^^^^^ ---------------- the lifetime gets resolved as `'static` + | ^^^^^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL | fn static_ref_to_implicit_path(&'static self) -> ContainsLifetime<'static> { | +++++++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:160:51 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:162:51 | LL | fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> { - | ^^^^^^^ -- the lifetime gets resolved as `'static` + | ^^^^^^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'static` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'static` | LL - fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'_> { LL + fn static_ref_to_explicit_anonymous_path(&'static self) -> ContainsLifetime<'static> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:172:55 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:174:55 | LL | fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + '_ { LL + fn explicit_bound_ref_to_impl_trait_bound<'a>(v: &'a u8) -> impl FnOnce() + 'a { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:177:65 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:179:65 | LL | fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> { - | ^^ -- the lifetime gets resolved as `'a` - | | - | this lifetime flows to the output + | ^^ the lifetime is named here -- the same lifetime is elided here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'_> { LL + fn explicit_bound_ref_to_impl_trait_precise_capture<'a>(v: &'a u8) -> impl FnOnce() + use<'a> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:182:72 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:184:72 | LL | fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ { - | ^^ -- the lifetime gets resolved as `'a` + | ^^ -- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + '_ { LL + fn explicit_bound_path_to_impl_trait_bound<'a>(v: ContainsLifetime<'a>) -> impl FnOnce() + 'a { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:188:29 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:190:29 | LL | v: ContainsLifetime<'a>, - | ^^ this lifetime flows to the output + | ^^ the lifetime is named here LL | LL | ) -> impl FnOnce() + use<'_> { - | -- the lifetime gets resolved as `'a` + | -- the same lifetime is elided here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL - ) -> impl FnOnce() + use<'_> { LL + ) -> impl FnOnce() + use<'a> { | -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:202:54 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:204:54 | LL | fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &u8> + '_> { - | ^^ --- -- the lifetimes get resolved as `'a` - | | | - | | the lifetimes get resolved as `'a` - | this lifetime flows to the output + | ^^ the lifetime is named here --- the same lifetime is elided here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn explicit_bound_ref_to_dyn_trait_bound<'a>(v: &'a u8) -> Box<dyn Iterator<Item = &'a u8> + '_> { | ++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:208:29 +error: hiding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:210:29 | LL | v: ContainsLifetime<'a>, - | ^^ this lifetime flows to the output + | ^^ the lifetime is named here LL | LL | ) -> Box<dyn Iterator<Item = ContainsLifetime> + '_> { - | ---------------- -- the lifetimes get resolved as `'a` - | | - | the lifetimes get resolved as `'a` + | ---------------- the same lifetime is hidden here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | ) -> Box<dyn Iterator<Item = ContainsLifetime<'a>> + '_> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:217:33 +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:222:33 + | +LL | fn multiple_inputs<'a>(v: (&'a u8, &'a u8)) -> &u8 { + | ^^ ^^ --- the same lifetime is elided here + | | | + | | the lifetime is named here + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` + | +LL | fn multiple_inputs<'a>(v: (&'a u8, &'a u8)) -> &'a u8 { + | ++ + +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:227:33 | LL | fn multiple_outputs<'a>(v: &'a u8) -> (&u8, &u8) { - | ^^ --- --- the lifetimes get resolved as `'a` + | ^^ --- --- the same lifetime is elided here | | | - | | the lifetimes get resolved as `'a` - | this lifetime flows to the output + | | the same lifetime is elided here + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn multiple_outputs<'a>(v: &'a u8) -> (&'a u8, &'a u8) { | ++ ++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:230:45 +error: hiding or eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:232:53 + | +LL | fn all_three_categories<'a>(v: ContainsLifetime<'a>) -> (&u8, ContainsLifetime) { + | ^^ --- ---------------- the same lifetime is hidden here + | | | + | | the same lifetime is elided here + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` + | +LL | fn all_three_categories<'a>(v: ContainsLifetime<'a>) -> (&'a u8, ContainsLifetime<'a>) { + | ++ ++++ + +error: eliding a lifetime that's named elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:237:38 + | +LL | fn explicit_bound_output<'a>(v: &'a u8) -> (&u8, &'a u8, ContainsLifetime<'a>) { + | ^^ --- -- -- the same lifetime is named here + | | | | + | | | the same lifetime is named here + | | the same lifetime is elided here + | the lifetime is named here + | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` + | +LL | fn explicit_bound_output<'a>(v: &'a u8) -> (&'a u8, &'a u8, ContainsLifetime<'a>) { + | ++ + +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:250:45 | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime; - | ^^^ ---------------- the lifetime gets resolved as `'_` + | ^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_>; | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:233:49 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:253:49 | LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime; - | ^^^^^ ---------------- the lifetime gets resolved as `'_` + | ^^^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime<'_>; | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:238:45 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:258:45 | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime { - | ^^^ ---------------- the lifetime gets resolved as `'_` + | ^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:243:49 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:263:49 | LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime { - | ^^^^^ ---------------- the lifetime gets resolved as `'_` + | ^^^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn method_implicit_ref_to_implicit_path(&self) -> ContainsLifetime<'_> { | ++++ -error: lifetime flowing from input to output with different syntax can be confusing - --> $DIR/mismatched-lifetime-syntaxes.rs:257:45 +error: hiding a lifetime that's elided elsewhere is confusing + --> $DIR/mismatched-lifetime-syntaxes.rs:277:45 | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime; - | ^^^ ---------------- the lifetime gets resolved as `'_` + | ^^^ ---------------- the same lifetime is hidden here | | - | this lifetime flows to the output + | the lifetime is elided here | -help: one option is to remove the lifetime for references and use the anonymous lifetime for paths + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: use `'_` for type paths | LL | fn implicit_ref_to_implicit_path(v: &u8) -> ContainsLifetime<'_>; | ++++ -error: aborting due to 39 previous errors +error: aborting due to 42 previous errors diff --git a/tests/ui/linking/export-executable-symbols.rs b/tests/ui/linking/export-executable-symbols.rs index aea5527b6a1..2bff58ca38a 100644 --- a/tests/ui/linking/export-executable-symbols.rs +++ b/tests/ui/linking/export-executable-symbols.rs @@ -1,22 +1,22 @@ //@ run-pass -//@ only-linux -//@ only-gnu -//@ compile-flags: -Zexport-executable-symbols +//@ compile-flags: -Ctarget-feature=-crt-static -Zexport-executable-symbols +//@ ignore-wasm +//@ ignore-cross-compile //@ edition: 2024 // Regression test for <https://github.com/rust-lang/rust/issues/101610>. #![feature(rustc_private)] -extern crate libc; - #[unsafe(no_mangle)] fn hack() -> u64 { 998244353 } fn main() { + #[cfg(unix)] unsafe { + extern crate libc; let handle = libc::dlopen(std::ptr::null(), libc::RTLD_NOW); let ptr = libc::dlsym(handle, c"hack".as_ptr()); let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr); @@ -27,4 +27,24 @@ fn main() { panic!("symbol `hack` is not found"); } } + #[cfg(windows)] + unsafe { + type PCSTR = *const u8; + type HMODULE = *mut core::ffi::c_void; + type FARPROC = Option<unsafe extern "system" fn() -> isize>; + #[link(name = "kernel32", kind = "raw-dylib")] + unsafe extern "system" { + fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE; + fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC; + } + let handle = GetModuleHandleA(std::ptr::null_mut()); + let ptr = GetProcAddress(handle, b"hack\0".as_ptr()); + let ptr: Option<unsafe fn() -> u64> = std::mem::transmute(ptr); + if let Some(f) = ptr { + assert!(f() == 998244353); + println!("symbol `hack` is found successfully"); + } else { + panic!("symbol `hack` is not found"); + } + } } diff --git a/tests/ui/darwin-ld64.rs b/tests/ui/linking/ld64-cross-compilation.rs index 75acc07a002..d6c6d1ff91d 100644 --- a/tests/ui/darwin-ld64.rs +++ b/tests/ui/linking/ld64-cross-compilation.rs @@ -1,11 +1,11 @@ +//! This is a regression test for https://github.com/rust-lang/rust/issues/140686. +//! Although this is a ld64(ld-classic) bug, we still need to support it +//! due to cross-compilation and support for older Xcode. + //@ compile-flags: -Copt-level=3 -Ccodegen-units=256 -Clink-arg=-ld_classic //@ run-pass //@ only-x86_64-apple-darwin -// This is a regression test for https://github.com/rust-lang/rust/issues/140686. -// Although this is a ld64(ld-classic) bug, we still need to support it -// due to cross-compilation and support for older Xcode. - fn main() { let dst: Vec<u8> = Vec::new(); let len = broken_func(std::hint::black_box(2), dst); diff --git a/tests/ui/lint/invalid_null_args.rs b/tests/ui/lint/invalid_null_args.rs index f40f06a0d36..ee29d622ad7 100644 --- a/tests/ui/lint/invalid_null_args.rs +++ b/tests/ui/lint/invalid_null_args.rs @@ -58,10 +58,9 @@ unsafe fn null_ptr() { let _a: A = ptr::read_unaligned(ptr::null_mut()); //~^ ERROR calling this function with a null pointer is undefined behavior + // These two should *not* fire the lint. let _a: A = ptr::read_volatile(ptr::null()); - //~^ ERROR calling this function with a null pointer is undefined behavior let _a: A = ptr::read_volatile(ptr::null_mut()); - //~^ ERROR calling this function with a null pointer is undefined behavior let _a: A = ptr::replace(ptr::null_mut(), v); //~^ ERROR calling this function with a null pointer is undefined behavior @@ -82,8 +81,8 @@ unsafe fn null_ptr() { ptr::write_unaligned(ptr::null_mut(), v); //~^ ERROR calling this function with a null pointer is undefined behavior + // This one should *not* fire the lint. ptr::write_volatile(ptr::null_mut(), v); - //~^ ERROR calling this function with a null pointer is undefined behavior ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0); //~^ ERROR calling this function with a null pointer is undefined behavior diff --git a/tests/ui/lint/invalid_null_args.stderr b/tests/ui/lint/invalid_null_args.stderr index 11c6270cfb7..028bd7051dc 100644 --- a/tests/ui/lint/invalid_null_args.stderr +++ b/tests/ui/lint/invalid_null_args.stderr @@ -164,27 +164,7 @@ LL | let _a: A = ptr::read_unaligned(ptr::null_mut()); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:61:17 - | -LL | let _a: A = ptr::read_volatile(ptr::null()); - | ^^^^^^^^^^^^^^^^^^^-----------^ - | | - | null pointer originates from here - | - = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> - -error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:63:17 - | -LL | let _a: A = ptr::read_volatile(ptr::null_mut()); - | ^^^^^^^^^^^^^^^^^^^---------------^ - | | - | null pointer originates from here - | - = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> - -error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:66:17 + --> $DIR/invalid_null_args.rs:65:17 | LL | let _a: A = ptr::replace(ptr::null_mut(), v); | ^^^^^^^^^^^^^---------------^^^^ @@ -194,7 +174,7 @@ LL | let _a: A = ptr::replace(ptr::null_mut(), v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:69:5 + --> $DIR/invalid_null_args.rs:68:5 | LL | ptr::swap::<A>(ptr::null_mut(), &mut v); | ^^^^^^^^^^^^^^^---------------^^^^^^^^^ @@ -204,7 +184,7 @@ LL | ptr::swap::<A>(ptr::null_mut(), &mut v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:71:5 + --> $DIR/invalid_null_args.rs:70:5 | LL | ptr::swap::<A>(&mut v, ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -214,7 +194,7 @@ LL | ptr::swap::<A>(&mut v, ptr::null_mut()); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:74:5 + --> $DIR/invalid_null_args.rs:73:5 | LL | ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^^^^^ @@ -224,7 +204,7 @@ LL | ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:76:5 + --> $DIR/invalid_null_args.rs:75:5 | LL | ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -234,7 +214,7 @@ LL | ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:79:5 + --> $DIR/invalid_null_args.rs:78:5 | LL | ptr::write(ptr::null_mut(), v); | ^^^^^^^^^^^---------------^^^^ @@ -244,7 +224,7 @@ LL | ptr::write(ptr::null_mut(), v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:82:5 + --> $DIR/invalid_null_args.rs:81:5 | LL | ptr::write_unaligned(ptr::null_mut(), v); | ^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -254,17 +234,7 @@ LL | ptr::write_unaligned(ptr::null_mut(), v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:85:5 - | -LL | ptr::write_volatile(ptr::null_mut(), v); - | ^^^^^^^^^^^^^^^^^^^^---------------^^^^ - | | - | null pointer originates from here - | - = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> - -error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:88:5 + --> $DIR/invalid_null_args.rs:87:5 | LL | ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^ @@ -274,7 +244,7 @@ LL | ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:93:18 + --> $DIR/invalid_null_args.rs:92:18 | LL | let _a: u8 = ptr::read(const_ptr); | ^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +257,7 @@ LL | let null_ptr = ptr::null_mut(); | ^^^^^^^^^^^^^^^ error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:100:5 + --> $DIR/invalid_null_args.rs:99:5 | LL | std::slice::from_raw_parts::<()>(ptr::null(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -297,7 +267,7 @@ LL | std::slice::from_raw_parts::<()>(ptr::null(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:102:5 + --> $DIR/invalid_null_args.rs:101:5 | LL | std::slice::from_raw_parts::<Zst>(ptr::null(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -307,7 +277,7 @@ LL | std::slice::from_raw_parts::<Zst>(ptr::null(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:104:5 + --> $DIR/invalid_null_args.rs:103:5 | LL | std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -317,7 +287,7 @@ LL | std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:106:5 + --> $DIR/invalid_null_args.rs:105:5 | LL | std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -326,5 +296,5 @@ LL | std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0); | = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> -error: aborting due to 31 previous errors +error: aborting due to 28 previous errors diff --git a/tests/ui/lint/lint-double-negations-macro.rs b/tests/ui/lint/lint-double-negations-macro.rs new file mode 100644 index 00000000000..a6583271d5a --- /dev/null +++ b/tests/ui/lint/lint-double-negations-macro.rs @@ -0,0 +1,16 @@ +//@ check-pass +macro_rules! neg { + ($e: expr) => { + -$e + }; +} +macro_rules! bad_macro { + ($e: expr) => { + --$e //~ WARN use of a double negation + }; +} + +fn main() { + neg!(-1); + bad_macro!(1); +} diff --git a/tests/ui/lint/lint-double-negations-macro.stderr b/tests/ui/lint/lint-double-negations-macro.stderr new file mode 100644 index 00000000000..d6ac9be48f3 --- /dev/null +++ b/tests/ui/lint/lint-double-negations-macro.stderr @@ -0,0 +1,20 @@ +warning: use of a double negation + --> $DIR/lint-double-negations-macro.rs:9:9 + | +LL | --$e + | ^^^^ +... +LL | bad_macro!(1); + | ------------- in this macro invocation + | + = note: the prefix `--` could be misinterpreted as a decrement operator which exists in other languages + = note: use `-= 1` if you meant to decrement the value + = note: `#[warn(double_negations)]` on by default + = note: this warning originates in the macro `bad_macro` (in Nightly builds, run with -Z macro-backtrace for more info) +help: add parentheses for clarity + | +LL | -(-$e) + | + + + +warning: 1 warning emitted + diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr index 51205ff4340..0399fab746e 100644 --- a/tests/ui/lint/lint-stability-deprecated.stderr +++ b/tests/ui/lint/lint-stability-deprecated.stderr @@ -1,8 +1,8 @@ -warning: use of deprecated function `lint_stability::deprecated`: text - --> $DIR/lint-stability-deprecated.rs:24:9 +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text + --> $DIR/lint-stability-deprecated.rs:97:48 | -LL | deprecated(); - | ^^^^^^^^^^ +LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); + | ^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/lint-stability-deprecated.rs:6:9 @@ -10,6 +10,12 @@ note: the lint level is defined here LL | #![warn(deprecated)] | ^^^^^^^^^^ +warning: use of deprecated function `lint_stability::deprecated`: text + --> $DIR/lint-stability-deprecated.rs:24:9 + | +LL | deprecated(); + | ^^^^^^^^^^ + warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:29:16 | @@ -317,12 +323,6 @@ LL | fn_in_body(); | ^^^^^^^^^^ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:97:48 - | -LL | struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated); - | ^^^^^^^^^^^^^^^^^ - -warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:101:13 | LL | TypeDeprecated = u16, diff --git a/tests/ui/lint/lint-stability.stderr b/tests/ui/lint/lint-stability.stderr index fd57908a77b..249f3ccaa54 100644 --- a/tests/ui/lint/lint-stability.stderr +++ b/tests/ui/lint/lint-stability.stderr @@ -1,4 +1,13 @@ error[E0658]: use of unstable library feature `unstable_test_feature` + --> $DIR/lint-stability.rs:88:48 + | +LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable); + | ^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature `unstable_test_feature` --> $DIR/lint-stability.rs:17:5 | LL | extern crate stability_cfg2; @@ -368,15 +377,6 @@ LL | let _ = Unstable::StableVariant; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `unstable_test_feature` - --> $DIR/lint-stability.rs:88:48 - | -LL | struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable); - | ^^^^^^^^^^^^^^^ - | - = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature `unstable_test_feature` --> $DIR/lint-stability.rs:92:13 | LL | TypeUnstable = u8, diff --git a/tests/ui/lint/unused/unused-attr-duplicate.rs b/tests/ui/lint/unused/unused-attr-duplicate.rs index bf94a42f6e0..cfa6c2b4228 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.rs +++ b/tests/ui/lint/unused/unused-attr-duplicate.rs @@ -66,9 +66,11 @@ fn t1() {} #[non_exhaustive] //~ ERROR unused attribute pub struct X; +trait Trait {} + #[automatically_derived] #[automatically_derived] //~ ERROR unused attribute -impl X {} +impl Trait for X {} #[inline(always)] #[inline(never)] //~ ERROR unused attribute diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 6db6af823f4..ecc1b7ff5a4 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -179,112 +179,112 @@ LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:70:1 + --> $DIR/unused-attr-duplicate.rs:72:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:69:1 + --> $DIR/unused-attr-duplicate.rs:71:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:74:1 + --> $DIR/unused-attr-duplicate.rs:76:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:73:1 + --> $DIR/unused-attr-duplicate.rs:75:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:77:1 + --> $DIR/unused-attr-duplicate.rs:79:1 | LL | #[cold] | ^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:76:1 + --> $DIR/unused-attr-duplicate.rs:78:1 | LL | #[cold] | ^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:79:1 + --> $DIR/unused-attr-duplicate.rs:81:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:78:1 + --> $DIR/unused-attr-duplicate.rs:80:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:86:5 + --> $DIR/unused-attr-duplicate.rs:88:5 | LL | #[link_name = "this_does_not_exist"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:88:5 + --> $DIR/unused-attr-duplicate.rs:90:5 | LL | #[link_name = "rust_dbg_extern_identity_u32"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:92:1 + --> $DIR/unused-attr-duplicate.rs:94:1 | LL | #[export_name = "exported_symbol_name"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:94:1 + --> $DIR/unused-attr-duplicate.rs:96:1 | LL | #[export_name = "exported_symbol_name2"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:98:1 + --> $DIR/unused-attr-duplicate.rs:100:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:97:1 + --> $DIR/unused-attr-duplicate.rs:99:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:102:1 + --> $DIR/unused-attr-duplicate.rs:104:1 | LL | #[used] | ^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:101:1 + --> $DIR/unused-attr-duplicate.rs:103:1 | LL | #[used] | ^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:105:1 + --> $DIR/unused-attr-duplicate.rs:107:1 | LL | #[link_section = ".text"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:108:1 + --> $DIR/unused-attr-duplicate.rs:110:1 | LL | #[link_section = ".bss"] | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 28fd8eeb8cb..862ffa42d80 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -45,7 +45,7 @@ error: `#[must_use]` has no effect when applied to a static item LL | #[must_use] | ^^^^^^^^^^^ -error: `#[must_use]` has no effect when applied to an implementation block +error: `#[must_use]` has no effect when applied to an inherent implementation block --> $DIR/unused_attributes-must_use.rs:33:1 | LL | #[must_use] @@ -69,7 +69,7 @@ error: `#[must_use]` has no effect when applied to a type parameter LL | fn qux<#[must_use] T>(_: T) {} | ^^^^^^^^^^^ -error: `#[must_use]` has no effect when applied to an implementation block +error: `#[must_use]` has no effect when applied to an trait implementation block --> $DIR/unused_attributes-must_use.rs:79:1 | LL | #[must_use] diff --git a/tests/ui/lto/debuginfo-lto-alloc.rs b/tests/ui/lto/debuginfo-lto-alloc.rs index 89043275329..d6855f8760d 100644 --- a/tests/ui/lto/debuginfo-lto-alloc.rs +++ b/tests/ui/lto/debuginfo-lto-alloc.rs @@ -8,8 +8,9 @@ // This test reproduces the circumstances that caused the error to appear, and checks // that compilation is successful. -//@ check-pass +//@ build-pass //@ compile-flags: --test -C debuginfo=2 -C lto=fat +//@ no-prefer-dynamic //@ incremental extern crate alloc; diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index a4d94836a09..461d2e0e8c1 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -18,10 +18,13 @@ fn arm_rhs_must_be_in_braces() -> i32 { cfg_select! { _ => {} true => {} - //~^ WARN unreachable rule + //~^ WARN unreachable predicate } cfg_select! { - //~^ ERROR none of the rules in this `cfg_select` evaluated to true + //~^ ERROR none of the predicates in this `cfg_select` evaluated to true false => {} } + +cfg_select! {} +//~^ ERROR none of the predicates in this `cfg_select` evaluated to true diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index fef5e95a6bc..6c18a7c189d 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -4,15 +4,15 @@ error: expected `{`, found `1` LL | true => 1 | ^ expected `{` -warning: unreachable rule +warning: unreachable predicate --> $DIR/cfg_select.rs:20:5 | LL | _ => {} | - always matches LL | true => {} - | ^^^^ this rules is never reached + | ^^^^ this predicate is never reached -error: none of the rules in this `cfg_select` evaluated to true +error: none of the predicates in this `cfg_select` evaluated to true --> $DIR/cfg_select.rs:24:1 | LL | / cfg_select! { @@ -21,5 +21,11 @@ LL | | false => {} LL | | } | |_^ -error: aborting due to 2 previous errors; 1 warning emitted +error: none of the predicates in this `cfg_select` evaluated to true + --> $DIR/cfg_select.rs:29:1 + | +LL | cfg_select! {} + | ^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 32cff62284e..aeecb82e9d9 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -20,17 +20,12 @@ error[E0034]: multiple applicable items in scope LL | let z = x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in the trait `FinalFoo` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:60:5 - | -LL | fn foo(&self) -> u8; - | ^^^^^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T` +note: candidate #1 is defined in an impl of the trait `NuisanceFoo` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:73:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ -note: candidate #3 is defined in an impl of the trait `X` for the type `T` +note: candidate #2 is defined in an impl of the trait `X` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:46:9 | LL | fn foo(self: Smaht<Self, u64>) -> u64 { @@ -38,14 +33,9 @@ LL | fn foo(self: Smaht<Self, u64>) -> u64 { help: disambiguate the method for candidate #1 | LL - let z = x.foo(); -LL + let z = FinalFoo::foo(&x); - | -help: disambiguate the method for candidate #2 - | -LL - let z = x.foo(); LL + let z = NuisanceFoo::foo(x); | -help: disambiguate the method for candidate #3 +help: disambiguate the method for candidate #2 | LL - let z = x.foo(); LL + let z = X::foo(x); diff --git a/tests/ui/methods/wrong-ambig-message.rs b/tests/ui/methods/wrong-ambig-message.rs new file mode 100644 index 00000000000..f88d77e259d --- /dev/null +++ b/tests/ui/methods/wrong-ambig-message.rs @@ -0,0 +1,34 @@ +fn main() { + trait Hello { + fn name(&self) -> String; + } + + #[derive(Debug)] + struct Container2 { + val: String, + } + + trait AName2 { + fn name(&self) -> String; + } + + trait BName2 { + fn name(&self, v: bool) -> String; + } + + impl AName2 for Container2 { + fn name(&self) -> String { + "aname2".into() + } + } + + impl BName2 for Container2 { + fn name(&self, _v: bool) -> String { + "bname2".into() + } + } + + let c2 = Container2 { val: "abc".into() }; + println!("c2 = {:?}", c2.name()); + //~^ ERROR: multiple applicable items in scope +} diff --git a/tests/ui/methods/wrong-ambig-message.stderr b/tests/ui/methods/wrong-ambig-message.stderr new file mode 100644 index 00000000000..9a254595e40 --- /dev/null +++ b/tests/ui/methods/wrong-ambig-message.stderr @@ -0,0 +1,30 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/wrong-ambig-message.rs:32:30 + | +LL | println!("c2 = {:?}", c2.name()); + | ^^^^ multiple `name` found + | +note: candidate #1 is defined in an impl of the trait `AName2` for the type `Container2` + --> $DIR/wrong-ambig-message.rs:20:9 + | +LL | fn name(&self) -> String { + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl of the trait `BName2` for the type `Container2` + --> $DIR/wrong-ambig-message.rs:26:9 + | +LL | fn name(&self, _v: bool) -> String { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method for candidate #1 + | +LL - println!("c2 = {:?}", c2.name()); +LL + println!("c2 = {:?}", AName2::name(&c2)); + | +help: disambiguate the method for candidate #2 + | +LL - println!("c2 = {:?}", c2.name()); +LL + println!("c2 = {:?}", BName2::name(&c2)); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/mir/alignment/borrow_misaligned_field_projection.rs b/tests/ui/mir/alignment/borrow_misaligned_field_projection.rs index a22965ce1d8..6ba895f172d 100644 --- a/tests/ui/mir/alignment/borrow_misaligned_field_projection.rs +++ b/tests/ui/mir/alignment/borrow_misaligned_field_projection.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ ignore-i686-pc-windows-msvc: #112480 //@ compile-flags: -C debug-assertions //@ error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is diff --git a/tests/ui/mir/alignment/misaligned_borrow.rs b/tests/ui/mir/alignment/misaligned_borrow.rs index de8912c7038..60c21deaba5 100644 --- a/tests/ui/mir/alignment/misaligned_borrow.rs +++ b/tests/ui/mir/alignment/misaligned_borrow.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ ignore-i686-pc-windows-msvc: #112480 //@ compile-flags: -C debug-assertions //@ error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is diff --git a/tests/ui/mir/alignment/misaligned_lhs.rs b/tests/ui/mir/alignment/misaligned_lhs.rs index b169823bc08..e8ddb10fd9c 100644 --- a/tests/ui/mir/alignment/misaligned_lhs.rs +++ b/tests/ui/mir/alignment/misaligned_lhs.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ ignore-i686-pc-windows-msvc: #112480 //@ compile-flags: -C debug-assertions //@ error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is diff --git a/tests/ui/mir/alignment/misaligned_mut_borrow.rs b/tests/ui/mir/alignment/misaligned_mut_borrow.rs index bba20edecfd..c066cc0efcd 100644 --- a/tests/ui/mir/alignment/misaligned_mut_borrow.rs +++ b/tests/ui/mir/alignment/misaligned_mut_borrow.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ ignore-i686-pc-windows-msvc: #112480 //@ compile-flags: -C debug-assertions //@ error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is diff --git a/tests/ui/mir/alignment/misaligned_rhs.rs b/tests/ui/mir/alignment/misaligned_rhs.rs index 55da30a2fd7..6bdc39c9d91 100644 --- a/tests/ui/mir/alignment/misaligned_rhs.rs +++ b/tests/ui/mir/alignment/misaligned_rhs.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ ignore-i686-pc-windows-msvc: #112480 //@ compile-flags: -C debug-assertions //@ error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is diff --git a/tests/ui/mir/alignment/two_pointers.rs b/tests/ui/mir/alignment/two_pointers.rs index 198a1c9853d..fd8b2f543aa 100644 --- a/tests/ui/mir/alignment/two_pointers.rs +++ b/tests/ui/mir/alignment/two_pointers.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ ignore-i686-pc-windows-msvc: #112480 //@ compile-flags: -C debug-assertions //@ error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is diff --git a/tests/ui/mir/enum/convert_non_integer_break.rs b/tests/ui/mir/enum/convert_non_integer_break.rs index 29795190bf6..b0778e2024f 100644 --- a/tests/ui/mir/enum/convert_non_integer_break.rs +++ b/tests/ui/mir/enum/convert_non_integer_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value diff --git a/tests/ui/mir/enum/convert_non_integer_niche_break.rs b/tests/ui/mir/enum/convert_non_integer_niche_break.rs index 9ff4849c5b1..d26a3aeb506 100644 --- a/tests/ui/mir/enum/convert_non_integer_niche_break.rs +++ b/tests/ui/mir/enum/convert_non_integer_niche_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0x5 diff --git a/tests/ui/mir/enum/negative_discr_break.rs b/tests/ui/mir/enum/negative_discr_break.rs index fa1284f72a0..35ee8aa3fc8 100644 --- a/tests/ui/mir/enum/negative_discr_break.rs +++ b/tests/ui/mir/enum/negative_discr_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0xfd diff --git a/tests/ui/mir/enum/niche_option_tuple_break.rs b/tests/ui/mir/enum/niche_option_tuple_break.rs index affdc4784a3..0a933afa153 100644 --- a/tests/ui/mir/enum/niche_option_tuple_break.rs +++ b/tests/ui/mir/enum/niche_option_tuple_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value diff --git a/tests/ui/mir/enum/numbered_variants_break.rs b/tests/ui/mir/enum/numbered_variants_break.rs index e3e71dc8aec..fbe7d6627a3 100644 --- a/tests/ui/mir/enum/numbered_variants_break.rs +++ b/tests/ui/mir/enum/numbered_variants_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0x3 diff --git a/tests/ui/mir/enum/option_with_bigger_niche_break.rs b/tests/ui/mir/enum/option_with_bigger_niche_break.rs index c66614b845b..675d27f0ec2 100644 --- a/tests/ui/mir/enum/option_with_bigger_niche_break.rs +++ b/tests/ui/mir/enum/option_with_bigger_niche_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0x0 diff --git a/tests/ui/mir/enum/plain_no_data_break.rs b/tests/ui/mir/enum/plain_no_data_break.rs index db68e752479..966dd641873 100644 --- a/tests/ui/mir/enum/plain_no_data_break.rs +++ b/tests/ui/mir/enum/plain_no_data_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0x1 diff --git a/tests/ui/mir/enum/single_with_repr_break.rs b/tests/ui/mir/enum/single_with_repr_break.rs index 5a4ec85a9b5..53e4932d5fd 100644 --- a/tests/ui/mir/enum/single_with_repr_break.rs +++ b/tests/ui/mir/enum/single_with_repr_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0x1 diff --git a/tests/ui/mir/enum/with_niche_int_break.rs b/tests/ui/mir/enum/with_niche_int_break.rs index 6a97eaa8f4f..d363dc7568a 100644 --- a/tests/ui/mir/enum/with_niche_int_break.rs +++ b/tests/ui/mir/enum/with_niche_int_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value diff --git a/tests/ui/mir/enum/wrap_break.rs b/tests/ui/mir/enum/wrap_break.rs index 4491394ca5a..5c410afa511 100644 --- a/tests/ui/mir/enum/wrap_break.rs +++ b/tests/ui/mir/enum/wrap_break.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: trying to construct an enum from an invalid value 0x0 #![feature(never_type)] diff --git a/tests/crashes/128094.rs b/tests/ui/mir/gvn-nonsensical-coroutine-layout.rs index 56d09d78bed..f0d174cd01b 100644 --- a/tests/crashes/128094.rs +++ b/tests/ui/mir/gvn-nonsensical-coroutine-layout.rs @@ -1,15 +1,19 @@ -//@ known-bug: rust-lang/rust#128094 +//! Verify that we do not ICE when a coroutine body is malformed. //@ compile-flags: -Zmir-enable-passes=+GVN //@ edition: 2018 pub enum Request { TestSome(T), + //~^ ERROR cannot find type `T` in this scope [E0412] } pub async fn handle_event(event: Request) { async move { static instance: Request = Request { bar: 17 }; + //~^ ERROR expected struct, variant or union type, found enum `Request` [E0574] &instance } .await; } + +fn main() {} diff --git a/tests/ui/mir/gvn-nonsensical-coroutine-layout.stderr b/tests/ui/mir/gvn-nonsensical-coroutine-layout.stderr new file mode 100644 index 00000000000..abc7b16ca74 --- /dev/null +++ b/tests/ui/mir/gvn-nonsensical-coroutine-layout.stderr @@ -0,0 +1,26 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/gvn-nonsensical-coroutine-layout.rs:6:14 + | +LL | TestSome(T), + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | pub enum Request<T> { + | +++ + +error[E0574]: expected struct, variant or union type, found enum `Request` + --> $DIR/gvn-nonsensical-coroutine-layout.rs:12:36 + | +LL | static instance: Request = Request { bar: 17 }; + | ^^^^^^^ not a struct, variant or union type + | +help: consider importing this struct instead + | +LL + use std::error::Request; + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0412, E0574. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/crashes/135128.rs b/tests/ui/mir/gvn-nonsensical-sized-str.rs index c718b758dc6..29a82f8ce2a 100644 --- a/tests/crashes/135128.rs +++ b/tests/ui/mir/gvn-nonsensical-sized-str.rs @@ -1,13 +1,16 @@ -//@ known-bug: #135128 +//! Verify that we do not ICE when optimizing bodies with nonsensical bounds. //@ compile-flags: -Copt-level=1 //@ edition: 2021 +//@ build-pass #![feature(trivial_bounds)] async fn return_str() -> str where str: Sized, + //~^ WARN trait bound str: Sized does not depend on any type or lifetime parameters { *"Sized".to_string().into_boxed_str() } + fn main() {} diff --git a/tests/ui/mir/gvn-nonsensical-sized-str.stderr b/tests/ui/mir/gvn-nonsensical-sized-str.stderr new file mode 100644 index 00000000000..08f0193e9f6 --- /dev/null +++ b/tests/ui/mir/gvn-nonsensical-sized-str.stderr @@ -0,0 +1,10 @@ +warning: trait bound str: Sized does not depend on any type or lifetime parameters + --> $DIR/gvn-nonsensical-sized-str.rs:10:10 + | +LL | str: Sized, + | ^^^^^ + | + = note: `#[warn(trivial_bounds)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/mir/null/borrowed_mut_null.rs b/tests/ui/mir/null/borrowed_mut_null.rs index d26452b9dac..a4660f4bf57 100644 --- a/tests/ui/mir/null/borrowed_mut_null.rs +++ b/tests/ui/mir/null/borrowed_mut_null.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: null pointer dereference occurred diff --git a/tests/ui/mir/null/borrowed_null.rs b/tests/ui/mir/null/borrowed_null.rs index fefac3a7212..2a50058a482 100644 --- a/tests/ui/mir/null/borrowed_null.rs +++ b/tests/ui/mir/null/borrowed_null.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: null pointer dereference occurred diff --git a/tests/ui/mir/null/borrowed_null_zst.rs b/tests/ui/mir/null/borrowed_null_zst.rs index 835727c068b..106fa00b1db 100644 --- a/tests/ui/mir/null/borrowed_null_zst.rs +++ b/tests/ui/mir/null/borrowed_null_zst.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: null pointer dereference occurred diff --git a/tests/ui/mir/null/null_lhs.rs b/tests/ui/mir/null/null_lhs.rs index 238d350d1bd..b59338588a5 100644 --- a/tests/ui/mir/null/null_lhs.rs +++ b/tests/ui/mir/null/null_lhs.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: null pointer dereference occurred diff --git a/tests/ui/mir/null/null_rhs.rs b/tests/ui/mir/null/null_rhs.rs index 18eafb61869..18fdad759fd 100644 --- a/tests/ui/mir/null/null_rhs.rs +++ b/tests/ui/mir/null/null_rhs.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: null pointer dereference occurred diff --git a/tests/ui/mir/null/two_pointers.rs b/tests/ui/mir/null/two_pointers.rs index 52b9510be12..b2aa7cf0384 100644 --- a/tests/ui/mir/null/two_pointers.rs +++ b/tests/ui/mir/null/two_pointers.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -C debug-assertions //@ error-pattern: null pointer dereference occurred diff --git a/tests/ui/mir/validate/critical-edge.rs b/tests/ui/mir/validate/critical-edge.rs index 2a3bf6a6181..7fe3891d642 100644 --- a/tests/ui/mir/validate/critical-edge.rs +++ b/tests/ui/mir/validate/critical-edge.rs @@ -21,6 +21,8 @@ pub fn f(a: u32) -> u32 { } bb1 = { Call(RET = f(1), ReturnTo(bb2), UnwindTerminate(ReasonAbi)) +//~^ ERROR broken MIR in Item +//~| ERROR encountered critical edge in `Call` terminator } bb2 = { @@ -29,5 +31,3 @@ pub fn f(a: u32) -> u32 { } } } - -//~? RAW encountered critical edge in `Call` terminator diff --git a/tests/ui/mir/validate/project-into-simd.rs b/tests/ui/mir/validate/project-into-simd.rs new file mode 100644 index 00000000000..67766c8c4b0 --- /dev/null +++ b/tests/ui/mir/validate/project-into-simd.rs @@ -0,0 +1,18 @@ +// Optimized MIR shouldn't have critical call edges +// +//@ build-fail +//@ edition: 2021 +//@ compile-flags: --crate-type=lib +//@ failure-status: 101 +//@ dont-check-compiler-stderr + +#![feature(repr_simd)] + +#[repr(simd)] +pub struct U32x4([u32; 4]); + +pub fn f(a: U32x4) -> [u32; 4] { + a.0 + //~^ ERROR broken MIR in Item + //~| ERROR Projecting into SIMD type U32x4 is banned by MCP#838 +} diff --git a/tests/ui/missing/missing-stability.stderr b/tests/ui/missing/missing-stability.stderr index 659f8c78cae..bf8046c4e12 100644 --- a/tests/ui/missing/missing-stability.stderr +++ b/tests/ui/missing/missing-stability.stderr @@ -1,17 +1,14 @@ error: function has missing stability attribute --> $DIR/missing-stability.rs:8:1 | -LL | / pub fn unmarked() { -LL | | -LL | | () -LL | | } - | |_^ +LL | pub fn unmarked() { + | ^^^^^^^^^^^^^^^^^ error: function has missing stability attribute --> $DIR/missing-stability.rs:22:5 | LL | pub fn unmarked() {} - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index 76c6fc5e7b9..96168ebeaa1 100644 --- a/tests/ui/nll/issue-50716.rs +++ b/tests/ui/nll/issue-50716.rs @@ -5,7 +5,7 @@ trait A { type X: ?Sized; } -fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR +fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) where for<'b> &'b T: A, <&'static T as A>::X: Sized diff --git a/tests/ui/nll/issue-50716.stderr b/tests/ui/nll/issue-50716.stderr index edd7fd765da..536f88085de 100644 --- a/tests/ui/nll/issue-50716.stderr +++ b/tests/ui/nll/issue-50716.stderr @@ -1,18 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/issue-50716.rs:8:27 - | -LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) - | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected trait `<<&'a T as A>::X as MetaSized>` - found trait `<<&'static T as A>::X as MetaSized>` -note: the lifetime `'a` as defined here... - --> $DIR/issue-50716.rs:8:8 - | -LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) - | ^^ - = note: ...does not necessarily outlive the static lifetime - error: lifetime may not live long enough --> $DIR/issue-50716.rs:13:14 | @@ -22,6 +7,5 @@ LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) LL | let _x = *s; | ^^ proving this value is `Sized` requires that `'a` must outlive `'static` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/panics/panic-in-cleanup.rs b/tests/ui/panics/panic-in-cleanup.rs index 8cddeb37348..2e307de4393 100644 --- a/tests/ui/panics/panic-in-cleanup.rs +++ b/tests/ui/panics/panic-in-cleanup.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panic in a destructor during cleanup diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs index 6068e4fdc59..b926d0fa776 100644 --- a/tests/ui/panics/panic-in-ffi.rs +++ b/tests/ui/panics/panic-in-ffi.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panic in a function that cannot unwind diff --git a/tests/ui/panics/panic-in-message-fmt.rs b/tests/ui/panics/panic-in-message-fmt.rs index 1e9bbaf45c5..4d539f17a0a 100644 --- a/tests/ui/panics/panic-in-message-fmt.rs +++ b/tests/ui/panics/panic-in-message-fmt.rs @@ -1,6 +1,6 @@ // Checks what happens when formatting the panic message panics. -//@ run-fail +//@ run-crash //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panicked while processing panic diff --git a/tests/ui/panics/panic-main.rs b/tests/ui/panics/panic-main.rs index 3876dbb37c3..2009f69e19e 100644 --- a/tests/ui/panics/panic-main.rs +++ b/tests/ui/panics/panic-main.rs @@ -1,4 +1,37 @@ -//@ run-fail +//@ revisions: default abort-zero abort-one abort-full unwind-zero unwind-one unwind-full + +//@[default] run-fail + +//@[abort-zero] compile-flags: -Cpanic=abort +//@[abort-zero] no-prefer-dynamic +//@[abort-zero] exec-env:RUST_BACKTRACE=0 +//@[abort-zero] run-crash + +//@[abort-one] compile-flags: -Cpanic=abort +//@[abort-one] no-prefer-dynamic +//@[abort-one] exec-env:RUST_BACKTRACE=1 +//@[abort-one] run-crash + +//@[abort-full] compile-flags: -Cpanic=abort +//@[abort-full] no-prefer-dynamic +//@[abort-full] exec-env:RUST_BACKTRACE=full +//@[abort-full] run-crash + +//@[unwind-zero] compile-flags: -Cpanic=unwind +//@[unwind-zero] exec-env:RUST_BACKTRACE=0 +//@[unwind-zero] needs-unwind +//@[unwind-zero] run-fail + +//@[unwind-one] compile-flags: -Cpanic=unwind +//@[unwind-one] exec-env:RUST_BACKTRACE=1 +//@[unwind-one] needs-unwind +//@[unwind-one] run-fail + +//@[unwind-full] compile-flags: -Cpanic=unwind +//@[unwind-full] exec-env:RUST_BACKTRACE=full +//@[unwind-full] needs-unwind +//@[unwind-full] run-fail + //@ error-pattern:moop //@ needs-subprocess diff --git a/tests/ui/parser/better-expected.rs b/tests/ui/parser/better-expected.rs index 16b61caa4df..91128c39691 100644 --- a/tests/ui/parser/better-expected.rs +++ b/tests/ui/parser/better-expected.rs @@ -1,3 +1,3 @@ fn main() { - let x: [isize 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3` + let x: [isize 3]; //~ ERROR expected `;` or `]`, found `3` } diff --git a/tests/ui/parser/better-expected.stderr b/tests/ui/parser/better-expected.stderr index f4ec933be16..4646ce7eff0 100644 --- a/tests/ui/parser/better-expected.stderr +++ b/tests/ui/parser/better-expected.stderr @@ -1,10 +1,14 @@ -error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3` +error: expected `;` or `]`, found `3` --> $DIR/better-expected.rs:2:19 | LL | let x: [isize 3]; - | - ^ expected one of 7 possible tokens - | | - | while parsing the type for `x` + | ^ expected `;` or `]` + | + = note: you might have meant to write a slice or array type +help: you might have meant to use `;` as the separator + | +LL | let x: [isize ;3]; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/deli-ident-issue-2.rs b/tests/ui/parser/deli-ident-issue-2.rs index 5394760df70..419933c68ad 100644 --- a/tests/ui/parser/deli-ident-issue-2.rs +++ b/tests/ui/parser/deli-ident-issue-2.rs @@ -1,6 +1,6 @@ fn main() { if 1 < 2 { - let _a = vec!]; //~ ERROR mismatched closing delimiter + let _a = vec!]; } } //~ ERROR unexpected closing delimiter diff --git a/tests/ui/parser/deli-ident-issue-2.stderr b/tests/ui/parser/deli-ident-issue-2.stderr index e0188cdfb4a..703cbf19626 100644 --- a/tests/ui/parser/deli-ident-issue-2.stderr +++ b/tests/ui/parser/deli-ident-issue-2.stderr @@ -1,19 +1,13 @@ -error: mismatched closing delimiter: `]` - --> $DIR/deli-ident-issue-2.rs:2:14 - | -LL | if 1 < 2 { - | ^ unclosed delimiter -LL | let _a = vec!]; - | ^ mismatched closing delimiter - error: unexpected closing delimiter: `}` --> $DIR/deli-ident-issue-2.rs:5:1 | +LL | if 1 < 2 { + | - the nearest open delimiter LL | let _a = vec!]; | - missing open `[` for this delimiter LL | } LL | } | ^ unexpected closing delimiter -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/error-pattern-issue-50571.rs b/tests/ui/parser/issues/error-pattern-issue-50571.rs new file mode 100644 index 00000000000..0c2ce6052cb --- /dev/null +++ b/tests/ui/parser/issues/error-pattern-issue-50571.rs @@ -0,0 +1,11 @@ +// There is a regression introduced for issue #143828 +//@ edition: 2015 + +#![allow(dead_code)] +trait Foo { + fn foo([a, b]: [i32; 2]) {} + //~^ ERROR: expected `;` or `]`, found `,` + //~| ERROR: patterns aren't allowed in methods without bodies +} + +fn main() {} diff --git a/tests/ui/parser/issues/error-pattern-issue-50571.stderr b/tests/ui/parser/issues/error-pattern-issue-50571.stderr new file mode 100644 index 00000000000..47457cff461 --- /dev/null +++ b/tests/ui/parser/issues/error-pattern-issue-50571.stderr @@ -0,0 +1,28 @@ +error: expected `;` or `]`, found `,` + --> $DIR/error-pattern-issue-50571.rs:6:14 + | +LL | fn foo([a, b]: [i32; 2]) {} + | ^ expected `;` or `]` + | + = note: you might have meant to write a slice or array type +help: you might have meant to use `;` as the separator + | +LL - fn foo([a, b]: [i32; 2]) {} +LL + fn foo([a; b]: [i32; 2]) {} + | + +error[E0642]: patterns aren't allowed in methods without bodies + --> $DIR/error-pattern-issue-50571.rs:6:12 + | +LL | fn foo([a, b]: [i32; 2]) {} + | ^^^^^^ + | +help: give this argument a name or use an underscore to ignore it + | +LL - fn foo([a, b]: [i32; 2]) {} +LL + fn foo(_: [i32; 2]) {} + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0642`. diff --git a/tests/ui/parser/issues/issue-104367.stderr b/tests/ui/parser/issues/issue-104367.stderr index c067d12e2d9..f01fa4a1265 100644 --- a/tests/ui/parser/issues/issue-104367.stderr +++ b/tests/ui/parser/issues/issue-104367.stderr @@ -18,7 +18,6 @@ LL | d: [u32; { LL | #![cfg] { | - unclosed delimiter LL | #![w,) - | - missing open `(` for this delimiter LL | | ^ diff --git a/tests/ui/parser/issues/issue-105209.rs b/tests/ui/parser/issues/issue-105209.rs index f4e331523bf..12c902e1d80 100644 --- a/tests/ui/parser/issues/issue-105209.rs +++ b/tests/ui/parser/issues/issue-105209.rs @@ -1,3 +1,3 @@ //@ compile-flags: -Zunpretty=ast-tree #![c={#![c[)x //~ ERROR mismatched closing delimiter - //~ ERROR this file contains an unclosed delimiter + //~ ERROR this file contains an unclosed delimiter diff --git a/tests/ui/parser/issues/issue-105209.stderr b/tests/ui/parser/issues/issue-105209.stderr index 72017e4327d..75643d18029 100644 --- a/tests/ui/parser/issues/issue-105209.stderr +++ b/tests/ui/parser/issues/issue-105209.stderr @@ -7,16 +7,15 @@ LL | #![c={#![c[)x | unclosed delimiter error: this file contains an unclosed delimiter - --> $DIR/issue-105209.rs:3:68 + --> $DIR/issue-105209.rs:3:56 | LL | #![c={#![c[)x - | - - - - missing open `(` for this delimiter - | | | | - | | | unclosed delimiter + | - - - unclosed delimiter + | | | | | unclosed delimiter | unclosed delimiter LL | - | ^ + | ^ error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs b/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs index 316c612940c..439793ea8f7 100644 --- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs +++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs @@ -1,6 +1,6 @@ //@ edition:2018 #![crate_type = "lib"] -#![feature(type_ascription)] +#![feature(type_ascription, const_index, const_trait_impl)] use std::future::Future; use std::pin::Pin; @@ -129,7 +129,6 @@ pub fn inside_block() { static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); //~^ ERROR: cast cannot be followed by indexing -//~| ERROR: cannot call non-const operator in statics static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); //~^ ERROR: expected one of diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr index 64cf8baf9a5..ce7129da937 100644 --- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr +++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr @@ -219,13 +219,13 @@ LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]); | + + error: expected one of `)`, `,`, `.`, `?`, or an operator, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:134:36 + --> $DIR/issue-35813-postfix-after-cast.rs:133:36 | LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); | ^ expected one of `)`, `,`, `.`, `?`, or an operator error: cast cannot be followed by `?` - --> $DIR/issue-35813-postfix-after-cast.rs:139:5 + --> $DIR/issue-35813-postfix-after-cast.rs:138:5 | LL | Err(0u64) as Result<u64,u64>?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -236,25 +236,25 @@ LL | (Err(0u64) as Result<u64,u64>)?; | + + error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:141:14 + --> $DIR/issue-35813-postfix-after-cast.rs:140:14 | LL | Err(0u64): Result<u64,u64>?; | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: expected identifier, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:153:13 + --> $DIR/issue-35813-postfix-after-cast.rs:152:13 | LL | drop_ptr: F(); | ^ expected identifier error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:160:13 + --> $DIR/issue-35813-postfix-after-cast.rs:159:13 | LL | drop_ptr: fn(u8); | ^ expected one of 8 possible tokens error: cast cannot be followed by a function call - --> $DIR/issue-35813-postfix-after-cast.rs:166:5 + --> $DIR/issue-35813-postfix-after-cast.rs:165:5 | LL | drop as fn(u8)(0); | ^^^^^^^^^^^^^^ @@ -265,13 +265,13 @@ LL | (drop as fn(u8))(0); | + + error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:168:13 + --> $DIR/issue-35813-postfix-after-cast.rs:167:13 | LL | drop_ptr: fn(u8)(0); | ^ expected one of 8 possible tokens error: cast cannot be followed by `.await` - --> $DIR/issue-35813-postfix-after-cast.rs:173:5 + --> $DIR/issue-35813-postfix-after-cast.rs:172:5 | LL | Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -282,13 +282,13 @@ LL | (Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>).await; | + + error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:176:21 + --> $DIR/issue-35813-postfix-after-cast.rs:175:21 | LL | Box::pin(noop()): Pin<Box<_>>.await; | ^ expected one of `.`, `;`, `?`, `}`, or an operator error: cast cannot be followed by a field access - --> $DIR/issue-35813-postfix-after-cast.rs:188:5 + --> $DIR/issue-35813-postfix-after-cast.rs:187:5 | LL | Foo::default() as Foo.bar; | ^^^^^^^^^^^^^^^^^^^^^ @@ -299,7 +299,7 @@ LL | (Foo::default() as Foo).bar; | + + error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:` - --> $DIR/issue-35813-postfix-after-cast.rs:190:19 + --> $DIR/issue-35813-postfix-after-cast.rs:189:19 | LL | Foo::default(): Foo.bar; | ^ expected one of `.`, `;`, `?`, `}`, or an operator @@ -322,21 +322,11 @@ LL | if true { 33 } else { 44 }: i32.max(0) | ^ expected one of `,`, `.`, `?`, or an operator error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-35813-postfix-after-cast.rs:151:13 + --> $DIR/issue-35813-postfix-after-cast.rs:150:13 | LL | drop as F(); | ^^^ only `Fn` traits may use parentheses -error[E0015]: cannot call non-const operator in statics - --> $DIR/issue-35813-postfix-after-cast.rs:130:42 - | -LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); - | ^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error: aborting due to 40 previous errors +error: aborting due to 39 previous errors -Some errors have detailed explanations: E0015, E0214. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0214`. diff --git a/tests/ui/parser/issues/issue-62973.stderr b/tests/ui/parser/issues/issue-62973.stderr index ea3e2bebee4..c7fc5bc29ed 100644 --- a/tests/ui/parser/issues/issue-62973.stderr +++ b/tests/ui/parser/issues/issue-62973.stderr @@ -18,10 +18,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-62973.rs:10:2 | LL | fn p() { match s { v, E { [) {) } - | - - - - missing open `(` for this delimiter - | | | | - | | | missing open `(` for this delimiter - | | unclosed delimiter + | - - unclosed delimiter + | | | unclosed delimiter LL | LL | diff --git a/tests/ui/parser/issues/issue-63116.stderr b/tests/ui/parser/issues/issue-63116.stderr index e5bad84d112..736a0ac2cf6 100644 --- a/tests/ui/parser/issues/issue-63116.stderr +++ b/tests/ui/parser/issues/issue-63116.stderr @@ -10,9 +10,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-63116.rs:4:18 | LL | impl W <s(f;Y(;] - | - -^ - | | | - | | missing open `[` for this delimiter + | - ^ + | | | unclosed delimiter error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr index b82b0f3255b..5301d43e2ae 100644 --- a/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr +++ b/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -28,18 +28,14 @@ LL | V = [Vec::new; { [0].len() ].len() as isize, error: this file contains an unclosed delimiter --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:23:65 | -LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - missing open `[` for this delimiter -... -LL | V = [Vec::new; { [].len() ].len() as isize, - | - missing open `[` for this delimiter -... LL | mod c { | - unclosed delimiter LL | enum Bug { -LL | V = [Vec::new; { [0].len() ].len() as isize, - | - missing open `[` for this delimiter + | - this delimiter might not be properly closed... ... +LL | } + | - ...as it matches this but it has different indentation +LL | LL | fn main() {} | ^ diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs index 89aaa68ba40..9b4452ed2a1 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs @@ -1,7 +1,7 @@ // FIXME: this case need more work to fix // currently the TokenTree matching ')' with '{', which is not user friendly for diagnostics async fn obstest() -> Result<> { - let obs_connect = || -> Result<(), MyError) { //~ ERROR mismatched closing delimiter + let obs_connect = || -> Result<(), MyError) { async { } } diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr index 0ecb748a0a4..c29a4ff8dbe 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr @@ -1,19 +1,13 @@ -error: mismatched closing delimiter: `)` - --> $DIR/issue-68987-unmatch-issue-2.rs:3:32 - | -LL | async fn obstest() -> Result<> { - | ^ unclosed delimiter -LL | let obs_connect = || -> Result<(), MyError) { - | ^ mismatched closing delimiter - error: unexpected closing delimiter: `}` --> $DIR/issue-68987-unmatch-issue-2.rs:14:1 | +LL | async fn obstest() -> Result<> { + | - the nearest open delimiter LL | let obs_connect = || -> Result<(), MyError) { | - missing open `(` for this delimiter ... LL | } | ^ unexpected closing delimiter -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs index e98df8d7c3c..e71e2730980 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs @@ -3,6 +3,6 @@ fn f(i: u32, j: u32) { let res = String::new(); let mut cnt = i; while cnt < j { - write!&mut res, " "); //~ ERROR mismatched closing delimiter + write!&mut res, " "); } } //~ ERROR unexpected closing delimiter diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr index dfc4407ed65..6b012af1af3 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr @@ -1,19 +1,13 @@ -error: mismatched closing delimiter: `)` - --> $DIR/issue-68987-unmatch-issue-3.rs:5:19 - | -LL | while cnt < j { - | ^ unclosed delimiter -LL | write!&mut res, " "); - | ^ mismatched closing delimiter - error: unexpected closing delimiter: `}` --> $DIR/issue-68987-unmatch-issue-3.rs:8:1 | +LL | while cnt < j { + | - the nearest open delimiter LL | write!&mut res, " "); | - missing open `(` for this delimiter LL | } LL | } | ^ unexpected closing delimiter -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-81827.stderr b/tests/ui/parser/issues/issue-81827.stderr index 986ed6b7e70..9737c8c90ae 100644 --- a/tests/ui/parser/issues/issue-81827.stderr +++ b/tests/ui/parser/issues/issue-81827.stderr @@ -11,9 +11,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-81827.rs:7:27 | LL | fn r()->i{0|{#[cfg(r(0{]0 - | - - - ^ - | | | | - | | | missing open `[` for this delimiter + | - - ^ + | | | | | unclosed delimiter | unclosed delimiter diff --git a/tests/ui/parser/issues/unnessary-error-issue-138401.rs b/tests/ui/parser/issues/unnessary-error-issue-138401.rs new file mode 100644 index 00000000000..208c516365a --- /dev/null +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.rs @@ -0,0 +1,6 @@ +pub fn foo(x: i64) -> i64 { + x.abs) +} +//~^ ERROR unexpected closing delimiter: `}` + +fn main() {} diff --git a/tests/ui/parser/issues/unnessary-error-issue-138401.stderr b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr new file mode 100644 index 00000000000..54c73b50a42 --- /dev/null +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr @@ -0,0 +1,12 @@ +error: unexpected closing delimiter: `}` + --> $DIR/unnessary-error-issue-138401.rs:3:1 + | +LL | pub fn foo(x: i64) -> i64 { + | - the nearest open delimiter +LL | x.abs) + | - missing open `(` for this delimiter +LL | } + | ^ unexpected closing delimiter + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/recover/array-type-no-semi.rs b/tests/ui/parser/recover/array-type-no-semi.rs new file mode 100644 index 00000000000..2cc5d979604 --- /dev/null +++ b/tests/ui/parser/recover/array-type-no-semi.rs @@ -0,0 +1,17 @@ +// when the next token is not a semicolon, +// we should suggest to use semicolon if recovery is allowed +// See issue #143828 + +fn main() { + let x = 5; + let b: [i32, 5]; + //~^ ERROR expected `;` or `]`, found `,` + let a: [i32, ]; + //~^ ERROR expected `;` or `]`, found `,` + //~| ERROR expected value, found builtin type `i32` [E0423] + let c: [i32, x]; + //~^ ERROR expected `;` or `]`, found `,` + //~| ERROR attempt to use a non-constant value in a constant [E0435] + let e: [i32 5]; + //~^ ERROR expected `;` or `]`, found `5` +} diff --git a/tests/ui/parser/recover/array-type-no-semi.stderr b/tests/ui/parser/recover/array-type-no-semi.stderr new file mode 100644 index 00000000000..82330465144 --- /dev/null +++ b/tests/ui/parser/recover/array-type-no-semi.stderr @@ -0,0 +1,71 @@ +error: expected `;` or `]`, found `,` + --> $DIR/array-type-no-semi.rs:7:16 + | +LL | let b: [i32, 5]; + | ^ expected `;` or `]` + | + = note: you might have meant to write a slice or array type +help: you might have meant to use `;` as the separator + | +LL - let b: [i32, 5]; +LL + let b: [i32; 5]; + | + +error: expected `;` or `]`, found `,` + --> $DIR/array-type-no-semi.rs:9:16 + | +LL | let a: [i32, ]; + | - ^ expected `;` or `]` + | | + | while parsing the type for `a` + | help: use `=` if you meant to assign + | + = note: you might have meant to write a slice or array type + +error: expected `;` or `]`, found `,` + --> $DIR/array-type-no-semi.rs:12:16 + | +LL | let c: [i32, x]; + | ^ expected `;` or `]` + | + = note: you might have meant to write a slice or array type +help: you might have meant to use `;` as the separator + | +LL - let c: [i32, x]; +LL + let c: [i32; x]; + | + +error: expected `;` or `]`, found `5` + --> $DIR/array-type-no-semi.rs:15:17 + | +LL | let e: [i32 5]; + | ^ expected `;` or `]` + | + = note: you might have meant to write a slice or array type +help: you might have meant to use `;` as the separator + | +LL | let e: [i32 ;5]; + | + + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/array-type-no-semi.rs:12:18 + | +LL | let c: [i32, x]; + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL - let x = 5; +LL + const x: /* Type */ = 5; + | + +error[E0423]: expected value, found builtin type `i32` + --> $DIR/array-type-no-semi.rs:9:13 + | +LL | let a: [i32, ]; + | ^^^ not a value + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0423, E0435. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs index 560efecb91c..fb9a1c643fc 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs +++ b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.rs @@ -1 +1,6 @@ -type v = [isize * 3]; //~ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*` +type v = [isize * 3]; +//~^ ERROR expected `;` or `]`, found `*` +//~| WARN type `v` should have an upper camel case name [non_camel_case_types] + + +fn main() {} diff --git a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr index 5bc9c2ccf00..8d7938a1a46 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-fixed-vec.stderr @@ -1,8 +1,23 @@ -error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*` +error: expected `;` or `]`, found `*` --> $DIR/removed-syntax-fixed-vec.rs:1:17 | LL | type v = [isize * 3]; - | ^ expected one of 7 possible tokens + | ^ expected `;` or `]` + | + = note: you might have meant to write a slice or array type +help: you might have meant to use `;` as the separator + | +LL - type v = [isize * 3]; +LL + type v = [isize ; 3]; + | + +warning: type `v` should have an upper camel case name + --> $DIR/removed-syntax-fixed-vec.rs:1:6 + | +LL | type v = [isize * 3]; + | ^ help: convert the identifier to upper camel case (notice the capitalization): `V` + | + = note: `#[warn(non_camel_case_types)]` on by default -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/parser/trait-object-trait-parens.rs b/tests/ui/parser/trait-object-trait-parens.rs index 438034bc38a..51f0e2de611 100644 --- a/tests/ui/parser/trait-object-trait-parens.rs +++ b/tests/ui/parser/trait-object-trait-parens.rs @@ -6,17 +6,17 @@ fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {} fn main() { let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; - //~^ ERROR `?Trait` is not permitted in trait object types + //~^ ERROR relaxed bounds are not permitted in trait object types //~| ERROR only auto traits can be used as additional traits //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; - //~^ ERROR `?Trait` is not permitted in trait object types + //~^ ERROR relaxed bounds are not permitted in trait object types //~| ERROR only auto traits can be used as additional traits //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; - //~^ ERROR `?Trait` is not permitted in trait object types + //~^ ERROR relaxed bounds are not permitted in trait object types //~| ERROR only auto traits can be used as additional traits //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr index d75352b6811..26d388f8779 100644 --- a/tests/ui/parser/trait-object-trait-parens.stderr +++ b/tests/ui/parser/trait-object-trait-parens.stderr @@ -1,29 +1,20 @@ -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:8:24 | LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:13:16 | LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>; | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:18:44 | LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; | ^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:8:16 @@ -100,5 +91,4 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>; error: aborting due to 6 previous errors; 3 warnings emitted -Some errors have detailed explanations: E0225, E0658. -For more information about an error, try `rustc --explain E0225`. +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/precondition-checks/alignment.rs b/tests/ui/precondition-checks/alignment.rs index 92400528fa0..038a625bed7 100644 --- a/tests/ui/precondition-checks/alignment.rs +++ b/tests/ui/precondition-checks/alignment.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: Alignment::new_unchecked requires diff --git a/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs index 30c6f79fb08..41ba2c5254a 100644 --- a/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs +++ b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: `ascii::Char::digit_unchecked` input cannot exceed 9 diff --git a/tests/ui/precondition-checks/assert_unchecked.rs b/tests/ui/precondition-checks/assert_unchecked.rs index 22b2b414550..da5383cdea0 100644 --- a/tests/ui/precondition-checks/assert_unchecked.rs +++ b/tests/ui/precondition-checks/assert_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: hint::assert_unchecked must never be called when the condition is false diff --git a/tests/ui/precondition-checks/char-from_u32_unchecked.rs b/tests/ui/precondition-checks/char-from_u32_unchecked.rs index d950f20c772..7c34d926d3e 100644 --- a/tests/ui/precondition-checks/char-from_u32_unchecked.rs +++ b/tests/ui/precondition-checks/char-from_u32_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: invalid value for `char` diff --git a/tests/ui/precondition-checks/copy-nonoverlapping.rs b/tests/ui/precondition-checks/copy-nonoverlapping.rs index eacaa63e543..1d584ddef4c 100644 --- a/tests/ui/precondition-checks/copy-nonoverlapping.rs +++ b/tests/ui/precondition-checks/copy-nonoverlapping.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::copy_nonoverlapping requires //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping diff --git a/tests/ui/precondition-checks/copy.rs b/tests/ui/precondition-checks/copy.rs index 1fadd90bf70..8faa56a880e 100644 --- a/tests/ui/precondition-checks/copy.rs +++ b/tests/ui/precondition-checks/copy.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::copy requires //@ revisions: null_src null_dst misaligned_src misaligned_dst diff --git a/tests/ui/precondition-checks/layout.rs b/tests/ui/precondition-checks/layout.rs index 4ee66cc9328..6755ebce854 100644 --- a/tests/ui/precondition-checks/layout.rs +++ b/tests/ui/precondition-checks/layout.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: Layout::from_size_align_unchecked requires //@ revisions: toolarge badalign diff --git a/tests/ui/precondition-checks/nonnull.rs b/tests/ui/precondition-checks/nonnull.rs index 6b8edd4e582..75bbd65b486 100644 --- a/tests/ui/precondition-checks/nonnull.rs +++ b/tests/ui/precondition-checks/nonnull.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: NonNull::new_unchecked requires diff --git a/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs index 46ce7dc356f..d55707fdd0b 100644 --- a/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs +++ b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: NonZero::from_mut_unchecked requires diff --git a/tests/ui/precondition-checks/nonzero-new_unchecked.rs b/tests/ui/precondition-checks/nonzero-new_unchecked.rs index 7827a42844f..978f01f150f 100644 --- a/tests/ui/precondition-checks/nonzero-new_unchecked.rs +++ b/tests/ui/precondition-checks/nonzero-new_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: NonZero::new_unchecked requires diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs index ada8932c398..33350dfbc4f 100644 --- a/tests/ui/precondition-checks/read_volatile.rs +++ b/tests/ui/precondition-checks/read_volatile.rs @@ -1,9 +1,7 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires -//@ revisions: null misaligned - -#![allow(invalid_null_arguments)] +//@ revisions: misaligned use std::ptr; @@ -11,8 +9,6 @@ fn main() { let src = [0u16; 2]; let src = src.as_ptr(); unsafe { - #[cfg(null)] - ptr::read_volatile(ptr::null::<u8>()); #[cfg(misaligned)] ptr::read_volatile(src.byte_add(1)); } diff --git a/tests/ui/precondition-checks/replace.rs b/tests/ui/precondition-checks/replace.rs index 44afbd8174c..447a00c6572 100644 --- a/tests/ui/precondition-checks/replace.rs +++ b/tests/ui/precondition-checks/replace.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::replace requires //@ revisions: null misaligned diff --git a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs index 9b9ded69a83..b6397ab2a12 100644 --- a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs +++ b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts_mut requires //@ revisions: null misaligned toolarge diff --git a/tests/ui/precondition-checks/slice-from-raw-parts.rs b/tests/ui/precondition-checks/slice-from-raw-parts.rs index 96578c1eae5..a317e3d41a0 100644 --- a/tests/ui/precondition-checks/slice-from-raw-parts.rs +++ b/tests/ui/precondition-checks/slice-from-raw-parts.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts requires //@ revisions: null misaligned toolarge diff --git a/tests/ui/precondition-checks/slice-get_unchecked.rs b/tests/ui/precondition-checks/slice-get_unchecked.rs index 1d8188fb953..7bcb8442540 100644 --- a/tests/ui/precondition-checks/slice-get_unchecked.rs +++ b/tests/ui/precondition-checks/slice-get_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked requires //@ revisions: usize range range_to range_from backwards_range diff --git a/tests/ui/precondition-checks/slice-get_unchecked_mut.rs b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs index 34c1454af43..2ba3227f39e 100644 --- a/tests/ui/precondition-checks/slice-get_unchecked_mut.rs +++ b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked_mut requires //@ revisions: usize range range_to range_from backwards_range diff --git a/tests/ui/precondition-checks/str-get_unchecked.rs b/tests/ui/precondition-checks/str-get_unchecked.rs index 14d17f997ec..2273190e9f4 100644 --- a/tests/ui/precondition-checks/str-get_unchecked.rs +++ b/tests/ui/precondition-checks/str-get_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: str::get_unchecked requires //@ revisions: range range_to range_from backwards_range diff --git a/tests/ui/precondition-checks/str-get_unchecked_mut.rs b/tests/ui/precondition-checks/str-get_unchecked_mut.rs index ca1b1690055..53e6ee64d47 100644 --- a/tests/ui/precondition-checks/str-get_unchecked_mut.rs +++ b/tests/ui/precondition-checks/str-get_unchecked_mut.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: str::get_unchecked_mut requires //@ revisions: range range_to range_from backwards_range diff --git a/tests/ui/precondition-checks/swap-nonoverlapping.rs b/tests/ui/precondition-checks/swap-nonoverlapping.rs index ea1f6f36ad7..81ba72382c0 100644 --- a/tests/ui/precondition-checks/swap-nonoverlapping.rs +++ b/tests/ui/precondition-checks/swap-nonoverlapping.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires //@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping diff --git a/tests/ui/precondition-checks/unchecked_add.rs b/tests/ui/precondition-checks/unchecked_add.rs index f44a6ea32ad..b7727aeb968 100644 --- a/tests/ui/precondition-checks/unchecked_add.rs +++ b/tests/ui/precondition-checks/unchecked_add.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow diff --git a/tests/ui/precondition-checks/unchecked_mul.rs b/tests/ui/precondition-checks/unchecked_mul.rs index 66655dda136..3eea8b66abb 100644 --- a/tests/ui/precondition-checks/unchecked_mul.rs +++ b/tests/ui/precondition-checks/unchecked_mul.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow diff --git a/tests/ui/precondition-checks/unchecked_shl.rs b/tests/ui/precondition-checks/unchecked_shl.rs index 1c96db0b1ec..57c617e0845 100644 --- a/tests/ui/precondition-checks/unchecked_shl.rs +++ b/tests/ui/precondition-checks/unchecked_shl.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shl cannot overflow diff --git a/tests/ui/precondition-checks/unchecked_shr.rs b/tests/ui/precondition-checks/unchecked_shr.rs index 4a6d9ffb1d3..18502d2b645 100644 --- a/tests/ui/precondition-checks/unchecked_shr.rs +++ b/tests/ui/precondition-checks/unchecked_shr.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shr cannot overflow diff --git a/tests/ui/precondition-checks/unchecked_sub.rs b/tests/ui/precondition-checks/unchecked_sub.rs index 545dde0e278..bfe8f5849f5 100644 --- a/tests/ui/precondition-checks/unchecked_sub.rs +++ b/tests/ui/precondition-checks/unchecked_sub.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: u8::unchecked_sub cannot overflow diff --git a/tests/ui/precondition-checks/unreachable_unchecked.rs b/tests/ui/precondition-checks/unreachable_unchecked.rs index 2435450c4b5..f2855d03a3e 100644 --- a/tests/ui/precondition-checks/unreachable_unchecked.rs +++ b/tests/ui/precondition-checks/unreachable_unchecked.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached diff --git a/tests/ui/precondition-checks/vec-from-parts.rs b/tests/ui/precondition-checks/vec-from-parts.rs new file mode 100644 index 00000000000..ace90770360 --- /dev/null +++ b/tests/ui/precondition-checks/vec-from-parts.rs @@ -0,0 +1,15 @@ +//@ run-crash +//@ compile-flags: -Cdebug-assertions=yes +//@ error-pattern: unsafe precondition(s) violated: Vec::from_parts_in requires that length <= capacity +#![feature(allocator_api)] + +use std::ptr::NonNull; + +fn main() { + let ptr: NonNull<i32> = std::ptr::NonNull::dangling(); + // Test Vec::from_parts_in with length > capacity + unsafe { + let alloc = std::alloc::Global; + let _vec = Vec::from_parts_in(ptr, 10, 5, alloc); + } +} diff --git a/tests/ui/precondition-checks/vec-from-raw-parts.rs b/tests/ui/precondition-checks/vec-from-raw-parts.rs new file mode 100644 index 00000000000..1bc8e6ada10 --- /dev/null +++ b/tests/ui/precondition-checks/vec-from-raw-parts.rs @@ -0,0 +1,29 @@ +//@ run-crash +//@ compile-flags: -Cdebug-assertions=yes +//@ error-pattern: unsafe precondition(s) violated: Vec::from_raw_parts_in requires that length <= capacity +//@ revisions: vec_from_raw_parts vec_from_raw_parts_in string_from_raw_parts + +#![feature(allocator_api)] + +fn main() { + let ptr = std::ptr::null_mut::<u8>(); + // Test Vec::from_raw_parts with length > capacity + unsafe { + #[cfg(vec_from_raw_parts)] + let _vec = Vec::from_raw_parts(ptr, 10, 5); + } + + // Test Vec::from_raw_parts_in with length > capacity + unsafe { + let alloc = std::alloc::Global; + #[cfg(vec_from_raw_parts_in)] + let _vec = Vec::from_raw_parts_in(ptr, 10, 5, alloc); + } + + // Test String::from_raw_parts with length > capacity + // Because it calls Vec::from_raw_parts, it should also fail + unsafe { + #[cfg(string_from_raw_parts)] + let _vec = String::from_raw_parts(ptr, 10, 5); + } +} diff --git a/tests/ui/precondition-checks/vec-set-len.rs b/tests/ui/precondition-checks/vec-set-len.rs new file mode 100644 index 00000000000..c6bdee7dc67 --- /dev/null +++ b/tests/ui/precondition-checks/vec-set-len.rs @@ -0,0 +1,11 @@ +//@ run-crash +//@ compile-flags: -Cdebug-assertions=yes +//@ error-pattern: unsafe precondition(s) violated: Vec::set_len requires that new_len <= capacity() + +fn main() { + let mut vec: Vec<i32> = Vec::with_capacity(5); + // Test set_len with length > capacity + unsafe { + vec.set_len(10); + } +} diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs index 0d5ecb014b3..d6ad6320e41 100644 --- a/tests/ui/precondition-checks/write_volatile.rs +++ b/tests/ui/precondition-checks/write_volatile.rs @@ -1,9 +1,7 @@ -//@ run-fail +//@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires -//@ revisions: null misaligned - -#![allow(invalid_null_arguments)] +//@ revisions: misaligned use std::ptr; @@ -11,8 +9,6 @@ fn main() { let mut dst = [0u16; 2]; let mut dst = dst.as_mut_ptr(); unsafe { - #[cfg(null)] - ptr::write_volatile(ptr::null_mut::<u8>(), 1u8); #[cfg(misaligned)] ptr::write_volatile(dst.byte_add(1), 1u16); } diff --git a/tests/ui/privacy/effective_visibilities_invariants.stderr b/tests/ui/privacy/effective_visibilities_invariants.stderr index 64d0402f84e..97bee1e2d8d 100644 --- a/tests/ui/privacy/effective_visibilities_invariants.stderr +++ b/tests/ui/privacy/effective_visibilities_invariants.stderr @@ -23,7 +23,7 @@ error: module has missing stability attribute --> $DIR/effective_visibilities_invariants.rs:5:1 | LL | pub mod m {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/privacy/issue-113860-1.stderr b/tests/ui/privacy/issue-113860-1.stderr index dad9ebadf04..764c9f4925b 100644 --- a/tests/ui/privacy/issue-113860-1.stderr +++ b/tests/ui/privacy/issue-113860-1.stderr @@ -20,28 +20,20 @@ LL | | fn main() {} error: trait has missing stability attribute --> $DIR/issue-113860-1.rs:4:1 | -LL | / pub trait Trait { -LL | | -LL | | fn fun() {} -LL | | -LL | | } - | |_^ +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ error: implementation has missing stability attribute --> $DIR/issue-113860-1.rs:10:1 | -LL | / impl Trait for u8 { -LL | | -LL | | pub(self) fn fun() {} -LL | | -LL | | } - | |_^ +LL | impl Trait for u8 { + | ^^^^^^^^^^^^^^^^^ error: associated function has missing stability attribute --> $DIR/issue-113860-1.rs:6:5 | LL | fn fun() {} - | ^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/privacy/issue-113860-2.stderr b/tests/ui/privacy/issue-113860-2.stderr index 9805c22dbdf..d0847aa2b49 100644 --- a/tests/ui/privacy/issue-113860-2.stderr +++ b/tests/ui/privacy/issue-113860-2.stderr @@ -20,28 +20,20 @@ LL | | fn main() {} error: trait has missing stability attribute --> $DIR/issue-113860-2.rs:4:1 | -LL | / pub trait Trait { -LL | | -LL | | type X; -LL | | -LL | | } - | |_^ +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ error: implementation has missing stability attribute --> $DIR/issue-113860-2.rs:10:1 | -LL | / impl Trait for u8 { -LL | | -LL | | pub(self) type X = Self; -LL | | -LL | | } - | |_^ +LL | impl Trait for u8 { + | ^^^^^^^^^^^^^^^^^ error: associated type has missing stability attribute --> $DIR/issue-113860-2.rs:6:5 | LL | type X; - | ^^^^^^^ + | ^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/privacy/issue-113860.stderr b/tests/ui/privacy/issue-113860.stderr index 88efcae4a85..d7a15255b15 100644 --- a/tests/ui/privacy/issue-113860.stderr +++ b/tests/ui/privacy/issue-113860.stderr @@ -20,28 +20,20 @@ LL | | fn main() {} error: trait has missing stability attribute --> $DIR/issue-113860.rs:4:1 | -LL | / pub trait Trait { -LL | | -LL | | const X: u32; -LL | | -LL | | } - | |_^ +LL | pub trait Trait { + | ^^^^^^^^^^^^^^^ error: implementation has missing stability attribute --> $DIR/issue-113860.rs:10:1 | -LL | / impl Trait for u8 { -LL | | -LL | | pub(self) const X: u32 = 3; -LL | | -LL | | } - | |_^ +LL | impl Trait for u8 { + | ^^^^^^^^^^^^^^^^^ error: associated constant has missing stability attribute --> $DIR/issue-113860.rs:6:5 | LL | const X: u32; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs index 746b98fbd07..f79e4641312 100644 --- a/tests/ui/privacy/private-in-public-warn.rs +++ b/tests/ui/privacy/private-in-public-warn.rs @@ -35,6 +35,7 @@ mod types { mod traits { trait PrivTr {} + impl PrivTr for () {} pub struct Pub<T>(T); pub trait PubTr {} @@ -45,7 +46,10 @@ mod traits { pub trait Tr3 { type Alias: PrivTr; //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias` - fn f<T: PrivTr>(arg: T) {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f` + fn f<T: PrivTr>(arg: T) {} + //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f` + fn g() -> impl PrivTr; + fn h() -> impl PrivTr {} } impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>` impl<T: PrivTr> PubTr for Pub<T> {} // OK, trait impl predicates @@ -75,12 +79,18 @@ mod generics { pub struct Pub<T = u8>(T); trait PrivTr<T> {} pub trait PubTr<T> {} + impl PrivTr<Priv<()>> for () {} pub trait Tr1: PrivTr<Pub> {} //~^ ERROR trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1` pub trait Tr2: PubTr<Priv> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr2` pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr3` pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more private than the item `Tr4` + + pub trait Tr5 { + fn required() -> impl PrivTr<Priv<()>>; + fn provided() -> impl PrivTr<Priv<()>> {} + } } mod impls { diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index 3743879ffa6..c2a57e3b82c 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr @@ -130,7 +130,7 @@ LL | type Alias = Priv; | ^^^^^^^^^^ can't leak private type error: trait `traits::PrivTr` is more private than the item `traits::Alias` - --> $DIR/private-in-public-warn.rs:41:5 + --> $DIR/private-in-public-warn.rs:42:5 | LL | pub type Alias<T: PrivTr> = T; | ^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `traits::Alias` is reachable at visibility `pub(crate)` @@ -147,7 +147,7 @@ LL | #![deny(private_interfaces, private_bounds)] | ^^^^^^^^^^^^^^ error: trait `traits::PrivTr` is more private than the item `traits::Tr1` - --> $DIR/private-in-public-warn.rs:43:5 + --> $DIR/private-in-public-warn.rs:44:5 | LL | pub trait Tr1: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr1` is reachable at visibility `pub(crate)` @@ -159,7 +159,7 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits::PrivTr` is more private than the item `traits::Tr2` - --> $DIR/private-in-public-warn.rs:44:5 + --> $DIR/private-in-public-warn.rs:45:5 | LL | pub trait Tr2<T: PrivTr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr2` is reachable at visibility `pub(crate)` @@ -171,7 +171,7 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias` - --> $DIR/private-in-public-warn.rs:46:9 + --> $DIR/private-in-public-warn.rs:47:9 | LL | type Alias: PrivTr; | ^^^^^^^^^^^^^^^^^^ associated type `traits::Tr3::Alias` is reachable at visibility `pub(crate)` @@ -183,7 +183,7 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f` - --> $DIR/private-in-public-warn.rs:48:9 + --> $DIR/private-in-public-warn.rs:49:9 | LL | fn f<T: PrivTr>(arg: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Tr3::f` is reachable at visibility `pub(crate)` @@ -195,7 +195,7 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>` - --> $DIR/private-in-public-warn.rs:50:5 + --> $DIR/private-in-public-warn.rs:54:5 | LL | impl<T: PrivTr> Pub<T> {} | ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)` @@ -207,103 +207,103 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` - --> $DIR/private-in-public-warn.rs:59:5 + --> $DIR/private-in-public-warn.rs:63:5 | LL | pub type Alias<T> where T: PrivTr = T; | ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:55:5 + --> $DIR/private-in-public-warn.rs:59:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` - --> $DIR/private-in-public-warn.rs:62:5 + --> $DIR/private-in-public-warn.rs:66:5 | LL | pub trait Tr2<T> where T: PrivTr {} | ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:55:5 + --> $DIR/private-in-public-warn.rs:59:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f` - --> $DIR/private-in-public-warn.rs:65:9 + --> $DIR/private-in-public-warn.rs:69:9 | LL | fn f<T>(arg: T) where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:55:5 + --> $DIR/private-in-public-warn.rs:59:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` - --> $DIR/private-in-public-warn.rs:68:5 + --> $DIR/private-in-public-warn.rs:72:5 | LL | impl<T> Pub<T> where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:55:5 + --> $DIR/private-in-public-warn.rs:59:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1` - --> $DIR/private-in-public-warn.rs:79:5 + --> $DIR/private-in-public-warn.rs:84:5 | LL | pub trait Tr1: PrivTr<Pub> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)` | note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:76:5 + --> $DIR/private-in-public-warn.rs:80:5 | LL | trait PrivTr<T> {} | ^^^^^^^^^^^^^^^ error: type `generics::Priv` is more private than the item `generics::Tr2` - --> $DIR/private-in-public-warn.rs:81:5 + --> $DIR/private-in-public-warn.rs:86:5 | LL | pub trait Tr2: PubTr<Priv> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)` | note: but type `generics::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:74:5 + --> $DIR/private-in-public-warn.rs:78:5 | LL | struct Priv<T = u8>(T); | ^^^^^^^^^^^^^^^^^^^ error: type `generics::Priv` is more private than the item `generics::Tr3` - --> $DIR/private-in-public-warn.rs:82:5 + --> $DIR/private-in-public-warn.rs:87:5 | LL | pub trait Tr3: PubTr<[Priv; 1]> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)` | note: but type `generics::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:74:5 + --> $DIR/private-in-public-warn.rs:78:5 | LL | struct Priv<T = u8>(T); | ^^^^^^^^^^^^^^^^^^^ error: type `generics::Priv` is more private than the item `Tr4` - --> $DIR/private-in-public-warn.rs:83:5 + --> $DIR/private-in-public-warn.rs:88:5 | LL | pub trait Tr4: PubTr<Pub<Priv>> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)` | note: but type `generics::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:74:5 + --> $DIR/private-in-public-warn.rs:78:5 | LL | struct Priv<T = u8>(T); | ^^^^^^^^^^^^^^^^^^^ error[E0446]: private type `impls::Priv` in public interface - --> $DIR/private-in-public-warn.rs:109:9 + --> $DIR/private-in-public-warn.rs:119:9 | LL | struct Priv; | ----------- `impls::Priv` declared as private @@ -312,19 +312,19 @@ LL | type Alias = Priv; | ^^^^^^^^^^ can't leak private type error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f` - --> $DIR/private-in-public-warn.rs:180:9 + --> $DIR/private-in-public-warn.rs:190:9 | LL | pub fn f(arg: Priv) {} | ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::<impl Pub2>::f` is reachable at visibility `pub(crate)` | note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:153:5 + --> $DIR/private-in-public-warn.rs:163:5 | LL | struct Priv; | ^^^^^^^^^^^ error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:183:9 + --> $DIR/private-in-public-warn.rs:193:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -333,7 +333,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:186:9 + --> $DIR/private-in-public-warn.rs:196:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -342,7 +342,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:189:9 + --> $DIR/private-in-public-warn.rs:199:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -351,7 +351,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:192:9 + --> $DIR/private-in-public-warn.rs:202:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -360,43 +360,43 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1` - --> $DIR/private-in-public-warn.rs:222:5 + --> $DIR/private-in-public-warn.rs:232:5 | LL | pub trait Tr1: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)` | note: but trait `PrivTr1` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:208:5 + --> $DIR/private-in-public-warn.rs:218:5 | LL | trait PrivTr1<T = u8> { | ^^^^^^^^^^^^^^^^^^^^^ error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2` - --> $DIR/private-in-public-warn.rs:224:5 + --> $DIR/private-in-public-warn.rs:234:5 | LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)` | note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:208:5 + --> $DIR/private-in-public-warn.rs:218:5 | LL | trait PrivTr1<T = u8> { | ^^^^^^^^^^^^^^^^^^^^^ error: type `Priv2` is more private than the item `aliases_priv::Tr2` - --> $DIR/private-in-public-warn.rs:224:5 + --> $DIR/private-in-public-warn.rs:234:5 | LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)` | note: but type `Priv2` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:206:5 + --> $DIR/private-in-public-warn.rs:216:5 | LL | struct Priv2; | ^^^^^^^^^^^^ warning: bounds on generic parameters in type aliases are not enforced - --> $DIR/private-in-public-warn.rs:41:23 + --> $DIR/private-in-public-warn.rs:42:23 | LL | pub type Alias<T: PrivTr> = T; | --^^^^^^ @@ -410,7 +410,7 @@ LL | pub type Alias<T: PrivTr> = T; = note: `#[warn(type_alias_bounds)]` on by default warning: where clauses on type aliases are not enforced - --> $DIR/private-in-public-warn.rs:59:29 + --> $DIR/private-in-public-warn.rs:63:29 | LL | pub type Alias<T> where T: PrivTr = T; | ------^^^^^^^^^ diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs index 4eeecdc0569..75640147026 100644 --- a/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -1,5 +1,6 @@ pub struct OtherType; pub trait OtherTrait {} +impl OtherTrait for OtherType {} #[macro_export] macro_rules! m { diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs index 877029f3de3..b85f2754fb1 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -9,10 +9,10 @@ #![deny(exported_private_dependencies)] // This crate is a private dependency -// FIXME: This should trigger. pub extern crate priv_dep; +//~^ ERROR crate `priv_dep` from private dependency 'priv_dep' is re-exported // This crate is a public dependency -extern crate pub_dep; +pub extern crate pub_dep; // This crate is a private dependency extern crate pm; @@ -44,8 +44,12 @@ impl PublicType { pub trait MyPubTrait { type Foo: OtherTrait; + //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface + + fn required() -> impl OtherTrait; + + fn provided() -> impl OtherTrait { OtherType } } -//~^^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface pub trait WithSuperTrait: OtherTrait {} //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface @@ -91,16 +95,16 @@ pub struct AllowedPrivType { pub allowed: OtherType, } -// FIXME: This should trigger. pub use priv_dep::m; -// FIXME: This should trigger. +//~^ ERROR macro `m` from private dependency 'priv_dep' is re-exported pub use pm::fn_like; -// FIXME: This should trigger. +//~^ ERROR macro `fn_like` from private dependency 'pm' is re-exported pub use pm::PmDerive; -// FIXME: This should trigger. +//~^ ERROR macro `PmDerive` from private dependency 'pm' is re-exported pub use pm::pm_attr; +//~^ ERROR macro `pm_attr` from private dependency 'pm' is re-exported -// FIXME: This should trigger. pub use priv_dep::E::V1; +//~^ ERROR variant `V1` from private dependency 'priv_dep' is re-exported fn main() {} diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr index adfe13424cd..24bd071567f 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,8 +1,8 @@ -error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:29:5 +error: crate `priv_dep` from private dependency 'priv_dep' is re-exported + --> $DIR/pub-priv1.rs:12:1 | -LL | pub field: OtherType, - | ^^^^^^^^^^^^^^^^^^^^ +LL | pub extern crate priv_dep; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/pub-priv1.rs:9:9 @@ -10,6 +10,42 @@ note: the lint level is defined here LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: macro `m` from private dependency 'priv_dep' is re-exported + --> $DIR/pub-priv1.rs:98:9 + | +LL | pub use priv_dep::m; + | ^^^^^^^^^^^ + +error: macro `fn_like` from private dependency 'pm' is re-exported + --> $DIR/pub-priv1.rs:100:9 + | +LL | pub use pm::fn_like; + | ^^^^^^^^^^^ + +error: derive macro `PmDerive` from private dependency 'pm' is re-exported + --> $DIR/pub-priv1.rs:102:9 + | +LL | pub use pm::PmDerive; + | ^^^^^^^^^^^^ + +error: attribute macro `pm_attr` from private dependency 'pm' is re-exported + --> $DIR/pub-priv1.rs:104:9 + | +LL | pub use pm::pm_attr; + | ^^^^^^^^^^^ + +error: variant `V1` from private dependency 'priv_dep' is re-exported + --> $DIR/pub-priv1.rs:107:9 + | +LL | pub use priv_dep::E::V1; + | ^^^^^^^^^^^^^^^ + +error: type `OtherType` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:29:5 + | +LL | pub field: OtherType, + | ^^^^^^^^^^^^^^^^^^^^ + error: type `OtherType` from private dependency 'priv_dep' in public interface --> $DIR/pub-priv1.rs:36:5 | @@ -29,66 +65,66 @@ LL | type Foo: OtherTrait; | ^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:50:1 + --> $DIR/pub-priv1.rs:54:1 | LL | pub trait WithSuperTrait: OtherTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:59:5 + --> $DIR/pub-priv1.rs:63:5 | LL | type X = OtherType; | ^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:63:1 + --> $DIR/pub-priv1.rs:67:1 | LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:66:1 + --> $DIR/pub-priv1.rs:70:1 | LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:69:1 + --> $DIR/pub-priv1.rs:73:1 | LL | pub static STATIC: OtherType = OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:72:1 + --> $DIR/pub-priv1.rs:76:1 | LL | pub const CONST: OtherType = OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:75:1 + --> $DIR/pub-priv1.rs:79:1 | LL | pub type Alias = OtherType; | ^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:80:1 + --> $DIR/pub-priv1.rs:84:1 | LL | impl OtherTrait for PublicWithPrivateImpl {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:85:1 + --> $DIR/pub-priv1.rs:89:1 | LL | impl PubTraitOnPrivate for OtherType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:85:1 + --> $DIR/pub-priv1.rs:89:1 | LL | impl PubTraitOnPrivate for OtherType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 14 previous errors +error: aborting due to 20 previous errors diff --git a/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs new file mode 100644 index 00000000000..13f3065e442 --- /dev/null +++ b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs @@ -0,0 +1,13 @@ +// We should not emit sealed traits note, see issue #143392 + +mod inner { + pub trait TraitA {} + + pub trait TraitB: TraitA {} +} + +struct Struct; + +impl inner::TraitB for Struct {} //~ ERROR the trait bound `Struct: TraitA` is not satisfied [E0277] + +fn main(){} diff --git a/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr new file mode 100644 index 00000000000..f80d985ad6e --- /dev/null +++ b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `Struct: TraitA` is not satisfied + --> $DIR/false-sealed-traits-note.rs:11:24 + | +LL | impl inner::TraitB for Struct {} + | ^^^^^^ the trait `TraitA` is not implemented for `Struct` + | +help: this trait has no implementations, consider adding one + --> $DIR/false-sealed-traits-note.rs:4:5 + | +LL | pub trait TraitA {} + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `TraitB` + --> $DIR/false-sealed-traits-note.rs:6:23 + | +LL | pub trait TraitB: TraitA {} + | ^^^^^^ required by this bound in `TraitB` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index 1734b9afe92..91d16eca1b0 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -49,12 +49,6 @@ crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "produce_it") crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #3, def_site_ctxt: #0, kind: Macro(Bang, "meta_macro::print_def_site") crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro(Bang, "$crate::dummy") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include") SyntaxContexts: #0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque) diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 42257312a87..63741326e34 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -72,12 +72,6 @@ crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "outer") crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #3, def_site_ctxt: #3, kind: Macro(Bang, "inner") crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro(Bang, "print_bang") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include") SyntaxContexts: #0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque) diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr index 23c93a4ed8b..4244c11eb3e 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr @@ -10,13 +10,13 @@ error: `#[doc(alias = "...")]` isn't allowed on foreign module LL | #[doc(alias = "foo")] | ^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on implementation block +error: `#[doc(alias = "...")]` isn't allowed on inherent implementation block --> $DIR/check-doc-alias-attr-location.rs:12:7 | LL | #[doc(alias = "bar")] | ^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on implementation block +error: `#[doc(alias = "...")]` isn't allowed on trait implementation block --> $DIR/check-doc-alias-attr-location.rs:18:7 | LL | #[doc(alias = "foobar")] diff --git a/tests/ui/sanitizer/address.rs b/tests/ui/sanitizer/address.rs index 7a5e767687c..704d84764c1 100644 --- a/tests/ui/sanitizer/address.rs +++ b/tests/ui/sanitizer/address.rs @@ -4,7 +4,7 @@ // //@ compile-flags: -Z sanitizer=address -O -g // -//@ run-fail +//@ run-fail-or-crash //@ error-pattern: AddressSanitizer: stack-buffer-overflow //@ error-pattern: 'xs' (line 14) <== Memory access at offset diff --git a/tests/ui/sanitizer/badfree.rs b/tests/ui/sanitizer/badfree.rs index ecbb58eba00..6b3aea7239c 100644 --- a/tests/ui/sanitizer/badfree.rs +++ b/tests/ui/sanitizer/badfree.rs @@ -4,7 +4,7 @@ // //@ compile-flags: -Z sanitizer=address -O // -//@ run-fail +//@ run-fail-or-crash //@ regex-error-pattern: AddressSanitizer: (SEGV|attempting free on address which was not malloc) use std::ffi::c_void; diff --git a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs index b7dd4a43782..c1a2c2f26ac 100644 --- a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs +++ b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs @@ -11,7 +11,7 @@ //@ compile-flags: -Zsanitizer=address -Clto=thin //@[opt0]compile-flags: -Copt-level=0 //@[opt1]compile-flags: -Copt-level=1 -//@ run-fail +//@ run-fail-or-crash //@ error-pattern: ERROR: AddressSanitizer: stack-use-after-scope static mut P: *mut usize = std::ptr::null_mut(); diff --git a/tests/ui/sanitizer/thread.rs b/tests/ui/sanitizer/thread.rs index 566774d6b1d..9073124d1bd 100644 --- a/tests/ui/sanitizer/thread.rs +++ b/tests/ui/sanitizer/thread.rs @@ -15,7 +15,7 @@ // //@ compile-flags: -Z sanitizer=thread -O // -//@ run-fail +//@ run-fail-or-crash //@ error-pattern: WARNING: ThreadSanitizer: data race //@ error-pattern: Location is heap block of size 4 //@ error-pattern: allocated by main thread diff --git a/tests/ui/sanitizer/use-after-scope.rs b/tests/ui/sanitizer/use-after-scope.rs index 4d7f6f6c2f2..106dc6466d6 100644 --- a/tests/ui/sanitizer/use-after-scope.rs +++ b/tests/ui/sanitizer/use-after-scope.rs @@ -3,7 +3,7 @@ //@ ignore-cross-compile // //@ compile-flags: -Zsanitizer=address -//@ run-fail +//@ run-fail-or-crash //@ error-pattern: ERROR: AddressSanitizer: stack-use-after-scope static mut P: *mut usize = std::ptr::null_mut(); diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs index ecd669059ed..ce2fb8235cc 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.rs +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.rs @@ -4,11 +4,11 @@ struct Foo<'a>(&'a str); impl<'b> Foo<'b> { fn a<'a>(self: Self, a: &'a str) -> &str { - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing a } fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing a } } diff --git a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr index 5351bf3c94c..7108fa1a290 100644 --- a/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr +++ b/tests/ui/self/elision/ignore-non-reference-lifetimes.stderr @@ -1,26 +1,28 @@ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/ignore-non-reference-lifetimes.rs:6:30 | LL | fn a<'a>(self: Self, a: &'a str) -> &str { - | ^^ ---- the lifetime gets resolved as `'a` + | ^^ ---- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default -help: one option is to consistently use `'a` +help: consistently use `'a` | LL | fn a<'a>(self: Self, a: &'a str) -> &'a str { | ++ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/ignore-non-reference-lifetimes.rs:10:33 | LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &str { - | ^^ ---- the lifetime gets resolved as `'a` + | ^^ ---- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn b<'a>(self: Foo<'b>, a: &'a str) -> &'a str { | ++ diff --git a/tests/ui/self/self_lifetime-async.rs b/tests/ui/self/self_lifetime-async.rs index f839ab03a60..0093971fee4 100644 --- a/tests/ui/self/self_lifetime-async.rs +++ b/tests/ui/self/self_lifetime-async.rs @@ -4,13 +4,13 @@ struct Foo<'a>(&'a ()); impl<'a> Foo<'a> { async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing } type Alias = Foo<'static>; impl Alias { async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing } fn main() {} diff --git a/tests/ui/self/self_lifetime-async.stderr b/tests/ui/self/self_lifetime-async.stderr index a9c1be2e808..43dc96abdc2 100644 --- a/tests/ui/self/self_lifetime-async.stderr +++ b/tests/ui/self/self_lifetime-async.stderr @@ -1,26 +1,28 @@ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/self_lifetime-async.rs:6:29 | LL | async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - | ^^ --- the lifetime gets resolved as `'b` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default -help: one option is to consistently use `'b` +help: consistently use `'b` | LL | async fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } | ++ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/self_lifetime-async.rs:12:42 | LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - | ^^ --- the lifetime gets resolved as `'a` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | async fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } | ++ diff --git a/tests/ui/self/self_lifetime.rs b/tests/ui/self/self_lifetime.rs index aaa31f85ad5..190809af22f 100644 --- a/tests/ui/self/self_lifetime.rs +++ b/tests/ui/self/self_lifetime.rs @@ -5,13 +5,13 @@ struct Foo<'a>(&'a ()); impl<'a> Foo<'a> { fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing } type Alias = Foo<'static>; impl Alias { fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - //~^ WARNING lifetime flowing from input to output with different syntax + //~^ WARNING eliding a lifetime that's named elsewhere is confusing } fn main() {} diff --git a/tests/ui/self/self_lifetime.stderr b/tests/ui/self/self_lifetime.stderr index ec676e69cf6..4f9b2fcd2ad 100644 --- a/tests/ui/self/self_lifetime.stderr +++ b/tests/ui/self/self_lifetime.stderr @@ -1,26 +1,28 @@ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/self_lifetime.rs:7:23 | LL | fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } - | ^^ --- the lifetime gets resolved as `'b` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default -help: one option is to consistently use `'b` +help: consistently use `'b` | LL | fn foo<'b>(self: &'b Foo<'a>) -> &'b () { self.0 } | ++ -warning: lifetime flowing from input to output with different syntax can be confusing +warning: eliding a lifetime that's named elsewhere is confusing --> $DIR/self_lifetime.rs:13:36 | LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } - | ^^ --- the lifetime gets resolved as `'a` + | ^^ --- the same lifetime is elided here | | - | this lifetime flows to the output + | the lifetime is named here | -help: one option is to consistently use `'a` + = help: the same lifetime is referred to in inconsistent ways, making the signature confusing +help: consistently use `'a` | LL | fn bar<'a>(self: &Alias, arg: &'a ()) -> &'a () { arg } | ++ diff --git a/tests/ui/lexical-scopes.rs b/tests/ui/shadowed/shadowing-generic-item.rs index 46cfdf1efa8..c3a0ced04e7 100644 --- a/tests/ui/lexical-scopes.rs +++ b/tests/ui/shadowed/shadowing-generic-item.rs @@ -1,3 +1,5 @@ +//! Test that generic parameters shadow structs and modules with the same name. + struct T { i: i32 } fn f<T>() { let t = T { i: 0 }; //~ ERROR expected struct, variant or union type, found type parameter `T` diff --git a/tests/ui/lexical-scopes.stderr b/tests/ui/shadowed/shadowing-generic-item.stderr index f0eaa1a5c64..55a0bb36ea8 100644 --- a/tests/ui/lexical-scopes.stderr +++ b/tests/ui/shadowed/shadowing-generic-item.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found type parameter `T` - --> $DIR/lexical-scopes.rs:3:13 + --> $DIR/shadowing-generic-item.rs:5:13 | LL | struct T { i: i32 } | - you might have meant to refer to this struct @@ -9,7 +9,7 @@ LL | let t = T { i: 0 }; | ^ not a struct, variant or union type error[E0599]: no function or associated item named `f` found for type parameter `Foo` in the current scope - --> $DIR/lexical-scopes.rs:10:10 + --> $DIR/shadowing-generic-item.rs:12:10 | LL | fn g<Foo>() { | --- function or associated item `f` not found for this type parameter diff --git a/tests/ui/simd/generics.rs b/tests/ui/simd/generics.rs index 1ae08fef7cd..54e76f7bc5d 100644 --- a/tests/ui/simd/generics.rs +++ b/tests/ui/simd/generics.rs @@ -2,24 +2,18 @@ #![allow(non_camel_case_types)] #![feature(repr_simd, core_intrinsics)] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::simd_add; use std::ops; -#[repr(simd)] -#[derive(Copy, Clone)] -struct f32x4([f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone)] -struct A<const N: usize>([f32; N]); +type A<const N: usize> = Simd<f32, N>; -#[repr(simd)] -#[derive(Copy, Clone)] -struct B<T>([T; 4]); +type B<T> = Simd<T, 4>; -#[repr(simd)] -#[derive(Copy, Clone)] -struct C<T, const N: usize>([T; N]); +type C<T, const N: usize> = Simd<T, N>; fn add<T: ops::Add<Output = T>>(lhs: T, rhs: T) -> T { lhs + rhs @@ -33,48 +27,24 @@ impl ops::Add for f32x4 { } } -impl ops::Add for A<4> { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - unsafe { simd_add(self, rhs) } - } -} - -impl ops::Add for B<f32> { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - unsafe { simd_add(self, rhs) } - } -} - -impl ops::Add for C<f32, 4> { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - unsafe { simd_add(self, rhs) } - } -} - pub fn main() { let x = [1.0f32, 2.0f32, 3.0f32, 4.0f32]; let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32]; // lame-o - let a = f32x4([1.0f32, 2.0f32, 3.0f32, 4.0f32]); - let f32x4([a0, a1, a2, a3]) = add(a, a); + let a = f32x4::from_array([1.0f32, 2.0f32, 3.0f32, 4.0f32]); + let [a0, a1, a2, a3] = add(a, a).into_array(); assert_eq!(a0, 2.0f32); assert_eq!(a1, 4.0f32); assert_eq!(a2, 6.0f32); assert_eq!(a3, 8.0f32); - let a = A(x); - assert_eq!(add(a, a).0, y); + let a = A::from_array(x); + assert_eq!(add(a, a).into_array(), y); - let b = B(x); - assert_eq!(add(b, b).0, y); + let b = B::from_array(x); + assert_eq!(add(b, b).into_array(), y); - let c = C(x); - assert_eq!(add(c, c).0, y); + let c = C::from_array(x); + assert_eq!(add(c, c).into_array(), y); } diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs index 01fed8537d0..743aae8d1c3 100644 --- a/tests/ui/simd/intrinsic/float-math-pass.rs +++ b/tests/ui/simd/intrinsic/float-math-pass.rs @@ -11,9 +11,9 @@ #![feature(repr_simd, intrinsics, core_intrinsics)] #![allow(non_camel_case_types)] -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct f32x4(pub [f32; 4]); +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; use std::intrinsics::simd::*; @@ -27,19 +27,19 @@ macro_rules! assert_approx_eq { ($a:expr, $b:expr) => {{ let a = $a; let b = $b; - assert_approx_eq_f32!(a.0[0], b.0[0]); - assert_approx_eq_f32!(a.0[1], b.0[1]); - assert_approx_eq_f32!(a.0[2], b.0[2]); - assert_approx_eq_f32!(a.0[3], b.0[3]); + assert_approx_eq_f32!(a[0], b[0]); + assert_approx_eq_f32!(a[1], b[1]); + assert_approx_eq_f32!(a[2], b[2]); + assert_approx_eq_f32!(a[3], b[3]); }}; } fn main() { - let x = f32x4([1.0, 1.0, 1.0, 1.0]); - let y = f32x4([-1.0, -1.0, -1.0, -1.0]); - let z = f32x4([0.0, 0.0, 0.0, 0.0]); + let x = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + let y = f32x4::from_array([-1.0, -1.0, -1.0, -1.0]); + let z = f32x4::from_array([0.0, 0.0, 0.0, 0.0]); - let h = f32x4([0.5, 0.5, 0.5, 0.5]); + let h = f32x4::from_array([0.5, 0.5, 0.5, 0.5]); unsafe { let r = simd_fabs(y); diff --git a/tests/ui/simd/intrinsic/float-minmax-pass.rs b/tests/ui/simd/intrinsic/float-minmax-pass.rs index 00c0d8cea3f..12210ba0ad1 100644 --- a/tests/ui/simd/intrinsic/float-minmax-pass.rs +++ b/tests/ui/simd/intrinsic/float-minmax-pass.rs @@ -6,15 +6,15 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct f32x4(pub [f32; 4]); +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; use std::intrinsics::simd::*; fn main() { - let x = f32x4([1.0, 2.0, 3.0, 4.0]); - let y = f32x4([2.0, 1.0, 4.0, 3.0]); + let x = f32x4::from_array([1.0, 2.0, 3.0, 4.0]); + let y = f32x4::from_array([2.0, 1.0, 4.0, 3.0]); #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] let nan = f32::NAN; @@ -23,13 +23,13 @@ fn main() { #[cfg(any(target_arch = "mips", target_arch = "mips64"))] let nan = f32::from_bits(f32::NAN.to_bits() - 1); - let n = f32x4([nan, nan, nan, nan]); + let n = f32x4::from_array([nan, nan, nan, nan]); unsafe { let min0 = simd_fmin(x, y); let min1 = simd_fmin(y, x); assert_eq!(min0, min1); - let e = f32x4([1.0, 1.0, 3.0, 3.0]); + let e = f32x4::from_array([1.0, 1.0, 3.0, 3.0]); assert_eq!(min0, e); let minn = simd_fmin(x, n); assert_eq!(minn, x); @@ -39,7 +39,7 @@ fn main() { let max0 = simd_fmax(x, y); let max1 = simd_fmax(y, x); assert_eq!(max0, max1); - let e = f32x4([2.0, 2.0, 4.0, 4.0]); + let e = f32x4::from_array([2.0, 2.0, 4.0, 4.0]); assert_eq!(max0, e); let maxn = simd_fmax(x, n); assert_eq!(maxn, x); diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs index 4c97fb2141d..bf38a8b1720 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs @@ -2,80 +2,77 @@ #![allow(non_camel_case_types)] #![feature(repr_simd, core_intrinsics)] -#[repr(simd)] -#[derive(Copy, Clone)] -struct i32x4(pub [i32; 4]); +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone)] -struct U32<const N: usize>([u32; N]); - -#[repr(simd)] -#[derive(Copy, Clone)] -struct f32x4(pub [f32; 4]); +type U32<const N: usize> = Simd<u32, N>; macro_rules! all_eq { - ($a: expr, $b: expr) => {{ + ($a: expr, $b: expr $(,)?) => {{ let a = $a; let b = $b; - assert!(a.0 == b.0); + assert!(a == b); }}; } use std::intrinsics::simd::*; fn main() { - let x1 = i32x4([1, 2, 3, 4]); - let y1 = U32::<4>([1, 2, 3, 4]); - let z1 = f32x4([1.0, 2.0, 3.0, 4.0]); - let x2 = i32x4([2, 3, 4, 5]); - let y2 = U32::<4>([2, 3, 4, 5]); - let z2 = f32x4([2.0, 3.0, 4.0, 5.0]); - let x3 = i32x4([0, i32::MAX, i32::MIN, -1_i32]); - let y3 = U32::<4>([0, i32::MAX as _, i32::MIN as _, -1_i32 as _]); + let x1 = i32x4::from_array([1, 2, 3, 4]); + let y1 = U32::<4>::from_array([1, 2, 3, 4]); + let z1 = f32x4::from_array([1.0, 2.0, 3.0, 4.0]); + let x2 = i32x4::from_array([2, 3, 4, 5]); + let y2 = U32::<4>::from_array([2, 3, 4, 5]); + let z2 = f32x4::from_array([2.0, 3.0, 4.0, 5.0]); + let x3 = i32x4::from_array([0, i32::MAX, i32::MIN, -1_i32]); + let y3 = U32::<4>::from_array([0, i32::MAX as _, i32::MIN as _, -1_i32 as _]); unsafe { - all_eq!(simd_add(x1, x2), i32x4([3, 5, 7, 9])); - all_eq!(simd_add(x2, x1), i32x4([3, 5, 7, 9])); - all_eq!(simd_add(y1, y2), U32::<4>([3, 5, 7, 9])); - all_eq!(simd_add(y2, y1), U32::<4>([3, 5, 7, 9])); - all_eq!(simd_add(z1, z2), f32x4([3.0, 5.0, 7.0, 9.0])); - all_eq!(simd_add(z2, z1), f32x4([3.0, 5.0, 7.0, 9.0])); - - all_eq!(simd_mul(x1, x2), i32x4([2, 6, 12, 20])); - all_eq!(simd_mul(x2, x1), i32x4([2, 6, 12, 20])); - all_eq!(simd_mul(y1, y2), U32::<4>([2, 6, 12, 20])); - all_eq!(simd_mul(y2, y1), U32::<4>([2, 6, 12, 20])); - all_eq!(simd_mul(z1, z2), f32x4([2.0, 6.0, 12.0, 20.0])); - all_eq!(simd_mul(z2, z1), f32x4([2.0, 6.0, 12.0, 20.0])); - - all_eq!(simd_sub(x2, x1), i32x4([1, 1, 1, 1])); - all_eq!(simd_sub(x1, x2), i32x4([-1, -1, -1, -1])); - all_eq!(simd_sub(y2, y1), U32::<4>([1, 1, 1, 1])); - all_eq!(simd_sub(y1, y2), U32::<4>([!0, !0, !0, !0])); - all_eq!(simd_sub(z2, z1), f32x4([1.0, 1.0, 1.0, 1.0])); - all_eq!(simd_sub(z1, z2), f32x4([-1.0, -1.0, -1.0, -1.0])); - - all_eq!(simd_div(x1, x1), i32x4([1, 1, 1, 1])); - all_eq!(simd_div(i32x4([2, 4, 6, 8]), i32x4([2, 2, 2, 2])), x1); - all_eq!(simd_div(y1, y1), U32::<4>([1, 1, 1, 1])); - all_eq!(simd_div(U32::<4>([2, 4, 6, 8]), U32::<4>([2, 2, 2, 2])), y1); - all_eq!(simd_div(z1, z1), f32x4([1.0, 1.0, 1.0, 1.0])); - all_eq!(simd_div(z1, z2), f32x4([1.0 / 2.0, 2.0 / 3.0, 3.0 / 4.0, 4.0 / 5.0])); - all_eq!(simd_div(z2, z1), f32x4([2.0 / 1.0, 3.0 / 2.0, 4.0 / 3.0, 5.0 / 4.0])); - - all_eq!(simd_rem(x1, x1), i32x4([0, 0, 0, 0])); - all_eq!(simd_rem(x2, x1), i32x4([0, 1, 1, 1])); - all_eq!(simd_rem(y1, y1), U32::<4>([0, 0, 0, 0])); - all_eq!(simd_rem(y2, y1), U32::<4>([0, 1, 1, 1])); - all_eq!(simd_rem(z1, z1), f32x4([0.0, 0.0, 0.0, 0.0])); + all_eq!(simd_add(x1, x2), i32x4::from_array([3, 5, 7, 9])); + all_eq!(simd_add(x2, x1), i32x4::from_array([3, 5, 7, 9])); + all_eq!(simd_add(y1, y2), U32::<4>::from_array([3, 5, 7, 9])); + all_eq!(simd_add(y2, y1), U32::<4>::from_array([3, 5, 7, 9])); + all_eq!(simd_add(z1, z2), f32x4::from_array([3.0, 5.0, 7.0, 9.0])); + all_eq!(simd_add(z2, z1), f32x4::from_array([3.0, 5.0, 7.0, 9.0])); + + all_eq!(simd_mul(x1, x2), i32x4::from_array([2, 6, 12, 20])); + all_eq!(simd_mul(x2, x1), i32x4::from_array([2, 6, 12, 20])); + all_eq!(simd_mul(y1, y2), U32::<4>::from_array([2, 6, 12, 20])); + all_eq!(simd_mul(y2, y1), U32::<4>::from_array([2, 6, 12, 20])); + all_eq!(simd_mul(z1, z2), f32x4::from_array([2.0, 6.0, 12.0, 20.0])); + all_eq!(simd_mul(z2, z1), f32x4::from_array([2.0, 6.0, 12.0, 20.0])); + + all_eq!(simd_sub(x2, x1), i32x4::from_array([1, 1, 1, 1])); + all_eq!(simd_sub(x1, x2), i32x4::from_array([-1, -1, -1, -1])); + all_eq!(simd_sub(y2, y1), U32::<4>::from_array([1, 1, 1, 1])); + all_eq!(simd_sub(y1, y2), U32::<4>::from_array([!0, !0, !0, !0])); + all_eq!(simd_sub(z2, z1), f32x4::from_array([1.0, 1.0, 1.0, 1.0])); + all_eq!(simd_sub(z1, z2), f32x4::from_array([-1.0, -1.0, -1.0, -1.0])); + + all_eq!(simd_div(x1, x1), i32x4::from_array([1, 1, 1, 1])); + all_eq!(simd_div(i32x4::from_array([2, 4, 6, 8]), i32x4::from_array([2, 2, 2, 2])), x1); + all_eq!(simd_div(y1, y1), U32::<4>::from_array([1, 1, 1, 1])); + all_eq!( + simd_div(U32::<4>::from_array([2, 4, 6, 8]), U32::<4>::from_array([2, 2, 2, 2])), + y1, + ); + all_eq!(simd_div(z1, z1), f32x4::from_array([1.0, 1.0, 1.0, 1.0])); + all_eq!(simd_div(z1, z2), f32x4::from_array([1.0 / 2.0, 2.0 / 3.0, 3.0 / 4.0, 4.0 / 5.0])); + all_eq!(simd_div(z2, z1), f32x4::from_array([2.0 / 1.0, 3.0 / 2.0, 4.0 / 3.0, 5.0 / 4.0])); + + all_eq!(simd_rem(x1, x1), i32x4::from_array([0, 0, 0, 0])); + all_eq!(simd_rem(x2, x1), i32x4::from_array([0, 1, 1, 1])); + all_eq!(simd_rem(y1, y1), U32::<4>::from_array([0, 0, 0, 0])); + all_eq!(simd_rem(y2, y1), U32::<4>::from_array([0, 1, 1, 1])); + all_eq!(simd_rem(z1, z1), f32x4::from_array([0.0, 0.0, 0.0, 0.0])); all_eq!(simd_rem(z1, z2), z1); - all_eq!(simd_rem(z2, z1), f32x4([0.0, 1.0, 1.0, 1.0])); + all_eq!(simd_rem(z2, z1), f32x4::from_array([0.0, 1.0, 1.0, 1.0])); - all_eq!(simd_shl(x1, x2), i32x4([1 << 2, 2 << 3, 3 << 4, 4 << 5])); - all_eq!(simd_shl(x2, x1), i32x4([2 << 1, 3 << 2, 4 << 3, 5 << 4])); - all_eq!(simd_shl(y1, y2), U32::<4>([1 << 2, 2 << 3, 3 << 4, 4 << 5])); - all_eq!(simd_shl(y2, y1), U32::<4>([2 << 1, 3 << 2, 4 << 3, 5 << 4])); + all_eq!(simd_shl(x1, x2), i32x4::from_array([1 << 2, 2 << 3, 3 << 4, 4 << 5])); + all_eq!(simd_shl(x2, x1), i32x4::from_array([2 << 1, 3 << 2, 4 << 3, 5 << 4])); + all_eq!(simd_shl(y1, y2), U32::<4>::from_array([1 << 2, 2 << 3, 3 << 4, 4 << 5])); + all_eq!(simd_shl(y2, y1), U32::<4>::from_array([2 << 1, 3 << 2, 4 << 3, 5 << 4])); // test right-shift by assuming left-shift is correct all_eq!(simd_shr(simd_shl(x1, x2), x2), x1); @@ -85,7 +82,7 @@ fn main() { all_eq!( simd_funnel_shl(x1, x2, x1), - i32x4([ + i32x4::from_array([ (1 << 1) | (2 >> 31), (2 << 2) | (3 >> 30), (3 << 3) | (4 >> 29), @@ -94,7 +91,7 @@ fn main() { ); all_eq!( simd_funnel_shl(x2, x1, x1), - i32x4([ + i32x4::from_array([ (2 << 1) | (1 >> 31), (3 << 2) | (2 >> 30), (4 << 3) | (3 >> 29), @@ -103,7 +100,7 @@ fn main() { ); all_eq!( simd_funnel_shl(y1, y2, y1), - U32::<4>([ + U32::<4>::from_array([ (1 << 1) | (2 >> 31), (2 << 2) | (3 >> 30), (3 << 3) | (4 >> 29), @@ -112,7 +109,7 @@ fn main() { ); all_eq!( simd_funnel_shl(y2, y1, y1), - U32::<4>([ + U32::<4>::from_array([ (2 << 1) | (1 >> 31), (3 << 2) | (2 >> 30), (4 << 3) | (3 >> 29), @@ -122,7 +119,7 @@ fn main() { all_eq!( simd_funnel_shr(x1, x2, x1), - i32x4([ + i32x4::from_array([ (1 << 31) | (2 >> 1), (2 << 30) | (3 >> 2), (3 << 29) | (4 >> 3), @@ -131,7 +128,7 @@ fn main() { ); all_eq!( simd_funnel_shr(x2, x1, x1), - i32x4([ + i32x4::from_array([ (2 << 31) | (1 >> 1), (3 << 30) | (2 >> 2), (4 << 29) | (3 >> 3), @@ -140,7 +137,7 @@ fn main() { ); all_eq!( simd_funnel_shr(y1, y2, y1), - U32::<4>([ + U32::<4>::from_array([ (1 << 31) | (2 >> 1), (2 << 30) | (3 >> 2), (3 << 29) | (4 >> 3), @@ -149,7 +146,7 @@ fn main() { ); all_eq!( simd_funnel_shr(y2, y1, y1), - U32::<4>([ + U32::<4>::from_array([ (2 << 31) | (1 >> 1), (3 << 30) | (2 >> 2), (4 << 29) | (3 >> 3), @@ -159,52 +156,69 @@ fn main() { // ensure we get logical vs. arithmetic shifts correct let (a, b, c, d) = (-12, -123, -1234, -12345); - all_eq!(simd_shr(i32x4([a, b, c, d]), x1), i32x4([a >> 1, b >> 2, c >> 3, d >> 4])); all_eq!( - simd_shr(U32::<4>([a as u32, b as u32, c as u32, d as u32]), y1), - U32::<4>([(a as u32) >> 1, (b as u32) >> 2, (c as u32) >> 3, (d as u32) >> 4]) + simd_shr(i32x4::from_array([a, b, c, d]), x1), + i32x4::from_array([a >> 1, b >> 2, c >> 3, d >> 4]), + ); + all_eq!( + simd_shr(U32::<4>::from_array([a as u32, b as u32, c as u32, d as u32]), y1), + U32::<4>::from_array([ + (a as u32) >> 1, + (b as u32) >> 2, + (c as u32) >> 3, + (d as u32) >> 4, + ]), ); - all_eq!(simd_and(x1, x2), i32x4([0, 2, 0, 4])); - all_eq!(simd_and(x2, x1), i32x4([0, 2, 0, 4])); - all_eq!(simd_and(y1, y2), U32::<4>([0, 2, 0, 4])); - all_eq!(simd_and(y2, y1), U32::<4>([0, 2, 0, 4])); + all_eq!(simd_and(x1, x2), i32x4::from_array([0, 2, 0, 4])); + all_eq!(simd_and(x2, x1), i32x4::from_array([0, 2, 0, 4])); + all_eq!(simd_and(y1, y2), U32::<4>::from_array([0, 2, 0, 4])); + all_eq!(simd_and(y2, y1), U32::<4>::from_array([0, 2, 0, 4])); - all_eq!(simd_or(x1, x2), i32x4([3, 3, 7, 5])); - all_eq!(simd_or(x2, x1), i32x4([3, 3, 7, 5])); - all_eq!(simd_or(y1, y2), U32::<4>([3, 3, 7, 5])); - all_eq!(simd_or(y2, y1), U32::<4>([3, 3, 7, 5])); + all_eq!(simd_or(x1, x2), i32x4::from_array([3, 3, 7, 5])); + all_eq!(simd_or(x2, x1), i32x4::from_array([3, 3, 7, 5])); + all_eq!(simd_or(y1, y2), U32::<4>::from_array([3, 3, 7, 5])); + all_eq!(simd_or(y2, y1), U32::<4>::from_array([3, 3, 7, 5])); - all_eq!(simd_xor(x1, x2), i32x4([3, 1, 7, 1])); - all_eq!(simd_xor(x2, x1), i32x4([3, 1, 7, 1])); - all_eq!(simd_xor(y1, y2), U32::<4>([3, 1, 7, 1])); - all_eq!(simd_xor(y2, y1), U32::<4>([3, 1, 7, 1])); + all_eq!(simd_xor(x1, x2), i32x4::from_array([3, 1, 7, 1])); + all_eq!(simd_xor(x2, x1), i32x4::from_array([3, 1, 7, 1])); + all_eq!(simd_xor(y1, y2), U32::<4>::from_array([3, 1, 7, 1])); + all_eq!(simd_xor(y2, y1), U32::<4>::from_array([3, 1, 7, 1])); - all_eq!(simd_neg(x1), i32x4([-1, -2, -3, -4])); - all_eq!(simd_neg(x2), i32x4([-2, -3, -4, -5])); - all_eq!(simd_neg(z1), f32x4([-1.0, -2.0, -3.0, -4.0])); - all_eq!(simd_neg(z2), f32x4([-2.0, -3.0, -4.0, -5.0])); + all_eq!(simd_neg(x1), i32x4::from_array([-1, -2, -3, -4])); + all_eq!(simd_neg(x2), i32x4::from_array([-2, -3, -4, -5])); + all_eq!(simd_neg(z1), f32x4::from_array([-1.0, -2.0, -3.0, -4.0])); + all_eq!(simd_neg(z2), f32x4::from_array([-2.0, -3.0, -4.0, -5.0])); - all_eq!(simd_bswap(x1), i32x4([0x01000000, 0x02000000, 0x03000000, 0x04000000])); - all_eq!(simd_bswap(y1), U32::<4>([0x01000000, 0x02000000, 0x03000000, 0x04000000])); + all_eq!( + simd_bswap(x1), + i32x4::from_array([0x01000000, 0x02000000, 0x03000000, 0x04000000]), + ); + all_eq!( + simd_bswap(y1), + U32::<4>::from_array([0x01000000, 0x02000000, 0x03000000, 0x04000000]), + ); all_eq!( simd_bitreverse(x1), - i32x4([0x80000000u32 as i32, 0x40000000, 0xc0000000u32 as i32, 0x20000000]) + i32x4::from_array([0x80000000u32 as i32, 0x40000000, 0xc0000000u32 as i32, 0x20000000]) + ); + all_eq!( + simd_bitreverse(y1), + U32::<4>::from_array([0x80000000, 0x40000000, 0xc0000000, 0x20000000]), ); - all_eq!(simd_bitreverse(y1), U32::<4>([0x80000000, 0x40000000, 0xc0000000, 0x20000000])); - all_eq!(simd_ctlz(x1), i32x4([31, 30, 30, 29])); - all_eq!(simd_ctlz(y1), U32::<4>([31, 30, 30, 29])); + all_eq!(simd_ctlz(x1), i32x4::from_array([31, 30, 30, 29])); + all_eq!(simd_ctlz(y1), U32::<4>::from_array([31, 30, 30, 29])); - all_eq!(simd_ctpop(x1), i32x4([1, 1, 2, 1])); - all_eq!(simd_ctpop(y1), U32::<4>([1, 1, 2, 1])); - all_eq!(simd_ctpop(x2), i32x4([1, 2, 1, 2])); - all_eq!(simd_ctpop(y2), U32::<4>([1, 2, 1, 2])); - all_eq!(simd_ctpop(x3), i32x4([0, 31, 1, 32])); - all_eq!(simd_ctpop(y3), U32::<4>([0, 31, 1, 32])); + all_eq!(simd_ctpop(x1), i32x4::from_array([1, 1, 2, 1])); + all_eq!(simd_ctpop(y1), U32::<4>::from_array([1, 1, 2, 1])); + all_eq!(simd_ctpop(x2), i32x4::from_array([1, 2, 1, 2])); + all_eq!(simd_ctpop(y2), U32::<4>::from_array([1, 2, 1, 2])); + all_eq!(simd_ctpop(x3), i32x4::from_array([0, 31, 1, 32])); + all_eq!(simd_ctpop(y3), U32::<4>::from_array([0, 31, 1, 32])); - all_eq!(simd_cttz(x1), i32x4([0, 1, 0, 2])); - all_eq!(simd_cttz(y1), U32::<4>([0, 1, 0, 2])); + all_eq!(simd_cttz(x1), i32x4::from_array([0, 1, 0, 2])); + all_eq!(simd_cttz(y1), U32::<4>::from_array([0, 1, 0, 2])); } } diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs index 4d12a312331..a997f123703 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs @@ -4,26 +4,24 @@ #![allow(non_camel_case_types)] #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct u32x4(pub [u32; 4]); +use std::intrinsics::simd::{simd_saturating_add, simd_saturating_sub}; -#[repr(simd)] -#[derive(Copy, Clone)] -struct I32<const N: usize>([i32; N]); +type I32<const N: usize> = Simd<i32, N>; fn main() { // unsigned { const M: u32 = u32::MAX; - let a = u32x4([1, 2, 3, 4]); - let b = u32x4([2, 4, 6, 8]); - let m = u32x4([M, M, M, M]); - let m1 = u32x4([M - 1, M - 1, M - 1, M - 1]); - let z = u32x4([0, 0, 0, 0]); + let a = u32x4::from_array([1, 2, 3, 4]); + let b = u32x4::from_array([2, 4, 6, 8]); + let m = u32x4::from_array([M, M, M, M]); + let m1 = u32x4::from_array([M - 1, M - 1, M - 1, M - 1]); + let z = u32x4::from_array([0, 0, 0, 0]); unsafe { assert_eq!(simd_saturating_add(z, z), z); @@ -48,41 +46,41 @@ fn main() { const MIN: i32 = i32::MIN; const MAX: i32 = i32::MAX; - let a = I32::<4>([1, 2, 3, 4]); - let b = I32::<4>([2, 4, 6, 8]); - let c = I32::<4>([-1, -2, -3, -4]); - let d = I32::<4>([-2, -4, -6, -8]); + let a = I32::<4>::from_array([1, 2, 3, 4]); + let b = I32::<4>::from_array([2, 4, 6, 8]); + let c = I32::<4>::from_array([-1, -2, -3, -4]); + let d = I32::<4>::from_array([-2, -4, -6, -8]); - let max = I32::<4>([MAX, MAX, MAX, MAX]); - let max1 = I32::<4>([MAX - 1, MAX - 1, MAX - 1, MAX - 1]); - let min = I32::<4>([MIN, MIN, MIN, MIN]); - let min1 = I32::<4>([MIN + 1, MIN + 1, MIN + 1, MIN + 1]); + let max = I32::<4>::from_array([MAX, MAX, MAX, MAX]); + let max1 = I32::<4>::from_array([MAX - 1, MAX - 1, MAX - 1, MAX - 1]); + let min = I32::<4>::from_array([MIN, MIN, MIN, MIN]); + let min1 = I32::<4>::from_array([MIN + 1, MIN + 1, MIN + 1, MIN + 1]); - let z = I32::<4>([0, 0, 0, 0]); + let z = I32::<4>::from_array([0, 0, 0, 0]); unsafe { - assert_eq!(simd_saturating_add(z, z).0, z.0); - assert_eq!(simd_saturating_add(z, a).0, a.0); - assert_eq!(simd_saturating_add(b, z).0, b.0); - assert_eq!(simd_saturating_add(a, a).0, b.0); - assert_eq!(simd_saturating_add(a, max).0, max.0); - assert_eq!(simd_saturating_add(max, b).0, max.0); - assert_eq!(simd_saturating_add(max1, a).0, max.0); - assert_eq!(simd_saturating_add(min1, z).0, min1.0); - assert_eq!(simd_saturating_add(min, z).0, min.0); - assert_eq!(simd_saturating_add(min1, c).0, min.0); - assert_eq!(simd_saturating_add(min, c).0, min.0); - assert_eq!(simd_saturating_add(min1, d).0, min.0); - assert_eq!(simd_saturating_add(min, d).0, min.0); + assert_eq!(simd_saturating_add(z, z), z); + assert_eq!(simd_saturating_add(z, a), a); + assert_eq!(simd_saturating_add(b, z), b); + assert_eq!(simd_saturating_add(a, a), b); + assert_eq!(simd_saturating_add(a, max), max); + assert_eq!(simd_saturating_add(max, b), max); + assert_eq!(simd_saturating_add(max1, a), max); + assert_eq!(simd_saturating_add(min1, z), min1); + assert_eq!(simd_saturating_add(min, z), min); + assert_eq!(simd_saturating_add(min1, c), min); + assert_eq!(simd_saturating_add(min, c), min); + assert_eq!(simd_saturating_add(min1, d), min); + assert_eq!(simd_saturating_add(min, d), min); - assert_eq!(simd_saturating_sub(b, z).0, b.0); - assert_eq!(simd_saturating_sub(b, a).0, a.0); - assert_eq!(simd_saturating_sub(a, a).0, z.0); - assert_eq!(simd_saturating_sub(a, b).0, c.0); - assert_eq!(simd_saturating_sub(z, max).0, min1.0); - assert_eq!(simd_saturating_sub(min1, z).0, min1.0); - assert_eq!(simd_saturating_sub(min1, a).0, min.0); - assert_eq!(simd_saturating_sub(min1, b).0, min.0); + assert_eq!(simd_saturating_sub(b, z), b); + assert_eq!(simd_saturating_sub(b, a), a); + assert_eq!(simd_saturating_sub(a, a), z); + assert_eq!(simd_saturating_sub(a, b), c); + assert_eq!(simd_saturating_sub(z, max), min1); + assert_eq!(simd_saturating_sub(min1, z), min1); + assert_eq!(simd_saturating_sub(min1, a), min); + assert_eq!(simd_saturating_sub(min1, b), min); } } } diff --git a/tests/ui/simd/intrinsic/generic-as.rs b/tests/ui/simd/intrinsic/generic-as.rs index da53211cbc7..f9ed416b6ff 100644 --- a/tests/ui/simd/intrinsic/generic-as.rs +++ b/tests/ui/simd/intrinsic/generic-as.rs @@ -2,45 +2,47 @@ #![feature(repr_simd, core_intrinsics)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::simd_as; -#[derive(Copy, Clone)] -#[repr(simd)] -struct V<T>([T; 2]); +type V<T> = Simd<T, 2>; fn main() { unsafe { - let u = V::<u32>([u32::MIN, u32::MAX]); + let u: V::<u32> = Simd([u32::MIN, u32::MAX]); let i: V<i16> = simd_as(u); - assert_eq!(i.0[0], u.0[0] as i16); - assert_eq!(i.0[1], u.0[1] as i16); + assert_eq!(i[0], u[0] as i16); + assert_eq!(i[1], u[1] as i16); } unsafe { - let f = V::<f32>([f32::MIN, f32::MAX]); + let f: V::<f32> = Simd([f32::MIN, f32::MAX]); let i: V<i16> = simd_as(f); - assert_eq!(i.0[0], f.0[0] as i16); - assert_eq!(i.0[1], f.0[1] as i16); + assert_eq!(i[0], f[0] as i16); + assert_eq!(i[1], f[1] as i16); } unsafe { - let f = V::<f32>([f32::MIN, f32::MAX]); + let f: V::<f32> = Simd([f32::MIN, f32::MAX]); let u: V<u8> = simd_as(f); - assert_eq!(u.0[0], f.0[0] as u8); - assert_eq!(u.0[1], f.0[1] as u8); + assert_eq!(u[0], f[0] as u8); + assert_eq!(u[1], f[1] as u8); } unsafe { - let f = V::<f64>([f64::MIN, f64::MAX]); + let f: V::<f64> = Simd([f64::MIN, f64::MAX]); let i: V<isize> = simd_as(f); - assert_eq!(i.0[0], f.0[0] as isize); - assert_eq!(i.0[1], f.0[1] as isize); + assert_eq!(i[0], f[0] as isize); + assert_eq!(i[1], f[1] as isize); } unsafe { - let f = V::<f64>([f64::MIN, f64::MAX]); + let f: V::<f64> = Simd([f64::MIN, f64::MAX]); let u: V<usize> = simd_as(f); - assert_eq!(u.0[0], f.0[0] as usize); - assert_eq!(u.0[1], f.0[1] as usize); + assert_eq!(u[0], f[0] as usize); + assert_eq!(u[1], f[1] as usize); } } diff --git a/tests/ui/simd/intrinsic/generic-bswap-byte.rs b/tests/ui/simd/intrinsic/generic-bswap-byte.rs index 903a07656a7..d30a560b1c2 100644 --- a/tests/ui/simd/intrinsic/generic-bswap-byte.rs +++ b/tests/ui/simd/intrinsic/generic-bswap-byte.rs @@ -2,19 +2,15 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_bswap; - -#[repr(simd)] -#[derive(Copy, Clone)] -struct i8x4([i8; 4]); +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone)] -struct u8x4([u8; 4]); +use std::intrinsics::simd::simd_bswap; fn main() { unsafe { - assert_eq!(simd_bswap(i8x4([0, 1, 2, 3])).0, [0, 1, 2, 3]); - assert_eq!(simd_bswap(u8x4([0, 1, 2, 3])).0, [0, 1, 2, 3]); + assert_eq!(simd_bswap(i8x4::from_array([0, 1, 2, 3])).into_array(), [0, 1, 2, 3]); + assert_eq!(simd_bswap(u8x4::from_array([0, 1, 2, 3])).into_array(), [0, 1, 2, 3]); } } diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs index 7a4663bcad2..0c3b00d65bf 100644 --- a/tests/ui/simd/intrinsic/generic-cast-pass.rs +++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs @@ -2,55 +2,57 @@ #![feature(repr_simd, core_intrinsics)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::simd_cast; use std::cmp::{max, min}; -#[derive(Copy, Clone)] -#[repr(simd)] -struct V<T>([T; 2]); +type V<T> = Simd<T, 2>; fn main() { unsafe { - let u = V::<u32>([i16::MIN as u32, i16::MAX as u32]); + let u: V::<u32> = Simd([i16::MIN as u32, i16::MAX as u32]); let i: V<i16> = simd_cast(u); - assert_eq!(i.0[0], u.0[0] as i16); - assert_eq!(i.0[1], u.0[1] as i16); + assert_eq!(i[0], u[0] as i16); + assert_eq!(i[1], u[1] as i16); } unsafe { - let f = V::<f32>([i16::MIN as f32, i16::MAX as f32]); + let f: V::<f32> = Simd([i16::MIN as f32, i16::MAX as f32]); let i: V<i16> = simd_cast(f); - assert_eq!(i.0[0], f.0[0] as i16); - assert_eq!(i.0[1], f.0[1] as i16); + assert_eq!(i[0], f[0] as i16); + assert_eq!(i[1], f[1] as i16); } unsafe { - let f = V::<f32>([u8::MIN as f32, u8::MAX as f32]); + let f: V::<f32> = Simd([u8::MIN as f32, u8::MAX as f32]); let u: V<u8> = simd_cast(f); - assert_eq!(u.0[0], f.0[0] as u8); - assert_eq!(u.0[1], f.0[1] as u8); + assert_eq!(u[0], f[0] as u8); + assert_eq!(u[1], f[1] as u8); } unsafe { // We would like to do isize::MIN..=isize::MAX, but those values are not representable in // an f64, so we clamp to the range of an i32 to prevent running into UB. - let f = V::<f64>([ + let f: V::<f64> = Simd([ max(isize::MIN, i32::MIN as isize) as f64, min(isize::MAX, i32::MAX as isize) as f64, ]); let i: V<isize> = simd_cast(f); - assert_eq!(i.0[0], f.0[0] as isize); - assert_eq!(i.0[1], f.0[1] as isize); + assert_eq!(i[0], f[0] as isize); + assert_eq!(i[1], f[1] as isize); } unsafe { - let f = V::<f64>([ + let f: V::<f64> = Simd([ max(usize::MIN, u32::MIN as usize) as f64, min(usize::MAX, u32::MAX as usize) as f64, ]); let u: V<usize> = simd_cast(f); - assert_eq!(u.0[0], f.0[0] as usize); - assert_eq!(u.0[1], f.0[1] as usize); + assert_eq!(u[0], f[0] as usize); + assert_eq!(u[1], f[1] as usize); } } diff --git a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs index ea34e9ffeb8..594d1d25d16 100644 --- a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs +++ b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs @@ -1,18 +1,24 @@ //@ run-pass #![feature(repr_simd, core_intrinsics)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::simd_cast; -#[derive(Copy, Clone)] -#[repr(simd)] -struct V<T>([T; 4]); +type V<T> = Simd<T, 4>; fn main() { - let u = V::<usize>([0, 1, 2, 3]); + let u: V::<usize> = Simd([0, 1, 2, 3]); let uu32: V<u32> = unsafe { simd_cast(u) }; let ui64: V<i64> = unsafe { simd_cast(u) }; - for (u, (uu32, ui64)) in u.0.iter().zip(uu32.0.iter().zip(ui64.0.iter())) { + for (u, (uu32, ui64)) in u + .as_array() + .iter() + .zip(uu32.as_array().iter().zip(ui64.as_array().iter())) + { assert_eq!(*u as u32, *uu32); assert_eq!(*u as i64, *ui64); } diff --git a/tests/ui/simd/intrinsic/generic-comparison-pass.rs b/tests/ui/simd/intrinsic/generic-comparison-pass.rs index 50a05eecb03..3e803e8f603 100644 --- a/tests/ui/simd/intrinsic/generic-comparison-pass.rs +++ b/tests/ui/simd/intrinsic/generic-comparison-pass.rs @@ -3,17 +3,11 @@ #![feature(repr_simd, core_intrinsics, macro_metavar_expr_concat)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::{simd_eq, simd_ge, simd_gt, simd_le, simd_lt, simd_ne}; +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone)] -struct i32x4([i32; 4]); -#[repr(simd)] -#[derive(Copy, Clone)] -struct u32x4(pub [u32; 4]); -#[repr(simd)] -#[derive(Copy, Clone)] -struct f32x4(pub [f32; 4]); +use std::intrinsics::simd::{simd_eq, simd_ge, simd_gt, simd_le, simd_lt, simd_ne}; macro_rules! cmp { ($method: ident($lhs: expr, $rhs: expr)) => {{ @@ -21,10 +15,11 @@ macro_rules! cmp { let rhs = $rhs; let e: u32x4 = ${concat(simd_, $method)}($lhs, $rhs); // assume the scalar version is correct/the behaviour we want. - assert!((e.0[0] != 0) == lhs.0[0].$method(&rhs.0[0])); - assert!((e.0[1] != 0) == lhs.0[1].$method(&rhs.0[1])); - assert!((e.0[2] != 0) == lhs.0[2].$method(&rhs.0[2])); - assert!((e.0[3] != 0) == lhs.0[3].$method(&rhs.0[3])); + let (lhs, rhs, e) = (lhs.as_array(), rhs.as_array(), e.as_array()); + assert!((e[0] != 0) == lhs[0].$method(&rhs[0])); + assert!((e[1] != 0) == lhs[1].$method(&rhs[1])); + assert!((e[2] != 0) == lhs[2].$method(&rhs[2])); + assert!((e[3] != 0) == lhs[3].$method(&rhs[3])); }}; } macro_rules! tests { @@ -53,17 +48,17 @@ macro_rules! tests { fn main() { // 13 vs. -100 tests that we get signed vs. unsigned comparisons // correct (i32: 13 > -100, u32: 13 < -100). let i1 = i32x4(10, -11, 12, 13); - let i1 = i32x4([10, -11, 12, 13]); - let i2 = i32x4([5, -5, 20, -100]); - let i3 = i32x4([10, -11, 20, -100]); + let i1 = i32x4::from_array([10, -11, 12, 13]); + let i2 = i32x4::from_array([5, -5, 20, -100]); + let i3 = i32x4::from_array([10, -11, 20, -100]); - let u1 = u32x4([10, !11 + 1, 12, 13]); - let u2 = u32x4([5, !5 + 1, 20, !100 + 1]); - let u3 = u32x4([10, !11 + 1, 20, !100 + 1]); + let u1 = u32x4::from_array([10, !11 + 1, 12, 13]); + let u2 = u32x4::from_array([5, !5 + 1, 20, !100 + 1]); + let u3 = u32x4::from_array([10, !11 + 1, 20, !100 + 1]); - let f1 = f32x4([10.0, -11.0, 12.0, 13.0]); - let f2 = f32x4([5.0, -5.0, 20.0, -100.0]); - let f3 = f32x4([10.0, -11.0, 20.0, -100.0]); + let f1 = f32x4::from_array([10.0, -11.0, 12.0, 13.0]); + let f2 = f32x4::from_array([5.0, -5.0, 20.0, -100.0]); + let f3 = f32x4::from_array([10.0, -11.0, 20.0, -100.0]); unsafe { tests! { @@ -84,7 +79,7 @@ fn main() { // NAN comparisons are special: // -11 (*) 13 // -5 -100 (*) - let f4 = f32x4([f32::NAN, f1.0[1], f32::NAN, f2.0[3]]); + let f4 = f32x4::from_array([f32::NAN, f1[1], f32::NAN, f2[3]]); unsafe { tests! { diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs index e4d47cdb381..f441d992e11 100644 --- a/tests/ui/simd/intrinsic/generic-elements-pass.rs +++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs @@ -2,24 +2,15 @@ #![feature(repr_simd, intrinsics, core_intrinsics)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::{ simd_extract, simd_extract_dyn, simd_insert, simd_insert_dyn, simd_shuffle, }; #[repr(simd)] -#[derive(Copy, Clone, Debug, PartialEq)] -#[allow(non_camel_case_types)] -struct i32x2([i32; 2]); -#[repr(simd)] -#[derive(Copy, Clone, Debug, PartialEq)] -#[allow(non_camel_case_types)] -struct i32x4([i32; 4]); -#[repr(simd)] -#[derive(Copy, Clone, Debug, PartialEq)] -#[allow(non_camel_case_types)] -struct i32x8([i32; 8]); - -#[repr(simd)] struct SimdShuffleIdx<const LEN: usize>([u32; LEN]); macro_rules! all_eq { @@ -34,26 +25,26 @@ macro_rules! all_eq { } fn main() { - let x2 = i32x2([20, 21]); - let x4 = i32x4([40, 41, 42, 43]); - let x8 = i32x8([80, 81, 82, 83, 84, 85, 86, 87]); + let x2 = i32x2::from_array([20, 21]); + let x4 = i32x4::from_array([40, 41, 42, 43]); + let x8 = i32x8::from_array([80, 81, 82, 83, 84, 85, 86, 87]); unsafe { - all_eq!(simd_insert(x2, 0, 100), i32x2([100, 21])); - all_eq!(simd_insert(x2, 1, 100), i32x2([20, 100])); - - all_eq!(simd_insert(x4, 0, 100), i32x4([100, 41, 42, 43])); - all_eq!(simd_insert(x4, 1, 100), i32x4([40, 100, 42, 43])); - all_eq!(simd_insert(x4, 2, 100), i32x4([40, 41, 100, 43])); - all_eq!(simd_insert(x4, 3, 100), i32x4([40, 41, 42, 100])); - - all_eq!(simd_insert(x8, 0, 100), i32x8([100, 81, 82, 83, 84, 85, 86, 87])); - all_eq!(simd_insert(x8, 1, 100), i32x8([80, 100, 82, 83, 84, 85, 86, 87])); - all_eq!(simd_insert(x8, 2, 100), i32x8([80, 81, 100, 83, 84, 85, 86, 87])); - all_eq!(simd_insert(x8, 3, 100), i32x8([80, 81, 82, 100, 84, 85, 86, 87])); - all_eq!(simd_insert(x8, 4, 100), i32x8([80, 81, 82, 83, 100, 85, 86, 87])); - all_eq!(simd_insert(x8, 5, 100), i32x8([80, 81, 82, 83, 84, 100, 86, 87])); - all_eq!(simd_insert(x8, 6, 100), i32x8([80, 81, 82, 83, 84, 85, 100, 87])); - all_eq!(simd_insert(x8, 7, 100), i32x8([80, 81, 82, 83, 84, 85, 86, 100])); + all_eq!(simd_insert(x2, 0, 100), i32x2::from_array([100, 21])); + all_eq!(simd_insert(x2, 1, 100), i32x2::from_array([20, 100])); + + all_eq!(simd_insert(x4, 0, 100), i32x4::from_array([100, 41, 42, 43])); + all_eq!(simd_insert(x4, 1, 100), i32x4::from_array([40, 100, 42, 43])); + all_eq!(simd_insert(x4, 2, 100), i32x4::from_array([40, 41, 100, 43])); + all_eq!(simd_insert(x4, 3, 100), i32x4::from_array([40, 41, 42, 100])); + + all_eq!(simd_insert(x8, 0, 100), i32x8::from_array([100, 81, 82, 83, 84, 85, 86, 87])); + all_eq!(simd_insert(x8, 1, 100), i32x8::from_array([80, 100, 82, 83, 84, 85, 86, 87])); + all_eq!(simd_insert(x8, 2, 100), i32x8::from_array([80, 81, 100, 83, 84, 85, 86, 87])); + all_eq!(simd_insert(x8, 3, 100), i32x8::from_array([80, 81, 82, 100, 84, 85, 86, 87])); + all_eq!(simd_insert(x8, 4, 100), i32x8::from_array([80, 81, 82, 83, 100, 85, 86, 87])); + all_eq!(simd_insert(x8, 5, 100), i32x8::from_array([80, 81, 82, 83, 84, 100, 86, 87])); + all_eq!(simd_insert(x8, 6, 100), i32x8::from_array([80, 81, 82, 83, 84, 85, 100, 87])); + all_eq!(simd_insert(x8, 7, 100), i32x8::from_array([80, 81, 82, 83, 84, 85, 86, 100])); all_eq!(simd_extract(x2, 0), 20); all_eq!(simd_extract(x2, 1), 21); @@ -73,22 +64,22 @@ fn main() { all_eq!(simd_extract(x8, 7), 87); } unsafe { - all_eq!(simd_insert_dyn(x2, 0, 100), i32x2([100, 21])); - all_eq!(simd_insert_dyn(x2, 1, 100), i32x2([20, 100])); - - all_eq!(simd_insert_dyn(x4, 0, 100), i32x4([100, 41, 42, 43])); - all_eq!(simd_insert_dyn(x4, 1, 100), i32x4([40, 100, 42, 43])); - all_eq!(simd_insert_dyn(x4, 2, 100), i32x4([40, 41, 100, 43])); - all_eq!(simd_insert_dyn(x4, 3, 100), i32x4([40, 41, 42, 100])); - - all_eq!(simd_insert_dyn(x8, 0, 100), i32x8([100, 81, 82, 83, 84, 85, 86, 87])); - all_eq!(simd_insert_dyn(x8, 1, 100), i32x8([80, 100, 82, 83, 84, 85, 86, 87])); - all_eq!(simd_insert_dyn(x8, 2, 100), i32x8([80, 81, 100, 83, 84, 85, 86, 87])); - all_eq!(simd_insert_dyn(x8, 3, 100), i32x8([80, 81, 82, 100, 84, 85, 86, 87])); - all_eq!(simd_insert_dyn(x8, 4, 100), i32x8([80, 81, 82, 83, 100, 85, 86, 87])); - all_eq!(simd_insert_dyn(x8, 5, 100), i32x8([80, 81, 82, 83, 84, 100, 86, 87])); - all_eq!(simd_insert_dyn(x8, 6, 100), i32x8([80, 81, 82, 83, 84, 85, 100, 87])); - all_eq!(simd_insert_dyn(x8, 7, 100), i32x8([80, 81, 82, 83, 84, 85, 86, 100])); + all_eq!(simd_insert_dyn(x2, 0, 100), i32x2::from_array([100, 21])); + all_eq!(simd_insert_dyn(x2, 1, 100), i32x2::from_array([20, 100])); + + all_eq!(simd_insert_dyn(x4, 0, 100), i32x4::from_array([100, 41, 42, 43])); + all_eq!(simd_insert_dyn(x4, 1, 100), i32x4::from_array([40, 100, 42, 43])); + all_eq!(simd_insert_dyn(x4, 2, 100), i32x4::from_array([40, 41, 100, 43])); + all_eq!(simd_insert_dyn(x4, 3, 100), i32x4::from_array([40, 41, 42, 100])); + + all_eq!(simd_insert_dyn(x8, 0, 100), i32x8::from_array([100, 81, 82, 83, 84, 85, 86, 87])); + all_eq!(simd_insert_dyn(x8, 1, 100), i32x8::from_array([80, 100, 82, 83, 84, 85, 86, 87])); + all_eq!(simd_insert_dyn(x8, 2, 100), i32x8::from_array([80, 81, 100, 83, 84, 85, 86, 87])); + all_eq!(simd_insert_dyn(x8, 3, 100), i32x8::from_array([80, 81, 82, 100, 84, 85, 86, 87])); + all_eq!(simd_insert_dyn(x8, 4, 100), i32x8::from_array([80, 81, 82, 83, 100, 85, 86, 87])); + all_eq!(simd_insert_dyn(x8, 5, 100), i32x8::from_array([80, 81, 82, 83, 84, 100, 86, 87])); + all_eq!(simd_insert_dyn(x8, 6, 100), i32x8::from_array([80, 81, 82, 83, 84, 85, 100, 87])); + all_eq!(simd_insert_dyn(x8, 7, 100), i32x8::from_array([80, 81, 82, 83, 84, 85, 86, 100])); all_eq!(simd_extract_dyn(x2, 0), 20); all_eq!(simd_extract_dyn(x2, 1), 21); @@ -108,38 +99,47 @@ fn main() { all_eq!(simd_extract_dyn(x8, 7), 87); } - let y2 = i32x2([120, 121]); - let y4 = i32x4([140, 141, 142, 143]); - let y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]); + let y2 = i32x2::from_array([120, 121]); + let y4 = i32x4::from_array([140, 141, 142, 143]); + let y8 = i32x8::from_array([180, 181, 182, 183, 184, 185, 186, 187]); unsafe { - all_eq!(simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0]) }), i32x2([121, 20])); + all_eq!( + simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0]) }), + i32x2::from_array([121, 20]) + ); all_eq!( simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2]) }), - i32x4([121, 20, 21, 120]) + i32x4::from_array([121, 20, 21, 120]) ); all_eq!( simd_shuffle(x2, y2, const { SimdShuffleIdx([3u32, 0, 1, 2, 1, 2, 3, 0]) }), - i32x8([121, 20, 21, 120, 21, 120, 121, 20]) + i32x8::from_array([121, 20, 21, 120, 21, 120, 121, 20]) ); - all_eq!(simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2]) }), i32x2([143, 42])); + all_eq!( + simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2]) }), + i32x2::from_array([143, 42]) + ); all_eq!( simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0]) }), - i32x4([143, 42, 141, 40]) + i32x4::from_array([143, 42, 141, 40]) ); all_eq!( simd_shuffle(x4, y4, const { SimdShuffleIdx([7u32, 2, 5, 0, 3, 6, 4, 1]) }), - i32x8([143, 42, 141, 40, 43, 142, 140, 41]) + i32x8::from_array([143, 42, 141, 40, 43, 142, 140, 41]) ); - all_eq!(simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5]) }), i32x2([183, 85])); + all_eq!( + simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5]) }), + i32x2::from_array([183, 85]) + ); all_eq!( simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0]) }), - i32x4([183, 85, 187, 80]) + i32x4::from_array([183, 85, 187, 80]) ); all_eq!( simd_shuffle(x8, y8, const { SimdShuffleIdx([11u32, 5, 15, 0, 3, 8, 12, 1]) }), - i32x8([183, 85, 187, 80, 83, 180, 184, 81]) + i32x8::from_array([183, 85, 187, 80, 83, 180, 184, 81]) ); } } diff --git a/tests/ui/simd/intrinsic/generic-gather-scatter-pass.rs b/tests/ui/simd/intrinsic/generic-gather-scatter-pass.rs index b98d4d6575b..c2418c019ed 100644 --- a/tests/ui/simd/intrinsic/generic-gather-scatter-pass.rs +++ b/tests/ui/simd/intrinsic/generic-gather-scatter-pass.rs @@ -6,24 +6,26 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::{simd_gather, simd_scatter}; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct x4<T>(pub [T; 4]); +type x4<T> = Simd<T, 4>; fn main() { let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.]; - let default = x4([-3_f32, -3., -3., -3.]); - let s_strided = x4([0_f32, 2., -3., 6.]); - let mask = x4([-1_i32, -1, 0, -1]); + let default = x4::from_array([-3_f32, -3., -3., -3.]); + let s_strided = x4::from_array([0_f32, 2., -3., 6.]); + let mask = x4::from_array([-1_i32, -1, 0, -1]); // reading from *const unsafe { let pointer = x.as_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i * 2))); let r_strided = simd_gather(default, pointers, mask); @@ -34,7 +36,7 @@ fn main() { unsafe { let pointer = x.as_mut_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i * 2))); let r_strided = simd_gather(default, pointers, mask); @@ -45,9 +47,9 @@ fn main() { unsafe { let pointer = x.as_mut_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i * 2))); - let values = x4([42_f32, 43_f32, 44_f32, 45_f32]); + let values = x4::from_array([42_f32, 43_f32, 44_f32, 45_f32]); simd_scatter(values, pointers, mask); assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]); @@ -65,14 +67,14 @@ fn main() { &x[7] as *const f32, ]; - let default = x4([y[0], y[0], y[0], y[0]]); - let s_strided = x4([y[0], y[2], y[0], y[6]]); + let default = x4::from_array([y[0], y[0], y[0], y[0]]); + let s_strided = x4::from_array([y[0], y[2], y[0], y[6]]); // reading from *const unsafe { let pointer = y.as_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i * 2))); let r_strided = simd_gather(default, pointers, mask); @@ -83,7 +85,7 @@ fn main() { unsafe { let pointer = y.as_mut_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i * 2))); let r_strided = simd_gather(default, pointers, mask); @@ -94,9 +96,9 @@ fn main() { unsafe { let pointer = y.as_mut_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i * 2))); - let values = x4([y[7], y[6], y[5], y[1]]); + let values = x4::from_array([y[7], y[6], y[5], y[1]]); simd_scatter(values, pointers, mask); let s = [ diff --git a/tests/ui/simd/intrinsic/generic-select-pass.rs b/tests/ui/simd/intrinsic/generic-select-pass.rs index 0e5f7c4902f..ff2d70d6a97 100644 --- a/tests/ui/simd/intrinsic/generic-select-pass.rs +++ b/tests/ui/simd/intrinsic/generic-select-pass.rs @@ -6,38 +6,24 @@ // Test that the simd_select intrinsics produces correct results. #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{simd_select, simd_select_bitmask}; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct i32x4(pub [i32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct u32x4(pub [u32; 4]); +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct u32x8([u32; 8]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct f32x4(pub [f32; 4]); +use std::intrinsics::simd::{simd_select, simd_select_bitmask}; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct b8x4(pub [i8; 4]); +type b8x4 = i8x4; fn main() { - let m0 = b8x4([!0, !0, !0, !0]); - let m1 = b8x4([0, 0, 0, 0]); - let m2 = b8x4([!0, !0, 0, 0]); - let m3 = b8x4([0, 0, !0, !0]); - let m4 = b8x4([!0, 0, !0, 0]); + let m0 = b8x4::from_array([!0, !0, !0, !0]); + let m1 = b8x4::from_array([0, 0, 0, 0]); + let m2 = b8x4::from_array([!0, !0, 0, 0]); + let m3 = b8x4::from_array([0, 0, !0, !0]); + let m4 = b8x4::from_array([!0, 0, !0, 0]); unsafe { - let a = i32x4([1, -2, 3, 4]); - let b = i32x4([5, 6, -7, 8]); + let a = i32x4::from_array([1, -2, 3, 4]); + let b = i32x4::from_array([5, 6, -7, 8]); let r: i32x4 = simd_select(m0, a, b); let e = a; @@ -48,21 +34,21 @@ fn main() { assert_eq!(r, e); let r: i32x4 = simd_select(m2, a, b); - let e = i32x4([1, -2, -7, 8]); + let e = i32x4::from_array([1, -2, -7, 8]); assert_eq!(r, e); let r: i32x4 = simd_select(m3, a, b); - let e = i32x4([5, 6, 3, 4]); + let e = i32x4::from_array([5, 6, 3, 4]); assert_eq!(r, e); let r: i32x4 = simd_select(m4, a, b); - let e = i32x4([1, 6, 3, 8]); + let e = i32x4::from_array([1, 6, 3, 8]); assert_eq!(r, e); } unsafe { - let a = u32x4([1, 2, 3, 4]); - let b = u32x4([5, 6, 7, 8]); + let a = u32x4::from_array([1, 2, 3, 4]); + let b = u32x4::from_array([5, 6, 7, 8]); let r: u32x4 = simd_select(m0, a, b); let e = a; @@ -73,21 +59,21 @@ fn main() { assert_eq!(r, e); let r: u32x4 = simd_select(m2, a, b); - let e = u32x4([1, 2, 7, 8]); + let e = u32x4::from_array([1, 2, 7, 8]); assert_eq!(r, e); let r: u32x4 = simd_select(m3, a, b); - let e = u32x4([5, 6, 3, 4]); + let e = u32x4::from_array([5, 6, 3, 4]); assert_eq!(r, e); let r: u32x4 = simd_select(m4, a, b); - let e = u32x4([1, 6, 3, 8]); + let e = u32x4::from_array([1, 6, 3, 8]); assert_eq!(r, e); } unsafe { - let a = f32x4([1., 2., 3., 4.]); - let b = f32x4([5., 6., 7., 8.]); + let a = f32x4::from_array([1., 2., 3., 4.]); + let b = f32x4::from_array([5., 6., 7., 8.]); let r: f32x4 = simd_select(m0, a, b); let e = a; @@ -98,23 +84,23 @@ fn main() { assert_eq!(r, e); let r: f32x4 = simd_select(m2, a, b); - let e = f32x4([1., 2., 7., 8.]); + let e = f32x4::from_array([1., 2., 7., 8.]); assert_eq!(r, e); let r: f32x4 = simd_select(m3, a, b); - let e = f32x4([5., 6., 3., 4.]); + let e = f32x4::from_array([5., 6., 3., 4.]); assert_eq!(r, e); let r: f32x4 = simd_select(m4, a, b); - let e = f32x4([1., 6., 3., 8.]); + let e = f32x4::from_array([1., 6., 3., 8.]); assert_eq!(r, e); } unsafe { let t = !0 as i8; let f = 0 as i8; - let a = b8x4([t, f, t, f]); - let b = b8x4([f, f, f, t]); + let a = b8x4::from_array([t, f, t, f]); + let b = b8x4::from_array([f, f, f, t]); let r: b8x4 = simd_select(m0, a, b); let e = a; @@ -125,21 +111,21 @@ fn main() { assert_eq!(r, e); let r: b8x4 = simd_select(m2, a, b); - let e = b8x4([t, f, f, t]); + let e = b8x4::from_array([t, f, f, t]); assert_eq!(r, e); let r: b8x4 = simd_select(m3, a, b); - let e = b8x4([f, f, t, f]); + let e = b8x4::from_array([f, f, t, f]); assert_eq!(r, e); let r: b8x4 = simd_select(m4, a, b); - let e = b8x4([t, f, t, t]); + let e = b8x4::from_array([t, f, t, t]); assert_eq!(r, e); } unsafe { - let a = u32x8([0, 1, 2, 3, 4, 5, 6, 7]); - let b = u32x8([8, 9, 10, 11, 12, 13, 14, 15]); + let a = u32x8::from_array([0, 1, 2, 3, 4, 5, 6, 7]); + let b = u32x8::from_array([8, 9, 10, 11, 12, 13, 14, 15]); let r: u32x8 = simd_select_bitmask(0u8, a, b); let e = b; @@ -150,21 +136,21 @@ fn main() { assert_eq!(r, e); let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b); - let e = u32x8([0, 9, 2, 11, 4, 13, 6, 15]); + let e = u32x8::from_array([0, 9, 2, 11, 4, 13, 6, 15]); assert_eq!(r, e); let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b); - let e = u32x8([8, 1, 10, 3, 12, 5, 14, 7]); + let e = u32x8::from_array([8, 1, 10, 3, 12, 5, 14, 7]); assert_eq!(r, e); let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b); - let e = u32x8([8, 9, 10, 11, 4, 5, 6, 7]); + let e = u32x8::from_array([8, 9, 10, 11, 4, 5, 6, 7]); assert_eq!(r, e); } unsafe { - let a = u32x4([0, 1, 2, 3]); - let b = u32x4([4, 5, 6, 7]); + let a = u32x4::from_array([0, 1, 2, 3]); + let b = u32x4::from_array([4, 5, 6, 7]); let r: u32x4 = simd_select_bitmask(0u8, a, b); let e = b; @@ -175,15 +161,15 @@ fn main() { assert_eq!(r, e); let r: u32x4 = simd_select_bitmask(0b0101u8, a, b); - let e = u32x4([0, 5, 2, 7]); + let e = u32x4::from_array([0, 5, 2, 7]); assert_eq!(r, e); let r: u32x4 = simd_select_bitmask(0b1010u8, a, b); - let e = u32x4([4, 1, 6, 3]); + let e = u32x4::from_array([4, 1, 6, 3]); assert_eq!(r, e); let r: u32x4 = simd_select_bitmask(0b1100u8, a, b); - let e = u32x4([4, 5, 2, 3]); + let e = u32x4::from_array([4, 5, 2, 3]); assert_eq!(r, e); } } diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs index 13e7266b2a5..14f180425d8 100644 --- a/tests/ui/simd/intrinsic/inlining-issue67557.rs +++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs @@ -5,11 +5,13 @@ //@ compile-flags: -Zmir-opt-level=4 #![feature(core_intrinsics, repr_simd)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::simd_shuffle; -#[repr(simd)] -#[derive(Debug, PartialEq)] -struct Simd2([u8; 2]); +type Simd2 = u8x2; #[repr(simd)] struct SimdShuffleIdx<const LEN: usize>([u32; LEN]); @@ -17,7 +19,11 @@ struct SimdShuffleIdx<const LEN: usize>([u32; LEN]); fn main() { unsafe { const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 1]); - let p_res: Simd2 = simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX); + let p_res: Simd2 = simd_shuffle( + Simd2::from_array([10, 11]), + Simd2::from_array([12, 13]), + IDX, + ); let a_res: Simd2 = inline_me(); assert_10_11(p_res); @@ -27,16 +33,16 @@ fn main() { #[inline(never)] fn assert_10_11(x: Simd2) { - assert_eq!(x, Simd2([10, 11])); + assert_eq!(x.into_array(), [10, 11]); } #[inline(never)] fn assert_10_13(x: Simd2) { - assert_eq!(x, Simd2([10, 13])); + assert_eq!(x.into_array(), [10, 13]); } #[inline(always)] unsafe fn inline_me() -> Simd2 { const IDX: SimdShuffleIdx<2> = SimdShuffleIdx([0, 3]); - simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX) + simd_shuffle(Simd2::from_array([10, 11]), Simd2::from_array([12, 13]), IDX) } diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs index 3a73c0273e1..63b65d83f76 100644 --- a/tests/ui/simd/intrinsic/ptr-cast.rs +++ b/tests/ui/simd/intrinsic/ptr-cast.rs @@ -2,18 +2,20 @@ #![feature(repr_simd, core_intrinsics)] +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::{simd_cast_ptr, simd_expose_provenance, simd_with_exposed_provenance}; -#[derive(Copy, Clone)] -#[repr(simd)] -struct V<T>([T; 2]); +type V<T> = Simd<T, 2>; fn main() { unsafe { let mut foo = 4i8; let ptr = &mut foo as *mut i8; - let ptrs = V::<*mut i8>([ptr, core::ptr::null_mut()]); + let ptrs: V::<*mut i8> = Simd([ptr, core::ptr::null_mut()]); // change constness and type let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs); @@ -22,8 +24,8 @@ fn main() { let with_exposed_provenance: V<*mut i8> = simd_with_exposed_provenance(exposed_addr); - assert!(const_ptrs.0 == [ptr as *const u8, core::ptr::null()]); - assert!(exposed_addr.0 == [ptr as usize, 0]); - assert!(with_exposed_provenance.0 == ptrs.0); + assert!(const_ptrs.into_array() == [ptr as *const u8, core::ptr::null()]); + assert!(exposed_addr.into_array() == [ptr as usize, 0]); + assert!(with_exposed_provenance.into_array() == ptrs.into_array()); } } diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs index 0a44f36fb2e..1d57eff341c 100644 --- a/tests/ui/simd/issue-105439.rs +++ b/tests/ui/simd/issue-105439.rs @@ -10,7 +10,9 @@ struct i32x4([i32; 4]); #[inline(always)] fn to_array(a: i32x4) -> [i32; 4] { - a.0 + // This was originally just `a.0`, but that ended up being annoying enough + // that it was banned by <https://github.com/rust-lang/compiler-team/issues/838> + unsafe { std::mem::transmute(a) } } fn main() { diff --git a/tests/ui/simd/issue-39720.rs b/tests/ui/simd/issue-39720.rs index db441e55167..09d6142c920 100644 --- a/tests/ui/simd/issue-39720.rs +++ b/tests/ui/simd/issue-39720.rs @@ -2,16 +2,16 @@ #![feature(repr_simd, core_intrinsics)] -#[repr(simd)] -#[derive(Copy, Clone, Debug)] -pub struct Char3(pub [i8; 3]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, Debug)] -pub struct Short3(pub [i16; 3]); +pub type Char3 = Simd<i8, 3>; + +pub type Short3 = Simd<i16, 3>; fn main() { - let cast: Short3 = unsafe { std::intrinsics::simd::simd_cast(Char3([10, -3, -9])) }; + let cast: Short3 = unsafe { std::intrinsics::simd::simd_cast(Char3::from_array([10, -3, -9])) }; println!("{:?}", cast); } diff --git a/tests/ui/simd/issue-85915-simd-ptrs.rs b/tests/ui/simd/issue-85915-simd-ptrs.rs index 4e2379d0525..a74c36fabc1 100644 --- a/tests/ui/simd/issue-85915-simd-ptrs.rs +++ b/tests/ui/simd/issue-85915-simd-ptrs.rs @@ -6,35 +6,27 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::{simd_gather, simd_scatter}; - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct cptrx4<T>([*const T; 4]); +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct mptrx4<T>([*mut T; 4]); +use std::intrinsics::simd::{simd_gather, simd_scatter}; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct f32x4([f32; 4]); +type cptrx4<T> = Simd<*const T, 4>; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct i32x4([i32; 4]); +type mptrx4<T> = Simd<*mut T, 4>; fn main() { let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.]; - let default = f32x4([-3_f32, -3., -3., -3.]); - let s_strided = f32x4([0_f32, 2., -3., 6.]); - let mask = i32x4([-1_i32, -1, 0, -1]); + let default = f32x4::from_array([-3_f32, -3., -3., -3.]); + let s_strided = f32x4::from_array([0_f32, 2., -3., 6.]); + let mask = i32x4::from_array([-1_i32, -1, 0, -1]); // reading from *const unsafe { let pointer = &x as *const f32; - let pointers = cptrx4([ + let pointers = cptrx4::from_array([ pointer.offset(0) as *const f32, pointer.offset(2), pointer.offset(4), @@ -49,14 +41,14 @@ fn main() { // writing to *mut unsafe { let pointer = &mut x as *mut f32; - let pointers = mptrx4([ + let pointers = mptrx4::from_array([ pointer.offset(0) as *mut f32, pointer.offset(2), pointer.offset(4), pointer.offset(6), ]); - let values = f32x4([42_f32, 43_f32, 44_f32, 45_f32]); + let values = f32x4::from_array([42_f32, 43_f32, 44_f32, 45_f32]); simd_scatter(values, pointers, mask); assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]); diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs index a6c3017572a..da4cd456589 100644 --- a/tests/ui/simd/issue-89193.rs +++ b/tests/ui/simd/issue-89193.rs @@ -6,36 +6,38 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::simd_gather; -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -struct x4<T>(pub [T; 4]); +type x4<T> = Simd<T, 4>; fn main() { let x: [usize; 4] = [10, 11, 12, 13]; - let default = x4([0_usize, 1, 2, 3]); + let default = x4::from_array([0_usize, 1, 2, 3]); let all_set = u8::MAX as i8; // aka -1 - let mask = x4([all_set, all_set, all_set, all_set]); - let expected = x4([10_usize, 11, 12, 13]); + let mask = x4::from_array([all_set, all_set, all_set, all_set]); + let expected = x4::from_array([10_usize, 11, 12, 13]); unsafe { let pointer = x.as_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(1), pointer.offset(2), pointer.offset(3)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i))); let result = simd_gather(default, pointers, mask); assert_eq!(result, expected); } // and again for isize let x: [isize; 4] = [10, 11, 12, 13]; - let default = x4([0_isize, 1, 2, 3]); - let expected = x4([10_isize, 11, 12, 13]); + let default = x4::from_array([0_isize, 1, 2, 3]); + let expected = x4::from_array([10_isize, 11, 12, 13]); unsafe { let pointer = x.as_ptr(); let pointers = - x4([pointer.offset(0), pointer.offset(1), pointer.offset(2), pointer.offset(3)]); + x4::from_array(std::array::from_fn(|i| pointer.add(i))); let result = simd_gather(default, pointers, mask); assert_eq!(result, expected); } diff --git a/tests/ui/simd/masked-load-store.rs b/tests/ui/simd/masked-load-store.rs index 69ea76581ee..da32ba611c4 100644 --- a/tests/ui/simd/masked-load-store.rs +++ b/tests/ui/simd/masked-load-store.rs @@ -1,11 +1,11 @@ //@ run-pass #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[derive(Copy, Clone)] -#[repr(simd)] -struct Simd<T, const N: usize>([T; N]); +use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; fn main() { unsafe { @@ -15,7 +15,7 @@ fn main() { let b: Simd<u8, 4> = simd_masked_load(Simd::<i8, 4>([-1, 0, -1, -1]), b_src.as_ptr(), b_default); - assert_eq!(&b.0, &[4, 9, 6, 7]); + assert_eq!(b.as_array(), &[4, 9, 6, 7]); let mut output = [u8::MAX; 5]; diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index a56f2ea1452..1490f8e2319 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -11,6 +11,10 @@ )] #![allow(incomplete_features)] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + #[cfg(old)] use std::intrinsics::simd::simd_shuffle; @@ -18,10 +22,6 @@ use std::intrinsics::simd::simd_shuffle; #[rustc_intrinsic] unsafe fn simd_shuffle_const_generic<T, U, const I: &'static [u32]>(a: T, b: T) -> U; -#[derive(Copy, Clone)] -#[repr(simd)] -struct Simd<T, const N: usize>([T; N]); - trait Shuffle<const N: usize> { const I: Simd<u32, N>; const J: &'static [u32] = &Self::I.0; @@ -57,9 +57,9 @@ fn main() { let b = Simd::<u8, 4>([4, 5, 6, 7]); unsafe { let x: Simd<u8, 4> = I1.shuffle(a, b); - assert_eq!(x.0, [0, 2, 4, 6]); + assert_eq!(x.into_array(), [0, 2, 4, 6]); let y: Simd<u8, 2> = I2.shuffle(a, b); - assert_eq!(y.0, [1, 5]); + assert_eq!(y.into_array(), [1, 5]); } } diff --git a/tests/ui/simd/repr_packed.rs b/tests/ui/simd/repr_packed.rs index cc54477ae71..f0c6de7c402 100644 --- a/tests/ui/simd/repr_packed.rs +++ b/tests/ui/simd/repr_packed.rs @@ -3,15 +3,16 @@ #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] -use std::intrinsics::simd::simd_add; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[repr(simd, packed)] -struct Simd<T, const N: usize>([T; N]); +use std::intrinsics::simd::simd_add; fn check_size_align<T, const N: usize>() { use std::mem; - assert_eq!(mem::size_of::<Simd<T, N>>(), mem::size_of::<[T; N]>()); - assert_eq!(mem::size_of::<Simd<T, N>>() % mem::align_of::<Simd<T, N>>(), 0); + assert_eq!(mem::size_of::<PackedSimd<T, N>>(), mem::size_of::<[T; N]>()); + assert_eq!(mem::size_of::<PackedSimd<T, N>>() % mem::align_of::<PackedSimd<T, N>>(), 0); } fn check_ty<T>() { @@ -35,14 +36,21 @@ fn main() { unsafe { // powers-of-two have no padding and have the same layout as #[repr(simd)] - let x: Simd<f64, 4> = - simd_add(Simd::<f64, 4>([0., 1., 2., 3.]), Simd::<f64, 4>([2., 2., 2., 2.])); - assert_eq!(std::mem::transmute::<_, [f64; 4]>(x), [2., 3., 4., 5.]); + let x: PackedSimd<f64, 4> = + simd_add( + PackedSimd::<f64, 4>([0., 1., 2., 3.]), + PackedSimd::<f64, 4>([2., 2., 2., 2.]), + ); + assert_eq!(x.into_array(), [2., 3., 4., 5.]); // non-powers-of-two should have padding (which is removed by #[repr(packed)]), // but the intrinsic handles it - let x: Simd<f64, 3> = simd_add(Simd::<f64, 3>([0., 1., 2.]), Simd::<f64, 3>([2., 2., 2.])); - let arr: [f64; 3] = x.0; + let x: PackedSimd<f64, 3> = + simd_add( + PackedSimd::<f64, 3>([0., 1., 2.]), + PackedSimd::<f64, 3>([2., 2., 2.]), + ); + let arr: [f64; 3] = x.into_array(); assert_eq!(arr, [2., 3., 4.]); } } diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs index cd270edcf00..061571a4786 100644 --- a/tests/ui/simd/shuffle.rs +++ b/tests/ui/simd/shuffle.rs @@ -10,10 +10,16 @@ use std::marker::ConstParamTy; use std::intrinsics::simd::simd_shuffle; +// not using `minisimd` because of the `ConstParamTy` #[derive(Copy, Clone, ConstParamTy, PartialEq, Eq)] #[repr(simd)] struct Simd<T, const N: usize>([T; N]); +fn into_array<T, const N: usize>(v: Simd<T, N>) -> [T; N] { + const { assert!(size_of::<Simd<T, N>>() == size_of::<[T; N]>()) } + unsafe { std::intrinsics::transmute_unchecked(v) } +} + unsafe fn __shuffle_vector16<const IDX: Simd<u32, 16>, T, U>(x: T, y: T) -> U { simd_shuffle(x, y, IDX) } @@ -25,10 +31,10 @@ fn main() { let b = Simd::<u8, 4>([4, 5, 6, 7]); unsafe { let x: Simd<u8, 4> = simd_shuffle(a, b, I1); - assert_eq!(x.0, [0, 2, 4, 6]); + assert_eq!(into_array(x), [0, 2, 4, 6]); let y: Simd<u8, 2> = simd_shuffle(a, b, I2); - assert_eq!(y.0, [1, 5]); + assert_eq!(into_array(y), [1, 5]); } // Test that an indirection (via an unnamed constant) diff --git a/tests/ui/simd/simd-bitmask-notpow2.rs b/tests/ui/simd/simd-bitmask-notpow2.rs index 4935097065e..b9af591d1b9 100644 --- a/tests/ui/simd/simd-bitmask-notpow2.rs +++ b/tests/ui/simd/simd-bitmask-notpow2.rs @@ -4,21 +4,23 @@ //@ ignore-endian-big #![feature(repr_simd, core_intrinsics)] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + use std::intrinsics::simd::{simd_bitmask, simd_select_bitmask}; fn main() { // Non-power-of-2 multi-byte mask. - #[repr(simd, packed)] #[allow(non_camel_case_types)] - #[derive(Copy, Clone, Debug, PartialEq)] - struct i32x10([i32; 10]); + type i32x10 = PackedSimd<i32, 10>; impl i32x10 { fn splat(x: i32) -> Self { Self([x; 10]) } } unsafe { - let mask = i32x10([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]); + let mask = i32x10::from_array([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]); let mask_bits = if cfg!(target_endian = "little") { 0b0101001011 } else { 0b1101001010 }; let mask_bytes = if cfg!(target_endian = "little") { [0b01001011, 0b01] } else { [0b11, 0b01001010] }; @@ -43,17 +45,20 @@ fn main() { } // Test for a mask where the next multiple of 8 is not a power of two. - #[repr(simd, packed)] #[allow(non_camel_case_types)] - #[derive(Copy, Clone, Debug, PartialEq)] - struct i32x20([i32; 20]); + type i32x20 = PackedSimd<i32, 20>; impl i32x20 { fn splat(x: i32) -> Self { Self([x; 20]) } } unsafe { - let mask = i32x20([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0, 0, 0, 0, !0, !0, !0, !0, !0, !0, !0]); + let mask = i32x20::from_array([ + !0, !0, 0, !0, 0, + 0, !0, 0, !0, 0, + 0, 0, 0, !0, !0, + !0, !0, !0, !0, !0, + ]); let mask_bits = if cfg!(target_endian = "little") { 0b11111110000101001011 } else { diff --git a/tests/ui/simd/simd-bitmask.rs b/tests/ui/simd/simd-bitmask.rs index 6fcceeaa24b..609dae3647b 100644 --- a/tests/ui/simd/simd-bitmask.rs +++ b/tests/ui/simd/simd-bitmask.rs @@ -1,11 +1,11 @@ //@run-pass #![feature(repr_simd, core_intrinsics)] -use std::intrinsics::simd::{simd_bitmask, simd_select_bitmask}; +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; -#[derive(Copy, Clone)] -#[repr(simd)] -struct Simd<T, const N: usize>([T; N]); +use std::intrinsics::simd::{simd_bitmask, simd_select_bitmask}; fn main() { unsafe { @@ -41,11 +41,11 @@ fn main() { let mask = if cfg!(target_endian = "little") { 0b0101u8 } else { 0b1010u8 }; let r = simd_select_bitmask(mask, a, b); - assert_eq!(r.0, e); + assert_eq!(r.into_array(), e); let mask = if cfg!(target_endian = "little") { [0b0101u8] } else { [0b1010u8] }; let r = simd_select_bitmask(mask, a, b); - assert_eq!(r.0, e); + assert_eq!(r.into_array(), e); let a = Simd::<i32, 16>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); let b = Simd::<i32, 16>([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); @@ -57,7 +57,7 @@ fn main() { 0b0011000000001010u16 }; let r = simd_select_bitmask(mask, a, b); - assert_eq!(r.0, e); + assert_eq!(r.into_array(), e); let mask = if cfg!(target_endian = "little") { [0b00001100u8, 0b01010000u8] @@ -65,6 +65,6 @@ fn main() { [0b00110000u8, 0b00001010u8] }; let r = simd_select_bitmask(mask, a, b); - assert_eq!(r.0, e); + assert_eq!(r.into_array(), e); } } diff --git a/tests/ui/simd/target-feature-mixup.rs b/tests/ui/simd/target-feature-mixup.rs index 77f18615248..82902891b97 100644 --- a/tests/ui/simd/target-feature-mixup.rs +++ b/tests/ui/simd/target-feature-mixup.rs @@ -8,6 +8,11 @@ #![feature(repr_simd, target_feature, cfg_target_feature)] +#[path = "../../auxiliary/minisimd.rs"] +mod minisimd; +#[allow(unused)] +use minisimd::*; + use std::process::{Command, ExitStatus}; use std::env; @@ -50,19 +55,13 @@ fn is_sigill(status: ExitStatus) -> bool { #[allow(nonstandard_style)] mod test { // An SSE type - #[repr(simd)] - #[derive(PartialEq, Debug, Clone, Copy)] - struct __m128i([u64; 2]); + type __m128i = super::u64x2; // An AVX type - #[repr(simd)] - #[derive(PartialEq, Debug, Clone, Copy)] - struct __m256i([u64; 4]); + type __m256i = super::u64x4; // An AVX-512 type - #[repr(simd)] - #[derive(PartialEq, Debug, Clone, Copy)] - struct __m512i([u64; 8]); + type __m512i = super::u64x8; pub fn main(level: &str) { unsafe { @@ -88,9 +87,9 @@ mod test { )*) => ($( $(#[$attr])* unsafe fn $main(level: &str) { - let m128 = __m128i([1, 2]); - let m256 = __m256i([3, 4, 5, 6]); - let m512 = __m512i([7, 8, 9, 10, 11, 12, 13, 14]); + let m128 = __m128i::from_array([1, 2]); + let m256 = __m256i::from_array([3, 4, 5, 6]); + let m512 = __m512i::from_array([7, 8, 9, 10, 11, 12, 13, 14]); assert_eq!(id_sse_128(m128), m128); assert_eq!(id_sse_256(m256), m256); assert_eq!(id_sse_512(m512), m512); @@ -125,55 +124,55 @@ mod test { #[target_feature(enable = "sse2")] unsafe fn id_sse_128(a: __m128i) -> __m128i { - assert_eq!(a, __m128i([1, 2])); + assert_eq!(a, __m128i::from_array([1, 2])); a.clone() } #[target_feature(enable = "sse2")] unsafe fn id_sse_256(a: __m256i) -> __m256i { - assert_eq!(a, __m256i([3, 4, 5, 6])); + assert_eq!(a, __m256i::from_array([3, 4, 5, 6])); a.clone() } #[target_feature(enable = "sse2")] unsafe fn id_sse_512(a: __m512i) -> __m512i { - assert_eq!(a, __m512i([7, 8, 9, 10, 11, 12, 13, 14])); + assert_eq!(a, __m512i::from_array([7, 8, 9, 10, 11, 12, 13, 14])); a.clone() } #[target_feature(enable = "avx")] unsafe fn id_avx_128(a: __m128i) -> __m128i { - assert_eq!(a, __m128i([1, 2])); + assert_eq!(a, __m128i::from_array([1, 2])); a.clone() } #[target_feature(enable = "avx")] unsafe fn id_avx_256(a: __m256i) -> __m256i { - assert_eq!(a, __m256i([3, 4, 5, 6])); + assert_eq!(a, __m256i::from_array([3, 4, 5, 6])); a.clone() } #[target_feature(enable = "avx")] unsafe fn id_avx_512(a: __m512i) -> __m512i { - assert_eq!(a, __m512i([7, 8, 9, 10, 11, 12, 13, 14])); + assert_eq!(a, __m512i::from_array([7, 8, 9, 10, 11, 12, 13, 14])); a.clone() } #[target_feature(enable = "avx512bw")] unsafe fn id_avx512_128(a: __m128i) -> __m128i { - assert_eq!(a, __m128i([1, 2])); + assert_eq!(a, __m128i::from_array([1, 2])); a.clone() } #[target_feature(enable = "avx512bw")] unsafe fn id_avx512_256(a: __m256i) -> __m256i { - assert_eq!(a, __m256i([3, 4, 5, 6])); + assert_eq!(a, __m256i::from_array([3, 4, 5, 6])); a.clone() } #[target_feature(enable = "avx512bw")] unsafe fn id_avx512_512(a: __m512i) -> __m512i { - assert_eq!(a, __m512i([7, 8, 9, 10, 11, 12, 13, 14])); + assert_eq!(a, __m512i::from_array([7, 8, 9, 10, 11, 12, 13, 14])); a.clone() } } diff --git a/tests/ui/sized-hierarchy/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs index 12b2eb2b5c1..bbb2c6d96ba 100644 --- a/tests/ui/sized-hierarchy/default-bound.rs +++ b/tests/ui/sized-hierarchy/default-bound.rs @@ -14,13 +14,13 @@ fn neg_sized<T: ?Sized>() {} fn metasized<T: MetaSized>() {} fn neg_metasized<T: ?MetaSized>() {} -//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~^ ERROR bound modifier `?` can only be applied to `Sized` fn pointeesized<T: PointeeSized>() { } fn neg_pointeesized<T: ?PointeeSized>() { } -//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +//~^ ERROR bound modifier `?` can only be applied to `Sized` fn main() { diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr index 22f0fa29d3e..0a4ea6f44d8 100644 --- a/tests/ui/sized-hierarchy/default-bound.stderr +++ b/tests/ui/sized-hierarchy/default-bound.stderr @@ -1,10 +1,10 @@ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/default-bound.rs:16:21 | LL | fn neg_metasized<T: ?MetaSized>() {} | ^^^^^^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/default-bound.rs:22:24 | LL | fn neg_pointeesized<T: ?PointeeSized>() { } diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs index b25acf9e6ea..ab3b28e84db 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.rs +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -6,18 +6,18 @@ use std::marker::{MetaSized, PointeeSized}; trait Sized_: Sized { } trait NegSized: ?Sized { } -//~^ ERROR `?Trait` is not permitted in supertraits +//~^ ERROR relaxed bounds are not permitted in supertrait bounds trait MetaSized_: MetaSized { } trait NegMetaSized: ?MetaSized { } -//~^ ERROR `?Trait` is not permitted in supertraits +//~^ ERROR relaxed bounds are not permitted in supertrait bounds trait PointeeSized_: PointeeSized { } trait NegPointeeSized: ?PointeeSized { } -//~^ ERROR `?Trait` is not permitted in supertraits +//~^ ERROR relaxed bounds are not permitted in supertrait bounds trait Bare {} diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr index de23936b900..f5589d6e279 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.stderr +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -1,32 +1,22 @@ -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:8:17 | LL | trait NegSized: ?Sized { } | ^^^^^^ | = note: traits are `?Sized` by default - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:13:21 | LL | trait NegMetaSized: ?MetaSized { } | ^^^^^^^^^^ - | - = note: traits are `?MetaSized` by default - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: `?Trait` is not permitted in supertraits +error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:19:24 | LL | trait NegPointeeSized: ?PointeeSized { } | ^^^^^^^^^^^^^ - | - = note: traits are `?PointeeSized` by default - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0277]: the size for values of type `T` cannot be known --> $DIR/default-supertrait.rs:52:38 @@ -121,5 +111,4 @@ LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() { error: aborting due to 9 previous errors -Some errors have detailed explanations: E0277, E0658. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current_sized_hierarchy.stderr b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current_sized_hierarchy.stderr new file mode 100644 index 00000000000..b904b784df7 --- /dev/null +++ b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current_sized_hierarchy.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/incomplete-inference-issue-143992.rs:30:28 + | +LL | let _x = T::Assoc::new(()); + | ------------- ^^ expected `[u32; 1]`, found `()` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $DIR/incomplete-inference-issue-143992.rs:21:8 + | +LL | fn new(r: R) -> R { + | ^^^ ---- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next_sized_hierarchy.stderr b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next_sized_hierarchy.stderr new file mode 100644 index 00000000000..b904b784df7 --- /dev/null +++ b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next_sized_hierarchy.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/incomplete-inference-issue-143992.rs:30:28 + | +LL | let _x = T::Assoc::new(()); + | ------------- ^^ expected `[u32; 1]`, found `()` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $DIR/incomplete-inference-issue-143992.rs:21:8 + | +LL | fn new(r: R) -> R { + | ^^^ ---- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs new file mode 100644 index 00000000000..b9e65ed2839 --- /dev/null +++ b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs @@ -0,0 +1,33 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: current next current_sized_hierarchy next_sized_hierarchy +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[current] check-pass +//@[next] check-pass +//@[next] compile-flags: -Znext-solver +//@[next_sized_hierarchy] compile-flags: -Znext-solver + +#![cfg_attr(any(current_sized_hierarchy, next_sized_hierarchy), feature(sized_hierarchy))] + +// Test that we avoid incomplete inference when normalizing. Without this, +// `Trait`'s implicit `MetaSized` supertrait requires proving `T::Assoc<_>: MetaSized` +// before checking the `new` arguments, resulting in eagerly constraining the inference +// var to `u32`. This is undesirable and would breaking code. + +pub trait Trait { + type Assoc<G>: OtherTrait<G>; +} + +pub trait OtherTrait<R> { + fn new(r: R) -> R { + r + } +} + +pub fn function<T: Trait>() +where + T::Assoc<[u32; 1]>: Clone, +{ + let _x = T::Assoc::new(()); + //[next_sized_hierarchy]~^ ERROR mismatched types + //[current_sized_hierarchy]~^^ ERROR mismatched types +} diff --git a/tests/ui/sized-hierarchy/overflow.current.stderr b/tests/ui/sized-hierarchy/overflow.current.stderr deleted file mode 100644 index e90548aa78c..00000000000 --- a/tests/ui/sized-hierarchy/overflow.current.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error[E0275]: overflow evaluating the requirement `Element: MetaSized` - --> $DIR/overflow.rs:16:16 - | -LL | struct Element(<Box<Box<Element>> as ParseTokens>::Output); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: required for `Box<Element>` to implement `ParseTokens` - --> $DIR/overflow.rs:12:31 - | -LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { - | - ^^^^^^^^^^^ ^^^^^^ - | | - | unsatisfied trait bound introduced here - = note: 1 redundant requirement hidden - = note: required for `Box<Box<Element>>` to implement `ParseTokens` - -error[E0275]: overflow evaluating the requirement `Box<Element>: ParseTokens` - --> $DIR/overflow.rs:18:22 - | -LL | impl ParseTokens for Element { - | ^^^^^^^ - | -note: required for `Box<Box<Element>>` to implement `ParseTokens` - --> $DIR/overflow.rs:12:31 - | -LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { - | ----------- ^^^^^^^^^^^ ^^^^^^ - | | - | unsatisfied trait bound introduced here -note: required because it appears within the type `Element` - --> $DIR/overflow.rs:16:8 - | -LL | struct Element(<Box<Box<Element>> as ParseTokens>::Output); - | ^^^^^^^ -note: required by a bound in `ParseTokens` - --> $DIR/overflow.rs:9:1 - | -LL | / trait ParseTokens { -LL | | type Output; -LL | | } - | |_^ required by this bound in `ParseTokens` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/sized-hierarchy/overflow.rs b/tests/ui/sized-hierarchy/overflow.rs index e1af4885e53..f8e5dd5d402 100644 --- a/tests/ui/sized-hierarchy/overflow.rs +++ b/tests/ui/sized-hierarchy/overflow.rs @@ -1,9 +1,13 @@ //@ compile-flags: --crate-type=lib //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) +//@[current] check-pass //@[next] check-pass //@[next] compile-flags: -Znext-solver +// FIXME(sized_hierarchy): this is expected to fail in the old solver when there +// isn't a temporary revert of the `sized_hierarchy` feature + use std::marker::PhantomData; trait ParseTokens { @@ -14,8 +18,6 @@ impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { } struct Element(<Box<Box<Element>> as ParseTokens>::Output); -//[current]~^ ERROR overflow evaluating impl ParseTokens for Element { -//[current]~^ ERROR overflow evaluating type Output = (); } diff --git a/tests/ui/sized-hierarchy/pointee-validation.rs b/tests/ui/sized-hierarchy/pointee-validation.rs new file mode 100644 index 00000000000..dfc28829e08 --- /dev/null +++ b/tests/ui/sized-hierarchy/pointee-validation.rs @@ -0,0 +1,20 @@ +// Test that despite us dropping `PointeeSized` bounds during HIR ty lowering +// we still validate it first. +// issue: <https://github.com/rust-lang/rust/issues/142718> +#![feature(sized_hierarchy)] + +use std::marker::PointeeSized; + +struct T where (): PointeeSized<(), Undefined = ()>; +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied +//~| ERROR associated type `Undefined` not found for `PointeeSized` + +const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} +//~^ ERROR `const` can only be applied to `const` traits +//~| ERROR `const` can only be applied to `const` traits +//~| ERROR const trait impls are experimental +//~| ERROR `[const]` can only be applied to `const` traits +//~| ERROR `[const]` can only be applied to `const` traits +//~| ERROR const trait impls are experimental + +fn main() {} diff --git a/tests/ui/sized-hierarchy/pointee-validation.stderr b/tests/ui/sized-hierarchy/pointee-validation.stderr new file mode 100644 index 00000000000..a056d548356 --- /dev/null +++ b/tests/ui/sized-hierarchy/pointee-validation.stderr @@ -0,0 +1,76 @@ +error[E0658]: const trait impls are experimental + --> $DIR/pointee-validation.rs:12:32 + | +LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} + | ^^^^^ + | + = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: const trait impls are experimental + --> $DIR/pointee-validation.rs:12:55 + | +LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} + | ^^^^^^^ + | + = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/pointee-validation.rs:8:20 + | +LL | struct T where (): PointeeSized<(), Undefined = ()>; + | ^^^^^^^^^^^^-------------------- help: remove the unnecessary generics + | | + | expected 0 generic arguments + +error[E0220]: associated type `Undefined` not found for `PointeeSized` + --> $DIR/pointee-validation.rs:8:37 + | +LL | struct T where (): PointeeSized<(), Undefined = ()>; + | ^^^^^^^^^ associated type `Undefined` not found + +error: `const` can only be applied to `const` traits + --> $DIR/pointee-validation.rs:12:32 + | +LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} + | ^^^^^ can't be applied to `PointeeSized` + | +note: `PointeeSized` can't be used with `const` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + +error: `[const]` can only be applied to `const` traits + --> $DIR/pointee-validation.rs:12:55 + | +LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} + | ^^^^^^^ can't be applied to `PointeeSized` + | +note: `PointeeSized` can't be used with `[const]` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + +error: `const` can only be applied to `const` traits + --> $DIR/pointee-validation.rs:12:32 + | +LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} + | ^^^^^ can't be applied to `PointeeSized` + | +note: `PointeeSized` can't be used with `const` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `[const]` can only be applied to `const` traits + --> $DIR/pointee-validation.rs:12:55 + | +LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {} + | ^^^^^^^ can't be applied to `PointeeSized` + | +note: `PointeeSized` can't be used with `[const]` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0107, E0220, E0658. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/sized-hierarchy/reject-dyn-pointeesized.rs b/tests/ui/sized-hierarchy/reject-dyn-pointeesized.rs index ece1702679d..89e4c15371d 100644 --- a/tests/ui/sized-hierarchy/reject-dyn-pointeesized.rs +++ b/tests/ui/sized-hierarchy/reject-dyn-pointeesized.rs @@ -3,7 +3,7 @@ use std::marker::PointeeSized; type Foo = dyn PointeeSized; -//~^ ERROR `PointeeSized` cannot be used with trait objects +//~^ ERROR at least one trait is required for an object type fn foo(f: &Foo) {} @@ -12,5 +12,5 @@ fn main() { let x = main; let y: Box<dyn PointeeSized> = x; -//~^ ERROR `PointeeSized` cannot be used with trait objects +//~^ ERROR at least one trait is required for an object type } diff --git a/tests/ui/sized-hierarchy/reject-dyn-pointeesized.stderr b/tests/ui/sized-hierarchy/reject-dyn-pointeesized.stderr index a833c6952fd..616b2400f86 100644 --- a/tests/ui/sized-hierarchy/reject-dyn-pointeesized.stderr +++ b/tests/ui/sized-hierarchy/reject-dyn-pointeesized.stderr @@ -1,10 +1,10 @@ -error: `PointeeSized` cannot be used with trait objects +error[E0224]: at least one trait is required for an object type --> $DIR/reject-dyn-pointeesized.rs:5:12 | LL | type Foo = dyn PointeeSized; | ^^^^^^^^^^^^^^^^ -error: `PointeeSized` cannot be used with trait objects +error[E0224]: at least one trait is required for an object type --> $DIR/reject-dyn-pointeesized.rs:14:16 | LL | let y: Box<dyn PointeeSized> = x; @@ -12,3 +12,4 @@ LL | let y: Box<dyn PointeeSized> = x; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index b9c768812c8..a21a48997ee 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,57 +1,57 @@ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const_trait_impl.rs:36:9 | LL | impl<T: [const] Debug> const A for T { | ^^^^^^^ can't be applied to `Debug` | -note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const_trait_impl.rs:42:9 | LL | impl<T: [const] Debug + [const] Sup> const A for T { | ^^^^^^^ can't be applied to `Debug` | -note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const_trait_impl.rs:48:9 | LL | impl<T: [const] Debug + [const] Sub> const A for T { | ^^^^^^^ can't be applied to `Debug` | -note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const_trait_impl.rs:42:9 | LL | impl<T: [const] Debug + [const] Sup> const A for T { | ^^^^^^^ can't be applied to `Debug` | -note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const_trait_impl.rs:36:9 | LL | impl<T: [const] Debug> const A for T { | ^^^^^^^ can't be applied to `Debug` | -note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const_trait_impl.rs:48:9 | LL | impl<T: [const] Debug + [const] Sub> const A for T { | ^^^^^^^ can't be applied to `Debug` | -note: `Debug` can't be used with `[const]` because it isn't annotated with `#[const_trait]` +note: `Debug` can't be used with `[const]` because it isn't `const` --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index c3e72e83948..8a37f19ffb0 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -20,8 +20,7 @@ impl Foo { } #[stable(feature = "stable", since = "1.0.0")] -#[const_trait] -pub trait Bar { +pub const trait Bar { //~^ ERROR trait has missing const stability attribute #[stable(feature = "stable", since = "1.0.0")] fn fun(); diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr index 09461e6fb54..5748e20cd2b 100644 --- a/tests/ui/stability-attribute/missing-const-stability.stderr +++ b/tests/ui/stability-attribute/missing-const-stability.stderr @@ -2,29 +2,25 @@ error: function has missing const stability attribute --> $DIR/missing-const-stability.rs:7:1 | LL | pub const fn foo() {} - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ error: trait has missing const stability attribute - --> $DIR/missing-const-stability.rs:24:1 + --> $DIR/missing-const-stability.rs:23:1 | -LL | / pub trait Bar { -LL | | -LL | | #[stable(feature = "stable", since = "1.0.0")] -LL | | fn fun(); -LL | | } - | |_^ +LL | pub const trait Bar { + | ^^^^^^^^^^^^^^^^^^^ error: function has missing const stability attribute - --> $DIR/missing-const-stability.rs:37:1 + --> $DIR/missing-const-stability.rs:36:1 | LL | pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated function has missing const stability attribute --> $DIR/missing-const-stability.rs:16:5 | LL | pub const fn foo() {} - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-3.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-3.stderr index a6d1ebf2945..d33bb53360b 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-3.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity-3.stderr @@ -1,10 +1,8 @@ error: macro has missing stability attribute --> $DIR/stability-attribute-sanity-3.rs:8:1 | -LL | / macro_rules! mac { -LL | | () => () -LL | | } - | |_^ +LL | macro_rules! mac { + | ^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/std/issue-81357-unsound-file-methods.rs b/tests/ui/std/issue-81357-unsound-file-methods.rs index 838df40c32d..99bd31aa260 100644 --- a/tests/ui/std/issue-81357-unsound-file-methods.rs +++ b/tests/ui/std/issue-81357-unsound-file-methods.rs @@ -1,4 +1,4 @@ -//@ run-fail +//@ run-crash //@ only-windows fn main() { diff --git a/tests/ui/structs/default-field-values/const-trait-default-field-value.rs b/tests/ui/structs/default-field-values/const-trait-default-field-value.rs new file mode 100644 index 00000000000..60c22efabc4 --- /dev/null +++ b/tests/ui/structs/default-field-values/const-trait-default-field-value.rs @@ -0,0 +1,37 @@ +//@ check-pass + +// Ensure that `default_field_values` and `const_default` interact properly. + +#![feature(const_default)] +#![feature(const_trait_impl)] +#![feature(default_field_values)] +#![feature(derive_const)] + +#[derive(PartialEq, Eq, Debug)] +#[derive_const(Default)] +struct S { + r: Option<String> = <Option<_> as Default>::default(), + s: String = String::default(), + o: Option<String> = Option::<String>::default(), + p: std::marker::PhantomData<()> = std::marker::PhantomData::default(), + q: Option<String> = <Option<String> as Default>::default(), + t: Option<String> = Option::default(), + v: Option<String> = const { Option::default() }, +} + +const _: S = S { .. }; +const _: S = const { S { .. } }; +const _: S = S::default(); +const _: S = const { S::default() }; + +fn main() { + let s = S { .. }; + assert_eq!(s.r, None); + assert_eq!(&s.s, ""); + assert_eq!(s.o, None); + assert_eq!(s.p, std::marker::PhantomData); + assert_eq!(s.q, None); + assert_eq!(s.t, None); + assert_eq!(s.v, None); + assert_eq!(s, S::default()); +} diff --git a/tests/ui/suggestions/issue-94171.stderr b/tests/ui/suggestions/issue-94171.stderr index bcbd46cd8ec..52306a2465f 100644 --- a/tests/ui/suggestions/issue-94171.stderr +++ b/tests/ui/suggestions/issue-94171.stderr @@ -22,9 +22,7 @@ error: this file contains an unclosed delimiter --> $DIR/issue-94171.rs:5:52 | LL | fn L(]{match - | -- unclosed delimiter - | | - | missing open `[` for this delimiter + | - unclosed delimiter LL | (; {` | - - unclosed delimiter | | diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr index 167262dcf06..a028f433172 100644 --- a/tests/ui/symbol-names/basic.legacy.stderr +++ b/tests/ui/symbol-names/basic.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN5basic4main17hc88b9d80a69d119aE) +error: symbol-name(_ZN5basic4main17h1dddcfd03744167fE) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(basic::main::hc88b9d80a69d119a) +error: demangling(basic::main::h1dddcfd03744167f) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr index 4e17bdc4577..14cbd877d9f 100644 --- a/tests/ui/symbol-names/issue-60925.legacy.stderr +++ b/tests/ui/symbol-names/issue-60925.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17hbddb77d6f71afb32E) +error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h4b3099ec5dc5d306E) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::hbddb77d6f71afb32) +error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h4b3099ec5dc5d306) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] diff --git a/tests/ui/struct-ctor-mangling.rs b/tests/ui/symbol-names/struct-constructor-mangling.rs index f32cbb7aaae..ec8791e2154 100644 --- a/tests/ui/struct-ctor-mangling.rs +++ b/tests/ui/symbol-names/struct-constructor-mangling.rs @@ -1,3 +1,5 @@ +//! Test that the symbol mangling of Foo-the-constructor-function versus Foo-the-type do not collide + //@ run-pass fn size_of_val<T>(_: &T) -> usize { @@ -6,8 +8,6 @@ fn size_of_val<T>(_: &T) -> usize { struct Foo(#[allow(dead_code)] i64); -// Test that the (symbol) mangling of `Foo` (the `struct` type) and that of -// `typeof Foo` (the function type of the `struct` constructor) don't collide. fn main() { size_of_val(&Foo(0)); size_of_val(&Foo); diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 910582ae4d9..2049c531abd 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -94,7 +94,7 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } args: [] variant_index: 0 subpatterns: [ @@ -108,7 +108,7 @@ body: did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar) variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 10333377570083945360 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 7908585036048874241 } args: [] variant_index: 0 subpatterns: [] @@ -156,7 +156,7 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } args: [] variant_index: 0 subpatterns: [ @@ -208,7 +208,7 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } args: [] variant_index: 1 subpatterns: [] diff --git a/tests/ui/trait-bounds/duplicate-relaxed-bounds.rs b/tests/ui/trait-bounds/duplicate-relaxed-bounds.rs new file mode 100644 index 00000000000..a1681ddec77 --- /dev/null +++ b/tests/ui/trait-bounds/duplicate-relaxed-bounds.rs @@ -0,0 +1,22 @@ +fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {} +//~^ ERROR duplicate relaxed `Sized` bounds +//~| ERROR duplicate relaxed `Iterator` bounds +//~| ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` + +trait Trait { + // We used to say "type parameter has more than one relaxed default bound" + // even on *associated types* like here. Test that we no longer do that. + type Type: ?Sized + ?Sized; + //~^ ERROR duplicate relaxed `Sized` bounds + //~| ERROR duplicate relaxed `Sized` bounds +} + +// We used to emit an additional error about "multiple relaxed default bounds". +// However, multiple relaxed bounds are actually *fine* if they're distinct. +// Ultimately, we still reject this because `Sized` is +// the only (stable) default trait, so we're fine. +fn not_dupes<T: ?Sized + ?Iterator>() {} +//~^ ERROR bound modifier `?` can only be applied to `Sized` + +fn main() {} diff --git a/tests/ui/trait-bounds/duplicate-relaxed-bounds.stderr b/tests/ui/trait-bounds/duplicate-relaxed-bounds.stderr new file mode 100644 index 00000000000..ccc723fc7a6 --- /dev/null +++ b/tests/ui/trait-bounds/duplicate-relaxed-bounds.stderr @@ -0,0 +1,47 @@ +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/duplicate-relaxed-bounds.rs:1:13 + | +LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {} + | ^^^^^^ ^^^^^^ + +error[E0203]: duplicate relaxed `Iterator` bounds + --> $DIR/duplicate-relaxed-bounds.rs:1:31 + | +LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {} + | ^^^^^^^^^ ^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/duplicate-relaxed-bounds.rs:1:31 + | +LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {} + | ^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/duplicate-relaxed-bounds.rs:1:43 + | +LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {} + | ^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/duplicate-relaxed-bounds.rs:19:26 + | +LL | fn not_dupes<T: ?Sized + ?Iterator>() {} + | ^^^^^^^^^ + +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/duplicate-relaxed-bounds.rs:10:16 + | +LL | type Type: ?Sized + ?Sized; + | ^^^^^^ ^^^^^^ + +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/duplicate-relaxed-bounds.rs:10:16 + | +LL | type Type: ?Sized + ?Sized; + | ^^^^^^ ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0203`. diff --git a/tests/ui/trait-bounds/bad-suggestionf-for-repeated-unsized-bound-127441.rs b/tests/ui/trait-bounds/fix-dyn-sized-fn-param-sugg.rs index e6d7f74880f..1aa36207bc3 100644 --- a/tests/ui/trait-bounds/bad-suggestionf-for-repeated-unsized-bound-127441.rs +++ b/tests/ui/trait-bounds/fix-dyn-sized-fn-param-sugg.rs @@ -1,39 +1,38 @@ -// Regression test for #127441 - -// Tests that we make the correct suggestion -// in case there are more than one `?Sized` -// bounds on a function parameter +// Test that we emit a correct structured suggestions for dynamically sized ("maybe unsized") +// function parameters. +// We used to emit a butchered suggestion if duplicate relaxed `Sized` bounds were present. +// issue: <https://github.com/rust-lang/rust/issues/127441>. use std::fmt::Debug; fn foo1<T: ?Sized>(a: T) {} -//~^ ERROR he size for values of type `T` cannot be known at compilation time +//~^ ERROR the size for values of type `T` cannot be known at compilation time fn foo2<T: ?Sized + ?Sized>(a: T) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~^ ERROR duplicate relaxed `Sized` bounds //~| ERROR the size for values of type `T` cannot be known at compilation time fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported -//~| ERROR he size for values of type `T` cannot be known at compilation time +//~^ ERROR duplicate relaxed `Sized` bounds +//~| ERROR the size for values of type `T` cannot be known at compilation time fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~^ ERROR duplicate relaxed `Sized` bounds //~| ERROR the size for values of type `T` cannot be known at compilation time fn foo5(_: impl ?Sized) {} //~^ ERROR the size for values of type `impl ?Sized` cannot be known at compilation time fn foo6(_: impl ?Sized + ?Sized) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~^ ERROR duplicate relaxed `Sized` bounds //~| ERROR the size for values of type `impl ?Sized + ?Sized` cannot be known at compilation tim fn foo7(_: impl ?Sized + ?Sized + Debug) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~^ ERROR duplicate relaxed `Sized` bounds //~| ERROR the size for values of type `impl ?Sized + ?Sized + Debug` cannot be known at compilation time fn foo8(_: impl ?Sized + Debug + ?Sized ) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported +//~^ ERROR duplicate relaxed `Sized` bounds //~| ERROR the size for values of type `impl ?Sized + Debug + ?Sized` cannot be known at compilation time fn main() {} diff --git a/tests/ui/trait-bounds/bad-suggestionf-for-repeated-unsized-bound-127441.stderr b/tests/ui/trait-bounds/fix-dyn-sized-fn-param-sugg.stderr index 363f52d6df8..7a9c2f043ac 100644 --- a/tests/ui/trait-bounds/bad-suggestionf-for-repeated-unsized-bound-127441.stderr +++ b/tests/ui/trait-bounds/fix-dyn-sized-fn-param-sugg.stderr @@ -1,41 +1,41 @@ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:12:12 +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:11:12 | LL | fn foo2<T: ?Sized + ?Sized>(a: T) {} | ^^^^^^ ^^^^^^ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:16:12 +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:15:12 | LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {} | ^^^^^^ ^^^^^^ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:20:12 +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:19:12 | LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {} | ^^^^^^ ^^^^^^ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:27:17 +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:26:17 | LL | fn foo6(_: impl ?Sized + ?Sized) {} | ^^^^^^ ^^^^^^ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:31:17 +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:30:17 | LL | fn foo7(_: impl ?Sized + ?Sized + Debug) {} | ^^^^^^ ^^^^^^ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:35:17 +error[E0203]: duplicate relaxed `Sized` bounds + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:34:17 | LL | fn foo8(_: impl ?Sized + Debug + ?Sized ) {} | ^^^^^^ ^^^^^^ error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:9:23 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:8:23 | LL | fn foo1<T: ?Sized>(a: T) {} | - ^ doesn't have a size known at compile-time @@ -54,7 +54,7 @@ LL | fn foo1<T: ?Sized>(a: &T) {} | + error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:12:32 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:11:32 | LL | fn foo2<T: ?Sized + ?Sized>(a: T) {} | - ^ doesn't have a size known at compile-time @@ -73,7 +73,7 @@ LL | fn foo2<T: ?Sized + ?Sized>(a: &T) {} | + error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:16:40 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:15:40 | LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {} | - ^ doesn't have a size known at compile-time @@ -92,7 +92,7 @@ LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: &T) {} | + error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:20:41 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:19:41 | LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {} | - ^ doesn't have a size known at compile-time @@ -111,7 +111,7 @@ LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: &T) {} | + error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:24:12 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:23:12 | LL | fn foo5(_: impl ?Sized) {} | ^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | fn foo5(_: &impl ?Sized) {} | + error[E0277]: the size for values of type `impl ?Sized + ?Sized` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:27:12 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:26:12 | LL | fn foo6(_: impl ?Sized + ?Sized) {} | ^^^^^^^^^^^^^^^^^^^^ @@ -151,7 +151,7 @@ LL | fn foo6(_: &impl ?Sized + ?Sized) {} | + error[E0277]: the size for values of type `impl ?Sized + ?Sized + Debug` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:31:12 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:30:12 | LL | fn foo7(_: impl ?Sized + ?Sized + Debug) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -171,7 +171,7 @@ LL | fn foo7(_: &impl ?Sized + ?Sized + Debug) {} | + error[E0277]: the size for values of type `impl ?Sized + Debug + ?Sized` cannot be known at compilation time - --> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:35:12 + --> $DIR/fix-dyn-sized-fn-param-sugg.rs:34:12 | LL | fn foo8(_: impl ?Sized + Debug + ?Sized ) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs index e5abcae5d21..14a26670497 100644 --- a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs @@ -2,6 +2,6 @@ trait Trait {} fn test<T: ?self::<i32>::Trait>() {} //~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args` -//~| ERROR relaxing a default bound only does something for `?Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr index dc55b26c918..bf968b05af0 100644 --- a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr @@ -1,4 +1,4 @@ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/maybe-bound-has-path-args.rs:3:12 | LL | fn test<T: ?self::<i32>::Trait>() {} diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs index 9127c2de16d..e123f18474d 100644 --- a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs @@ -2,11 +2,11 @@ trait HasAssoc { type Assoc; } fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {} -//~^ ERROR relaxing a default bound +//~^ ERROR bound modifier `?` can only be applied to `Sized` trait NoAssoc {} fn noassoc<T: ?NoAssoc<Missing = ()>>() {} -//~^ ERROR relaxing a default bound +//~^ ERROR bound modifier `?` can only be applied to `Sized` //~| ERROR associated type `Missing` not found for `NoAssoc` fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr index 36a1e0ade20..b2ae0584aff 100644 --- a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr @@ -1,10 +1,10 @@ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/maybe-bound-with-assoc.rs:4:16 | LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default +error: bound modifier `?` can only be applied to `Sized` --> $DIR/maybe-bound-with-assoc.rs:8:15 | LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {} diff --git a/tests/ui/trait-bounds/more_maybe_bounds.rs b/tests/ui/trait-bounds/more_maybe_bounds.rs new file mode 100644 index 00000000000..47348b0a0dd --- /dev/null +++ b/tests/ui/trait-bounds/more_maybe_bounds.rs @@ -0,0 +1,29 @@ +// FIXME(more_maybe_bounds): Even under `more_maybe_bounds` / `-Zexperimental-default-bounds`, +// trying to relax non-default bounds should still be an error in all contexts! As you can see +// there are places like supertrait bounds and trait object types where we currently don't perform +// this check. +#![feature(auto_traits, more_maybe_bounds, negative_impls)] + +trait Trait1 {} +auto trait Trait2 {} + +// FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`. +trait Trait3: ?Trait1 {} +trait Trait4 where Self: Trait1 {} + +// FIXME: `?Trait2` should be rejected, `Trait2` isn't marked `#[lang = "default_traitN"]`. +fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {} +fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} +//~^ ERROR bound modifier `?` can only be applied to default traits like `Sized` +//~| ERROR bound modifier `?` can only be applied to default traits like `Sized` +//~| ERROR bound modifier `?` can only be applied to default traits like `Sized` + +struct S; +impl !Trait2 for S {} +impl Trait1 for S {} +impl Trait3 for S {} + +fn main() { + foo(Box::new(S)); + bar(&S); +} diff --git a/tests/ui/trait-bounds/more_maybe_bounds.stderr b/tests/ui/trait-bounds/more_maybe_bounds.stderr new file mode 100644 index 00000000000..09c9fc31165 --- /dev/null +++ b/tests/ui/trait-bounds/more_maybe_bounds.stderr @@ -0,0 +1,20 @@ +error: bound modifier `?` can only be applied to default traits like `Sized` + --> $DIR/more_maybe_bounds.rs:16:20 + | +LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} + | ^^^^^^^ + +error: bound modifier `?` can only be applied to default traits like `Sized` + --> $DIR/more_maybe_bounds.rs:16:30 + | +LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} + | ^^^^^^^ + +error: bound modifier `?` can only be applied to default traits like `Sized` + --> $DIR/more_maybe_bounds.rs:16:40 + | +LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr b/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr index d0dd9502915..010b1584643 100644 --- a/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr +++ b/tests/ui/traits/const-traits/conditionally-const-invalid-places.stderr @@ -72,7 +72,7 @@ error: `[const]` is not allowed here LL | type Type<T: [const] Trait>: [const] Trait; | ^^^^^^^ | -note: associated types in non-`#[const_trait]` traits cannot have `[const]` trait bounds +note: associated types in non-`const` traits cannot have `[const]` trait bounds --> $DIR/conditionally-const-invalid-places.rs:25:5 | LL | type Type<T: [const] Trait>: [const] Trait; @@ -84,7 +84,7 @@ error: `[const]` is not allowed here LL | type Type<T: [const] Trait>: [const] Trait; | ^^^^^^^ | -note: associated types in non-`#[const_trait]` traits cannot have `[const]` trait bounds +note: associated types in non-`const` traits cannot have `[const]` trait bounds --> $DIR/conditionally-const-invalid-places.rs:25:5 | LL | type Type<T: [const] Trait>: [const] Trait; @@ -180,7 +180,7 @@ error: `[const]` is not allowed here LL | trait Child0: [const] Trait {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/conditionally-const-invalid-places.rs:52:1 | LL | trait Child0: [const] Trait {} @@ -192,7 +192,7 @@ error: `[const]` is not allowed here LL | trait Child1 where Self: [const] Trait {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/conditionally-const-invalid-places.rs:53:1 | LL | trait Child1 where Self: [const] Trait {} diff --git a/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs b/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs new file mode 100644 index 00000000000..81acce65f2a --- /dev/null +++ b/tests/ui/traits/const-traits/const-assoc-bound-in-trait-wc.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(const_clone)] +#![feature(const_trait_impl)] + +#[const_trait] +trait A where Self::Target: [const] Clone { + type Target; +} + +const fn foo<T>() where T: [const] A {} + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs index ae31d9ae0ac..baded179201 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs +++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs @@ -4,10 +4,10 @@ trait NonConst {} const fn perform<T: [const] NonConst>() {} -//~^ ERROR `[const]` can only be applied to `#[const_trait]` traits -//~| ERROR `[const]` can only be applied to `#[const_trait]` traits +//~^ ERROR `[const]` can only be applied to `const` traits +//~| ERROR `[const]` can only be applied to `const` traits fn operate<T: const NonConst>() {} -//~^ ERROR `const` can only be applied to `#[const_trait]` traits +//~^ ERROR `const` can only be applied to `const` traits fn main() {} diff --git a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr index 6c68e4ec3ac..304d81bb917 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr +++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr @@ -1,33 +1,33 @@ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const-bounds-non-const-trait.rs:6:21 | LL | const fn perform<T: [const] NonConst>() {} | ^^^^^^^ can't be applied to `NonConst` | -help: mark `NonConst` as `#[const_trait]` to allow it to have `const` implementations +help: mark `NonConst` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait NonConst {} | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/const-bounds-non-const-trait.rs:6:21 | LL | const fn perform<T: [const] NonConst>() {} | ^^^^^^^ can't be applied to `NonConst` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `NonConst` as `#[const_trait]` to allow it to have `const` implementations +help: mark `NonConst` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait NonConst {} | ++++++++++++++ -error: `const` can only be applied to `#[const_trait]` traits +error: `const` can only be applied to `const` traits --> $DIR/const-bounds-non-const-trait.rs:10:15 | LL | fn operate<T: const NonConst>() {} | ^^^^^ can't be applied to `NonConst` | -help: mark `NonConst` as `#[const_trait]` to allow it to have `const` implementations +help: mark `NonConst` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait NonConst {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs index 6bea664b65f..176ae091a41 100644 --- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs @@ -4,6 +4,6 @@ pub trait A {} impl const A for () {} -//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` +//~^ ERROR: const `impl` for trait `A` which is not `const` fn main() {} diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr index c728eda069e..bf73436b78d 100644 --- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr +++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr @@ -1,12 +1,12 @@ -error: const `impl` for trait `A` which is not marked with `#[const_trait]` +error: const `impl` for trait `A` which is not `const` --> $DIR/const-impl-requires-const-trait.rs:6:12 | LL | impl const A for () {} | ^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -help: mark `A` as `#[const_trait]` to allow it to have `const` implementations +help: mark `A` as `const` to allow it to have `const` implementations | LL | #[const_trait] pub trait A {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs index dc960422a4a..da28d9a47c3 100644 --- a/tests/ui/traits/const-traits/const-impl-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-trait.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Znext-solver //@ known-bug: #110395 -// Broken until we have `const PartialEq` impl in stdlib +// Broken until `(): const PartialEq` #![allow(incomplete_features)] #![feature(const_trait_impl, const_cmp, const_destruct)] diff --git a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs index ece87529c3e..658132441c2 100644 --- a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs +++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.rs @@ -1,9 +1,7 @@ #![feature(const_trait_impl)] -// FIXME(const_trait_impl) add effects //@ edition: 2021 -#[const_trait] -trait Trait {} +const trait Trait {} fn main() { let _: &dyn const Trait; //~ ERROR const trait bounds are not allowed in trait object types @@ -14,5 +12,7 @@ fn main() { trait NonConst {} const fn handle(_: &dyn const NonConst) {} //~^ ERROR const trait bounds are not allowed in trait object types +//~| ERROR `const` can only be applied to `const` traits const fn take(_: &dyn [const] NonConst) {} //~^ ERROR `[const]` is not allowed here +//~| ERROR `[const]` can only be applied to `const` traits diff --git a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr index 090555c6377..3ba5da39106 100644 --- a/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr +++ b/tests/ui/traits/const-traits/const-trait-bounds-trait-objects.stderr @@ -1,11 +1,11 @@ error: const trait bounds are not allowed in trait object types - --> $DIR/const-trait-bounds-trait-objects.rs:9:17 + --> $DIR/const-trait-bounds-trait-objects.rs:7:17 | LL | let _: &dyn const Trait; | ^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/const-trait-bounds-trait-objects.rs:10:17 + --> $DIR/const-trait-bounds-trait-objects.rs:8:17 | LL | let _: &dyn [const] Trait; | ^^^^^^^ @@ -13,18 +13,40 @@ LL | let _: &dyn [const] Trait; = note: trait objects cannot have `[const]` trait bounds error: const trait bounds are not allowed in trait object types - --> $DIR/const-trait-bounds-trait-objects.rs:15:25 + --> $DIR/const-trait-bounds-trait-objects.rs:13:25 | LL | const fn handle(_: &dyn const NonConst) {} | ^^^^^^^^^^^^^^ error: `[const]` is not allowed here - --> $DIR/const-trait-bounds-trait-objects.rs:17:23 + --> $DIR/const-trait-bounds-trait-objects.rs:16:23 | LL | const fn take(_: &dyn [const] NonConst) {} | ^^^^^^^ | = note: trait objects cannot have `[const]` trait bounds -error: aborting due to 4 previous errors +error: `const` can only be applied to `const` traits + --> $DIR/const-trait-bounds-trait-objects.rs:13:25 + | +LL | const fn handle(_: &dyn const NonConst) {} + | ^^^^^ can't be applied to `NonConst` + | +help: mark `NonConst` as `const` to allow it to have `const` implementations + | +LL | #[const_trait] trait NonConst {} + | ++++++++++++++ + +error: `[const]` can only be applied to `const` traits + --> $DIR/const-trait-bounds-trait-objects.rs:16:23 + | +LL | const fn take(_: &dyn [const] NonConst) {} + | ^^^^^^^ can't be applied to `NonConst` + | +help: mark `NonConst` as `const` to allow it to have `const` implementations + | +LL | #[const_trait] trait NonConst {} + | ++++++++++++++ + +error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs index 04fea1189ae..c0796907855 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs +++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.rs @@ -1,5 +1,5 @@ #[derive_const(Debug)] //~ ERROR use of unstable library feature -//~^ ERROR const `impl` for trait `Debug` which is not marked with `#[const_trait]` +//~^ ERROR const `impl` for trait `Debug` which is not `const` //~| ERROR cannot call non-const method pub struct S; diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr index 5bde358001c..cbc62d602a4 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr @@ -4,16 +4,17 @@ error[E0658]: use of unstable library feature `derive_const` LL | #[derive_const(Debug)] | ^^^^^^^^^^^^ | + = note: see issue #118304 <https://github.com/rust-lang/rust/issues/118304> for more information = help: add `#![feature(derive_const)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: const `impl` for trait `Debug` which is not marked with `#[const_trait]` +error: const `impl` for trait `Debug` which is not `const` --> $DIR/derive-const-gate.rs:1:16 | LL | #[derive_const(Debug)] | ^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0015]: cannot call non-const method `Formatter::<'_>::write_str` in constant functions diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr index c0bd360ebe5..93638801895 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr @@ -1,10 +1,10 @@ -error: const `impl` for trait `Debug` which is not marked with `#[const_trait]` +error: const `impl` for trait `Debug` which is not `const` --> $DIR/derive-const-non-const-type.rs:12:16 | LL | #[derive_const(Debug)] | ^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_finish` in constant functions diff --git a/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs index e53b87274d3..47c85980aca 100644 --- a/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs +++ b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.rs @@ -4,7 +4,7 @@ use std::ops::FromResidual; impl<T> const FromResidual for T { - //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + //~^ ERROR const `impl` for trait `FromResidual` which is not `const` //~| ERROR type parameter `T` must be used as the type parameter for some local type fn from_residual(t: T) -> _ { //~^ ERROR the placeholder `_` is not allowed diff --git a/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr index a165ef12060..5c5fba95f02 100644 --- a/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr +++ b/tests/ui/traits/const-traits/ice-119717-constant-lifetime.stderr @@ -1,10 +1,10 @@ -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +error: const `impl` for trait `FromResidual` which is not `const` --> $DIR/ice-119717-constant-lifetime.rs:6:15 | LL | impl<T> const FromResidual for T { | ^^^^^^^^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) diff --git a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs index 3473be565c1..5e368b9e6a9 100644 --- a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs +++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.rs @@ -6,11 +6,11 @@ struct TryMe; struct Error; impl const FromResidual<Error> for TryMe {} -//~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +//~^ ERROR const `impl` for trait `FromResidual` which is not `const` //~| ERROR not all trait items implemented impl const Try for TryMe { - //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]` + //~^ ERROR const `impl` for trait `Try` which is not `const` //~| ERROR not all trait items implemented type Output = (); type Residual = Error; diff --git a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr index 41f99c2d375..849d6522cd6 100644 --- a/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr +++ b/tests/ui/traits/const-traits/ice-126148-failed-to-normalize.stderr @@ -1,10 +1,10 @@ -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +error: const `impl` for trait `FromResidual` which is not `const` --> $DIR/ice-126148-failed-to-normalize.rs:8:12 | LL | impl const FromResidual<Error> for TryMe {} | ^^^^^^^^^^^^^^^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0046]: not all trait items implemented, missing: `from_residual` @@ -15,13 +15,13 @@ LL | impl const FromResidual<Error> for TryMe {} | = help: implement the missing item: `fn from_residual(_: Error) -> Self { todo!() }` -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` +error: const `impl` for trait `Try` which is not `const` --> $DIR/ice-126148-failed-to-normalize.rs:12:12 | LL | impl const Try for TryMe { | ^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0046]: not all trait items implemented, missing: `from_output`, `branch` diff --git a/tests/ui/traits/const-traits/imply-always-const.rs b/tests/ui/traits/const-traits/imply-always-const.rs new file mode 100644 index 00000000000..f6cab0681ec --- /dev/null +++ b/tests/ui/traits/const-traits/imply-always-const.rs @@ -0,0 +1,19 @@ +//@ check-pass + +#![feature(const_trait_impl)] + +#[const_trait] +trait A where Self::Assoc: const B { + type Assoc; +} + +#[const_trait] +trait B {} + +fn needs_b<T: const B>() {} + +fn test<T: A>() { + needs_b::<T::Assoc>(); +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr b/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr deleted file mode 100644 index 89e59e5db6e..00000000000 --- a/tests/ui/traits/const-traits/match-non-const-eq.gated.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0015]: cannot match on `str` in constant functions - --> $DIR/match-non-const-eq.rs:7:9 - | -LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts - | ^^^ - | - = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/match-non-const-eq.rs b/tests/ui/traits/const-traits/match-non-const-eq.rs index 73f8af86bd0..03adb8dc5a4 100644 --- a/tests/ui/traits/const-traits/match-non-const-eq.rs +++ b/tests/ui/traits/const-traits/match-non-const-eq.rs @@ -1,11 +1,12 @@ -//@ known-bug: #110395 //@ revisions: stock gated -#![cfg_attr(gated, feature(const_trait_impl))] +#![cfg_attr(gated, feature(const_trait_impl, const_cmp))] +//@[gated] check-pass const fn foo(input: &'static str) { match input { - "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts - //FIXME ~^ ERROR cannot match on `str` in constant functions + "a" => (), + //[stock]~^ ERROR cannot match on `str` in constant functions + //[stock]~| ERROR `PartialEq` is not yet stable as a const trait _ => (), } } diff --git a/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr b/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr index 89e59e5db6e..5b662447bde 100644 --- a/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr +++ b/tests/ui/traits/const-traits/match-non-const-eq.stock.stderr @@ -1,12 +1,26 @@ -error[E0015]: cannot match on `str` in constant functions +error[E0658]: cannot match on `str` in constant functions --> $DIR/match-non-const-eq.rs:7:9 | -LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts +LL | "a" => (), | ^^^ | = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error: `PartialEq` is not yet stable as a const trait + --> $DIR/match-non-const-eq.rs:7:9 + | +LL | "a" => (), + | ^^^ + | +help: add `#![feature(const_cmp)]` to the crate attributes to enable + | +LL + #![feature(const_cmp)] + | + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs index 5f47778a140..8d1d3a4c790 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs @@ -2,9 +2,12 @@ const fn maybe_const_maybe<T: [const] ?Sized>() {} //~^ ERROR `[const]` trait not allowed with `?` trait polarity modifier +//~| ERROR `[const]` can only be applied to `const` traits +//~| ERROR `[const]` can only be applied to `const` traits fn const_maybe<T: const ?Sized>() {} //~^ ERROR `const` trait not allowed with `?` trait polarity modifier +//~| ERROR `const` can only be applied to `const` traits const fn maybe_const_negative<T: [const] !Trait>() {} //~^ ERROR `[const]` trait not allowed with `!` trait polarity modifier diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr index 429131f905f..0ac40c51270 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr @@ -7,7 +7,7 @@ LL | const fn maybe_const_maybe<T: [const] ?Sized>() {} | there is not a well-defined meaning for a `[const] ?` trait error: `const` trait not allowed with `?` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:25 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:8:25 | LL | fn const_maybe<T: const ?Sized>() {} | ----- ^ @@ -15,7 +15,7 @@ LL | fn const_maybe<T: const ?Sized>() {} | there is not a well-defined meaning for a `const ?` trait error: `[const]` trait not allowed with `!` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:42 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:12:42 | LL | const fn maybe_const_negative<T: [const] !Trait>() {} | ------- ^ @@ -23,7 +23,7 @@ LL | const fn maybe_const_negative<T: [const] !Trait>() {} | there is not a well-defined meaning for a `[const] !` trait error: `const` trait not allowed with `!` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:16:28 | LL | fn const_negative<T: const !Trait>() {} | ----- ^ @@ -31,16 +31,44 @@ LL | fn const_negative<T: const !Trait>() {} | there is not a well-defined meaning for a `const !` trait error: negative bounds are not supported - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:42 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:12:42 | LL | const fn maybe_const_negative<T: [const] !Trait>() {} | ^ error: negative bounds are not supported - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:16:28 | LL | fn const_negative<T: const !Trait>() {} | ^ -error: aborting due to 6 previous errors +error: `[const]` can only be applied to `const` traits + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:31 + | +LL | const fn maybe_const_maybe<T: [const] ?Sized>() {} + | ^^^^^^^ can't be applied to `Sized` + | +note: `Sized` can't be used with `[const]` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + +error: `[const]` can only be applied to `const` traits + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:31 + | +LL | const fn maybe_const_maybe<T: [const] ?Sized>() {} + | ^^^^^^^ can't be applied to `Sized` + | +note: `Sized` can't be used with `[const]` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `const` can only be applied to `const` traits + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:8:19 + | +LL | fn const_maybe<T: const ?Sized>() {} + | ^^^^^ can't be applied to `Sized` + | +note: `Sized` can't be used with `const` because it isn't `const` + --> $SRC_DIR/core/src/marker.rs:LL:COL + +error: aborting due to 9 previous errors diff --git a/tests/ui/traits/const-traits/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/spec-effectvar-ice.rs index c85b1746967..46f71b114a3 100644 --- a/tests/ui/traits/const-traits/spec-effectvar-ice.rs +++ b/tests/ui/traits/const-traits/spec-effectvar-ice.rs @@ -8,11 +8,11 @@ trait Specialize {} trait Foo {} impl<T> const Foo for T {} -//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +//~^ error: const `impl` for trait `Foo` which is not `const` impl<T> const Foo for T where T: const Specialize {} -//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` -//~| error: `const` can only be applied to `#[const_trait]` traits +//~^ error: const `impl` for trait `Foo` which is not `const` +//~| error: `const` can only be applied to `const` traits //~| error: specialization impl does not specialize any associated items //~| error: cannot specialize on trait `Specialize` diff --git a/tests/ui/traits/const-traits/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/spec-effectvar-ice.stderr index 474d96698d5..ef5e58e1c3d 100644 --- a/tests/ui/traits/const-traits/spec-effectvar-ice.stderr +++ b/tests/ui/traits/const-traits/spec-effectvar-ice.stderr @@ -1,36 +1,36 @@ -error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +error: const `impl` for trait `Foo` which is not `const` --> $DIR/spec-effectvar-ice.rs:10:15 | LL | impl<T> const Foo for T {} | ^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo {} | ++++++++++++++ -error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +error: const `impl` for trait `Foo` which is not `const` --> $DIR/spec-effectvar-ice.rs:13:15 | LL | impl<T> const Foo for T where T: const Specialize {} | ^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo {} | ++++++++++++++ -error: `const` can only be applied to `#[const_trait]` traits +error: `const` can only be applied to `const` traits --> $DIR/spec-effectvar-ice.rs:13:34 | LL | impl<T> const Foo for T where T: const Specialize {} | ^^^^^ can't be applied to `Specialize` | -help: mark `Specialize` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Specialize` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Specialize {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr index 19f072b289e..0ecbad64bc8 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.nn.stderr @@ -4,43 +4,43 @@ error: `[const]` is not allowed here LL | trait Bar: [const] Foo {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/super-traits-fail-2.rs:11:1 | LL | trait Bar: [const] Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index 4921f78d3ac..0e5b697d1dd 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr @@ -1,58 +1,58 @@ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-2.rs:11:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.rs b/tests/ui/traits/const-traits/super-traits-fail-2.rs index 781dacb81a1..36e7c1c4e4a 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-2.rs @@ -9,11 +9,11 @@ trait Foo { #[cfg_attr(any(yy, ny), const_trait)] trait Bar: [const] Foo {} -//[ny,nn]~^ ERROR: `[const]` can only be applied to `#[const_trait]` -//[ny,nn]~| ERROR: `[const]` can only be applied to `#[const_trait]` -//[ny,nn]~| ERROR: `[const]` can only be applied to `#[const_trait]` -//[ny]~| ERROR: `[const]` can only be applied to `#[const_trait]` -//[ny]~| ERROR: `[const]` can only be applied to `#[const_trait]` +//[ny,nn]~^ ERROR: `[const]` can only be applied to `const` traits +//[ny,nn]~| ERROR: `[const]` can only be applied to `const` traits +//[ny,nn]~| ERROR: `[const]` can only be applied to `const` traits +//[ny]~| ERROR: `[const]` can only be applied to `const` traits +//[ny]~| ERROR: `[const]` can only be applied to `const` traits //[yn,nn]~^^^^^^ ERROR: `[const]` is not allowed here const fn foo<T: Bar>(x: &T) { diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr index a151349822e..657e8ee82e3 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr @@ -4,7 +4,7 @@ error: `[const]` is not allowed here LL | trait Bar: [const] Foo {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/super-traits-fail-2.rs:11:1 | LL | trait Bar: [const] Foo {} diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr index 3f48375dd04..a0ae60526ef 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nnn.stderr @@ -4,7 +4,7 @@ error: `[const]` is not allowed here LL | trait Bar: [const] Foo {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/super-traits-fail-3.rs:23:1 | LL | trait Bar: [const] Foo {} @@ -30,60 +30,60 @@ LL | const fn foo<T: [const] Bar>(x: &T) { = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr index 3f48375dd04..a0ae60526ef 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nny.stderr @@ -4,7 +4,7 @@ error: `[const]` is not allowed here LL | trait Bar: [const] Foo {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/super-traits-fail-3.rs:23:1 | LL | trait Bar: [const] Foo {} @@ -30,60 +30,60 @@ LL | const fn foo<T: [const] Bar>(x: &T) { = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: enable `#![feature(const_trait_impl)]` in your crate and mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs index 5370f607dec..d74bd346784 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs @@ -21,17 +21,17 @@ trait Foo { #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)] //[nyy,nyn]~^ ERROR: `const_trait` is a temporary placeholder for marking a trait that is suitable for `const` `impls` and all default bodies as `const`, which may be removed or renamed in the future trait Bar: [const] Foo {} -//[yny,ynn,nny,nnn]~^ ERROR: `[const]` can only be applied to `#[const_trait]` -//[yny,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `#[const_trait]` -//[yny,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `#[const_trait]` -//[yny]~^^^^ ERROR: `[const]` can only be applied to `#[const_trait]` -//[yny]~| ERROR: `[const]` can only be applied to `#[const_trait]` +//[yny,ynn,nny,nnn]~^ ERROR: `[const]` can only be applied to `const` traits +//[yny,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `const` traits +//[yny,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `const` traits +//[yny]~^^^^ ERROR: `[const]` can only be applied to `const` traits +//[yny]~| ERROR: `[const]` can only be applied to `const` traits //[yyn,ynn,nny,nnn]~^^^^^^ ERROR: `[const]` is not allowed here //[nyy,nyn,nny,nnn]~^^^^^^^ ERROR: const trait impls are experimental const fn foo<T: [const] Bar>(x: &T) { - //[yyn,ynn,nny,nnn]~^ ERROR: `[const]` can only be applied to `#[const_trait]` - //[yyn,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `#[const_trait]` + //[yyn,ynn,nny,nnn]~^ ERROR: `[const]` can only be applied to `const` traits + //[yyn,ynn,nny,nnn]~| ERROR: `[const]` can only be applied to `const` traits //[nyy,nyn,nny,nnn]~^^^ ERROR: const trait impls are experimental x.a(); //[yyn]~^ ERROR: the trait bound `T: [const] Foo` is not satisfied diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr index 89e090b7d1c..c8ec77c2f09 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.ynn.stderr @@ -4,66 +4,66 @@ error: `[const]` is not allowed here LL | trait Bar: [const] Foo {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/super-traits-fail-3.rs:23:1 | LL | trait Bar: [const] Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | -help: mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr index 683eeb73850..a820239cde0 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yny.stderr @@ -1,58 +1,58 @@ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:23:12 | LL | trait Bar: [const] Foo {} | ^^^^^^^ can't be applied to `Foo` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Foo` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Foo` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Foo { | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr index 39cfdfe2030..de3664dae84 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yyn.stderr @@ -4,31 +4,31 @@ error: `[const]` is not allowed here LL | trait Bar: [const] Foo {} | ^^^^^^^ | -note: this trait is not a `#[const_trait]`, so it cannot have `[const]` trait bounds +note: this trait is not `const`, so it cannot have `[const]` trait bounds --> $DIR/super-traits-fail-3.rs:23:1 | LL | trait Bar: [const] Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | -help: mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ -error: `[const]` can only be applied to `#[const_trait]` traits +error: `[const]` can only be applied to `const` traits --> $DIR/super-traits-fail-3.rs:32:17 | LL | const fn foo<T: [const] Bar>(x: &T) { | ^^^^^^^ can't be applied to `Bar` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: mark `Bar` as `#[const_trait]` to allow it to have `const` implementations +help: mark `Bar` as `const` to allow it to have `const` implementations | LL | #[const_trait] trait Bar: [const] Foo {} | ++++++++++++++ diff --git a/tests/ui/traits/const-traits/trait-default-body-stability.stderr b/tests/ui/traits/const-traits/trait-default-body-stability.stderr index a13d9a1e075..b995d6f4f3d 100644 --- a/tests/ui/traits/const-traits/trait-default-body-stability.stderr +++ b/tests/ui/traits/const-traits/trait-default-body-stability.stderr @@ -1,19 +1,19 @@ -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` +error: const `impl` for trait `Try` which is not `const` --> $DIR/trait-default-body-stability.rs:19:12 | LL | impl const Try for T { | ^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +error: const `impl` for trait `FromResidual` which is not `const` --> $DIR/trait-default-body-stability.rs:34:12 | LL | impl const FromResidual for T { | ^^^^^^^^^^^^ this trait is not `const` | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: marking a trait with `const` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change error[E0015]: `?` is not allowed on `T` in constant functions diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs index 5069cd256b2..e7cca41a47e 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.rs @@ -64,4 +64,8 @@ fn main() { x.leak_foo(); //~^ ERROR the trait bound `dyn Trait: Leak` is not satisfied x.maybe_leak_foo(); + // Ensure that we validate the generic args of relaxed bounds in trait object types. + let _: dyn Trait + ?Leak<(), Undefined = ()>; + //~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR associated type `Undefined` not found for `Leak` } diff --git a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr index 48745e40268..350233b7cbe 100644 --- a/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr +++ b/tests/ui/traits/default_auto_traits/maybe-bounds-in-dyn-traits.stderr @@ -18,6 +18,27 @@ note: required by a bound in `Trait::leak_foo` LL | fn leak_foo(&self) {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo` -error: aborting due to 2 previous errors +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/maybe-bounds-in-dyn-traits.rs:68:25 + | +LL | let _: dyn Trait + ?Leak<(), Undefined = ()>; + | ^^^^-------------------- help: remove the unnecessary generics + | | + | expected 0 generic arguments + | +note: trait defined here, with 0 generic parameters + --> $DIR/maybe-bounds-in-dyn-traits.rs:44:12 + | +LL | auto trait Leak {} + | ^^^^ + +error[E0220]: associated type `Undefined` not found for `Leak` + --> $DIR/maybe-bounds-in-dyn-traits.rs:68:34 + | +LL | let _: dyn Trait + ?Leak<(), Undefined = ()>; + | ^^^^^^^^^ associated type `Undefined` not found + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0107, E0220, E0277. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/maybe-polarity-pass.rs b/tests/ui/traits/maybe-polarity-pass.rs deleted file mode 100644 index 1ccd52bc169..00000000000 --- a/tests/ui/traits/maybe-polarity-pass.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![feature(auto_traits)] -#![feature(more_maybe_bounds)] -#![feature(negative_impls)] - -trait Trait1 {} -auto trait Trait2 {} - -trait Trait3 : ?Trait1 {} -trait Trait4 where Self: Trait1 {} - -fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {} -fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} -//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - -struct S; -impl !Trait2 for S {} -impl Trait1 for S {} -impl Trait3 for S {} - -fn main() { - foo(Box::new(S)); - bar(&S); -} diff --git a/tests/ui/traits/maybe-polarity-pass.stderr b/tests/ui/traits/maybe-polarity-pass.stderr deleted file mode 100644 index 1f378dd665a..00000000000 --- a/tests/ui/traits/maybe-polarity-pass.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-polarity-pass.rs:12:20 - | -LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} - | ^^^^^^^ - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-polarity-pass.rs:12:30 - | -LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} - | ^^^^^^^ - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-polarity-pass.rs:12:40 - | -LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} - | ^^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/traits/maybe-polarity-repeated.rs b/tests/ui/traits/maybe-polarity-repeated.rs deleted file mode 100644 index fd1ef567b3e..00000000000 --- a/tests/ui/traits/maybe-polarity-repeated.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![feature(more_maybe_bounds)] - -trait Trait {} -fn foo<T: ?Trait + ?Trait>(_: T) {} -//~^ ERROR type parameter has more than one relaxed default bound, only one is supported -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default -//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - -fn main() {} diff --git a/tests/ui/traits/maybe-polarity-repeated.stderr b/tests/ui/traits/maybe-polarity-repeated.stderr deleted file mode 100644 index 4fa1dc45bda..00000000000 --- a/tests/ui/traits/maybe-polarity-repeated.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/maybe-polarity-repeated.rs:4:11 - | -LL | fn foo<T: ?Trait + ?Trait>(_: T) {} - | ^^^^^^ ^^^^^^ - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-polarity-repeated.rs:4:11 - | -LL | fn foo<T: ?Trait + ?Trait>(_: T) {} - | ^^^^^^ - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-polarity-repeated.rs:4:20 - | -LL | fn foo<T: ?Trait + ?Trait>(_: T) {} - | ^^^^^^ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0203`. diff --git a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs deleted file mode 100644 index 04963c98765..00000000000 --- a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Test that ?Trait bounds are forbidden in supertraits and trait object types. -//! -//! While `?Sized` and other maybe bounds are allowed in type parameter bounds and where clauses, -//! they are explicitly forbidden in certain syntactic positions: -//! - As supertraits in trait definitions -//! - In trait object type expressions -//! -//! See https://github.com/rust-lang/rust/issues/20503 - -trait Tr: ?Sized {} -//~^ ERROR `?Trait` is not permitted in supertraits - -type A1 = dyn Tr + (?Sized); -//~^ ERROR `?Trait` is not permitted in trait object types -type A2 = dyn for<'a> Tr + (?Sized); -//~^ ERROR `?Trait` is not permitted in trait object types - -fn main() {} diff --git a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr b/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr deleted file mode 100644 index bd0baa580bd..00000000000 --- a/tests/ui/traits/maybe-trait-bounds-forbidden-locations.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0658]: `?Trait` is not permitted in supertraits - --> $DIR/maybe-trait-bounds-forbidden-locations.rs:10:11 - | -LL | trait Tr: ?Sized {} - | ^^^^^^ - | - = note: traits are `?Sized` by default - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-trait-bounds-forbidden-locations.rs:13:20 - | -LL | type A1 = dyn Tr + (?Sized); - | ^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-trait-bounds-forbidden-locations.rs:15:28 - | -LL | type A2 = dyn for<'a> Tr + (?Sized); - | ^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr index 1eb445f4848..8901805a20f 100644 --- a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr @@ -12,13 +12,6 @@ LL | impl<T: Bound, U> Trait<U> for T { | ----- ^^^^^^^^ ^ | | | unsatisfied trait bound introduced here -note: required by a bound in `Bound` - --> $DIR/normalizes-to-is-not-productive.rs:8:1 - | -LL | / trait Bound { -LL | | fn method(); -LL | | } - | |_^ required by this bound in `Bound` error[E0277]: the trait bound `Foo: Bound` is not satisfied --> $DIR/normalizes-to-is-not-productive.rs:47:19 diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index 8d8909625ff..d179c805962 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -19,23 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>` LL | Self::Assoc: A<T>, | ^^^^ -error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: MetaSized` - --> $DIR/normalize-param-env-2.rs:24:22 - | -LL | Self::Assoc: A<T>, - | ^^^^ - | -note: required by a bound in `A` - --> $DIR/normalize-param-env-2.rs:9:1 - | -LL | / trait A<T> { -LL | | type Assoc; -LL | | -LL | | fn f() -... | -LL | | } - | |_^ required by this bound in `A` - error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed` --> $DIR/normalize-param-env-2.rs:24:22 | @@ -63,6 +46,6 @@ LL | where LL | Self::Assoc: A<T>, | ^^^^ required by this bound in `A::f` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index 9f7f74f9466..f5fd9ce9864 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -4,20 +4,6 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait` LL | <T as Trait>::Assoc: Trait, | ^^^^^ -error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: MetaSized` - --> $DIR/normalize-param-env-4.rs:19:26 - | -LL | <T as Trait>::Assoc: Trait, - | ^^^^^ - | -note: required by a bound in `Trait` - --> $DIR/normalize-param-env-4.rs:7:1 - | -LL | / trait Trait { -LL | | type Assoc; -LL | | } - | |_^ required by this bound in `Trait` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index 50d1a874551..87f9c241e40 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -15,7 +15,6 @@ use foo::*; fn test() -> impl Sized { <() as Callable>::call() -//~^ ERROR: type annotations needed } fn main() {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index 13fbfdb855c..e8e569ba625 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -4,13 +4,6 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self LL | impl<V: ?Sized> Callable for () { | ^ unconstrained type parameter -error[E0282]: type annotations needed - --> $DIR/resolve-impl-before-constrain-check.rs:17:6 - | -LL | <() as Callable>::call() - | ^^ cannot infer type for type parameter `V` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0282. -For more information about an error, try `rustc --explain E0207`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/wf-object/maybe-bound.rs b/tests/ui/traits/wf-object/maybe-bound.rs deleted file mode 100644 index 17771e976ef..00000000000 --- a/tests/ui/traits/wf-object/maybe-bound.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects). - -trait Foo {} - -type _0 = dyn ?Sized + Foo; -//~^ ERROR `?Trait` is not permitted in trait object types - -type _1 = dyn Foo + ?Sized; -//~^ ERROR `?Trait` is not permitted in trait object types - -type _2 = dyn Foo + ?Sized + ?Sized; -//~^ ERROR `?Trait` is not permitted in trait object types -//~| ERROR `?Trait` is not permitted in trait object types - -type _3 = dyn ?Sized + Foo; -//~^ ERROR `?Trait` is not permitted in trait object types - -fn main() {} diff --git a/tests/ui/traits/wf-object/maybe-bound.stderr b/tests/ui/traits/wf-object/maybe-bound.stderr deleted file mode 100644 index be7afabd0d0..00000000000 --- a/tests/ui/traits/wf-object/maybe-bound.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:5:15 - | -LL | type _0 = dyn ?Sized + Foo; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:8:21 - | -LL | type _1 = dyn Foo + ?Sized; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:11:21 - | -LL | type _2 = dyn Foo + ?Sized + ?Sized; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:11:30 - | -LL | type _2 = dyn Foo + ?Sized + ?Sized; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` is not permitted in trait object types - --> $DIR/maybe-bound.rs:15:15 - | -LL | type _3 = dyn ?Sized + Foo; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/wf-object/only-maybe-bound.rs b/tests/ui/traits/wf-object/only-maybe-bound.rs index 3e6db3e997c..96360e0331c 100644 --- a/tests/ui/traits/wf-object/only-maybe-bound.rs +++ b/tests/ui/traits/wf-object/only-maybe-bound.rs @@ -2,6 +2,6 @@ type _0 = dyn ?Sized; //~^ ERROR at least one trait is required for an object type [E0224] -//~| ERROR ?Trait` is not permitted in trait object types +//~| ERROR relaxed bounds are not permitted in trait object types fn main() {} diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr index 26269476eaa..6ae4568c699 100644 --- a/tests/ui/traits/wf-object/only-maybe-bound.stderr +++ b/tests/ui/traits/wf-object/only-maybe-bound.stderr @@ -1,11 +1,8 @@ -error[E0658]: `?Trait` is not permitted in trait object types +error: relaxed bounds are not permitted in trait object types --> $DIR/only-maybe-bound.rs:3:15 | LL | type _0 = dyn ?Sized; | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0224]: at least one trait is required for an object type --> $DIR/only-maybe-bound.rs:3:11 @@ -15,5 +12,4 @@ LL | type _0 = dyn ?Sized; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0224, E0658. -For more information about an error, try `rustc --explain E0224`. +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/type/pattern_types/validity.rs b/tests/ui/type/pattern_types/validity.rs index a4e49692c98..432aacb9be3 100644 --- a/tests/ui/type/pattern_types/validity.rs +++ b/tests/ui/type/pattern_types/validity.rs @@ -11,7 +11,7 @@ const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) }; //~^ ERROR: constructing invalid value: encountered 0 const BAD_UNINIT: pattern_type!(u32 is 1..) = - //~^ ERROR: using uninitialized data, but this operation requires initialized memory + //~^ ERROR: this operation requires initialized memory unsafe { std::mem::transmute(std::mem::MaybeUninit::<u32>::uninit()) }; const BAD_PTR: pattern_type!(usize is 1..) = unsafe { std::mem::transmute(&42) }; @@ -27,7 +27,7 @@ const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) })); //~^ ERROR: constructing invalid value at .0.0: encountered 0 const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') = - //~^ ERROR: using uninitialized data, but this operation requires initialized memory + //~^ ERROR: this operation requires initialized memory unsafe { std::mem::transmute(std::mem::MaybeUninit::<u32>::uninit()) }; const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') }; diff --git a/tests/ui/type/pattern_types/validity.stderr b/tests/ui/type/pattern_types/validity.stderr index 4f4c16028f6..b545cd75ddb 100644 --- a/tests/ui/type/pattern_types/validity.stderr +++ b/tests/ui/type/pattern_types/validity.stderr @@ -9,11 +9,15 @@ LL | const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) }; HEX_DUMP } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x0..0x4], and this operation requires initialized memory --> $DIR/validity.rs:13:1 | LL | const BAD_UNINIT: pattern_type!(u32 is 1..) = | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `BAD_UNINIT` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ â–‘â–‘â–‘â–‘ + } error[E0080]: unable to turn pointer into integer --> $DIR/validity.rs:17:1 @@ -46,11 +50,15 @@ LL | const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) })); HEX_DUMP } -error[E0080]: using uninitialized data, but this operation requires initialized memory +error[E0080]: reading memory at ALLOC1[0x0..0x4], but memory is uninitialized at [0x0..0x4], and this operation requires initialized memory --> $DIR/validity.rs:29:1 | LL | const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') = | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `CHAR_UNINIT` failed here + | + = note: the raw bytes of the constant (size: 4, align: 4) { + __ __ __ __ │ â–‘â–‘â–‘â–‘ + } error[E0080]: constructing invalid value: encountered 97, but expected something in the range 65..=89 --> $DIR/validity.rs:33:1 diff --git a/tests/ui/typeck/issue-91334.stderr b/tests/ui/typeck/issue-91334.stderr index 01e34919ce6..a348e1ebf7e 100644 --- a/tests/ui/typeck/issue-91334.stderr +++ b/tests/ui/typeck/issue-91334.stderr @@ -11,9 +11,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-91334.rs:7:23 | LL | fn f(){||yield(((){), - | - - - ^ - | | | | - | | | missing open `(` for this delimiter + | - - ^ + | | | | | unclosed delimiter | unclosed delimiter diff --git a/tests/ui/underscore-lifetime/raw-underscore-lifetime.rs b/tests/ui/underscore-lifetime/raw-underscore-lifetime.rs new file mode 100644 index 00000000000..874b3d2c48d --- /dev/null +++ b/tests/ui/underscore-lifetime/raw-underscore-lifetime.rs @@ -0,0 +1,9 @@ +// This test is to ensure that the raw underscore lifetime won't emit two duplicate errors. +// See issue #143152 + +//@ edition: 2021 + +fn f<'r#_>(){} +//~^ ERROR `_` cannot be a raw lifetime + +fn main() {} diff --git a/tests/ui/underscore-lifetime/raw-underscore-lifetime.stderr b/tests/ui/underscore-lifetime/raw-underscore-lifetime.stderr new file mode 100644 index 00000000000..bdb357a47f4 --- /dev/null +++ b/tests/ui/underscore-lifetime/raw-underscore-lifetime.stderr @@ -0,0 +1,8 @@ +error: `_` cannot be a raw lifetime + --> $DIR/raw-underscore-lifetime.rs:6:6 + | +LL | fn f<'r#_>(){} + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/unsized/maybe-bounds-where.rs b/tests/ui/unsized/maybe-bounds-where.rs deleted file mode 100644 index 4c4141631a7..00000000000 --- a/tests/ui/unsized/maybe-bounds-where.rs +++ /dev/null @@ -1,28 +0,0 @@ -struct S1<T>(T) where (T): ?Sized; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared - -struct S2<T>(T) where u8: ?Sized; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared - -struct S3<T>(T) where &'static T: ?Sized; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared - -trait Trait<'a> {} - -struct S4<T>(T) where for<'a> T: ?Trait<'a>; -//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared -//~| ERROR relaxing a default bound only does something for `?Sized` - -struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; -//~^ ERROR type parameter has more than one relaxed default bound -//~| ERROR relaxing a default bound only does something for `?Sized` - -impl<T> S1<T> { - fn f() where T: ?Sized {} - //~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared -} - -fn main() { - let u = vec![1, 2, 3]; - let _s: S5<[u8]> = S5(&u[..]); // OK -} diff --git a/tests/ui/unsized/maybe-bounds-where.stderr b/tests/ui/unsized/maybe-bounds-where.stderr deleted file mode 100644 index fb6d37c2966..00000000000 --- a/tests/ui/unsized/maybe-bounds-where.stderr +++ /dev/null @@ -1,70 +0,0 @@ -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/maybe-bounds-where.rs:1:28 - | -LL | struct S1<T>(T) where (T): ?Sized; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/maybe-bounds-where.rs:4:27 - | -LL | struct S2<T>(T) where u8: ?Sized; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/maybe-bounds-where.rs:7:35 - | -LL | struct S3<T>(T) where &'static T: ?Sized; - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/maybe-bounds-where.rs:12:34 - | -LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>; - | ^^^^^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared - --> $DIR/maybe-bounds-where.rs:21:21 - | -LL | fn f() where T: ?Sized {} - | ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-bounds-where.rs:12:34 - | -LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>; - | ^^^^^^^^^^ - -error[E0203]: type parameter has more than one relaxed default bound, only one is supported - --> $DIR/maybe-bounds-where.rs:16:33 - | -LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; - | ^^^^^^^^^^^^^^^ ^^^^^^ - | - = help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/maybe-bounds-where.rs:16:33 - | -LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; - | ^^^^^^^^^^^^^^^ - -error: aborting due to 8 previous errors - -Some errors have detailed explanations: E0203, E0658. -For more information about an error, try `rustc --explain E0203`. diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.rs b/tests/ui/unsized/relaxed-bounds-invalid-places.rs new file mode 100644 index 00000000000..b8eda1e7786 --- /dev/null +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.rs @@ -0,0 +1,34 @@ +// Test various places where relaxed bounds are not permitted. +// +// Relaxed bounds are only permitted inside impl-Trait, assoc ty item bounds and +// on type params defined by the closest item. + +struct S1<T>(T) where (T): ?Sized; //~ ERROR this relaxed bound is not permitted here + +struct S2<T>(T) where u8: ?Sized; //~ ERROR this relaxed bound is not permitted here + +struct S3<T>(T) where &'static T: ?Sized; //~ ERROR this relaxed bound is not permitted here + +trait Trait<'a> {} + +struct S4<T>(T) where for<'a> T: ?Trait<'a>; +//~^ ERROR this relaxed bound is not permitted here +//~| ERROR bound modifier `?` can only be applied to `Sized` + +struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; +//~^ ERROR bound modifier `?` can only be applied to `Sized` + +impl<T> S1<T> { + fn f() where T: ?Sized {} //~ ERROR this relaxed bound is not permitted here +} + +trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bounds + +// Test that relaxed `Sized` bounds are rejected in trait object types: + +type O1 = dyn Tr + ?Sized; //~ ERROR relaxed bounds are not permitted in trait object types +type O2 = dyn ?Sized + ?Sized + Tr; +//~^ ERROR relaxed bounds are not permitted in trait object types +//~| ERROR relaxed bounds are not permitted in trait object types + +fn main() {} diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr new file mode 100644 index 00000000000..30285d62693 --- /dev/null +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr @@ -0,0 +1,80 @@ +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:6:28 + | +LL | struct S1<T>(T) where (T): ?Sized; + | ^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:8:27 + | +LL | struct S2<T>(T) where u8: ?Sized; + | ^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:10:35 + | +LL | struct S3<T>(T) where &'static T: ?Sized; + | ^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:14:34 + | +LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>; + | ^^^^^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:22:21 + | +LL | fn f() where T: ?Sized {} + | ^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + +error: relaxed bounds are not permitted in supertrait bounds + --> $DIR/relaxed-bounds-invalid-places.rs:25:11 + | +LL | trait Tr: ?Sized {} + | ^^^^^^ + | + = note: traits are `?Sized` by default + +error: relaxed bounds are not permitted in trait object types + --> $DIR/relaxed-bounds-invalid-places.rs:29:20 + | +LL | type O1 = dyn Tr + ?Sized; + | ^^^^^^ + +error: relaxed bounds are not permitted in trait object types + --> $DIR/relaxed-bounds-invalid-places.rs:30:15 + | +LL | type O2 = dyn ?Sized + ?Sized + Tr; + | ^^^^^^ + +error: relaxed bounds are not permitted in trait object types + --> $DIR/relaxed-bounds-invalid-places.rs:30:24 + | +LL | type O2 = dyn ?Sized + ?Sized + Tr; + | ^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/relaxed-bounds-invalid-places.rs:14:34 + | +LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>; + | ^^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/relaxed-bounds-invalid-places.rs:18:33 + | +LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; + | ^^^^^^^^^^^^^^^ + +error: aborting due to 11 previous errors + diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs new file mode 100644 index 00000000000..3749deb7627 --- /dev/null +++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_feature.rs @@ -0,0 +1,25 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![stable(feature = "a", since = "1.1.1" )] + +#[stable(feature = "a", since = "1.1.1" )] +pub trait Foo { + #[stable(feature = "a", since = "1.1.1" )] + fn foo(); +} +#[stable(feature = "a", since = "1.1.1" )] +pub struct Bar; +#[stable(feature = "a", since = "1.1.1" )] +pub struct Moo; + +#[unstable_feature_bound(feat_bar)] +#[unstable(feature = "feat_bar", issue = "none" )] +impl Foo for Bar { + fn foo() {} +} + +#[unstable_feature_bound(feat_moo)] +#[unstable(feature = "feat_moo", issue = "none" )] +impl Foo for Moo { + fn foo() {} +} diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs new file mode 100644 index 00000000000..8c0d14a1bab --- /dev/null +++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux1.rs @@ -0,0 +1,19 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![stable(feature = "a", since = "1.1.1" )] + +/// Aux crate for unstable impl codegen test. + +#[stable(feature = "a", since = "1.1.1" )] +pub trait Trait { + #[stable(feature = "a", since = "1.1.1" )] + fn method(&self); +} + +#[unstable_feature_bound(foo)] +#[unstable(feature = "foo", issue = "none" )] +impl<T> Trait for T { + fn method(&self) { + println!("hi"); + } +} diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs new file mode 100644 index 00000000000..1b0e2b2eec3 --- /dev/null +++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_codegen_aux2.rs @@ -0,0 +1,13 @@ +//@ aux-build:unstable_impl_codegen_aux1.rs +#![feature(foo)] + +extern crate unstable_impl_codegen_aux1 as aux; +use aux::Trait; + +/// Upstream crate for unstable impl codegen test +/// that depends on aux crate in +/// unstable_impl_codegen_aux1.rs + +pub fn foo<T>(a: T) { + a.method(); +} diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs new file mode 100644 index 00000000000..2e055101216 --- /dev/null +++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_coherence_aux.rs @@ -0,0 +1,11 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![stable(feature = "a", since = "1.1.1" )] + +#[stable(feature = "a", since = "1.1.1" )] +pub trait Trait {} + +#[unstable_feature_bound(foo)] +#[unstable(feature = "foo", issue = "none" )] +impl <T> Trait for T {} diff --git a/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs new file mode 100644 index 00000000000..3a433007b5d --- /dev/null +++ b/tests/ui/unstable-feature-bound/auxiliary/unstable_impl_method_selection_aux.rs @@ -0,0 +1,20 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![stable(feature = "a", since = "1.1.1" )] + +#[stable(feature = "a", since = "1.1.1" )] +pub trait Trait { + #[stable(feature = "a", since = "1.1.1" )] + fn foo(&self) {} +} + +#[stable(feature = "a", since = "1.1.1" )] +impl Trait for Vec<u32> { + fn foo(&self) {} +} + +#[unstable_feature_bound(bar)] +#[unstable(feature = "bar", issue = "none" )] +impl Trait for Vec<u64> { + fn foo(&self) {} +} diff --git a/tests/ui/unstable-feature-bound/unstable-feature-bound-no-effect.rs b/tests/ui/unstable-feature-bound/unstable-feature-bound-no-effect.rs new file mode 100644 index 00000000000..99501893ae0 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-bound-no-effect.rs @@ -0,0 +1,35 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![stable(feature = "a", since = "1.1.1" )] + +/// If #[unstable(..)] and #[unstable_feature_name(..)] have the same feature name, +/// the error should not be thrown as it can effectively mark an impl as unstable. +/// +/// If the feature name in #[feature] does not exist in #[unstable_feature_bound(..)] +/// an error should still be thrown because that feature will not be unstable. + +#[stable(feature = "a", since = "1.1.1")] +trait Moo {} +#[stable(feature = "a", since = "1.1.1")] +trait Foo {} +#[stable(feature = "a", since = "1.1.1")] +trait Boo {} +#[stable(feature = "a", since = "1.1.1")] +pub struct Bar; + + +#[unstable(feature = "feat_moo", issue = "none")] +#[unstable_feature_bound(feat_foo)] //~^ ERROR: an `#[unstable]` annotation here has no effect +impl Moo for Bar {} + +#[unstable(feature = "feat_foo", issue = "none")] +#[unstable_feature_bound(feat_foo)] +impl Foo for Bar {} + + +#[unstable(feature = "feat_foo", issue = "none")] +#[unstable_feature_bound(feat_foo, feat_bar)] +impl Boo for Bar {} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable-feature-bound-no-effect.stderr b/tests/ui/unstable-feature-bound/unstable-feature-bound-no-effect.stderr new file mode 100644 index 00000000000..4c8af2bbe56 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-bound-no-effect.stderr @@ -0,0 +1,11 @@ +error: an `#[unstable]` annotation here has no effect + --> $DIR/unstable-feature-bound-no-effect.rs:22:1 + | +LL | #[unstable(feature = "feat_moo", issue = "none")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information + = note: `#[deny(ineffective_unstable_trait_impl)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs new file mode 100644 index 00000000000..798c2d8562c --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.rs @@ -0,0 +1,12 @@ +//@ aux-build:unstable_feature.rs +extern crate unstable_feature; +use unstable_feature::{Foo, Bar, Moo}; + +// FIXME: both `feat_bar` and `feat_moo` are needed to pass this test, +// but the diagnostic only will point out `feat_bar`. + +fn main() { + Bar::foo(); + //~^ ERROR: use of unstable library feature `feat_bar` [E0658] + Moo::foo(); +} diff --git a/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr new file mode 100644 index 00000000000..673d10ce2ad --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-bound-two-error.stderr @@ -0,0 +1,13 @@ +error[E0658]: use of unstable library feature `feat_bar` + --> $DIR/unstable-feature-bound-two-error.rs:9:5 + | +LL | Bar::foo(); + | ^^^ + | + = help: add `#![feature(feat_bar)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `Bar` to implement `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr new file mode 100644 index 00000000000..ce8d7358cfc --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.fail.stderr @@ -0,0 +1,13 @@ +error[E0658]: use of unstable library feature `feat_moo` + --> $DIR/unstable-feature-cross-crate-exact-symbol.rs:16:5 + | +LL | Moo::foo(); + | ^^^ + | + = help: add `#![feature(feat_moo)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `Moo` to implement `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs new file mode 100644 index 00000000000..a427bb8eb7e --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-exact-symbol.rs @@ -0,0 +1,18 @@ +//@ aux-build:unstable_feature.rs +//@ revisions: pass fail +//@[pass] check-pass + +#![cfg_attr(pass, feature(feat_bar, feat_moo))] +#![cfg_attr(fail, feature(feat_bar))] + +extern crate unstable_feature; +use unstable_feature::{Foo, Bar, Moo}; + +/// To use impls gated by both `feat_foo` and `feat_moo`, +/// both features must be enabled. + +fn main() { + Bar::foo(); + Moo::foo(); + //[fail]~^ ERROR:use of unstable library feature `feat_moo` [E0658] +} diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs new file mode 100644 index 00000000000..5b09c898a08 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-multiple-symbol.rs @@ -0,0 +1,11 @@ +//@ aux-build:unstable_feature.rs +//@ check-pass +#![feature(feat_bar, feat_moo)] +extern crate unstable_feature; +use unstable_feature::{Foo, Bar}; + +/// Bar::foo() should still be usable even if we enable multiple feature. + +fn main() { + Bar::foo(); +} diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr new file mode 100644 index 00000000000..87a2ad41fc1 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.fail.stderr @@ -0,0 +1,13 @@ +error[E0658]: use of unstable library feature `feat_bar` + --> $DIR/unstable-feature-cross-crate-require-bound.rs:12:5 + | +LL | Bar::foo(); + | ^^^ + | + = help: add `#![feature(feat_bar)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `Bar` to implement `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs new file mode 100644 index 00000000000..8be214b5324 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-cross-crate-require-bound.rs @@ -0,0 +1,14 @@ +//@ aux-build:unstable_feature.rs +//@ revisions: pass fail +//@[pass] check-pass + +#![cfg_attr(pass, feature(feat_bar))] +extern crate unstable_feature; +use unstable_feature::{Foo, Bar}; + +/// #[feature(..)] is required to use unstable impl. + +fn main() { + Bar::foo(); + //[fail]~^ ERROR: use of unstable library feature `feat_bar` [E0658] +} diff --git a/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr new file mode 100644 index 00000000000..b8cb63ec65f --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.fail.stderr @@ -0,0 +1,17 @@ +error: unstable feature `feat_moo` is used without being enabled. + --> $DIR/unstable-feature-exact-symbol.rs:37:5 + | +LL | Bar::moo(); + | ^^^ + | + = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_moo)]` +note: required for `Bar` to implement `Moo` + --> $DIR/unstable-feature-exact-symbol.rs:29:6 + | +LL | #[unstable_feature_bound(feat_moo)] + | ----------------------------------- unsatisfied trait bound introduced here +LL | impl Moo for Bar { + | ^^^ ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs new file mode 100644 index 00000000000..2de9e6a857e --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-feature-exact-symbol.rs @@ -0,0 +1,42 @@ +//@ revisions: pass fail +//@[pass] check-pass + +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![unstable(feature = "feat_foo", issue = "none" )] + +/// In staged-api crate, impl that is marked as unstable with +/// feature name `feat_moo` should not be accessible +/// if only `feat_foo` is enabled. + +pub trait Foo { + fn foo(); +} + +pub trait Moo { + fn moo(); +} + +pub struct Bar; + +#[unstable_feature_bound(feat_foo)] +impl Foo for Bar { + fn foo() {} +} + +#[unstable_feature_bound(feat_moo)] +impl Moo for Bar { + fn moo() {} +} + +#[cfg_attr(fail, unstable_feature_bound(feat_foo))] +#[cfg_attr(pass, unstable_feature_bound(feat_foo, feat_moo))] +fn bar() { + Bar::foo(); + Bar::moo(); + //[fail]~^ ERROR unstable feature `feat_moo` is used without being enabled. + +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr new file mode 100644 index 00000000000..db9759b4cc3 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.fail.stderr @@ -0,0 +1,22 @@ +error: unstable feature `feat_foo` is used without being enabled. + --> $DIR/unstable-impl-assoc-type.rs:23:16 + | +LL | type Assoc = Self; + | ^^^^ + | + = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_foo)]` +note: required for `Foo` to implement `Bar` + --> $DIR/unstable-impl-assoc-type.rs:19:6 + | +LL | #[unstable_feature_bound(feat_foo)] + | ----------------------------------- unsatisfied trait bound introduced here +LL | impl Bar for Foo {} + | ^^^ ^^^ +note: required by a bound in `Trait::Assoc` + --> $DIR/unstable-impl-assoc-type.rs:13:17 + | +LL | type Assoc: Bar; + | ^^^ required by this bound in `Trait::Assoc` + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs new file mode 100644 index 00000000000..e31dc688dfa --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-impl-assoc-type.rs @@ -0,0 +1,28 @@ +//@ revisions: pass fail +//@[pass] check-pass + +#![allow(internal_features)] +#![feature(staged_api)] +#![unstable(feature = "feat_foo", issue = "none" )] + +/// Test that you can't leak unstable impls through item bounds on associated types. + +trait Bar {} + +trait Trait { + type Assoc: Bar; +} + +struct Foo; + +#[unstable_feature_bound(feat_foo)] +impl Bar for Foo {} + +#[cfg_attr(pass, unstable_feature_bound(feat_foo))] +impl Trait for Foo { + type Assoc = Self; + //[fail]~^ ERROR: unstable feature `feat_foo` is used without being enabled. + +} + +fn main(){} diff --git a/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr new file mode 100644 index 00000000000..d56072362fe --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.fail.stderr @@ -0,0 +1,17 @@ +error: unstable feature `feat_foo` is used without being enabled. + --> $DIR/unstable-impl-cannot-use-feature.rs:26:5 + | +LL | Bar::foo(); + | ^^^ + | + = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_foo)]` +note: required for `Bar` to implement `Foo` + --> $DIR/unstable-impl-cannot-use-feature.rs:20:6 + | +LL | #[unstable_feature_bound(feat_foo)] + | ----------------------------------- unsatisfied trait bound introduced here +LL | impl Foo for Bar { + | ^^^ ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs new file mode 100644 index 00000000000..0da618445fd --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-impl-cannot-use-feature.rs @@ -0,0 +1,30 @@ +//@ revisions: pass fail +//@[pass] check-pass + +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![unstable(feature = "feat_foo", issue = "none" )] + +#![cfg_attr(fail, feature(feat_foo))] + +/// In staged-api crate, using an unstable impl requires +/// #[unstable_feature_bound(..)], not #[feature(..)]. + +pub trait Foo { + fn foo(); +} +pub struct Bar; + +#[unstable_feature_bound(feat_foo)] +impl Foo for Bar { + fn foo() {} +} + +#[cfg_attr(pass, unstable_feature_bound(feat_foo))] +fn bar() { + Bar::foo(); + //[fail]~^ ERROR: unstable feature `feat_foo` is used without being enabled. +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs b/tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs new file mode 100644 index 00000000000..c9a9029b0a0 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable-impl-multiple-symbol.rs @@ -0,0 +1,27 @@ +//@ check-pass + +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![unstable(feature = "feat_foo", issue = "none" )] + +/// In staged-api crate, if feat_foo is only needed to use an impl, +/// having both `feat_foo` and `feat_bar` will still make it pass. + +pub trait Foo { + fn foo(); +} +pub struct Bar; + +// Annotate the impl as unstable. +#[unstable_feature_bound(feat_foo)] +impl Foo for Bar { + fn foo() {} +} + +#[unstable_feature_bound(feat_foo, feat_bar)] +fn bar() { + Bar::foo(); +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr new file mode 100644 index 00000000000..f8354256828 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.fail.stderr @@ -0,0 +1,17 @@ +error: unstable feature `feat_bar` is used without being enabled. + --> $DIR/unstable_feature_bound_free_fn.rs:36:5 + | +LL | bar(); + | ^^^^^ + | + = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_bar)]` +note: required by a bound in `bar` + --> $DIR/unstable_feature_bound_free_fn.rs:29:1 + | +LL | #[unstable_feature_bound(feat_bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `bar` +LL | fn bar() { + | --- required by a bound in this function + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs new file mode 100644 index 00000000000..30e2ab3d65e --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_free_fn.rs @@ -0,0 +1,40 @@ +//@ revisions: pass fail +//@[pass] check-pass + +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![stable(feature = "a", since = "1.1.1" )] + +/// When a free function with #[unstable_feature_bound(feat_bar)] is called by another +/// free function, that function should be annotated with +/// #[unstable_feature_bound(feat_bar)] too. + +#[stable(feature = "a", since = "1.1.1")] +trait Foo { + #[stable(feature = "a", since = "1.1.1")] + fn foo() { + } +} +#[stable(feature = "a", since = "1.1.1")] +pub struct Bar; + +#[unstable_feature_bound(feat_bar)] +#[unstable(feature = "feat_bar", issue = "none" )] +impl Foo for Bar { + fn foo() {} +} + + +#[unstable_feature_bound(feat_bar)] +fn bar() { + Bar::foo(); +} + +#[cfg_attr(pass, unstable_feature_bound(feat_bar))] +fn bar2() { + bar(); + //[fail]~^ERROR unstable feature `feat_bar` is used without being enabled. +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs new file mode 100644 index 00000000000..1a9652c1023 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs @@ -0,0 +1,14 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![stable(feature = "a", since = "1.1.1" )] + +// Lint against the usage of both #[unstable_feature_bound] and #[stable] on the +// same item. + +#[stable(feature = "a", since = "1.1.1")] +#[unstable_feature_bound(feat_bar)] +fn bar() {} +//~^ ERROR Item annotated with `#[unstable_feature_bound]` should not be stable + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr new file mode 100644 index 00000000000..9cb6a181bef --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr @@ -0,0 +1,10 @@ +error: Item annotated with `#[unstable_feature_bound]` should not be stable + --> $DIR/unstable_feature_bound_incompatible_stability.rs:11:1 + | +LL | fn bar() {} + | ^^^^^^^^^^^ + | + = help: If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs new file mode 100644 index 00000000000..3d6b52ba517 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.rs @@ -0,0 +1,36 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![allow(dead_code)] +#![unstable(feature = "feat_bar", issue = "none" )] + +/// Test the behaviour of multiple unstable_feature_bound attribute. + +trait Foo { + fn foo(); +} +struct Bar; + +#[unstable_feature_bound(feat_bar, feat_koo)] +#[unstable_feature_bound(feat_foo, feat_moo)] +impl Foo for Bar { + fn foo(){} +} + +#[unstable_feature_bound(feat_bar, feat_koo)] +#[unstable_feature_bound(feat_foo, feat_moo)] +fn moo() { + Bar::foo(); +} + +#[unstable_feature_bound(feat_bar, feat_koo, feat_foo, feat_moo)] +fn koo() { + Bar::foo(); +} + +#[unstable_feature_bound(feat_koo, feat_foo, feat_moo)] +fn boo() { + Bar::foo(); + //~^ ERROR: unstable feature `feat_bar` is used without being enabled. +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr new file mode 100644 index 00000000000..936c70c1979 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_multi_attr.stderr @@ -0,0 +1,18 @@ +error: unstable feature `feat_bar` is used without being enabled. + --> $DIR/unstable_feature_bound_multi_attr.rs:32:5 + | +LL | Bar::foo(); + | ^^^ + | + = help: The feature can be enabled by marking the current item with `#[unstable_feature_bound(feat_bar)]` +note: required for `Bar` to implement `Foo` + --> $DIR/unstable_feature_bound_multi_attr.rs:15:6 + | +LL | #[unstable_feature_bound(feat_bar, feat_koo)] + | --------------------------------------------- unsatisfied trait bound introduced here +LL | #[unstable_feature_bound(feat_foo, feat_moo)] +LL | impl Foo for Bar { + | ^^^ ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs new file mode 100644 index 00000000000..51e388f7dd3 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.rs @@ -0,0 +1,13 @@ +/// Unstable feature bound can only be used only when +/// #[feature(staged_api)] is enabled. + +pub trait Foo { +} +pub struct Bar; + +#[unstable_feature_bound(feat_bar)] +//~^ ERROR: stability attributes may not be used outside of the standard library +impl Foo for Bar { +} + +fn main(){} diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr new file mode 100644 index 00000000000..35ab89e6ad9 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr @@ -0,0 +1,9 @@ +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/unstable_feature_bound_staged_api.rs:8:1 + | +LL | #[unstable_feature_bound(feat_bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0734`. diff --git a/tests/ui/unstable-feature-bound/unstable_impl_codegen.rs b/tests/ui/unstable-feature-bound/unstable_impl_codegen.rs new file mode 100644 index 00000000000..285a64d2250 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_impl_codegen.rs @@ -0,0 +1,13 @@ +//@ aux-build:unstable_impl_codegen_aux2.rs +//@ run-pass + +/// Downstream crate for unstable impl codegen test +/// that depends on upstream crate in +/// unstable_impl_codegen_aux2.rs + +extern crate unstable_impl_codegen_aux2 as aux; +use aux::foo; + +fn main() { + foo(1_u8); +} diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr new file mode 100644 index 00000000000..c3147558b03 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy` + --> $DIR/unstable_impl_coherence.rs:14:1 + | +LL | impl aux::Trait for LocalTy {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `unstable_impl_coherence_aux`: + - impl<T> Trait for T + where unstable feature: `foo`; + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr new file mode 100644 index 00000000000..c3147558b03 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy` + --> $DIR/unstable_impl_coherence.rs:14:1 + | +LL | impl aux::Trait for LocalTy {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `unstable_impl_coherence_aux`: + - impl<T> Trait for T + where unstable feature: `foo`; + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs new file mode 100644 index 00000000000..22100f85f71 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs @@ -0,0 +1,17 @@ +//@ aux-build:unstable_impl_coherence_aux.rs +//@ revisions: enabled disabled + +#![cfg_attr(enabled, feature(foo))] +extern crate unstable_impl_coherence_aux as aux; +use aux::Trait; + +/// Coherence test for unstable impl. +/// No matter feature `foo` is enabled or not, the impl +/// for aux::Trait will be rejected by coherence checking. + +struct LocalTy; + +impl aux::Trait for LocalTy {} +//~^ ERROR: conflicting implementations of trait `Trait` for type `LocalTy` + +fn main(){} diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs new file mode 100644 index 00000000000..acf521d3130 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs @@ -0,0 +1,15 @@ +//@ aux-build:unstable_impl_method_selection_aux.rs + +extern crate unstable_impl_method_selection_aux as aux; +use aux::Trait; + +// The test below should not infer the type based on the fact +// that `impl Trait for Vec<u64>` is unstable. This would cause breakage +// in downstream crate once `impl Trait for Vec<u64>` is stabilised. + +fn bar() { + vec![].foo(); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr new file mode 100644 index 00000000000..c2bb10f043b --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr @@ -0,0 +1,14 @@ +error[E0283]: type annotations needed + --> $DIR/unstable_impl_method_selection.rs:11:12 + | +LL | vec![].foo(); + | ^^^ cannot infer type for struct `Vec<_>` + | + = note: multiple `impl`s satisfying `Vec<_>: Trait` found in the `unstable_impl_method_selection_aux` crate: + - impl Trait for Vec<u32>; + - impl Trait for Vec<u64> + where unstable feature: `bar`; + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/unstable-feature-bound/unstable_inherent_method.rs b/tests/ui/unstable-feature-bound/unstable_inherent_method.rs new file mode 100644 index 00000000000..5f3095430a8 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_inherent_method.rs @@ -0,0 +1,23 @@ +#![allow(internal_features)] +#![feature(staged_api)] +#![stable(feature = "a", since = "1.1.1" )] + +/// FIXME(tiif): we haven't allowed marking trait and impl method as +/// unstable yet, but it should be possible. + +#[stable(feature = "a", since = "1.1.1" )] +pub trait Trait { + #[unstable(feature = "feat", issue = "none" )] + #[unstable_feature_bound(foo)] + //~^ ERROR: attribute should be applied to `impl` or free function outside of any `impl` or trait + fn foo(); +} + +#[stable(feature = "a", since = "1.1.1" )] +impl Trait for u8 { + #[unstable_feature_bound(foo)] + //~^ ERROR: attribute should be applied to `impl` or free function outside of any `impl` or trait + fn foo() {} +} + +fn main() {} diff --git a/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr b/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr new file mode 100644 index 00000000000..fa1c39db259 --- /dev/null +++ b/tests/ui/unstable-feature-bound/unstable_inherent_method.stderr @@ -0,0 +1,20 @@ +error: attribute should be applied to `impl` or free function outside of any `impl` or trait + --> $DIR/unstable_inherent_method.rs:11:5 + | +LL | #[unstable_feature_bound(foo)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn foo(); + | --------- not an `impl` or free function + +error: attribute should be applied to `impl` or free function outside of any `impl` or trait + --> $DIR/unstable_inherent_method.rs:18:5 + | +LL | #[unstable_feature_bound(foo)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn foo() {} + | ----------- not an `impl` or free function + +error: aborting due to 2 previous errors + diff --git a/tests/ui/wasm/simd-to-array-80108.rs b/tests/ui/wasm/simd-to-array-80108.rs index c7f8585eaa4..f6b368992be 100644 --- a/tests/ui/wasm/simd-to-array-80108.rs +++ b/tests/ui/wasm/simd-to-array-80108.rs @@ -10,6 +10,8 @@ pub struct Vector([i32; 4]); impl Vector { pub const fn to_array(self) -> [i32; 4] { - self.0 + // This used to just be `.0`, but that was banned in + // <https://github.com/rust-lang/compiler-team/issues/838> + unsafe { std::mem::transmute(self) } } } diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs index 428ebf4b408..6f21e5ccbaa 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.rs +++ b/tests/ui/where-clauses/ignore-err-clauses.rs @@ -1,13 +1,13 @@ use std::ops::Add; fn dbl<T>(x: T) -> <T as Add>::Output -//~^ ERROR type annotations needed where T: Copy + Add, UUU: Copy, //~^ ERROR cannot find type `UUU` in this scope { x + x + //~^ ERROR use of moved value: `x` } fn main() { diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr index fbf1b99334f..9c76c1c6a04 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.stderr +++ b/tests/ui/where-clauses/ignore-err-clauses.stderr @@ -1,16 +1,33 @@ error[E0412]: cannot find type `UUU` in this scope - --> $DIR/ignore-err-clauses.rs:7:5 + --> $DIR/ignore-err-clauses.rs:6:5 | LL | UUU: Copy, | ^^^ not found in this scope -error[E0282]: type annotations needed - --> $DIR/ignore-err-clauses.rs:3:14 +error[E0382]: use of moved value: `x` + --> $DIR/ignore-err-clauses.rs:9:9 | LL | fn dbl<T>(x: T) -> <T as Add>::Output - | ^ cannot infer type for type parameter `T` + | - move occurs because `x` has type `T`, which does not implement the `Copy` trait +... +LL | x + x + | ----^ + | | | + | | value used here after move + | `x` moved due to usage in operator + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/ignore-err-clauses.rs:3:8 + | +LL | fn dbl<T>(x: T) -> <T as Add>::Output + | ^ consider constraining this type parameter with `Clone` +... +LL | x + x + | - you could clone this value +note: calling this operator moves the left-hand side + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL error: aborting due to 2 previous errors -Some errors have detailed explanations: E0282, E0412. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0382, E0412. +For more information about an error, try `rustc --explain E0382`. |
