Skip to content

Commit 98ef662

Browse files
committed
Disallow unsafe in derive
1 parent 7fa4c69 commit 98ef662

File tree

6 files changed

+37
-2
lines changed

6 files changed

+37
-2
lines changed

compiler/rustc_builtin_macros/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept a
110110
builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values
111111
.suggestion = remove the value
112112
113+
builtin_macros_derive_unsafe_path = traits in `#[derive(...)]` don't accept `unsafe(...)`
114+
.suggestion = remove the `unsafe(...)`
115+
113116
builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
114117
.cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
115118
.custom = use `std::env::var({$var_expr})` to read the variable at run time

compiler/rustc_builtin_macros/src/derive.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::cfg_eval::cfg_eval;
22
use crate::errors;
33

44
use rustc_ast as ast;
5-
use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
5+
use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Unsafe};
66
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
77
use rustc_feature::AttributeTemplate;
88
use rustc_parse::validate_attr;
@@ -56,6 +56,7 @@ impl MultiItemModifier for Expander {
5656
// Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the
5757
// paths.
5858
report_path_args(sess, meta);
59+
report_unsafe_args(sess, meta);
5960
meta.path.clone()
6061
})
6162
.map(|path| (path, dummy_annotatable(), None, self.0))
@@ -150,3 +151,12 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) {
150151
}
151152
}
152153
}
154+
155+
fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) {
156+
match meta.unsafety {
157+
Unsafe::Yes(span) => {
158+
sess.dcx().emit_err(errors::DeriveUnsafePath { span });
159+
}
160+
Unsafe::No => {}
161+
}
162+
}

compiler/rustc_builtin_macros/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,13 @@ pub(crate) struct DerivePathArgsValue {
295295
pub(crate) span: Span,
296296
}
297297

298+
#[derive(Diagnostic)]
299+
#[diag(builtin_macros_derive_unsafe_path)]
300+
pub(crate) struct DeriveUnsafePath {
301+
#[primary_span]
302+
pub(crate) span: Span,
303+
}
304+
298305
#[derive(Diagnostic)]
299306
#[diag(builtin_macros_no_default_variant)]
300307
#[help]

compiler/rustc_expand/src/expand.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
774774
if let SyntaxExtensionKind::Derive(..) = ext {
775775
self.gate_proc_macro_input(&item);
776776
}
777-
// FIX THIS LATER
777+
// The `MetaItem` representing the trait to derive can't
778+
// have an unsafe around it (as of now).
778779
let meta = ast::MetaItem {
779780
unsafety: ast::Unsafe::No,
780781
kind: MetaItemKind::Word,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![feature(unsafe_attributes)]
2+
3+
#[derive(unsafe(Debug))] //~ ERROR: traits in `#[derive(...)]` don't accept `unsafe(...)`
4+
struct Foo;
5+
6+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: traits in `#[derive(...)]` don't accept `unsafe(...)`
2+
--> $DIR/derive-unsafe-attributes.rs:3:10
3+
|
4+
LL | #[derive(unsafe(Debug))]
5+
| ^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)