update discriminant_value
usage in the compiler
This commit is contained in:
parent
25930e47ba
commit
3188ca7dd9
3 changed files with 16 additions and 71 deletions
|
@ -187,7 +187,6 @@ use rustc_ast::ptr::P;
|
|||
use rustc_attr as attr;
|
||||
use rustc_data_structures::map_in_place::MapInPlace;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::source_map::respan;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
@ -437,14 +436,7 @@ impl<'a> TraitDef<'a> {
|
|||
// This can only cause further compilation errors
|
||||
// downstream in blatantly illegal code, so it
|
||||
// is fine.
|
||||
self.expand_enum_def(
|
||||
cx,
|
||||
enum_def,
|
||||
&item.attrs,
|
||||
item.ident,
|
||||
generics,
|
||||
from_scratch,
|
||||
)
|
||||
self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch)
|
||||
}
|
||||
ast::ItemKind::Union(ref struct_def, ref generics) => {
|
||||
if self.supports_unions {
|
||||
|
@ -769,7 +761,6 @@ impl<'a> TraitDef<'a> {
|
|||
&self,
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
enum_def: &'a EnumDef,
|
||||
type_attrs: &[ast::Attribute],
|
||||
type_ident: Ident,
|
||||
generics: &Generics,
|
||||
from_scratch: bool,
|
||||
|
@ -801,7 +792,6 @@ impl<'a> TraitDef<'a> {
|
|||
cx,
|
||||
self,
|
||||
enum_def,
|
||||
type_attrs,
|
||||
type_ident,
|
||||
self_args,
|
||||
&nonself_args[..],
|
||||
|
@ -816,38 +806,6 @@ impl<'a> TraitDef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_repr_type_name(sess: &ParseSess, type_attrs: &[ast::Attribute]) -> &'static str {
|
||||
let mut repr_type_name = "isize";
|
||||
for a in type_attrs {
|
||||
for r in &attr::find_repr_attrs(sess, a) {
|
||||
repr_type_name = match *r {
|
||||
attr::ReprPacked(_)
|
||||
| attr::ReprSimd
|
||||
| attr::ReprAlign(_)
|
||||
| attr::ReprTransparent
|
||||
| attr::ReprNoNiche => continue,
|
||||
|
||||
attr::ReprC => "i32",
|
||||
|
||||
attr::ReprInt(attr::SignedInt(ast::IntTy::Isize)) => "isize",
|
||||
attr::ReprInt(attr::SignedInt(ast::IntTy::I8)) => "i8",
|
||||
attr::ReprInt(attr::SignedInt(ast::IntTy::I16)) => "i16",
|
||||
attr::ReprInt(attr::SignedInt(ast::IntTy::I32)) => "i32",
|
||||
attr::ReprInt(attr::SignedInt(ast::IntTy::I64)) => "i64",
|
||||
attr::ReprInt(attr::SignedInt(ast::IntTy::I128)) => "i128",
|
||||
|
||||
attr::ReprInt(attr::UnsignedInt(ast::UintTy::Usize)) => "usize",
|
||||
attr::ReprInt(attr::UnsignedInt(ast::UintTy::U8)) => "u8",
|
||||
attr::ReprInt(attr::UnsignedInt(ast::UintTy::U16)) => "u16",
|
||||
attr::ReprInt(attr::UnsignedInt(ast::UintTy::U32)) => "u32",
|
||||
attr::ReprInt(attr::UnsignedInt(ast::UintTy::U64)) => "u64",
|
||||
attr::ReprInt(attr::UnsignedInt(ast::UintTy::U128)) => "u128",
|
||||
}
|
||||
}
|
||||
}
|
||||
repr_type_name
|
||||
}
|
||||
|
||||
impl<'a> MethodDef<'a> {
|
||||
fn call_substructure_method(
|
||||
&self,
|
||||
|
@ -1148,20 +1106,11 @@ impl<'a> MethodDef<'a> {
|
|||
cx: &mut ExtCtxt<'_>,
|
||||
trait_: &TraitDef<'b>,
|
||||
enum_def: &'b EnumDef,
|
||||
type_attrs: &[ast::Attribute],
|
||||
type_ident: Ident,
|
||||
self_args: Vec<P<Expr>>,
|
||||
nonself_args: &[P<Expr>],
|
||||
) -> P<Expr> {
|
||||
self.build_enum_match_tuple(
|
||||
cx,
|
||||
trait_,
|
||||
enum_def,
|
||||
type_attrs,
|
||||
type_ident,
|
||||
self_args,
|
||||
nonself_args,
|
||||
)
|
||||
self.build_enum_match_tuple(cx, trait_, enum_def, type_ident, self_args, nonself_args)
|
||||
}
|
||||
|
||||
/// Creates a match for a tuple of all `self_args`, where either all
|
||||
|
@ -1181,11 +1130,11 @@ impl<'a> MethodDef<'a> {
|
|||
|
||||
/// ```{.text}
|
||||
/// let __self0_vi = unsafe {
|
||||
/// std::intrinsics::discriminant_value(&self) } as i32;
|
||||
/// std::intrinsics::discriminant_value(&self) };
|
||||
/// let __self1_vi = unsafe {
|
||||
/// std::intrinsics::discriminant_value(&arg1) } as i32;
|
||||
/// std::intrinsics::discriminant_value(&arg1) };
|
||||
/// let __self2_vi = unsafe {
|
||||
/// std::intrinsics::discriminant_value(&arg2) } as i32;
|
||||
/// std::intrinsics::discriminant_value(&arg2) };
|
||||
///
|
||||
/// if __self0_vi == __self1_vi && __self0_vi == __self2_vi && ... {
|
||||
/// match (...) {
|
||||
|
@ -1204,7 +1153,6 @@ impl<'a> MethodDef<'a> {
|
|||
cx: &mut ExtCtxt<'_>,
|
||||
trait_: &TraitDef<'b>,
|
||||
enum_def: &'b EnumDef,
|
||||
type_attrs: &[ast::Attribute],
|
||||
type_ident: Ident,
|
||||
mut self_args: Vec<P<Expr>>,
|
||||
nonself_args: &[P<Expr>],
|
||||
|
@ -1392,21 +1340,18 @@ impl<'a> MethodDef<'a> {
|
|||
//
|
||||
if variants.len() > 1 && self_args.len() > 1 {
|
||||
// Build a series of let statements mapping each self_arg
|
||||
// to its discriminant value. If this is a C-style enum
|
||||
// with a specific repr type, then casts the values to
|
||||
// that type. Otherwise casts to `i32` (the default repr
|
||||
// type).
|
||||
// to its discriminant value.
|
||||
//
|
||||
// i.e., for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
|
||||
// with three Self args, builds three statements:
|
||||
//
|
||||
// ```
|
||||
// let __self0_vi = unsafe {
|
||||
// std::intrinsics::discriminant_value(&self) } as i32;
|
||||
// std::intrinsics::discriminant_value(&self) };
|
||||
// let __self1_vi = unsafe {
|
||||
// std::intrinsics::discriminant_value(&arg1) } as i32;
|
||||
// std::intrinsics::discriminant_value(&arg1) };
|
||||
// let __self2_vi = unsafe {
|
||||
// std::intrinsics::discriminant_value(&arg2) } as i32;
|
||||
// std::intrinsics::discriminant_value(&arg2) };
|
||||
// ```
|
||||
let mut index_let_stmts: Vec<ast::Stmt> = Vec::with_capacity(vi_idents.len() + 1);
|
||||
|
||||
|
@ -1414,17 +1359,12 @@ impl<'a> MethodDef<'a> {
|
|||
// discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
|
||||
let mut discriminant_test = cx.expr_bool(sp, true);
|
||||
|
||||
let target_type_name = find_repr_type_name(&cx.parse_sess, type_attrs);
|
||||
|
||||
let mut first_ident = None;
|
||||
for (&ident, self_arg) in vi_idents.iter().zip(&self_args) {
|
||||
let self_addr = cx.expr_addr_of(sp, self_arg.clone());
|
||||
let variant_value =
|
||||
deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
|
||||
|
||||
let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name, sp));
|
||||
let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
|
||||
let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
|
||||
let let_stmt = cx.stmt_let(sp, false, ident, variant_value);
|
||||
index_let_stmts.push(let_stmt);
|
||||
|
||||
match first_ident {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#![feature(const_panic)]
|
||||
#![feature(const_transmute)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(discriminant_kind)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(never_type)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
|
|
@ -15,8 +15,10 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
|
||||
use rustc_span::Span;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::hash::Hash;
|
||||
use std::intrinsics;
|
||||
use std::marker::DiscriminantKind;
|
||||
|
||||
/// The shorthand encoding uses an enum's variant index `usize`
|
||||
/// and is offset by this value so it never matches a real variant.
|
||||
|
@ -60,6 +62,7 @@ where
|
|||
E: TyEncoder,
|
||||
M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<T, usize>,
|
||||
T: EncodableWithShorthand,
|
||||
<T::Variant as DiscriminantKind>::Discriminant: Ord + TryFrom<usize>,
|
||||
{
|
||||
let existing_shorthand = cache(encoder).get(value).cloned();
|
||||
if let Some(shorthand) = existing_shorthand {
|
||||
|
@ -75,7 +78,8 @@ where
|
|||
// The shorthand encoding uses the same usize as the
|
||||
// discriminant, with an offset so they can't conflict.
|
||||
let discriminant = intrinsics::discriminant_value(variant);
|
||||
assert!(discriminant < SHORTHAND_OFFSET as u64);
|
||||
assert!(discriminant < SHORTHAND_OFFSET.try_into().ok().unwrap());
|
||||
|
||||
let shorthand = start + SHORTHAND_OFFSET;
|
||||
|
||||
// Get the number of bits that leb128 could fit
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue