Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ attr_parsing_empty_attribute =

attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
.help = `#[{$name}]` can {$only}be applied to {$applied}
.suggestion = remove the attribute
attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target}
.warn = {-attr_parsing_previously_accepted}
.help = `#[{$name}]` can {$only}be applied to {$applied}
.suggestion = remove the attribute

attr_parsing_empty_confusables =
expected at least one confusable name
Expand Down
20 changes: 18 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/must_use.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use rustc_errors::DiagArgValue;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::{MethodKind, Target};
use rustc_span::{Symbol, sym};

use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
use crate::context::{ALL_TARGETS, AcceptContext, AllowedTargets, Stage};
use crate::context::MaybeWarn::{Allow, Error};
use crate::context::{AcceptContext, AllowedTargets, Stage};
use crate::parser::ArgParser;
use crate::session_diagnostics;
pub(crate) struct MustUseParser;
Expand All @@ -13,7 +15,21 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
const PATH: &[Symbol] = &[sym::must_use];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
Allow(Target::Fn),
Allow(Target::Enum),
Allow(Target::Struct),
Allow(Target::Union),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::ForeignFn),
// `impl Trait` in return position can trip
// `unused_must_use` if `Trait` is marked as
// `#[must_use]`
Allow(Target::Trait),
Error(Target::WherePredicate),
]);
const TEMPLATE: AttributeTemplate = template!(
Word, NameValueStr: "reason",
"https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emi
target: target.plural_name(),
applied: applied.clone(),
only,
attr_span: *span,
},
),
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,13 +489,16 @@ pub(crate) struct InvalidTargetLint {
pub target: &'static str,
pub applied: String,
pub only: &'static str,
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[help]
#[diag(attr_parsing_invalid_target)]
pub(crate) struct InvalidTarget {
#[primary_span]
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
pub span: Span,
pub name: Symbol,
pub target: &'static str,
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,6 @@ passes_must_not_suspend =
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
.label = is not a struct, enum, union, or trait

passes_must_use_no_effect =
`#[must_use]` has no effect when applied to {$target}
.suggestion = remove the attribute

passes_no_link =
attribute should be applied to an `extern crate` item
.label = not an `extern crate` item
Expand Down
41 changes: 2 additions & 39 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
self.check_may_dangle(hir_id, *attr_span)
}
Attribute::Parsed(AttributeKind::MustUse { span, .. }) => {
self.check_must_use(hir_id, *span, target)
}
&Attribute::Parsed(AttributeKind::CustomMir(dialect, phase, attr_span)) => {
self.check_custom_mir(dialect, phase, attr_span)
}
Expand Down Expand Up @@ -249,7 +246,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::Coverage (..)
| AttributeKind::ShouldPanic { .. }
| AttributeKind::Coroutine(..)
| AttributeKind::Linkage(..),
| AttributeKind::Linkage(..)
| AttributeKind::MustUse { .. },
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
Expand Down Expand Up @@ -1260,41 +1258,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

/// Warns against some misuses of `#[must_use]`
fn check_must_use(&self, hir_id: HirId, attr_span: Span, target: Target) {
if matches!(
target,
Target::Fn
| Target::Enum
| Target::Struct
| Target::Union
| Target::Method(MethodKind::Trait { body: false } | MethodKind::Inherent)
| Target::ForeignFn
// `impl Trait` in return position can trip
// `unused_must_use` if `Trait` is marked as
// `#[must_use]`
| Target::Trait
) {
return;
}

// `#[must_use]` can be applied to a trait method definition with a default body
if let Target::Method(MethodKind::Trait { body: true }) = target
&& let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id
&& let containing_item = self.tcx.hir_expect_item(parent_def_id)
&& let hir::ItemKind::Trait(..) = containing_item.kind
{
return;
}

self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr_span,
errors::MustUseNoEffect { target: target.plural_name(), attr_span },
);
}

/// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait.
fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) {
match target {
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,14 +358,6 @@ pub(crate) struct BothFfiConstAndPure {
pub attr_span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_must_use_no_effect)]
pub(crate) struct MustUseNoEffect {
pub target: &'static str,
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_must_not_suspend)]
pub(crate) struct MustNotSuspend {
Expand Down
1 change: 1 addition & 0 deletions tests/ui/attributes/rustc_confusables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ impl Bar {
#[rustc_confusables("blah")]
//~^ ERROR attribute cannot be used on
//~| HELP can only be applied to
//~| HELP remove the attribute
fn not_inherent_impl_method() {}
3 changes: 3 additions & 0 deletions tests/ui/extern/issue-47725.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
//~^ WARN attribute cannot be used on
//~| WARN previously accepted
//~| HELP can be applied to
//~| HELP remove the attribute
struct Foo;

#[link_name = "foobar"]
//~^ WARN attribute cannot be used on
//~| WARN previously accepted
//~| HELP can be applied to
//~| HELP remove the attribute
extern "C" {
fn foo() -> u32;
}
Expand All @@ -19,6 +21,7 @@ extern "C" {
//~| HELP must be of the form
//~| WARN attribute cannot be used on
//~| WARN previously accepted
//~| HELP remove the attribute
//~| HELP can be applied to
//~| NOTE for more information, visit
extern "C" {
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/extern/issue-47725.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0539]: malformed `link_name` attribute input
--> $DIR/issue-47725.rs:17:1
--> $DIR/issue-47725.rs:19:1
|
LL | #[link_name]
| ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]`
Expand All @@ -21,7 +21,7 @@ LL | #![warn(unused_attributes)]
| ^^^^^^^^^^^^^^^^^

warning: `#[link_name]` attribute cannot be used on foreign modules
--> $DIR/issue-47725.rs:9:1
--> $DIR/issue-47725.rs:10:1
|
LL | #[link_name = "foobar"]
| ^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -30,7 +30,7 @@ LL | #[link_name = "foobar"]
= help: `#[link_name]` can be applied to foreign functions, foreign statics

warning: `#[link_name]` attribute cannot be used on foreign modules
--> $DIR/issue-47725.rs:17:1
--> $DIR/issue-47725.rs:19:1
|
LL | #[link_name]
| ^^^^^^^^^^^^
Expand Down
Loading
Loading