Skip to content

Commit 706bc33

Browse files
committed
Use the right span for errors about #[deprecated] attributes.
1 parent 0e2337a commit 706bc33

File tree

7 files changed

+53
-35
lines changed

7 files changed

+53
-35
lines changed

compiler/rustc_attr/src/builtin.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -637,19 +637,15 @@ pub struct Deprecation {
637637
}
638638

639639
/// Finds the deprecation attribute. `None` if none exists.
640-
pub fn find_deprecation(sess: &Session, attrs: &[Attribute], item_sp: Span) -> Option<Deprecation> {
641-
find_deprecation_generic(sess, attrs.iter(), item_sp)
640+
pub fn find_deprecation(sess: &Session, attrs: &[Attribute]) -> Option<(Deprecation, Span)> {
641+
find_deprecation_generic(sess, attrs.iter())
642642
}
643643

644-
fn find_deprecation_generic<'a, I>(
645-
sess: &Session,
646-
attrs_iter: I,
647-
item_sp: Span,
648-
) -> Option<Deprecation>
644+
fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
649645
where
650646
I: Iterator<Item = &'a Attribute>,
651647
{
652-
let mut depr: Option<Deprecation> = None;
648+
let mut depr: Option<(Deprecation, Span)> = None;
653649
let diagnostic = &sess.parse_sess.span_diagnostic;
654650

655651
'outer: for attr in attrs_iter {
@@ -658,8 +654,10 @@ where
658654
continue;
659655
}
660656

661-
if depr.is_some() {
662-
struct_span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes").emit();
657+
if let Some((_, span)) = &depr {
658+
struct_span_err!(diagnostic, attr.span, E0550, "multiple deprecated attributes")
659+
.span_note(*span, "first deprecation attribute here")
660+
.emit();
663661
break;
664662
}
665663

@@ -780,7 +778,7 @@ where
780778
sess.mark_attr_used(&attr);
781779

782780
let is_since_rustc_version = sess.check_name(attr, sym::rustc_deprecated);
783-
depr = Some(Deprecation { since, note, suggestion, is_since_rustc_version });
781+
depr = Some((Deprecation { since, note, suggestion, is_since_rustc_version }, attr.span));
784782
}
785783

786784
depr

compiler/rustc_expand/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ impl SyntaxExtension {
793793
allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe),
794794
local_inner_macros,
795795
stability,
796-
deprecation: attr::find_deprecation(&sess, attrs, span),
796+
deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
797797
helper_attrs,
798798
edition,
799799
is_builtin,

compiler/rustc_passes/src/stability.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,22 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
8585
did_error = self.forbid_staged_api_attrs(hir_id, attrs, inherit_deprecation.clone());
8686
}
8787

88-
let depr =
89-
if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs, item_sp) };
88+
let depr = if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs) };
9089
let mut is_deprecated = false;
91-
if let Some(depr) = &depr {
90+
if let Some((depr, span)) = &depr {
9291
is_deprecated = true;
9392

9493
if kind == AnnotationKind::Prohibited || kind == AnnotationKind::DeprecationProhibited {
95-
self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless");
94+
self.tcx
95+
.sess
96+
.struct_span_err(*span, "this deprecation annotation is useless")
97+
.span_suggestion(
98+
*span,
99+
"try removing the deprecation attribute",
100+
String::new(),
101+
rustc_errors::Applicability::MachineApplicable,
102+
)
103+
.emit();
96104
}
97105

98106
// `Deprecation` is just two pointers, no need to intern it
@@ -116,7 +124,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
116124
}
117125
} else {
118126
self.recurse_with_stability_attrs(
119-
depr.map(|d| DeprecationEntry::local(d, hir_id)),
127+
depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
120128
None,
121129
None,
122130
visit_children,
@@ -141,11 +149,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
141149
}
142150
}
143151

