mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Permit deriving default on enums with #[default]
This commit is contained in:
parent
fd853c00e2
commit
c70147fd66
@ -2,11 +2,15 @@ use crate::deriving::generic::ty::*;
|
|||||||
use crate::deriving::generic::*;
|
use crate::deriving::generic::*;
|
||||||
|
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
use rustc_ast::EnumDef;
|
||||||
|
use rustc_ast::VariantData;
|
||||||
use rustc_ast::{Expr, MetaItem};
|
use rustc_ast::{Expr, MetaItem};
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::Applicability;
|
||||||
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
|
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
|
||||||
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
pub fn expand_deriving_default(
|
pub fn expand_deriving_default(
|
||||||
cx: &mut ExtCtxt<'_>,
|
cx: &mut ExtCtxt<'_>,
|
||||||
@ -34,8 +38,25 @@ pub fn expand_deriving_default(
|
|||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
is_unsafe: false,
|
is_unsafe: false,
|
||||||
unify_fieldless_variants: false,
|
unify_fieldless_variants: false,
|
||||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
combine_substructure: combine_substructure(Box::new(|cx, trait_span, substr| {
|
||||||
default_substructure(a, b, c)
|
match substr.fields {
|
||||||
|
StaticStruct(_, fields) => {
|
||||||
|
default_struct_substructure(cx, trait_span, substr, fields)
|
||||||
|
}
|
||||||
|
StaticEnum(enum_def, _) => {
|
||||||
|
if !cx.sess.features_untracked().derive_default_enum {
|
||||||
|
rustc_session::parse::feature_err(
|
||||||
|
cx.parse_sess(),
|
||||||
|
sym::derive_default_enum,
|
||||||
|
span,
|
||||||
|
"deriving `Default` on enums is experimental",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
default_enum_substructure(cx, trait_span, enum_def)
|
||||||
|
}
|
||||||
|
_ => cx.span_bug(trait_span, "method in `derive(Default)`"),
|
||||||
|
}
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
@ -43,44 +64,158 @@ pub fn expand_deriving_default(
|
|||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_substructure(
|
fn default_struct_substructure(
|
||||||
cx: &mut ExtCtxt<'_>,
|
cx: &mut ExtCtxt<'_>,
|
||||||
trait_span: Span,
|
trait_span: Span,
|
||||||
substr: &Substructure<'_>,
|
substr: &Substructure<'_>,
|
||||||
|
summary: &StaticFields,
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
// Note that `kw::Default` is "default" and `sym::Default` is "Default"!
|
// Note that `kw::Default` is "default" and `sym::Default` is "Default"!
|
||||||
let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]);
|
let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]);
|
||||||
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
|
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
|
||||||
|
|
||||||
match *substr.fields {
|
match summary {
|
||||||
StaticStruct(_, ref summary) => match *summary {
|
Unnamed(ref fields, is_tuple) => {
|
||||||
Unnamed(ref fields, is_tuple) => {
|
if !is_tuple {
|
||||||
if !is_tuple {
|
cx.expr_ident(trait_span, substr.type_ident)
|
||||||
cx.expr_ident(trait_span, substr.type_ident)
|
} else {
|
||||||
} else {
|
let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
|
||||||
let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
|
cx.expr_call_ident(trait_span, substr.type_ident, exprs)
|
||||||
cx.expr_call_ident(trait_span, substr.type_ident, exprs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Named(ref fields) => {
|
|
||||||
let default_fields = fields
|
|
||||||
.iter()
|
|
||||||
.map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
|
|
||||||
.collect();
|
|
||||||
cx.expr_struct_ident(trait_span, substr.type_ident, default_fields)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
StaticEnum(..) => {
|
|
||||||
struct_span_err!(
|
|
||||||
&cx.sess.parse_sess.span_diagnostic,
|
|
||||||
trait_span,
|
|
||||||
E0665,
|
|
||||||
"`Default` cannot be derived for enums, only structs"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
// let compilation continue
|
|
||||||
DummyResult::raw_expr(trait_span, true)
|
|
||||||
}
|
}
|
||||||
_ => cx.span_bug(trait_span, "method in `derive(Default)`"),
|
Named(ref fields) => {
|
||||||
|
let default_fields = fields
|
||||||
|
.iter()
|
||||||
|
.map(|&(ident, span)| cx.field_imm(span, ident, default_call(span)))
|
||||||
|
.collect();
|
||||||
|
cx.expr_struct_ident(trait_span, substr.type_ident, default_fields)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_enum_substructure(
|
||||||
|
cx: &mut ExtCtxt<'_>,
|
||||||
|
trait_span: Span,
|
||||||
|
enum_def: &EnumDef,
|
||||||
|
) -> P<Expr> {
|
||||||
|
let default_variant = match extract_default_variant(cx, enum_def, trait_span) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(()) => return DummyResult::raw_expr(trait_span, true),
|
||||||
|
};
|
||||||
|
|
||||||
|
// At this point, we know that there is exactly one variant with a `#[default]` attribute. The
|
||||||
|
// attribute hasn't yet been validated.
|
||||||
|
|
||||||
|
if let Err(()) = validate_default_attribute(cx, default_variant) {
|
||||||
|
return DummyResult::raw_expr(trait_span, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now know there is exactly one unit variant with exactly one `#[default]` attribute.
|
||||||
|
|
||||||
|
cx.expr_path(cx.path(
|
||||||
|
default_variant.span,
|
||||||
|
vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_default_variant<'a>(
|
||||||
|
cx: &mut ExtCtxt<'_>,
|
||||||
|
enum_def: &'a EnumDef,
|
||||||
|
trait_span: Span,
|
||||||
|
) -> Result<&'a rustc_ast::Variant, ()> {
|
||||||
|
let default_variants: SmallVec<[_; 1]> = enum_def
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.filter(|variant| cx.sess.contains_name(&variant.attrs, kw::Default))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let variant = match default_variants.as_slice() {
|
||||||
|
[variant] => variant,
|
||||||
|
[] => {
|
||||||
|
cx.struct_span_err(trait_span, "no default declared")
|
||||||
|
.help("make a unit variant default by placing `#[default]` above it")
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
[first, rest @ ..] => {
|
||||||
|
cx.struct_span_err(trait_span, "multiple declared defaults")
|
||||||
|
.span_label(first.span, "first default")
|
||||||
|
.span_labels(rest.iter().map(|variant| variant.span), "additional default")
|
||||||
|
.note("only one variant can be default")
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !matches!(variant.data, VariantData::Unit(..)) {
|
||||||
|
cx.struct_span_err(variant.ident.span, "`#[default]` may only be used on unit variants")
|
||||||
|
.help("consider a manual implementation of `Default`")
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(non_exhaustive_attr) = cx.sess.find_by_name(&variant.attrs, sym::non_exhaustive) {
|
||||||
|
cx.struct_span_err(variant.ident.span, "default variant must be exhaustive")
|
||||||
|
.span_label(non_exhaustive_attr.span, "declared `#[non_exhaustive]` here")
|
||||||
|
.help("consider a manual implementation of `Default`")
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(variant)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_default_attribute(
|
||||||
|
cx: &mut ExtCtxt<'_>,
|
||||||
|
default_variant: &rustc_ast::Variant,
|
||||||
|
) -> Result<(), ()> {
|
||||||
|
let attrs: SmallVec<[_; 1]> =
|
||||||
|
cx.sess.filter_by_name(&default_variant.attrs, kw::Default).collect();
|
||||||
|
|
||||||
|
let attr = match attrs.as_slice() {
|
||||||
|
[attr] => attr,
|
||||||
|
[] => cx.bug(
|
||||||
|
"this method must only be called with a variant that has a `#[default]` attribute",
|
||||||
|
),
|
||||||
|
[first, rest @ ..] => {
|
||||||
|
// FIXME(jhpratt) Do we want to perform this check? It doesn't exist
|
||||||
|
// for `#[inline]`, `#[non_exhaustive]`, and presumably others.
|
||||||
|
|
||||||
|
let suggestion_text =
|
||||||
|
if rest.len() == 1 { "try removing this" } else { "try removing these" };
|
||||||
|
|
||||||
|
cx.struct_span_err(default_variant.ident.span, "multiple `#[default]` attributes")
|
||||||
|
.note("only one `#[default]` attribute is needed")
|
||||||
|
.span_label(first.span, "`#[default]` used here")
|
||||||
|
.span_label(rest[0].span, "`#[default]` used again here")
|
||||||
|
.span_help(rest.iter().map(|attr| attr.span).collect::<Vec<_>>(), suggestion_text)
|
||||||
|
// This would otherwise display the empty replacement, hence the otherwise
|
||||||
|
// repetitive `.span_help` call above.
|
||||||
|
.tool_only_multipart_suggestion(
|
||||||
|
suggestion_text,
|
||||||
|
rest.iter().map(|attr| (attr.span, String::new())).collect(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if !attr.is_word() {
|
||||||
|
cx.struct_span_err(attr.span, "`#[default]` attribute does not accept a value")
|
||||||
|
.span_suggestion_hidden(
|
||||||
|
attr.span,
|
||||||
|
"try using `#[default]`",
|
||||||
|
"#[default]".into(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -683,6 +683,9 @@ declare_features! (
|
|||||||
/// Infer generic args for both consts and types.
|
/// Infer generic args for both consts and types.
|
||||||
(active, generic_arg_infer, "1.55.0", Some(85077), None),
|
(active, generic_arg_infer, "1.55.0", Some(85077), None),
|
||||||
|
|
||||||
|
/// Allows `#[derive(Default)]` and `#[default]` on enums.
|
||||||
|
(active, derive_default_enum, "1.56.0", Some(86985), None),
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: actual feature gates
|
// feature-group-end: actual feature gates
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -489,6 +489,7 @@ symbols! {
|
|||||||
deref_mut,
|
deref_mut,
|
||||||
deref_target,
|
deref_target,
|
||||||
derive,
|
derive,
|
||||||
|
derive_default_enum,
|
||||||
destructuring_assignment,
|
destructuring_assignment,
|
||||||
diagnostic,
|
diagnostic,
|
||||||
direct,
|
direct,
|
||||||
|
@ -161,7 +161,8 @@ pub fn default<T: Default>() -> T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Derive macro generating an impl of the trait `Default`.
|
/// Derive macro generating an impl of the trait `Default`.
|
||||||
#[rustc_builtin_macro]
|
#[cfg_attr(not(bootstrap), rustc_builtin_macro(Default, attributes(default)))]
|
||||||
|
#[cfg_attr(bootstrap, rustc_builtin_macro)]
|
||||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||||
#[allow_internal_unstable(core_intrinsics)]
|
#[allow_internal_unstable(core_intrinsics)]
|
||||||
pub macro Default($item:item) {
|
pub macro Default($item:item) {
|
||||||
|
19
src/test/ui/deriving/deriving-default-enum.rs
Normal file
19
src/test/ui/deriving/deriving-default-enum.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// run-pass
|
||||||
|
|
||||||
|
#![feature(derive_default_enum)]
|
||||||
|
|
||||||
|
// nb: does not impl Default
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct NotDefault;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, PartialEq)]
|
||||||
|
enum Foo {
|
||||||
|
#[default]
|
||||||
|
Alpha,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Beta(NotDefault),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(Foo::default(), Foo::Alpha);
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
#![feature(derive_default_enum)]
|
||||||
|
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ mod default {
|
|||||||
trait Sized {}
|
trait Sized {}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct S {
|
enum S {
|
||||||
#[default] // OK
|
#[default] // OK
|
||||||
field: u8,
|
Foo,
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#[derive(Default)] //~ ERROR E0665
|
|
||||||
enum Food {
|
|
||||||
Sweet,
|
|
||||||
Salty,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
error[E0665]: `Default` cannot be derived for enums, only structs
|
|
||||||
--> $DIR/E0665.rs:1:10
|
|
||||||
|
|
|
||||||
LL | #[derive(Default)]
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0665`.
|
|
@ -0,0 +1,7 @@
|
|||||||
|
#[derive(Default)] //~ ERROR deriving `Default` on enums is experimental
|
||||||
|
enum Foo {
|
||||||
|
#[default]
|
||||||
|
Alpha,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,13 @@
|
|||||||
|
error[E0658]: deriving `Default` on enums is experimental
|
||||||
|
--> $DIR/feature-gate-derive_default_enum.rs:1:10
|
||||||
|
|
|
||||||
|
LL | #[derive(Default)]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #86985 <https://github.com/rust-lang/rust/issues/86985> for more information
|
||||||
|
= help: add `#![feature(derive_default_enum)]` to the crate attributes to enable
|
||||||
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
@ -5,9 +5,62 @@
|
|||||||
|
|
||||||
#![feature(asm, llvm_asm)]
|
#![feature(asm, llvm_asm)]
|
||||||
#![feature(trace_macros, concat_idents)]
|
#![feature(trace_macros, concat_idents)]
|
||||||
|
#![feature(derive_default_enum)]
|
||||||
|
|
||||||
#[derive(Default)] //~ ERROR
|
#[derive(Default)] //~ ERROR no default declared
|
||||||
enum OrDeriveThis {}
|
enum NoDeclaredDefault {
|
||||||
|
Foo,
|
||||||
|
Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)] //~ ERROR multiple declared defaults
|
||||||
|
enum MultipleDefaults {
|
||||||
|
#[default]
|
||||||
|
Foo,
|
||||||
|
#[default]
|
||||||
|
Bar,
|
||||||
|
#[default]
|
||||||
|
Baz,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
enum ExtraDeriveTokens {
|
||||||
|
#[default = 1] //~ ERROR `#[default]` attribute does not accept a value
|
||||||
|
Foo,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
enum TwoDefaultAttrs {
|
||||||
|
#[default]
|
||||||
|
#[default]
|
||||||
|
Foo, //~ERROR multiple `#[default]` attributes
|
||||||
|
Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
enum ManyDefaultAttrs {
|
||||||
|
#[default]
|
||||||
|
#[default]
|
||||||
|
#[default]
|
||||||
|
#[default]
|
||||||
|
Foo, //~ERROR multiple `#[default]` attributes
|
||||||
|
Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
enum DefaultHasFields {
|
||||||
|
#[default]
|
||||||
|
Foo {}, //~ ERROR `#[default]` may only be used on unit variants
|
||||||
|
Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
enum NonExhaustiveDefault {
|
||||||
|
#[default]
|
||||||
|
#[non_exhaustive]
|
||||||
|
Foo, //~ ERROR default variant must be exhaustive
|
||||||
|
Bar,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
asm!(invalid); //~ ERROR
|
asm!(invalid); //~ ERROR
|
||||||
|
@ -1,49 +1,133 @@
|
|||||||
error[E0665]: `Default` cannot be derived for enums, only structs
|
error: no default declared
|
||||||
--> $DIR/macros-nonfatal-errors.rs:9:10
|
--> $DIR/macros-nonfatal-errors.rs:10:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Default)]
|
LL | #[derive(Default)]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
|
= help: make a unit variant default by placing `#[default]` above it
|
||||||
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: multiple declared defaults
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:16:10
|
||||||
|
|
|
||||||
|
LL | #[derive(Default)]
|
||||||
|
| ^^^^^^^
|
||||||
|
...
|
||||||
|
LL | Foo,
|
||||||
|
| --- first default
|
||||||
|
LL | #[default]
|
||||||
|
LL | Bar,
|
||||||
|
| --- additional default
|
||||||
|
LL | #[default]
|
||||||
|
LL | Baz,
|
||||||
|
| --- additional default
|
||||||
|
|
|
||||||
|
= note: only one variant can be default
|
||||||
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: `#[default]` attribute does not accept a value
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:28:5
|
||||||
|
|
|
||||||
|
LL | #[default = 1]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: try using `#[default]`
|
||||||
|
|
||||||
|
error: multiple `#[default]` attributes
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:36:5
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ---------- `#[default]` used here
|
||||||
|
LL | #[default]
|
||||||
|
| ---------- `#[default]` used again here
|
||||||
|
LL | Foo,
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: only one `#[default]` attribute is needed
|
||||||
|
help: try removing this
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:35:5
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: multiple `#[default]` attributes
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:46:5
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ---------- `#[default]` used here
|
||||||
|
LL | #[default]
|
||||||
|
| ---------- `#[default]` used again here
|
||||||
|
...
|
||||||
|
LL | Foo,
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: only one `#[default]` attribute is needed
|
||||||
|
help: try removing these
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:43:5
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `#[default]` may only be used on unit variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:53:5
|
||||||
|
|
|
||||||
|
LL | Foo {},
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= help: consider a manual implementation of `Default`
|
||||||
|
|
||||||
|
error: default variant must be exhaustive
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:61:5
|
||||||
|
|
|
||||||
|
LL | #[non_exhaustive]
|
||||||
|
| ----------------- declared `#[non_exhaustive]` here
|
||||||
|
LL | Foo,
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= help: consider a manual implementation of `Default`
|
||||||
|
|
||||||
error: asm template must be a string literal
|
error: asm template must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:13:10
|
--> $DIR/macros-nonfatal-errors.rs:66:10
|
||||||
|
|
|
|
||||||
LL | asm!(invalid);
|
LL | asm!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: inline assembly must be a string literal
|
error: inline assembly must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:14:15
|
--> $DIR/macros-nonfatal-errors.rs:67:15
|
||||||
|
|
|
|
||||||
LL | llvm_asm!(invalid);
|
LL | llvm_asm!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: concat_idents! requires ident args.
|
error: concat_idents! requires ident args.
|
||||||
--> $DIR/macros-nonfatal-errors.rs:16:5
|
--> $DIR/macros-nonfatal-errors.rs:69:5
|
||||||
|
|
|
|
||||||
LL | concat_idents!("not", "idents");
|
LL | concat_idents!("not", "idents");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: argument must be a string literal
|
error: argument must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:18:17
|
--> $DIR/macros-nonfatal-errors.rs:71:17
|
||||||
|
|
|
|
||||||
LL | option_env!(invalid);
|
LL | option_env!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: expected string literal
|
error: expected string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:19:10
|
--> $DIR/macros-nonfatal-errors.rs:72:10
|
||||||
|
|
|
|
||||||
LL | env!(invalid);
|
LL | env!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: expected string literal
|
error: expected string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:20:10
|
--> $DIR/macros-nonfatal-errors.rs:73:10
|
||||||
|
|
|
|
||||||
LL | env!(foo, abr, baz);
|
LL | env!(foo, abr, baz);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
|
error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
|
||||||
--> $DIR/macros-nonfatal-errors.rs:21:5
|
--> $DIR/macros-nonfatal-errors.rs:74:5
|
||||||
|
|
|
|
||||||
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
|
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -51,7 +135,7 @@ LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
|
|||||||
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: format argument must be a string literal
|
error: format argument must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:23:13
|
--> $DIR/macros-nonfatal-errors.rs:76:13
|
||||||
|
|
|
|
||||||
LL | format!(invalid);
|
LL | format!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
@ -62,19 +146,19 @@ LL | format!("{}", invalid);
|
|||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: argument must be a string literal
|
error: argument must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:25:14
|
--> $DIR/macros-nonfatal-errors.rs:78:14
|
||||||
|
|
|
|
||||||
LL | include!(invalid);
|
LL | include!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: argument must be a string literal
|
error: argument must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:27:18
|
--> $DIR/macros-nonfatal-errors.rs:80:18
|
||||||
|
|
|
|
||||||
LL | include_str!(invalid);
|
LL | include_str!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
|
error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
|
||||||
--> $DIR/macros-nonfatal-errors.rs:28:5
|
--> $DIR/macros-nonfatal-errors.rs:81:5
|
||||||
|
|
|
|
||||||
LL | include_str!("i'd be quite surprised if a file with this name existed");
|
LL | include_str!("i'd be quite surprised if a file with this name existed");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -82,13 +166,13 @@ LL | include_str!("i'd be quite surprised if a file with this name existed")
|
|||||||
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: argument must be a string literal
|
error: argument must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:29:20
|
--> $DIR/macros-nonfatal-errors.rs:82:20
|
||||||
|
|
|
|
||||||
LL | include_bytes!(invalid);
|
LL | include_bytes!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
|
error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
|
||||||
--> $DIR/macros-nonfatal-errors.rs:30:5
|
--> $DIR/macros-nonfatal-errors.rs:83:5
|
||||||
|
|
|
|
||||||
LL | include_bytes!("i'd be quite surprised if a file with this name existed");
|
LL | include_bytes!("i'd be quite surprised if a file with this name existed");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -96,11 +180,10 @@ LL | include_bytes!("i'd be quite surprised if a file with this name existed
|
|||||||
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: trace_macros! accepts only `true` or `false`
|
error: trace_macros! accepts only `true` or `false`
|
||||||
--> $DIR/macros-nonfatal-errors.rs:32:5
|
--> $DIR/macros-nonfatal-errors.rs:85:5
|
||||||
|
|
|
|
||||||
LL | trace_macros!(invalid);
|
LL | trace_macros!(invalid);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 15 previous errors
|
error: aborting due to 21 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0665`.
|
|
||||||
|
@ -29,7 +29,7 @@ impl Clone for Cat {
|
|||||||
impl Default for Cat {
|
impl Default for Cat {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
default();
|
default();
|
||||||
//~^ ERROR cannot find function `default`
|
//~^ ERROR cannot find function `default` in this scope [E0425]
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user