1
Fork 0

Use the right span for errors about #[deprecated] attributes.

This commit is contained in:
Mara Bos 2020-11-01 12:29:57 +01:00
parent 0e2337a5d6
commit 706bc33651
7 changed files with 53 additions and 35 deletions

View file

@ -637,19 +637,15 @@ pub struct Deprecation {
} }
/// Finds the deprecation attribute. `None` if none exists. /// Finds the deprecation attribute. `None` if none exists.
pub fn find_deprecation(sess: &Session, attrs: &[Attribute], item_sp: Span) -> Option<Deprecation> { pub fn find_deprecation(sess: &Session, attrs: &[Attribute]) -> Option<(Deprecation, Span)> {
find_deprecation_generic(sess, attrs.iter(), item_sp) find_deprecation_generic(sess, attrs.iter())
} }
fn find_deprecation_generic<'a, I>( fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
sess: &Session,
attrs_iter: I,
item_sp: Span,
) -> Option<Deprecation>
where where
I: Iterator<Item = &'a Attribute>, I: Iterator<Item = &'a Attribute>,
{ {
let mut depr: Option<Deprecation> = None; let mut depr: Option<(Deprecation, Span)> = None;
let diagnostic = &sess.parse_sess.span_diagnostic; let diagnostic = &sess.parse_sess.span_diagnostic;
'outer: for attr in attrs_iter { 'outer: for attr in attrs_iter {
@ -658,8 +654,10 @@ where
continue; continue;
} }
if depr.is_some() { if let Some((_, span)) = &depr {
struct_span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes").emit(); struct_span_err!(diagnostic, attr.span, E0550, "multiple deprecated attributes")
.span_note(*span, "first deprecation attribute here")
.emit();
break; break;
} }
@ -780,7 +778,7 @@ where
sess.mark_attr_used(&attr); sess.mark_attr_used(&attr);
let is_since_rustc_version = sess.check_name(attr, sym::rustc_deprecated); let is_since_rustc_version = sess.check_name(attr, sym::rustc_deprecated);
depr = Some(Deprecation { since, note, suggestion, is_since_rustc_version }); depr = Some((Deprecation { since, note, suggestion, is_since_rustc_version }, attr.span));
} }
depr depr

View file

@ -793,7 +793,7 @@ impl SyntaxExtension {
allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe), allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe),
local_inner_macros, local_inner_macros,
stability, stability,
deprecation: attr::find_deprecation(&sess, attrs, span), deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
helper_attrs, helper_attrs,
edition, edition,
is_builtin, is_builtin,

View file

