Auto merge of #146862 - matthiaskrgr:rollup-1zqootr, r=matthiaskrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#143857 (Port #[macro_export] to the new attribute parsing infrastructure)
 - rust-lang/rust#146486 (Improve `core::sync::atomic` coverage)
 - rust-lang/rust#146606 (ci: x86_64-gnu-tools: Add `--test-args` regression test)
 - rust-lang/rust#146639 (std: merge definitions of `StdioPipes`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-09-21 20:33:36 +00:00
commit 9f32ccf35f
40 changed files with 864 additions and 410 deletions

View file

@ -1,3 +1,4 @@
use rustc_ast::AttrStyle;
use rustc_errors::DiagArgValue;
use rustc_hir::attrs::MacroUseArgs;
@ -133,3 +134,65 @@ impl<S: Stage> NoArgsAttributeParser<S> for AllowInternalUnsafeParser {
]);
const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span);
}
pub(crate) struct MacroExportParser;
impl<S: Stage> SingleAttributeParser<S> for MacroExportParser {
const PATH: &[Symbol] = &[sym::macro_export];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
Allow(Target::MacroDef),
Error(Target::WherePredicate),
Error(Target::Crate),
]);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let suggestions = || {
<Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(AttrStyle::Inner, "macro_export")
};
let local_inner_macros = match args {
ArgParser::NoArgs => false,
ArgParser::List(list) => {
let Some(l) = list.single() else {
let span = cx.attr_span;
cx.emit_lint(
AttributeLintKind::InvalidMacroExportArguments {
suggestions: suggestions(),
},
span,
);
return None;
};
match l.meta_item().and_then(|i| i.path().word_sym()) {
Some(sym::local_inner_macros) => true,
_ => {
let span = cx.attr_span;
cx.emit_lint(
AttributeLintKind::InvalidMacroExportArguments {
suggestions: suggestions(),
},
span,
);
return None;
}
}
}
ArgParser::NameValue(_) => {
let span = cx.attr_span;
let suggestions = suggestions();
cx.emit_err(IllFormedAttributeInputLint {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
),
span,
});
return None;
}
};
Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros })
}
}

View file

@ -40,7 +40,7 @@ use crate::attributes::lint_helpers::{
};
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
use crate::attributes::macro_attrs::{
AllowInternalUnsafeParser, MacroEscapeParser, MacroUseParser,
AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser,
};
use crate::attributes::must_use::MustUseParser;
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
@ -183,6 +183,7 @@ attribute_parsers!(
Single<LinkOrdinalParser>,
Single<LinkSectionParser>,
Single<LinkageParser>,
Single<MacroExportParser>,
Single<MoveSizeLimitParser>,
Single<MustUseParser>,
Single<ObjcClassParser>,

View file

@ -31,6 +31,18 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emi
},
);
}
AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter
.emit_node_span_lint(
rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS,
*id,
*span,
session_diagnostics::IllFormedAttributeInput {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
),
},
),
AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
*id,

View file

@ -942,9 +942,9 @@ impl SyntaxExtension {
.unwrap_or_default();
let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe(_));
let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
.and_then(|macro_export| macro_export.meta_item_list())
.is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
let local_inner_macros =
*find_attr!(attrs, AttributeKind::MacroExport {local_inner_macros: l, ..} => l)
.unwrap_or(&false);
let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);

View file

