Skip to content

Commit 9f7c5a8

Browse files
committed
update libcore, add discriminant_kind lang-item
1 parent aab144f commit 9f7c5a8

File tree

6 files changed

+58
-12
lines changed

6 files changed

+58
-12
lines changed

src/doc/unstable-book/src/language-features/lang-items.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ the source code.
287287
- `unsize`: `libcore/marker.rs`
288288
- `sync`: `libcore/marker.rs`
289289
- `phantom_data`: `libcore/marker.rs`
290+
- `discriminant_kind`: `libcore/marker.rs`
290291
- `freeze`: `libcore/marker.rs`
291292
- `debug_trait`: `libcore/fmt/mod.rs`
292293
- `non_zero`: `libcore/nonzero.rs`

src/libcore/intrinsics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
)]
5555
#![allow(missing_docs)]
5656

57+
#[cfg(not(bootstrap))]
58+
use crate::marker::DiscriminantKind;
5759
use crate::mem;
5860

5961
#[stable(feature = "drop_in_place", since = "1.8.0")]
@@ -1912,6 +1914,10 @@ extern "rust-intrinsic" {
19121914
/// The stabilized version of this intrinsic is
19131915
/// [`std::mem::discriminant`](../../std/mem/fn.discriminant.html)
19141916
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
1917+
#[cfg(not(bootstrap))]
1918+
pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
1919+
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
1920+
#[cfg(bootstrap)]
19151921
pub fn discriminant_value<T>(v: &T) -> u64;
19161922

19171923
/// Rust's "try catch" construct which invokes the function pointer `try_fn`

src/libcore/marker.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use crate::cell::UnsafeCell;
1010
use crate::cmp;
11+
use crate::fmt::Debug;
1112
use crate::hash::Hash;
1213
use crate::hash::Hasher;
1314

@@ -679,6 +680,37 @@ mod impls {
679680
unsafe impl<T: Send + ?Sized> Send for &mut T {}
680681
}
681682

683+
/// Compiler-internal trait used to indicate the type of enum discriminants.
684+
///
685+
/// This trait is automatically implemented for every type and does not add any
686+
/// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute
687+
/// between `DiscriminantKind::Discriminant` and `mem::Discriminant`.
688+
///
689+
/// [`mem::Discriminant`]: https://doc.rust-lang.org/stable/core/mem/struct.Discriminant.html
690+
#[unstable(
691+
feature = "discriminant_kind",
692+
issue = "none",
693+
reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
694+
)]
695+
#[cfg_attr(not(bootstrap), lang = "discriminant_kind")]
696+
pub trait DiscriminantKind {
697+
/// The type of the dicriminant, which must satisfy the trait
698+
/// bounds required by `mem::Discriminant`.
699+
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
700+
}
701+
702+
// Manually implement `DiscriminantKind` for all types during bootstrap
703+
// to reduce the required amount of conditional compilation.
704+
#[unstable(
705+
feature = "discriminant_kind",
706+
issue = "none",
707+
reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
708+
)]
709+
#[cfg(bootstrap)]
710+
impl<T: ?Sized> DiscriminantKind for T {
711+
type Discriminant = u64;
712+
}
713+
682714
/// Compiler-internal trait used to determine whether a type contains
683715
/// any `UnsafeCell` internally, but not through an indirection.
684716
/// This affects, for example, whether a `static` of that type is

src/libcore/mem/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::cmp;
1010
use crate::fmt;
1111
use crate::hash;
1212
use crate::intrinsics;
13-
use crate::marker::{Copy, PhantomData, Sized};
13+
use crate::marker::{Copy, DiscriminantKind, Sized};
1414
use crate::ptr;
1515

1616
mod manually_drop;
@@ -930,7 +930,7 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
930930
///
931931
/// [`discriminant`]: fn.discriminant.html
932932
#[stable(feature = "discriminant_value", since = "1.21.0")]
933-
pub struct Discriminant<T>(u64, PhantomData<fn() -> T>);
933+
pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
934934

935935
// N.B. These trait implementations cannot be derived because we don't want any bounds on T.
936936

@@ -995,5 +995,5 @@ impl<T> fmt::Debug for Discriminant<T> {
995995
#[stable(feature = "discriminant_value", since = "1.21.0")]
996996
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
997997
pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
998-
Discriminant(intrinsics::discriminant_value(v), PhantomData)
998+
Discriminant(intrinsics::discriminant_value(v))
999999
}

src/librustc_hir/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ language_item_table! {
163163
CopyTraitLangItem, "copy", copy_trait, Target::Trait;
164164
CloneTraitLangItem, "clone", clone_trait, Target::Trait;
165165
SyncTraitLangItem, "sync", sync_trait, Target::Trait;
166+
DiscriminantKindTraitLangItem,"discriminant_kind", discriminant_kind_trait, Target::Trait;
166167
FreezeTraitLangItem, "freeze", freeze_trait, Target::Trait;
167168

168169
DropTraitLangItem, "drop", drop_trait, Target::Trait;

src/librustc_typeck/check/intrinsic.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir as hir;
88
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
99
use rustc_middle::ty::subst::Subst;
1010
use rustc_middle::ty::{self, Ty, TyCtxt};
11-
use rustc_span::symbol::Symbol;
11+
use rustc_span::symbol::{Ident, Symbol};
1212
use rustc_target::spec::abi::Abi;
1313

1414
use std::iter;
@@ -283,14 +283,20 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
283283
"likely" => (0, vec![tcx.types.bool], tcx.types.bool),
284284
"unlikely" => (0, vec![tcx.types.bool], tcx.types.bool),
285285

286-
"discriminant_value" => (
287-
1,
288-
vec![tcx.mk_imm_ref(
289-
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))),
290-
param(0),
291-
)],
292-
tcx.types.u64,
293-
),
286+
"discriminant_value" => {
287+
let assoc_items =
288+
tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
289+
let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
290+
291+
(
292+
1,
293+
vec![tcx.mk_imm_ref(
294+
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(0))),
295+
param(0),
296+
)],
297+
tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())),
298+
)
299+
}
294300

295301
"try" => {
296302
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);

0 commit comments

Comments
 (0)