@ -85,14 +85,22 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
did_error = self.forbid_staged_api_attrs(hir_id, attrs, inherit_deprecation.clone()); did_error = self.forbid_staged_api_attrs(hir_id, attrs, inherit_deprecation.clone());
} }
let depr = let depr = if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs) };
if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs, item_sp) };
let mut is_deprecated = false; let mut is_deprecated = false;
if let Some(depr) = &depr { if let Some((depr, span)) = &depr {
is_deprecated = true; is_deprecated = true;
if kind == AnnotationKind::Prohibited || kind == AnnotationKind::DeprecationProhibited { if kind == AnnotationKind::Prohibited || kind == AnnotationKind::DeprecationProhibited {
self.tcx.sess.span_err(item_sp, "This deprecation annotation is useless"); self.tcx
.sess
.struct_span_err(*span, "this deprecation annotation is useless")
.span_suggestion(
*span,
"try removing the deprecation attribute",
String::new(),
rustc_errors::Applicability::MachineApplicable,
)
.emit();
} }
// `Deprecation` is just two pointers, no need to intern it // `Deprecation` is just two pointers, no need to intern it
@ -116,7 +124,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
} }
} else { } else {
self.recurse_with_stability_attrs( self.recurse_with_stability_attrs(
depr.map(|d| DeprecationEntry::local(d, hir_id)), depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
None, None,
None, None,
visit_children, visit_children,
@ -141,11 +149,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
} }
} }
if depr.as_ref().map_or(false, |d| d.is_since_rustc_version) { if let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr {
if stab.is_none() { if stab.is_none() {
struct_span_err!( struct_span_err!(
self.tcx.sess, self.tcx.sess,
item_sp, *span,
E0549, E0549,
"rustc_deprecated attribute must be paired with \ "rustc_deprecated attribute must be paired with \
either stable or unstable attribute" either stable or unstable attribute"
@ -168,7 +176,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
// Check if deprecated_since < stable_since. If it is, // Check if deprecated_since < stable_since. If it is,
// this is *almost surely* an accident. // this is *almost surely* an accident.
if let (&Some(dep_since), &attr::Stable { since: stab_since }) = if let (&Some(dep_since), &attr::Stable { since: stab_since }) =
(&depr.as_ref().and_then(|d| d.since), &stab.level) (&depr.as_ref().and_then(|(d, _)| d.since), &stab.level)
{ {
// Explicit version of iter::order::lt to handle parse errors properly // Explicit version of iter::order::lt to handle parse errors properly
for (dep_v, stab_v) in for (dep_v, stab_v) in
@ -214,7 +222,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
} }
self.recurse_with_stability_attrs( self.recurse_with_stability_attrs(
depr.map(|d| DeprecationEntry::local(d, hir_id)), depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
stab, stab,
const_stab, const_stab,
visit_children, visit_children,

View file

@ -24,8 +24,8 @@ mod bogus_attribute_types_1 {
} }
#[deprecated(since = "a", note = "b")] #[deprecated(since = "a", note = "b")]
#[deprecated(since = "a", note = "b")] #[deprecated(since = "a", note = "b")] //~ ERROR multiple deprecated attributes
fn multiple1() { } //~ ERROR multiple deprecated attributes fn multiple1() { }
#[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items #[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
fn f1() { } fn f1() { }

View file

@ -41,10 +41,16 @@ LL | #[deprecated("test")]
| ^^^^^^ | ^^^^^^
error[E0550]: multiple deprecated attributes error[E0550]: multiple deprecated attributes
--> $DIR/deprecation-sanity.rs:28:1 --> $DIR/deprecation-sanity.rs:27:1
| |
LL | fn multiple1() { } LL | #[deprecated(since = "a", note = "b")]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first deprecation attribute here
--> $DIR/deprecation-sanity.rs:26:1
|
LL | #[deprecated(since = "a", note = "b")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0538]: multiple 'since' items error[E0538]: multiple 'since' items
--> $DIR/deprecation-sanity.rs:30:27 --> $DIR/deprecation-sanity.rs:30:27

View file

@ -59,14 +59,14 @@ fn multiple3() { }
#[stable(feature = "a", since = "b")] #[stable(feature = "a", since = "b")]
#[rustc_deprecated(since = "b", reason = "text")] #[rustc_deprecated(since = "b", reason = "text")]
#[rustc_deprecated(since = "b", reason = "text")] #[rustc_deprecated(since = "b", reason = "text")] //~ ERROR multiple deprecated attributes
#[rustc_const_unstable(feature = "c", issue = "none")] #[rustc_const_unstable(feature = "c", issue = "none")]
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
pub const fn multiple4() { } //~ ERROR multiple deprecated attributes pub const fn multiple4() { }
//~^ ERROR Invalid stability or deprecation version found //~^ ERROR Invalid stability or deprecation version found
#[rustc_deprecated(since = "a", reason = "text")] #[rustc_deprecated(since = "a", reason = "text")]
fn deprecated_without_unstable_or_stable() { } fn deprecated_without_unstable_or_stable() { }
//~^ ERROR rustc_deprecated attribute must be paired with either stable or unstable attribute //~^^ ERROR rustc_deprecated attribute must be paired with either stable or unstable attribute
fn main() { } fn main() { }

View file

@ -83,10 +83,16 @@ LL | #[stable(feature = "a", since = "b")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0550]: multiple deprecated attributes error[E0550]: multiple deprecated attributes
--> $DIR/stability-attribute-sanity.rs:65:1 --> $DIR/stability-attribute-sanity.rs:62:1
| |
LL | pub const fn multiple4() { } LL | #[rustc_deprecated(since = "b", reason = "text")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first deprecation attribute here
--> $DIR/stability-attribute-sanity.rs:61:1
|
LL | #[rustc_deprecated(since = "b", reason = "text")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0544]: multiple stability levels error[E0544]: multiple stability levels
--> $DIR/stability-attribute-sanity.rs:64:1 --> $DIR/stability-attribute-sanity.rs:64:1
@ -101,10 +107,10 @@ LL | pub const fn multiple4() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
--> $DIR/stability-attribute-sanity.rs:69:1 --> $DIR/stability-attribute-sanity.rs:68:1
| |
LL | fn deprecated_without_unstable_or_stable() { } LL | #[rustc_deprecated(since = "a", reason = "text")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 18 previous errors error: aborting due to 18 previous errors