Skip to content
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

Revert stabilization of never type #67224

Merged
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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 {
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
95 changes: 88 additions & 7 deletions src/libcore/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

#![stable(feature = "rust1", since = "1.0.0")]

use crate::fmt;

mod num;

#[unstable(feature = "convert_float_to_int", issue = "67057")]
Expand Down Expand Up @@ -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:
///
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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`].
///
Expand All @@ -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
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
11 changes: 11 additions & 0 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#![stable(feature = "rust1", since = "1.0.0")]

use crate::convert::Infallible;
use crate::fmt;
use crate::intrinsics;
use crate::mem;
Expand Down Expand Up @@ -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 {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_utils/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_error_codes/error_codes/E0725.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_feature/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_feature/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
2 changes: 1 addition & 1 deletion src/libserialize/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down
9 changes: 8 additions & 1 deletion src/libstd/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
4 changes: 3 additions & 1 deletion src/libstd/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ mod prim_bool { }
/// write:
///
/// ```
/// #![feature(never_type)]
/// # fn foo() -> u32 {
/// let x: ! = {
/// return 123
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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")]
Expand Down
Loading