@ -551,6 +551,9 @@ pub enum AttributeKind {
/// Represents `#[macro_escape]`.
MacroEscape(Span),
/// Represents [`#[macro_export]`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path).
MacroExport { span: Span, local_inner_macros: bool },
/// Represents `#[rustc_macro_transparency]`.
MacroTransparency(Transparency),

View file

@ -56,6 +56,7 @@ impl AttributeKind {
Linkage(..) => No,
LoopMatch(..) => No,
MacroEscape(..) => No,
MacroExport { .. } => Yes,
MacroTransparency(..) => Yes,
MacroUse { .. } => No,
Marker(..) => No,

View file

@ -31,9 +31,34 @@ pub struct AttributeLint<Id> {
#[derive(Clone, Debug, HashStable_Generic)]
pub enum AttributeLintKind {
UnusedDuplicate { this: Span, other: Span, warning: bool },
IllFormedAttributeInput { suggestions: Vec<String> },
EmptyAttribute { first_span: Span },
InvalidTarget { name: AttrPath, target: Target, applied: Vec<String>, only: &'static str },
InvalidStyle { name: AttrPath, is_used_as_inner: bool, target: Target, target_span: Span },
UnusedDuplicate {
this: Span,
other: Span,
warning: bool,
},
IllFormedAttributeInput {
suggestions: Vec<String>,
},
EmptyAttribute {
first_span: Span,
},
/// Copy of `IllFormedAttributeInput`
/// specifically for the `invalid_macro_export_arguments` lint until that is removed,
/// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
InvalidMacroExportArguments {
suggestions: Vec<String>,
},
InvalidTarget {
name: AttrPath,
target: Target,
applied: Vec<String>,
only: &'static str,
},
InvalidStyle {
name: AttrPath,
is_used_as_inner: bool,
target: Target,
target_span: Span,
},
}

View file

@ -1,11 +1,12 @@
use rustc_errors::MultiSpan;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind};
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind, find_attr};
use rustc_middle::ty::TyCtxt;
use rustc_session::{declare_lint, impl_lint_pass};
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::{ExpnKind, Span, kw, sym};
use rustc_span::{ExpnKind, Span, kw};
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
@ -241,7 +242,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
)
}
ItemKind::Macro(_, _macro, _kinds)
if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
if find_attr!(
cx.tcx.get_all_attrs(item.owner_id.def_id),
AttributeKind::MacroExport { .. }
) =>
{
cx.emit_span_lint(
NON_LOCAL_DEFINITIONS,

View file

@ -4191,8 +4191,13 @@ declare_lint! {
/// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`.
///
pub INVALID_MACRO_EXPORT_ARGUMENTS,
Warn,
Deny,
"\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseError,
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
report_in_deps: true,
};
}
declare_lint! {

View file

@ -349,10 +349,6 @@ passes_invalid_attr_at_crate_level =
passes_invalid_attr_at_crate_level_item =
the inner attribute doesn't annotate this {$kind}
passes_invalid_macro_export_arguments = invalid `#[macro_export]` argument
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
passes_lang_item_fn = {$name ->
[panic_impl] `#[panic_handler]`
*[other] `{$name}` lang item
@ -392,9 +388,6 @@ passes_loop_match_attr =
`#[loop_match]` should be applied to a loop
.label = not a loop
passes_macro_export =
`#[macro_export]` only has an effect on macro definitions
passes_macro_export_on_decl_macro =
`#[macro_export]` has no effect on declarative macro definitions
.note = declarative macros follow the same exporting rules as regular items

View file

@ -38,8 +38,8 @@ use rustc_middle::{bug, span_bug};
use rustc_session::config::CrateType;
use rustc_session::lint;
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
};
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
@ -217,7 +217,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
},
Attribute::Parsed(AttributeKind::Link(_, attr_span)) => {
self.check_link(hir_id, *attr_span, span, target)
}
},
Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => {
self.check_macro_export(hir_id, *span, target)
},
Attribute::Parsed(
AttributeKind::BodyStability { .. }
| AttributeKind::ConstStabilityIndirect
@ -331,7 +334,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::rustc_has_incoherent_inherent_impls, ..] => {
self.check_has_incoherent_inherent_impls(attr, span, target)
}
[sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
[sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
self.check_autodiff(hir_id, attr, span, target)
}
@ -1850,45 +1852,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
fn check_macro_export(&self, hir_id: HirId, attr_span: Span, target: Target) {
if target != Target::MacroDef {
return;
}
// special case when `#[macro_export]` is applied to a macro 2.0
let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
let is_decl_macro = !macro_definition.macro_rules;
if is_decl_macro {
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span(),
errors::MacroExport::Normal,
attr_span,
errors::MacroExport::OnDeclMacro,
);
} else if let Some(meta_item_list) = attr.meta_item_list()
&& !meta_item_list.is_empty()
{
if meta_item_list.len() > 1 {
self.tcx.emit_node_span_lint(
INVALID_MACRO_EXPORT_ARGUMENTS,
hir_id,
attr.span(),
errors::MacroExport::TooManyItems,
);
} else if !meta_item_list[0].has_name(sym::local_inner_macros) {
self.tcx.emit_node_span_lint(
INVALID_MACRO_EXPORT_ARGUMENTS,
hir_id,
meta_item_list[0].span(),
errors::MacroExport::InvalidArgument,
);
}
} else {
// special case when `#[macro_export]` is applied to a macro 2.0
let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
let is_decl_macro = !macro_definition.macro_rules;
if is_decl_macro {
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span(),
errors::MacroExport::OnDeclMacro,
);
}
}
}
@ -2253,7 +2232,9 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
// In the long run, the checks should be harmonized.
if let ItemKind::Macro(_, macro_def, _) = item.kind {
let def_id = item.owner_id.to_def_id();
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
if macro_def.macro_rules
&& !find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. })
{
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
}
}
@ -2384,7 +2365,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
// which were unsuccessfully resolved due to cannot determine
// resolution for the attribute macro error.
const ATTRS_TO_CHECK: &[Symbol] = &[
sym::macro_export,
sym::rustc_main,
sym::derive,
sym::test,

View file

@ -530,18 +530,9 @@ pub(crate) struct RustcForceInlineCoro {
#[derive(LintDiagnostic)]
pub(crate) enum MacroExport {
#[diag(passes_macro_export)]
Normal,
#[diag(passes_macro_export_on_decl_macro)]
#[note]
OnDeclMacro,
#[diag(passes_invalid_macro_export_arguments)]
InvalidArgument,
#[diag(passes_invalid_macro_export_arguments_too_many_items)]
TooManyItems,
}
#[derive(Subdiagnostic)]

View file

@ -11,6 +11,38 @@ fn bool_() {
assert_eq!(a.compare_exchange(false, true, SeqCst, SeqCst), Ok(false));
}
#[test]
#[should_panic = "there is no such thing as an acquire store"]
fn store_illegal_rt_store_acquire_ordering() {
let a = AtomicBool::new(false);
let ord = Ordering::Acquire;
a.store(true, ord);
}
#[test]
#[should_panic = "there is no such thing as an acquire-release store"]
fn store_illegal_rt_store_acq_rel_ordering() {
let a = AtomicBool::new(false);
let ord = Ordering::AcqRel;
a.store(true, ord);
}
#[test]
#[should_panic = "there is no such thing as a release load"]
fn store_illegal_rt_load_release_ordering() {
let a = AtomicBool::new(false);
let ord = Ordering::Release;
a.load(ord);
}
#[test]
#[should_panic = "there is no such thing as an acquire-release load"]
fn store_illegal_rt_load_acq_rel_ordering() {
let a = AtomicBool::new(false);
let ord = Ordering::AcqRel;
a.load(ord);
}
#[test]
fn bool_and() {
let a = AtomicBool::new(true);
@ -283,25 +315,229 @@ fn atomic_compare_exchange() {
static ATOMIC: AtomicIsize = AtomicIsize::new(0);
ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, Relaxed, Acquire).ok();
ATOMIC.compare_exchange(0, 1, Relaxed, SeqCst).ok();
ATOMIC.compare_exchange(0, 1, Acquire, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, Release, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok();
ATOMIC.compare_exchange(0, 1, Acquire, SeqCst).ok();
ATOMIC.compare_exchange(0, 1, Release, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, Release, Acquire).ok();
ATOMIC.compare_exchange(0, 1, Release, SeqCst).ok();
ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok();
ATOMIC.compare_exchange(0, 1, AcqRel, SeqCst).ok();
ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok();
ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok();
ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok();
ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, Relaxed, Acquire).ok();
ATOMIC.compare_exchange_weak(0, 1, Relaxed, SeqCst).ok();
ATOMIC.compare_exchange_weak(0, 1, Acquire, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok();
ATOMIC.compare_exchange_weak(0, 1, Acquire, SeqCst).ok();
ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, Release, Acquire).ok();
ATOMIC.compare_exchange_weak(0, 1, Release, SeqCst).ok();
ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok();
ATOMIC.compare_exchange_weak(0, 1, AcqRel, SeqCst).ok();
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok();
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok();
ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok();
}
#[test]
#[should_panic = "there is no such thing as an acquire-release failure ordering"]
fn atomic_compare_exchange_illegal_acq_rel() {
use Ordering::*;
static ATOMIC: AtomicIsize = AtomicIsize::new(0);
let failure = AcqRel;
ATOMIC.compare_exchange(0, 1, Relaxed, failure).ok();
}
#[test]
#[should_panic = "there is no such thing as a release failure ordering"]
fn atomic_compare_exchange_illegal_release() {
use Ordering::*;
static ATOMIC: AtomicIsize = AtomicIsize::new(0);
let failure = Release;
ATOMIC.compare_exchange(0, 1, Relaxed, failure).ok();
}
#[test]
#[should_panic = "there is no such thing as an acquire-release failure ordering"]
fn atomic_compare_exchange_weak_illegal_acq_rel() {
use Ordering::*;
static ATOMIC: AtomicIsize = AtomicIsize::new(0);
let failure = AcqRel;
ATOMIC.compare_exchange_weak(0, 1, Relaxed, failure).ok();
}
#[test]
#[should_panic = "there is no such thing as a release failure ordering"]
fn atomic_compare_exchange_weak_illegal_release() {
use Ordering::*;
static ATOMIC: AtomicIsize = AtomicIsize::new(0);
let failure = Release;
ATOMIC.compare_exchange_weak(0, 1, Relaxed, failure).ok();
}
#[test]
fn atomic_swap() {
use Ordering::*;
static ATOMIC: AtomicBool = AtomicBool::new(false);
assert_eq!(ATOMIC.swap(true, Relaxed), false);
assert_eq!(ATOMIC.swap(false, Acquire), true);
assert_eq!(ATOMIC.swap(true, Release), false);
assert_eq!(ATOMIC.swap(false, AcqRel), true);
assert_eq!(ATOMIC.swap(true, SeqCst), false);
}
#[test]
fn atomic_add() {
use Ordering::*;
static ATOMIC: AtomicU8 = AtomicU8::new(0);
assert_eq!(ATOMIC.fetch_add(1, Relaxed), 0);
assert_eq!(ATOMIC.fetch_add(1, Acquire), 1);
assert_eq!(ATOMIC.fetch_add(1, Release), 2);
assert_eq!(ATOMIC.fetch_add(1, AcqRel), 3);
assert_eq!(ATOMIC.fetch_add(1, SeqCst), 4);
assert_eq!(ATOMIC.load(Relaxed), 5);
}
#[test]
fn atomic_sub() {
use Ordering::*;
static ATOMIC: AtomicU8 = AtomicU8::new(5);
assert_eq!(ATOMIC.fetch_sub(1, Relaxed), 5);
assert_eq!(ATOMIC.fetch_sub(1, Acquire), 4);
assert_eq!(ATOMIC.fetch_sub(1, Release), 3);
assert_eq!(ATOMIC.fetch_sub(1, AcqRel), 2);
assert_eq!(ATOMIC.fetch_sub(1, SeqCst), 1);
assert_eq!(ATOMIC.load(Relaxed), 0);
}
#[test]
fn atomic_and_or() {
use Ordering::*;
static ATOMIC: AtomicBool = AtomicBool::new(false);
assert_eq!(ATOMIC.fetch_or(true, Relaxed), false);
assert_eq!(ATOMIC.fetch_and(false, Relaxed), true);
assert_eq!(ATOMIC.fetch_or(true, Acquire), false);
assert_eq!(ATOMIC.fetch_and(false, Acquire), true);
assert_eq!(ATOMIC.fetch_or(true, Release), false);
assert_eq!(ATOMIC.fetch_and(false, Release), true);
assert_eq!(ATOMIC.fetch_or(true, AcqRel), false);
assert_eq!(ATOMIC.fetch_and(false, AcqRel), true);
assert_eq!(ATOMIC.fetch_or(true, SeqCst), false);
assert_eq!(ATOMIC.fetch_and(false, SeqCst), true);
assert_eq!(ATOMIC.load(Relaxed), false);
}
#[test]
fn atomic_nand() {
use Ordering::*;
static ATOMIC: AtomicU8 = AtomicU8::new(0x13);
assert_eq!(ATOMIC.fetch_nand(0x13, Relaxed), 0x13);
assert_eq!(ATOMIC.fetch_nand(0xec, Acquire), 0xec);
assert_eq!(ATOMIC.fetch_nand(0x13, Release), 0x13);
assert_eq!(ATOMIC.fetch_nand(0xec, AcqRel), 0xec);
assert_eq!(ATOMIC.fetch_nand(0x13, SeqCst), 0x13);
assert_eq!(ATOMIC.load(Relaxed), 0xec);
}
#[test]
fn atomic_xor() {
use Ordering::*;
static ATOMIC: AtomicBool = AtomicBool::new(false);
assert_eq!(ATOMIC.fetch_xor(true, Relaxed), false);
assert_eq!(ATOMIC.fetch_xor(true, Acquire), true);
assert_eq!(ATOMIC.fetch_xor(true, Release), false);
assert_eq!(ATOMIC.fetch_xor(true, AcqRel), true);
assert_eq!(ATOMIC.fetch_xor(true, SeqCst), false);
assert_eq!(ATOMIC.load(Relaxed), true);
}
#[test]
fn atomic_max() {
use Ordering::*;
static ATOMIC: AtomicI8 = AtomicI8::new(0);
assert_eq!(ATOMIC.fetch_max(1, Relaxed), 0);
assert_eq!(ATOMIC.fetch_max(2, Acquire), 1);
assert_eq!(ATOMIC.fetch_max(3, Release), 2);
assert_eq!(ATOMIC.fetch_max(4, AcqRel), 3);
assert_eq!(ATOMIC.fetch_max(5, SeqCst), 4);
assert_eq!(ATOMIC.load(Relaxed), 5);
}
#[test]
fn atomic_umax() {
use Ordering::*;
static ATOMIC: AtomicU8 = AtomicU8::new(0);
assert_eq!(ATOMIC.fetch_max(1, Relaxed), 0);
assert_eq!(ATOMIC.fetch_max(2, Acquire), 1);
assert_eq!(ATOMIC.fetch_max(3, Release), 2);
assert_eq!(ATOMIC.fetch_max(4, AcqRel), 3);
assert_eq!(ATOMIC.fetch_max(5, SeqCst), 4);
assert_eq!(ATOMIC.load(Relaxed), 5);
}
#[test]
fn atomic_min() {
use Ordering::*;
static ATOMIC: AtomicI8 = AtomicI8::new(5);
assert_eq!(ATOMIC.fetch_min(4, Relaxed), 5);
assert_eq!(ATOMIC.fetch_min(3, Acquire), 4);
assert_eq!(ATOMIC.fetch_min(2, Release), 3);
assert_eq!(ATOMIC.fetch_min(1, AcqRel), 2);
assert_eq!(ATOMIC.fetch_min(0, SeqCst), 1);
assert_eq!(ATOMIC.load(Relaxed), 0);
}
#[test]
fn atomic_umin() {
use Ordering::*;
static ATOMIC: AtomicU8 = AtomicU8::new(5);
assert_eq!(ATOMIC.fetch_min(4, Relaxed), 5);
assert_eq!(ATOMIC.fetch_min(3, Acquire), 4);
assert_eq!(ATOMIC.fetch_min(2, Release), 3);
assert_eq!(ATOMIC.fetch_min(1, AcqRel), 2);
assert_eq!(ATOMIC.fetch_min(0, SeqCst), 1);
assert_eq!(ATOMIC.load(Relaxed), 0);
}
/* FIXME(#110395)
#[test]
fn atomic_const_from() {

View file

@ -268,8 +268,8 @@ impl AsInner<imp::Process> for Child {
}
}
impl FromInner<(imp::Process, imp::StdioPipes)> for Child {
fn from_inner((handle, io): (imp::Process, imp::StdioPipes)) -> Child {
impl FromInner<(imp::Process, StdioPipes)> for Child {
fn from_inner((handle, io): (imp::Process, StdioPipes)) -> Child {
Child {
handle,
stdin: io.stdin.map(ChildStdin::from_inner),
@ -296,6 +296,15 @@ impl fmt::Debug for Child {
}
}
/// The pipes connected to a spawned process.
///
/// Used to pass pipe handles between this module and [`imp`].
pub(crate) struct StdioPipes {
pub stdin: Option<AnonPipe>,
pub stdout: Option<AnonPipe>,
pub stderr: Option<AnonPipe>,
}
/// A handle to a child process's standard input (stdin).
///
/// This struct is used in the [`stdin`] field on [`Child`].

View file

@ -24,7 +24,7 @@ mod env;
pub use env::CommandEnvs;
pub use imp::{
Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes,
Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio,
};
#[cfg(any(

View file

@ -6,6 +6,7 @@ pub use crate::ffi::OsString as EnvKey;
use crate::ffi::{OsStr, OsString};
use crate::num::{NonZero, NonZeroI32};
use crate::path::Path;
use crate::process::StdioPipes;
use crate::sys::fs::File;
use crate::sys::pal::helpers;
use crate::sys::pal::os::error_string;
@ -27,14 +28,6 @@ pub struct Command {
env: CommandEnv,
}
// passed back to std::process with the pipes connected to the child, if any
// were requested
pub struct StdioPipes {
pub stdin: Option<AnonPipe>,
pub stdout: Option<AnonPipe>,
pub stderr: Option<AnonPipe>,
}
#[derive(Copy, Clone, Debug)]
pub enum Stdio {
Inherit,

View file

@ -9,6 +9,7 @@ use crate::collections::BTreeMap;
use crate::ffi::{CStr, CString, OsStr, OsString};
use crate::os::unix::prelude::*;
use crate::path::Path;
use crate::process::StdioPipes;
use crate::sys::fd::FileDesc;
use crate::sys::fs::File;
#[cfg(not(target_os = "fuchsia"))]
@ -104,14 +105,6 @@ pub struct Command {
setsid: bool,
}
// passed back to std::process with the pipes connected to the child, if any
// were requested
pub struct StdioPipes {
pub stdin: Option<AnonPipe>,
pub stdout: Option<AnonPipe>,
pub stderr: Option<AnonPipe>,
}
// passed to do_exec() with configuration of what the child stdio should look
// like
#[cfg_attr(target_os = "vita", allow(dead_code))]

View file

@ -2,6 +2,7 @@ use libc::{c_int, size_t};
use super::common::*;
use crate::num::NonZero;
use crate::process::StdioPipes;
use crate::sys::pal::fuchsia::*;
use crate::{fmt, io, mem, ptr};

View file

@ -23,5 +23,5 @@ cfg_select! {
pub use imp::{ExitStatus, ExitStatusError, Process};
pub use self::common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes};
pub use self::common::{Command, CommandArgs, ExitCode, Stdio};
pub use crate::ffi::OsString as EnvKey;

View file

@ -13,6 +13,7 @@ use libc::{gid_t, uid_t};
use super::common::*;
use crate::io::{self, Error, ErrorKind};
use crate::num::NonZero;
use crate::process::StdioPipes;
use crate::sys::cvt;
#[cfg(target_os = "linux")]
use crate::sys::pal::linux::pidfd::PidFd;

View file

@ -3,6 +3,7 @@ use libc::{c_int, pid_t};
use super::common::*;
use crate::io;
use crate::num::NonZero;
use crate::process::StdioPipes;
use crate::sys::pal::unsupported::*;
////////////////////////////////////////////////////////////////////////////////

View file

@ -4,6 +4,7 @@ use libc::{self, RTP_ID, c_char, c_int};
use super::common::*;
use crate::io::{self, ErrorKind};
use crate::num::NonZero;
use crate::process::StdioPipes;
use crate::sys::{cvt, thread};
use crate::{fmt, sys};

View file

@ -3,6 +3,7 @@ pub use crate::ffi::OsString as EnvKey;
use crate::ffi::{OsStr, OsString};
use crate::num::NonZero;
use crate::path::Path;
use crate::process::StdioPipes;
use crate::sys::fs::File;
use crate::sys::pipe::AnonPipe;
use crate::sys::unsupported;
@ -23,14 +24,6 @@ pub struct Command {
stderr: Option<Stdio>,
}
// passed back to std::process with the pipes connected to the child, if any
// were requested
pub struct StdioPipes {
pub stdin: Option<AnonPipe>,
pub stdout: Option<AnonPipe>,
pub stderr: Option<AnonPipe>,
}
#[derive(Debug)]
pub enum Stdio {
Inherit,

View file

@ -15,6 +15,7 @@ use crate::os::windows::ffi::{OsStrExt, OsStringExt};
use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle};
use crate::os::windows::process::ProcThreadAttributeList;
use crate::path::{Path, PathBuf};
use crate::process::StdioPipes;
use crate::sync::Mutex;
use crate::sys::args::{self, Arg};
use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS};
@ -169,12 +170,6 @@ pub enum Stdio {
Handle(Handle),
}
pub struct StdioPipes {
pub stdin: Option<AnonPipe>,
pub stdout: Option<AnonPipe>,
pub stderr: Option<AnonPipe>,
}
impl Command {
pub fn new(program: &OsStr) -> Command {
Command {

View file

@ -30,3 +30,10 @@ cat /tmp/toolstate/toolstates.json
python3 "$X_PY" test --stage 2 check-tools
python3 "$X_PY" test --stage 2 src/tools/clippy
python3 "$X_PY" test --stage 2 src/tools/rustfmt
# The below is a regression test for https://github.com/rust-lang/rust/pull/146501#issuecomment-3292608398.
# The bug caused 0 tests to run. By grepping on that 1 test is run we prevent regressing.
# Any test can be used. We arbitrarily chose `tests/ui/lint/unused/unused-result.rs`.
python3 "$X_PY" test tests/ui --test-args tests/ui/lint/unused/unused-result.rs --force-rerun |
grep --fixed-strings 'test result: ok. 1 passed; 0 failed; 0 ignored;' ||
( echo "ERROR: --test-args functionality is broken" && exit 1 )

View file

@ -6,6 +6,8 @@ use std::path::Path;
use rustc_ast::join_path_syms;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::find_attr;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId;
use rustc_span::sym;
@ -1458,16 +1460,17 @@ pub(crate) fn build_index(
if fqp.last() != Some(&item.name) {
return None;
}
let path =
if item.ty == ItemType::Macro && tcx.has_attr(defid, sym::macro_export) {
// `#[macro_export]` always exports to the crate root.
vec![tcx.crate_name(defid.krate)]
} else {
if fqp.len() < 2 {
return None;
}
fqp[..fqp.len() - 1].to_vec()
};
let path = if item.ty == ItemType::Macro
&& find_attr!(tcx.get_all_attrs(defid), AttributeKind::MacroExport { .. })
{
// `#[macro_export]` always exports to the crate root.
vec![tcx.crate_name(defid.krate)]
} else {
if fqp.len() < 2 {
return None;
}
fqp[..fqp.len() - 1].to_vec()
};
if path == item.module_path {
return None;
}

View file

@ -912,12 +912,8 @@ fn maybe_from_hir_attr(
hir::Attribute::Parsed(kind) => kind,
hir::Attribute::Unparsed(_) => {
return Some(if attr.has_name(sym::macro_export) {
Attribute::MacroExport
// FIXME: We should handle `#[doc(hidden)]`.
} else {
other_attr(tcx, attr)
});
// FIXME: We should handle `#[doc(hidden)]`.
return Some(other_attr(tcx, attr));
}
};
@ -925,6 +921,7 @@ fn maybe_from_hir_attr(
AK::Deprecation { .. } => return None, // Handled separately into Item::deprecation.
AK::DocComment { .. } => unreachable!("doc comments stripped out earlier"),
AK::MacroExport { .. } => Attribute::MacroExport,
AK::MustUse { reason, span: _ } => {
Attribute::MustUse { reason: reason.map(|s| s.to_string()) }
}

View file

@ -2,9 +2,10 @@
use std::mem;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::find_attr;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
use tracing::debug;
use crate::clean::utils::inherits_doc_hidden;
@ -114,7 +115,7 @@ impl DocFolder for Stripper<'_, '_> {
// If the macro has the `#[macro_export]` attribute, it means it's accessible at the
// crate level so it should be handled differently.
clean::MacroItem(..) => {
i.attrs.other_attrs.iter().any(|attr| attr.has_name(sym::macro_export))
find_attr!(&i.attrs.other_attrs, AttributeKind::MacroExport { .. })
}
_ => false,
};

View file

@ -5,10 +5,11 @@ use std::mem;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, MacroKinds, Res};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
use rustc_hir::intravisit::{Visitor, walk_body, walk_item};
use rustc_hir::{CRATE_HIR_ID, Node};
use rustc_hir::{CRATE_HIR_ID, Node, find_attr};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;
@ -166,7 +167,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if !child.reexport_chain.is_empty()
&& let Res::Def(DefKind::Macro(_), def_id) = child.res
&& let Some(local_def_id) = def_id.as_local()
&& self.cx.tcx.has_attr(def_id, sym::macro_export)
&& find_attr!(self.cx.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. })
&& inserted.insert(def_id)
{
let item = self.cx.tcx.hir_expect_item(local_def_id);
@ -406,7 +407,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|| match item.kind {
hir::ItemKind::Impl(..) => true,
hir::ItemKind::Macro(_, _, _) => {
self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export)
find_attr!(self.cx.tcx.get_all_attrs(item.owner_id.def_id), AttributeKind::MacroExport{..})
}
_ => false,
}
@ -524,7 +525,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let def_id = item.owner_id.to_def_id();
let is_macro_2_0 = !macro_def.macro_rules;
let nonexported = !tcx.has_attr(def_id, sym::macro_export);
let nonexported =
!find_attr!(tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. });
if is_macro_2_0 || nonexported || self.inlining {
self.add_to_current_mod(item, renamed, import_id);

View file

@ -5,10 +5,12 @@ use itertools::Itertools;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
use rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::find_attr;
use rustc_lint::{LateContext, LateLintPass, Level, LintContext};
use rustc_middle::lint::LevelAndSource;
use rustc_session::impl_lint_pass;
use rustc_span::{Span, SyntaxContext, sym};
use rustc_span::{Span, SyntaxContext};
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
@ -146,7 +148,8 @@ struct BodyVisitor<'a, 'tcx> {
}
fn is_public_macro(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
(cx.effective_visibilities.is_exported(def_id) || cx.tcx.has_attr(def_id, sym::macro_export))
( cx.effective_visibilities.is_exported(def_id) ||
find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::MacroExport{..}) )
&& !cx.tcx.is_doc_hidden(def_id)
}

View file

@ -0,0 +1,40 @@
Future incompatibility report: Future breakage diagnostic:
warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:7:1
|
LL | #[macro_export(hello, world)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
Future breakage diagnostic:
warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:14:1
|
LL | #[macro_export(not_local_inner_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
Future breakage diagnostic:
warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:31:1
|
LL | #[macro_export()]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
Future breakage diagnostic:
warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:38:1
|
LL | #[macro_export("blah")]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>

View file

@ -1,26 +1,103 @@
error: `#[macro_export]` can only take 1 or 0 arguments
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:7:1
|
LL | #[macro_export(hello, world)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
note: the lint level is defined here
--> $DIR/invalid_macro_export_argument.rs:4:24
|
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid `#[macro_export]` argument
--> $DIR/invalid_macro_export_argument.rs:13:16
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:14:1
|
LL | #[macro_export(not_local_inner_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
error: invalid `#[macro_export]` argument
--> $DIR/invalid_macro_export_argument.rs:33:16
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:31:1
|
LL | #[macro_export()]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:38:1
|
LL | #[macro_export("blah")]
| ^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
error: aborting due to 3 previous errors
error: aborting due to 4 previous errors
Future incompatibility report: Future breakage diagnostic:
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:7:1
|
LL | #[macro_export(hello, world)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
note: the lint level is defined here
--> $DIR/invalid_macro_export_argument.rs:4:24
|
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:14:1
|
LL | #[macro_export(not_local_inner_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
note: the lint level is defined here
--> $DIR/invalid_macro_export_argument.rs:4:24
|
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:31:1
|
LL | #[macro_export()]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
note: the lint level is defined here
--> $DIR/invalid_macro_export_argument.rs:4:24
|
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/invalid_macro_export_argument.rs:38:1
|
LL | #[macro_export("blah")]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
note: the lint level is defined here
--> $DIR/invalid_macro_export_argument.rs:4:24
|
LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -5,13 +5,15 @@
#![cfg_attr(allow, allow(invalid_macro_export_arguments))]
#[macro_export(hello, world)]
//[deny]~^ ERROR `#[macro_export]` can only take 1 or 0 arguments
//[deny]~^ ERROR valid forms for the attribute are
//[deny]~| WARN this was previously accepted
macro_rules! a {
() => ()
}
#[macro_export(not_local_inner_macros)]
//[deny]~^ ERROR invalid `#[macro_export]` argument
//[deny]~^ ERROR valid forms for the attribute are
//[deny]~| WARN this was previously accepted
macro_rules! b {
() => ()
}
@ -20,18 +22,22 @@ macro_rules! b {
macro_rules! c {
() => ()
}
#[macro_export(local_inner_macros)]
macro_rules! d {
() => ()
}
#[macro_export()]
//[deny]~^ ERROR valid forms for the attribute are
//[deny]~| WARN this was previously accepted
macro_rules! e {
() => ()
}
#[macro_export("blah")]
//[deny]~^ ERROR invalid `#[macro_export]` argument
//[deny]~^ ERROR valid forms for the attribute are
//[deny]~| WARN this was previously accepted
macro_rules! f {
() => ()
}

View file

@ -211,7 +211,7 @@ extern crate wloop;
//~^ ERROR can't find crate for `wloop` [E0463]
#[macro_export = 18]
//~^ ERROR malformed `macro_export` attribute input
//~^ ERROR valid forms for the attribute are
#[allow_internal_unsafe = 1]
//~^ ERROR malformed
//~| ERROR allow_internal_unsafe side-steps the unsafe_code lint

View file

@ -178,22 +178,6 @@ LL | #[no_link()]
|
= note: for more information, visit <https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute>
error: malformed `macro_export` attribute input
--> $DIR/malformed-attrs.rs:213:1
|
LL | #[macro_export = 18]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, visit <https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope>
help: the following are the possible correct uses
|
LL - #[macro_export = 18]
LL + #[macro_export(local_inner_macros)]
|
LL - #[macro_export = 18]
LL + #[macro_export]
|
error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type
--> $DIR/malformed-attrs.rs:98:1
|
@ -725,6 +709,12 @@ error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `
LL | #[macro_use = 1]
| ^^^^^^^^^^^^^^^^
error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]`
--> $DIR/malformed-attrs.rs:213:1
|
LL | #[macro_export = 18]
| ^^^^^^^^^^^^^^^^^^^^
error[E0565]: malformed `allow_internal_unsafe` attribute input
--> $DIR/malformed-attrs.rs:215:1
|

View file

@ -8,7 +8,7 @@
#![macro_export]
//~^ ERROR: `macro_export` attribute cannot be used at crate level
//~^ ERROR: `#[macro_export]` attribute cannot be used on crates
#![rustc_main]
//~^ ERROR: `rustc_main` attribute cannot be used at crate level
//~| ERROR: use of an internal attribute [E0658]
@ -32,7 +32,6 @@
mod inline {
//~^ NOTE the inner attribute doesn't annotate this module
//~| NOTE the inner attribute doesn't annotate this module
//~| NOTE the inner attribute doesn't annotate this module
mod inner { #![inline] }
//~^ ERROR attribute cannot be used on

View file

@ -8,6 +8,14 @@ LL | #![rustc_main]
= note: the `#[rustc_main]` attribute is an internal implementation detail that will never be stable
= note: the `#[rustc_main]` attribute is used internally to specify test entry point function
error: `#[macro_export]` attribute cannot be used on crates
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:10:1
|
LL | #![macro_export]
| ^^^^^^^^^^^^^^^^
|
= help: `#[macro_export]` can only be applied to macro defs
error: `#[path]` attribute cannot be used on crates
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:19:1
|
@ -49,7 +57,7 @@ LL | #[inline]
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:17
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:17
|
LL | mod inner { #![inline] }
| ^^^^^^^^^^
@ -57,7 +65,7 @@ LL | mod inner { #![inline] }
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on structs
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5
|
LL | #[inline] struct S;
| ^^^^^^^^^
@ -65,7 +73,7 @@ LL | #[inline] struct S;
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on type aliases
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:49:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:48:5
|
LL | #[inline] type T = S;
| ^^^^^^^^^
@ -73,7 +81,7 @@ LL | #[inline] type T = S;
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on inherent impl blocks
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:52:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5
|
LL | #[inline] impl S { }
| ^^^^^^^^^
@ -81,7 +89,7 @@ LL | #[inline] impl S { }
= help: `#[inline]` can only be applied to functions
error: `#[export_name]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:82:1
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:81:1
|
LL | #[export_name = "2200"]
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -89,7 +97,7 @@ LL | #[export_name = "2200"]
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:85:17
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:84:17
|
LL | mod inner { #![export_name="2200"] }
| ^^^^^^^^^^^^^^^^^^^^^^
@ -97,7 +105,7 @@ LL | mod inner { #![export_name="2200"] }
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on structs
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:90:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:89:5
|
LL | #[export_name = "2200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -105,7 +113,7 @@ LL | #[export_name = "2200"] struct S;
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on type aliases
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:93:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:92:5
|
LL | #[export_name = "2200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -113,7 +121,7 @@ LL | #[export_name = "2200"] type T = S;
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on inherent impl blocks
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:95:5
|
LL | #[export_name = "2200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -121,7 +129,7 @@ LL | #[export_name = "2200"] impl S { }
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on required trait methods
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:100:9
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:99:9
|
LL | #[export_name = "2200"] fn foo();
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -129,7 +137,7 @@ LL | #[export_name = "2200"] fn foo();
= help: `#[export_name]` can be applied to statics, functions, inherent methods, provided trait methods, and trait methods in impl blocks
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:56:1
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:1
|
LL | #[no_link]
| ^^^^^^^^^^
@ -143,7 +151,7 @@ LL | | }
| |_- not an `extern crate` item
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:107:8
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:8
|
LL | #[repr(C)]
| ^
@ -156,7 +164,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:8
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:130:8
|
LL | #[repr(Rust)]
| ^^^^
@ -174,21 +182,6 @@ error: attribute should be applied to an `extern crate` item
LL | #![no_link]
| ^^^^^^^^^^^ not an `extern crate` item
error: `macro_export` attribute cannot be used at crate level
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:10:1
|
LL | #![macro_export]
| ^^^^^^^^^^^^^^^^
...
LL | mod inline {
| ------ the inner attribute doesn't annotate this module
|
help: perhaps you meant to use an outer attribute
|
LL - #![macro_export]
LL + #[macro_export]
|
error: `rustc_main` attribute cannot be used at crate level
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1
|
@ -220,85 +213,85 @@ LL + #[repr()]
|
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:61:17
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:60:17
|
LL | mod inner { #![no_link] }
| ------------^^^^^^^^^^^-- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:65:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:5
|
LL | #[no_link] fn f() { }
| ^^^^^^^^^^ ---------- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:69:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:68:5
|
LL | #[no_link] struct S;
| ^^^^^^^^^^ --------- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:72:5
|
LL | #[no_link]type T = S;
| ^^^^^^^^^^----------- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:77:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5
|
LL | #[no_link] impl S { }
| ^^^^^^^^^^ ---------- not an `extern crate` item
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:111:25
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:110:25
|
LL | mod inner { #![repr(C)] }
| --------------------^---- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:115:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:114:12
|
LL | #[repr(C)] fn f() { }
| ^ ---------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:120:12
|
LL | #[repr(C)] type T = S;
| ^ ----------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:125:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:124:12
|
LL | #[repr(C)] impl S { }
| ^ ---------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:135:25
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:134:25
|
LL | mod inner { #![repr(Rust)] }
| --------------------^^^^---- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:139:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:138:12
|
LL | #[repr(Rust)] fn f() { }
| ^^^^ ---------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:145:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:144:12
|
LL | #[repr(Rust)] type T = S;
| ^^^^ ----------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:149:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:148:12
|
LL | #[repr(Rust)] impl S { }
| ^^^^ ---------- not a struct, enum, or union
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:40:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:39:5
|
LL | #[inline = "2100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^
@ -313,7 +306,7 @@ Some errors have detailed explanations: E0517, E0658.
For more information about an error, try `rustc --explain E0517`.
Future incompatibility report: Future breakage diagnostic:
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:40:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:39:5
|
LL | #[inline = "2100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^

View file

@ -214,22 +214,40 @@ mod macro_use {
}
#[macro_export]
//~^ WARN `#[macro_export]` only has an effect on macro definitions
//~^ WARN `#[macro_export]` attribute cannot be used on modules [unused_attributes]
//~| WARN previously accepted
//~| HELP can only be applied to
//~| HELP remove the attribute
mod macro_export {
mod inner { #![macro_export] }
//~^ WARN `#[macro_export]` only has an effect on macro definitions
//~^ WARN `#[macro_export]` attribute cannot be used on modules
//~| WARN previously accepted
//~| HELP can only be applied to
//~| HELP remove the attribute
#[macro_export] fn f() { }
//~^ WARN `#[macro_export]` only has an effect on macro definitions
//~^ WARN `#[macro_export]` attribute cannot be used on function
//~| WARN previously accepted
//~| HELP can only be applied to
//~| HELP remove the attribute
#[macro_export] struct S;
//~^ WARN `#[macro_export]` only has an effect on macro definitions
//~^ WARN `#[macro_export]` attribute cannot be used on structs
//~| WARN previously accepted
//~| HELP can only be applied to
//~| HELP remove the attribute
#[macro_export] type T = S;
//~^ WARN `#[macro_export]` only has an effect on macro definitions
//~^ WARN `#[macro_export]` attribute cannot be used on type aliases
//~| WARN previously accepted
//~| HELP can only be applied to
//~| HELP remove the attribute
#[macro_export] impl S { }
//~^ WARN `#[macro_export]` only has an effect on macro definitions
//~^ WARN `#[macro_export]` attribute cannot be used on inherent impl blocks
//~| WARN previously accepted
//~| HELP can only be applied to
//~| HELP remove the attribute
}
// At time of unit test authorship, if compiling without `--test` then

View file

@ -53,18 +53,6 @@ note: attribute also specified here
LL | #![no_builtins]
| ^^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:44:5
|
LL | #[macro_export]
| ^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:43:5
|
LL | #[macro_export]
| ^^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:41:1
|
@ -77,6 +65,18 @@ note: attribute also specified here
LL | #[macro_use]
| ^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:44:5
|
LL | #[macro_export]
| ^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:43:5
|
LL | #[macro_export]
| ^^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:51:1
|