Rollup merge of #150943 - port_must_not_suspend, r=jdonszelmann,JonathanBrouwer
Port `#[must_not_suspend]` to attribute parser Tracking issue: rust-lang/rust#131229 r? @JonathanBrouwer
This commit is contained in:
commit
a2994063d4
15 changed files with 77 additions and 61 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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> {
|
||||
|
|
@ -208,6 +208,7 @@ attribute_parsers!(
|
|||
Single<LinkageParser>,
|
||||
Single<MacroExportParser>,
|
||||
Single<MoveSizeLimitParser>,
|
||||
Single<MustNotSuspendParser>,
|
||||
Single<MustUseParser>,
|
||||
Single<ObjcClassParser>,
|
||||
Single<ObjcSelectorParser>,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ impl AttributeKind {
|
|||
Marker(..) => No,
|
||||
MayDangle(..) => No,
|
||||
MoveSizeLimit { .. } => No,
|
||||
MustNotSupend { .. } => Yes,
|
||||
MustUse { .. } => Yes,
|
||||
Naked(..) => No,
|
||||
NoCore(..) => No,
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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 _;
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -368,10 +368,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`
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -1152,16 +1152,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)
|
||||
|
|
|
|||
|
|
@ -186,15 +186,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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue