rustc_const_eval: support all unit enum variants.
This commit is contained in:
parent
0ff828baa0
commit
8054377f8f
13 changed files with 180 additions and 67 deletions
|
@ -273,6 +273,12 @@ for ::middle::const_val::ConstVal<'tcx> {
|
||||||
ConstVal::Bool(value) => {
|
ConstVal::Bool(value) => {
|
||||||
value.hash_stable(hcx, hasher);
|
value.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
|
ConstVal::Char(value) => {
|
||||||
|
value.hash_stable(hcx, hasher);
|
||||||
|
}
|
||||||
|
ConstVal::Variant(def_id) => {
|
||||||
|
def_id.hash_stable(hcx, hasher);
|
||||||
|
}
|
||||||
ConstVal::Function(def_id, substs) => {
|
ConstVal::Function(def_id, substs) => {
|
||||||
def_id.hash_stable(hcx, hasher);
|
def_id.hash_stable(hcx, hasher);
|
||||||
substs.hash_stable(hcx, hasher);
|
substs.hash_stable(hcx, hasher);
|
||||||
|
@ -296,9 +302,6 @@ for ::middle::const_val::ConstVal<'tcx> {
|
||||||
value.hash_stable(hcx, hasher);
|
value.hash_stable(hcx, hasher);
|
||||||
times.hash_stable(hcx, hasher);
|
times.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
ConstVal::Char(value) => {
|
|
||||||
value.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,13 @@ pub enum ConstVal<'tcx> {
|
||||||
Str(InternedString),
|
Str(InternedString),
|
||||||
ByteStr(Rc<Vec<u8>>),
|
ByteStr(Rc<Vec<u8>>),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
|
Char(char),
|
||||||
|
Variant(DefId),
|
||||||
Function(DefId, &'tcx Substs<'tcx>),
|
Function(DefId, &'tcx Substs<'tcx>),
|
||||||
Struct(BTreeMap<ast::Name, ConstVal<'tcx>>),
|
Struct(BTreeMap<ast::Name, ConstVal<'tcx>>),
|
||||||
Tuple(Vec<ConstVal<'tcx>>),
|
Tuple(Vec<ConstVal<'tcx>>),
|
||||||
Array(Vec<ConstVal<'tcx>>),
|
Array(Vec<ConstVal<'tcx>>),
|
||||||
Repeat(Box<ConstVal<'tcx>>, u64),
|
Repeat(Box<ConstVal<'tcx>>, u64),
|
||||||
Char(char),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ConstVal<'tcx> {
|
impl<'tcx> ConstVal<'tcx> {
|
||||||
|
@ -54,12 +55,13 @@ impl<'tcx> ConstVal<'tcx> {
|
||||||
Str(_) => "string literal",
|
Str(_) => "string literal",
|
||||||
ByteStr(_) => "byte string literal",
|
ByteStr(_) => "byte string literal",
|
||||||
Bool(_) => "boolean",
|
Bool(_) => "boolean",
|
||||||
|
Char(..) => "char",
|
||||||
|
Variant(_) => "enum variant",
|
||||||
Struct(_) => "struct",
|
Struct(_) => "struct",
|
||||||
Tuple(_) => "tuple",
|
Tuple(_) => "tuple",
|
||||||
Function(..) => "function definition",
|
Function(..) => "function definition",
|
||||||
Array(..) => "array",
|
Array(..) => "array",
|
||||||
Repeat(..) => "repeat",
|
Repeat(..) => "repeat",
|
||||||
Char(..) => "char",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1307,10 +1307,11 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
|
||||||
write!(fmt, "b\"{}\"", escaped)
|
write!(fmt, "b\"{}\"", escaped)
|
||||||
}
|
}
|
||||||
Bool(b) => write!(fmt, "{:?}", b),
|
Bool(b) => write!(fmt, "{:?}", b),
|
||||||
|
Char(c) => write!(fmt, "{:?}", c),
|
||||||
|
Variant(def_id) |
|
||||||
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
|
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
|
||||||
Struct(_) | Tuple(_) | Array(_) | Repeat(..) =>
|
Struct(_) | Tuple(_) | Array(_) | Repeat(..) =>
|
||||||
bug!("ConstVal `{:?}` should not be in MIR", const_val),
|
bug!("ConstVal `{:?}` should not be in MIR", const_val),
|
||||||
Char(c) => write!(fmt, "{:?}", c),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1693,6 +1693,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||||
-> impl Iterator<Item=ConstInt> + 'a {
|
-> impl Iterator<Item=ConstInt> + 'a {
|
||||||
let repr_type = self.repr.discr_type();
|
let repr_type = self.repr.discr_type();
|
||||||
|
@ -1706,7 +1707,13 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
Ok(ConstVal::Integral(v)) => {
|
Ok(ConstVal::Integral(v)) => {
|
||||||
discr = v;
|
discr = v;
|
||||||
}
|
}
|
||||||
_ => {}
|
err => {
|
||||||
|
if !expr_did.is_local() {
|
||||||
|
span_bug!(tcx.def_span(expr_did),
|
||||||
|
"variant discriminant evaluation succeeded \
|
||||||
|
in its crate but failed locally: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev_discr = Some(discr);
|
prev_discr = Some(discr);
|
||||||
|
@ -1740,7 +1747,15 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
explicit_value = v;
|
explicit_value = v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_ => {
|
err => {
|
||||||
|
if !expr_did.is_local() {
|
||||||
|
span_bug!(tcx.def_span(expr_did),
|
||||||
|
"variant discriminant evaluation succeeded \
|
||||||
|
in its crate but failed locally: {:?}", err);
|
||||||
|
}
|
||||||
|
if explicit_index == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
explicit_index -= 1;
|
explicit_index -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc::middle::const_val::{ConstVal, ConstEvalErr, EvalResult, ErrKind};
|
||||||
use rustc::hir::map as hir_map;
|
use rustc::hir::map as hir_map;
|
||||||
use rustc::hir::map::blocks::FnLikeNode;
|
use rustc::hir::map::blocks::FnLikeNode;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::hir::def::Def;
|
use rustc::hir::def::{Def, CtorKind};
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::maps::Providers;
|
use rustc::ty::maps::Providers;
|
||||||
|
@ -48,28 +48,6 @@ macro_rules! math {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
variant_def: DefId)
|
|
||||||
-> Option<(&'tcx Expr, &'a ty::TypeckTables<'tcx>)> {
|
|
||||||
if let Some(variant_node_id) = tcx.hir.as_local_node_id(variant_def) {
|
|
||||||
let enum_node_id = tcx.hir.get_parent(variant_node_id);
|
|
||||||
if let Some(hir_map::NodeItem(it)) = tcx.hir.find(enum_node_id) {
|
|
||||||
if let hir::ItemEnum(ref edef, _) = it.node {
|
|
||||||
for variant in &edef.variants {
|
|
||||||
if variant.node.data.id() == variant_node_id {
|
|
||||||
return variant.node.disr_expr.map(|e| {
|
|
||||||
let def_id = tcx.hir.body_owner_def_id(e);
|
|
||||||
(&tcx.hir.body(e).value,
|
|
||||||
tcx.item_tables(def_id))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// * `def_id` is the id of the constant.
|
/// * `def_id` is the id of the constant.
|
||||||
/// * `substs` is the monomorphized substitutions for the expression.
|
/// * `substs` is the monomorphized substitutions for the expression.
|
||||||
///
|
///
|
||||||
|
@ -289,9 +267,22 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprCast(ref base, _) => {
|
hir::ExprCast(ref base, _) => {
|
||||||
match cast_const(tcx, cx.eval(base)?, ety) {
|
let base_val = cx.eval(base)?;
|
||||||
|
let base_ty = cx.tables.expr_ty(base);
|
||||||
|
|
||||||
|
// Avoid applying substitutions if they're empty, that'd ICE.
|
||||||
|
let base_ty = if cx.substs.is_empty() {
|
||||||
|
base_ty
|
||||||
|
} else {
|
||||||
|
base_ty.subst(tcx, cx.substs)
|
||||||
|
};
|
||||||
|
if ety == base_ty {
|
||||||
|
base_val
|
||||||
|
} else {
|
||||||
|
match cast_const(tcx, base_val, ety) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
|
Err(kind) => signal!(e, kind),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprPath(ref qpath) => {
|
hir::ExprPath(ref qpath) => {
|
||||||
|
@ -317,27 +308,20 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
|
||||||
debug!("bad reference: {:?}, {:?}", err.description(), err.span);
|
debug!("bad reference: {:?}, {:?}", err.description(), err.span);
|
||||||
signal!(e, ErroneousReferencedConstant(box err))
|
signal!(e, ErroneousReferencedConstant(box err))
|
||||||
},
|
},
|
||||||
},
|
|
||||||
Def::VariantCtor(variant_def, ..) => {
|
|
||||||
if let Some((expr, tables)) = lookup_variant_by_id(tcx, variant_def) {
|
|
||||||
let cx = ConstContext::with_tables(tcx, tables);
|
|
||||||
match cx.eval(expr) {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(ConstEvalErr { kind: TypeckError, .. }) => {
|
|
||||||
signal!(e, TypeckError);
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
debug!("bad reference: {:?}, {:?}", err.description(), err.span);
|
|
||||||
signal!(e, ErroneousReferencedConstant(box err))
|
|
||||||
},
|
},
|
||||||
|
Def::VariantCtor(variant_def, CtorKind::Const) => {
|
||||||
|
Variant(variant_def)
|
||||||
}
|
}
|
||||||
} else {
|
Def::VariantCtor(_, CtorKind::Fn) => {
|
||||||
signal!(e, UnimplementedConstVal("enum variants"));
|
signal!(e, UnimplementedConstVal("enum variants"));
|
||||||
}
|
}
|
||||||
}
|
Def::StructCtor(_, CtorKind::Const) => {
|
||||||
Def::StructCtor(..) => {
|
|
||||||
ConstVal::Struct(Default::default())
|
ConstVal::Struct(Default::default())
|
||||||
}
|
}
|
||||||
|
Def::StructCtor(_, CtorKind::Fn) => {
|
||||||
|
signal!(e, UnimplementedConstVal("tuple struct constructors"))
|
||||||
|
}
|
||||||
Def::Local(def_id) => {
|
Def::Local(def_id) => {
|
||||||
debug!("Def::Local({:?}): {:?}", def_id, cx.fn_args);
|
debug!("Def::Local({:?}): {:?}", def_id, cx.fn_args);
|
||||||
if let Some(val) = cx.fn_args.as_ref().and_then(|args| args.get(&def_id)) {
|
if let Some(val) = cx.fn_args.as_ref().and_then(|args| args.get(&def_id)) {
|
||||||
|
@ -578,7 +562,7 @@ fn cast_const_int<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
U8(u) => Ok(Char(u as char)),
|
U8(u) => Ok(Char(u as char)),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
},
|
},
|
||||||
_ => bug!(),
|
_ => Err(CannotCast),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,6 +606,11 @@ fn cast_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
Bool(b) => cast_const_int(tcx, U8(b as u8), ty),
|
Bool(b) => cast_const_int(tcx, U8(b as u8), ty),
|
||||||
Float(f) => cast_const_float(tcx, f, ty),
|
Float(f) => cast_const_float(tcx, f, ty),
|
||||||
Char(c) => cast_const_int(tcx, U32(c as u32), ty),
|
Char(c) => cast_const_int(tcx, U32(c as u32), ty),
|
||||||
|
Variant(v) => {
|
||||||
|
let adt = tcx.lookup_adt_def(tcx.parent_def_id(v).unwrap());
|
||||||
|
let idx = adt.variant_index_with_id(v);
|
||||||
|
cast_const_int(tcx, adt.discriminant_for_variant(tcx, idx), ty)
|
||||||
|
}
|
||||||
Function(..) => Err(UnimplementedConstVal("casting fn pointers")),
|
Function(..) => Err(UnimplementedConstVal("casting fn pointers")),
|
||||||
ByteStr(b) => match ty.sty {
|
ByteStr(b) => match ty.sty {
|
||||||
ty::TyRawPtr(_) => {
|
ty::TyRawPtr(_) => {
|
||||||
|
|
|
@ -116,6 +116,7 @@ fn print_const_val(value: &ConstVal, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
ConstVal::ByteStr(ref b) => write!(f, "{:?}", &b[..]),
|
ConstVal::ByteStr(ref b) => write!(f, "{:?}", &b[..]),
|
||||||
ConstVal::Bool(b) => write!(f, "{:?}", b),
|
ConstVal::Bool(b) => write!(f, "{:?}", b),
|
||||||
ConstVal::Char(c) => write!(f, "{:?}", c),
|
ConstVal::Char(c) => write!(f, "{:?}", c),
|
||||||
|
ConstVal::Variant(_) |
|
||||||
ConstVal::Struct(_) |
|
ConstVal::Struct(_) |
|
||||||
ConstVal::Tuple(_) |
|
ConstVal::Tuple(_) |
|
||||||
ConstVal::Function(..) |
|
ConstVal::Function(..) |
|
||||||
|
@ -620,8 +621,13 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> {
|
||||||
let const_cx = eval::ConstContext::with_tables(self.tcx.global_tcx(), self.tables);
|
let const_cx = eval::ConstContext::with_tables(self.tcx.global_tcx(), self.tables);
|
||||||
match const_cx.eval(expr) {
|
match const_cx.eval(expr) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
|
if let ConstVal::Variant(def_id) = value {
|
||||||
|
let ty = self.tables.expr_ty(expr);
|
||||||
|
self.lower_variant_or_leaf(Def::Variant(def_id), ty, vec![])
|
||||||
|
} else {
|
||||||
PatternKind::Constant { value: value }
|
PatternKind::Constant { value: value }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.errors.push(PatternError::ConstEval(e));
|
self.errors.push(PatternError::ConstEval(e));
|
||||||
PatternKind::Wild
|
PatternKind::Wild
|
||||||
|
|
|
@ -100,15 +100,13 @@ impl<'tcx> Const<'tcx> {
|
||||||
ConstVal::Integral(ref i) => return Const::from_constint(ccx, i),
|
ConstVal::Integral(ref i) => return Const::from_constint(ccx, i),
|
||||||
ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
|
ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
|
||||||
ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
|
ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
|
||||||
|
ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false),
|
||||||
|
ConstVal::Function(..) => C_null(type_of::type_of(ccx, ty)),
|
||||||
|
ConstVal::Variant(_) |
|
||||||
ConstVal::Struct(_) | ConstVal::Tuple(_) |
|
ConstVal::Struct(_) | ConstVal::Tuple(_) |
|
||||||
ConstVal::Array(..) | ConstVal::Repeat(..) => {
|
ConstVal::Array(..) | ConstVal::Repeat(..) => {
|
||||||
bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv)
|
bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv)
|
||||||
}
|
}
|
||||||
ConstVal::Function(..) => {
|
|
||||||
let llty = type_of::type_of(ccx, ty);
|
|
||||||
return Const::new(C_null(llty), ty);
|
|
||||||
}
|
|
||||||
ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!ty.has_erasable_regions());
|
assert!(!ty.has_erasable_regions());
|
||||||
|
|
|
@ -10,21 +10,22 @@
|
||||||
|
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
enum Cake {
|
enum Cake {
|
||||||
BlackForest,
|
BlackForest,
|
||||||
Marmor,
|
Marmor,
|
||||||
}
|
}
|
||||||
use Cake::*;
|
use Cake::*;
|
||||||
|
|
||||||
const BOO: (Cake, Cake) = (Marmor, BlackForest);
|
struct Pair<A, B>(A, B);
|
||||||
|
|
||||||
|
const BOO: Pair<Cake, Cake> = Pair(Marmor, BlackForest);
|
||||||
//~^ ERROR: constant evaluation error [E0080]
|
//~^ ERROR: constant evaluation error [E0080]
|
||||||
//~| unimplemented constant expression: enum variants
|
//~| unimplemented constant expression: tuple struct constructors
|
||||||
const FOO: Cake = BOO.1;
|
const FOO: Cake = BOO.1;
|
||||||
|
|
||||||
const fn foo() -> Cake {
|
const fn foo() -> Cake {
|
||||||
Marmor
|
Marmor
|
||||||
//~^ ERROR: constant evaluation error [E0080]
|
|
||||||
//~| unimplemented constant expression: enum variants
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const WORKS: Cake = Marmor;
|
const WORKS: Cake = Marmor;
|
||||||
|
@ -34,7 +35,7 @@ const GOO: Cake = foo();
|
||||||
fn main() {
|
fn main() {
|
||||||
match BlackForest {
|
match BlackForest {
|
||||||
FOO => println!("hi"), //~ NOTE: for pattern here
|
FOO => println!("hi"), //~ NOTE: for pattern here
|
||||||
GOO => println!("meh"), //~ NOTE: for pattern here
|
GOO => println!("meh"),
|
||||||
WORKS => println!("möp"),
|
WORKS => println!("möp"),
|
||||||
_ => println!("bye"),
|
_ => println!("bye"),
|
||||||
}
|
}
|
||||||
|
|
20
src/test/compile-fail/issue-41394.rs
Normal file
20
src/test/compile-fail/issue-41394.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
enum Foo {
|
||||||
|
A = "" + 1
|
||||||
|
//~^ ERROR binary operation `+` cannot be applied to type `&'static str`
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Bar {
|
||||||
|
A = Foo::A as isize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
26
src/test/run-pass/auxiliary/issue-41394.rs
Normal file
26
src/test/run-pass/auxiliary/issue-41394.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum Foo {
|
||||||
|
Foo = Private::Variant as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
enum Private {
|
||||||
|
Variant = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn foo() -> Foo {
|
||||||
|
Foo::Foo
|
||||||
|
}
|
38
src/test/run-pass/const-pattern-variant.rs
Normal file
38
src/test/run-pass/const-pattern-variant.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(const_fn)]
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
enum Cake {
|
||||||
|
BlackForest,
|
||||||
|
Marmor,
|
||||||
|
}
|
||||||
|
use Cake::*;
|
||||||
|
|
||||||
|
const BOO: (Cake, Cake) = (Marmor, BlackForest);
|
||||||
|
const FOO: Cake = BOO.1;
|
||||||
|
|
||||||
|
const fn foo() -> Cake {
|
||||||
|
Marmor
|
||||||
|
}
|
||||||
|
|
||||||
|
const WORKS: Cake = Marmor;
|
||||||
|
|
||||||
|
const GOO: Cake = foo();
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match BlackForest {
|
||||||
|
FOO => println!("hi"),
|
||||||
|
GOO => println!("meh"),
|
||||||
|
WORKS => println!("möp"),
|
||||||
|
_ => println!("bye"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,13 +8,10 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// Note: This test is checking that we forbid a coding pattern that
|
// Note: This test was used to demonstrate #5873 (now #23898).
|
||||||
// Issue #5873 explicitly wants to allow.
|
|
||||||
|
|
||||||
enum State { ST_NULL, ST_WHITESPACE }
|
enum State { ST_NULL, ST_WHITESPACE }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
[State::ST_NULL; (State::ST_WHITESPACE as usize)];
|
[State::ST_NULL; (State::ST_WHITESPACE as usize)];
|
||||||
//~^ ERROR constant evaluation error
|
|
||||||
//~| unimplemented constant expression: enum variants
|
|
||||||
}
|
}
|
17
src/test/run-pass/issue-41394.rs
Normal file
17
src/test/run-pass/issue-41394.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:issue-41394.rs
|
||||||
|
|
||||||
|
extern crate issue_41394 as lib;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(lib::foo() as u32, 42);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue