Unify structures and enum variants in AST
This commit is contained in:
parent
ec4362da56
commit
ea47c2b6b3
@ -267,14 +267,13 @@ pub fn lower_variant(_lctx: &LoweringContext, v: &Variant) -> P<hir::Variant> {
|
||||
id: v.node.id,
|
||||
name: v.node.name.name,
|
||||
attrs: v.node.attrs.clone(),
|
||||
kind: match v.node.kind {
|
||||
TupleVariantKind(ref variant_args) => {
|
||||
hir::TupleVariantKind(variant_args.iter()
|
||||
.map(|ref x| lower_variant_arg(_lctx, x))
|
||||
.collect())
|
||||
}
|
||||
StructVariantKind(ref struct_def) => {
|
||||
hir::StructVariantKind(lower_struct_def(_lctx, struct_def))
|
||||
kind: {
|
||||
if v.node.def.ctor_id.is_none() {
|
||||
hir::StructVariantKind(lower_struct_def(_lctx, &v.node.def))
|
||||
} else {
|
||||
hir::TupleVariantKind(v.node.def.fields.iter().map(|ref field| {
|
||||
hir::VariantArg { id: field.node.id, ty: lower_ty(_lctx, &field.node.ty) }
|
||||
}).collect())
|
||||
}
|
||||
},
|
||||
disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(_lctx, e)),
|
||||
@ -567,13 +566,6 @@ fn lower_bounds(_lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParam
|
||||
bounds.iter().map(|bound| lower_ty_param_bound(_lctx, bound)).collect()
|
||||
}
|
||||
|
||||
fn lower_variant_arg(_lctx: &LoweringContext, va: &VariantArg) -> hir::VariantArg {
|
||||
hir::VariantArg {
|
||||
id: va.id,
|
||||
ty: lower_ty(_lctx, &va.ty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lower_block(_lctx: &LoweringContext, b: &Block) -> P<hir::Block> {
|
||||
P(hir::Block {
|
||||
id: b.id,
|
||||
|
@ -504,40 +504,20 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||
qualname.push_str("::");
|
||||
qualname.push_str(name);
|
||||
let val = self.span.snippet(variant.span);
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
// first ident in span is the variant's name
|
||||
self.fmt.tuple_variant_str(variant.span,
|
||||
self.span.span_for_first_ident(variant.span),
|
||||
variant.node.id,
|
||||
name,
|
||||
&qualname,
|
||||
&enum_data.qualname,
|
||||
&val,
|
||||
enum_data.id);
|
||||
for arg in args {
|
||||
self.visit_ty(&*arg.ty);
|
||||
}
|
||||
}
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
let ctor_id = match struct_def.ctor_id {
|
||||
Some(node_id) => node_id,
|
||||
None => ast::DUMMY_NODE_ID,
|
||||
};
|
||||
self.fmt.struct_variant_str(variant.span,
|
||||
self.span.span_for_first_ident(variant.span),
|
||||
variant.node.id,
|
||||
ctor_id,
|
||||
&qualname,
|
||||
&enum_data.qualname,
|
||||
&val,
|
||||
enum_data.id);
|
||||
|
||||
for field in &struct_def.fields {
|
||||
self.process_struct_field_def(field, variant.node.id);
|
||||
self.visit_ty(&*field.node.ty);
|
||||
}
|
||||
}
|
||||
let ctor_id = variant.node.def.ctor_id.unwrap_or(ast::DUMMY_NODE_ID);
|
||||
self.fmt.struct_variant_str(variant.span,
|
||||
self.span.span_for_first_ident(variant.span),
|
||||
variant.node.id,
|
||||
ctor_id,
|
||||
&qualname,
|
||||
&enum_data.qualname,
|
||||
&val,
|
||||
enum_data.id);
|
||||
|
||||
for field in &variant.node.def.fields {
|
||||
self.process_struct_field_def(field, variant.node.id);
|
||||
self.visit_ty(&*field.node.ty);
|
||||
}
|
||||
}
|
||||
self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id);
|
||||
|
@ -1594,7 +1594,7 @@ pub struct EnumDef {
|
||||
pub struct Variant_ {
|
||||
pub name: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub kind: VariantKind,
|
||||
pub def: P<StructDef>,
|
||||
pub id: NodeId,
|
||||
/// Explicit discriminant, eg `Foo = 1`
|
||||
pub disr_expr: Option<P<Expr>>,
|
||||
|
@ -140,19 +140,14 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
|
||||
if !(cx.in_cfg)(&v.node.attrs) {
|
||||
None
|
||||
} else {
|
||||
Some(v.map(|Spanned {node: ast::Variant_ {id, name, attrs, kind,
|
||||
Some(v.map(|Spanned {node: ast::Variant_ {id, name, attrs, def,
|
||||
disr_expr}, span}| {
|
||||
Spanned {
|
||||
node: ast::Variant_ {
|
||||
id: id,
|
||||
name: name,
|
||||
attrs: attrs,
|
||||
kind: match kind {
|
||||
ast::TupleVariantKind(..) => kind,
|
||||
ast::StructVariantKind(def) => {
|
||||
ast::StructVariantKind(fold_struct(cx, def))
|
||||
}
|
||||
},
|
||||
def: fold_struct(cx, def),
|
||||
disr_expr: disr_expr,
|
||||
},
|
||||
span: span
|
||||
|
@ -993,15 +993,20 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
}
|
||||
|
||||
fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
|
||||
let args = tys.into_iter().map(|ty| {
|
||||
ast::VariantArg { ty: ty, id: ast::DUMMY_NODE_ID }
|
||||
let fields = tys.into_iter().map(|ty| {
|
||||
Spanned { span: ty.span, node: ast::StructField_ {
|
||||
ty: ty,
|
||||
kind: ast::UnnamedField(ast::Inherited),
|
||||
attrs: Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
}}
|
||||
}).collect();
|
||||
|
||||
respan(span,
|
||||
ast::Variant_ {
|
||||
name: name,
|
||||
attrs: Vec::new(),
|
||||
kind: ast::TupleVariantKind(args),
|
||||
def: P(ast::StructDef { fields: fields, ctor_id: Some(ast::DUMMY_NODE_ID) }),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
disr_expr: None,
|
||||
})
|
||||
|
@ -700,16 +700,8 @@ impl<'a> TraitDef<'a> {
|
||||
let mut field_tys = Vec::new();
|
||||
|
||||
for variant in &enum_def.variants {
|
||||
match variant.node.kind {
|
||||
ast::VariantKind::TupleVariantKind(ref args) => {
|
||||
field_tys.extend(args.iter()
|
||||
.map(|arg| arg.ty.clone()));
|
||||
}
|
||||
ast::VariantKind::StructVariantKind(ref args) => {
|
||||
field_tys.extend(args.fields.iter()
|
||||
.map(|field| field.node.ty.clone()));
|
||||
}
|
||||
}
|
||||
field_tys.extend(variant.node.def.fields.iter()
|
||||
.map(|field| field.node.ty.clone()));
|
||||
}
|
||||
|
||||
let methods = self.methods.iter().map(|method_def| {
|
||||
@ -1413,14 +1405,7 @@ impl<'a> MethodDef<'a> {
|
||||
-> P<Expr> {
|
||||
let summary = enum_def.variants.iter().map(|v| {
|
||||
let ident = v.node.name;
|
||||
let summary = match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect())
|
||||
}
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
trait_.summarise_struct(cx, &**struct_def)
|
||||
}
|
||||
};
|
||||
let summary = trait_.summarise_struct(cx, &v.node.def);
|
||||
(ident, v.span, summary)
|
||||
}).collect();
|
||||
self.call_substructure_method(cx, trait_, type_ident,
|
||||
@ -1560,34 +1545,7 @@ impl<'a> TraitDef<'a> {
|
||||
-> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
|
||||
let variant_ident = variant.node.name;
|
||||
let variant_path = cx.path(variant.span, vec![enum_ident, variant_ident]);
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref variant_args) => {
|
||||
if variant_args.is_empty() {
|
||||
return (cx.pat_enum(variant.span, variant_path, vec![]), vec![]);
|
||||
}
|
||||
|
||||
let mut paths = Vec::new();
|
||||
let mut ident_expr: Vec<(_, _, _, &'a [ast::Attribute])> = Vec::new();
|
||||
for (i, va) in variant_args.iter().enumerate() {
|
||||
let sp = self.set_expn_info(cx, va.ty.span);
|
||||
let ident = cx.ident_of(&format!("{}_{}", prefix, i));
|
||||
let path1 = codemap::Spanned{span: sp, node: ident};
|
||||
paths.push(path1);
|
||||
let expr_path = cx.expr_path(cx.path_ident(sp, ident));
|
||||
let val = cx.expr(sp, ast::ExprParen(cx.expr_deref(sp, expr_path)));
|
||||
ident_expr.push((sp, None, val, &[]));
|
||||
}
|
||||
|
||||
let subpats = self.create_subpatterns(cx, paths, mutbl);
|
||||
|
||||
(cx.pat_enum(variant.span, variant_path, subpats),
|
||||
ident_expr)
|
||||
}
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
self.create_struct_pattern(cx, variant_path, &**struct_def,
|
||||
prefix, mutbl)
|
||||
}
|
||||
}
|
||||
self.create_struct_pattern(cx, variant_path, &variant.node.def, prefix, mutbl)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,45 +94,35 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure
|
||||
let mut arms = Vec::new();
|
||||
|
||||
for variant in &enum_def.variants {
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
if !args.is_empty() {
|
||||
cx.span_err(trait_span,
|
||||
"`FromPrimitive` cannot be derived for \
|
||||
enum variants with arguments");
|
||||
return cx.expr_fail(trait_span,
|
||||
InternedString::new(""));
|
||||
}
|
||||
let span = variant.span;
|
||||
|
||||
// expr for `$n == $variant as $name`
|
||||
let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
|
||||
let variant = cx.expr_path(path);
|
||||
let ty = cx.ty_ident(span, cx.ident_of(name));
|
||||
let cast = cx.expr_cast(span, variant.clone(), ty);
|
||||
let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
|
||||
|
||||
// expr for `Some($variant)`
|
||||
let body = cx.expr_some(span, variant);
|
||||
|
||||
// arm for `_ if $guard => $body`
|
||||
let arm = ast::Arm {
|
||||
attrs: vec!(),
|
||||
pats: vec!(cx.pat_wild(span)),
|
||||
guard: Some(guard),
|
||||
body: body,
|
||||
};
|
||||
|
||||
arms.push(arm);
|
||||
}
|
||||
ast::StructVariantKind(_) => {
|
||||
cx.span_err(trait_span,
|
||||
"`FromPrimitive` cannot be derived for enums \
|
||||
with struct variants");
|
||||
return cx.expr_fail(trait_span,
|
||||
InternedString::new(""));
|
||||
}
|
||||
let def = &variant.node.def;
|
||||
if def.ctor_id.is_none() || !def.fields.is_empty() {
|
||||
cx.span_err(trait_span, "`FromPrimitive` cannot be derived \
|
||||
for enums with non-unit variants");
|
||||
return cx.expr_fail(trait_span,
|
||||
InternedString::new(""));
|
||||
}
|
||||
|
||||
let span = variant.span;
|
||||
|
||||
// expr for `$n == $variant as $name`
|
||||
let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
|
||||
let variant = cx.expr_path(path);
|
||||
let ty = cx.ty_ident(span, cx.ident_of(name));
|
||||
let cast = cx.expr_cast(span, variant.clone(), ty);
|
||||
let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
|
||||
|
||||
// expr for `Some($variant)`
|
||||
let body = cx.expr_some(span, variant);
|
||||
|
||||
// arm for `_ if $guard => $body`
|
||||
let arm = ast::Arm {
|
||||
attrs: vec!(),
|
||||
pats: vec!(cx.pat_wild(span)),
|
||||
guard: Some(guard),
|
||||
body: body,
|
||||
};
|
||||
|
||||
arms.push(arm);
|
||||
}
|
||||
|
||||
// arm for `_ => None`
|
||||
|
@ -450,20 +450,12 @@ pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
|
||||
}
|
||||
|
||||
pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
|
||||
v.map(|Spanned {node: Variant_ {id, name, attrs, kind, disr_expr}, span}| Spanned {
|
||||
v.map(|Spanned {node: Variant_ {id, name, attrs, def, disr_expr}, span}| Spanned {
|
||||
node: Variant_ {
|
||||
id: fld.new_id(id),
|
||||
name: name,
|
||||
attrs: fold_attrs(attrs, fld),
|
||||
kind: match kind {
|
||||
TupleVariantKind(variant_args) => {
|
||||
TupleVariantKind(variant_args.move_map(|x|
|
||||
fld.fold_variant_arg(x)))
|
||||
}
|
||||
StructVariantKind(struct_def) => {
|
||||
StructVariantKind(fld.fold_struct_def(struct_def))
|
||||
}
|
||||
},
|
||||
def: fld.fold_struct_def(def),
|
||||
disr_expr: disr_expr.map(|e| fld.fold_expr(e)),
|
||||
},
|
||||
span: fld.new_span(span),
|
||||
|
@ -46,11 +46,11 @@ use ast::PatWildSingle;
|
||||
use ast::{PolyTraitRef, QSelf};
|
||||
use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
|
||||
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
|
||||
use ast::{StructVariantKind, BiSub, StrStyle};
|
||||
use ast::{BiSub, StrStyle};
|
||||
use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
|
||||
use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
|
||||
use ast::{TtDelimited, TtSequence, TtToken};
|
||||
use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
|
||||
use ast::{Ty, Ty_, TypeBinding};
|
||||
use ast::{TyMac};
|
||||
use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer};
|
||||
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
|
||||
@ -5131,22 +5131,13 @@ impl<'a> Parser<'a> {
|
||||
let variant_attrs = self.parse_outer_attributes();
|
||||
let vlo = self.span.lo;
|
||||
|
||||
let kind;
|
||||
let mut args = Vec::new();
|
||||
let struct_def;
|
||||
let mut disr_expr = None;
|
||||
let ident = try!(self.parse_ident());
|
||||
if try!(self.eat(&token::OpenDelim(token::Brace)) ){
|
||||
// Parse a struct variant.
|
||||
all_nullary = false;
|
||||
let start_span = self.span;
|
||||
let struct_def = try!(self.parse_struct_def());
|
||||
if struct_def.fields.is_empty() {
|
||||
self.span_err(start_span,
|
||||
&format!("unit-like struct variant should be written \
|
||||
without braces, as `{},`",
|
||||
ident));
|
||||
}
|
||||
kind = StructVariantKind(struct_def);
|
||||
struct_def = try!(self.parse_struct_def());
|
||||
} else if self.check(&token::OpenDelim(token::Paren)) {
|
||||
all_nullary = false;
|
||||
let arg_tys = try!(self.parse_enum_variant_seq(
|
||||
@ -5155,25 +5146,31 @@ impl<'a> Parser<'a> {
|
||||
seq_sep_trailing_allowed(token::Comma),
|
||||
|p| p.parse_ty_sum()
|
||||
));
|
||||
let mut fields = Vec::new();
|
||||
for ty in arg_tys {
|
||||
args.push(ast::VariantArg {
|
||||
fields.push(Spanned { span: ty.span, node: ast::StructField_ {
|
||||
ty: ty,
|
||||
kind: ast::UnnamedField(ast::Inherited),
|
||||
attrs: Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
});
|
||||
}});
|
||||
}
|
||||
kind = TupleVariantKind(args);
|
||||
struct_def = P(StructDef { fields: fields,
|
||||
ctor_id: Some(ast::DUMMY_NODE_ID) });
|
||||
} else if try!(self.eat(&token::Eq) ){
|
||||
disr_expr = Some(try!(self.parse_expr_nopanic()));
|
||||
any_disr = disr_expr.as_ref().map(|expr| expr.span);
|
||||
kind = TupleVariantKind(args);
|
||||
struct_def = P(StructDef { fields: Vec::new(),
|
||||
ctor_id: Some(ast::DUMMY_NODE_ID) });
|
||||
} else {
|
||||
kind = TupleVariantKind(Vec::new());
|
||||
struct_def = P(StructDef { fields: Vec::new(),
|
||||
ctor_id: Some(ast::DUMMY_NODE_ID) });
|
||||
}
|
||||
|
||||
let vr = ast::Variant_ {
|
||||
name: ident,
|
||||
attrs: variant_attrs,
|
||||
kind: kind,
|
||||
def: struct_def,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
disr_expr: disr_expr,
|
||||
};
|
||||
|
@ -1223,7 +1223,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
ast::ItemStruct(ref struct_def, ref generics) => {
|
||||
try!(self.head(&visibility_qualified(item.vis,"struct")));
|
||||
try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
|
||||
try!(self.print_struct(&struct_def, generics, item.ident, item.span, true));
|
||||
}
|
||||
|
||||
ast::ItemDefaultImpl(unsafety, ref trait_ref) => {
|
||||
@ -1388,7 +1388,8 @@ impl<'a> State<'a> {
|
||||
struct_def: &ast::StructDef,
|
||||
generics: &ast::Generics,
|
||||
ident: ast::Ident,
|
||||
span: codemap::Span) -> io::Result<()> {
|
||||
span: codemap::Span,
|
||||
print_finalizer: bool) -> io::Result<()> {
|
||||
try!(self.print_ident(ident));
|
||||
try!(self.print_generics(generics));
|
||||
if ast_util::struct_def_is_tuple_like(struct_def) {
|
||||
@ -1410,7 +1411,9 @@ impl<'a> State<'a> {
|
||||
try!(self.pclose());
|
||||
}
|
||||
try!(self.print_where_clause(&generics.where_clause));
|
||||
try!(word(&mut self.s, ";"));
|
||||
if print_finalizer {
|
||||
try!(word(&mut self.s, ";"));
|
||||
}
|
||||
try!(self.end());
|
||||
self.end() // close the outer-box
|
||||
} else {
|
||||
@ -1505,23 +1508,9 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
|
||||
match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
try!(self.print_ident(v.node.name));
|
||||
if !args.is_empty() {
|
||||
try!(self.popen());
|
||||
try!(self.commasep(Consistent,
|
||||
&args[..],
|
||||
|s, arg| s.print_type(&*arg.ty)));
|
||||
try!(self.pclose());
|
||||
}
|
||||
}
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
try!(self.head(""));
|
||||
let generics = ast_util::empty_generics();
|
||||
try!(self.print_struct(&**struct_def, &generics, v.node.name, v.span));
|
||||
}
|
||||
}
|
||||
try!(self.head(""));
|
||||
let generics = ast_util::empty_generics();
|
||||
try!(self.print_struct(&v.node.def, &generics, v.node.name, v.span, false));
|
||||
match v.node.disr_expr {
|
||||
Some(ref d) => {
|
||||
try!(space(&mut self.s));
|
||||
@ -3103,6 +3092,7 @@ mod tests {
|
||||
use ast_util;
|
||||
use codemap;
|
||||
use parse::token;
|
||||
use ptr::P;
|
||||
|
||||
#[test]
|
||||
fn test_fun_to_string() {
|
||||
@ -3129,7 +3119,7 @@ mod tests {
|
||||
name: ident,
|
||||
attrs: Vec::new(),
|
||||
// making this up as I go.... ?
|
||||
kind: ast::TupleVariantKind(Vec::new()),
|
||||
def: P(ast::StructDef { fields: Vec::new(), ctor_id: Some(ast::DUMMY_NODE_ID) }),
|
||||
id: 0,
|
||||
disr_expr: None,
|
||||
});
|
||||
|
@ -315,20 +315,7 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
variant: &'v Variant,
|
||||
generics: &'v Generics) {
|
||||
visitor.visit_ident(variant.span, variant.node.name);
|
||||
|
||||
match variant.node.kind {
|
||||
TupleVariantKind(ref variant_arguments) => {
|
||||
for variant_argument in variant_arguments {
|
||||
visitor.visit_ty(&variant_argument.ty)
|
||||
}
|
||||
}
|
||||
StructVariantKind(ref struct_definition) => {
|
||||
visitor.visit_struct_def(struct_definition,
|
||||
variant.node.name,
|
||||
generics,
|
||||
variant.node.id)
|
||||
}
|
||||
}
|
||||
visitor.visit_struct_def(&variant.node.def, variant.node.name, generics, variant.node.id);
|
||||
walk_list!(visitor, visit_expr, &variant.node.disr_expr);
|
||||
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ struct B(isize);
|
||||
|
||||
#[derive(FromPrimitive)]
|
||||
enum C { Foo(isize), Bar(usize) }
|
||||
//~^^ ERROR `FromPrimitive` cannot be derived for enum variants with arguments
|
||||
//~^^^ ERROR `FromPrimitive` cannot be derived for enum variants with arguments
|
||||
//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
|
||||
//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
|
||||
|
||||
#[derive(FromPrimitive)]
|
||||
enum D { Baz { x: isize } }
|
||||
//~^^ ERROR `FromPrimitive` cannot be derived for enums with struct variants
|
||||
//~^^^ ERROR `FromPrimitive` cannot be derived for enums with struct variants
|
||||
//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
|
||||
//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
|
||||
|
||||
pub fn main() {}
|
||||
|
@ -1,15 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// compile-flags: -Z parse-only
|
||||
|
||||
enum Foo {
|
||||
Bar {} //~ ERROR unit-like struct variant should be written without braces, as `Bar,`
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user