Prohibit #[default]
in invalid places
This commit is contained in:
parent
5ae2371ceb
commit
72465b0a32
3 changed files with 131 additions and 29 deletions
|
@ -2,6 +2,7 @@ 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::walk_list;
|
||||||
use rustc_ast::EnumDef;
|
use rustc_ast::EnumDef;
|
||||||
use rustc_ast::VariantData;
|
use rustc_ast::VariantData;
|
||||||
use rustc_ast::{Expr, MetaItem};
|
use rustc_ast::{Expr, MetaItem};
|
||||||
|
@ -19,6 +20,8 @@ pub fn expand_deriving_default(
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
|
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
|
||||||
|
|
||||||
let inline = cx.meta_word(span, sym::inline);
|
let inline = cx.meta_word(span, sym::inline);
|
||||||
let attrs = vec![cx.attribute(inline)];
|
let attrs = vec![cx.attribute(inline)];
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
|
@ -184,7 +187,10 @@ fn extract_default_variant<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
if !matches!(variant.data, VariantData::Unit(..)) {
|
if !matches!(variant.data, VariantData::Unit(..)) {
|
||||||
cx.struct_span_err(variant.ident.span, "`#[default]` may only be used on unit variants")
|
cx.struct_span_err(
|
||||||
|
variant.ident.span,
|
||||||
|
"the `#[default]` attribute may only be used on unit enum variants",
|
||||||
|
)
|
||||||
.help("consider a manual implementation of `Default`")
|
.help("consider a manual implementation of `Default`")
|
||||||
.emit();
|
.emit();
|
||||||
|
|
||||||
|
@ -253,3 +259,31 @@ fn validate_default_attribute(
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DetectNonVariantDefaultAttr<'a, 'b> {
|
||||||
|
cx: &'a ExtCtxt<'b>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, 'b> {
|
||||||
|
fn visit_attribute(&mut self, attr: &'a rustc_ast::Attribute) {
|
||||||
|
if attr.has_name(kw::Default) {
|
||||||
|
self.cx
|
||||||
|
.struct_span_err(
|
||||||
|
attr.span,
|
||||||
|
"the `#[default]` attribute may only be used on unit enum variants",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
rustc_ast::visit::walk_attribute(self, attr);
|
||||||
|
}
|
||||||
|
fn visit_variant(&mut self, v: &'a rustc_ast::Variant) {
|
||||||
|
self.visit_ident(v.ident);
|
||||||
|
self.visit_vis(&v.vis);
|
||||||
|
self.visit_variant_data(&v.data);
|
||||||
|
walk_list!(self, visit_anon_const, &v.disr_expr);
|
||||||
|
for attr in &v.attrs {
|
||||||
|
rustc_ast::visit::walk_attribute(self, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,8 +5,40 @@
|
||||||
|
|
||||||
#![feature(asm, llvm_asm)]
|
#![feature(asm, llvm_asm)]
|
||||||
#![feature(trace_macros, concat_idents)]
|
#![feature(trace_macros, concat_idents)]
|
||||||
|
#![feature(stmt_expr_attributes, arbitrary_enum_discriminant)]
|
||||||
#![feature(derive_default_enum)]
|
#![feature(derive_default_enum)]
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct DefaultInnerAttrStruct {
|
||||||
|
#[default] //~ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
foo: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct DefaultInnerAttrTupleStruct(#[default] ());
|
||||||
|
//~^ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
#[default] //~ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
struct DefaultOuterAttrStruct {}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
#[default] //~ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
enum DefaultOuterAttrEnum {
|
||||||
|
#[default]
|
||||||
|
Foo,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip] // needs some work to handle this case
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Default)]
|
||||||
|
enum AttrOnInnerExpression {
|
||||||
|
Foo = #[default] 0, //~ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
Bar([u8; #[default] 1]), //~ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
#[default]
|
||||||
|
Baz,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)] //~ ERROR no default declared
|
#[derive(Default)] //~ ERROR no default declared
|
||||||
enum NoDeclaredDefault {
|
enum NoDeclaredDefault {
|
||||||
Foo,
|
Foo,
|
||||||
|
@ -50,7 +82,7 @@ enum ManyDefaultAttrs {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
enum DefaultHasFields {
|
enum DefaultHasFields {
|
||||||
#[default]
|
#[default]
|
||||||
Foo {}, //~ ERROR `#[default]` may only be used on unit variants
|
Foo {}, //~ ERROR the `#[default]` attribute may only be used on unit enum variants
|
||||||
Bar,
|
Bar,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,41 @@
|
||||||
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:13:5
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:18:36
|
||||||
|
|
|
||||||
|
LL | struct DefaultInnerAttrTupleStruct(#[default] ());
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:22:1
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:26:1
|
||||||
|
|
|
||||||
|
LL | #[default]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:36:11
|
||||||
|
|
|
||||||
|
LL | Foo = #[default] 0,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
|
--> $DIR/macros-nonfatal-errors.rs:37:14
|
||||||
|
|
|
||||||
|
LL | Bar([u8; #[default] 1]),
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: no default declared
|
error: no default declared
|
||||||
--> $DIR/macros-nonfatal-errors.rs:10:10
|
--> $DIR/macros-nonfatal-errors.rs:42:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Default)]
|
LL | #[derive(Default)]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -8,7 +44,7 @@ LL | #[derive(Default)]
|
||||||
= 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
|
error: multiple declared defaults
|
||||||
--> $DIR/macros-nonfatal-errors.rs:16:10
|
--> $DIR/macros-nonfatal-errors.rs:48:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Default)]
|
LL | #[derive(Default)]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -26,7 +62,7 @@ LL | Baz,
|
||||||
= 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: `#[default]` attribute does not accept a value
|
error: `#[default]` attribute does not accept a value
|
||||||
--> $DIR/macros-nonfatal-errors.rs:28:5
|
--> $DIR/macros-nonfatal-errors.rs:60:5
|
||||||
|
|
|
|
||||||
LL | #[default = 1]
|
LL | #[default = 1]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
@ -34,7 +70,7 @@ LL | #[default = 1]
|
||||||
= help: try using `#[default]`
|
= help: try using `#[default]`
|
||||||
|
|
||||||
error: multiple `#[default]` attributes
|
error: multiple `#[default]` attributes
|
||||||
--> $DIR/macros-nonfatal-errors.rs:36:5
|
--> $DIR/macros-nonfatal-errors.rs:68:5
|
||||||
|
|
|
|
||||||
LL | #[default]
|
LL | #[default]
|
||||||
| ---------- `#[default]` used here
|
| ---------- `#[default]` used here
|
||||||
|
@ -45,13 +81,13 @@ LL | Foo,
|
||||||
|
|
|
|
||||||
= note: only one `#[default]` attribute is needed
|
= note: only one `#[default]` attribute is needed
|
||||||
help: try removing this
|
help: try removing this
|
||||||
--> $DIR/macros-nonfatal-errors.rs:35:5
|
--> $DIR/macros-nonfatal-errors.rs:67:5
|
||||||
|
|
|
|
||||||
LL | #[default]
|
LL | #[default]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: multiple `#[default]` attributes
|
error: multiple `#[default]` attributes
|
||||||
--> $DIR/macros-nonfatal-errors.rs:46:5
|
--> $DIR/macros-nonfatal-errors.rs:78:5
|
||||||
|
|
|
|
||||||
LL | #[default]
|
LL | #[default]
|
||||||
| ---------- `#[default]` used here
|
| ---------- `#[default]` used here
|
||||||
|
@ -63,7 +99,7 @@ LL | Foo,
|
||||||
|
|
|
|
||||||
= note: only one `#[default]` attribute is needed
|
= note: only one `#[default]` attribute is needed
|
||||||
help: try removing these
|
help: try removing these
|
||||||
--> $DIR/macros-nonfatal-errors.rs:43:5
|
--> $DIR/macros-nonfatal-errors.rs:75:5
|
||||||
|
|
|
|
||||||
LL | #[default]
|
LL | #[default]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -72,8 +108,8 @@ LL | #[default]
|
||||||
LL | #[default]
|
LL | #[default]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[default]` may only be used on unit variants
|
error: the `#[default]` attribute may only be used on unit enum variants
|
||||||
--> $DIR/macros-nonfatal-errors.rs:53:5
|
--> $DIR/macros-nonfatal-errors.rs:85:5
|
||||||
|
|
|
|
||||||
LL | Foo {},
|
LL | Foo {},
|
||||||
| ^^^
|
| ^^^
|
||||||
|
@ -81,7 +117,7 @@ LL | Foo {},
|
||||||
= help: consider a manual implementation of `Default`
|
= help: consider a manual implementation of `Default`
|
||||||
|
|
||||||
error: default variant must be exhaustive
|
error: default variant must be exhaustive
|
||||||
--> $DIR/macros-nonfatal-errors.rs:61:5
|
--> $DIR/macros-nonfatal-errors.rs:93:5
|
||||||
|
|
|
|
||||||
LL | #[non_exhaustive]
|
LL | #[non_exhaustive]
|
||||||
| ----------------- declared `#[non_exhaustive]` here
|
| ----------------- declared `#[non_exhaustive]` here
|
||||||
|
@ -91,43 +127,43 @@ LL | Foo,
|
||||||
= help: consider a manual implementation of `Default`
|
= 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:66:10
|
--> $DIR/macros-nonfatal-errors.rs:98: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:67:15
|
--> $DIR/macros-nonfatal-errors.rs:99: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:69:5
|
--> $DIR/macros-nonfatal-errors.rs:101: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:71:17
|
--> $DIR/macros-nonfatal-errors.rs:103:17
|
||||||
|
|
|
|
||||||
LL | option_env!(invalid);
|
LL | option_env!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: expected string literal
|
error: expected string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:72:10
|
--> $DIR/macros-nonfatal-errors.rs:104:10
|
||||||
|
|
|
|
||||||
LL | env!(invalid);
|
LL | env!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: expected string literal
|
error: expected string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:73:10
|
--> $DIR/macros-nonfatal-errors.rs:105: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:74:5
|
--> $DIR/macros-nonfatal-errors.rs:106:5
|
||||||
|
|
|
|
||||||
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
|
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -135,7 +171,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:76:13
|
--> $DIR/macros-nonfatal-errors.rs:108:13
|
||||||
|
|
|
|
||||||
LL | format!(invalid);
|
LL | format!(invalid);
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -146,19 +182,19 @@ LL | format!("{}", invalid);
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: argument must be a string literal
|
error: argument must be a string literal
|
||||||
--> $DIR/macros-nonfatal-errors.rs:78:14
|
--> $DIR/macros-nonfatal-errors.rs:110: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:80:18
|
--> $DIR/macros-nonfatal-errors.rs:112: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:81:5
|
--> $DIR/macros-nonfatal-errors.rs:113: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");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -166,13 +202,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:82:20
|
--> $DIR/macros-nonfatal-errors.rs:114: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:83:5
|
--> $DIR/macros-nonfatal-errors.rs:115: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");
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -180,10 +216,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:85:5
|
--> $DIR/macros-nonfatal-errors.rs:117:5
|
||||||
|
|
|
|
||||||
LL | trace_macros!(invalid);
|
LL | trace_macros!(invalid);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 21 previous errors
|
error: aborting due to 27 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue