Skip to content

Revert stabilization of never type #67224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcore/clone.rs
Original file line number Diff line number Diff line change
@@ -195,7 +195,7 @@ mod impls {
bool char
}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Clone for ! {
#[inline]
fn clone(&self) -> Self {
8 changes: 4 additions & 4 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
@@ -1141,24 +1141,24 @@ mod impls {

ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl PartialEq for ! {
fn eq(&self, _: &!) -> bool {
*self
}
}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Eq for ! {}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl PartialOrd for ! {
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
*self
}
}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Ord for ! {
fn cmp(&self, _: &!) -> Ordering {
*self
95 changes: 88 additions & 7 deletions src/libcore/convert/mod.rs
Original file line number Diff line number Diff line change
@@ -40,6 +40,8 @@
#![stable(feature = "rust1", since = "1.0.0")]

use crate::fmt;

mod num;

#[unstable(feature = "convert_float_to_int", issue = "67057")]
@@ -429,7 +431,9 @@ pub trait TryInto<T>: Sized {
/// - `TryFrom<T> for U` implies [`TryInto`]`<U> for T`
/// - [`try_from`] is reflexive, which means that `TryFrom<T> for T`
/// is implemented and cannot fail -- the associated `Error` type for
/// calling `T::try_from()` on a value of type `T` is [`!`].
/// calling `T::try_from()` on a value of type `T` is [`Infallible`].
/// When the [`!`] type is stabilized [`Infallible`] and [`!`] will be
/// equivalent.
///
/// `TryFrom<T>` can be implemented as follows:
///
@@ -478,6 +482,7 @@ pub trait TryInto<T>: Sized {
/// [`TryInto`]: trait.TryInto.html
/// [`i32::MAX`]: ../../std/i32/constant.MAX.html
/// [`!`]: ../../std/primitive.never.html
/// [`Infallible`]: enum.Infallible.html
#[stable(feature = "try_from", since = "1.34.0")]
pub trait TryFrom<T>: Sized {
/// The type returned in the event of a conversion error.
@@ -633,9 +638,9 @@ impl AsRef<str> for str {
// THE NO-ERROR ERROR TYPE
////////////////////////////////////////////////////////////////////////////////

/// A type alias for [the `!` “never” type][never].
/// The error type for errors that can never happen.
///
/// `Infallible` represents types of errors that can never happen since `!` has no valid values.
/// Since this enum has no variant, a value of this type can never actually exist.
/// This can be useful for generic APIs that use [`Result`] and parameterize the error type,
/// to indicate that the result is always [`Ok`].
///
@@ -652,15 +657,91 @@ impl AsRef<str> for str {
/// }
/// ```
///
/// # Eventual deprecation
/// # Future compatibility
///
/// This enum has the same role as [the `!` “never” type][never],
/// which is unstable in this version of Rust.
/// When `!` is stabilized, we plan to make `Infallible` a type alias to it:
///
/// ```ignore (illustrates future std change)
/// pub type Infallible = !;
/// ```
///
/// … and eventually deprecate `Infallible`.
///
///
/// However there is one case where `!` syntax can be used
/// before `!` is stabilized as a full-fleged type: in the position of a function’s return type.
/// Specifically, it is possible implementations for two different function pointer types:
///
/// ```
/// trait MyTrait {}
/// impl MyTrait for fn() -> ! {}
/// impl MyTrait for fn() -> std::convert::Infallible {}
/// ```
///
/// Previously, `Infallible` was defined as `enum Infallible {}`.
/// Now that it is merely a type alias to `!`, we will eventually deprecate `Infallible`.
/// With `Infallible` being an enum, this code is valid.
/// However when `Infallible` becomes an alias for the never type,
/// the two `impl`s will start to overlap
/// and therefore will be disallowed by the language’s trait coherence rules.
///
/// [`Ok`]: ../result/enum.Result.html#variant.Ok
/// [`Result`]: ../result/enum.Result.html
/// [`TryFrom`]: trait.TryFrom.html
/// [`Into`]: trait.Into.html
/// [never]: ../../std/primitive.never.html
#[stable(feature = "convert_infallible", since = "1.34.0")]
pub type Infallible = !;
#[derive(Copy)]
pub enum Infallible {}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Clone for Infallible {
fn clone(&self) -> Infallible {
match *self {}
}
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl fmt::Debug for Infallible {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl fmt::Display for Infallible {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {}
}
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl PartialEq for Infallible {
fn eq(&self, _: &Infallible) -> bool {
match *self {}
}
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Eq for Infallible {}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl PartialOrd for Infallible {
fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> {
match *self {}
}
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Ord for Infallible {
fn cmp(&self, _other: &Self) -> crate::cmp::Ordering {
match *self {}
}
}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl From<!> for Infallible {
fn from(x: !) -> Self {
x
}
}
4 changes: 2 additions & 2 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
@@ -1940,14 +1940,14 @@ macro_rules! fmt_refs {

fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Debug for ! {
fn fmt(&self, _: &mut Formatter<'_>) -> Result {
*self
}
}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Display for ! {
fn fmt(&self, _: &mut Formatter<'_>) -> Result {
*self
2 changes: 1 addition & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@
#![feature(iter_once_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(nll)]
#![feature(exhaustive_patterns)]
#![feature(no_core)]
2 changes: 1 addition & 1 deletion src/libcore/marker.rs
Original file line number Diff line number Diff line change
@@ -776,7 +776,7 @@ mod copy_impls {
bool char
}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Copy for ! {}

#[stable(feature = "rust1", since = "1.0.0")]
11 changes: 11 additions & 0 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use crate::convert::Infallible;
use crate::fmt;
use crate::intrinsics;
use crate::mem;
@@ -4724,8 +4725,18 @@ impl fmt::Display for TryFromIntError {
}

#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
fn from(x: Infallible) -> TryFromIntError {
match x {}
}
}

#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
fn from(never: !) -> TryFromIntError {
// Match rather than coerce to make sure that code like
// `From<Infallible> for TryFromIntError` above will keep working
// when `Infallible` becomes an alias to `!`.
match never {}
}
}
2 changes: 1 addition & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![cfg_attr(windows, feature(libc))]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![feature(overlapping_marker_traits)]
#![feature(extern_types)]
2 changes: 1 addition & 1 deletion src/librustc_codegen_utils/lib.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(nll)]
#![feature(in_band_lifetimes)]

4 changes: 2 additions & 2 deletions src/librustc_error_codes/error_codes/E0725.md
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ command line flags.
Erroneous code example:

```ignore (can't specify compiler flags from doctests)
#![feature(specialization)] // error: the feature `specialization` is not in
// the list of allowed features
#![feature(never_type)] // error: the feature `never_type` is not in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep #![feature(specialization)] to make things easier the second time around.

// the list of allowed features
```

Delete the offending feature attribute, or add it to the list of allowed
2 changes: 0 additions & 2 deletions src/librustc_feature/accepted.rs
Original file line number Diff line number Diff line change
@@ -253,8 +253,6 @@ declare_features! (
(accepted, const_constructor, "1.40.0", Some(61456), None),
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
(accepted, cfg_doctest, "1.40.0", Some(62210), None),
/// Allows the `!` type. Does not imply 'exhaustive_patterns' any more.
(accepted, never_type, "1.41.0", Some(35121), None),
/// Allows relaxing the coherence rules such that
/// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
(accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
3 changes: 3 additions & 0 deletions src/librustc_feature/active.rs
Original file line number Diff line number Diff line change
@@ -307,6 +307,9 @@ declare_features! (
/// Allows `X..Y` patterns.
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),

/// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
(active, never_type, "1.13.0", Some(35121), None),

/// Allows exhaustive pattern matching on types that contain uninhabited types.
(active, exhaustive_patterns, "1.13.0", Some(51085), None),

2 changes: 1 addition & 1 deletion src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![feature(drain_filter)]
#![feature(exhaustive_patterns)]
#![feature(iter_order_by)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(specialization)]
#![feature(try_trait)]
#![feature(unicode_internals)]
2 changes: 1 addition & 1 deletion src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ This API is completely unstable and subject to change.
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(slice_patterns)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]

#![recursion_limit="256"]

2 changes: 1 addition & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
#![feature(crate_visibility_modifier)]
#![feature(const_fn)]
#![feature(drain_filter)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(unicode_internals)]

#![recursion_limit="256"]
2 changes: 1 addition & 1 deletion src/libserialize/lib.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ Core encoding and decoding interfaces.
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(specialization)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(nll)]
#![feature(associated_type_bounds)]
#![cfg_attr(test, feature(test))]
9 changes: 8 additions & 1 deletion src/libstd/error.rs
Original file line number Diff line number Diff line change
@@ -465,7 +465,7 @@ impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
}
}

#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
impl Error for ! {
fn description(&self) -> &str { *self }
}
@@ -551,6 +551,13 @@ impl Error for string::FromUtf16Error {
}
}

#[stable(feature = "str_parse_error2", since = "1.8.0")]
impl Error for string::ParseError {
fn description(&self) -> &str {
match *self {}
}
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl Error for char::DecodeUtf16Error {
fn description(&self) -> &str {
2 changes: 1 addition & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
@@ -281,7 +281,7 @@
#![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_slice)]
#![feature(needs_panic_runtime)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(never_type)]
#![feature(nll)]
#![cfg_attr(bootstrap, feature(on_unimplemented))]
#![feature(optin_builtin_traits)]
4 changes: 3 additions & 1 deletion src/libstd/primitive_docs.rs
Original file line number Diff line number Diff line change
@@ -71,6 +71,7 @@ mod prim_bool { }
/// write:
///
/// ```
/// #![feature(never_type)]
/// # fn foo() -> u32 {
/// let x: ! = {
/// return 123
@@ -200,6 +201,7 @@ mod prim_bool { }
/// for example:
///
/// ```
/// #![feature(never_type)]
/// # use std::fmt;
/// # trait Debug {
/// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result;
@@ -237,7 +239,7 @@ mod prim_bool { }
/// [`Default`]: default/trait.Default.html
/// [`default()`]: default/trait.Default.html#tymethod.default
///
#[stable(feature = "never_type", since = "1.41.0")]
#[unstable(feature = "never_type", issue = "35121")]
mod prim_never { }

#[doc(primitive = "char")]
Loading