Disallow unsafe in derive
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index a3d6a1c..2d1269e 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -110,6 +110,9 @@
 builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values
     .suggestion = remove the value
 
+builtin_macros_derive_unsafe_path = traits in `#[derive(...)]` don't accept `unsafe(...)`
+    .suggestion = remove the `unsafe(...)`
+
 builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
     .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
     .custom = use `std::env::var({$var_expr})` to read the variable at run time
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index d14858e..d70eaa6 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -2,7 +2,7 @@
 use crate::errors;
 
 use rustc_ast as ast;
-use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
+use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind, Unsafe};
 use rustc_expand::base::{
     Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
 };
@@ -60,6 +60,7 @@ fn expand(
                                 // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the
                                 // paths.
                                 report_path_args(sess, meta);
+                                report_unsafe_args(sess, meta);
                                 meta.path.clone()
                             })
                             .map(|path| DeriveResolution {
@@ -159,3 +160,12 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) {
         }
     }
 }
+
+fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) {
+    match meta.unsafety {
+        Unsafe::Yes(span) => {
+            sess.dcx().emit_err(errors::DeriveUnsafePath { span });
+        }
+        Unsafe::No => {}
+    }
+}
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index d157703..b14eb2b 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -296,6 +296,13 @@ pub(crate) struct DerivePathArgsValue {
 }
 
 #[derive(Diagnostic)]
+#[diag(builtin_macros_derive_unsafe_path)]
+pub(crate) struct DeriveUnsafePath {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(builtin_macros_no_default_variant)]
 #[help]
 pub(crate) struct NoDefaultVariant {
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 77cb617..dfef254 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -778,7 +778,8 @@ fn expand_invoc(
                     if let SyntaxExtensionKind::Derive(..) = ext {
                         self.gate_proc_macro_input(&item);
                     }
-                    // FIX THIS LATER
+                    // The `MetaItem` representing the trait to derive can't
+                    // have an unsafe around it (as of now).
                     let meta = ast::MetaItem {
                         unsafety: ast::Unsafe::No,
                         kind: MetaItemKind::Word,
diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs
new file mode 100644
index 0000000..774ce86
--- /dev/null
+++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs
@@ -0,0 +1,6 @@
+#![feature(unsafe_attributes)]
+
+#[derive(unsafe(Debug))] //~ ERROR: traits in `#[derive(...)]` don't accept `unsafe(...)`
+struct Foo;
+
+fn main() {}
diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr
new file mode 100644
index 0000000..fc0daf1
--- /dev/null
+++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr
@@ -0,0 +1,8 @@
+error: traits in `#[derive(...)]` don't accept `unsafe(...)`
+  --> $DIR/derive-unsafe-attributes.rs:3:10
+   |
+LL | #[derive(unsafe(Debug))]
+   |          ^^^^^^
+
+error: aborting due to 1 previous error
+