From e645e51d97ff550adc6ba3598802f6855a366f20 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 20:13:10 +0100 Subject: [PATCH 01/19] Remove an outdated test This... is a weird test. It has two impls: - `impl From> for Box` (commented out, more on that later), and - `impl Into> for Foo` The idea of that test is to show that the first impl doesn't compile, but the second does, thus `TryFrom` should be using `Into` and not `From` (because `Into` is more general, since the `From` impl doesn't compile). However: 1. The types are different -- `Box` vs `Vec`, which is significant b/c `Box` is fundamental 2. The commented out impl actually compiles! (which wasn't detected b/c it's commented out :\ ) Here is a table for compilation of the impls: | | `Vec` | `Box` | |--------|--------------|----------------| | `From` | since 1.41.0 | never | | `Into` | always | not since 1.28 | [godbolt used to test this](https://godbolt.org/z/T38E3jGKa) Order of events: 1. in `1.28` the `incoherent_fundamental_impls` lint becomes deny by default (this is *not* mentioned in the changelog yay) 2. `1.32` changed absolutely nothing, even though this version is credited in the test 3. the test was added (I'm not exactly sure when) (see https://github.com/rust-lang/rust/pull/56796) 4. in `1.41` coherence was relaxed to allow `From`+`Vec` to compile To conclude: since `1.41` this test does nothing (and before that it was written in a way which did not detect this change). It looks to me like today (since `1.41`) we *could* bound `TryFrom` impl with `From` (but now it'd be a useless breaking change of course). Am I missing anything? Is there a useful version of this test that could be written? --- tests/ui/never_type/try_from.rs | 37 --------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 tests/ui/never_type/try_from.rs diff --git a/tests/ui/never_type/try_from.rs b/tests/ui/never_type/try_from.rs deleted file mode 100644 index acde524e98f5b..0000000000000 --- a/tests/ui/never_type/try_from.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ run-pass -// This test relies on `TryFrom` being blanket impl for all `T: Into` -// and `TryInto` being blanket impl for all `U: TryFrom` - -// This test was added to show the motivation for doing this -// over `TryFrom` being blanket impl for all `T: From` - -#![feature(never_type)] - -use std::convert::{TryInto, Infallible}; - -struct Foo { - t: T, -} - -// This fails to compile due to coherence restrictions -// as of Rust version 1.32.x, therefore it could not be used -// instead of the `Into` version of the impl, and serves as -// motivation for a blanket impl for all `T: Into`, instead -// of a blanket impl for all `T: From` -/* -impl From> for Box { - fn from(foo: Foo) -> Box { - Box::new(foo.t) - } -} -*/ - -impl Into> for Foo { - fn into(self) -> Vec { - vec![self.t] - } -} - -pub fn main() { - let _: Result, Infallible> = Foo { t: 10 }.try_into(); -} From a37873d7fb5903f1545b913a14f4aaa0306822a6 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 1 Dec 2025 16:41:39 +0100 Subject: [PATCH 02/19] add a coretest checking `TryInto`/`TryFrom` impls --- library/coretests/tests/convert.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/coretests/tests/convert.rs b/library/coretests/tests/convert.rs index f1048f4cf09cb..1eb7468e56ea7 100644 --- a/library/coretests/tests/convert.rs +++ b/library/coretests/tests/convert.rs @@ -14,3 +14,20 @@ fn convert() { const BAR: Vec = into(Vec::new()); assert_eq!(BAR, Vec::::new()); } + +#[test] +fn into_as_try_into() { + struct A; + struct B; + + impl Into for A { + fn into(self) -> B { + B + } + } + + // This wouldn't compile if the `TryInto`/`TryFrom` blanket impls used + // `U: From` instead of `T: Into` + let Ok(B) = A.try_into(); + let Ok(B) = B::try_from(A); +} From d60f7800ef5fb3996a8c74f57b9932ab913448af Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 23 Nov 2025 11:21:06 -0300 Subject: [PATCH 03/19] This statement is misleading --- library/core/src/mem/mod.rs | 4 +--- tests/ui/thir-print/offset_of.stdout | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index f4fcc9b1f3665..ad5fda0cfe4db 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -898,8 +898,6 @@ pub const fn replace(dest: &mut T, src: T) -> T { /// Disposes of a value. /// -/// This does so by calling the argument's implementation of [`Drop`][drop]. -/// /// This effectively does nothing for types which implement `Copy`, e.g. /// integers. Such values are copied and _then_ moved into the function, so the /// value persists after this function call. @@ -910,7 +908,7 @@ pub const fn replace(dest: &mut T, src: T) -> T { /// pub fn drop(_x: T) {} /// ``` /// -/// Because `_x` is moved into the function, it is automatically dropped before +/// Because `_x` is moved into the function, it is automatically [dropped][drop] before /// the function returns. /// /// [drop]: Drop diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index e1b6ea9349b42..846817f475288 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -68,7 +68,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) - span: $DIR/offset_of.rs:37:5: 1435:57 (#0) + span: $DIR/offset_of.rs:37:5: 1433:57 (#0) } } Stmt { @@ -117,7 +117,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) - span: $DIR/offset_of.rs:38:5: 1435:57 (#0) + span: $DIR/offset_of.rs:38:5: 1433:57 (#0) } } Stmt { @@ -166,7 +166,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) - span: $DIR/offset_of.rs:39:5: 1435:57 (#0) + span: $DIR/offset_of.rs:39:5: 1433:57 (#0) } } Stmt { @@ -215,7 +215,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) - span: $DIR/offset_of.rs:40:5: 1435:57 (#0) + span: $DIR/offset_of.rs:40:5: 1433:57 (#0) } } Stmt { @@ -264,7 +264,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) - span: $DIR/offset_of.rs:41:5: 1435:57 (#0) + span: $DIR/offset_of.rs:41:5: 1433:57 (#0) } } ] @@ -864,7 +864,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).12)) - span: $DIR/offset_of.rs:45:5: 1435:57 (#0) + span: $DIR/offset_of.rs:45:5: 1433:57 (#0) } } Stmt { @@ -913,7 +913,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).24)) - span: $DIR/offset_of.rs:46:5: 1435:57 (#0) + span: $DIR/offset_of.rs:46:5: 1433:57 (#0) } } Stmt { @@ -962,7 +962,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).36)) - span: $DIR/offset_of.rs:47:5: 1435:57 (#0) + span: $DIR/offset_of.rs:47:5: 1433:57 (#0) } } Stmt { @@ -1011,7 +1011,7 @@ body: ) else_block: None lint_level: Explicit(HirId(DefId(offset_of::generic).48)) - span: $DIR/offset_of.rs:48:5: 1435:57 (#0) + span: $DIR/offset_of.rs:48:5: 1433:57 (#0) } } ] From 140832aa592997525a94027d2cfe9c6acd7f6bdf Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 15:39:17 +0100 Subject: [PATCH 04/19] update readme wrt never type tests --- tests/ui/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ui/README.md b/tests/ui/README.md index 344b0b2500df9..9864d88ceb079 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -941,6 +941,8 @@ Contains a single test. It imports a massive amount of very similar types from a ## `tests/ui/never_type/` +Tests relating to the never type. Most tests are specifically about the never type fallback behavior. + See [Tracking issue for promoting `!` to a type (RFC 1216) #35121](https://github.com/rust-lang/rust/issues/35121). ## `tests/ui/new-range/` From 3432ff9a1da3a6560bcf33fda3cee5061ab4bebc Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 15:39:17 +0100 Subject: [PATCH 05/19] remove test for `T -> !` coercion We used to allow `T -> !` coercions (yes!! not `! -> T`) in unreachable code. This was later removed during 2018 stabilization attempt, see: - https://github.com/rust-lang/rust/issues/40800 - https://github.com/rust-lang/rust/pull/47630/commits/59688e119e1b9c2506fa9173728ae88eb196bf5e - https://github.com/rust-lang/rust/issues/46325 I've kept `tests/ui/coercion/coerce-to-bang-cast.rs`, as that is a reasonable test for us *not* having `-> !` coercions. --- tests/ui/coercion/coerce-to-bang.rs | 79 -------------- tests/ui/coercion/coerce-to-bang.stderr | 130 ------------------------ 2 files changed, 209 deletions(-) delete mode 100644 tests/ui/coercion/coerce-to-bang.rs delete mode 100644 tests/ui/coercion/coerce-to-bang.stderr diff --git a/tests/ui/coercion/coerce-to-bang.rs b/tests/ui/coercion/coerce-to-bang.rs deleted file mode 100644 index 1e06934d09f9e..0000000000000 --- a/tests/ui/coercion/coerce-to-bang.rs +++ /dev/null @@ -1,79 +0,0 @@ -#![feature(never_type)] - -fn foo(x: usize, y: !, z: usize) { } - -fn call_foo_a() { - foo(return, 22, 44); - //~^ ERROR mismatched types -} - -fn call_foo_b() { - // Divergence happens in the argument itself, definitely ok. - foo(22, return, 44); -} - -fn call_foo_c() { - // This test fails because the divergence happens **after** the - // coercion to `!`: - foo(22, 44, return); //~ ERROR mismatched types -} - -fn call_foo_d() { - // This test passes because `a` has type `!`: - let a: ! = return; - let b = 22; - let c = 44; - foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. - //~^ ERROR mismatched types -} - -fn call_foo_e() { - // This test probably could pass but we don't *know* that `a` - // has type `!` so we don't let it work. - let a = return; - let b = 22; - let c = 44; - foo(a, b, c); //~ ERROR mismatched types -} - -fn call_foo_f() { - // This fn fails because `a` has type `usize`, and hence a - // reference to is it **not** considered to diverge. - let a: usize = return; - let b = 22; - let c = 44; - foo(a, b, c); //~ ERROR mismatched types -} - -fn array_a() { - // Return is coerced to `!` just fine, but `22` cannot be. - let x: [!; 2] = [return, 22]; //~ ERROR mismatched types -} - -fn array_b() { - // Error: divergence has not yet occurred. - let x: [!; 2] = [22, return]; //~ ERROR mismatched types -} - -fn tuple_a() { - // No divergence at all. - let x: (usize, !, usize) = (22, 44, 66); //~ ERROR mismatched types -} - -fn tuple_b() { - // Divergence happens before coercion: OK - let x: (usize, !, usize) = (return, 44, 66); - //~^ ERROR mismatched types -} - -fn tuple_c() { - // Divergence happens before coercion: OK - let x: (usize, !, usize) = (22, return, 66); -} - -fn tuple_d() { - // Error: divergence happens too late - let x: (usize, !, usize) = (22, 44, return); //~ ERROR mismatched types -} - -fn main() { } diff --git a/tests/ui/coercion/coerce-to-bang.stderr b/tests/ui/coercion/coerce-to-bang.stderr deleted file mode 100644 index 3c737358adc77..0000000000000 --- a/tests/ui/coercion/coerce-to-bang.stderr +++ /dev/null @@ -1,130 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:6:17 - | -LL | foo(return, 22, 44); - | --- ^^ expected `!`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type `!` - found type `{integer}` -note: function defined here - --> $DIR/coerce-to-bang.rs:3:4 - | -LL | fn foo(x: usize, y: !, z: usize) { } - | ^^^ ---- - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:18:13 - | -LL | foo(22, 44, return); - | --- ^^ expected `!`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type `!` - found type `{integer}` -note: function defined here - --> $DIR/coerce-to-bang.rs:3:4 - | -LL | fn foo(x: usize, y: !, z: usize) { } - | ^^^ ---- - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:26:12 - | -LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. - | --- ^ expected `!`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type `!` - found type `{integer}` -note: function defined here - --> $DIR/coerce-to-bang.rs:3:4 - | -LL | fn foo(x: usize, y: !, z: usize) { } - | ^^^ ---- - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:36:12 - | -LL | foo(a, b, c); - | --- ^ expected `!`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type `!` - found type `{integer}` -note: function defined here - --> $DIR/coerce-to-bang.rs:3:4 - | -LL | fn foo(x: usize, y: !, z: usize) { } - | ^^^ ---- - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:45:12 - | -LL | foo(a, b, c); - | --- ^ expected `!`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type `!` - found type `{integer}` -note: function defined here - --> $DIR/coerce-to-bang.rs:3:4 - | -LL | fn foo(x: usize, y: !, z: usize) { } - | ^^^ ---- - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:50:21 - | -LL | let x: [!; 2] = [return, 22]; - | ------ ^^^^^^^^^^^^ expected `[!; 2]`, found `[{integer}; 2]` - | | - | expected due to this - | - = note: expected array `[!; 2]` - found array `[{integer}; 2]` - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:55:22 - | -LL | let x: [!; 2] = [22, return]; - | ^^ expected `!`, found integer - | - = note: expected type `!` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:60:37 - | -LL | let x: (usize, !, usize) = (22, 44, 66); - | ^^ expected `!`, found integer - | - = note: expected type `!` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:65:41 - | -LL | let x: (usize, !, usize) = (return, 44, 66); - | ^^ expected `!`, found integer - | - = note: expected type `!` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/coerce-to-bang.rs:76:37 - | -LL | let x: (usize, !, usize) = (22, 44, return); - | ^^ expected `!`, found integer - | - = note: expected type `!` - found type `{integer}` - -error: aborting due to 10 previous errors - -For more information about this error, try `rustc --explain E0308`. From e6d2b2add76bbe223d20134583ccc003a80fc025 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 16:56:42 +0100 Subject: [PATCH 06/19] refactor `Box dyn Error>` regression test --- .../coerce-issue-49593-box-never.e2021.stderr | 19 ++++++ .../coercion/coerce-issue-49593-box-never.rs | 62 +++++++------------ 2 files changed, 40 insertions(+), 41 deletions(-) create mode 100644 tests/ui/coercion/coerce-issue-49593-box-never.e2021.stderr diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.e2021.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.e2021.stderr new file mode 100644 index 0000000000000..214c37febc06b --- /dev/null +++ b/tests/ui/coercion/coerce-issue-49593-box-never.e2021.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `(): std::error::Error` is not satisfied + --> $DIR/coerce-issue-49593-box-never.rs:28:5 + | +LL | Box::new(x) + | ^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` + | + = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` + +error[E0277]: the trait bound `(): std::error::Error` is not satisfied + --> $DIR/coerce-issue-49593-box-never.rs:33:5 + | +LL | raw_ptr(x) + | ^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` + | + = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.rs b/tests/ui/coercion/coerce-issue-49593-box-never.rs index 6706d07e1f764..751450a7fb435 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never.rs +++ b/tests/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,57 +1,37 @@ -//@ revisions: nofallback fallback -//@[fallback] edition: 2024 -//@[fallback] check-pass +// Regression test for . +// +// This checks that we can construct `Box` by calling `Box::new` +// with a value of the never type. And similarly for raw pointers. +// +// This used to fail because we tried to coerce `! -> dyn Error`, which then +// failed because we were trying to pass an unsized value by value, etc. +// +// On edition <= 2021 this currently fails because of never type fallback to +// unit. +// +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +// +//@[e2024] check-pass #![feature(never_type)] use std::error::Error; use std::mem; -fn raw_ptr_box(t: T) -> *mut T { +fn raw_ptr(t: T) -> *mut T { panic!() } fn foo(x: !) -> Box { - // Method resolution will generate new inference vars and relate them. - // Thus fallback will not fall back to `!`, but `()` instead. - Box::<_ /* ! */>::new(x) - //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied + Box::new(x) + //[e2021]~^ ERROR trait bound `(): std::error::Error` is not satisfied } fn foo_raw_ptr(x: !) -> *mut dyn Error { - /* *mut $0 is coerced to *mut Error here */ - raw_ptr_box::<_ /* ! */>(x) - //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied -} - -fn no_coercion(d: *mut dyn Error) -> *mut dyn Error { - /* an unsize coercion won't compile here, and it is indeed not used - because there is nothing requiring the _ to be Sized */ - d as *mut _ -} - -trait Xyz {} -struct S; -struct T; -impl Xyz for S {} -impl Xyz for T {} - -fn foo_no_never() { - let mut x /* : Option */ = None; - let mut first_iter = false; - loop { - if !first_iter { - let y: Box - = /* Box<$0> is coerced to Box here */ Box::new(x.unwrap()); - } - - x = Some(S); - first_iter = true; - } - - let mut y: Option = None; - // assert types are equal - mem::swap(&mut x, &mut y); + raw_ptr(x) + //[e2021]~^ ERROR trait bound `(): std::error::Error` is not satisfied } fn main() {} From 0cbb9e68917a54fde791174dd7424e010309f088 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 17:35:27 +0100 Subject: [PATCH 07/19] expand never type gate test --- .../feature-gates/feature-gate-never_type.rs | 79 +++++++++++++++---- .../feature-gate-never_type.stderr | 68 ++++++++++------ 2 files changed, 106 insertions(+), 41 deletions(-) diff --git a/tests/ui/feature-gates/feature-gate-never_type.rs b/tests/ui/feature-gates/feature-gate-never_type.rs index f5d28a4877fdf..c678d55acd0ff 100644 --- a/tests/ui/feature-gates/feature-gate-never_type.rs +++ b/tests/ui/feature-gates/feature-gate-never_type.rs @@ -1,26 +1,71 @@ // Test that ! errors when used in illegal positions with feature(never_type) disabled -trait Foo { - type Wub; -} +mod ungated { + //! Functions returning `!` directly (as in `-> !`) and function pointers doing the same are + //! allowed with no gates. -type Ma = (u32, !, i32); //~ ERROR type is experimental -type Meeshka = Vec; //~ ERROR type is experimental -type Mow = &'static fn(!) -> !; //~ ERROR type is experimental -type Skwoz = &'static mut !; //~ ERROR type is experimental + fn panic() -> ! { + panic!(); + } -impl Foo for Meeshka { - type Wub = !; //~ ERROR type is experimental + fn takes_fn_ptr(x: fn() -> !) -> ! { + x() + } } -fn look_ma_no_feature_gate !>() {} //~ ERROR type is experimental -fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental -fn panic() -> ! { - panic!(); -} -fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental - panic +mod gated { + //! All other mentions of the type are gated. + + trait Foo { + type Wub; + } + + type Ma = (u32, !, i32); //~ ERROR type is experimental + type Meeshka = Vec; //~ ERROR type is experimental + type Mow = &'static fn(!) -> !; //~ ERROR type is experimental + type Skwoz = &'static mut !; //~ ERROR type is experimental + type Meow = fn() -> Result<(), !>; //~ ERROR type is experimental + + impl Foo for Meeshka { + type Wub = !; //~ ERROR type is experimental + } + + fn look_ma_no_feature_gate !>() {} //~ ERROR type is experimental + + fn tadam(f: &dyn Fn() -> !) {} //~ ERROR type is experimental + + fn toudoum() -> impl Fn() -> ! { //~ ERROR type is experimental + || panic!() + } + + fn infallible() -> Result<(), !> { //~ ERROR type is experimental + Ok(()) + } } -fn main() { +mod hack { + //! There is a hack which, by exploiting the fact that `fn() -> !` can be named stably and that + //! type system does not interact with stability, allows one to mention the never type while + //! avoiding any and all feature gates. It is generally considered a "hack"/compiler bug, and + //! thus users of this hack resign stability guarantees. However, fixing this is more trouble + //! than good. + + trait F { + type Ret; + } + + impl F for fn() -> T { + type Ret = T; + } + + type Never = ! as F>::Ret; + + fn damn( + never: Never, + _: &dyn Fn() -> Never, + ) -> (impl Fn() -> Never, &'static mut Never, Never, u8) { + (|| never, never, never, never) + } } + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-never_type.stderr b/tests/ui/feature-gates/feature-gate-never_type.stderr index 33e4e019b18d3..475aac433b84d 100644 --- a/tests/ui/feature-gates/feature-gate-never_type.stderr +++ b/tests/ui/feature-gates/feature-gate-never_type.stderr @@ -1,83 +1,103 @@ error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:7:17 + --> $DIR/feature-gate-never_type.rs:23:21 | -LL | type Ma = (u32, !, i32); - | ^ +LL | type Ma = (u32, !, i32); + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:8:20 + --> $DIR/feature-gate-never_type.rs:24:24 | -LL | type Meeshka = Vec; - | ^ +LL | type Meeshka = Vec; + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:9:24 + --> $DIR/feature-gate-never_type.rs:25:28 | -LL | type Mow = &'static fn(!) -> !; - | ^ +LL | type Mow = &'static fn(!) -> !; + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:10:27 + --> $DIR/feature-gate-never_type.rs:26:31 | -LL | type Skwoz = &'static mut !; - | ^ +LL | type Skwoz = &'static mut !; + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:13:16 + --> $DIR/feature-gate-never_type.rs:27:36 | -LL | type Wub = !; - | ^ +LL | type Meow = fn() -> Result<(), !>; + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:16:43 + --> $DIR/feature-gate-never_type.rs:30:20 | -LL | fn look_ma_no_feature_gate !>() {} - | ^ +LL | type Wub = !; + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:17:26 + --> $DIR/feature-gate-never_type.rs:33:47 | -LL | fn tadam(f: &dyn Fn() -> !) {} - | ^ +LL | fn look_ma_no_feature_gate !>() {} + | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `!` type is experimental - --> $DIR/feature-gate-never_type.rs:21:30 + --> $DIR/feature-gate-never_type.rs:35:30 | -LL | fn toudoum() -> impl Fn() -> ! { +LL | fn tadam(f: &dyn Fn() -> !) {} | ^ | = note: see issue #35121 for more information = help: add `#![feature(never_type)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 8 previous errors +error[E0658]: the `!` type is experimental + --> $DIR/feature-gate-never_type.rs:37:34 + | +LL | fn toudoum() -> impl Fn() -> ! { + | ^ + | + = note: see issue #35121 for more information + = help: add `#![feature(never_type)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `!` type is experimental + --> $DIR/feature-gate-never_type.rs:41:35 + | +LL | fn infallible() -> Result<(), !> { + | ^ + | + = note: see issue #35121 for more information + = help: add `#![feature(never_type)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0658`. From 98430c4d9d547a7e8dc8171247b6eed09427b922 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 19:00:43 +0100 Subject: [PATCH 08/19] remove unused features from some tests --- tests/ui/lint/unused/issue-103320-must-use-ops.rs | 1 - tests/ui/lint/unused/issue-103320-must-use-ops.stderr | 10 +++++----- tests/ui/never_type/auto-traits.rs | 1 - tests/ui/process/process-panic-after-fork.rs | 1 - 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/ui/lint/unused/issue-103320-must-use-ops.rs b/tests/ui/lint/unused/issue-103320-must-use-ops.rs index 5749fef46908f..bb399fc1aa29c 100644 --- a/tests/ui/lint/unused/issue-103320-must-use-ops.rs +++ b/tests/ui/lint/unused/issue-103320-must-use-ops.rs @@ -1,7 +1,6 @@ //@ check-pass #![warn(unused_must_use)] -#![feature(never_type)] use std::ops::Add; use std::ops::Sub; diff --git a/tests/ui/lint/unused/issue-103320-must-use-ops.stderr b/tests/ui/lint/unused/issue-103320-must-use-ops.stderr index 57439ec6a8fdb..0f32757ed20fd 100644 --- a/tests/ui/lint/unused/issue-103320-must-use-ops.stderr +++ b/tests/ui/lint/unused/issue-103320-must-use-ops.stderr @@ -1,5 +1,5 @@ warning: unused return value of `add` that must be used - --> $DIR/issue-103320-must-use-ops.rs:16:5 + --> $DIR/issue-103320-must-use-ops.rs:15:5 | LL | x.add(4); | ^^^^^^^^ @@ -16,7 +16,7 @@ LL | let _ = x.add(4); | +++++++ warning: unused return value of `sub` that must be used - --> $DIR/issue-103320-must-use-ops.rs:18:5 + --> $DIR/issue-103320-must-use-ops.rs:17:5 | LL | x.sub(4); | ^^^^^^^^ @@ -28,7 +28,7 @@ LL | let _ = x.sub(4); | +++++++ warning: unused return value of `mul` that must be used - --> $DIR/issue-103320-must-use-ops.rs:20:5 + --> $DIR/issue-103320-must-use-ops.rs:19:5 | LL | x.mul(4); | ^^^^^^^^ @@ -40,7 +40,7 @@ LL | let _ = x.mul(4); | +++++++ warning: unused return value of `div` that must be used - --> $DIR/issue-103320-must-use-ops.rs:22:5 + --> $DIR/issue-103320-must-use-ops.rs:21:5 | LL | x.div(4); | ^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = x.div(4); | +++++++ warning: unused return value of `rem` that must be used - --> $DIR/issue-103320-must-use-ops.rs:24:5 + --> $DIR/issue-103320-must-use-ops.rs:23:5 | LL | x.rem(4); | ^^^^^^^^ diff --git a/tests/ui/never_type/auto-traits.rs b/tests/ui/never_type/auto-traits.rs index 8a2b9a1458665..19554f13b0bac 100644 --- a/tests/ui/never_type/auto-traits.rs +++ b/tests/ui/never_type/auto-traits.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(auto_traits)] -#![feature(negative_impls)] #![feature(never_type)] fn main() { diff --git a/tests/ui/process/process-panic-after-fork.rs b/tests/ui/process/process-panic-after-fork.rs index 154ff51878d6e..4632d3b61f7bf 100644 --- a/tests/ui/process/process-panic-after-fork.rs +++ b/tests/ui/process/process-panic-after-fork.rs @@ -8,7 +8,6 @@ //@ ignore-backends: gcc #![feature(rustc_private)] -#![feature(never_type)] #![feature(panic_always_abort)] #![allow(invalid_from_utf8)] From 5dec6b3a56b8852f491e7758ff4c1bed6090a3a3 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 19:56:13 +0100 Subject: [PATCH 09/19] refactor test for note on `!: Tr` error --- .../defaulted-never-note.e2021.stderr | 18 +++++ .../defaulted-never-note.e2024.stderr | 62 ++++++++++++++ .../defaulted-never-note.fallback.stderr | 24 ------ .../defaulted-never-note.nofallback.stderr | 18 ----- tests/ui/never_type/defaulted-never-note.rs | 81 ++++++++++++------- 5 files changed, 131 insertions(+), 72 deletions(-) create mode 100644 tests/ui/never_type/defaulted-never-note.e2021.stderr create mode 100644 tests/ui/never_type/defaulted-never-note.e2024.stderr delete mode 100644 tests/ui/never_type/defaulted-never-note.fallback.stderr delete mode 100644 tests/ui/never_type/defaulted-never-note.nofallback.stderr diff --git a/tests/ui/never_type/defaulted-never-note.e2021.stderr b/tests/ui/never_type/defaulted-never-note.e2021.stderr new file mode 100644 index 0000000000000..96013df5fb0d0 --- /dev/null +++ b/tests/ui/never_type/defaulted-never-note.e2021.stderr @@ -0,0 +1,18 @@ +Future incompatibility report: Future breakage diagnostic: +warning: this function depends on never type fallback being `()` + --> $DIR/defaulted-never-note.rs:38:1 + | +LL | fn main() { + | ^^^^^^^^^ + | + = help: specify the types explicitly +note: in edition 2024, the requirement `!: OnlyUnit` will fail + --> $DIR/defaulted-never-note.rs:40:19 + | +LL | requires_unit(x); + | ^ +help: use `()` annotations to avoid fallback changes + | +LL | let x: () = return; + | ++++ + diff --git a/tests/ui/never_type/defaulted-never-note.e2024.stderr b/tests/ui/never_type/defaulted-never-note.e2024.stderr new file mode 100644 index 0000000000000..d8c6059a67d3f --- /dev/null +++ b/tests/ui/never_type/defaulted-never-note.e2024.stderr @@ -0,0 +1,62 @@ +error[E0277]: the trait bound `!: OnlyUnit` is not satisfied + --> $DIR/defaulted-never-note.rs:40:19 + | +LL | requires_unit(x); + | ------------- ^ the trait `OnlyUnit` is not implemented for `!` + | | + | required by a bound introduced by this call + | +help: the trait `OnlyUnit` is implemented for `()` + --> $DIR/defaulted-never-note.rs:13:1 + | +LL | impl OnlyUnit for () {} + | ^^^^^^^^^^^^^^^^^^^^ + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) + = help: you might have intended to use the type `()` here instead +note: required by a bound in `requires_unit` + --> $DIR/defaulted-never-note.rs:16:26 + | +LL | fn requires_unit(_: impl OnlyUnit) {} + | ^^^^^^^^ required by this bound in `requires_unit` + +error[E0277]: the trait bound `!: OnlyU32` is not satisfied + --> $DIR/defaulted-never-note.rs:48:18 + | +LL | requires_u32(x); + | ------------ ^ the trait `OnlyU32` is not implemented for `!` + | | + | required by a bound introduced by this call + | +help: the trait `OnlyU32` is implemented for `u32` + --> $DIR/defaulted-never-note.rs:23:1 + | +LL | impl OnlyU32 for u32 {} + | ^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `requires_u32` + --> $DIR/defaulted-never-note.rs:26:25 + | +LL | fn requires_u32(_: impl OnlyU32) {} + | ^^^^^^^ required by this bound in `requires_u32` + +error[E0277]: the trait bound `!: Nothing` is not satisfied + --> $DIR/defaulted-never-note.rs:54:22 + | +LL | requires_nothing(x); + | ---------------- ^ the trait `Nothing` is not implemented for `!` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/defaulted-never-note.rs:31:1 + | +LL | trait Nothing {} + | ^^^^^^^^^^^^^ +note: required by a bound in `requires_nothing` + --> $DIR/defaulted-never-note.rs:34:29 + | +LL | fn requires_nothing(_: impl Nothing) {} + | ^^^^^^^ required by this bound in `requires_nothing` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/defaulted-never-note.fallback.stderr b/tests/ui/never_type/defaulted-never-note.fallback.stderr deleted file mode 100644 index 81b01052ba391..0000000000000 --- a/tests/ui/never_type/defaulted-never-note.fallback.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied - --> $DIR/defaulted-never-note.rs:27:9 - | -LL | foo(_x); - | --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` - | | - | required by a bound introduced by this call - | -help: the trait `ImplementedForUnitButNotNever` is implemented for `()` - --> $DIR/defaulted-never-note.rs:20:1 - | -LL | impl ImplementedForUnitButNotNever for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) - = help: you might have intended to use the type `()` here instead -note: required by a bound in `foo` - --> $DIR/defaulted-never-note.rs:22:11 - | -LL | fn foo(_t: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr deleted file mode 100644 index f084985153c6b..0000000000000 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ /dev/null @@ -1,18 +0,0 @@ -Future incompatibility report: Future breakage diagnostic: -warning: this function depends on never type fallback being `()` - --> $DIR/defaulted-never-note.rs:25:1 - | -LL | fn smeg() { - | ^^^^^^^^^ - | - = help: specify the types explicitly -note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail - --> $DIR/defaulted-never-note.rs:27:9 - | -LL | foo(_x); - | ^^ -help: use `()` annotations to avoid fallback changes - | -LL | let _x: () = return; - | ++++ - diff --git a/tests/ui/never_type/defaulted-never-note.rs b/tests/ui/never_type/defaulted-never-note.rs index 71b3e0bcf80a7..79510bbfa0dc0 100644 --- a/tests/ui/never_type/defaulted-never-note.rs +++ b/tests/ui/never_type/defaulted-never-note.rs @@ -1,37 +1,58 @@ -//@ revisions: nofallback fallback -//@[fallback] edition: 2024 -//@[nofallback] run-pass -//@[fallback] check-fail - +// Test diagnostic for the case where a trait is not implemented for `!`. If it is implemented +// for `()`, we want to add a note saying that this might be caused by a breaking change in the +// compiler. +// +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2021] run-pass #![expect(dependency_on_unit_never_type_fallback, unused)] -trait Deserialize: Sized { - fn deserialize() -> Result; -} +trait OnlyUnit {} -impl Deserialize for () { - fn deserialize() -> Result<(), String> { - Ok(()) - } -} +impl OnlyUnit for () {} +//[e2024]~^ help: trait `OnlyUnit` is implemented for `()` -trait ImplementedForUnitButNotNever {} - -impl ImplementedForUnitButNotNever for () {} //[fallback]~ HELP trait `ImplementedForUnitButNotNever` is implemented for `()` - -fn foo(_t: T) {} -//[fallback]~^ note: required by this bound in `foo` -//[fallback]~| note: required by a bound in `foo` -fn smeg() { - let _x = return; - foo(_x); - //[fallback]~^ ERROR the trait bound - //[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented - //[fallback]~| NOTE this error might have been caused - //[fallback]~| NOTE required by a bound introduced by this call - //[fallback]~| HELP you might have intended to use the type `()` -} +fn requires_unit(_: impl OnlyUnit) {} +//[e2024]~^ note: required by this bound in `requires_unit` +//[e2024]~| note: required by a bound in `requires_unit` + + +trait OnlyU32 {} + +impl OnlyU32 for u32 {} +//[e2024]~^ help: the trait `OnlyU32` is implemented for `u32` + +fn requires_u32(_: impl OnlyU32) {} +//[e2024]~^ note: required by this bound in `requires_u32` +//[e2024]~| note: required by a bound in `requires_u32` + + +trait Nothing {} +//[e2024]~^ help: this trait has no implementations, consider adding one + +fn requires_nothing(_: impl Nothing) {} +//[e2024]~^ note: required by this bound in `requires_nothing` +//[e2024]~| note: required by a bound in `requires_nothing` fn main() { - smeg(); + let x = return; + requires_unit(x); + //[e2024]~^ error: the trait bound `!: OnlyUnit` is not satisfied + //[e2024]~| note: the trait `OnlyUnit` is not implemented for `!` + //[e2024]~| note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) + //[e2024]~| note: required by a bound introduced by this call + //[e2024]~| help: you might have intended to use the type `()` + + #[cfg(e2024)] + requires_u32(x); + //[e2024]~^ error: the trait bound `!: OnlyU32` is not satisfied + //[e2024]~| note: the trait `OnlyU32` is not implemented for `!` + //[e2024]~| note: required by a bound introduced by this call + + #[cfg(e2024)] + requires_nothing(x); + //[e2024]~^ error: the trait bound `!: Nothing` is not satisfied + //[e2024]~| note: the trait `Nothing` is not implemented for `!` + //[e2024]~| note: required by a bound introduced by this call } From 8c8d93071417427a69d0a3b83acc8b163bc5e5b5 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 17:43:01 +0100 Subject: [PATCH 10/19] delete a duplicate test Duplicate of `from_infer_breaking_with_unit_fallback.rs` and `question_mark_from_never.rs` --- ...lue-fallback-issue-66757.nofallback.stderr | 17 ----------- .../never-value-fallback-issue-66757.rs | 30 ------------------- 2 files changed, 47 deletions(-) delete mode 100644 tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr delete mode 100644 tests/ui/never_type/never-value-fallback-issue-66757.rs diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr deleted file mode 100644 index d00118cd61da2..0000000000000 --- a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: the trait bound `E: From<()>` is not satisfied - --> $DIR/never-value-fallback-issue-66757.rs:27:6 - | -LL | >::from(never); - | ^ unsatisfied trait bound - | -help: the trait `From<()>` is not implemented for `E` - but trait `From` is implemented for it - --> $DIR/never-value-fallback-issue-66757.rs:16:1 - | -LL | impl From for E { - | ^^^^^^^^^^^^^^^^^^ - = help: for that trait implementation, expected `!`, found `()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.rs b/tests/ui/never_type/never-value-fallback-issue-66757.rs deleted file mode 100644 index a113d1b13a4ae..0000000000000 --- a/tests/ui/never_type/never-value-fallback-issue-66757.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Regression test for #66757 -// -// Test than when you have a `!` value (e.g., the local variable -// never) and an uninferred variable (here the argument to `From`) it -// doesn't fallback to `()` but rather `!`. -// -//@ revisions: nofallback fallback -//@[fallback] edition: 2024 -//@[fallback] run-pass -//@[nofallback] check-fail - -#![feature(never_type)] - -struct E; - -impl From for E { - fn from(_: !) -> E { - E - } -} - -#[allow(unreachable_code)] -#[allow(dead_code)] -#[allow(unused_must_use)] -fn foo(never: !) { - >::from(never); // Ok - >::from(never); //[nofallback]~ ERROR trait bound `E: From<()>` is not satisfied -} - -fn main() { } From 109b6de8fc0c41b3814563f1344d1bb39fdbef50 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 23:05:54 +0100 Subject: [PATCH 11/19] remove outdated tests I don't think they are testing anything anymore --- tests/ui/never_type/impl_trait_fallback.rs | 11 ------- .../ui/never_type/impl_trait_fallback.stderr | 14 -------- tests/ui/never_type/impl_trait_fallback2.rs | 25 -------------- .../ui/never_type/impl_trait_fallback2.stderr | 33 ------------------- tests/ui/never_type/impl_trait_fallback3.rs | 17 ---------- .../ui/never_type/impl_trait_fallback3.stderr | 18 ---------- tests/ui/never_type/impl_trait_fallback4.rs | 26 --------------- .../ui/never_type/impl_trait_fallback4.stderr | 18 ---------- 8 files changed, 162 deletions(-) delete mode 100644 tests/ui/never_type/impl_trait_fallback.rs delete mode 100644 tests/ui/never_type/impl_trait_fallback.stderr delete mode 100644 tests/ui/never_type/impl_trait_fallback2.rs delete mode 100644 tests/ui/never_type/impl_trait_fallback2.stderr delete mode 100644 tests/ui/never_type/impl_trait_fallback3.rs delete mode 100644 tests/ui/never_type/impl_trait_fallback3.stderr delete mode 100644 tests/ui/never_type/impl_trait_fallback4.rs delete mode 100644 tests/ui/never_type/impl_trait_fallback4.stderr diff --git a/tests/ui/never_type/impl_trait_fallback.rs b/tests/ui/never_type/impl_trait_fallback.rs deleted file mode 100644 index dafbd5af9a1ef..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ check-pass -#![expect(dependency_on_unit_never_type_fallback)] - -fn main() {} - -trait T {} -impl T for () {} - -fn should_ret_unit() -> impl T { - panic!() -} diff --git a/tests/ui/never_type/impl_trait_fallback.stderr b/tests/ui/never_type/impl_trait_fallback.stderr deleted file mode 100644 index bdf6df9878323..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback.stderr +++ /dev/null @@ -1,14 +0,0 @@ -Future incompatibility report: Future breakage diagnostic: -warning: this function depends on never type fallback being `()` - --> $DIR/impl_trait_fallback.rs:9:1 - | -LL | fn should_ret_unit() -> impl T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: specify the types explicitly -note: in edition 2024, the requirement `!: T` will fail - --> $DIR/impl_trait_fallback.rs:9:25 - | -LL | fn should_ret_unit() -> impl T { - | ^^^^^^ - diff --git a/tests/ui/never_type/impl_trait_fallback2.rs b/tests/ui/never_type/impl_trait_fallback2.rs deleted file mode 100644 index c7c624bdce6e4..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback2.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ edition:2015..2021 -#![feature(type_alias_impl_trait)] - -fn main() {} - -trait T {} -impl T for i32 {} - -fn should_ret_unit() -> impl T { - //~^ ERROR `(): T` is not satisfied - panic!() -} - -type Foo = impl T; - -#[define_opaque(Foo)] -fn a() -> Foo { - //~^ ERROR `(): T` is not satisfied - panic!() -} - -#[define_opaque(Foo)] -fn b() -> Foo { - 42 -} diff --git a/tests/ui/never_type/impl_trait_fallback2.stderr b/tests/ui/never_type/impl_trait_fallback2.stderr deleted file mode 100644 index c23b39590a3fb..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback2.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback2.rs:9:25 - | -LL | fn should_ret_unit() -> impl T { - | ^^^^^^ the trait `T` is not implemented for `()` -LL | -LL | panic!() - | -------- return type was inferred to be `_` here - | -help: the trait `T` is implemented for `i32` - --> $DIR/impl_trait_fallback2.rs:7:1 - | -LL | impl T for i32 {} - | ^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback2.rs:17:11 - | -LL | fn a() -> Foo { - | ^^^ the trait `T` is not implemented for `()` -LL | -LL | panic!() - | -------- return type was inferred to be `_` here - | -help: the trait `T` is implemented for `i32` - --> $DIR/impl_trait_fallback2.rs:7:1 - | -LL | impl T for i32 {} - | ^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/impl_trait_fallback3.rs b/tests/ui/never_type/impl_trait_fallback3.rs deleted file mode 100644 index 03cd6fc25c2b4..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback3.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ edition:2015..2021 -#![feature(type_alias_impl_trait)] - -fn main() {} - -trait T { - type Assoc; -} - -type Foo = impl T; - -#[define_opaque(Foo)] -fn a() -> Foo { - //~^ ERROR the trait bound `(): T` is not satisfied - // This is not a defining use, it doesn't actually constrain the opaque type. - panic!() -} diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr deleted file mode 100644 index 259aea18d688d..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback3.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback3.rs:13:11 - | -LL | fn a() -> Foo { - | ^^^ the trait `T` is not implemented for `()` -... -LL | panic!() - | -------- return type was inferred to be `_` here - | -help: this trait has no implementations, consider adding one - --> $DIR/impl_trait_fallback3.rs:6:1 - | -LL | trait T { - | ^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/impl_trait_fallback4.rs b/tests/ui/never_type/impl_trait_fallback4.rs deleted file mode 100644 index 52ddd74f91612..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback4.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ edition:2015..2021 -#![feature(type_alias_impl_trait)] - -trait T { - type Assoc: Cake; -} - -trait Cake: std::fmt::Display { - fn cake() -> Self; -} - -type Foo = impl T; - -fn foo() -> impl T { - //~^ ERROR `(): T` is not satisfied - panic!() -} - -#[define_opaque(Foo)] -fn a() -> Foo { - foo() -} - -fn main() { - println!("{}", ::Assoc::cake()); -} diff --git a/tests/ui/never_type/impl_trait_fallback4.stderr b/tests/ui/never_type/impl_trait_fallback4.stderr deleted file mode 100644 index f9de4b6a4944e..0000000000000 --- a/tests/ui/never_type/impl_trait_fallback4.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the trait bound `(): T` is not satisfied - --> $DIR/impl_trait_fallback4.rs:14:13 - | -LL | fn foo() -> impl T { - | ^^^^^^ the trait `T` is not implemented for `()` -LL | -LL | panic!() - | -------- return type was inferred to be `_` here - | -help: this trait has no implementations, consider adding one - --> $DIR/impl_trait_fallback4.rs:4:1 - | -LL | trait T { - | ^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. From 0104d69e4bf6bd1c9d1d66e1e69d72fb0a49cb0b Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 20:14:10 +0100 Subject: [PATCH 12/19] move `tests/ui/{never => never_type}/*` there are only 1 test in that directory, probably created by mistake. --- tests/ui/{never => never_type}/never-type-method-call-15207.rs | 0 .../ui/{never => never_type}/never-type-method-call-15207.stderr | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{never => never_type}/never-type-method-call-15207.rs (100%) rename tests/ui/{never => never_type}/never-type-method-call-15207.stderr (100%) diff --git a/tests/ui/never/never-type-method-call-15207.rs b/tests/ui/never_type/never-type-method-call-15207.rs similarity index 100% rename from tests/ui/never/never-type-method-call-15207.rs rename to tests/ui/never_type/never-type-method-call-15207.rs diff --git a/tests/ui/never/never-type-method-call-15207.stderr b/tests/ui/never_type/never-type-method-call-15207.stderr similarity index 100% rename from tests/ui/never/never-type-method-call-15207.stderr rename to tests/ui/never_type/never-type-method-call-15207.stderr From b1efa8e57973c381419aeff33a858d441e9c4a13 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 23:24:32 +0100 Subject: [PATCH 13/19] stylistic test changes --- tests/ui/never_type/call-fn-never-arg.rs | 2 +- tests/ui/never_type/cast-never.rs | 2 +- .../diverging-fallback-no-leak.e2021.stderr | 18 +++++++++++++ .../diverging-fallback-no-leak.e2024.stderr | 26 +++++++++++++++++++ .../never_type/diverging-fallback-no-leak.rs | 12 +++++---- tests/ui/never_type/eq-never-types.rs | 9 +++---- .../fallback-closure-ret.e2021.stderr | 18 +++++++++++++ .../fallback-closure-ret.e2024.stderr | 24 +++++++++++++++++ tests/ui/never_type/fallback-closure-ret.rs | 16 +++++++----- tests/ui/never_type/impl-for-never.rs | 3 ++- tests/ui/never_type/issue-44402.rs | 11 ++++---- tests/ui/never_type/issue-51506.rs | 2 ++ tests/ui/never_type/issue-51506.stderr | 4 +-- tests/ui/never_type/never-assign-dead-code.rs | 2 +- tests/ui/never_type/never-associated-type.rs | 2 +- tests/ui/never_type/never-in-range-pat.rs | 2 +- tests/ui/never_type/never-type-arg.rs | 2 +- tests/ui/never_type/never_transmute_never.rs | 4 +-- .../ui/never_type/question_mark_from_never.rs | 2 +- tests/ui/never_type/span-bug-issue-121445.rs | 2 ++ .../never_type/span-bug-issue-121445.stderr | 4 +-- 21 files changed, 132 insertions(+), 35 deletions(-) create mode 100644 tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr create mode 100644 tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr create mode 100644 tests/ui/never_type/fallback-closure-ret.e2021.stderr create mode 100644 tests/ui/never_type/fallback-closure-ret.e2024.stderr diff --git a/tests/ui/never_type/call-fn-never-arg.rs b/tests/ui/never_type/call-fn-never-arg.rs index d37f0888b2f0c..d64370f2ece6f 100644 --- a/tests/ui/never_type/call-fn-never-arg.rs +++ b/tests/ui/never_type/call-fn-never-arg.rs @@ -1,5 +1,5 @@ // Test that we can use a ! for an argument of type ! - +// //@ check-pass #![feature(never_type)] diff --git a/tests/ui/never_type/cast-never.rs b/tests/ui/never_type/cast-never.rs index 34314fcebab05..eaca210182873 100644 --- a/tests/ui/never_type/cast-never.rs +++ b/tests/ui/never_type/cast-never.rs @@ -1,5 +1,5 @@ // Test that we can explicitly cast ! to another type - +// //@ check-pass #![feature(never_type)] diff --git a/tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr b/tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr new file mode 100644 index 0000000000000..e67db8c719851 --- /dev/null +++ b/tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr @@ -0,0 +1,18 @@ +Future incompatibility report: Future breakage diagnostic: +warning: this function depends on never type fallback being `()` + --> $DIR/diverging-fallback-no-leak.rs:17:1 + | +LL | fn main() { + | ^^^^^^^^^ + | + = help: specify the types explicitly +note: in edition 2024, the requirement `!: Test` will fail + --> $DIR/diverging-fallback-no-leak.rs:20:23 + | +LL | unconstrained_arg(return); + | ^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | unconstrained_arg::<()>(return); + | ++++++ + diff --git a/tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr b/tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr new file mode 100644 index 0000000000000..36b4a1b40e264 --- /dev/null +++ b/tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr @@ -0,0 +1,26 @@ +error[E0277]: the trait bound `!: Test` is not satisfied + --> $DIR/diverging-fallback-no-leak.rs:20:23 + | +LL | unconstrained_arg(return); + | ----------------- ^^^^^^ the trait `Test` is not implemented for `!` + | | + | required by a bound introduced by this call + | +help: the following other types implement trait `Test` + --> $DIR/diverging-fallback-no-leak.rs:11:1 + | +LL | impl Test for i32 {} + | ^^^^^^^^^^^^^^^^^ `i32` +LL | impl Test for () {} + | ^^^^^^^^^^^^^^^^ `()` + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) + = help: you might have intended to use the type `()` here instead +note: required by a bound in `unconstrained_arg` + --> $DIR/diverging-fallback-no-leak.rs:14:25 + | +LL | fn unconstrained_arg(_: T) {} + | ^^^^ required by this bound in `unconstrained_arg` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/diverging-fallback-no-leak.rs b/tests/ui/never_type/diverging-fallback-no-leak.rs index d2bc064e4fd56..fd276ea638801 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.rs +++ b/tests/ui/never_type/diverging-fallback-no-leak.rs @@ -1,8 +1,9 @@ -//@ revisions: nofallback fallback -//@[fallback] edition: 2024 -//@[nofallback] check-pass +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +// +//@[e2021] check-pass -#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))] fn make_unit() {} @@ -12,9 +13,10 @@ impl Test for () {} fn unconstrained_arg(_: T) {} +#[cfg_attr(e2021, expect(dependency_on_unit_never_type_fallback))] fn main() { // Here the type variable falls back to `!`, // and hence we get a type error. unconstrained_arg(return); - //[fallback]~^ error: trait bound `!: Test` is not satisfied + //[e2024]~^ error: trait bound `!: Test` is not satisfied } diff --git a/tests/ui/never_type/eq-never-types.rs b/tests/ui/never_type/eq-never-types.rs index 19717fcf4433c..c130b9a352142 100644 --- a/tests/ui/never_type/eq-never-types.rs +++ b/tests/ui/never_type/eq-never-types.rs @@ -1,10 +1,9 @@ -//@ check-pass +// Regression test for // -// issue: rust-lang/rust#120600 +//@ edition: 2024 +//@ check-pass -#![allow(internal_features)] -#![feature(never_type, rustc_attrs)] -#![rustc_never_type_options(fallback = "never")] +#![feature(never_type)] fn ice(a: !) { a == a; diff --git a/tests/ui/never_type/fallback-closure-ret.e2021.stderr b/tests/ui/never_type/fallback-closure-ret.e2021.stderr new file mode 100644 index 0000000000000..44ec166eaa30e --- /dev/null +++ b/tests/ui/never_type/fallback-closure-ret.e2021.stderr @@ -0,0 +1,18 @@ +Future incompatibility report: Future breakage diagnostic: +warning: this function depends on never type fallback being `()` + --> $DIR/fallback-closure-ret.rs:21:1 + | +LL | fn main() { + | ^^^^^^^^^ + | + = help: specify the types explicitly +note: in edition 2024, the requirement `!: Bar` will fail + --> $DIR/fallback-closure-ret.rs:22:5 + | +LL | foo(|| panic!()); + | ^^^^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | foo::<()>(|| panic!()); + | ++++++ + diff --git a/tests/ui/never_type/fallback-closure-ret.e2024.stderr b/tests/ui/never_type/fallback-closure-ret.e2024.stderr new file mode 100644 index 0000000000000..9687ddf6459db --- /dev/null +++ b/tests/ui/never_type/fallback-closure-ret.e2024.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `!: Bar` is not satisfied + --> $DIR/fallback-closure-ret.rs:22:5 + | +LL | foo(|| panic!()); + | ^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `!` + | +help: the following other types implement trait `Bar` + --> $DIR/fallback-closure-ret.rs:15:1 + | +LL | impl Bar for () {} + | ^^^^^^^^^^^^^^^ `()` +LL | impl Bar for u32 {} + | ^^^^^^^^^^^^^^^^ `u32` + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) + = help: you might have intended to use the type `()` here instead +note: required by a bound in `foo` + --> $DIR/fallback-closure-ret.rs:18:11 + | +LL | fn foo(_: impl Fn() -> R) {} + | ^^^ required by this bound in `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/fallback-closure-ret.rs b/tests/ui/never_type/fallback-closure-ret.rs index 4f2bc16e7d568..11d7c685706b4 100644 --- a/tests/ui/never_type/fallback-closure-ret.rs +++ b/tests/ui/never_type/fallback-closure-ret.rs @@ -1,12 +1,15 @@ +// Tests the pattern of returning `!` from a closure and then checking if the +// return type iumplements a trait (not implemented for `!`). +// // This test used to test that this pattern is not broken by context dependant // never type fallback. However, it got removed, so now this is an example of // expected breakage from the never type fallback change. // -//@ revisions: nofallback fallback -//@[nofallback] check-pass -//@[fallback] edition: 2024 - -#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))] +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +// +//@[e2021] check-pass trait Bar {} impl Bar for () {} @@ -14,6 +17,7 @@ impl Bar for u32 {} fn foo(_: impl Fn() -> R) {} +#[cfg_attr(e2021, expect(dependency_on_unit_never_type_fallback))] fn main() { - foo(|| panic!()); //[fallback]~ error: the trait bound `!: Bar` is not satisfied + foo(|| panic!()); //[e2024]~ error: the trait bound `!: Bar` is not satisfied } diff --git a/tests/ui/never_type/impl-for-never.rs b/tests/ui/never_type/impl-for-never.rs index 0da79a712d2bb..dad3002c9a0c9 100644 --- a/tests/ui/never_type/impl-for-never.rs +++ b/tests/ui/never_type/impl-for-never.rs @@ -1,8 +1,9 @@ +// Test that we can call static methods on ! both directly and when it appears in a generic +// //@ run-pass #![feature(never_type)] -// Test that we can call static methods on ! both directly and when it appears in a generic trait StringifyType { fn stringify_type() -> &'static str; diff --git a/tests/ui/never_type/issue-44402.rs b/tests/ui/never_type/issue-44402.rs index 820d1af37bf6a..ae8c59a5cf06c 100644 --- a/tests/ui/never_type/issue-44402.rs +++ b/tests/ui/never_type/issue-44402.rs @@ -1,13 +1,14 @@ +// Regression test for +// +// Previously inhabitedness check was handling cycles incorrectly causing this +// to not compile. +// //@ check-pass #![allow(dead_code)] #![feature(never_type)] #![feature(exhaustive_patterns)] -// Regression test for inhabitedness check. The old -// cache used to cause us to incorrectly decide -// that `test_b` was invalid. - struct Foo { field1: !, field2: Option<&'static Bar>, @@ -30,4 +31,4 @@ fn test_b() { } } -fn main() { } +fn main() {} diff --git a/tests/ui/never_type/issue-51506.rs b/tests/ui/never_type/issue-51506.rs index d0fe6a0f59a87..c366b6c16b297 100644 --- a/tests/ui/never_type/issue-51506.rs +++ b/tests/ui/never_type/issue-51506.rs @@ -1,3 +1,5 @@ +// Regression test for + #![feature(never_type, specialization)] #![allow(incomplete_features)] diff --git a/tests/ui/never_type/issue-51506.stderr b/tests/ui/never_type/issue-51506.stderr index 09379257c4cca..0e666e017f9c6 100644 --- a/tests/ui/never_type/issue-51506.stderr +++ b/tests/ui/never_type/issue-51506.stderr @@ -1,12 +1,12 @@ error[E0277]: `!` is not an iterator - --> $DIR/issue-51506.rs:13:24 + --> $DIR/issue-51506.rs:15:24 | LL | default type Out = !; | ^ `!` is not an iterator | = help: the trait `Iterator` is not implemented for `!` note: required by a bound in `Trait::Out` - --> $DIR/issue-51506.rs:7:15 + --> $DIR/issue-51506.rs:9:15 | LL | type Out: Iterator; | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::Out` diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs index 2c99d3086fbad..0aae868c29b53 100644 --- a/tests/ui/never_type/never-assign-dead-code.rs +++ b/tests/ui/never_type/never-assign-dead-code.rs @@ -1,5 +1,5 @@ // Test that an assignment of type ! makes the rest of the block dead code. - +// //@ check-pass #![feature(never_type)] diff --git a/tests/ui/never_type/never-associated-type.rs b/tests/ui/never_type/never-associated-type.rs index f7b88f604f26f..a62ec7e599107 100644 --- a/tests/ui/never_type/never-associated-type.rs +++ b/tests/ui/never_type/never-associated-type.rs @@ -1,5 +1,5 @@ // Test that we can use ! as an associated type. - +// //@ check-pass #![feature(never_type)] diff --git a/tests/ui/never_type/never-in-range-pat.rs b/tests/ui/never_type/never-in-range-pat.rs index ae2d76c172ea0..2e0409bfa6458 100644 --- a/tests/ui/never_type/never-in-range-pat.rs +++ b/tests/ui/never_type/never-in-range-pat.rs @@ -1,5 +1,5 @@ // Regression test for . - +// // Make sure we don't ICE when there's `!` in a range pattern. // // This shouldn't be allowed anyways, but we only deny it during MIR diff --git a/tests/ui/never_type/never-type-arg.rs b/tests/ui/never_type/never-type-arg.rs index 10023cf41999e..45ce6836e2a40 100644 --- a/tests/ui/never_type/never-type-arg.rs +++ b/tests/ui/never_type/never-type-arg.rs @@ -1,5 +1,5 @@ // Test that we can use ! as an argument to a trait impl. - +// //@ check-pass #![feature(never_type)] diff --git a/tests/ui/never_type/never_transmute_never.rs b/tests/ui/never_type/never_transmute_never.rs index b1fcffcb3b7e4..096aadd8f04ad 100644 --- a/tests/ui/never_type/never_transmute_never.rs +++ b/tests/ui/never_type/never_transmute_never.rs @@ -1,7 +1,5 @@ //@ check-pass -#![crate_type="lib"] - #![feature(never_type)] #![allow(dead_code)] #![allow(unreachable_code)] @@ -21,3 +19,5 @@ pub fn ub() { }; f(x) } + +fn main() {} diff --git a/tests/ui/never_type/question_mark_from_never.rs b/tests/ui/never_type/question_mark_from_never.rs index 06d2a1926ea90..8d73313667abe 100644 --- a/tests/ui/never_type/question_mark_from_never.rs +++ b/tests/ui/never_type/question_mark_from_never.rs @@ -1,4 +1,4 @@ -// issue: rust-lang/rust#66757 +// Regression test for . // // See also: `tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs`. // diff --git a/tests/ui/never_type/span-bug-issue-121445.rs b/tests/ui/never_type/span-bug-issue-121445.rs index 2fe22529c4e9d..64bf6bd6aa11e 100644 --- a/tests/ui/never_type/span-bug-issue-121445.rs +++ b/tests/ui/never_type/span-bug-issue-121445.rs @@ -1,3 +1,5 @@ +// Regression test for + #![feature(never_type)] fn test2() { diff --git a/tests/ui/never_type/span-bug-issue-121445.stderr b/tests/ui/never_type/span-bug-issue-121445.stderr index b211afa236fef..8c8bc133433a7 100644 --- a/tests/ui/never_type/span-bug-issue-121445.stderr +++ b/tests/ui/never_type/span-bug-issue-121445.stderr @@ -1,5 +1,5 @@ error[E0369]: no implementation for `SingleVariant | ()` - --> $DIR/span-bug-issue-121445.rs:6:9 + --> $DIR/span-bug-issue-121445.rs:8:9 | LL | let c2 = SingleVariant::Points(0) | ------------------------ SingleVariant @@ -10,7 +10,7 @@ LL | | }; | |_________- () | note: an implementation of `BitOr<()>` might be missing for `SingleVariant` - --> $DIR/span-bug-issue-121445.rs:11:1 + --> $DIR/span-bug-issue-121445.rs:13:1 | LL | enum SingleVariant { | ^^^^^^^^^^^^^^^^^^ must implement `BitOr<()>` From e9873435a39b73232e38e441e19e63c934c9ae25 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 23:34:34 +0100 Subject: [PATCH 14/19] merge `diverging-fallback-no-leak` into an existing test --- .../editions/never-type-fallback-breaking.rs | 7 +++++ .../diverging-fallback-no-leak.e2021.stderr | 18 ------------- .../diverging-fallback-no-leak.e2024.stderr | 26 ------------------- ...diverging-fallback-no-leak.fallback.stderr | 26 ------------------- ...verging-fallback-no-leak.nofallback.stderr | 18 ------------- .../never_type/diverging-fallback-no-leak.rs | 22 ---------------- 6 files changed, 7 insertions(+), 110 deletions(-) delete mode 100644 tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr delete mode 100644 tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr delete mode 100644 tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr delete mode 100644 tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr delete mode 100644 tests/ui/never_type/diverging-fallback-no-leak.rs diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs index 96e4694453977..5554df41f3bc7 100644 --- a/tests/ui/editions/never-type-fallback-breaking.rs +++ b/tests/ui/editions/never-type-fallback-breaking.rs @@ -75,3 +75,10 @@ fn fully_apit() -> Result<(), ()> { //[e2024]~^ error: the trait bound `!: Default` is not satisfied Ok(()) } + +fn return_as_argument() { + //[e2021]~^ error: this function depends on never type fallback being `()` + //[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! + takes_apit2(return); + //[e2024]~^ error: trait bound `!: Test` is not satisfied +} diff --git a/tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr b/tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr deleted file mode 100644 index e67db8c719851..0000000000000 --- a/tests/ui/never_type/diverging-fallback-no-leak.e2021.stderr +++ /dev/null @@ -1,18 +0,0 @@ -Future incompatibility report: Future breakage diagnostic: -warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-no-leak.rs:17:1 - | -LL | fn main() { - | ^^^^^^^^^ - | - = help: specify the types explicitly -note: in edition 2024, the requirement `!: Test` will fail - --> $DIR/diverging-fallback-no-leak.rs:20:23 - | -LL | unconstrained_arg(return); - | ^^^^^^ -help: use `()` annotations to avoid fallback changes - | -LL | unconstrained_arg::<()>(return); - | ++++++ - diff --git a/tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr b/tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr deleted file mode 100644 index 36b4a1b40e264..0000000000000 --- a/tests/ui/never_type/diverging-fallback-no-leak.e2024.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0277]: the trait bound `!: Test` is not satisfied - --> $DIR/diverging-fallback-no-leak.rs:20:23 - | -LL | unconstrained_arg(return); - | ----------------- ^^^^^^ the trait `Test` is not implemented for `!` - | | - | required by a bound introduced by this call - | -help: the following other types implement trait `Test` - --> $DIR/diverging-fallback-no-leak.rs:11:1 - | -LL | impl Test for i32 {} - | ^^^^^^^^^^^^^^^^^ `i32` -LL | impl Test for () {} - | ^^^^^^^^^^^^^^^^ `()` - = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) - = help: you might have intended to use the type `()` here instead -note: required by a bound in `unconstrained_arg` - --> $DIR/diverging-fallback-no-leak.rs:14:25 - | -LL | fn unconstrained_arg(_: T) {} - | ^^^^ required by this bound in `unconstrained_arg` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr deleted file mode 100644 index 1baccd7b637bf..0000000000000 --- a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0277]: the trait bound `!: Test` is not satisfied - --> $DIR/diverging-fallback-no-leak.rs:18:23 - | -LL | unconstrained_arg(return); - | ----------------- ^^^^^^ the trait `Test` is not implemented for `!` - | | - | required by a bound introduced by this call - | -help: the following other types implement trait `Test` - --> $DIR/diverging-fallback-no-leak.rs:10:1 - | -LL | impl Test for i32 {} - | ^^^^^^^^^^^^^^^^^ `i32` -LL | impl Test for () {} - | ^^^^^^^^^^^^^^^^ `()` - = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) - = help: you might have intended to use the type `()` here instead -note: required by a bound in `unconstrained_arg` - --> $DIR/diverging-fallback-no-leak.rs:13:25 - | -LL | fn unconstrained_arg(_: T) {} - | ^^^^ required by this bound in `unconstrained_arg` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr deleted file mode 100644 index 8423261ed610c..0000000000000 --- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr +++ /dev/null @@ -1,18 +0,0 @@ -Future incompatibility report: Future breakage diagnostic: -warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-no-leak.rs:15:1 - | -LL | fn main() { - | ^^^^^^^^^ - | - = help: specify the types explicitly -note: in edition 2024, the requirement `!: Test` will fail - --> $DIR/diverging-fallback-no-leak.rs:18:23 - | -LL | unconstrained_arg(return); - | ^^^^^^ -help: use `()` annotations to avoid fallback changes - | -LL | unconstrained_arg::<()>(return); - | ++++++ - diff --git a/tests/ui/never_type/diverging-fallback-no-leak.rs b/tests/ui/never_type/diverging-fallback-no-leak.rs deleted file mode 100644 index fd276ea638801..0000000000000 --- a/tests/ui/never_type/diverging-fallback-no-leak.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ revisions: e2021 e2024 -//@[e2021] edition: 2021 -//@[e2024] edition: 2024 -// -//@[e2021] check-pass - - -fn make_unit() {} - -trait Test {} -impl Test for i32 {} -impl Test for () {} - -fn unconstrained_arg(_: T) {} - -#[cfg_attr(e2021, expect(dependency_on_unit_never_type_fallback))] -fn main() { - // Here the type variable falls back to `!`, - // and hence we get a type error. - unconstrained_arg(return); - //[e2024]~^ error: trait bound `!: Test` is not satisfied -} From 7d33e7e0912172d9f6bd4277ee1f5b4a37541a9a Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 17:43:01 +0100 Subject: [PATCH 15/19] clarify purposes of tests --- .../never-type-fallback-breaking.e2021.fixed | 4 ++ .../never-type-fallback-breaking.e2021.stderr | 40 +++++++++---------- .../never-type-fallback-breaking.e2024.stderr | 16 ++++---- .../editions/never-type-fallback-breaking.rs | 11 ++--- tests/ui/never_type/exhaustive_patterns.rs | 3 ++ .../ui/never_type/exhaustive_patterns.stderr | 4 +- tests/ui/never_type/never-result.rs | 3 ++ tests/ui/never_type/never-type-rvalues.rs | 2 + 8 files changed, 46 insertions(+), 37 deletions(-) diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed index c8f3e87027a39..7e6c47ed43e05 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed @@ -1,3 +1,7 @@ +// This is a test for various ways in which the change to the never type +// fallback can break things and for the `dependency_on_unit_never_type_fallback` +// lint. +// //@ revisions: e2021 e2024 // //@[e2021] edition: 2021 diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index ded694f5a3d47..a910b19d9bf76 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -1,5 +1,5 @@ error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:16:1 + --> $DIR/never-type-fallback-breaking.rs:20:1 | LL | fn m() { | ^^^^^^ @@ -8,7 +8,7 @@ LL | fn m() { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:20:17 + --> $DIR/never-type-fallback-breaking.rs:24:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | let x: () = match true { | ++++ error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:28:1 + --> $DIR/never-type-fallback-breaking.rs:32:1 | LL | fn q() -> Option<()> { | ^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | fn q() -> Option<()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:35:5 + --> $DIR/never-type-fallback-breaking.rs:39:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | deserialize::<()>()?; | ++++++ error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:45:1 + --> $DIR/never-type-fallback-breaking.rs:49:1 | LL | fn meow() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `(): From` will fail - --> $DIR/never-type-fallback-breaking.rs:48:5 + --> $DIR/never-type-fallback-breaking.rs:52:5 | LL | help(1)?; | ^^^^^^^ @@ -57,7 +57,7 @@ LL | help::<(), _>(1)?; | +++++++++ error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:57:1 + --> $DIR/never-type-fallback-breaking.rs:61:1 | LL | pub fn fallback_return() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | pub fn fallback_return() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:60:19 + --> $DIR/never-type-fallback-breaking.rs:64:19 | LL | takes_apit(|| Default::default())?; | ^^^^^^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | takes_apit::<()>(|| Default::default())?; | ++++++ error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:71:1 + --> $DIR/never-type-fallback-breaking.rs:75:1 | LL | fn fully_apit() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | fn fully_apit() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:74:17 + --> $DIR/never-type-fallback-breaking.rs:78:17 | LL | takes_apit2(mk()?); | ^^^^^ @@ -98,7 +98,7 @@ error: aborting due to 5 previous errors Future incompatibility report: Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:16:1 + --> $DIR/never-type-fallback-breaking.rs:20:1 | LL | fn m() { | ^^^^^^ @@ -107,7 +107,7 @@ LL | fn m() { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:20:17 + --> $DIR/never-type-fallback-breaking.rs:24:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | let x: () = match true { Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:28:1 + --> $DIR/never-type-fallback-breaking.rs:32:1 | LL | fn q() -> Option<()> { | ^^^^^^^^^^^^^^^^^^^^ @@ -128,7 +128,7 @@ LL | fn q() -> Option<()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:35:5 + --> $DIR/never-type-fallback-breaking.rs:39:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ @@ -140,7 +140,7 @@ LL | deserialize::<()>()?; Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:45:1 + --> $DIR/never-type-fallback-breaking.rs:49:1 | LL | fn meow() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | fn meow() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `(): From` will fail - --> $DIR/never-type-fallback-breaking.rs:48:5 + --> $DIR/never-type-fallback-breaking.rs:52:5 | LL | help(1)?; | ^^^^^^^ @@ -161,7 +161,7 @@ LL | help::<(), _>(1)?; Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:57:1 + --> $DIR/never-type-fallback-breaking.rs:61:1 | LL | pub fn fallback_return() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL | pub fn fallback_return() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:60:19 + --> $DIR/never-type-fallback-breaking.rs:64:19 | LL | takes_apit(|| Default::default())?; | ^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | takes_apit::<()>(|| Default::default())?; Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/never-type-fallback-breaking.rs:71:1 + --> $DIR/never-type-fallback-breaking.rs:75:1 | LL | fn fully_apit() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -191,7 +191,7 @@ LL | fn fully_apit() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/never-type-fallback-breaking.rs:74:17 + --> $DIR/never-type-fallback-breaking.rs:78:17 | LL | takes_apit2(mk()?); | ^^^^^ diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr index 4c6740df5d4da..65be5d90d011c 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:20:17 + --> $DIR/never-type-fallback-breaking.rs:24:17 | LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -8,7 +8,7 @@ LL | true => Default::default(), = help: you might have intended to use the type `()` here instead error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:35:5 + --> $DIR/never-type-fallback-breaking.rs:39:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -16,13 +16,13 @@ LL | deserialize()?; = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) = help: you might have intended to use the type `()` here instead note: required by a bound in `deserialize` - --> $DIR/never-type-fallback-breaking.rs:31:23 + --> $DIR/never-type-fallback-breaking.rs:35:23 | LL | fn deserialize() -> Option { | ^^^^^^^ required by this bound in `deserialize` error[E0277]: the trait bound `(): From` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:48:5 + --> $DIR/never-type-fallback-breaking.rs:52:5 | LL | help(1)?; | ^^^^^^^ the trait `From` is not implemented for `()` @@ -39,13 +39,13 @@ LL | help(1)?; and 4 others = note: required for `!` to implement `Into<()>` note: required by a bound in `help` - --> $DIR/never-type-fallback-breaking.rs:42:20 + --> $DIR/never-type-fallback-breaking.rs:46:20 | LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result { | ^^^^^^^^ required by this bound in `help` error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:60:19 + --> $DIR/never-type-fallback-breaking.rs:64:19 | LL | takes_apit(|| Default::default())?; | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` @@ -54,7 +54,7 @@ LL | takes_apit(|| Default::default())?; = help: you might have intended to use the type `()` here instead error[E0277]: the trait bound `!: Default` is not satisfied - --> $DIR/never-type-fallback-breaking.rs:74:17 + --> $DIR/never-type-fallback-breaking.rs:78:17 | LL | takes_apit2(mk()?); | ----------- ^^^^^ the trait `Default` is not implemented for `!` @@ -64,7 +64,7 @@ LL | takes_apit2(mk()?); = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) = help: you might have intended to use the type `()` here instead note: required by a bound in `takes_apit2` - --> $DIR/never-type-fallback-breaking.rs:69:25 + --> $DIR/never-type-fallback-breaking.rs:73:25 | LL | fn takes_apit2(_x: impl Default) {} | ^^^^^^^ required by this bound in `takes_apit2` diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs index 5554df41f3bc7..ae31b436f5662 100644 --- a/tests/ui/editions/never-type-fallback-breaking.rs +++ b/tests/ui/editions/never-type-fallback-breaking.rs @@ -1,3 +1,7 @@ +// This is a test for various ways in which the change to the never type +// fallback can break things and for the `dependency_on_unit_never_type_fallback` +// lint. +// //@ revisions: e2021 e2024 // //@[e2021] edition: 2021 @@ -75,10 +79,3 @@ fn fully_apit() -> Result<(), ()> { //[e2024]~^ error: the trait bound `!: Default` is not satisfied Ok(()) } - -fn return_as_argument() { - //[e2021]~^ error: this function depends on never type fallback being `()` - //[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - takes_apit2(return); - //[e2024]~^ error: trait bound `!: Test` is not satisfied -} diff --git a/tests/ui/never_type/exhaustive_patterns.rs b/tests/ui/never_type/exhaustive_patterns.rs index b56eab6cb9d94..4f9e55c3d8dc1 100644 --- a/tests/ui/never_type/exhaustive_patterns.rs +++ b/tests/ui/never_type/exhaustive_patterns.rs @@ -1,3 +1,6 @@ +// Check that we don't consider types which aren't publicly uninhabited as +// uninhabited for purposes of pattern matching. +// //@ check-fail #![feature(exhaustive_patterns, never_type)] diff --git a/tests/ui/never_type/exhaustive_patterns.stderr b/tests/ui/never_type/exhaustive_patterns.stderr index 1f22b9e619867..f8b582d1b50bf 100644 --- a/tests/ui/never_type/exhaustive_patterns.stderr +++ b/tests/ui/never_type/exhaustive_patterns.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in local binding - --> $DIR/exhaustive_patterns.rs:21:9 + --> $DIR/exhaustive_patterns.rs:24:9 | LL | let Either::A(()) = foo(); | ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered @@ -7,7 +7,7 @@ LL | let Either::A(()) = foo(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html note: `Either<(), !>` defined here - --> $DIR/exhaustive_patterns.rs:9:6 + --> $DIR/exhaustive_patterns.rs:12:6 | LL | enum Either { | ^^^^^^ diff --git a/tests/ui/never_type/never-result.rs b/tests/ui/never_type/never-result.rs index 98ad140466621..ffcd443393464 100644 --- a/tests/ui/never_type/never-result.rs +++ b/tests/ui/never_type/never-result.rs @@ -1,3 +1,6 @@ +// Test that `!` can be coerced to multiple different types after getting it +// from pattern matching. +// //@ run-pass #![allow(unused_variables)] diff --git a/tests/ui/never_type/never-type-rvalues.rs b/tests/ui/never_type/never-type-rvalues.rs index d3f6f628e1a7b..943de2563ef81 100644 --- a/tests/ui/never_type/never-type-rvalues.rs +++ b/tests/ui/never_type/never-type-rvalues.rs @@ -1,3 +1,5 @@ +// Check that the never type can be used in various positions. +// //@ run-pass #![feature(never_type)] From 3f606fac007550927614dda38436570ff223be11 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 13 Nov 2025 23:24:32 +0100 Subject: [PATCH 16/19] minor test improvements --- tests/ui/never_type/call-fn-never-arg.rs | 2 +- tests/ui/never_type/exhaustive_patterns.rs | 2 +- tests/ui/never_type/impl-for-never.rs | 1 + tests/ui/never_type/impl-for-never.run.stdout | 2 ++ tests/ui/never_type/never-assign-dead-code.rs | 2 +- tests/ui/never_type/never-assign-wrong-type.rs | 1 - tests/ui/never_type/never-assign-wrong-type.stderr | 2 +- tests/ui/never_type/never-result.rs | 6 ++---- tests/ui/never_type/never_transmute_never.rs | 4 ++-- 9 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 tests/ui/never_type/impl-for-never.run.stdout diff --git a/tests/ui/never_type/call-fn-never-arg.rs b/tests/ui/never_type/call-fn-never-arg.rs index d64370f2ece6f..546b37fb52f5f 100644 --- a/tests/ui/never_type/call-fn-never-arg.rs +++ b/tests/ui/never_type/call-fn-never-arg.rs @@ -3,7 +3,7 @@ //@ check-pass #![feature(never_type)] -#![allow(unreachable_code)] +#![expect(unreachable_code)] fn foo(x: !) -> ! { x diff --git a/tests/ui/never_type/exhaustive_patterns.rs b/tests/ui/never_type/exhaustive_patterns.rs index 4f9e55c3d8dc1..0562575d511e1 100644 --- a/tests/ui/never_type/exhaustive_patterns.rs +++ b/tests/ui/never_type/exhaustive_patterns.rs @@ -3,7 +3,7 @@ // //@ check-fail -#![feature(exhaustive_patterns, never_type)] +#![feature(never_type)] mod inner { pub struct Wrapper(T); diff --git a/tests/ui/never_type/impl-for-never.rs b/tests/ui/never_type/impl-for-never.rs index dad3002c9a0c9..e908d2a62547c 100644 --- a/tests/ui/never_type/impl-for-never.rs +++ b/tests/ui/never_type/impl-for-never.rs @@ -1,6 +1,7 @@ // Test that we can call static methods on ! both directly and when it appears in a generic // //@ run-pass +//@ check-run-results #![feature(never_type)] diff --git a/tests/ui/never_type/impl-for-never.run.stdout b/tests/ui/never_type/impl-for-never.run.stdout new file mode 100644 index 0000000000000..8f23a337b3920 --- /dev/null +++ b/tests/ui/never_type/impl-for-never.run.stdout @@ -0,0 +1,2 @@ +! is ! +None is none diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs index 0aae868c29b53..05e5d5551336b 100644 --- a/tests/ui/never_type/never-assign-dead-code.rs +++ b/tests/ui/never_type/never-assign-dead-code.rs @@ -3,7 +3,7 @@ //@ check-pass #![feature(never_type)] -#![allow(dropping_copy_types)] +#![expect(dropping_copy_types)] #![warn(unused)] fn main() { diff --git a/tests/ui/never_type/never-assign-wrong-type.rs b/tests/ui/never_type/never-assign-wrong-type.rs index 67e26f5663f41..ccc2f872dab43 100644 --- a/tests/ui/never_type/never-assign-wrong-type.rs +++ b/tests/ui/never_type/never-assign-wrong-type.rs @@ -1,7 +1,6 @@ // Test that we can't use another type in place of ! #![feature(never_type)] -#![deny(warnings)] fn main() { let x: ! = "hello"; //~ ERROR mismatched types diff --git a/tests/ui/never_type/never-assign-wrong-type.stderr b/tests/ui/never_type/never-assign-wrong-type.stderr index f59de5d2a4289..dd890e4d163b3 100644 --- a/tests/ui/never_type/never-assign-wrong-type.stderr +++ b/tests/ui/never_type/never-assign-wrong-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/never-assign-wrong-type.rs:7:16 + --> $DIR/never-assign-wrong-type.rs:6:16 | LL | let x: ! = "hello"; | - ^^^^^^^ expected `!`, found `&str` diff --git a/tests/ui/never_type/never-result.rs b/tests/ui/never_type/never-result.rs index ffcd443393464..34b7cd67a55a1 100644 --- a/tests/ui/never_type/never-result.rs +++ b/tests/ui/never_type/never-result.rs @@ -3,11 +3,9 @@ // //@ run-pass -#![allow(unused_variables)] -#![allow(unreachable_code)] -#![allow(unreachable_patterns)] -// Test that we can extract a ! through pattern matching then use it as several different types. #![feature(never_type)] +#![expect(unused_variables)] +#![expect(unreachable_code)] fn main() { let x: Result = Ok(123); diff --git a/tests/ui/never_type/never_transmute_never.rs b/tests/ui/never_type/never_transmute_never.rs index 096aadd8f04ad..6d32a12bc44a3 100644 --- a/tests/ui/never_type/never_transmute_never.rs +++ b/tests/ui/never_type/never_transmute_never.rs @@ -2,8 +2,8 @@ #![feature(never_type)] #![allow(dead_code)] -#![allow(unreachable_code)] -#![allow(unused_variables)] +#![expect(unreachable_code)] +#![expect(unused_variables)] struct Foo; From cb5318d03735dd0481cd0e3ee42ae0573633ac72 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 14 Nov 2025 00:16:12 +0100 Subject: [PATCH 17/19] stop using "nofallback" revision terminology --- ...fallback-unconstrained-return.e2021.stderr | 43 +++++++++++++++++++ ...fallback-unconstrained-return.e2024.stderr | 24 +++++++++++ ...diverging-fallback-unconstrained-return.rs | 10 ++--- .../fallback-closure-wrap.e2024.stderr | 15 +++++++ tests/ui/never_type/fallback-closure-wrap.rs | 13 +++--- 5 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 tests/ui/never_type/diverging-fallback-unconstrained-return.e2021.stderr create mode 100644 tests/ui/never_type/diverging-fallback-unconstrained-return.e2024.stderr create mode 100644 tests/ui/never_type/fallback-closure-wrap.e2024.stderr diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.e2021.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.e2021.stderr new file mode 100644 index 0000000000000..eb79cf5dd1559 --- /dev/null +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.e2021.stderr @@ -0,0 +1,43 @@ +error: this function depends on never type fallback being `()` + --> $DIR/diverging-fallback-unconstrained-return.rs:26:1 + | +LL | fn main() { + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! + = note: for more information, see + = help: specify the types explicitly +note: in edition 2024, the requirement `!: UnitReturn` will fail + --> $DIR/diverging-fallback-unconstrained-return.rs:37:23 + | +LL | let _ = if true { unconstrained_return() } else { panic!() }; + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _: () = if true { unconstrained_return() } else { panic!() }; + | ++++ + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: this function depends on never type fallback being `()` + --> $DIR/diverging-fallback-unconstrained-return.rs:26:1 + | +LL | fn main() { + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! + = note: for more information, see + = help: specify the types explicitly +note: in edition 2024, the requirement `!: UnitReturn` will fail + --> $DIR/diverging-fallback-unconstrained-return.rs:37:23 + | +LL | let _ = if true { unconstrained_return() } else { panic!() }; + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _: () = if true { unconstrained_return() } else { panic!() }; + | ++++ + diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.e2024.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.e2024.stderr new file mode 100644 index 0000000000000..d28f5d7de92f5 --- /dev/null +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.e2024.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `!: UnitReturn` is not satisfied + --> $DIR/diverging-fallback-unconstrained-return.rs:37:23 + | +LL | let _ = if true { unconstrained_return() } else { panic!() }; + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `UnitReturn` is not implemented for `!` + | +help: the following other types implement trait `UnitReturn` + --> $DIR/diverging-fallback-unconstrained-return.rs:15:1 + | +LL | impl UnitReturn for i32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` +LL | impl UnitReturn for () {} + | ^^^^^^^^^^^^^^^^^^^^^^ `()` + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) + = help: you might have intended to use the type `()` here instead +note: required by a bound in `unconstrained_return` + --> $DIR/diverging-fallback-unconstrained-return.rs:18:28 + | +LL | fn unconstrained_return() -> T { + | ^^^^^^^^^^ required by this bound in `unconstrained_return` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.rs b/tests/ui/never_type/diverging-fallback-unconstrained-return.rs index 565fac34bd786..1c8ce71080bfb 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.rs +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.rs @@ -4,8 +4,8 @@ // in the objc crate, where changing the fallback from `!` to `()` // resulted in unsoundness. // -//@ revisions: nofallback fallback -//@[fallback] edition: 2024 +//@ revisions: e2021 e2024 +//@[e2024] edition: 2024 #![expect(unit_bindings)] @@ -24,8 +24,8 @@ fn unconstrained_return() -> T { } fn main() { - //[nofallback]~^ error: this function depends on never type fallback being `()` - //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! + //[e2021]~^ error: this function depends on never type fallback being `()` + //[e2021]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! // In Ye Olde Days, the `T` parameter of `unconstrained_return` // winds up "entangled" with the `!` type that results from @@ -34,5 +34,5 @@ fn main() { // idea was to change that fallback to `!`, but that would have resulted // in this code no longer compiling (or worse, in some cases it injected // unsound results). - let _ = if true { unconstrained_return() } else { panic!() }; //[fallback]~ error: the trait bound `!: UnitReturn` is not satisfied + let _ = if true { unconstrained_return() } else { panic!() }; //[e2024]~ error: the trait bound `!: UnitReturn` is not satisfied } diff --git a/tests/ui/never_type/fallback-closure-wrap.e2024.stderr b/tests/ui/never_type/fallback-closure-wrap.e2024.stderr new file mode 100644 index 0000000000000..b55f9c99ae507 --- /dev/null +++ b/tests/ui/never_type/fallback-closure-wrap.e2024.stderr @@ -0,0 +1,15 @@ +error[E0271]: expected `{closure@fallback-closure-wrap.rs:16:40}` to return `()`, but it returns `!` + --> $DIR/fallback-closure-wrap.rs:17:9 + | +LL | let error = Closure::wrap(Box::new(move || { + | ------- this closure +LL | panic!("Can't connect to server."); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `!` + | + = note: expected unit type `()` + found type `!` + = note: required for the cast from `Box<{closure@$DIR/fallback-closure-wrap.rs:16:40: 16:47}>` to `Box` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/never_type/fallback-closure-wrap.rs b/tests/ui/never_type/fallback-closure-wrap.rs index 77546bb93c28d..51be6ac06cc21 100644 --- a/tests/ui/never_type/fallback-closure-wrap.rs +++ b/tests/ui/never_type/fallback-closure-wrap.rs @@ -1,22 +1,21 @@ // This is a minified example from Crater breakage observed when attempting to // stabilize never type, nstoddard/webgl-gui @ 22f0169f. // -// This particular test case currently fails as the inference to `()` rather -// than `!` happens as a result of an `as` cast, which is not currently tracked. // Crater did not find many cases of this occurring, but it is included for // awareness. // -//@ revisions: nofallback fallback -//@[fallback] edition: 2024 -//@[nofallback] check-pass -//@[fallback] check-fail +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +// +//@[e2021] check-pass use std::marker::PhantomData; fn main() { let error = Closure::wrap(Box::new(move || { panic!("Can't connect to server."); - //[fallback]~^ ERROR to return `()`, but it returns `!` + //[e2024]~^ ERROR to return `()`, but it returns `!` }) as Box); } From e833f244faf99c07826dfdf3ab5d83706ae4807f Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 2 Dec 2025 03:41:45 +0000 Subject: [PATCH 18/19] Rename supertrait item shadowing lints --- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +-- .../rustc_hir_typeck/src/method/confirm.rs | 4 +-- compiler/rustc_lint_defs/src/builtin.rs | 28 +++++++++++-------- .../supertrait-shadowing/common-ancestor-2.rs | 4 +-- .../common-ancestor-2.stderr | 8 +++--- .../supertrait-shadowing/common-ancestor-3.rs | 4 +-- .../common-ancestor-3.stderr | 8 +++--- .../supertrait-shadowing/common-ancestor.rs | 4 +-- .../common-ancestor.stderr | 8 +++--- .../supertrait-shadowing/definition-site.rs | 2 +- .../definition-site.stderr | 4 +-- .../false-subtrait-after-inference.rs | 4 +-- .../false-subtrait-after-inference.stderr | 8 +++--- 13 files changed, 47 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 06738d99bf562..0e8859facf58b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -13,7 +13,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{AmbigArg, ItemKind, find_attr}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt}; -use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; +use rustc_lint_defs::builtin::SHADOWING_SUPERTRAIT_ITEMS; use rustc_macros::LintDiagnostic; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::solve::NoSolution; @@ -797,7 +797,7 @@ fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_i }; tcx.emit_node_span_lint( - SUPERTRAIT_ITEM_SHADOWING_DEFINITION, + SHADOWING_SUPERTRAIT_ITEMS, tcx.local_def_id_to_hir_id(trait_item_def_id), tcx.def_span(trait_item_def_id), errors::SupertraitItemShadowing { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index f7a0a55d5880d..e81537008bb5e 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -12,7 +12,7 @@ use rustc_hir_analysis::hir_ty_lowering::{ use rustc_infer::infer::{ BoundRegionConversionTime, DefineOpaqueTypes, InferOk, RegionVariableOrigin, }; -use rustc_lint::builtin::SUPERTRAIT_ITEM_SHADOWING_USAGE; +use rustc_lint::builtin::RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, @@ -709,7 +709,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { }; self.tcx.emit_node_span_lint( - SUPERTRAIT_ITEM_SHADOWING_USAGE, + RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS, segment.hir_id, segment.ident.span, SupertraitItemShadowing { shadower, shadowee, item: segment.ident.name, subtrait }, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 899632b9d4b75..2f0333160f52b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -88,6 +88,7 @@ declare_lint_pass! { RENAMED_AND_REMOVED_LINTS, REPR_C_ENUMS_LARGER_THAN_INT, REPR_TRANSPARENT_NON_ZST_FIELDS, + RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS, RTSAN_NONBLOCKING_ASYNC, RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, RUST_2021_INCOMPATIBLE_OR_PATTERNS, @@ -98,11 +99,10 @@ declare_lint_pass! { RUST_2024_PRELUDE_COLLISIONS, SELF_CONSTRUCTOR_FROM_OUTER_ITEM, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, + SHADOWING_SUPERTRAIT_ITEMS, SINGLE_USE_LIFETIMES, SOFT_UNSTABLE, STABLE_FEATURES, - SUPERTRAIT_ITEM_SHADOWING_DEFINITION, - SUPERTRAIT_ITEM_SHADOWING_USAGE, TAIL_EXPR_DROP_ORDER, TEST_UNSTABLE_LINT, TEXT_DIRECTION_CODEPOINT_IN_COMMENT, @@ -4922,15 +4922,16 @@ declare_lint! { } declare_lint! { - /// The `supertrait_item_shadowing_usage` lint detects when the + /// The `resolving_to_items_shadowing_supertrait_items` lint detects when the /// usage of an item that is provided by both a subtrait and supertrait /// is shadowed, preferring the subtrait. /// /// ### Example /// - /// ```rust,compile_fail + #[cfg_attr(bootstrap, doc = "```ignore")] + #[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")] /// #![feature(supertrait_item_shadowing)] - /// #![deny(supertrait_item_shadowing_usage)] + /// #![deny(resolving_to_items_shadowing_supertrait_items)] /// /// trait Upstream { /// fn hello(&self) {} @@ -4944,7 +4945,8 @@ declare_lint! { /// /// struct MyType; /// MyType.hello(); - /// ``` + #[cfg_attr(bootstrap, doc = "```")] + #[cfg_attr(not(bootstrap), doc = "```")] /// /// {{produces}} /// @@ -4955,7 +4957,7 @@ declare_lint! { /// selection. In order to mitigate side-effects of this happening /// silently, this lint detects these cases when users want to deny them /// or fix the call sites. - pub SUPERTRAIT_ITEM_SHADOWING_USAGE, + pub RESOLVING_TO_ITEMS_SHADOWING_SUPERTRAIT_ITEMS, // FIXME(supertrait_item_shadowing): It is not decided if this should // warn by default at the call site. Allow, @@ -4964,15 +4966,16 @@ declare_lint! { } declare_lint! { - /// The `supertrait_item_shadowing_definition` lint detects when the + /// The `shadowing_supertrait_items` lint detects when the /// definition of an item that is provided by both a subtrait and /// supertrait is shadowed, preferring the subtrait. /// /// ### Example /// - /// ```rust,compile_fail + #[cfg_attr(bootstrap, doc = "```ignore")] + #[cfg_attr(not(bootstrap), doc = "```rust,compile_fail")] /// #![feature(supertrait_item_shadowing)] - /// #![deny(supertrait_item_shadowing_definition)] + /// #![deny(shadowing_supertrait_items)] /// /// trait Upstream { /// fn hello(&self) {} @@ -4983,7 +4986,8 @@ declare_lint! { /// fn hello(&self) {} /// } /// impl Downstream for T {} - /// ``` + #[cfg_attr(bootstrap, doc = "```")] + #[cfg_attr(not(bootstrap), doc = "```")] /// /// {{produces}} /// @@ -4994,7 +4998,7 @@ declare_lint! { /// selection. In order to mitigate side-effects of this happening /// silently, this lint detects these cases when users want to deny them /// or fix their trait definitions. - pub SUPERTRAIT_ITEM_SHADOWING_DEFINITION, + pub SHADOWING_SUPERTRAIT_ITEMS, // FIXME(supertrait_item_shadowing): It is not decided if this should // warn by default at the usage site. Allow, diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs index cecf6dccf9d16..525844983f510 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.rs @@ -2,8 +2,8 @@ //@ check-run-results #![feature(supertrait_item_shadowing)] -#![warn(supertrait_item_shadowing_usage)] -#![warn(supertrait_item_shadowing_definition)] +#![warn(resolving_to_items_shadowing_supertrait_items)] +#![warn(shadowing_supertrait_items)] #![allow(dead_code)] trait A { diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr index 934d5a0f7cfd3..392489c6734a1 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-2.stderr @@ -15,8 +15,8 @@ LL | fn hello(&self) { note: the lint level is defined here --> $DIR/common-ancestor-2.rs:6:9 | -LL | #![warn(supertrait_item_shadowing_definition)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `C` shadows identically named item from supertrait --> $DIR/common-ancestor-2.rs:32:8 @@ -40,8 +40,8 @@ LL | fn hello(&self) { note: the lint level is defined here --> $DIR/common-ancestor-2.rs:5:9 | -LL | #![warn(supertrait_item_shadowing_usage)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(resolving_to_items_shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 2 warnings emitted diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs index 040fa9aab3987..d647c07d966d3 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.rs @@ -2,8 +2,8 @@ //@ check-run-results #![feature(supertrait_item_shadowing)] -#![warn(supertrait_item_shadowing_usage)] -#![warn(supertrait_item_shadowing_definition)] +#![warn(resolving_to_items_shadowing_supertrait_items)] +#![warn(shadowing_supertrait_items)] #![allow(dead_code)] trait A { diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr index 28e44a2ff209a..fc0a22a9cf330 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor-3.stderr @@ -15,8 +15,8 @@ LL | fn hello(&self) { note: the lint level is defined here --> $DIR/common-ancestor-3.rs:6:9 | -LL | #![warn(supertrait_item_shadowing_definition)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `D` shadows identically named item from supertrait --> $DIR/common-ancestor-3.rs:34:5 @@ -61,8 +61,8 @@ LL | fn hello(&self) { note: the lint level is defined here --> $DIR/common-ancestor-3.rs:5:9 | -LL | #![warn(supertrait_item_shadowing_usage)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(resolving_to_items_shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 3 warnings emitted diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor.rs b/tests/ui/methods/supertrait-shadowing/common-ancestor.rs index 8e67c93536755..eeda26c4bd7e0 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor.rs +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor.rs @@ -2,8 +2,8 @@ //@ check-run-results #![feature(supertrait_item_shadowing)] -#![warn(supertrait_item_shadowing_usage)] -#![warn(supertrait_item_shadowing_definition)] +#![warn(resolving_to_items_shadowing_supertrait_items)] +#![warn(shadowing_supertrait_items)] #![allow(dead_code)] trait A { diff --git a/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr b/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr index f404fa6b53a35..be67fdf456b88 100644 --- a/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr +++ b/tests/ui/methods/supertrait-shadowing/common-ancestor.stderr @@ -12,8 +12,8 @@ LL | fn hello(&self) { note: the lint level is defined here --> $DIR/common-ancestor.rs:6:9 | -LL | #![warn(supertrait_item_shadowing_definition)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `B` shadows identically named item from supertrait --> $DIR/common-ancestor.rs:25:8 @@ -34,8 +34,8 @@ LL | fn hello(&self) { note: the lint level is defined here --> $DIR/common-ancestor.rs:5:9 | -LL | #![warn(supertrait_item_shadowing_usage)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(resolving_to_items_shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 2 warnings emitted diff --git a/tests/ui/methods/supertrait-shadowing/definition-site.rs b/tests/ui/methods/supertrait-shadowing/definition-site.rs index 2768a6a6b2717..248df032736f6 100644 --- a/tests/ui/methods/supertrait-shadowing/definition-site.rs +++ b/tests/ui/methods/supertrait-shadowing/definition-site.rs @@ -1,5 +1,5 @@ #![feature(supertrait_item_shadowing)] -#![deny(supertrait_item_shadowing_definition)] +#![deny(shadowing_supertrait_items)] trait SuperSuper { fn method(); diff --git a/tests/ui/methods/supertrait-shadowing/definition-site.stderr b/tests/ui/methods/supertrait-shadowing/definition-site.stderr index f0bbf414a690c..1e35a753a9ebc 100644 --- a/tests/ui/methods/supertrait-shadowing/definition-site.stderr +++ b/tests/ui/methods/supertrait-shadowing/definition-site.stderr @@ -12,8 +12,8 @@ LL | fn method(); note: the lint level is defined here --> $DIR/definition-site.rs:2:9 | -LL | #![deny(supertrait_item_shadowing_definition)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![deny(shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait item `method` from `Sub` shadows identically named item from supertrait --> $DIR/definition-site.rs:14:5 diff --git a/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.rs b/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.rs index c3bc47e6740d8..78df1b0892df9 100644 --- a/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.rs +++ b/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.rs @@ -1,6 +1,6 @@ #![feature(supertrait_item_shadowing)] -#![warn(supertrait_item_shadowing_usage)] -#![warn(supertrait_item_shadowing_definition)] +#![warn(resolving_to_items_shadowing_supertrait_items)] +#![warn(shadowing_supertrait_items)] struct W(T); diff --git a/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.stderr b/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.stderr index 47019ca7a320f..7832761169ad1 100644 --- a/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.stderr +++ b/tests/ui/methods/supertrait-shadowing/false-subtrait-after-inference.stderr @@ -12,8 +12,8 @@ LL | fn hello(&self) {} note: the lint level is defined here --> $DIR/false-subtrait-after-inference.rs:3:9 | -LL | #![warn(supertrait_item_shadowing_definition)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: trait item `hello` from `Downstream` shadows identically named item from supertrait --> $DIR/false-subtrait-after-inference.rs:22:7 @@ -34,8 +34,8 @@ LL | fn hello(&self) {} note: the lint level is defined here --> $DIR/false-subtrait-after-inference.rs:2:9 | -LL | #![warn(supertrait_item_shadowing_usage)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![warn(resolving_to_items_shadowing_supertrait_items)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/false-subtrait-after-inference.rs:22:7 From 388c42e72a832aae836f8e9b885137a73646f718 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 3 Dec 2025 14:10:54 +0300 Subject: [PATCH 19/19] linker: Remove special case for `rust-lld` in `detect_self_contained_mingw` `rust-lld` is supposed to live in sysroot, so it doesn't change the behavior of the function, only removes a potential micro-optimization. --- compiler/rustc_codegen_ssa/src/back/link.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 878b333580e1c..d35c3b6bb189e 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1763,10 +1763,6 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind { // Returns true if linker is located within sysroot fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool { - // Assume `-C linker=rust-lld` as self-contained mode - if linker == Path::new("rust-lld") { - return true; - } let linker_with_extension = if cfg!(windows) && linker.extension().is_none() { linker.with_extension("exe") } else {