Skip to content

Commit 830d1a0

Browse files
authored
Rollup merge of #77419 - GuillaumeGomez:create-e0777, r=jyn514
Create E0777 error code for invalid argument in derive The second commit is to fix a nit reported by @jyn514 [here](https://github.com/rust-lang/rust/pull/76406/files#r485186592).
2 parents f09c962 + d1d94ba commit 830d1a0

File tree

6 files changed

+68
-6
lines changed

6 files changed

+68
-6
lines changed

compiler/rustc_error_codes/src/error_codes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ E0773: include_str!("./error_codes/E0773.md"),
459459
E0774: include_str!("./error_codes/E0774.md"),
460460
E0775: include_str!("./error_codes/E0775.md"),
461461
E0776: include_str!("./error_codes/E0776.md"),
462+
E0777: include_str!("./error_codes/E0777.md"),
462463
;
463464
// E0006, // merged with E0005
464465
// E0008, // cannot bind by-move into a pattern guard
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
A literal value was used inside `#[derive]`.
2+
3+
Erroneous code example:
4+
5+
```compile_fail,E0777
6+
#[derive("Clone")] // error!
7+
struct Foo;
8+
```
9+
10+
Only paths to traits are allowed as argument inside `#[derive]`. You can find
11+
more information about the `#[derive]` attribute in the [Rust Book].
12+
13+
14+
```
15+
#[derive(Clone)] // ok!
16+
struct Foo;
17+
```
18+
19+
[Rust Book]: https://doc.rust-lang.org/book/appendix-03-derivable-traits.html

compiler/rustc_expand/src/expand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_ast_pretty::pprust;
1818
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
1919
use rustc_data_structures::map_in_place::MapInPlace;
2020
use rustc_data_structures::stack::ensure_sufficient_stack;
21-
use rustc_errors::{Applicability, PResult};
21+
use rustc_errors::{struct_span_err, Applicability, PResult};
2222
use rustc_feature::Features;
2323
use rustc_parse::parser::Parser;
2424
use rustc_parse::validate_attr;
@@ -542,7 +542,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
542542
fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) {
543543
let attr = self.cx.sess.find_by_name(item.attrs(), sym::derive);
544544
let span = attr.map_or(item.span(), |attr| attr.span);
545-
let mut err = rustc_errors::struct_span_err!(
545+
let mut err = struct_span_err!(
546546
self.cx.sess,
547547
span,
548548
E0774,

compiler/rustc_expand/src/proc_macro.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use rustc_ast::token;
55
use rustc_ast::tokenstream::{TokenStream, TokenTree};
66
use rustc_ast::{self as ast, *};
77
use rustc_data_structures::sync::Lrc;
8-
use rustc_errors::{Applicability, ErrorReported};
8+
use rustc_errors::{struct_span_err, Applicability, ErrorReported};
9+
use rustc_lexer::is_ident;
910
use rustc_parse::nt_to_tokenstream;
1011
use rustc_span::symbol::sym;
1112
use rustc_span::{Span, DUMMY_SP};
@@ -182,9 +183,22 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>)
182183
.filter_map(|nmi| match nmi {
183184
NestedMetaItem::Literal(lit) => {
184185
error_reported_filter_map = true;
185-
cx.struct_span_err(lit.span, "expected path to a trait, found literal")
186-
.help("for example, write `#[derive(Debug)]` for `Debug`")
187-
.emit();
186+
let mut err = struct_span_err!(
187+
cx.sess,
188+
lit.span,
189+
E0777,
190+
"expected path to a trait, found literal",
191+
);
192+
let token = lit.token.to_string();
193+
if token.starts_with('"')
194+
&& token.len() > 2
195+
&& is_ident(&token[1..token.len() - 1])
196+
{
197+
err.help(&format!("try using `#[derive({})]`", &token[1..token.len() - 1]));
198+
} else {
199+
err.help("for example, write `#[derive(Debug)]` for `Debug`");
200+
}
201+
err.emit();
188202
None
189203
}
190204
NestedMetaItem::MetaItem(mi) => Some(mi),

src/test/ui/error-codes/E0777.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#[derive("Clone")] //~ ERROR E0777
2+
#[derive("Clone
3+
")]
4+
//~^^ ERROR E0777
5+
struct Foo;
6+
7+
fn main() {}

src/test/ui/error-codes/E0777.stderr

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0777]: expected path to a trait, found literal
2+
--> $DIR/E0777.rs:1:10
3+
|
4+
LL | #[derive("Clone")]
5+
| ^^^^^^^
6+
|
7+
= help: try using `#[derive(Clone)]`
8+
9+
error[E0777]: expected path to a trait, found literal
10+
--> $DIR/E0777.rs:2:10
11+
|
12+
LL | #[derive("Clone
13+
| __________^
14+
LL | | ")]
15+
| |_^
16+
|
17+
= help: for example, write `#[derive(Debug)]` for `Debug`
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0777`.

0 commit comments

Comments
 (0)