Skip to content

Commit 88c9fc9

Browse files
author
Nicholas Matsakis
committed
Revert "Redefine core::convert::Infallible as !."
This reverts commit 089229a.
1 parent 12307b3 commit 88c9fc9

File tree

3 files changed

+106
-7
lines changed

3 files changed

+106
-7
lines changed

src/libcore/convert/mod.rs

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
4141
#![stable(feature = "rust1", since = "1.0.0")]
4242

43+
use crate::fmt;
44+
4345
mod num;
4446

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

636-
/// A type alias for [the `!` “never” type][never].
641+
/// The error type for errors that can never happen.
637642
///
638-
/// `Infallible` represents types of errors that can never happen since `!` has no valid values.
643+
/// Since this enum has no variant, a value of this type can never actually exist.
639644
/// This can be useful for generic APIs that use [`Result`] and parameterize the error type,
640645
/// to indicate that the result is always [`Ok`].
641646
///
@@ -652,15 +657,91 @@ impl AsRef<str> for str {
652657
/// }
653658
/// ```
654659
///
655-
/// # Eventual deprecation
660+
/// # Future compatibility
661+
///
662+
/// This enum has the same role as [the `!` “never” type][never],
663+
/// which is unstable in this version of Rust.
664+
/// When `!` is stabilized, we plan to make `Infallible` a type alias to it:
665+
///
666+
/// ```ignore (illustrates future std change)
667+
/// pub type Infallible = !;
668+
/// ```
669+
///
670+
/// … and eventually deprecate `Infallible`.
671+
///
672+
///
673+
/// However there is one case where `!` syntax can be used
674+
/// before `!` is stabilized as a full-fleged type: in the position of a function’s return type.
675+
/// Specifically, it is possible implementations for two different function pointer types:
676+
///
677+
/// ```
678+
/// trait MyTrait {}
679+
/// impl MyTrait for fn() -> ! {}
680+
/// impl MyTrait for fn() -> std::convert::Infallible {}
681+
/// ```
656682
///
657-
/// Previously, `Infallible` was defined as `enum Infallible {}`.
658-
/// Now that it is merely a type alias to `!`, we will eventually deprecate `Infallible`.
683+
/// With `Infallible` being an enum, this code is valid.
684+
/// However when `Infallible` becomes an alias for the never type,
685+
/// the two `impl`s will start to overlap
686+
/// and therefore will be disallowed by the language’s trait coherence rules.
659687
///
660688
/// [`Ok`]: ../result/enum.Result.html#variant.Ok
661689
/// [`Result`]: ../result/enum.Result.html
662690
/// [`TryFrom`]: trait.TryFrom.html
663691
/// [`Into`]: trait.Into.html
664692
/// [never]: ../../std/primitive.never.html
665693
#[stable(feature = "convert_infallible", since = "1.34.0")]
666-
pub type Infallible = !;
694+
#[derive(Copy)]
695+
pub enum Infallible {}
696+
697+
#[stable(feature = "convert_infallible", since = "1.34.0")]
698+
impl Clone for Infallible {
699+
fn clone(&self) -> Infallible {
700+
match *self {}
701+
}
702+
}
703+
704+
#[stable(feature = "convert_infallible", since = "1.34.0")]
705+
impl fmt::Debug for Infallible {
706+
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
707+
match *self {}
708+
}
709+
}
710+
711+
#[stable(feature = "convert_infallible", since = "1.34.0")]
712+
impl fmt::Display for Infallible {
713+
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
714+
match *self {}
715+
}
716+
}
717+
718+
#[stable(feature = "convert_infallible", since = "1.34.0")]
719+
impl PartialEq for Infallible {
720+
fn eq(&self, _: &Infallible) -> bool {
721+
match *self {}
722+
}
723+
}
724+
725+
#[stable(feature = "convert_infallible", since = "1.34.0")]
726+
impl Eq for Infallible {}
727+
728+
#[stable(feature = "convert_infallible", since = "1.34.0")]
729+
impl PartialOrd for Infallible {
730+
fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> {
731+
match *self {}
732+
}
733+
}
734+
735+
#[stable(feature = "convert_infallible", since = "1.34.0")]
736+
impl Ord for Infallible {
737+
fn cmp(&self, _other: &Self) -> crate::cmp::Ordering {
738+
match *self {}
739+
}
740+
}
741+
742+
#[stable(feature = "convert_infallible", since = "1.34.0")]
743+
impl From<!> for Infallible {
744+
fn from(x: !) -> Self {
745+
x
746+
}
747+
}

src/libcore/num/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
#![stable(feature = "rust1", since = "1.0.0")]
66

7+
use crate::convert::Infallible;
78
use crate::fmt;
89
use crate::intrinsics;
910
use crate::mem;
@@ -4724,8 +4725,18 @@ impl fmt::Display for TryFromIntError {
47244725
}
47254726

47264727
#[stable(feature = "try_from", since = "1.34.0")]
4728+
impl From<Infallible> for TryFromIntError {
4729+
fn from(x: Infallible) -> TryFromIntError {
4730+
match x {}
4731+
}
4732+
}
4733+
4734+
#[stable(feature = "never_type", since = "1.41.0")]
47274735
impl From<!> for TryFromIntError {
47284736
fn from(never: !) -> TryFromIntError {
4737+
// Match rather than coerce to make sure that code like
4738+
// `From<Infallible> for TryFromIntError` above will keep working
4739+
// when `Infallible` becomes an alias to `!`.
47294740
match never {}
47304741
}
47314742
}

src/libstd/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,13 @@ impl Error for string::FromUtf16Error {
551551
}
552552
}
553553

554+
#[stable(feature = "str_parse_error2", since = "1.8.0")]
555+
impl Error for string::ParseError {
556+
fn description(&self) -> &str {
557+
match *self {}
558+
}
559+
}
560+
554561
#[stable(feature = "decode_utf16", since = "1.9.0")]
555562
impl Error for char::DecodeUtf16Error {
556563
fn description(&self) -> &str {

0 commit comments

Comments
 (0)