Skip to content

Commit

Permalink
Rollup merge of rust-lang#106716 - c410-f3r:rfc-2397-1, r=davidtwco
Browse files Browse the repository at this point in the history
[RFC 2397] Deny incorrect locations

cc rust-lang#51992

As declared in the RFC, `#[do_not_recommend]` should only be applicable on trait implementations.
  • Loading branch information
Yuki Okushi committed Jan 13, 2023
2 parents 9a2f393 + 7dd45ba commit f6f362c
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 2 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/passes.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
-passes_see_issue =
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
passes_incorrect_do_not_recommend_location =
`#[do_not_recommend]` can only be placed on trait implementations
passes_outer_crate_level_attr =
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl CheckAttrVisitor<'_> {
let attrs = self.tcx.hir().attrs(hir_id);
for attr in attrs {
let attr_is_valid = match attr.name_or_empty() {
sym::do_not_recommend => self.check_do_not_recommend(attr.span, target),
sym::inline => self.check_inline(hir_id, attr, span, target),
sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target),
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
Expand Down Expand Up @@ -241,6 +242,16 @@ impl CheckAttrVisitor<'_> {
);
}

/// Checks if `#[do_not_recommend]` is applied on a trait impl.
fn check_do_not_recommend(&self, attr_span: Span, target: Target) -> bool {
if let Target::Impl = target {
true
} else {
self.tcx.sess.emit_err(errors::IncorrectDoNotRecommendLocation { span: attr_span });
false
}
}

/// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid.
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
match target {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ use rustc_span::{Span, Symbol, DUMMY_SP};

use crate::lang_items::Duplicate;

#[derive(Diagnostic)]
#[diag(passes_incorrect_do_not_recommend_location)]
pub struct IncorrectDoNotRecommendLocation {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_outer_crate_level_attr)]
pub struct OuterCrateLevelAttr;
Expand Down
45 changes: 45 additions & 0 deletions tests/ui/rfc-2397-do-not-recommend/incorrect-locations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#![feature(do_not_recommend)]

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
const CONST: () = ();

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
static Static: () = ();

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
type Type = ();

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
enum Enum {
}

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
extern {
}

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
fn fun() {
}

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
struct Struct {
}

#[do_not_recommend]
//~^ `#[do_not_recommend]` can only be placed
trait Trait {
}

#[do_not_recommend]
impl Trait for i32 {
}

fn main() {
}
50 changes: 50 additions & 0 deletions tests/ui/rfc-2397-do-not-recommend/incorrect-locations.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:3:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:7:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:11:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:15:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:20:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:25:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:30:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: `#[do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:35:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^

error: aborting due to 8 previous errors

5 changes: 4 additions & 1 deletion tests/ui/rfc-2397-do-not-recommend/unstable-feature.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
trait Foo {
}

#[do_not_recommend]
//~^ ERROR the `#[do_not_recommend]` attribute is an experimental feature
trait Foo {
impl Foo for i32 {
}

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/rfc-2397-do-not-recommend/unstable-feature.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0658]: the `#[do_not_recommend]` attribute is an experimental feature
--> $DIR/unstable-feature.rs:1:1
--> $DIR/unstable-feature.rs:4:1
|
LL | #[do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^
Expand Down

0 comments on commit f6f362c

Please sign in to comment.