Skip to content

Commit 6712f8c

Browse files
authored
Merge pull request #394 from dtolnay/deprecated
Prevent deprecation warning on generated impl for deprecated type
2 parents 42b1460 + 07e7d99 commit 6712f8c

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

impl/src/expand.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::ast::{Enum, Field, Input, Struct};
22
use crate::attr::Trait;
33
use crate::generics::InferredBounds;
44
use crate::unraw::MemberUnraw;
5-
use proc_macro2::{Ident, TokenStream};
5+
use proc_macro2::{Ident, Span, TokenStream};
66
use quote::{format_ident, quote, quote_spanned, ToTokens};
77
use std::collections::BTreeSet as Set;
88
use syn::{DeriveInput, GenericArgument, PathArguments, Result, Token, Type};
@@ -27,7 +27,7 @@ fn try_expand(input: &DeriveInput) -> Result<TokenStream> {
2727
}
2828

2929
fn fallback(input: &DeriveInput, error: syn::Error) -> TokenStream {
30-
let ty = &input.ident;
30+
let ty = call_site_ident(&input.ident);
3131
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
3232

3333
let error = error.to_compile_error();
@@ -55,7 +55,7 @@ fn fallback(input: &DeriveInput, error: syn::Error) -> TokenStream {
5555
}
5656

5757
fn impl_struct(input: Struct) -> TokenStream {
58-
let ty = &input.ident;
58+
let ty = call_site_ident(&input.ident);
5959
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
6060
let mut error_inferred_bounds = InferredBounds::new();
6161

@@ -228,7 +228,7 @@ fn impl_struct(input: Struct) -> TokenStream {
228228
}
229229

230230
fn impl_enum(input: Enum) -> TokenStream {
231-
let ty = &input.ident;
231+
let ty = call_site_ident(&input.ident);
232232
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
233233
let mut error_inferred_bounds = InferredBounds::new();
234234

@@ -492,6 +492,14 @@ fn impl_enum(input: Enum) -> TokenStream {
492492
}
493493
}
494494

495+
// Create an ident with which we can expand `impl Trait for #ident {}` on a
496+
// deprecated type without triggering deprecation warning on the generated impl.
497+
fn call_site_ident(ident: &Ident) -> Ident {
498+
let mut ident = ident.clone();
499+
ident.set_span(ident.span().resolved_at(Span::call_site()));
500+
ident
501+
}
502+
495503
fn fields_pat(fields: &[Field]) -> TokenStream {
496504
let mut members = fields.iter().map(|field| &field.member).peekable();
497505
match members.peek() {

tests/test_lints.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,37 @@ fn test_deprecated() {
3939
#![deny(deprecated)]
4040

4141
#[derive(Error, Debug)]
42-
pub enum MyError {
42+
#[deprecated]
43+
#[error("...")]
44+
pub struct DeprecatedStruct;
45+
46+
#[derive(Error, Debug)]
47+
#[error("{message} {}", .message)]
48+
pub struct DeprecatedStructField {
49+
#[deprecated]
50+
message: String,
51+
}
52+
53+
#[derive(Error, Debug)]
54+
#[deprecated]
55+
pub enum DeprecatedEnum {
56+
#[error("...")]
57+
Variant,
58+
}
59+
60+
#[derive(Error, Debug)]
61+
pub enum DeprecatedVariant {
4362
#[deprecated]
4463
#[error("...")]
45-
Deprecated,
64+
Variant,
4665
}
4766

4867
#[allow(deprecated)]
49-
let _ = MyError::Deprecated;
68+
let _: DeprecatedStruct;
69+
#[allow(deprecated)]
70+
let _: DeprecatedStructField;
71+
#[allow(deprecated)]
72+
let _ = DeprecatedEnum::Variant;
73+
#[allow(deprecated)]
74+
let _ = DeprecatedVariant::Variant;
5075
}

tests/ui/missing-display.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error[E0277]: `MyError` doesn't implement `std::fmt::Display`
22
--> tests/ui/missing-display.rs:4:10
33
|
4+
3 | #[derive(Error, Debug)]
5+
| ----- in this derive macro expansion
46
4 | pub enum MyError {
57
| ^^^^^^^ `MyError` cannot be formatted with the default formatter
68
|
@@ -11,3 +13,4 @@ note: required by a bound in `std::error::Error`
1113
|
1214
| pub trait Error: Debug + Display {
1315
| ^^^^^^^ required by this bound in `Error`
16+
= note: this error originates in the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)