diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index b1ff66eb64fa69d420603a35d9ad1e47998d0131..03ed62f2a0d664ef10f56629da1d17ef8d580726 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -833,7 +833,8 @@ pub fn provide(providers: &mut Providers<'_>) { /// Returns whether `span` originates in a foreign crate's external macro. /// -/// This is used to test whether a lint should be entirely aborted above. +/// This is used to test whether a lint should not even begin to figure out whether it should +/// be reported on the current node. pub fn in_external_macro(sess: &Session, span: Span) -> bool { let info = match span.ctxt().outer().expn_info() { Some(info) => info, @@ -859,3 +860,17 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { Err(_) => true, } } + +/// Returns whether `span` originates in a derive macro's expansion +pub fn in_derive_expansion(span: Span) -> bool { + let info = match span.ctxt().outer().expn_info() { + Some(info) => info, + // no ExpnInfo means this span doesn't come from a macro + None => return false, + }; + + match info.format { + ExpnFormat::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("), + _ => false, + } +} diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 2664d6eaa28572c83c7d41403b813213029a792b..c1a97cd94dc3945690ceb9fde728c0252b8db075 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,7 +3,7 @@ pub use self::StabilityLevel::*; -use crate::lint::{self, Lint}; +use crate::lint::{self, Lint, in_derive_expansion}; use crate::hir::{self, Item, Generics, StructField, Variant, HirId}; use crate::hir::def::Def; use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; @@ -562,6 +562,9 @@ pub fn eval_stability(self, def_id: DefId, id: Option, span: Span) -> Eva suggestion: Option, message: &str, lint: &'static Lint| { + if in_derive_expansion(span) { + return; + } let msg = if let Some(note) = note { format!("{}: {}", message, note) } else { diff --git a/src/test/ui/deprecation/derive_on_deprecated.rs b/src/test/ui/deprecation/derive_on_deprecated.rs new file mode 100644 index 0000000000000000000000000000000000000000..4980a7f5aa31cb617510eff2175af74f0af96441 --- /dev/null +++ b/src/test/ui/deprecation/derive_on_deprecated.rs @@ -0,0 +1,9 @@ +// compile-pass + +#![deny(deprecated)] + +#[deprecated = "oh no"] +#[derive(Default)] +struct X; + +fn main() {} diff --git a/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs new file mode 100644 index 0000000000000000000000000000000000000000..235146bad9c851f90c296a6987d46dfe267ff652 --- /dev/null +++ b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs @@ -0,0 +1,9 @@ +// compile-pass + +#![forbid(deprecated)] + +#[deprecated = "oh no"] +#[derive(Default)] +struct X; + +fn main() {}