diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index 99e7bb4baef..cbd6a257b77 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -76,8 +76,8 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur } } StaticEnum(..) => { - cx.span_err(trait_span, - "`Default` cannot be derived for enums, only structs"); + span_err_if_not_stage0!(cx, trait_span, E0665, + "`Default` cannot be derived for enums, only structs"); // let compilation continue cx.expr_usize(trait_span, 0) } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 6bc4ee0b399..0dd55f8d777 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -19,6 +19,17 @@ use syntax::symbol::Symbol; use syntax_pos::Span; +macro_rules! span_err_if_not_stage0 { + ($cx:expr, $sp:expr, $code:ident, $text:tt) => { + #[cfg(not(stage0))] { + span_err!($cx, $sp, $code, $text) + } + #[cfg(stage0)] { + $cx.span_err($sp, $text) + } + } +} + macro path_local($x:ident) { generic::ty::Path::new_local(stringify!($x)) } diff --git a/src/libsyntax_ext/diagnostics.rs b/src/libsyntax_ext/diagnostics.rs index 33ae24c37e5..f99a6c3c216 100644 --- a/src/libsyntax_ext/diagnostics.rs +++ b/src/libsyntax_ext/diagnostics.rs @@ -82,7 +82,7 @@ Erroneous code example: -```compile_fail,E0663 +```compile_fail,E0664 asm!("mov $$0x200, %eax" : : @@ -94,4 +94,38 @@ take a look at the unstable book: https://doc.rust-lang.org/unstable-book/language-features/asm.html "##, + +E0665: r##" +The `Default` trait was derived on an enum. + +Erroneous code example: + +```compile_fail,E0665 +#[derive(Default)] +enum Food { + Sweet, + Salty, +} +``` + +The `Default` cannot be derived on an enum for the simple reason that the +compiler doesn't know which value to pick by default whereas it can for a +struct as long as all its fields implement the `Default` trait as well. + +If you still want to implement `Default` on your enum, you'll have to do it "by +hand": + +``` +enum Food { + Sweet, + Salty, +} + +impl Default for Food { + fn default() -> Food { + Food::Sweet + } +} +``` +"##, } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 15fcfac13ad..af3ef181c59 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -31,8 +31,12 @@ mod diagnostics; -mod assert; +#[macro_use] +// for custom_derive +pub mod deriving; + mod asm; +mod assert; mod cfg; mod compile_error; mod concat; @@ -46,8 +50,6 @@ pub mod proc_macro_registrar; -// for custom_derive -pub mod deriving; pub mod proc_macro_impl; diff --git a/src/test/ui/E0665.rs b/src/test/ui/E0665.rs new file mode 100644 index 00000000000..8888bedf016 --- /dev/null +++ b/src/test/ui/E0665.rs @@ -0,0 +1,20 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-stage1 + +#[derive(Default)] //~ ERROR E0665 +enum Food { + Sweet, + Salty, +} + +fn main() { +} diff --git a/src/test/ui/E0665.stderr b/src/test/ui/E0665.stderr new file mode 100644 index 00000000000..c97e9e5ea89 --- /dev/null +++ b/src/test/ui/E0665.stderr @@ -0,0 +1,9 @@ +error[E0665]: `Default` cannot be derived for enums, only structs + --> $DIR/E0665.rs:13:10 + | +LL | #[derive(Default)] //~ ERROR E0665 + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0665`.