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
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub(crate) mod link_attrs;
pub(crate) mod lint_helpers;
pub(crate) mod loop_match;
pub(crate) mod macro_attrs;
pub(crate) mod must_not_suspend;
pub(crate) mod must_use;
pub(crate) mod no_implicit_prelude;
pub(crate) mod no_link;
Expand Down
35 changes: 35 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use super::prelude::*;

pub(crate) struct MustNotSuspendParser;

impl<S: Stage> SingleAttributeParser<S> for MustNotSuspendParser {
const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
Allow(Target::Union),
Allow(Target::Trait),
]);
const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let reason = match args {
ArgParser::NameValue(reason) => match reason.value_as_str() {
Some(val) => Some(val),
None => {
cx.expected_nv_or_no_args(reason.value_span);
return None;
}
},
ArgParser::NoArgs => None,
ArgParser::List(list) => {
cx.expected_nv_or_no_args(list.span);
return None;
}
};

Some(AttributeKind::MustNotSupend { reason })
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use crate::attributes::macro_attrs::{
AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
MacroUseParser,
};
use crate::attributes::must_not_suspend::MustNotSuspendParser;
use crate::attributes::must_use::MustUseParser;
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
use crate::attributes::no_link::NoLinkParser;
Expand Down Expand Up @@ -89,7 +90,6 @@ use crate::session_diagnostics::{
AttributeParseError, AttributeParseErrorReason, ParsedDescription,
};
use crate::target_checking::AllowedTargets;

type GroupType<S> = LazyLock<GroupTypeInner<S>>;

