diff options
Diffstat (limited to 'tests/ui')
91 files changed, 1760 insertions, 287 deletions
diff --git a/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs new file mode 100644 index 00000000000..0e2d1ef1208 --- /dev/null +++ b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs @@ -0,0 +1,27 @@ +//@ edition: 2021 +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(async_closure)] + +use std::future::Future; +use std::any::Any; + +struct Struct; +impl Struct { + fn method(&self) {} +} + +fn fake_async_closure<F, Fut>(_: F) +where + F: Fn(Struct) -> Fut, + Fut: Future<Output = ()>, +{} + +fn main() { + fake_async_closure(async |s| { + s.method(); + }) +} diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs index 0d8f92f013f..5704a33cc87 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs @@ -4,25 +4,12 @@ #![feature(unsized_tuple_coercion)] -trait Foo<T> { - fn foo(&self, _: T) -> u32 { 42 } -} - trait Bar { //~ WARN trait `Bar` is never used fn bar(&self) { println!("Bar!"); } } -impl<T> Foo<T> for () {} -impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } impl Bar for () {} -unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32>+'a)) -> u32 { - let foo_e : *const dyn Foo<u32> = t as *const _; - let r_1 = foo_e as *mut dyn Foo<u32>; - - (&*r_1).foo(0) -} - #[repr(C)] struct FooS<T:?Sized>(T); #[repr(C)] @@ -38,11 +25,6 @@ fn tuple_i32_to_u32<T:?Sized>(u: *const (i32, T)) -> *const (u32, T) { fn main() { - let x = 4u32; - let y : &dyn Foo<u32> = &x; - let fl = unsafe { round_trip_and_call(y as *const dyn Foo<u32>) }; - assert_eq!(fl, (43+4)); - let s = FooS([0,1,2]); let u: &FooS<[u32]> = &s; let u: *const FooS<[u32]> = u; diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr index 952687e98d0..4f57e2e7df7 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr @@ -1,5 +1,5 @@ warning: trait `Bar` is never used - --> $DIR/cast-rfc0401-vtable-kinds.rs:11:7 + --> $DIR/cast-rfc0401-vtable-kinds.rs:7:7 | LL | trait Bar { | ^^^ diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs new file mode 100644 index 00000000000..46e72ea0877 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -0,0 +1,18 @@ +//@ check-pass + +trait Trait<'a> {} + +fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { + x as _ + //~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on + //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} + +// (to test diagnostic list formatting) +fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) { + x as _ + //~^ warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on + //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr new file mode 100644 index 00000000000..e5ef8bf76b4 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -0,0 +1,43 @@ +warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323> + = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default + +warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323> + +warning: 2 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323> + = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default + +Future breakage diagnostic: +warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #127323 <https://github.com/rust-lang/rust/issues/127323> + = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default + diff --git a/tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs new file mode 100644 index 00000000000..ac8108d8ec4 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs @@ -0,0 +1,9 @@ +//@ check-pass + +trait Trait: Send {} +impl Trait for () {} + +fn main() { + // This is OK: `Trait` has `Send` super trait. + &() as *const dyn Trait as *const (dyn Trait + Send); +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs new file mode 100644 index 00000000000..c6038cfe864 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -0,0 +1,37 @@ +//@ check-fail +// +// issue: <https://github.com/rust-lang/rust/issues/120222> + +trait A {} +impl<T> A for T {} +trait B {} +impl<T> B for T {} + +trait Trait<G> {} +struct X; +impl<T> Trait<X> for T {} +struct Y; +impl<T> Trait<Y> for T {} + +fn main() { + let a: *const dyn A = &(); + let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid + + let x: *const dyn Trait<X> = &(); + let y: *const dyn Trait<Y> = x as _; //~ error: mismatched types + + _ = (b, y); +} + +fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) { + let _: *const dyn Trait<T> = x as _; //~ error: mismatched types + let _: *const dyn Trait<X> = t as _; //~ error: mismatched types +} + +trait Assocked { + type Assoc: ?Sized; +} + +fn change_assoc(x: *mut dyn Assocked<Assoc = u8>) -> *mut dyn Assocked<Assoc = u32> { + x as _ //~ error: mismatched types +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr new file mode 100644 index 00000000000..b04289ae747 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -0,0 +1,53 @@ +error[E0606]: casting `*const dyn A` as `*const dyn B` is invalid + --> $DIR/ptr-to-trait-obj-different-args.rs:18:27 + | +LL | let b: *const dyn B = a as _; + | ^^^^^^ + | + = note: vtable kinds may not match + +error[E0308]: mismatched types + --> $DIR/ptr-to-trait-obj-different-args.rs:21:34 + | +LL | let y: *const dyn Trait<Y> = x as _; + | ^^^^^^ expected `X`, found `Y` + | + = note: expected trait object `dyn Trait<X>` + found trait object `dyn Trait<Y>` + +error[E0308]: mismatched types + --> $DIR/ptr-to-trait-obj-different-args.rs:27:34 + | +LL | fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) { + | - found this type parameter +LL | let _: *const dyn Trait<T> = x as _; + | ^^^^^^ expected `X`, found type parameter `T` + | + = note: expected trait object `dyn Trait<X>` + found trait object `dyn Trait<T>` + +error[E0308]: mismatched types + --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 + | +LL | fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) { + | - expected this type parameter +LL | let _: *const dyn Trait<T> = x as _; +LL | let _: *const dyn Trait<X> = t as _; + | ^^^^^^ expected type parameter `T`, found `X` + | + = note: expected trait object `dyn Trait<T>` + found trait object `dyn Trait<X>` + +error[E0308]: mismatched types + --> $DIR/ptr-to-trait-obj-different-args.rs:36:5 + | +LL | x as _ + | ^^^^^^ expected `u8`, found `u32` + | + = note: expected trait object `dyn Assocked<Assoc = u8>` + found trait object `dyn Assocked<Assoc = u32>` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0308, E0606. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs new file mode 100644 index 00000000000..cdd55e24392 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs @@ -0,0 +1,27 @@ +//@ check-fail +// +// Make sure we can't trick the compiler by using a projection. + +trait Cat<'a> {} +impl Cat<'_> for () {} + +trait Id { + type Id: ?Sized; +} +impl<T: ?Sized> Id for T { + type Id = T; +} + +struct S<T: ?Sized> { + tail: <T as Id>::Id, +} + +fn m<'a>() { + let unsend: *const dyn Cat<'a> = &(); + let _send = unsend as *const S<dyn Cat<'static>>; + //~^ error: lifetime may not live long enough +} + +fn main() { + m(); +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr new file mode 100644 index 00000000000..d1d598e603f --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr @@ -0,0 +1,15 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:21:17 + | +LL | fn m<'a>() { + | -- lifetime `'a` defined here +LL | let unsend: *const dyn Cat<'a> = &(); +LL | let _send = unsend as *const S<dyn Cat<'static>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type `S<dyn Cat<'_>>`, which makes the generic argument `dyn Cat<'_>` invariant + = note: the struct `S<T>` is invariant over the parameter `T` + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs new file mode 100644 index 00000000000..96345de01c9 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs @@ -0,0 +1,31 @@ +//@ check-fail +// +// issue: <https://github.com/rust-lang/rust/issues/120217> + +#![feature(arbitrary_self_types)] + +trait Static<'a> { + fn proof(self: *const Self, s: &'a str) -> &'static str; +} + +fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { + x as _ //~ error: lifetime may not live long enough +} + +impl Static<'static> for () { + fn proof(self: *const Self, s: &'static str) -> &'static str { + s + } +} + +fn extend_lifetime(s: &str) -> &'static str { + bad_cast(&()).proof(s) +} + +fn main() { + let s = String::from("Hello World"); + let slice = extend_lifetime(&s); + println!("Now it exists: {slice}"); + drop(s); + println!("Now it’s gone: {slice}"); +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr new file mode 100644 index 00000000000..b7319e3356b --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-lt-ext.rs:12:5 + | +LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs new file mode 100644 index 00000000000..01c347bfae5 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -0,0 +1,37 @@ +//@ check-fail + +trait Trait<'a> {} + +fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + x as _ //~ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + x as _ //~ error: lifetime may not live long enough +} + +fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + x as _ //~ error: lifetime may not live long enough +} + +trait Assocked { + type Assoc: ?Sized; +} + +fn change_assoc_0<'a, 'b>( + x: *mut dyn Assocked<Assoc = dyn Send + 'a>, +) -> *mut dyn Assocked<Assoc = dyn Send + 'b> { + x as _ //~ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + +fn change_assoc_1<'a, 'b>( + x: *mut dyn Assocked<Assoc = dyn Trait<'a>>, +) -> *mut dyn Assocked<Assoc = dyn Trait<'b>> { + x as _ //~ error: lifetime may not live long enough + //~| error: lifetime may not live long enough +} + + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr new file mode 100644 index 00000000000..7044e4dec1f --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -0,0 +1,136 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5 + | +LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5 + | +LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +help: `'b` and `'a` must be the same: replace one with the other + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:11:5 + | +LL | fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:15:5 + | +LL | fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5 + | +LL | fn change_assoc_0<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a mutable pointer to `dyn Assocked<Assoc = dyn Send>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5 + | +LL | fn change_assoc_0<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Assocked<Assoc = dyn Send>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | fn change_assoc_1<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a mutable pointer to `dyn Assocked<Assoc = dyn Trait<'_>>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | fn change_assoc_1<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Assocked<Assoc = dyn Trait<'_>>` + = note: mutable pointers are invariant over their type parameter + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs new file mode 100644 index 00000000000..656c99c58dc --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -0,0 +1,17 @@ +//@ check-pass + +trait Trait<'a> {} + +fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { + x as _ +} + +fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) { + x as _ +} + +fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + x as _ +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs new file mode 100644 index 00000000000..ff2c4cacfb1 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs @@ -0,0 +1,14 @@ +trait Super {} +trait Sub: Super {} + +struct Wrapper<T: ?Sized>(T); + +// This cast should not compile. +// Upcasting can't work here, because we are also changing the type (`Wrapper`), +// and reinterpreting would be confusing/surprising. +// See <https://github.com/rust-lang/rust/pull/120248#discussion_r1487739518> +fn cast(ptr: *const dyn Sub) -> *const Wrapper<dyn Super> { + ptr as _ //~ error: casting `*const (dyn Sub + 'static)` as `*const Wrapper<dyn Super>` is invalid +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr new file mode 100644 index 00000000000..38c8ba96bc5 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr @@ -0,0 +1,11 @@ +error[E0606]: casting `*const (dyn Sub + 'static)` as `*const Wrapper<dyn Super>` is invalid + --> $DIR/ptr-to-trait-obj-wrap-upcast.rs:11:5 + | +LL | ptr as _ + | ^^^^^^^^ + | + = note: vtable kinds may not match + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/deriving/deriving-in-fn.rs b/tests/ui/deriving/deriving-in-fn.rs index 72da2148350..13f3d39597c 100644 --- a/tests/ui/deriving/deriving-in-fn.rs +++ b/tests/ui/deriving/deriving-in-fn.rs @@ -9,5 +9,5 @@ pub fn main() { } let f = Foo { foo: 10 }; - format!("{:?}", f); + let _ = format!("{:?}", f); } diff --git a/tests/ui/explicit-tail-calls/constck.rs b/tests/ui/explicit-tail-calls/constck.rs new file mode 100644 index 00000000000..938f15f12c0 --- /dev/null +++ b/tests/ui/explicit-tail-calls/constck.rs @@ -0,0 +1,22 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +const fn f() { + if false { + become not_const(); + //~^ error: cannot call non-const fn `not_const` in constant functions + } +} + +const fn g((): ()) { + if false { + become yes_const(not_const()); + //~^ error: cannot call non-const fn `not_const` in constant functions + } +} + +fn not_const() {} + +const fn yes_const((): ()) {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/constck.stderr b/tests/ui/explicit-tail-calls/constck.stderr new file mode 100644 index 00000000000..d9967c45fa0 --- /dev/null +++ b/tests/ui/explicit-tail-calls/constck.stderr @@ -0,0 +1,19 @@ +error[E0015]: cannot call non-const fn `not_const` in constant functions + --> $DIR/constck.rs:6:16 + | +LL | become not_const(); + | ^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const fn `not_const` in constant functions + --> $DIR/constck.rs:13:26 + | +LL | become yes_const(not_const()); + | ^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs new file mode 100644 index 00000000000..5a105ee4eb5 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs @@ -0,0 +1,14 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn test(_: &Type) { + const fn takes_borrow(_: &Type) {} + + let local = Type; + become takes_borrow(&local); + //~^ error: `local` does not live long enough +} + +struct Type; + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr new file mode 100644 index 00000000000..75fb13c378c --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr @@ -0,0 +1,14 @@ +error[E0597]: `local` does not live long enough + --> $DIR/ctfe-arg-bad-borrow.rs:8:25 + | +LL | let local = Type; + | ----- binding `local` declared here +LL | become takes_borrow(&local); + | ^^^^^^ borrowed value does not live long enough +LL | +LL | } + | - `local` dropped here while still borrowed + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs b/tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs new file mode 100644 index 00000000000..50bf6c946ca --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs @@ -0,0 +1,13 @@ +//@ check-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn test(x: &Type) { + const fn takes_borrow(_: &Type) {} + + become takes_borrow(x); +} + +pub struct Type; + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-move.rs b/tests/ui/explicit-tail-calls/ctfe-arg-move.rs new file mode 100644 index 00000000000..88ff3a4a5ad --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-move.rs @@ -0,0 +1,15 @@ +//@ check-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn test(s: String) -> String { + const fn takes_string(s: String) -> String { + s + } + + become takes_string(s); +} + +struct Type; + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs b/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs new file mode 100644 index 00000000000..86041b66960 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs @@ -0,0 +1,43 @@ +//@ run-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +/// A very unnecessarily complicated "implementation" of the Collatz conjecture. +/// Returns the number of steps to reach `1`. +/// +/// This is just a test for tail calls, which involves multiple functions calling each other. +/// +/// Panics if `x == 0`. +const fn collatz(x: u32) -> u32 { + assert!(x > 0); + + const fn switch(x: u32, steps: u32) -> u32 { + match x { + 1 => steps, + _ if x & 1 == 0 => become div2(x, steps + 1), + _ => become mul3plus1(x, steps + 1), + } + } + + const fn div2(x: u32, steps: u32) -> u32 { + become switch(x >> 1, steps) + } + + const fn mul3plus1(x: u32, steps: u32) -> u32 { + become switch(3 * x + 1, steps) + } + + switch(x, 0) +} + +const ASSERTS: () = { + assert!(collatz(1) == 0); + assert!(collatz(2) == 1); + assert!(collatz(3) == 7); + assert!(collatz(4) == 2); + assert!(collatz(6171) == 261); +}; + +fn main() { + let _ = ASSERTS; +} diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr new file mode 100644 index 00000000000..4a1e50b4111 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr @@ -0,0 +1,36 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/ctfe-id-unlimited.rs:17:42 + | +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames + | +note: inside `inner` + --> $DIR/ctfe-id-unlimited.rs:17:42 + | +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ +note: [... 125 additional calls inside `inner` ...] + --> $DIR/ctfe-id-unlimited.rs:17:42 + | +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ +note: inside `rec_id` + --> $DIR/ctfe-id-unlimited.rs:22:5 + | +LL | inner(0, n) + | ^^^^^^^^^^^ +note: inside `ID_ED` + --> $DIR/ctfe-id-unlimited.rs:29:20 + | +LL | const ID_ED: u32 = rec_id(ORIGINAL); + | ^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/ctfe-id-unlimited.rs:31:40 + | +LL | const ASSERT: () = assert!(ORIGINAL == ID_ED); + | ^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs new file mode 100644 index 00000000000..54e68b2b7f7 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs @@ -0,0 +1,35 @@ +//@ revisions: become return +//@ [become] run-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +// This is an identity function (`|x| x`), but implemented using recursion. +// Each step we increment accumulator and decrement the number. +// +// With normal calls this fails compilation because of the recursion limit, +// but with tail calls/`become` we don't grow the stack/spend recursion limit +// so this should compile. +const fn rec_id(n: u32) -> u32 { + const fn inner(acc: u32, n: u32) -> u32 { + match n { + 0 => acc, + #[cfg(r#become)] _ => become inner(acc + 1, n - 1), + #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + //[return]~^ error: evaluation of constant value failed + } + } + + inner(0, n) +} + +// Some relatively big number that is higher than recursion limit +const ORIGINAL: u32 = 12345; +// Original number, but with identity function applied +// (this is the same, but requires execution of the recursion) +const ID_ED: u32 = rec_id(ORIGINAL); +// Assert to make absolutely sure the computation actually happens +const ASSERT: () = assert!(ORIGINAL == ID_ED); + +fn main() { + let _ = ASSERT; +} diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs new file mode 100644 index 00000000000..3d69cde2989 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs @@ -0,0 +1,19 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn f() { + become g(); +} + +const fn g() { + panic!() + //~^ error: evaluation of constant value failed + //~| note: in this expansion of panic! + //~| note: inside `g` + //~| note: in this expansion of panic! +} + +const _: () = f(); +//~^ note: inside `_` + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr new file mode 100644 index 00000000000..8c070512105 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr @@ -0,0 +1,21 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/ctfe-tail-call-panic.rs:9:5 + | +LL | panic!() + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/ctfe-tail-call-panic.rs:9:5 + | +note: inside `g` + --> $DIR/ctfe-tail-call-panic.rs:9:5 + | +LL | panic!() + | ^^^^^^^^ +note: inside `_` + --> $DIR/ctfe-tail-call-panic.rs:16:15 + | +LL | const _: () = f(); + | ^^^ + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (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/explicit-tail-calls/drop-order.rs b/tests/ui/explicit-tail-calls/drop-order.rs new file mode 100644 index 00000000000..e20730446ec --- /dev/null +++ b/tests/ui/explicit-tail-calls/drop-order.rs @@ -0,0 +1,70 @@ +// FIXME(explicit_tail_calls): enable this test once rustc_codegen_ssa supports tail calls +//@ ignore-test: tail calls are not implemented in rustc_codegen_ssa yet, so this causes 🧊 +//@ run-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] +use std::cell::RefCell; + +fn main() { + let tail_counter = Default::default(); + tail_recursive(0, &tail_counter); + assert_eq!(tail_counter.into_inner(), (0..128).collect::<Vec<u8>>()); + + let simply_counter = Default::default(); + simply_recursive(0, &simply_counter); + assert_eq!(simply_counter.into_inner(), (0..128).rev().collect::<Vec<u8>>()); + + let scope_counter = Default::default(); + out_of_inner_scope(&scope_counter); + assert_eq!(scope_counter.into_inner(), (0..8).collect::<Vec<u8>>()); +} + +fn tail_recursive(n: u8, order: &RefCell<Vec<u8>>) { + if n >= 128 { + return; + } + + let _local = DropCounter(n, order); + + become tail_recursive(n + 1, order) +} + +fn simply_recursive(n: u8, order: &RefCell<Vec<u8>>) { + if n >= 128 { + return; + } + + let _local = DropCounter(n, order); + + return simply_recursive(n + 1, order); +} + +fn out_of_inner_scope(order: &RefCell<Vec<u8>>) { + fn inner(order: &RefCell<Vec<u8>>) { + let _7 = DropCounter(7, order); + let _6 = DropCounter(6, order); + } + + let _5 = DropCounter(5, order); + let _4 = DropCounter(4, order); + + if true { + let _3 = DropCounter(3, order); + let _2 = DropCounter(2, order); + loop { + let _1 = DropCounter(1, order); + let _0 = DropCounter(0, order); + + become inner(order); + } + } +} + +struct DropCounter<'a>(u8, &'a RefCell<Vec<u8>>); + +impl Drop for DropCounter<'_> { + #[track_caller] + fn drop(&mut self) { + self.1.borrow_mut().push(self.0); + } +} diff --git a/tests/ui/explicit-tail-calls/return-mismatches.rs b/tests/ui/explicit-tail-calls/return-mismatches.rs index 8094a192913..935a1a1d28b 100644 --- a/tests/ui/explicit-tail-calls/return-mismatches.rs +++ b/tests/ui/explicit-tail-calls/return-mismatches.rs @@ -13,7 +13,7 @@ fn _f1() { become _g1(); //~ error: mismatched types } -fn _g1() -> ! { //~ WARN: cannot return without recursing +fn _g1() -> ! { become _g1(); } diff --git a/tests/ui/explicit-tail-calls/return-mismatches.stderr b/tests/ui/explicit-tail-calls/return-mismatches.stderr index 31c7a46ded9..1dcc35797c1 100644 --- a/tests/ui/explicit-tail-calls/return-mismatches.stderr +++ b/tests/ui/explicit-tail-calls/return-mismatches.stderr @@ -22,17 +22,6 @@ error[E0308]: mismatched types LL | become _g2(); | ^^^^^^^^^^^^ expected `u32`, found `u16` -warning: function cannot return without recursing - --> $DIR/return-mismatches.rs:16:1 - | -LL | fn _g1() -> ! { - | ^^^^^^^^^^^^^ cannot return without recursing -LL | become _g1(); - | ----- recursive call site - | - = help: a `loop` may express intention better if this is on purpose - = note: `#[warn(unconditional_recursion)]` on by default - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/explicit-tail-calls/unsafeck.rs b/tests/ui/explicit-tail-calls/unsafeck.rs new file mode 100644 index 00000000000..872a70ca3a0 --- /dev/null +++ b/tests/ui/explicit-tail-calls/unsafeck.rs @@ -0,0 +1,11 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +const fn f() { + become dangerous(); + //~^ error: call to unsafe function `dangerous` is unsafe and requires unsafe function or block +} + +const unsafe fn dangerous() {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/unsafeck.stderr b/tests/ui/explicit-tail-calls/unsafeck.stderr new file mode 100644 index 00000000000..25b8967e17b --- /dev/null +++ b/tests/ui/explicit-tail-calls/unsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `dangerous` is unsafe and requires unsafe function or block + --> $DIR/unsafeck.rs:5:12 + | +LL | become dangerous(); + | ^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/fmt/struct-field-as-captured-argument.fixed b/tests/ui/fmt/struct-field-as-captured-argument.fixed index e13af744ec8..0da40737354 100644 --- a/tests/ui/fmt/struct-field-as-captured-argument.fixed +++ b/tests/ui/fmt/struct-field-as-captured-argument.fixed @@ -8,11 +8,11 @@ struct Foo { fn main() { let foo = Foo { field: 0 }; let bar = 3; - format!("{0}", foo.field); //~ ERROR invalid format string: field access isn't supported - format!("{1} {} {bar}", "aa", foo.field); //~ ERROR invalid format string: field access isn't supported - format!("{2} {} {1} {bar}", "aa", "bb", foo.field); //~ ERROR invalid format string: field access isn't supported - format!("{1} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{0}", foo.field); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1} {} {bar}", "aa", foo.field); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{2} {} {1} {bar}", "aa", "bb", foo.field); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported } diff --git a/tests/ui/fmt/struct-field-as-captured-argument.rs b/tests/ui/fmt/struct-field-as-captured-argument.rs index 6a875a85848..325b4e3a218 100644 --- a/tests/ui/fmt/struct-field-as-captured-argument.rs +++ b/tests/ui/fmt/struct-field-as-captured-argument.rs @@ -8,11 +8,11 @@ struct Foo { fn main() { let foo = Foo { field: 0 }; let bar = 3; - format!("{foo.field}"); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field} {} {bar}", "aa"); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field} {} {1} {bar}", "aa", "bb"); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field:?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field:#?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field:.3} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field}"); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field} {} {bar}", "aa"); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field} {} {1} {bar}", "aa", "bb"); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field:?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field:#?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field:.3} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported } diff --git a/tests/ui/fmt/struct-field-as-captured-argument.stderr b/tests/ui/fmt/struct-field-as-captured-argument.stderr index 7ea8b4068f2..4ef022cecb0 100644 --- a/tests/ui/fmt/struct-field-as-captured-argument.stderr +++ b/tests/ui/fmt/struct-field-as-captured-argument.stderr @@ -1,79 +1,79 @@ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:11:15 + --> $DIR/struct-field-as-captured-argument.rs:11:23 | -LL | format!("{foo.field}"); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field}"); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{0}", foo.field); - | ~ +++++++++++ +LL | let _ = format!("{0}", foo.field); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:12:15 + --> $DIR/struct-field-as-captured-argument.rs:12:23 | -LL | format!("{foo.field} {} {bar}", "aa"); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field} {} {bar}", "aa"); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1} {} {bar}", "aa", foo.field); - | ~ +++++++++++ +LL | let _ = format!("{1} {} {bar}", "aa", foo.field); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:13:15 + --> $DIR/struct-field-as-captured-argument.rs:13:23 | -LL | format!("{foo.field} {} {1} {bar}", "aa", "bb"); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field} {} {1} {bar}", "aa", "bb"); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{2} {} {1} {bar}", "aa", "bb", foo.field); - | ~ +++++++++++ +LL | let _ = format!("{2} {} {1} {bar}", "aa", "bb", foo.field); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:14:15 + --> $DIR/struct-field-as-captured-argument.rs:14:23 | -LL | format!("{foo.field} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:15:15 + --> $DIR/struct-field-as-captured-argument.rs:15:23 | -LL | format!("{foo.field:?} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field:?} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:16:15 + --> $DIR/struct-field-as-captured-argument.rs:16:23 | -LL | format!("{foo.field:#?} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field:#?} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:17:15 + --> $DIR/struct-field-as-captured-argument.rs:17:23 | -LL | format!("{foo.field:.3} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field:.3} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: aborting due to 7 previous errors diff --git a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr index 9b5d84b5b09..c5c4f2c4d23 100644 --- a/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr +++ b/tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.next.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `i32: Baz<Self>` is not satisfied +error[E0277]: the trait bound `<Self as Foo>::Bar<()>: Eq<i32>` is not satisfied --> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30 | LL | type Bar<T>: Baz<Self> = i32; diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr new file mode 100644 index 00000000000..d71c1768a6a --- /dev/null +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr @@ -0,0 +1,173 @@ +error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + | +LL | / fn autobatch<F>(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback<Self::CallbackArg>, + | |_______________________________________^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +help: consider further restricting this bound + | +LL | F: Callback<Self::CallbackArg> + MyFn<i32>, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:30 + | +LL | fn autobatch<F>(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `<Sender as ChannelSender>::autobatch` + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | fn autobatch<F>(self) -> impl Trait + | --------- required by a bound in this associated function +... +LL | F: Callback<Self::CallbackArg>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<Sender as ChannelSender>::autobatch` +help: consider further restricting this bound + | +LL | F: Callback<Self::CallbackArg> + MyFn<i32>, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + | +LL | / fn autobatch<F>(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback<Self::CallbackArg>, + | |_______________________________________^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider further restricting this bound + | +LL | F: Callback<Self::CallbackArg> + MyFn<i32>, + | +++++++++++ + +error[E0277]: the trait bound `F: Callback<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | F: Callback<Self::CallbackArg>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: the requirement `F: Callback<i32>` appears on the `impl`'s method `autobatch` but not on the corresponding trait's method + --> $DIR/false-positive-predicate-entailment-error.rs:25:8 + | +LL | trait ChannelSender { + | ------------- in this trait +... +LL | fn autobatch<F>(self) -> impl Trait + | ^^^^^^^^^ this trait's method doesn't have the requirement `F: Callback<i32>` +help: consider further restricting this bound + | +LL | F: Callback<Self::CallbackArg> + MyFn<i32>, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:30 + | +LL | fn autobatch<F>(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `F: Callback<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:27:12 + | +LL | F: Callback<Self::CallbackArg>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + | +LL | / fn autobatch<F>(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback<Self::CallbackArg>, + | |_______________________________________^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>` + | +note: required for `F` to implement `Callback<i32>` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl<A, F: MyFn<A>> Callback<A> for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider further restricting this bound + | +LL | F: Callback<Self::CallbackArg> + MyFn<i32>, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | F: Callback<Self::CallbackArg>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F` + | +note: required by a bound in `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:10:20 + | +LL | trait Callback<A>: MyFn<A, Output = Self::Ret> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Callback` +help: consider further restricting this bound + | +LL | F: Callback<Self::CallbackArg> + MyFn<i32>, + | +++++++++++ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs new file mode 100644 index 00000000000..59fdeab9e0a --- /dev/null +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs @@ -0,0 +1,51 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +trait MyFn<T> { + type Output; +} + +trait Callback<A>: MyFn<A, Output = Self::Ret> { + type Ret; +} + +impl<A, F: MyFn<A>> Callback<A> for F { + type Ret = F::Output; +} + +struct Thing; +trait Trait {} +impl Trait for Thing {} + +trait ChannelSender { + type CallbackArg; + + fn autobatch<F>(self) -> impl Trait + where + F: Callback<Self::CallbackArg>; + //[current]~^ ERROR the trait bound `F: Callback<i32>` is not satisfied +} + +struct Sender; + +impl ChannelSender for Sender { + type CallbackArg = i32; + + fn autobatch<F>(self) -> impl Trait + //[current]~^ ERROR the trait bound `F: MyFn<i32>` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied + where + F: Callback<Self::CallbackArg>, + //[current]~^ ERROR the trait bound `F: Callback<i32>` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied + { + Thing + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/nested_impl_trait.rs b/tests/ui/impl-trait/nested_impl_trait.rs index 502b2af2bc6..760102794c3 100644 --- a/tests/ui/impl-trait/nested_impl_trait.rs +++ b/tests/ui/impl-trait/nested_impl_trait.rs @@ -5,7 +5,7 @@ fn fine(x: impl Into<u32>) -> impl Into<u32> { x } fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } //~^ ERROR nested `impl Trait` is not allowed -//~| ERROR the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied +//~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} //~^ ERROR nested `impl Trait` is not allowed @@ -18,7 +18,7 @@ struct X; impl X { fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } //~^ ERROR nested `impl Trait` is not allowed - //~| ERROR the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied + //~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied } fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> { diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index a53312e5c0b..83d1347aff4 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -42,7 +42,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied +error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } @@ -51,7 +51,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } = help: the trait `Into<U>` is implemented for `T` = note: required for `impl Into<u32>` to implement `Into<impl Debug>` -error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied +error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs index a53071e304d..93b408331b8 100644 --- a/tests/ui/intrinsics/not-overridden.rs +++ b/tests/ui/intrinsics/not-overridden.rs @@ -1,6 +1,6 @@ //! Check that intrinsics that do not get overridden, but are marked as such, //! cause an error instead of silently invoking the body. -#![feature(rustc_attrs/* , effects*/)] // FIXME(effects) +#![feature(rustc_attrs)] //@ build-fail //@ failure-status:101 //@ normalize-stderr-test ".*note: .*\n\n" -> "" diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr new file mode 100644 index 00000000000..d9a4960feec --- /dev/null +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr @@ -0,0 +1,52 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` + --> $DIR/safe-intrinsic-mismatch.rs:11:5 + | +LL | fn size_of<T>() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` + --> $DIR/safe-intrinsic-mismatch.rs:11:5 + | +LL | fn size_of<T>() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` + --> $DIR/safe-intrinsic-mismatch.rs:16:1 + | +LL | const fn assume(_b: bool) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: intrinsic has wrong type + --> $DIR/safe-intrinsic-mismatch.rs:16:16 + | +LL | const fn assume(_b: bool) {} + | ^ expected unsafe fn, found safe fn + | + = note: expected signature `unsafe fn(_)` + found signature `fn(_)` + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate` + --> $DIR/safe-intrinsic-mismatch.rs:20:1 + | +LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: intrinsic has wrong type + --> $DIR/safe-intrinsic-mismatch.rs:20:26 + | +LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + | ^ expected unsafe fn, found safe fn + | + = note: expected signature `unsafe fn(_, _, _)` + found signature `fn(_, _, _)` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs index c116ba7a62e..af563e996c1 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs @@ -1,6 +1,11 @@ +//@ revisions: stock effects #![feature(intrinsics)] #![feature(rustc_attrs)] -// FIXME(effects) do this with revisions #![feature(effects)] +// as effects insert a const generic param to const intrinsics, +// check here that it doesn't report a const param mismatch either +// enabling or disabling effects. +#![cfg_attr(effects, feature(effects))] +#![allow(incomplete_features)] extern "rust-intrinsic" { fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr index 7f37e0f8211..6864c0f36de 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr @@ -1,11 +1,11 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` - --> $DIR/safe-intrinsic-mismatch.rs:6:5 + --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of<T>() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` - --> $DIR/safe-intrinsic-mismatch.rs:6:5 + --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of<T>() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ LL | fn size_of<T>() -> usize; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` - --> $DIR/safe-intrinsic-mismatch.rs:11:1 + --> $DIR/safe-intrinsic-mismatch.rs:16:1 | LL | const fn assume(_b: bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: intrinsic has wrong type - --> $DIR/safe-intrinsic-mismatch.rs:11:16 + --> $DIR/safe-intrinsic-mismatch.rs:16:16 | LL | const fn assume(_b: bool) {} | ^ expected unsafe fn, found safe fn @@ -28,13 +28,13 @@ LL | const fn assume(_b: bool) {} found signature `fn(_)` error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate` - --> $DIR/safe-intrinsic-mismatch.rs:15:1 + --> $DIR/safe-intrinsic-mismatch.rs:20:1 | LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: intrinsic has wrong type - --> $DIR/safe-intrinsic-mismatch.rs:15:26 + --> $DIR/safe-intrinsic-mismatch.rs:20:26 | LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} | ^ expected unsafe fn, found safe fn diff --git a/tests/ui/issues/issue-20676.rs b/tests/ui/issues/issue-20676.rs index b3319950b42..2059365c7d6 100644 --- a/tests/ui/issues/issue-20676.rs +++ b/tests/ui/issues/issue-20676.rs @@ -8,5 +8,5 @@ use std::fmt; fn main() { let a: &dyn fmt::Debug = &1; - format!("{:?}", a); + let _ = format!("{:?}", a); } diff --git a/tests/ui/lint/lint-unconditional-recursion-tail-calls.rs b/tests/ui/lint/lint-unconditional-recursion-tail-calls.rs new file mode 100644 index 00000000000..c94bf032579 --- /dev/null +++ b/tests/ui/lint/lint-unconditional-recursion-tail-calls.rs @@ -0,0 +1,24 @@ +#![allow(incomplete_features, dead_code)] +#![deny(unconditional_recursion)] //~ note: the lint level is defined here +#![feature(explicit_tail_calls)] + +fn f(x: bool) { + //~^ error: function cannot return without recursing + //~| note: cannot return without recursing + if x { + become f(!x) + } else { + f(!x) //~ note: recursive call site + } +} + +// This should *not* lint, tail-recursive functions which never return is a reasonable thing +fn g(x: bool) { + if x { + become g(!x) + } else { + become g(!x) + } +} + +fn main() {} diff --git a/tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr b/tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr new file mode 100644 index 00000000000..52f9740d027 --- /dev/null +++ b/tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr @@ -0,0 +1,18 @@ +error: function cannot return without recursing + --> $DIR/lint-unconditional-recursion-tail-calls.rs:5:1 + | +LL | fn f(x: bool) { + | ^^^^^^^^^^^^^ cannot return without recursing +... +LL | f(!x) + | ----- recursive call site + | + = help: a `loop` may express intention better if this is on purpose +note: the lint level is defined here + --> $DIR/lint-unconditional-recursion-tail-calls.rs:2:9 + | +LL | #![deny(unconditional_recursion)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs b/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs index e44eeffb01b..1acefa314aa 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs @@ -37,6 +37,16 @@ macro_rules! without_dollar_sign_is_an_ident { }; } +macro_rules! literals { + ($ident:ident) => {{ + let ${concat(_a, "_b")}: () = (); + let ${concat("_b", _a)}: () = (); + + let ${concat($ident, "_b")}: () = (); + let ${concat("_b", $ident)}: () = (); + }}; +} + fn main() { create_things!(behold); behold_separated_idents_in_a_fn(); @@ -55,4 +65,6 @@ fn main() { without_dollar_sign_is_an_ident!(_123); assert_eq!(VARident, 1); assert_eq!(VAR_123, 2); + + literals!(_hello); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs index f72b9baca89..b1cb2141cc4 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs @@ -26,14 +26,14 @@ macro_rules! idents_11 { macro_rules! no_params { () => { let ${concat(r#abc, abc)}: () = (); - //~^ ERROR `${concat(..)}` currently does not support raw identifiers + //~^ ERROR expected identifier or string literal //~| ERROR expected pattern, found `$` let ${concat(abc, r#abc)}: () = (); - //~^ ERROR `${concat(..)}` currently does not support raw identifiers + //~^ ERROR expected identifier or string literal let ${concat(r#abc, r#abc)}: () = (); - //~^ ERROR `${concat(..)}` currently does not support raw identifiers + //~^ ERROR expected identifier or string literal }; } diff --git a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr index dd525cf0801..4e11e20acc5 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr @@ -1,16 +1,16 @@ -error: `${concat(..)}` currently does not support raw identifiers +error: expected identifier or string literal --> $DIR/raw-identifiers.rs:28:22 | LL | let ${concat(r#abc, abc)}: () = (); | ^^^^^ -error: `${concat(..)}` currently does not support raw identifiers +error: expected identifier or string literal --> $DIR/raw-identifiers.rs:32:27 | LL | let ${concat(abc, r#abc)}: () = (); | ^^^^^ -error: `${concat(..)}` currently does not support raw identifiers +error: expected identifier or string literal --> $DIR/raw-identifiers.rs:35:22 | LL | let ${concat(r#abc, r#abc)}: () = (); diff --git a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs index bf47442ea76..b2845c8d1c1 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs @@ -11,9 +11,6 @@ macro_rules! wrong_concat_declarations { ${concat(aaaa,)} //~^ ERROR expected identifier - ${concat(aaaa, 1)} - //~^ ERROR expected identifier - ${concat(_, aaaa)} ${concat(aaaa aaaa)} @@ -30,9 +27,6 @@ macro_rules! wrong_concat_declarations { ${concat($ex, aaaa,)} //~^ ERROR expected identifier - - ${concat($ex, aaaa, 123)} - //~^ ERROR expected identifier }; } @@ -43,8 +37,80 @@ macro_rules! dollar_sign_without_referenced_ident { }; } +macro_rules! starting_number { + ($ident:ident) => {{ + let ${concat("1", $ident)}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! starting_valid_unicode { + ($ident:ident) => {{ + let ${concat("Ý", $ident)}: () = (); + }}; +} + +macro_rules! starting_invalid_unicode { + ($ident:ident) => {{ + let ${concat("\u{00BD}", $ident)}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! ending_number { + ($ident:ident) => {{ + let ${concat($ident, "1")}: () = (); + }}; +} + +macro_rules! ending_valid_unicode { + ($ident:ident) => {{ + let ${concat($ident, "Ý")}: () = (); + }}; +} + +macro_rules! ending_invalid_unicode { + ($ident:ident) => {{ + let ${concat($ident, "\u{00BD}")}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! empty { + () => {{ + let ${concat("", "")}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! unsupported_literals { + ($ident:ident) => {{ + let ${concat(_a, 'b')}: () = (); + //~^ ERROR expected identifier or string literal + //~| ERROR expected pattern + let ${concat(_a, 1)}: () = (); + //~^ ERROR expected identifier or string literal + + let ${concat($ident, 'b')}: () = (); + //~^ ERROR expected identifier or string literal + let ${concat($ident, 1)}: () = (); + //~^ ERROR expected identifier or string literal + }}; +} + fn main() { wrong_concat_declarations!(1); dollar_sign_without_referenced_ident!(VAR); + + starting_number!(_abc); + starting_valid_unicode!(_abc); + starting_invalid_unicode!(_abc); + + ending_number!(_abc); + ending_valid_unicode!(_abc); + ending_invalid_unicode!(_abc); + unsupported_literals!(_abc); + + empty!(); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr index b216a86d59a..2fe5842b39e 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr @@ -1,4 +1,4 @@ -error: expected identifier +error: expected identifier or string literal --> $DIR/syntax-errors.rs:5:10 | LL | ${concat()} @@ -10,59 +10,126 @@ error: `concat` must have at least two elements LL | ${concat(aaaa)} | ^^^^^^ -error: expected identifier +error: expected identifier or string literal --> $DIR/syntax-errors.rs:11:10 | LL | ${concat(aaaa,)} | ^^^^^^^^^^^^^^^ -error: expected identifier, found `1` - --> $DIR/syntax-errors.rs:14:24 - | -LL | ${concat(aaaa, 1)} - | ^ help: try removing `1` - error: expected comma - --> $DIR/syntax-errors.rs:19:10 + --> $DIR/syntax-errors.rs:16:10 | LL | ${concat(aaaa aaaa)} | ^^^^^^^^^^^^^^^^^^^ error: `concat` must have at least two elements - --> $DIR/syntax-errors.rs:22:11 + --> $DIR/syntax-errors.rs:19:11 | LL | ${concat($ex)} | ^^^^^^ error: expected comma - --> $DIR/syntax-errors.rs:28:10 + --> $DIR/syntax-errors.rs:25:10 | LL | ${concat($ex, aaaa 123)} | ^^^^^^^^^^^^^^^^^^^^^^^ -error: expected identifier - --> $DIR/syntax-errors.rs:31:10 +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:28:10 | LL | ${concat($ex, aaaa,)} | ^^^^^^^^^^^^^^^^^^^^ -error: expected identifier, found `123` - --> $DIR/syntax-errors.rs:34:29 +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:88:26 | -LL | ${concat($ex, aaaa, 123)} - | ^^^ help: try removing `123` +LL | let ${concat(_a, 'b')}: () = (); + | ^^^ + +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:91:26 + | +LL | let ${concat(_a, 1)}: () = (); + | ^ + +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:94:30 + | +LL | let ${concat($ident, 'b')}: () = (); + | ^^^ + +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:96:30 + | +LL | let ${concat($ident, 1)}: () = (); + | ^ error: `${concat(..)}` currently only accepts identifiers or meta-variables as parameters - --> $DIR/syntax-errors.rs:25:19 + --> $DIR/syntax-errors.rs:22:19 | LL | ${concat($ex, aaaa)} | ^^ error: variable `foo` is not recognized in meta-variable expression - --> $DIR/syntax-errors.rs:41:30 + --> $DIR/syntax-errors.rs:35:30 | LL | const ${concat(FOO, $foo)}: i32 = 2; | ^^^ -error: aborting due to 11 previous errors +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:42:14 + | +LL | let ${concat("1", $ident)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^ +... +LL | starting_number!(_abc); + | ---------------------- in this macro invocation + | + = note: this error originates in the macro `starting_number` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:55:14 + | +LL | let ${concat("\u{00BD}", $ident)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | starting_invalid_unicode!(_abc); + | ------------------------------- in this macro invocation + | + = note: this error originates in the macro `starting_invalid_unicode` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:74:14 + | +LL | let ${concat($ident, "\u{00BD}")}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | ending_invalid_unicode!(_abc); + | ----------------------------- in this macro invocation + | + = note: this error originates in the macro `ending_invalid_unicode` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected pattern, found `$` + --> $DIR/syntax-errors.rs:88:13 + | +LL | let ${concat(_a, 'b')}: () = (); + | ^ expected pattern +... +LL | unsupported_literals!(_abc); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `unsupported_literals` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:81:14 + | +LL | let ${concat("", "")}: () = (); + | ^^^^^^^^^^^^^^^^ +... +LL | empty!(); + | -------- in this macro invocation + | + = note: this error originates in the macro `empty` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 18 previous errors diff --git a/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs b/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs new file mode 100644 index 00000000000..b2cfb211e2d --- /dev/null +++ b/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs @@ -0,0 +1,14 @@ +//@ run-pass + +#![feature(macro_metavar_expr_concat)] + +macro_rules! turn_to_page { + ($ident:ident) => { + const ${concat("Ḧ", $ident)}: i32 = 394; + }; +} + +fn main() { + turn_to_page!(P); + assert_eq!(ḦP, 394); +} diff --git a/tests/ui/macros/out-of-scope-calls-false-positives.rs b/tests/ui/macros/out-of-scope-calls-false-positives.rs new file mode 100644 index 00000000000..8d696c177e4 --- /dev/null +++ b/tests/ui/macros/out-of-scope-calls-false-positives.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ needs-asm-support + +macro_rules! mac { () => { "" } } +macro_rules! mac2 { () => { "auxiliary/issue-40469.rs" } } + +std::arch::global_asm!(mac!()); // OK +include!(mac2!()); // OK + +fn main() {} diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index 8e4ba192d79..2c44ad2e0a4 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -190,7 +190,7 @@ error: unrecognized meta-variable expression LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; | ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and len -error: expected identifier +error: expected identifier or string literal --> $DIR/syntax-errors.rs:118:33 | LL | ( $( $i:ident ),* ) => { ${ {} } }; diff --git a/tests/ui/mir/alignment/misaligned-constant-gvn.rs b/tests/ui/mir/alignment/misaligned-constant-gvn.rs new file mode 100644 index 00000000000..363d5c0ed34 --- /dev/null +++ b/tests/ui/mir/alignment/misaligned-constant-gvn.rs @@ -0,0 +1,8 @@ +//@ build-pass +//@ compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN + +fn main() { + let variant: Option<u32> = None; + let transmuted: u64 = unsafe { std::mem::transmute(variant) }; + println!("{transmuted}"); +} diff --git a/tests/ui/mismatched_types/cast-rfc0401.rs b/tests/ui/mismatched_types/cast-rfc0401.rs index 57222f45947..b2ff5b4a0c0 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.rs +++ b/tests/ui/mismatched_types/cast-rfc0401.rs @@ -66,7 +66,7 @@ fn main() let cf: *const dyn Foo = &0; let _ = cf as *const [u16]; //~ ERROR is invalid - let _ = cf as *const dyn Bar; //~ ERROR is invalid + let _ = cf as *const dyn Bar; //~ ERROR casting `*const dyn Foo` as `*const dyn Bar` is invalid vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>(); //~ ERROR is invalid } diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index fbd92f8f662..a75039b8237 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -1,5 +1,5 @@ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:8:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | unsafe { mem::zeroed() } = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:23:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | core::mem::transmute(Zst) = help: specify the type explicitly warning: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:39:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | unsafe { Union { a: () }.b } = help: specify the type explicitly warning: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:49:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:58:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:67:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | unsafe { internally_create(x) } = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:83:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -60,7 +60,7 @@ LL | unsafe { zeroed() } = help: specify the type explicitly warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let zeroed = mem::zeroed; = help: specify the type explicitly warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:98:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | let f = internally_create; = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:122:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:158:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr new file mode 100644 index 00000000000..4138e9f8c86 --- /dev/null +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -0,0 +1,116 @@ +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + | +LL | unsafe { mem::zeroed() } + | ^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 + | +LL | core::mem::transmute(Zst) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this union access + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 + | +LL | unsafe { Union { a: () }.b } + | ^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this raw pointer dereference + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:58:18 + | +LL | unsafe { *ptr::from_ref(&()).cast() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 + | +LL | unsafe { internally_create(x) } + | ^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 + | +LL | unsafe { zeroed() } + | ^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 + | +LL | let zeroed = mem::zeroed; + | ^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 + | +LL | let f = internally_create; + | ^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` method + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 + | +LL | S(marker::PhantomData).create_out_of_thin_air() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:158:19 + | +LL | match send_message::<_ /* ?0 */>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | msg_send!(); + | ----------- in this macro invocation + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> + = help: specify the type explicitly + = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: the type `!` does not permit zero-initialization + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + | +LL | unsafe { mem::zeroed() } + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed + | + = note: the `!` type has no valid value + = note: `#[warn(invalid_value)]` on by default + +error: aborting due to 10 previous errors; 1 warning emitted + diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index d65bfee843e..c96f4dda3f8 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -1,4 +1,9 @@ -//@ check-pass +//@ revisions: e2015 e2024 +//@[e2015] check-pass +//@[e2024] check-fail +//@[e2024] edition:2024 +//@[e2024] compile-flags: -Zunstable-options + use std::{marker, mem, ptr}; fn main() {} @@ -6,8 +11,10 @@ fn main() {} fn _zero() { if false { unsafe { mem::zeroed() } - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! + //[e2024]~| warning: the type `!` does not permit zero-initialization } else { return; }; @@ -21,7 +28,8 @@ fn _trans() { unsafe { struct Zst; core::mem::transmute(Zst) - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! } } else { @@ -37,7 +45,8 @@ fn _union() { } unsafe { Union { a: () }.b } - //~^ warn: never type fallback affects this union access + //[e2015]~^ warn: never type fallback affects this union access + //[e2024]~^^ error: never type fallback affects this union access //~| warn: this will change its meaning in a future release! } else { return; @@ -47,7 +56,8 @@ fn _union() { fn _deref() { if false { unsafe { *ptr::from_ref(&()).cast() } - //~^ warn: never type fallback affects this raw pointer dereference + //[e2015]~^ warn: never type fallback affects this raw pointer dereference + //[e2024]~^^ error: never type fallback affects this raw pointer dereference //~| warn: this will change its meaning in a future release! } else { return; @@ -57,7 +67,9 @@ fn _deref() { fn _only_generics() { if false { unsafe fn internally_create<T>(_: Option<T>) { - let _ = mem::zeroed::<T>(); + unsafe { + let _ = mem::zeroed::<T>(); + } } // We need the option (and unwrap later) to call a function in a way, @@ -65,7 +77,8 @@ fn _only_generics() { let x = None; unsafe { internally_create(x) } - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! x.unwrap() @@ -77,11 +90,13 @@ fn _only_generics() { fn _stored_function() { if false { let zeroed = mem::zeroed; - //~^ warn: never type fallback affects this `unsafe` function + //[e2015]~^ warn: never type fallback affects this `unsafe` function + //[e2024]~^^ error: never type fallback affects this `unsafe` function //~| warn: this will change its meaning in a future release! unsafe { zeroed() } - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! } else { return; @@ -91,12 +106,15 @@ fn _stored_function() { fn _only_generics_stored_function() { if false { unsafe fn internally_create<T>(_: Option<T>) { - let _ = mem::zeroed::<T>(); + unsafe { + let _ = mem::zeroed::<T>(); + } } let x = None; let f = internally_create; - //~^ warn: never type fallback affects this `unsafe` function + //[e2015]~^ warn: never type fallback affects this `unsafe` function + //[e2024]~^^ error: never type fallback affects this `unsafe` function //~| warn: this will change its meaning in a future release! unsafe { f(x) } @@ -120,7 +138,8 @@ fn _method() { if false { unsafe { S(marker::PhantomData).create_out_of_thin_air() - //~^ warn: never type fallback affects this call to an `unsafe` method + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` method + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` method //~| warn: this will change its meaning in a future release! } } else { @@ -137,7 +156,8 @@ fn _objc() { macro_rules! msg_send { () => { match send_message::<_ /* ?0 */>() { - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! Ok(x) => x, Err(_) => loop {}, diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs index ff6619cbc98..3ede26dbcd0 100644 --- a/tests/ui/parser/bad-let-else-statement.rs +++ b/tests/ui/parser/bad-let-else-statement.rs @@ -147,14 +147,14 @@ fn o() -> Result<(), ()> { }; } -fn p() { - let 0 = become { - () - } else { - //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed - return; - }; -} +// fn p() { // FIXME(explicit_tail_calls): this currently trips an assertion... +// let 0 = become { +// () +// } else { +// // ~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed +// return; +// }; +// } fn q() { let foo = |x: i32| { diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr index 0bf6a346dfb..79d722bb7ac 100644 --- a/tests/ui/parser/bad-let-else-statement.stderr +++ b/tests/ui/parser/bad-let-else-statement.stderr @@ -204,19 +204,6 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:153:5 - | -LL | } else { - | ^ - | -help: wrap the expression in parentheses - | -LL ~ let 0 = become ({ -LL | () -LL ~ }) else { - | - -error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:163:5 | LL | } else { @@ -325,5 +312,5 @@ LL | | } else { = note: this pattern will always match, so the `else` clause is useless = help: consider removing the `else` clause -error: aborting due to 20 previous errors; 5 warnings emitted +error: aborting due to 19 previous errors; 5 warnings emitted diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 3c44c1c249c..2f624f24804 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | LL | field: u32, - | ---------- a field by that name exists in `Self` + | ----- a field by that name exists in `Self` ... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here @@ -14,7 +14,7 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | LL | field: u32, - | ---------- a field by that name exists in `Self` + | ----- a field by that name exists in `Self` ... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 5f75ae98870..74a2c9268a2 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:39:5 | LL | whiskers: isize, - | --------------- a field by that name exists in `Self` + | -------- a field by that name exists in `Self` ... LL | whiskers -= other; | ^^^^^^^^ @@ -35,7 +35,7 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 | LL | whiskers: isize, - | --------------- a field by that name exists in `Self` + | -------- a field by that name exists in `Self` ... LL | whiskers = 4; | ^^^^^^^^ diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index a2ab8644353..8737cf77001 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:8:21 | LL | banana: u8, - | ---------- a field by that name exists in `Self` + | ------ a field by that name exists in `Self` ... LL | banana: banana | ^^^^^^ diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 0306c8af87d..5662021a2d5 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | LL | config: String, - | -------------- a field by that name exists in `Self` + | ------ a field by that name exists in `Self` ... LL | Self { config } | ^^^^^^ help: a local variable with a similar name exists: `cofig` @@ -11,7 +11,7 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | LL | config: String, - | -------------- a field by that name exists in `Self` + | ------ a field by that name exists in `Self` ... LL | println!("{config}"); | ^^^^^^ help: a local variable with a similar name exists: `cofig` diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index e3de0a3fb74..f039eef2e06 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `cx` in this scope --> $DIR/unresolved_static_type_field.rs:9:11 | LL | cx: bool, - | -------- a field by that name exists in `Self` + | -- a field by that name exists in `Self` ... LL | f(cx); | ^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index af88a73b4d6..63c353c7d66 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -1,12 +1,16 @@ //@ known-bug: #110395 +//@ failure-status: 101 +//@ normalize-stderr-test ".*note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ rustc-env:RUST_BACKTRACE=0 // FIXME(effects) check-pass -// FIXME(effects) fix intrinsics const parameter counting +//@ compile-flags: -Znext-solver #![crate_type = "lib"] #![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs, staged_api)] -#![feature(fundamental)] +#![feature(fundamental, marker_trait_attr)] #![feature(const_trait_impl, effects, const_mut_refs)] -#![allow(internal_features)] +#![allow(internal_features, incomplete_features)] #![no_std] #![no_core] #![stable(feature = "minicore", since = "1.0.0")] @@ -532,3 +536,35 @@ fn test_const_eval_select() { const_eval_select((), const_fn, rt_fn); } + +mod effects { + use super::Sized; + + #[lang = "EffectsNoRuntime"] + pub struct NoRuntime; + #[lang = "EffectsMaybe"] + pub struct Maybe; + #[lang = "EffectsRuntime"] + pub struct Runtime; + + #[lang = "EffectsCompat"] + pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} + + impl Compat<false> for NoRuntime {} + impl Compat<true> for Runtime {} + impl<#[rustc_runtime] const RUNTIME: bool> Compat<RUNTIME> for Maybe {} + + #[lang = "EffectsTyCompat"] + #[marker] + pub trait TyCompat<T: ?Sized> {} + + impl<T: ?Sized> TyCompat<T> for T {} + impl<T: ?Sized> TyCompat<T> for Maybe {} + impl<T: ?Sized> TyCompat<Maybe> for T {} + + #[lang = "EffectsIntersection"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] + type Output: ?Sized; + } +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index 1963332b856..823ab69df9c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -1,17 +1,13 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/minicore.rs:8:30 - | -LL | #![feature(const_trait_impl, effects, const_mut_refs)] - | ^^^^^^^ - | - = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information - = note: `#[warn(incomplete_features)]` on by default +error: the compiler unexpectedly panicked. this is a bug. -error: requires `EffectsCompat` lang_item - --> $DIR/minicore.rs:455:9 - | -LL | impl<T: Clone> Clone for RefCell<T> { - | ^^^^^ +query stack during panic: +#0 [check_well_formed] checking that `<impl at $DIR/minicore.rs:459:1: 459:36>` is well-formed +#1 [check_mod_type_wf] checking that types are well-formed in top-level module +end of query stack -error: aborting due to 1 previous error; 1 warning emitted +error: the compiler unexpectedly panicked. this is a bug. +query stack during panic: +#0 [check_well_formed] checking that `drop` is well-formed +#1 [check_mod_type_wf] checking that types are well-formed in top-level module +end of query stack diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr deleted file mode 100644 index 03536dca1e8..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` - --> $DIR/issue-100222.rs:34:12 - | -LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output - | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` - | - = note: expected unit type `()` - found mutable reference `&mut <() as Index>::Output` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr deleted file mode 100644 index 6a70a503606..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` - --> $DIR/issue-100222.rs:25:12 - | -LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output - | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` - | - = note: expected unit type `()` - found mutable reference `&mut <() as Index>::Output` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs index 7949772a2b4..47f9fc664ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs @@ -1,6 +1,7 @@ //@ revisions: nn ny yn yy -//@ known-bug: #110395 //@ compile-flags: -Znext-solver +//@ check-pass + #![allow(incomplete_features)] #![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr deleted file mode 100644 index 03536dca1e8..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` - --> $DIR/issue-100222.rs:34:12 - | -LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output - | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` - | - = note: expected unit type `()` - found mutable reference `&mut <() as Index>::Output` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr deleted file mode 100644 index 6a70a503606..00000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` - --> $DIR/issue-100222.rs:25:12 - | -LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output - | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` - | - = note: expected unit type `()` - found mutable reference `&mut <() as Index>::Output` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed index e072c476c6b..4e562193f0d 100644 --- a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed +++ b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed @@ -3,9 +3,9 @@ trait Trait {} -fn assert_send(ptr: *mut dyn Trait) -> *mut (dyn Trait + Send) { +fn assert_send() -> *mut (dyn Trait + Send) { //~^ ERROR incorrect parentheses around trait bounds - ptr as _ + loop {} } fn foo2(_: &(dyn Trait + Send)) {} diff --git a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs index 88995141426..4a00059400c 100644 --- a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs +++ b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs @@ -3,9 +3,9 @@ trait Trait {} -fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) { +fn assert_send() -> *mut dyn (Trait + Send) { //~^ ERROR incorrect parentheses around trait bounds - ptr as _ + loop {} } fn foo2(_: &dyn (Trait + Send)) {} diff --git a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr index 2d1abe91a1e..c67557fa14f 100644 --- a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr +++ b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr @@ -1,13 +1,13 @@ error: incorrect parentheses around trait bounds - --> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:6:49 + --> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:6:30 | -LL | fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) { - | ^ ^ +LL | fn assert_send() -> *mut dyn (Trait + Send) { + | ^ ^ | help: fix the parentheses | -LL - fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) { -LL + fn assert_send(ptr: *mut dyn Trait) -> *mut (dyn Trait + Send) { +LL - fn assert_send() -> *mut dyn (Trait + Send) { +LL + fn assert_send() -> *mut (dyn Trait + Send) { | error: incorrect parentheses around trait bounds diff --git a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr index e0b23bd8110..c2029a5a1c8 100644 --- a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr +++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr @@ -17,10 +17,6 @@ note: required by a bound in `is_send` | LL | fn is_send(_: impl Send) {} | ^^^^ required by this bound in `is_send` -help: consider dereferencing here - | -LL | is_send(*foo()); - | + error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/typeck/receiver-self-ty-check-eq.rs b/tests/ui/traits/next-solver/typeck/receiver-self-ty-check-eq.rs new file mode 100644 index 00000000000..f8c8a17b7e5 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/receiver-self-ty-check-eq.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Fixes a regression in `receiver_is_valid` in wfcheck where we were using +// `InferCtxt::can_eq` instead of processing alias-relate goals, leading to false +// positives, not deref'ing enough steps to check the receiver is valid. + +trait Mirror { + type Mirror: ?Sized; +} +impl<T: ?Sized> Mirror for T { + type Mirror = T; +} + +trait Foo { + fn foo(&self) {} +} + +impl Foo for <() as Mirror>::Mirror { + fn foo(&self) {} +} + +fn main() {} diff --git a/tests/ui/traits/upcast_soundness_bug.rs b/tests/ui/traits/upcast_soundness_bug.rs index 95b48cdf379..5eaa58f7efe 100644 --- a/tests/ui/traits/upcast_soundness_bug.rs +++ b/tests/ui/traits/upcast_soundness_bug.rs @@ -1,7 +1,8 @@ #![feature(trait_upcasting)] -//@ known-bug: #120222 -//@ check-pass -//! This will segfault at runtime. +//@ check-fail +// +// issue: <https://github.com/rust-lang/rust/pull/120222> +//! This would segfault at runtime. pub trait SupSupA { fn method(&self) {} @@ -56,6 +57,7 @@ pub fn user2() -> &'static dyn Trait<u8, u16> { fn main() { let p: *const dyn Trait<u8, u8> = &(); let p = p as *const dyn Trait<u8, u16>; // <- this is bad! + //~^ error: mismatched types let p = p as *const dyn Super<u16>; // <- this upcast accesses improper vtable entry // accessing from L__unnamed_2 the position for the 'Super<u16> vtable (pointer)', // thus reading 'null pointer for missing_method' diff --git a/tests/ui/traits/upcast_soundness_bug.stderr b/tests/ui/traits/upcast_soundness_bug.stderr new file mode 100644 index 00000000000..5864abcdb41 --- /dev/null +++ b/tests/ui/traits/upcast_soundness_bug.stderr @@ -0,0 +1,13 @@ +error[E0308]: mismatched types + --> $DIR/upcast_soundness_bug.rs:59:13 + | +LL | let p = p as *const dyn Trait<u8, u16>; // <- this is bad! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` + | + = note: expected trait object `dyn Trait<u8, u8>` + found trait object `dyn Trait<u8, u16>` + = help: `dyn Trait<u8, u16>` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr index e992d059daf..09efd7a9e7e 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr @@ -8,7 +8,7 @@ LL | fn bar(self: Bar<u32>) { = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) error[E0307]: invalid `self` parameter type: `&Bar<u32>` - --> $DIR/method_resolution3.rs:21:18 + --> $DIR/method_resolution3.rs:20:18 | LL | fn baz(self: &Bar<u32>) { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr index 9272017cdf5..09efd7a9e7e 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr @@ -1,15 +1,21 @@ -error[E0271]: type mismatch resolving `Foo == u32` +error[E0307]: invalid `self` parameter type: `Bar<u32>` --> $DIR/method_resolution3.rs:16:18 | LL | fn bar(self: Bar<u32>) { - | ^^^^^^^^ types differ + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) -error[E0271]: type mismatch resolving `Foo == u32` - --> $DIR/method_resolution3.rs:21:18 +error[E0307]: invalid `self` parameter type: `&Bar<u32>` + --> $DIR/method_resolution3.rs:20:18 | LL | fn baz(self: &Bar<u32>) { - | ^^^^^^^^^ types differ + | ^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.rs b/tests/ui/type-alias-impl-trait/method_resolution3.rs index 447f3144b82..0e6176bfe03 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution3.rs @@ -14,13 +14,11 @@ struct Bar<T>(T); impl Bar<Foo> { fn bar(self: Bar<u32>) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + //~^ ERROR: invalid `self` parameter self.foo() } fn baz(self: &Bar<u32>) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + //~^ ERROR: invalid `self` parameter self.foo() } } diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr index 3a2ca18f890..8ffdb21f251 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr @@ -8,7 +8,7 @@ LL | fn foo(self: Bar<Foo>) { = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) error[E0307]: invalid `self` parameter type: `&Bar<Foo>` - --> $DIR/method_resolution4.rs:32:20 + --> $DIR/method_resolution4.rs:31:20 | LL | fn foomp(self: &Bar<Foo>) { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr index 33ed2800ebe..8ffdb21f251 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr @@ -1,15 +1,21 @@ -error[E0271]: type mismatch resolving `u32 == Foo` +error[E0307]: invalid `self` parameter type: `Bar<Foo>` --> $DIR/method_resolution4.rs:27:18 | LL | fn foo(self: Bar<Foo>) { - | ^^^^^^^^ types differ + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) -error[E0271]: type mismatch resolving `u32 == Foo` - --> $DIR/method_resolution4.rs:32:20 +error[E0307]: invalid `self` parameter type: `&Bar<Foo>` + --> $DIR/method_resolution4.rs:31:20 | LL | fn foomp(self: &Bar<Foo>) { - | ^^^^^^^^^ types differ + | ^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.rs b/tests/ui/type-alias-impl-trait/method_resolution4.rs index 42ed04b3c30..f33b4e473ae 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution4.rs @@ -25,13 +25,11 @@ impl Bar<Foo> { impl Bar<u32> { fn foo(self: Bar<Foo>) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `u32 == Foo` + //~^ ERROR: invalid `self` parameter self.bar() } fn foomp(self: &Bar<Foo>) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `u32 == Foo` + //~^ ERROR: invalid `self` parameter self.bar() } } diff --git a/tests/ui/typeck/ice-with-expr-not-struct-127332.rs b/tests/ui/typeck/ice-with-expr-not-struct-127332.rs new file mode 100644 index 00000000000..f3ea360e7e9 --- /dev/null +++ b/tests/ui/typeck/ice-with-expr-not-struct-127332.rs @@ -0,0 +1,15 @@ +// Regression test for ICE #127332 + +// Tests that we do not ICE when a with expr is +// not a struct but something else like an enum + +fn main() { + let x = || { + enum Foo { + A { x: u32 }, + } + let orig = Foo::A { x: 5 }; + Foo::A { x: 6, ..orig }; + //~^ ERROR functional record update syntax requires a struct + }; +} diff --git a/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr b/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr new file mode 100644 index 00000000000..446f49e8639 --- /dev/null +++ b/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr @@ -0,0 +1,9 @@ +error[E0436]: functional record update syntax requires a struct + --> $DIR/ice-with-expr-not-struct-127332.rs:12:26 + | +LL | Foo::A { x: 6, ..orig }; + | ^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0436`. |
