about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-04-05 19:30:03 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-05-19 10:12:35 +0200
commit9f7c5a80a38ea64ea49dd1a048e023c623a10acc (patch)
tree42d4c63ad64093cfaa0fd6f0d7c80f8b53d6c9e3
parentaab144f6d12101b202b42ceea329dc0ba5dcfe2a (diff)
downloadrust-9f7c5a80a38ea64ea49dd1a048e023c623a10acc.tar.gz
rust-9f7c5a80a38ea64ea49dd1a048e023c623a10acc.zip
update libcore, add `discriminant_kind` lang-item
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md1
-rw-r--r--src/libcore/intrinsics.rs6
-rw-r--r--src/libcore/marker.rs32
-rw-r--r--src/libcore/mem/mod.rs6
-rw-r--r--src/librustc_hir/lang_items.rs1
-rw-r--r--src/librustc_typeck/check/intrinsic.rs24
6 files changed, 58 insertions, 12 deletions
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 25082432192..20c7d7dcec8 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -287,6 +287,7 @@ the source code.
   - `unsize`: `libcore/marker.rs`
   - `sync`: `libcore/marker.rs`
   - `phantom_data`: `libcore/marker.rs`
+  - `discriminant_kind`: `libcore/marker.rs`
   - `freeze`: `libcore/marker.rs`
   - `debug_trait`: `libcore/fmt/mod.rs`
   - `non_zero`: `libcore/nonzero.rs`
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index a60380137e1..9006e4cfaf7 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -54,6 +54,8 @@
 )]
 #![allow(missing_docs)]
 
+#[cfg(not(bootstrap))]
+use crate::marker::DiscriminantKind;
 use crate::mem;
 
 #[stable(feature = "drop_in_place", since = "1.8.0")]
@@ -1912,6 +1914,10 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is
     /// [`std::mem::discriminant`](../../std/mem/fn.discriminant.html)
     #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
+    #[cfg(not(bootstrap))]
+    pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
+    #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
+    #[cfg(bootstrap)]
     pub fn discriminant_value<T>(v: &T) -> u64;
 
     /// Rust's "try catch" construct which invokes the function pointer `try_fn`
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 339b07119c6..c0c0f66aff9 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -8,6 +8,7 @@
 
 use crate::cell::UnsafeCell;
 use crate::cmp;
+use crate::fmt::Debug;
 use crate::hash::Hash;
 use crate::hash::Hasher;
 
@@ -679,6 +680,37 @@ mod impls {
     unsafe impl<T: Send + ?Sized> Send for &mut T {}
 }
 
+/// Compiler-internal trait used to indicate the type of enum discriminants.
+///
+/// This trait is automatically implemented for every type and does not add any
+/// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute
+/// between `DiscriminantKind::Discriminant` and `mem::Discriminant`.
+///
+/// [`mem::Discriminant`]: https://doc.rust-lang.org/stable/core/mem/struct.Discriminant.html
+#[unstable(
+    feature = "discriminant_kind",
+    issue = "none",
+    reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
+)]
+#[cfg_attr(not(bootstrap), lang = "discriminant_kind")]
+pub trait DiscriminantKind {
+    /// The type of the dicriminant, which must satisfy the trait
+    /// bounds required by `mem::Discriminant`.
+    type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
+}
+
+// Manually implement `DiscriminantKind` for all types during bootstrap
+// to reduce the required amount of conditional compilation.
+#[unstable(
+    feature = "discriminant_kind",
+    issue = "none",
+    reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
+)]
+#[cfg(bootstrap)]
+impl<T: ?Sized> DiscriminantKind for T {
+    type Discriminant = u64;
+}
+
 /// Compiler-internal trait used to determine whether a type contains
 /// any `UnsafeCell` internally, but not through an indirection.
 /// This affects, for example, whether a `static` of that type is
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index b1bbcaeab8d..010f2958e36 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -10,7 +10,7 @@ use crate::cmp;
 use crate::fmt;
 use crate::hash;
 use crate::intrinsics;
-use crate::marker::{Copy, PhantomData, Sized};
+use crate::marker::{Copy, DiscriminantKind, Sized};
 use crate::ptr;
 
 mod manually_drop;
@@ -930,7 +930,7 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
 ///
 /// [`discriminant`]: fn.discriminant.html
 #[stable(feature = "discriminant_value", since = "1.21.0")]
-pub struct Discriminant<T>(u64, PhantomData<fn() -> T>);
+pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
 
 // N.B. These trait implementations cannot be derived because we don't want any bounds on T.
 
@@ -995,5 +995,5 @@ impl<T> fmt::Debug for Discriminant<T> {
 #[stable(feature = "discriminant_value", since = "1.21.0")]
 #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
 pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
-    Discriminant(intrinsics::discriminant_value(v), PhantomData)
+    Discriminant(intrinsics::discriminant_value(v))
 }
diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs
index 53f72804a84..04fe3b60b6a 100644
--- a/src/librustc_hir/lang_items.rs
+++ b/src/librustc_hir/lang_items.rs
@@ -163,6 +163,7 @@ language_item_table! {
     CopyTraitLangItem,           "copy",               copy_trait,              Target::Trait;
     CloneTraitLangItem,          "clone",              clone_trait,             Target::Trait;
     SyncTraitLangItem,           "sync",               sync_trait,              Target::Trait;
+    DiscriminantKindTraitLangItem,"discriminant_kind", discriminant_kind_trait, Target::Trait;
     FreezeTraitLangItem,         "freeze",             freeze_trait,            Target::Trait;
 
     DropTraitLangItem,           "drop",               drop_trait,              Target::Trait;
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index db6c30adb04..68f9025fd19 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -8,7 +8,7 @@ use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_target::spec::abi::Abi;
 
 use std::iter;
@@ -283,14 +283,20 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             "likely" => (0, vec![tcx.types.bool], tcx.types.bool),
             "unlikely" => (0, vec![tcx.types.bool], tcx.types.bool),
 
-            "discriminant_value" => (
-                1,
-                vec![tcx.mk_imm_ref(
-                    tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))),
-                    param(0),
-                )],
-                tcx.types.u64,
-            ),
+            "discriminant_value" => {
+                let assoc_items =
+                    tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
+                let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
+
+                (
+                    1,
+                    vec![tcx.mk_imm_ref(
+                        tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))),
+                        param(0),
+                    )],
+                    tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())),
+                )
+            }
 
             "try" => {
                 let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);