about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2024.stderr26
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.rs34
-rw-r--r--tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs29
-rw-r--r--tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr12
-rw-r--r--tests/ui/never_type/question_mark_from_never.rs46
5 files changed, 147 insertions, 0 deletions
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
new file mode 100644
index 00000000000..e9a8882eb6c
--- /dev/null
+++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
@@ -0,0 +1,26 @@
+error[E0277]: the trait bound `!: Default` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:17:17
+   |
+LL |         true => Default::default(),
+   |                 ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
+   |
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
+   = help: did you intend to use the type `()` here instead?
+
+error[E0277]: the trait bound `!: Default` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:30:5
+   |
+LL |     deserialize()?;
+   |     ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
+   |
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
+   = help: did you intend to use the type `()` here instead?
+note: required by a bound in `deserialize`
+  --> $DIR/never-type-fallback-breaking.rs:26:23
+   |
+LL |     fn deserialize<T: Default>() -> Option<T> {
+   |                       ^^^^^^^ required by this bound in `deserialize`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs
new file mode 100644
index 00000000000..7dfa4702807
--- /dev/null
+++ b/tests/ui/editions/never-type-fallback-breaking.rs
@@ -0,0 +1,34 @@
+//@ revisions: e2021 e2024
+//
+//@[e2021] edition: 2021
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//
+//@[e2021] run-pass
+//@[e2024] check-fail
+
+fn main() {
+    m();
+    q();
+}
+
+fn m() {
+    let x = match true {
+        true => Default::default(),
+        //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+        false => panic!("..."),
+    };
+
+    dbg!(x);
+}
+
+fn q() -> Option<()> {
+    fn deserialize<T: Default>() -> Option<T> {
+        Some(T::default())
+    }
+
+    deserialize()?;
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+
+    None
+}
diff --git a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs
new file mode 100644
index 00000000000..19a1f9d0e13
--- /dev/null
+++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs
@@ -0,0 +1,29 @@
+// issue: rust-lang/rust#66757
+//
+// This is a *minimization* of the issue.
+// Note that the original version with the `?` does not fail anymore even with fallback to unit,
+// see `tests/ui/never_type/question_mark_from_never.rs`.
+//
+//@ revisions: unit never
+//@[never] check-pass
+#![allow(internal_features)]
+#![feature(rustc_attrs, never_type)]
+#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))]
+#![cfg_attr(never, rustc_never_type_options(fallback = "never"))]
+
+struct E;
+
+impl From<!> for E {
+    fn from(_: !) -> E {
+        E
+    }
+}
+
+#[allow(unreachable_code)]
+fn foo(never: !) {
+    <E as From<!>>::from(never); // Ok
+    <E as From<_>>::from(never); // Should the inference fail?
+    //[unit]~^ error: the trait bound `E: From<()>` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr
new file mode 100644
index 00000000000..3b8913ccf45
--- /dev/null
+++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `E: From<()>` is not satisfied
+  --> $DIR/from_infer_breaking_with_unit_fallback.rs:25:6
+   |
+LL |     <E as From<_>>::from(never); // Should the inference fail?
+   |      ^ the trait `From<()>` is not implemented for `E`
+   |
+   = help: the trait `From<!>` is implemented 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/question_mark_from_never.rs b/tests/ui/never_type/question_mark_from_never.rs
new file mode 100644
index 00000000000..06d2a1926ea
--- /dev/null
+++ b/tests/ui/never_type/question_mark_from_never.rs
@@ -0,0 +1,46 @@
+// issue: rust-lang/rust#66757
+//
+// See also: `tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs`.
+//
+//@ revisions: unit never
+//@ check-pass
+#![allow(internal_features)]
+#![feature(rustc_attrs, never_type)]
+#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))]
+#![cfg_attr(never, rustc_never_type_options(fallback = "never"))]
+
+type Infallible = !;
+
+struct E;
+
+impl From<Infallible> for E {
+    fn from(_: Infallible) -> E {
+        E
+    }
+}
+
+fn u32_try_from(x: u32) -> Result<u32, Infallible> {
+    Ok(x)
+}
+
+fn _f() -> Result<(), E> {
+    // In an old attempt to make `Infallible = !` this caused a problem.
+    //
+    // Because at the time the code desugared to
+    //
+    //   match u32::try_from(1u32) {
+    //       Ok(x) => x, Err(e) => return Err(E::from(e))
+    //   }
+    //
+    // With `Infallible = !`, `e: !` but with fallback to `()`, `e` in `E::from(e)` decayed to `()`
+    // causing an error.
+    //
+    // This does not happen with `Infallible = !`.
+    // And also does not happen with the newer `?` desugaring that does not pass `e` by value.
+    // (instead we only pass `Result<!, Error>` (where `Error = !` in this case) which does not get
+    // the implicit coercion and thus does not decay even with fallback to unit)
+    u32_try_from(1u32)?;
+    Ok(())
+}
+
+fn main() {}