pub(super) struct GroupTypeInner<S: Stage> {
Expand Down Expand Up @@ -208,6 +208,7 @@ attribute_parsers!(
Single<LinkageParser>,
Single<MacroExportParser>,
Single<MoveSizeLimitParser>,
Single<MustNotSuspendParser>,
Single<MustUseParser>,
Single<ObjcClassParser>,
Single<ObjcSelectorParser>,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,9 @@ pub enum AttributeKind {
/// Represents `#[move_size_limit]`
MoveSizeLimit { attr_span: Span, limit_span: Span, limit: Limit },

/// Represents `#[must_not_suspend]`
MustNotSupend { reason: Option<Symbol> },

/// Represents `#[must_use]`.
MustUse {
span: Span,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl AttributeKind {
Marker(..) => No,
MayDangle(..) => No,
MoveSizeLimit { .. } => No,
MustNotSupend { .. } => Yes,
MustUse { .. } => Yes,
Naked(..) => No,
NoCore(..) => No,
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_mir_transform/src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ use itertools::izip;
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::pluralize;
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{CoroutineDesugaring, CoroutineKind};
use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind, find_attr};
use rustc_index::bit_set::{BitMatrix, DenseBitSet, GrowableBitSet};
use rustc_index::{Idx, IndexVec, indexvec};
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
Expand All @@ -85,7 +85,6 @@ use rustc_mir_dataflow::{
};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::source_map::dummy_spanned;
use rustc_span::symbol::sym;
use rustc_span::{DUMMY_SP, Span};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::TyCtxtInferExt as _;
Expand Down Expand Up @@ -1989,11 +1988,11 @@ fn check_must_not_suspend_def(
hir_id: hir::HirId,
data: SuspendCheckData<'_>,
) -> bool {
if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
let reason = attr.value_str().map(|s| errors::MustNotSuspendReason {
span: data.source_span,
reason: s.as_str().to_string(),
});
if let Some(reason_str) =
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::MustNotSupend {reason} => reason)
{
let reason =
reason_str.map(|s| errors::MustNotSuspendReason { span: data.source_span, reason: s });
tcx.emit_node_span_lint(
rustc_session::lint::builtin::MUST_NOT_SUSPEND,
hir_id,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
pub(crate) struct MustNotSuspendReason {
#[primary_span]
pub span: Span,
pub reason: String,
pub reason: Symbol,
}

#[derive(Diagnostic)]
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 @@ -376,10 +376,6 @@ passes_must_implement_not_function_note = all `#[rustc_must_implement_one_of]` a

passes_must_implement_not_function_span_note = required by this annotation

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_no_main_function =
`main` function not found in crate `{$crate_name}`
.here_is_main = here is a function named `main`
Expand Down
12 changes: 1 addition & 11 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::ThreadLocal
| AttributeKind::CfiEncoding { .. }
| AttributeKind::RustcHasIncoherentInherentImpls
| AttributeKind::MustNotSupend { .. }
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
Expand All @@ -325,7 +326,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| [sym::rustc_dirty, ..]
| [sym::rustc_if_this_changed, ..]
| [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr),
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
[sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
self.check_autodiff(hir_id, attr, span, target)
}
Expand Down Expand Up @@ -1197,16 +1197,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

/// 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 {
Target::Struct | Target::Enum | Target::Union | Target::Trait => {}
_ => {
self.dcx().emit_err(errors::MustNotSuspend { attr_span: attr.span(), span });
}
}
}

/// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
fn check_may_dangle(&self, hir_id: HirId, attr_span: Span) {
if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,6 @@ pub(crate) struct BothFfiConstAndPure {
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_must_not_suspend)]
pub(crate) struct MustNotSuspend {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_link)]
#[warning]
Expand Down
31 changes: 16 additions & 15 deletions tests/ui/attributes/malformed-attrs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,6 @@ error: malformed `patchable_function_entry` attribute input
LL | #[patchable_function_entry]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`

error: malformed `must_not_suspend` attribute input
--> $DIR/malformed-attrs.rs:138:1
|
LL | #[must_not_suspend()]
| ^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL - #[must_not_suspend()]
LL + #[must_not_suspend = "reason"]
|
LL - #[must_not_suspend()]
LL + #[must_not_suspend]
|

error: malformed `allow` attribute input
--> $DIR/malformed-attrs.rs:184:1
|
Expand Down Expand Up @@ -527,6 +512,22 @@ LL | #[rustc_layout_scalar_valid_range_end]
| expected this to be a list
| help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]`

error[E0539]: malformed `must_not_suspend` attribute input
--> $DIR/malformed-attrs.rs:138:1
|
LL | #[must_not_suspend()]
| ^^^^^^^^^^^^^^^^^^--^
| |
| didn't expect a list here
|
help: try changing it to one of the following valid forms of the attribute
|
LL | #[must_not_suspend(count)]
| +++++
LL - #[must_not_suspend()]
LL + #[must_not_suspend]
|

error[E0539]: malformed `cfi_encoding` attribute input
--> $DIR/malformed-attrs.rs:140:1
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/lint/must_not_suspend/other_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![feature(must_not_suspend)]
#![deny(must_not_suspend)]

#[must_not_suspend] //~ ERROR attribute should be
#[must_not_suspend] //~ ERROR attribute cannot be used on modules
mod inner {}

fn main() {}
6 changes: 3 additions & 3 deletions tests/ui/lint/must_not_suspend/other_items.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
error: `#[must_not_suspend]` attribute cannot be used on modules
--> $DIR/other_items.rs:5:1
|
LL | #[must_not_suspend]
| ^^^^^^^^^^^^^^^^^^^
LL | mod inner {}
| ------------ is not a struct, enum, union, or trait
|
= help: `#[must_not_suspend]` can be applied to data types, traits, and unions

error: aborting due to 1 previous error

2 changes: 1 addition & 1 deletion tests/ui/lint/must_not_suspend/return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![feature(must_not_suspend)]
#![deny(must_not_suspend)]

#[must_not_suspend] //~ ERROR attribute should be
#[must_not_suspend] //~ ERROR attribute cannot be used on functions
fn foo() -> i32 {
0
}
Expand Down
12 changes: 5 additions & 7 deletions tests/ui/lint/must_not_suspend/return.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
error: `must_not_suspend` attribute should be applied to a struct, enum, union, or trait
error: `#[must_not_suspend]` attribute cannot be used on functions
--> $DIR/return.rs:5:1
|
LL | #[must_not_suspend]
| ^^^^^^^^^^^^^^^^^^^
LL | / fn foo() -> i32 {
LL | | 0
LL | | }
| |_- is not a struct, enum, union, or trait
LL | #[must_not_suspend]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[must_not_suspend]` can be applied to data types, traits, and unions

error: aborting due to 1 previous error

Loading