Skip to content

Commit e6d612e

Browse files
committedApr 28, 2024
Disallow unsafe in derive
1 parent 8638edd commit e6d612e

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::{
77
Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
88
};
@@ -60,6 +60,7 @@ impl MultiItemModifier for Expander {
6060
// Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the
6161
// paths.
6262
report_path_args(sess, meta);
63+
report_unsafe_args(sess, meta);
6364
meta.path.clone()
6465
})
6566
.map(|path| DeriveResolution {
@@ -159,3 +160,12 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) {
159160
}
160161
}
161162
}
163+
164+
fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) {
165+
match meta.unsafety {
166+
Unsafe::Yes(span) => {
167+
sess.dcx().emit_err(errors::DeriveUnsafePath { span });
168+
}
169+
Unsafe::No => {}
170+
}
171+
}

‎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)