144-
if depr.as_ref().map_or(false, |d| d.is_since_rustc_version) {
152+
if let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr {
145153
if stab.is_none() {
146154
struct_span_err!(
147155
self.tcx.sess,
148-
item_sp,
156+
*span,
149157
E0549,
150158
"rustc_deprecated attribute must be paired with \
151159
either stable or unstable attribute"
@@ -168,7 +176,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
168176
// Check if deprecated_since < stable_since. If it is,
169177
// this is *almost surely* an accident.
170178
if let (&Some(dep_since), &attr::Stable { since: stab_since }) =
171-
(&depr.as_ref().and_then(|d| d.since), &stab.level)
179+
(&depr.as_ref().and_then(|(d, _)| d.since), &stab.level)
172180
{
173181
// Explicit version of iter::order::lt to handle parse errors properly
174182
for (dep_v, stab_v) in
@@ -214,7 +222,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
214222
}
215223

216224
self.recurse_with_stability_attrs(
217-
depr.map(|d| DeprecationEntry::local(d, hir_id)),
225+
depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
218226
stab,
219227
const_stab,
220228
visit_children,

src/test/ui/deprecation/deprecation-sanity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ mod bogus_attribute_types_1 {
2424
}
2525

2626
#[deprecated(since = "a", note = "b")]
27-
#[deprecated(since = "a", note = "b")]
28-
fn multiple1() { } //~ ERROR multiple deprecated attributes
27+
#[deprecated(since = "a", note = "b")] //~ ERROR multiple deprecated attributes
28+
fn multiple1() { }
2929

3030
#[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
3131
fn f1() { }

src/test/ui/deprecation/deprecation-sanity.stderr

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,16 @@ LL | #[deprecated("test")]
4141
| ^^^^^^
4242

4343
error[E0550]: multiple deprecated attributes
44-
--> $DIR/deprecation-sanity.rs:28:1
44+
--> $DIR/deprecation-sanity.rs:27:1
4545
|
46-
LL | fn multiple1() { }
47-
| ^^^^^^^^^^^^^^^^^^
46+
LL | #[deprecated(since = "a", note = "b")]
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48+
|
49+
note: first deprecation attribute here
50+
--> $DIR/deprecation-sanity.rs:26:1
51+
|
52+
LL | #[deprecated(since = "a", note = "b")]
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4854

4955
error[E0538]: multiple 'since' items
5056
--> $DIR/deprecation-sanity.rs:30:27

src/test/ui/stability-attribute/stability-attribute-sanity.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ fn multiple3() { }
5959

6060
#[stable(feature = "a", since = "b")]
6161
#[rustc_deprecated(since = "b", reason = "text")]
62-
#[rustc_deprecated(since = "b", reason = "text")]
62+
#[rustc_deprecated(since = "b", reason = "text")] //~ ERROR multiple deprecated attributes
6363
#[rustc_const_unstable(feature = "c", issue = "none")]
6464
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
65-
pub const fn multiple4() { } //~ ERROR multiple deprecated attributes
65+
pub const fn multiple4() { }
6666
//~^ ERROR Invalid stability or deprecation version found
6767

6868
#[rustc_deprecated(since = "a", reason = "text")]
6969
fn deprecated_without_unstable_or_stable() { }
70-
//~^ ERROR rustc_deprecated attribute must be paired with either stable or unstable attribute
70+
//~^^ ERROR rustc_deprecated attribute must be paired with either stable or unstable attribute
7171

7272
fn main() { }

src/test/ui/stability-attribute/stability-attribute-sanity.stderr

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,16 @@ LL | #[stable(feature = "a", since = "b")]
8383
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8484

8585
error[E0550]: multiple deprecated attributes
86-
--> $DIR/stability-attribute-sanity.rs:65:1
86+
--> $DIR/stability-attribute-sanity.rs:62:1
8787
|
88-
LL | pub const fn multiple4() { }
89-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88+
LL | #[rustc_deprecated(since = "b", reason = "text")]
89+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90+
|
91+
note: first deprecation attribute here
92+
--> $DIR/stability-attribute-sanity.rs:61:1
93+
|
94+
LL | #[rustc_deprecated(since = "b", reason = "text")]
95+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9096

9197
error[E0544]: multiple stability levels
9298
--> $DIR/stability-attribute-sanity.rs:64:1
@@ -101,10 +107,10 @@ LL | pub const fn multiple4() { }
101107
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
102108

103109
error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
104-
--> $DIR/stability-attribute-sanity.rs:69:1
110+
--> $DIR/stability-attribute-sanity.rs:68:1
105111
|
106-
LL | fn deprecated_without_unstable_or_stable() { }
107-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
112+
LL | #[rustc_deprecated(since = "a", reason = "text")]
113+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
108114

109115
error: aborting due to 18 previous errors
110116

0 commit comments

Comments
 (0)