authorbors <bors@rust-lang.org> 2026-06-02 12:44:47 UTC
committerbors <bors@rust-lang.org> 2026-06-02 12:44:47 UTC
log48f976c7131e76b6a1ba6ba316c90d97ffdfe184
treef41d5b39c18777539cb2b583be7c32d865b7f27c
parent4f84d9fac456d973d592cf3fb48db958ecf22506
parentf38205f18d1385e0f53a34f4107a71d070379a98

Auto merge of #157303 - JonathanBrouwer:rollup-EWrtFmY, r=JonathanBrouwer

Rollup of 14 pull requests Successful merges: - rust-lang/rust#156467 (mark the 'import linkage' statics as unnamed_addr) - rust-lang/rust#156923 (Couple of diagnostics improvements for EII) - rust-lang/rust#157240 (Enable Enzyme for aarch64-apple-darwin) - rust-lang/rust#157244 (Privacy: tweak macros + more tests) - rust-lang/rust#157276 (miri subtree update) - rust-lang/rust#157130 (Use a `ArrayVec` in `CastTarget`) - rust-lang/rust#157131 (Add regression test for issue rust-lang/rust#144888) - rust-lang/rust#157195 (Move feature gating to the new attr parsing infrastructure) - rust-lang/rust#157233 (rustdoc: Fix trait impl ordering) - rust-lang/rust#157256 (tests: adapt for LLVM codegen change) - rust-lang/rust#157265 (Update books) - rust-lang/rust#157277 (triagebot.toml: add LawnGnome to libs reviewers) - rust-lang/rust#157291 (Clean up attribute target checking diagnostics) - rust-lang/rust#157301 (Remove unused import from a test)

219 files changed, 4733 insertions(+), 1825 deletions(-)

Cargo.lock+1
......@@ -4756,6 +4756,7 @@ dependencies = [
47564756name = "rustc_target"
47574757version = "0.0.0"
47584758dependencies = [
4759 "arrayvec",
47594760 "bitflags",
47604761 "object 0.37.3",
47614762 "rustc_abi",
compiler/rustc_ast_passes/src/feature_gate.rs+1-10
......@@ -2,7 +2,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
22use rustc_ast::{self as ast, AttrVec, GenericBound, NodeId, PatKind, attr, token};
33use rustc_attr_parsing::AttributeParser;
44use rustc_errors::msg;
5use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
5use rustc_feature::Features;
66use rustc_hir::Attribute;
77use rustc_hir::attrs::AttributeKind;
88use rustc_session::Session;
......@@ -155,15 +155,6 @@ impl<'a> PostExpansionVisitor<'a> {
155155
156156impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
157157 fn visit_attribute(&mut self, attr: &ast::Attribute) {
158 let attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name));
159 // Check feature gates for built-in attributes.
160 if let Some(BuiltinAttribute {
161 gate: AttributeGate::Gated { feature, message, check, notes, .. },
162 ..
163 }) = attr_info
164 {
165 gate_alt!(self, check(self.features), *feature, attr.span, *message, *notes);
166 }
167158 // Check unstable flavors of the `#[doc]` attribute.
168159 if attr.has_name(sym::doc) {
169160 for meta_item_inner in attr.meta_item_list().unwrap_or_default() {
compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs+8-3
......@@ -1,5 +1,7 @@
11use std::iter;
22
3use rustc_feature::AttributeStability;
4
35use super::prelude::*;
46use crate::session_diagnostics;
57
......@@ -16,6 +18,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser {
1618 Warn(Target::Arm),
1719 ]);
1820 const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
21 const STABILITY: AttributeStability = unstable!(allow_internal_unstable);
1922
2023 fn extend(
2124 cx: &mut AcceptContext<'_, '_>,
......@@ -32,6 +35,7 @@ impl CombineAttributeParser for UnstableFeatureBoundParser {
3235 const PATH: &[rustc_span::Symbol] = &[sym::unstable_feature_bound];
3336 type Item = (Symbol, Span);
3437 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableFeatureBound(items);
38 const STABILITY: AttributeStability = unstable!(staged_api);
3539 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
3640 Allow(Target::Fn),
3741 Allow(Target::Impl { of_trait: true }),
......@@ -43,9 +47,6 @@ impl CombineAttributeParser for UnstableFeatureBoundParser {
4347 cx: &mut AcceptContext<'_, '_>,
4448 args: &ArgParser,
4549 ) -> impl IntoIterator<Item = Self::Item> {
46 if !cx.features().staged_api() {
47 cx.emit_err(session_diagnostics::StabilityOutsideStd { span: cx.attr_span });
48 }
4950 parse_unstable(cx, args, <Self as CombineAttributeParser>::PATH[0])
5051 .into_iter()
5152 .zip(iter::repeat(cx.attr_span))
......@@ -65,6 +66,10 @@ impl CombineAttributeParser for RustcAllowConstFnUnstableParser {
6566 Allow(Target::Method(MethodKind::TraitImpl)),
6667 ]);
6768 const TEMPLATE: AttributeTemplate = template!(Word, List: &["feat1, feat2, ..."]);
69 const STABILITY: AttributeStability = unstable!(
70 rustc_attrs,
71 "rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
72 );
6873
6974 fn extend(
7075 cx: &mut AcceptContext<'_, '_>,
compiler/rustc_attr_parsing/src/attributes/autodiff.rs+3-1
......@@ -2,7 +2,7 @@ use std::str::FromStr;
22
33use rustc_ast::LitKind;
44use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
5use rustc_feature::{AttributeTemplate, template};
5use rustc_feature::{AttributeStability, AttributeTemplate, template};
66use rustc_hir::attrs::{AttributeKind, RustcAutodiff};
77use rustc_hir::{MethodKind, Target};
88use rustc_span::{Symbol, sym};
......@@ -13,6 +13,7 @@ use crate::attributes::prelude::Allow;
1313use crate::context::AcceptContext;
1414use crate::parser::{ArgParser, MetaItemOrLitParser};
1515use crate::target_checking::AllowedTargets;
16use crate::unstable;
1617
1718pub(crate) struct RustcAutodiffParser;
1819
......@@ -29,6 +30,7 @@ impl SingleAttributeParser for RustcAutodiffParser {
2930 List: &["MODE", "WIDTH", "INPUT_ACTIVITIES", "OUTPUT_ACTIVITY"],
3031 "https://doc.rust-lang.org/std/autodiff/index.html"
3132 );
33 const STABILITY: AttributeStability = unstable!(rustc_attrs);
3234
3335 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3436 let list = match args {
compiler/rustc_attr_parsing/src/attributes/body.rs+3
......@@ -1,5 +1,7 @@
11//! Attributes that can be found in function body.
22
3use rustc_feature::AttributeStability;
4
35use super::prelude::*;
46
57pub(crate) struct CoroutineParser;
......@@ -7,5 +9,6 @@ pub(crate) struct CoroutineParser;
79impl NoArgsAttributeParser for CoroutineParser {
810 const PATH: &[Symbol] = &[sym::coroutine];
911 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
12 const STABILITY: AttributeStability = unstable!(coroutines);
1013 const CREATE: fn(rustc_span::Span) -> AttributeKind = |_| AttributeKind::Coroutine;
1114}
compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24pub(crate) struct CfiEncodingParser;
35impl SingleAttributeParser for CfiEncodingParser {
......@@ -9,6 +11,7 @@ impl SingleAttributeParser for CfiEncodingParser {
911 Allow(Target::Union),
1012 ]);
1113 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
14 const STABILITY: AttributeStability = unstable!(cfi_encoding);
1215
1316 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1417 let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::cfi_encoding))?;
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+18-3
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
23use rustc_session::errors::feature_err;
34use rustc_span::edition::Edition::Edition2024;
......@@ -22,6 +23,7 @@ impl SingleAttributeParser for OptimizeParser {
2223 Allow(Target::Method(MethodKind::Inherent)),
2324 ]);
2425 const TEMPLATE: AttributeTemplate = template!(List: &["size", "speed", "none"]);
26 const STABILITY: AttributeStability = unstable!(optimize_attribute);
2527
2628 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
2729 let single = cx.expect_single_element_list(args, cx.attr_span)?;
......@@ -54,6 +56,7 @@ impl NoArgsAttributeParser for ColdParser {
5456 Allow(Target::ForeignFn),
5557 Allow(Target::Closure),
5658 ]);
59 const STABILITY: AttributeStability = AttributeStability::Stable;
5760 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Cold;
5861}
5962
......@@ -73,6 +76,7 @@ impl SingleAttributeParser for CoverageParser {
7376 Allow(Target::Crate),
7477 ]);
7578 const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::off, sym::on]);
79 const STABILITY: AttributeStability = unstable!(coverage_attribute);
7680
7781 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
7882 let arg = cx.expect_single_element_list(args, cx.attr_span)?;
......@@ -116,6 +120,7 @@ impl SingleAttributeParser for ExportNameParser {
116120 Warn(Target::MacroCall),
117121 ]);
118122 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
123 const STABILITY: AttributeStability = AttributeStability::Stable;
119124
120125 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
121126 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -143,6 +148,7 @@ impl SingleAttributeParser for RustcObjcClassParser {
143148 const ALLOWED_TARGETS: AllowedTargets =
144149 AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
145150 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName");
151 const STABILITY: AttributeStability = unstable!(rustc_attrs);
146152
147153 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
148154 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -170,6 +176,7 @@ impl SingleAttributeParser for RustcObjcSelectorParser {
170176 const ALLOWED_TARGETS: AllowedTargets =
171177 AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]);
172178 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName");
179 const STABILITY: AttributeStability = unstable!(rustc_attrs);
173180
174181 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
175182 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -197,7 +204,7 @@ pub(crate) struct NakedParser {
197204
198205impl AttributeParser for NakedParser {
199206 const ATTRIBUTES: AcceptMapping<Self> =
200 &[(&[sym::naked], template!(Word), |this, cx, args| {
207 &[(&[sym::naked], template!(Word), AttributeStability::Stable, |this, cx, args| {
201208 let Some(()) = cx.expect_no_args(args) else {
202209 return;
203210 };
......@@ -331,6 +338,7 @@ impl NoArgsAttributeParser for TrackCallerParser {
331338 Warn(Target::Field),
332339 Warn(Target::MacroCall),
333340 ]);
341 const STABILITY: AttributeStability = AttributeStability::Stable;
334342 const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller;
335343}
336344
......@@ -347,6 +355,7 @@ impl NoArgsAttributeParser for NoMangleParser {
347355 AllowSilent(Target::Const), // Handled in the `InvalidNoMangleItems` pass
348356 Error(Target::Closure),
349357 ]);
358 const STABILITY: AttributeStability = AttributeStability::Stable;
350359 const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoMangle;
351360}
352361
......@@ -365,6 +374,7 @@ impl AttributeParser for UsedParser {
365374 const ATTRIBUTES: AcceptMapping<Self> = &[(
366375 &[sym::used],
367376 template!(Word, List: &["compiler", "linker"]),
377 AttributeStability::Stable,
368378 |group: &mut Self, cx, args| {
369379 let used_by = match args {
370380 ArgParser::NoArgs => UsedBy::Default,
......@@ -502,6 +512,7 @@ impl CombineAttributeParser for TargetFeatureParser {
502512 was_forced: false,
503513 };
504514 const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]);
515 const STABILITY: AttributeStability = AttributeStability::Stable;
505516
506517 fn extend(
507518 cx: &mut AcceptContext<'_, '_>,
......@@ -541,6 +552,7 @@ impl CombineAttributeParser for ForceTargetFeatureParser {
541552 Allow(Target::Method(MethodKind::Trait { body: true })),
542553 Allow(Target::Method(MethodKind::TraitImpl)),
543554 ]);
555 const STABILITY: AttributeStability = unstable!(effective_target_features);
544556
545557 fn extend(
546558 cx: &mut AcceptContext<'_, '_>,
......@@ -554,10 +566,8 @@ pub(crate) struct SanitizeParser;
554566
555567impl SingleAttributeParser for SanitizeParser {
556568 const PATH: &[Symbol] = &[sym::sanitize];
557
558569 // FIXME: still checked in check_attrs.rs
559570 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
560
561571 const TEMPLATE: AttributeTemplate = template!(List: &[
562572 r#"address = "on|off""#,
563573 r#"kernel_address = "on|off""#,
......@@ -571,6 +581,7 @@ impl SingleAttributeParser for SanitizeParser {
571581 r#"thread = "on|off""#,
572582 r#"realtime = "nonblocking|blocking|caller""#,
573583 ]);
584 const STABILITY: AttributeStability = unstable!(sanitize);
574585
575586 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
576587 let list = cx.expect_list(args, cx.attr_span)?;
......@@ -667,6 +678,7 @@ impl NoArgsAttributeParser for ThreadLocalParser {
667678 const PATH: &[Symbol] = &[sym::thread_local];
668679 const ALLOWED_TARGETS: AllowedTargets =
669680 AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
681 const STABILITY: AttributeStability = unstable!(thread_local);
670682 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal;
671683}
672684
......@@ -675,6 +687,7 @@ pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser;
675687impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser {
676688 const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis];
677689 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
690 const STABILITY: AttributeStability = unstable!(rustc_attrs);
678691 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis;
679692}
680693
......@@ -684,6 +697,7 @@ impl NoArgsAttributeParser for RustcEiiForeignItemParser {
684697 const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item];
685698 const ALLOWED_TARGETS: AllowedTargets =
686699 AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]);
700 const STABILITY: AttributeStability = unstable!(eii_internals);
687701 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem;
688702}
689703
......@@ -693,6 +707,7 @@ impl SingleAttributeParser for PatchableFunctionEntryParser {
693707 const PATH: &[Symbol] = &[sym::patchable_function_entry];
694708 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
695709 const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
710 const STABILITY: AttributeStability = unstable!(patchable_function_entry);
696711
697712 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
698713 let meta_item_list = cx.expect_list(args, cx.attr_span)?;
compiler/rustc_attr_parsing/src/attributes/confusables.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24use crate::session_diagnostics::EmptyConfusables;
35
......@@ -11,6 +13,7 @@ impl AttributeParser for ConfusablesParser {
1113 const ATTRIBUTES: AcceptMapping<Self> = &[(
1214 &[sym::rustc_confusables],
1315 template!(List: &[r#""name1", "name2", ..."#]),
16 unstable!(rustc_attrs),
1417 |this, cx, args| {
1518 let Some(list) = cx.expect_list(args, cx.attr_span) else { return };
1619
compiler/rustc_attr_parsing/src/attributes/crate_level.rs+24-2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::{CrateType, WindowsSubsystemKind};
23use rustc_session::lint::builtin::UNKNOWN_CRATE_TYPES;
34use rustc_span::Symbol;
......@@ -13,6 +14,7 @@ impl SingleAttributeParser for CrateNameParser {
1314 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
1415 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
1516 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
17 const STABILITY: AttributeStability = AttributeStability::Stable;
1618
1719 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1820 let n = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -29,11 +31,10 @@ impl CombineAttributeParser for CrateTypeParser {
2931 const PATH: &[Symbol] = &[sym::crate_type];
3032 type Item = CrateType;
3133 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::CrateType(items);
32
3334 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
34
3535 const TEMPLATE: AttributeTemplate =
3636 template!(NameValueStr: "crate type", "https://doc.rust-lang.org/reference/linkage.html");
37 const STABILITY: AttributeStability = AttributeStability::Stable;
3738
3839 fn extend(
3940 cx: &mut AcceptContext<'_, '_>,
......@@ -74,6 +75,7 @@ impl SingleAttributeParser for RecursionLimitParser {
7475 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
7576 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute");
7677 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
78 const STABILITY: AttributeStability = AttributeStability::Stable;
7779
7880 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
7981 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -88,6 +90,7 @@ impl SingleAttributeParser for MoveSizeLimitParser {
8890 const PATH: &[Symbol] = &[sym::move_size_limit];
8991 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
9092 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
93 const STABILITY: AttributeStability = unstable!(large_assignments);
9194
9295 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
9396 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -103,6 +106,7 @@ impl SingleAttributeParser for TypeLengthLimitParser {
103106 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
104107 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
105108 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
109 const STABILITY: AttributeStability = AttributeStability::Stable;
106110
107111 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
108112 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -117,6 +121,10 @@ impl SingleAttributeParser for PatternComplexityLimitParser {
117121 const PATH: &[Symbol] = &[sym::pattern_complexity_limit];
118122 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
119123 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
124 const STABILITY: AttributeStability = unstable!(
125 rustc_attrs,
126 "the `#[pattern_complexity_limit]` attribute is used for rustc unit tests"
127 );
120128
121129 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
122130 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -130,6 +138,7 @@ pub(crate) struct NoCoreParser;
130138impl NoArgsAttributeParser for NoCoreParser {
131139 const PATH: &[Symbol] = &[sym::no_core];
132140 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
141 const STABILITY: AttributeStability = unstable!(no_core);
133142 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoCore;
134143}
135144
......@@ -139,6 +148,7 @@ impl NoArgsAttributeParser for NoStdParser {
139148 const PATH: &[Symbol] = &[sym::no_std];
140149 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
141150 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
151 const STABILITY: AttributeStability = AttributeStability::Stable;
142152 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoStd;
143153}
144154
......@@ -148,6 +158,7 @@ impl NoArgsAttributeParser for NoMainParser {
148158 const PATH: &[Symbol] = &[sym::no_main];
149159 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
150160 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
161 const STABILITY: AttributeStability = AttributeStability::Stable;
151162 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain;
152163}
153164
......@@ -156,6 +167,7 @@ pub(crate) struct RustcCoherenceIsCoreParser;
156167impl NoArgsAttributeParser for RustcCoherenceIsCoreParser {
157168 const PATH: &[Symbol] = &[sym::rustc_coherence_is_core];
158169 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
170 const STABILITY: AttributeStability = unstable!(rustc_attrs);
159171 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoherenceIsCore;
160172}
161173
......@@ -166,6 +178,7 @@ impl SingleAttributeParser for WindowsSubsystemParser {
166178 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
167179 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
168180 const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute");
181 const STABILITY: AttributeStability = AttributeStability::Stable;
169182
170183 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
171184 let nv = cx.expect_name_value(args, cx.inner_span, Some(sym::windows_subsystem))?;
......@@ -191,6 +204,7 @@ pub(crate) struct PanicRuntimeParser;
191204impl NoArgsAttributeParser for PanicRuntimeParser {
192205 const PATH: &[Symbol] = &[sym::panic_runtime];
193206 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
207 const STABILITY: AttributeStability = unstable!(panic_runtime);
194208 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PanicRuntime;
195209}
196210
......@@ -199,6 +213,7 @@ pub(crate) struct NeedsPanicRuntimeParser;
199213impl NoArgsAttributeParser for NeedsPanicRuntimeParser {
200214 const PATH: &[Symbol] = &[sym::needs_panic_runtime];
201215 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
216 const STABILITY: AttributeStability = unstable!(needs_panic_runtime);
202217 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsPanicRuntime;
203218}
204219
......@@ -207,6 +222,7 @@ pub(crate) struct ProfilerRuntimeParser;
207222impl NoArgsAttributeParser for ProfilerRuntimeParser {
208223 const PATH: &[Symbol] = &[sym::profiler_runtime];
209224 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
225 const STABILITY: AttributeStability = unstable!(profiler_runtime);
210226 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProfilerRuntime;
211227}
212228
......@@ -216,6 +232,7 @@ impl NoArgsAttributeParser for NoBuiltinsParser {
216232 const PATH: &[Symbol] = &[sym::no_builtins];
217233 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
218234 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
235 const STABILITY: AttributeStability = AttributeStability::Stable;
219236 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoBuiltins;
220237}
221238
......@@ -224,6 +241,7 @@ pub(crate) struct RustcPreserveUbChecksParser;
224241impl NoArgsAttributeParser for RustcPreserveUbChecksParser {
225242 const PATH: &[Symbol] = &[sym::rustc_preserve_ub_checks];
226243 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
244 const STABILITY: AttributeStability = unstable!(rustc_attrs);
227245 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks;
228246}
229247
......@@ -232,6 +250,7 @@ pub(crate) struct RustcNoImplicitBoundsParser;
232250impl NoArgsAttributeParser for RustcNoImplicitBoundsParser {
233251 const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds];
234252 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
253 const STABILITY: AttributeStability = unstable!(rustc_attrs);
235254 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds;
236255}
237256
......@@ -240,6 +259,7 @@ pub(crate) struct DefaultLibAllocatorParser;
240259impl NoArgsAttributeParser for DefaultLibAllocatorParser {
241260 const PATH: &[Symbol] = &[sym::default_lib_allocator];
242261 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
262 const STABILITY: AttributeStability = unstable!(allocator_internals);
243263 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::DefaultLibAllocator;
244264}
245265
......@@ -251,6 +271,7 @@ impl CombineAttributeParser for FeatureParser {
251271 const CONVERT: ConvertFn<Self::Item> = AttributeKind::Feature;
252272 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
253273 const TEMPLATE: AttributeTemplate = template!(List: &["feature1, feature2, ..."]);
274 const STABILITY: AttributeStability = AttributeStability::Stable;
254275
255276 fn extend(
256277 cx: &mut AcceptContext<'_, '_>,
......@@ -295,6 +316,7 @@ impl CombineAttributeParser for RegisterToolParser {
295316 const CONVERT: ConvertFn<Self::Item> = |tools, _span| AttributeKind::RegisterTool(tools);
296317 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
297318 const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]);
319 const STABILITY: AttributeStability = unstable!(register_tool);
298320
299321 fn extend(
300322 cx: &mut AcceptContext<'_, '_>,
compiler/rustc_attr_parsing/src/attributes/debugger.rs+4-2
......@@ -1,10 +1,11 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::{DebugVisualizer, DebuggerVisualizerType};
23
34use super::prelude::*;
45
5pub(crate) struct DebuggerViualizerParser;
6pub(crate) struct DebuggerVisualizerParser;
67
7impl CombineAttributeParser for DebuggerViualizerParser {
8impl CombineAttributeParser for DebuggerVisualizerParser {
89 const PATH: &[Symbol] = &[sym::debugger_visualizer];
910 const ALLOWED_TARGETS: AllowedTargets =
1011 AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]);
......@@ -12,6 +13,7 @@ impl CombineAttributeParser for DebuggerViualizerParser {
1213 List: &[r#"natvis_file = "...", gdb_script_file = "...""#],
1314 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute"
1415 );
16 const STABILITY: AttributeStability = AttributeStability::Stable;
1517
1618 type Item = DebugVisualizer;
1719 const CONVERT: ConvertFn<Self::Item> = |v, _| AttributeKind::DebuggerVisualizer(v);
compiler/rustc_attr_parsing/src/attributes/deprecation.rs+2
......@@ -1,4 +1,5 @@
11use rustc_ast::LitKind;
2use rustc_feature::AttributeStability;
23use rustc_hir::attrs::{DeprecatedSince, Deprecation};
34use rustc_hir::{RustcVersion, VERSION_PLACEHOLDER};
45
......@@ -62,6 +63,7 @@ impl SingleAttributeParser for DeprecatedParser {
6263 List: &[r#"since = "version""#, r#"note = "reason""#, r#"since = "version", note = "reason""#],
6364 NameValueStr: "reason"
6465 );
66 const STABILITY: AttributeStability = AttributeStability::Stable;
6567
6668 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
6769 let features = cx.features();
compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs+2-1
......@@ -1,4 +1,4 @@
1use rustc_feature::{AttributeTemplate, template};
1use rustc_feature::{AttributeStability, AttributeTemplate, template};
22use rustc_hir::Target;
33use rustc_hir::attrs::AttributeKind;
44use rustc_session::lint::builtin::{
......@@ -19,6 +19,7 @@ impl SingleAttributeParser for DoNotRecommendParser {
1919 // "Allowed" on any target, noop on all but trait impls
2020 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
2121 const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */);
22 const STABILITY: AttributeStability = AttributeStability::Stable;
2223
2324 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
2425 let attr_span = cx.attr_span;
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs+2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::diagnostic::Directive;
23use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
34
......@@ -14,6 +15,7 @@ impl AttributeParser for OnConstParser {
1415 const ATTRIBUTES: AcceptMapping<Self> = &[(
1516 &[sym::diagnostic, sym::on_const],
1617 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
18 AttributeStability::Stable, // Unstable, stability checked manually in the parser
1719 |this, cx, args| {
1820 if !cx.features().diagnostic_on_const() {
1921 // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs+2-1
......@@ -1,4 +1,4 @@
1use rustc_feature::template;
1use rustc_feature::{AttributeStability, template};
22use rustc_hir::attrs::AttributeKind;
33use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
44use rustc_span::sym;
......@@ -43,6 +43,7 @@ impl AttributeParser for OnMoveParser {
4343 const ATTRIBUTES: AcceptMapping<Self> = &[(
4444 &[sym::diagnostic, sym::on_move],
4545 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
46 AttributeStability::Stable, // Unstable, stability checked manually in the parser
4647 |this, cx, args| {
4748 this.parse(cx, args, Mode::DiagnosticOnMove);
4849 },
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs+6
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::diagnostic::Directive;
23use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
34
......@@ -38,6 +39,7 @@ impl AttributeParser for OnUnimplementedParser {
3839 (
3940 &[sym::diagnostic, sym::on_unimplemented],
4041 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
42 AttributeStability::Stable,
4143 |this, cx, args| {
4244 this.parse(cx, args, Mode::DiagnosticOnUnimplemented);
4345 },
......@@ -45,6 +47,10 @@ impl AttributeParser for OnUnimplementedParser {
4547 (
4648 &[sym::rustc_on_unimplemented],
4749 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
50 unstable!(
51 rustc_attrs,
52 "see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute"
53 ),
4854 |this, cx, args| {
4955 this.parse(cx, args, Mode::RustcOnUnimplemented);
5056 },
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs+2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::diagnostic::Directive;
23use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
34
......@@ -50,6 +51,7 @@ impl AttributeParser for OnUnknownParser {
5051 const ATTRIBUTES: AcceptMapping<Self> = &[(
5152 &[sym::diagnostic, sym::on_unknown],
5253 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
54 AttributeStability::Stable, // Unstable, stability checked manually in the parser
5355 |this, cx, args| {
5456 this.parse(cx, args, Mode::DiagnosticOnUnknown);
5557 },
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatch_args.rs+2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::diagnostic::Directive;
23use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
34
......@@ -15,6 +16,7 @@ impl AttributeParser for OnUnmatchArgsParser {
1516 const ATTRIBUTES: AcceptMapping<Self> = &[(
1617 &[sym::diagnostic, sym::on_unmatch_args],
1718 template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
19 AttributeStability::Stable, // Unstable, stability checked manually in the parser
1820 |this, cx, args| {
1921 if !cx.features().diagnostic_on_unmatch_args() {
2022 return;
compiler/rustc_attr_parsing/src/attributes/doc.rs+3-2
......@@ -1,6 +1,6 @@
11use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit};
22use rustc_errors::{Applicability, msg};
3use rustc_feature::template;
3use rustc_feature::{AttributeStability, template};
44use rustc_hir::Target;
55use rustc_hir::attrs::{
66 AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow,
......@@ -41,7 +41,7 @@ fn check_keyword(cx: &mut AcceptContext<'_, '_>, keyword: Symbol, span: Span) ->
4141
4242fn check_attribute(cx: &mut AcceptContext<'_, '_>, attribute: Symbol, span: Span) -> bool {
4343 // FIXME: This should support attributes with namespace like `diagnostic::do_not_recommend`.
44 if rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains_key(&attribute) {
44 if rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains(&attribute) {
4545 return true;
4646 }
4747 cx.emit_err(DocAttributeNotAttribute { span, attribute });
......@@ -704,6 +704,7 @@ impl AttributeParser for DocParser {
704704 ],
705705 NameValueStr: "string"
706706 ),
707 AttributeStability::Stable, // Some parts of the attribute are unstable, manually checked in parser
707708 |this, cx, args| {
708709 this.accept_single_doc_attr(cx, args);
709710 },
compiler/rustc_attr_parsing/src/attributes/dummy.rs+4-1
......@@ -1,4 +1,4 @@
1use rustc_feature::{AttributeTemplate, template};
1use rustc_feature::{AttributeStability, AttributeTemplate, template};
22use rustc_hir::attrs::AttributeKind;
33use rustc_span::{Symbol, sym};
44
......@@ -6,6 +6,7 @@ use crate::attributes::{OnDuplicate, SingleAttributeParser};
66use crate::context::AcceptContext;
77use crate::parser::ArgParser;
88use crate::target_checking::{ALL_TARGETS, AllowedTargets};
9use crate::unstable;
910
1011pub(crate) struct RustcDummyParser;
1112impl SingleAttributeParser for RustcDummyParser {
......@@ -13,6 +14,8 @@ impl SingleAttributeParser for RustcDummyParser {
1314 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Ignore;
1415 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
1516 const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
17 const STABILITY: AttributeStability =
18 unstable!(rustc_attrs, "the `#[rustc_dummy]` attribute is used for rustc unit tests");
1619
1720 fn convert(_: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1821 args.ignore_args();
compiler/rustc_attr_parsing/src/attributes/inline.rs+4-1
......@@ -2,6 +2,7 @@
22// note: need to model better how duplicate attr errors work when not using
33// SingleAttributeParser which is what we have two of here.
44
5use rustc_feature::AttributeStability;
56use rustc_hir::attrs::{AttributeKind, InlineAttr};
67use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
78
......@@ -32,6 +33,7 @@ impl SingleAttributeParser for InlineParser {
3233 List: &["always", "never"],
3334 "https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute"
3435 );
36 const STABILITY: AttributeStability = AttributeStability::Stable;
3537
3638 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3739 match args {
......@@ -68,7 +70,8 @@ impl SingleAttributeParser for RustcForceInlineParser {
6870 Allow(Target::Fn),
6971 Allow(Target::Method(MethodKind::Inherent)),
7072 ]);
71
73 const STABILITY: AttributeStability =
74 unstable!(rustc_attrs, "`#[rustc_force_inline]` forces a free function to be inlined");
7275 const TEMPLATE: AttributeTemplate = template!(Word, List: &["reason"], NameValueStr: "reason");
7376
7477 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
compiler/rustc_attr_parsing/src/attributes/instruction_set.rs+2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::InstructionSetAttr;
23
34use super::prelude::*;
......@@ -15,6 +16,7 @@ impl SingleAttributeParser for InstructionSetParser {
1516 Allow(Target::Method(MethodKind::Trait { body: true })),
1617 ]);
1718 const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute");
19 const STABILITY: AttributeStability = AttributeStability::Stable;
1820
1921 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
2022 const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
compiler/rustc_attr_parsing/src/attributes/link_attrs.rs+12-3
......@@ -1,5 +1,5 @@
11use rustc_errors::msg;
2use rustc_feature::Features;
2use rustc_feature::{AttributeStability, Features};
33use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
44use rustc_hir::attrs::*;
55use rustc_session::Session;
......@@ -34,6 +34,7 @@ impl SingleAttributeParser for LinkNameParser {
3434 NameValueStr: "name",
3535 "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute"
3636 );
37 const STABILITY: AttributeStability = AttributeStability::Stable;
3738
3839 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3940 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -70,6 +71,7 @@ impl CombineAttributeParser for LinkParser {
7071 r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
7172 ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute");
7273 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
74 const STABILITY: AttributeStability = AttributeStability::Stable;
7375
7476 fn extend(
7577 cx: &mut AcceptContext<'_, '_>,
......@@ -487,6 +489,7 @@ impl SingleAttributeParser for LinkSectionParser {
487489 const PATH: &[Symbol] = &[sym::link_section];
488490 const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
489491 const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
492 const STABILITY: AttributeStability = AttributeStability::Stable;
490493 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
491494 Allow(Target::Static),
492495 Allow(Target::Fn),
......@@ -529,6 +532,7 @@ pub(crate) struct ExportStableParser;
529532impl NoArgsAttributeParser for ExportStableParser {
530533 const PATH: &[Symbol] = &[sym::export_stable];
531534 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
535 const STABILITY: AttributeStability = unstable!(export_stable);
532536 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
533537}
534538
......@@ -537,6 +541,7 @@ impl NoArgsAttributeParser for FfiConstParser {
537541 const PATH: &[Symbol] = &[sym::ffi_const];
538542 const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
539543 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
544 const STABILITY: AttributeStability = unstable!(ffi_const);
540545 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::FfiConst;
541546}
542547
......@@ -545,6 +550,7 @@ impl NoArgsAttributeParser for FfiPureParser {
545550 const PATH: &[Symbol] = &[sym::ffi_pure];
546551 const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
547552 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
553 const STABILITY: AttributeStability = unstable!(ffi_pure);
548554 const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;
549555}
550556
......@@ -557,6 +563,7 @@ impl NoArgsAttributeParser for RustcStdInternalSymbolParser {
557563 Allow(Target::Static),
558564 Allow(Target::ForeignStatic),
559565 ]);
566 const STABILITY: AttributeStability = unstable!(rustc_attrs);
560567 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcStdInternalSymbol;
561568}
562569
......@@ -573,6 +580,7 @@ impl SingleAttributeParser for LinkOrdinalParser {
573580 List: &["ordinal"],
574581 "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute"
575582 );
583 const STABILITY: AttributeStability = AttributeStability::Stable;
576584
577585 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
578586 let ordinal = parse_single_integer(cx, args)?;
......@@ -603,7 +611,6 @@ pub(crate) struct LinkageParser;
603611
604612impl SingleAttributeParser for LinkageParser {
605613 const PATH: &[Symbol] = &[sym::linkage];
606
607614 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
608615 Allow(Target::Fn),
609616 Allow(Target::Method(MethodKind::Inherent)),
......@@ -614,7 +621,6 @@ impl SingleAttributeParser for LinkageParser {
614621 Allow(Target::ForeignFn),
615622 Warn(Target::Method(MethodKind::Trait { body: false })), // Not inherited
616623 ]);
617
618624 const TEMPLATE: AttributeTemplate = template!(NameValueStr: [
619625 "available_externally",
620626 "common",
......@@ -626,6 +632,7 @@ impl SingleAttributeParser for LinkageParser {
626632 "weak",
627633 "weak_odr",
628634 ]);
635 const STABILITY: AttributeStability = unstable!(linkage);
629636
630637 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
631638 let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::linkage))?;
......@@ -681,6 +688,7 @@ pub(crate) struct NeedsAllocatorParser;
681688impl NoArgsAttributeParser for NeedsAllocatorParser {
682689 const PATH: &[Symbol] = &[sym::needs_allocator];
683690 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
691 const STABILITY: AttributeStability = unstable!(allocator_internals);
684692 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator;
685693}
686694
......@@ -689,5 +697,6 @@ pub(crate) struct CompilerBuiltinsParser;
689697impl NoArgsAttributeParser for CompilerBuiltinsParser {
690698 const PATH: &[Symbol] = &[sym::compiler_builtins];
691699 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
700 const STABILITY: AttributeStability = unstable!(compiler_builtins);
692701 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CompilerBuiltins;
693702}
compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs+7
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct RustcAsPtrParser;
......@@ -10,6 +12,7 @@ impl NoArgsAttributeParser for RustcAsPtrParser {
1012 Allow(Target::Method(MethodKind::Trait { body: true })),
1113 Allow(Target::Method(MethodKind::TraitImpl)),
1214 ]);
15 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1316 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAsPtr;
1417}
1518
......@@ -21,6 +24,7 @@ impl NoArgsAttributeParser for RustcPubTransparentParser {
2124 Allow(Target::Enum),
2225 Allow(Target::Union),
2326 ]);
27 const STABILITY: AttributeStability = unstable!(rustc_attrs);
2428 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPubTransparent;
2529}
2630
......@@ -32,6 +36,7 @@ impl NoArgsAttributeParser for RustcPassByValueParser {
3236 Allow(Target::Enum),
3337 Allow(Target::TyAlias),
3438 ]);
39 const STABILITY: AttributeStability = unstable!(rustc_attrs);
3540 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPassByValue;
3641}
3742
......@@ -42,6 +47,7 @@ impl NoArgsAttributeParser for RustcShouldNotBeCalledOnConstItemsParser {
4247 Allow(Target::Method(MethodKind::Inherent)),
4348 Allow(Target::Method(MethodKind::TraitImpl)),
4449 ]);
50 const STABILITY: AttributeStability = unstable!(rustc_attrs);
4551 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcShouldNotBeCalledOnConstItems;
4652}
4753
......@@ -54,5 +60,6 @@ impl NoArgsAttributeParser for AutomaticallyDerivedParser {
5460 Error(Target::Crate),
5561 Error(Target::WherePredicate),
5662 ]);
63 const STABILITY: AttributeStability = AttributeStability::Stable;
5764 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::AutomaticallyDerived;
5865}
compiler/rustc_attr_parsing/src/attributes/loop_match.rs+4
......@@ -1,9 +1,12 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct LoopMatchParser;
46impl NoArgsAttributeParser for LoopMatchParser {
57 const PATH: &[Symbol] = &[sym::loop_match];
68 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Expression)]);
9 const STABILITY: AttributeStability = unstable!(loop_match);
710 const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch;
811}
912
......@@ -11,5 +14,6 @@ pub(crate) struct ConstContinueParser;
1114impl NoArgsAttributeParser for ConstContinueParser {
1215 const PATH: &[Symbol] = &[sym::const_continue];
1316 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Expression)]);
17 const STABILITY: AttributeStability = unstable!(loop_match);
1418 const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue;
1519}
compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs+7
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::{CollapseMacroDebuginfo, MacroUseArgs};
23use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS;
34
......@@ -8,6 +9,7 @@ impl NoArgsAttributeParser for MacroEscapeParser {
89 const PATH: &[Symbol] = &[sym::macro_escape];
910 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
1011 const ALLOWED_TARGETS: AllowedTargets = MACRO_USE_ALLOWED_TARGETS;
12 const STABILITY: AttributeStability = AttributeStability::Stable;
1113 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::MacroEscape;
1214}
1315
......@@ -41,6 +43,7 @@ impl AttributeParser for MacroUseParser {
4143 const ATTRIBUTES: AcceptMapping<Self> = &[(
4244 &[sym::macro_use],
4345 MACRO_USE_TEMPLATE,
46 AttributeStability::Stable,
4447 |group: &mut Self, cx: &mut AcceptContext<'_, '_>, args| {
4548 let span = cx.attr_span;
4649 group.first_span.get_or_insert(span);
......@@ -122,6 +125,7 @@ impl NoArgsAttributeParser for AllowInternalUnsafeParser {
122125 Warn(Target::Field),
123126 Warn(Target::Arm),
124127 ]);
128 const STABILITY: AttributeStability = unstable!(allow_internal_unsafe);
125129 const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span);
126130}
127131
......@@ -136,6 +140,7 @@ impl SingleAttributeParser for MacroExportParser {
136140 Error(Target::WherePredicate),
137141 Error(Target::Crate),
138142 ]);
143 const STABILITY: AttributeStability = AttributeStability::Stable;
139144
140145 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
141146 let local_inner_macros = match args {
......@@ -171,6 +176,7 @@ impl SingleAttributeParser for CollapseDebugInfoParser {
171176 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
172177 );
173178 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
179 const STABILITY: AttributeStability = AttributeStability::Stable;
174180
175181 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
176182 let single = cx.expect_single_element_list(args, cx.attr_span)?;
......@@ -200,5 +206,6 @@ pub(crate) struct RustcProcMacroDeclsParser;
200206impl NoArgsAttributeParser for RustcProcMacroDeclsParser {
201207 const PATH: &[Symbol] = &[sym::rustc_proc_macro_decls];
202208 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static)]);
209 const STABILITY: AttributeStability = unstable!(rustc_attrs);
203210 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls;
204211}
compiler/rustc_attr_parsing/src/attributes/mod.rs+15-6
......@@ -16,7 +16,7 @@
1616
1717use std::marker::PhantomData;
1818
19use rustc_feature::{AttributeTemplate, template};
19use rustc_feature::{AttributeStability, AttributeTemplate, template};
2020use rustc_hir::attrs::AttributeKind;
2121use rustc_span::edition::Edition;
2222use rustc_span::{Span, Symbol};
......@@ -71,7 +71,8 @@ pub(crate) mod transparency;
7171pub(crate) mod util;
7272
7373type AcceptFn<T> = for<'sess> fn(&mut T, &mut AcceptContext<'_, 'sess>, &ArgParser);
74type AcceptMapping<T> = &'static [(&'static [Symbol], AttributeTemplate, AcceptFn<T>)];
74type AcceptMapping<T> =
75 &'static [(&'static [Symbol], AttributeTemplate, AttributeStability, AcceptFn<T>)];
7576
7677/// An [`AttributeParser`] is a type which searches for syntactic attributes.
7778///
......@@ -130,6 +131,7 @@ pub(crate) trait SingleAttributeParser: 'static {
130131 /// applied more than once on the same syntax node.
131132 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
132133 const SAFETY: AttributeSafety = AttributeSafety::Normal;
134 const STABILITY: AttributeStability;
133135
134136 const ALLOWED_TARGETS: AllowedTargets;
135137
......@@ -151,8 +153,11 @@ impl<T: SingleAttributeParser> Default for Single<T> {
151153}
152154
153155impl<T: SingleAttributeParser> AttributeParser for Single<T> {
154 const ATTRIBUTES: AcceptMapping<Self> =
155 &[(T::PATH, <T as SingleAttributeParser>::TEMPLATE, |group: &mut Single<T>, cx, args| {
156 const ATTRIBUTES: AcceptMapping<Self> = &[(
157 T::PATH,
158 <T as SingleAttributeParser>::TEMPLATE,
159 T::STABILITY,
160 |group: &mut Single<T>, cx, args| {
156161 if let Some(pa) = T::convert(cx, args) {
157162 if let Some((_, used)) = group.1 {
158163 T::ON_DUPLICATE.exec::<T>(cx, used, cx.attr_span);
......@@ -160,7 +165,8 @@ impl<T: SingleAttributeParser> AttributeParser for Single<T> {
160165 group.1 = Some((pa, cx.attr_span));
161166 }
162167 }
163 })];
168 },
169 )];
164170 const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
165171 const SAFETY: AttributeSafety = T::SAFETY;
166172
......@@ -237,6 +243,7 @@ pub(crate) trait NoArgsAttributeParser: 'static {
237243 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
238244 const ALLOWED_TARGETS: AllowedTargets;
239245 const SAFETY: AttributeSafety = AttributeSafety::Normal;
246 const STABILITY: AttributeStability;
240247
241248 /// Create the [`AttributeKind`] given attribute's [`Span`].
242249 const CREATE: fn(Span) -> AttributeKind;
......@@ -254,6 +261,7 @@ impl<T: NoArgsAttributeParser> SingleAttributeParser for WithoutArgs<T> {
254261 const PATH: &[Symbol] = T::PATH;
255262 const ON_DUPLICATE: OnDuplicate = T::ON_DUPLICATE;
256263 const SAFETY: AttributeSafety = T::SAFETY;
264 const STABILITY: AttributeStability = T::STABILITY;
257265 const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
258266 const TEMPLATE: AttributeTemplate = template!(Word);
259267
......@@ -282,6 +290,7 @@ pub(crate) trait CombineAttributeParser: 'static {
282290 /// where `x` is a vec of these individual reprs.
283291 const CONVERT: ConvertFn<Self::Item>;
284292 const SAFETY: AttributeSafety = AttributeSafety::Normal;
293 const STABILITY: AttributeStability;
285294
286295 const ALLOWED_TARGETS: AllowedTargets;
287296
......@@ -317,7 +326,7 @@ impl<T: CombineAttributeParser> Default for Combine<T> {
317326
318327impl<T: CombineAttributeParser> AttributeParser for Combine<T> {
319328 const ATTRIBUTES: AcceptMapping<Self> =
320 &[(T::PATH, T::TEMPLATE, |group: &mut Combine<T>, cx, args| {
329 &[(T::PATH, T::TEMPLATE, T::STABILITY, |group: &mut Combine<T>, cx, args| {
321330 // Keep track of the span of the first attribute, for diagnostics
322331 group.first_span.get_or_insert(cx.attr_span);
323332 group.items.extend(T::extend(cx, args))
compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct MustNotSuspendParser;
......@@ -11,6 +13,7 @@ impl SingleAttributeParser for MustNotSuspendParser {
1113 Allow(Target::Trait),
1214 ]);
1315 const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);
16 const STABILITY: AttributeStability = unstable!(must_not_suspend);
1417
1518 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1619 let reason = match args {
compiler/rustc_attr_parsing/src/attributes/must_use.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct MustUseParser;
......@@ -24,6 +26,7 @@ impl SingleAttributeParser for MustUseParser {
2426 Word, NameValueStr: "reason",
2527 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
2628 );
29 const STABILITY: AttributeStability = AttributeStability::Stable;
2730
2831 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
2932 Some(AttributeKind::MustUse {
compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct NoImplicitPreludeParser;
......@@ -7,5 +9,6 @@ impl NoArgsAttributeParser for NoImplicitPreludeParser {
79 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
810 const ALLOWED_TARGETS: AllowedTargets =
911 AllowedTargets::AllowListWarnRest(&[Allow(Target::Mod), Allow(Target::Crate)]);
12 const STABILITY: AttributeStability = AttributeStability::Stable;
1013 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoImplicitPrelude;
1114}
compiler/rustc_attr_parsing/src/attributes/no_link.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct NoLinkParser;
......@@ -10,5 +12,6 @@ impl NoArgsAttributeParser for NoLinkParser {
1012 Warn(Target::Arm),
1113 Warn(Target::MacroDef),
1214 ]);
15 const STABILITY: AttributeStability = AttributeStability::Stable;
1316 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoLink;
1417}
compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs+2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::Target;
23use rustc_hir::attrs::AttributeKind;
34use rustc_span::{Span, Symbol, sym};
......@@ -20,5 +21,6 @@ impl NoArgsAttributeParser for NonExhaustiveParser {
2021 Warn(Target::MacroDef),
2122 Warn(Target::MacroCall),
2223 ]);
24 const STABILITY: AttributeStability = AttributeStability::Stable;
2325 const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive;
2426}
compiler/rustc_attr_parsing/src/attributes/path.rs+3
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct PathParser;
......@@ -11,6 +13,7 @@ impl SingleAttributeParser for PathParser {
1113 NameValueStr: "file",
1214 "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute"
1315 );
16 const STABILITY: AttributeStability = AttributeStability::Stable;
1417
1518 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1619 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
compiler/rustc_attr_parsing/src/attributes/pin_v2.rs+3
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::Target;
23use rustc_hir::attrs::AttributeKind;
34use rustc_span::{Span, Symbol, sym};
......@@ -5,6 +6,7 @@ use rustc_span::{Span, Symbol, sym};
56use crate::attributes::NoArgsAttributeParser;
67use crate::target_checking::AllowedTargets;
78use crate::target_checking::Policy::Allow;
9use crate::unstable;
810
911pub(crate) struct PinV2Parser;
1012
......@@ -15,5 +17,6 @@ impl NoArgsAttributeParser for PinV2Parser {
1517 Allow(Target::Struct),
1618 Allow(Target::Union),
1719 ]);
20 const STABILITY: AttributeStability = unstable!(pin_ergonomics);
1821 const CREATE: fn(Span) -> AttributeKind = AttributeKind::PinV2;
1922}
compiler/rustc_attr_parsing/src/attributes/prelude.rs+2
......@@ -25,3 +25,5 @@ pub(super) use crate::parser::*;
2525pub(super) use crate::target_checking::Policy::{Allow, Error, Warn};
2626#[doc(hidden)]
2727pub(super) use crate::target_checking::{ALL_TARGETS, AllowedTargets};
28#[doc(hidden)]
29pub(super) use crate::unstable;
compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs+5
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_session::lint::builtin::AMBIGUOUS_DERIVE_HELPERS;
23
34use super::prelude::*;
......@@ -9,6 +10,7 @@ pub(crate) struct ProcMacroParser;
910impl NoArgsAttributeParser for ProcMacroParser {
1011 const PATH: &[Symbol] = &[sym::proc_macro];
1112 const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS;
13 const STABILITY: AttributeStability = AttributeStability::Stable;
1214 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacro;
1315}
1416
......@@ -16,6 +18,7 @@ pub(crate) struct ProcMacroAttributeParser;
1618impl NoArgsAttributeParser for ProcMacroAttributeParser {
1719 const PATH: &[Symbol] = &[sym::proc_macro_attribute];
1820 const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS;
21 const STABILITY: AttributeStability = AttributeStability::Stable;
1922 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProcMacroAttribute;
2023}
2124
......@@ -27,6 +30,7 @@ impl SingleAttributeParser for ProcMacroDeriveParser {
2730 List: &["TraitName", "TraitName, attributes(name1, name2, ...)"],
2831 "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros"
2932 );
33 const STABILITY: AttributeStability = AttributeStability::Stable;
3034
3135 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3236 let (trait_name, helper_attrs) = parse_derive_like(cx, args, true)?;
......@@ -43,6 +47,7 @@ impl SingleAttributeParser for RustcBuiltinMacroParser {
4347 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
4448 const TEMPLATE: AttributeTemplate =
4549 template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]);
50 const STABILITY: AttributeStability = unstable!(rustc_attrs);
4651
4752 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
4853 let (builtin_name, helper_attrs) = parse_derive_like(cx, args, false)?;
compiler/rustc_attr_parsing/src/attributes/prototype.rs+3-2
......@@ -1,6 +1,6 @@
11//! Attributes that are only used on function prototypes.
22
3use rustc_feature::{AttributeTemplate, template};
3use rustc_feature::{AttributeStability, AttributeTemplate, template};
44use rustc_hir::Target;
55use rustc_hir::attrs::{AttributeKind, MirDialect, MirPhase};
66use rustc_span::{Span, Symbol, sym};
......@@ -8,14 +8,15 @@ use rustc_span::{Span, Symbol, sym};
88use crate::attributes::SingleAttributeParser;
99use crate::context::AcceptContext;
1010use crate::parser::{ArgParser, NameValueParser};
11use crate::session_diagnostics;
1211use crate::target_checking::AllowedTargets;
1312use crate::target_checking::Policy::Allow;
13use crate::{session_diagnostics, unstable};
1414
1515pub(crate) struct CustomMirParser;
1616
1717impl SingleAttributeParser for CustomMirParser {
1818 const PATH: &[rustc_span::Symbol] = &[sym::custom_mir];
19 const STABILITY: AttributeStability = unstable!(custom_mir);
1920
2021 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
2122
compiler/rustc_attr_parsing/src/attributes/repr.rs+6-2
......@@ -1,5 +1,6 @@
11use rustc_abi::{Align, Size};
22use rustc_ast::{IntTy, LitIntType, LitKind, UintTy};
3use rustc_feature::AttributeStability;
34use rustc_hir::attrs::IntType::{SignedInt, UnsignedInt};
45use rustc_hir::attrs::ReprAttr;
56
......@@ -55,6 +56,7 @@ impl CombineAttributeParser for ReprParser {
5556 //FIXME Still checked fully in `check_attr.rs`
5657 //This one is slightly more complicated because the allowed targets depend on the arguments
5758 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
59 const STABILITY: AttributeStability = AttributeStability::Stable;
5860}
5961
6062fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option<ReprAttr> {
......@@ -223,7 +225,8 @@ impl RustcAlignParser {
223225}
224226
225227impl AttributeParser for RustcAlignParser {
226 const ATTRIBUTES: AcceptMapping<Self> = &[(Self::PATH, Self::TEMPLATE, Self::parse)];
228 const ATTRIBUTES: AcceptMapping<Self> =
229 &[(Self::PATH, Self::TEMPLATE, unstable!(fn_align), Self::parse)];
227230 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
228231 Allow(Target::Fn),
229232 Allow(Target::Method(MethodKind::Inherent)),
......@@ -252,7 +255,8 @@ impl RustcAlignStaticParser {
252255}
253256
254257impl AttributeParser for RustcAlignStaticParser {
255 const ATTRIBUTES: AcceptMapping<Self> = &[(Self::PATH, Self::TEMPLATE, Self::parse)];
258 const ATTRIBUTES: AcceptMapping<Self> =
259 &[(Self::PATH, Self::TEMPLATE, unstable!(static_align), Self::parse)];
256260 const ALLOWED_TARGETS: AllowedTargets =
257261 AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]);
258262
compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs+7
......@@ -1,3 +1,5 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct RustcAllocatorParser;
......@@ -6,6 +8,7 @@ impl NoArgsAttributeParser for RustcAllocatorParser {
68 const PATH: &[Symbol] = &[sym::rustc_allocator];
79 const ALLOWED_TARGETS: AllowedTargets =
810 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
11 const STABILITY: AttributeStability = unstable!(rustc_attrs);
912 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator;
1013}
1114
......@@ -15,6 +18,7 @@ impl NoArgsAttributeParser for RustcAllocatorZeroedParser {
1518 const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed];
1619 const ALLOWED_TARGETS: AllowedTargets =
1720 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
21 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1822 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed;
1923}
2024
......@@ -25,6 +29,7 @@ impl SingleAttributeParser for RustcAllocatorZeroedVariantParser {
2529 const ALLOWED_TARGETS: AllowedTargets =
2630 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
2731 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function");
32 const STABILITY: AttributeStability = unstable!(rustc_attrs);
2833 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
2934 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
3035 let name = cx.expect_string_literal(nv)?;
......@@ -39,6 +44,7 @@ impl NoArgsAttributeParser for RustcDeallocatorParser {
3944 const PATH: &[Symbol] = &[sym::rustc_deallocator];
4045 const ALLOWED_TARGETS: AllowedTargets =
4146 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
47 const STABILITY: AttributeStability = unstable!(rustc_attrs);
4248 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator;
4349}
4450
......@@ -48,5 +54,6 @@ impl NoArgsAttributeParser for RustcReallocatorParser {
4854 const PATH: &[Symbol] = &[sym::rustc_reallocator];
4955 const ALLOWED_TARGETS: AllowedTargets =
5056 AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]);
57 const STABILITY: AttributeStability = unstable!(rustc_attrs);
5158 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcReallocator;
5259}
compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs+18
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::{AttributeKind, RustcDumpLayoutKind};
23use rustc_hir::{MethodKind, Target};
34use rustc_span::{Span, Symbol, sym};
......@@ -10,6 +11,7 @@ pub(crate) struct RustcDumpUserArgsParser;
1011impl NoArgsAttributeParser for RustcDumpUserArgsParser {
1112 const PATH: &[Symbol] = &[sym::rustc_dump_user_args];
1213 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
14 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1315 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
1416}
1517
......@@ -18,6 +20,7 @@ pub(crate) struct RustcDumpDefParentsParser;
1820impl NoArgsAttributeParser for RustcDumpDefParentsParser {
1921 const PATH: &[Symbol] = &[sym::rustc_dump_def_parents];
2022 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
23 const STABILITY: AttributeStability = unstable!(rustc_attrs);
2124 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
2225}
2326
......@@ -35,6 +38,7 @@ impl SingleAttributeParser for RustcDumpDefPathParser {
3538 Allow(Target::Impl { of_trait: false }),
3639 ]);
3740 const TEMPLATE: AttributeTemplate = template!(Word);
41 const STABILITY: AttributeStability = unstable!(rustc_attrs);
3842 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3943 cx.expect_no_args(args)?;
4044 Some(AttributeKind::RustcDumpDefPath(cx.attr_span))
......@@ -46,6 +50,7 @@ pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser;
4650impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser {
4751 const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques];
4852 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
53 const STABILITY: AttributeStability = unstable!(rustc_attrs);
4954 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques;
5055}
5156
......@@ -59,6 +64,7 @@ impl NoArgsAttributeParser for RustcDumpInferredOutlivesParser {
5964 Allow(Target::Union),
6065 Allow(Target::TyAlias),
6166 ]);
67 const STABILITY: AttributeStability = unstable!(rustc_attrs);
6268 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpInferredOutlives;
6369}
6470
......@@ -67,6 +73,7 @@ pub(crate) struct RustcDumpItemBoundsParser;
6773impl NoArgsAttributeParser for RustcDumpItemBoundsParser {
6874 const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds];
6975 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]);
76 const STABILITY: AttributeStability = unstable!(rustc_attrs);
7077 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
7178}
7279
......@@ -88,6 +95,8 @@ impl CombineAttributeParser for RustcDumpLayoutParser {
8895
8996 const TEMPLATE: AttributeTemplate =
9097 template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]);
98 const STABILITY: AttributeStability = unstable!(rustc_attrs);
99
91100 fn extend(
92101 cx: &mut AcceptContext<'_, '_>,
93102 args: &ArgParser,
......@@ -155,6 +164,7 @@ impl NoArgsAttributeParser for RustcDumpObjectLifetimeDefaultsParser {
155164 Allow(Target::TyAlias),
156165 Allow(Target::Union),
157166 ]);
167 const STABILITY: AttributeStability = unstable!(rustc_attrs);
158168 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpObjectLifetimeDefaults;
159169}
160170
......@@ -182,6 +192,7 @@ impl NoArgsAttributeParser for RustcDumpPredicatesParser {
182192 Allow(Target::TyAlias),
183193 Allow(Target::Union),
184194 ]);
195 const STABILITY: AttributeStability = unstable!(rustc_attrs);
185196 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates;
186197}
187198
......@@ -199,6 +210,7 @@ impl SingleAttributeParser for RustcDumpSymbolNameParser {
199210 Allow(Target::Impl { of_trait: false }),
200211 ]);
201212 const TEMPLATE: AttributeTemplate = template!(Word);
213 const STABILITY: AttributeStability = unstable!(rustc_attrs);
202214 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
203215 cx.expect_no_args(args)?;
204216 Some(AttributeKind::RustcDumpSymbolName(cx.attr_span))
......@@ -219,6 +231,10 @@ impl NoArgsAttributeParser for RustcDumpVariancesParser {
219231 Allow(Target::Struct),
220232 Allow(Target::Union),
221233 ]);
234 const STABILITY: AttributeStability = unstable!(
235 rustc_attrs,
236 "the `#[rustc_dump_variances]` attribute is used for rustc unit tests"
237 );
222238 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariances;
223239}
224240
......@@ -227,6 +243,7 @@ pub(crate) struct RustcDumpVariancesOfOpaquesParser;
227243impl NoArgsAttributeParser for RustcDumpVariancesOfOpaquesParser {
228244 const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques];
229245 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
246 const STABILITY: AttributeStability = unstable!(rustc_attrs);
230247 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques;
231248}
232249
......@@ -238,5 +255,6 @@ impl NoArgsAttributeParser for RustcDumpVtableParser {
238255 Allow(Target::Impl { of_trait: true }),
239256 Allow(Target::TyAlias),
240257 ]);
258 const STABILITY: AttributeStability = unstable!(rustc_attrs);
241259 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable;
242260}
compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs+72-10
......@@ -1,6 +1,7 @@
11use std::path::PathBuf;
22
33use rustc_ast::{LitIntType, LitKind, MetaItemLit};
4use rustc_feature::AttributeStability;
45use rustc_hir::LangItem;
56use rustc_hir::attrs::{
67 BorrowckGraphvizFormatKind, CguFields, CguKind, DivergingBlockBehavior,
......@@ -20,6 +21,10 @@ pub(crate) struct RustcMainParser;
2021impl NoArgsAttributeParser for RustcMainParser {
2122 const PATH: &[Symbol] = &[sym::rustc_main];
2223 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
24 const STABILITY: AttributeStability = unstable!(
25 rustc_attrs,
26 "the `#[rustc_main]` attribute is used internally to specify test entry point function"
27 );
2328 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain;
2429}
2530
......@@ -28,6 +33,10 @@ pub(crate) struct RustcMustImplementOneOfParser;
2833impl SingleAttributeParser for RustcMustImplementOneOfParser {
2934 const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of];
3035 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
36 const STABILITY: AttributeStability = unstable!(
37 rustc_attrs,
38 "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete definition of a trait. Its syntax and semantics are highly experimental and will be subject to change before stabilization"
39 );
3140 const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]);
3241 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
3342 let list = cx.expect_list(args, cx.attr_span)?;
......@@ -75,6 +84,8 @@ impl NoArgsAttributeParser for RustcNeverReturnsNullPtrParser {
7584 Allow(Target::Method(MethodKind::Trait { body: true })),
7685 Allow(Target::Method(MethodKind::TraitImpl)),
7786 ]);
87 const STABILITY: AttributeStability = unstable!(rustc_attrs);
88
7889 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNeverReturnsNullPtr;
7990}
8091pub(crate) struct RustcNoImplicitAutorefsParser;
......@@ -88,6 +99,7 @@ impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser {
8899 Allow(Target::Method(MethodKind::Trait { body: true })),
89100 Allow(Target::Method(MethodKind::TraitImpl)),
90101 ]);
102 const STABILITY: AttributeStability = unstable!(rustc_attrs);
91103
92104 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitAutorefs;
93105}
......@@ -98,6 +110,7 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser {
98110 const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics];
99111 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
100112 const TEMPLATE: AttributeTemplate = template!(List: &["N"]);
113 const STABILITY: AttributeStability = unstable!(rustc_attrs);
101114
102115 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
103116 let meta_items = cx.expect_list(args, cx.attr_span)?;
......@@ -141,6 +154,7 @@ impl NoArgsAttributeParser for RustcInheritOverflowChecksParser {
141154 Allow(Target::Method(MethodKind::TraitImpl)),
142155 Allow(Target::Closure),
143156 ]);
157 const STABILITY: AttributeStability = unstable!(rustc_attrs);
144158 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcInheritOverflowChecks;
145159}
146160
......@@ -150,6 +164,7 @@ impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser {
150164 const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access];
151165 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]);
152166 const TEMPLATE: AttributeTemplate = template!(Word);
167 const STABILITY: AttributeStability = unstable!(rustc_attrs);
153168 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
154169 let arg = cx.expect_single_element_list(args, cx.attr_span)?;
155170 let lint_message = cx.expect_string_literal(arg)?;
......@@ -163,6 +178,7 @@ pub(crate) struct RustcLintOptTyParser;
163178impl NoArgsAttributeParser for RustcLintOptTyParser {
164179 const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty];
165180 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
181 const STABILITY: AttributeStability = unstable!(rustc_attrs);
166182 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy;
167183}
168184
......@@ -258,6 +274,7 @@ impl AttributeParser for RustcCguTestAttributeParser {
258274 (
259275 &[sym::rustc_partition_reused],
260276 template!(List: &[r#"cfg = "...", module = "...""#]),
277 unstable!(rustc_attrs),
261278 |this, cx, args| {
262279 this.items.extend(parse_cgu_fields(cx, args, false).map(|(cfg, module, _)| {
263280 (cx.attr_span, CguFields::PartitionReused { cfg, module })
......@@ -267,6 +284,7 @@ impl AttributeParser for RustcCguTestAttributeParser {
267284 (
268285 &[sym::rustc_partition_codegened],
269286 template!(List: &[r#"cfg = "...", module = "...""#]),
287 unstable!(rustc_attrs),
270288 |this, cx, args| {
271289 this.items.extend(parse_cgu_fields(cx, args, false).map(|(cfg, module, _)| {
272290 (cx.attr_span, CguFields::PartitionCodegened { cfg, module })
......@@ -276,6 +294,7 @@ impl AttributeParser for RustcCguTestAttributeParser {
276294 (
277295 &[sym::rustc_expected_cgu_reuse],
278296 template!(List: &[r#"cfg = "...", module = "...", kind = "...""#]),
297 unstable!(rustc_attrs),
279298 |this, cx, args| {
280299 this.items.extend(parse_cgu_fields(cx, args, true).map(|(cfg, module, kind)| {
281300 // unwrap ok because if not given, we return None in `parse_cgu_fields`.
......@@ -305,6 +324,7 @@ impl SingleAttributeParser for RustcDeprecatedSafe2024Parser {
305324 Allow(Target::Method(MethodKind::TraitImpl)),
306325 ]);
307326 const TEMPLATE: AttributeTemplate = template!(List: &[r#"audit_that = "...""#]);
327 const STABILITY: AttributeStability = unstable!(rustc_attrs);
308328
309329 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
310330 let single = cx.expect_single_element_list(args, cx.attr_span)?;
......@@ -333,6 +353,7 @@ impl NoArgsAttributeParser for RustcConversionSuggestionParser {
333353 Allow(Target::Method(MethodKind::Trait { body: true })),
334354 Allow(Target::Method(MethodKind::TraitImpl)),
335355 ]);
356 const STABILITY: AttributeStability = unstable!(rustc_attrs);
336357 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcConversionSuggestion;
337358}
338359
......@@ -341,6 +362,7 @@ pub(crate) struct RustcCaptureAnalysisParser;
341362impl NoArgsAttributeParser for RustcCaptureAnalysisParser {
342363 const PATH: &[Symbol] = &[sym::rustc_capture_analysis];
343364 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
365 const STABILITY: AttributeStability = unstable!(rustc_attrs);
344366 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis;
345367}
346368
......@@ -353,6 +375,10 @@ impl SingleAttributeParser for RustcNeverTypeOptionsParser {
353375 r#"fallback = "unit", "never", "no""#,
354376 r#"diverging_block_default = "unit", "never""#,
355377 ]);
378 const STABILITY: AttributeStability = unstable!(
379 rustc_attrs,
380 "`rustc_never_type_options` is used to experiment with never type fallback and work on never type stabilization"
381 );
356382
357383 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
358384 let list = cx.expect_list(args, cx.attr_span)?;
......@@ -418,6 +444,7 @@ pub(crate) struct RustcTrivialFieldReadsParser;
418444impl NoArgsAttributeParser for RustcTrivialFieldReadsParser {
419445 const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads];
420446 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
447 const STABILITY: AttributeStability = unstable!(rustc_attrs);
421448 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads;
422449}
423450
......@@ -432,6 +459,7 @@ impl NoArgsAttributeParser for RustcNoMirInlineParser {
432459 Allow(Target::Method(MethodKind::Trait { body: true })),
433460 Allow(Target::Method(MethodKind::TraitImpl)),
434461 ]);
462 const STABILITY: AttributeStability = unstable!(rustc_attrs);
435463 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoMirInline;
436464}
437465
......@@ -447,6 +475,7 @@ impl NoArgsAttributeParser for RustcNoWritableParser {
447475 Allow(Target::Method(MethodKind::TraitImpl)),
448476 Allow(Target::Method(MethodKind::Trait { body: true })),
449477 ]);
478 const STABILITY: AttributeStability = unstable!(rustc_attrs);
450479 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoWritable;
451480}
452481
......@@ -461,6 +490,7 @@ impl NoArgsAttributeParser for RustcLintQueryInstabilityParser {
461490 Allow(Target::Method(MethodKind::Trait { body: true })),
462491 Allow(Target::Method(MethodKind::TraitImpl)),
463492 ]);
493 const STABILITY: AttributeStability = unstable!(rustc_attrs);
464494 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability;
465495}
466496
......@@ -475,7 +505,7 @@ impl NoArgsAttributeParser for RustcRegionsParser {
475505 Allow(Target::Method(MethodKind::Trait { body: true })),
476506 Allow(Target::Method(MethodKind::TraitImpl)),
477507 ]);
478
508 const STABILITY: AttributeStability = unstable!(rustc_attrs);
479509 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcRegions;
480510}
481511
......@@ -490,7 +520,7 @@ impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser {
490520 Allow(Target::Method(MethodKind::Trait { body: true })),
491521 Allow(Target::Method(MethodKind::TraitImpl)),
492522 ]);
493
523 const STABILITY: AttributeStability = unstable!(rustc_attrs);
494524 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintUntrackedQueryInformation;
495525}
496526
......@@ -500,6 +530,7 @@ impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser {
500530 const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit];
501531 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
502532 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
533 const STABILITY: AttributeStability = unstable!(rustc_attrs);
503534
504535 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
505536 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -513,6 +544,7 @@ impl SingleAttributeParser for RustcScalableVectorParser {
513544 const PATH: &[Symbol] = &[sym::rustc_scalable_vector];
514545 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
515546 const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);
547 const STABILITY: AttributeStability = unstable!(rustc_attrs);
516548
517549 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
518550 if args.as_no_args().is_ok() {
......@@ -534,6 +566,7 @@ impl SingleAttributeParser for LangParser {
534566 const PATH: &[Symbol] = &[sym::lang];
535567 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
536568 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
569 const STABILITY: AttributeStability = unstable!(lang_items);
537570
538571 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
539572 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -557,6 +590,7 @@ impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser {
557590 Allow(Target::Union),
558591 Allow(Target::ForeignTy),
559592 ]);
593 const STABILITY: AttributeStability = unstable!(rustc_attrs);
560594 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls;
561595}
562596
......@@ -565,6 +599,7 @@ pub(crate) struct PanicHandlerParser;
565599impl NoArgsAttributeParser for PanicHandlerParser {
566600 const PATH: &[Symbol] = &[sym::panic_handler];
567601 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
602 const STABILITY: AttributeStability = AttributeStability::Stable;
568603 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl);
569604}
570605
......@@ -579,6 +614,7 @@ impl NoArgsAttributeParser for RustcNounwindParser {
579614 Allow(Target::Method(MethodKind::TraitImpl)),
580615 Allow(Target::Method(MethodKind::Trait { body: true })),
581616 ]);
617 const STABILITY: AttributeStability = unstable!(rustc_attrs);
582618 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNounwind;
583619}
584620
......@@ -587,6 +623,7 @@ pub(crate) struct RustcOffloadKernelParser;
587623impl NoArgsAttributeParser for RustcOffloadKernelParser {
588624 const PATH: &[Symbol] = &[sym::rustc_offload_kernel];
589625 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
626 const STABILITY: AttributeStability = unstable!(rustc_attrs);
590627 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel;
591628}
592629
......@@ -598,7 +635,6 @@ impl CombineAttributeParser for RustcMirParser {
598635 type Item = RustcMirKind;
599636
600637 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcMir(items);
601
602638 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
603639 Allow(Target::Fn),
604640 Allow(Target::Method(MethodKind::Inherent)),
......@@ -606,8 +642,8 @@ impl CombineAttributeParser for RustcMirParser {
606642 Allow(Target::Method(MethodKind::Trait { body: false })),
607643 Allow(Target::Method(MethodKind::Trait { body: true })),
608644 ]);
609
610645 const TEMPLATE: AttributeTemplate = template!(List: &["arg1, arg2, ..."]);
646 const STABILITY: AttributeStability = unstable!(rustc_attrs);
611647
612648 fn extend(
613649 cx: &mut AcceptContext<'_, '_>,
......@@ -679,6 +715,10 @@ impl NoArgsAttributeParser for RustcNonConstTraitMethodParser {
679715 Allow(Target::Method(MethodKind::Trait { body: true })),
680716 Allow(Target::Method(MethodKind::Trait { body: false })),
681717 ]);
718 const STABILITY: AttributeStability = unstable!(
719 rustc_attrs,
720 "`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods as non-const to allow large traits an easier transition to const"
721 );
682722 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod;
683723}
684724
......@@ -690,7 +730,6 @@ impl CombineAttributeParser for RustcCleanParser {
690730 type Item = RustcCleanAttribute;
691731
692732 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcClean(items);
693
694733 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
695734 // tidy-alphabetical-start
696735 Allow(Target::AssocConst),
......@@ -715,7 +754,7 @@ impl CombineAttributeParser for RustcCleanParser {
715754 Allow(Target::Union),
716755 // tidy-alphabetical-end
717756 ]);
718
757 const STABILITY: AttributeStability = unstable!(rustc_attrs);
719758 const TEMPLATE: AttributeTemplate =
720759 template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]);
721760
......@@ -784,7 +823,6 @@ pub(crate) struct RustcIfThisChangedParser;
784823
785824impl SingleAttributeParser for RustcIfThisChangedParser {
786825 const PATH: &[Symbol] = &[sym::rustc_if_this_changed];
787
788826 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
789827 // tidy-alphabetical-start
790828 Allow(Target::AssocConst),
......@@ -809,8 +847,8 @@ impl SingleAttributeParser for RustcIfThisChangedParser {
809847 Allow(Target::Union),
810848 // tidy-alphabetical-end
811849 ]);
812
813850 const TEMPLATE: AttributeTemplate = template!(Word, List: &["DepNode"]);
851 const STABILITY: AttributeStability = unstable!(rustc_attrs);
814852
815853 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
816854 if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
......@@ -867,8 +905,8 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser {
867905 Allow(Target::Union),
868906 // tidy-alphabetical-end
869907 ]);
870
871908 const TEMPLATE: AttributeTemplate = template!(List: &["DepNode"]);
909 const STABILITY: AttributeStability = unstable!(rustc_attrs);
872910
873911 fn extend(
874912 cx: &mut AcceptContext<'_, '_>,
......@@ -895,6 +933,7 @@ impl NoArgsAttributeParser for RustcInsignificantDtorParser {
895933 Allow(Target::Struct),
896934 Allow(Target::ForeignTy),
897935 ]);
936 const STABILITY: AttributeStability = unstable!(rustc_attrs);
898937 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcInsignificantDtor;
899938}
900939
......@@ -933,6 +972,7 @@ impl NoArgsAttributeParser for RustcEffectiveVisibilityParser {
933972 Allow(Target::PatField),
934973 Allow(Target::Crate),
935974 ]);
975 const STABILITY: AttributeStability = unstable!(rustc_attrs);
936976 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility;
937977}
938978
......@@ -959,6 +999,10 @@ impl SingleAttributeParser for RustcDiagnosticItemParser {
959999 Allow(Target::Crate),
9601000 ]);
9611001 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
1002 const STABILITY: AttributeStability = unstable!(
1003 rustc_attrs,
1004 "the `#[rustc_diagnostic_item]` attribute allows the compiler to reference types from the standard library for diagnostic purposes"
1005 );
9621006
9631007 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
9641008 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -978,6 +1022,10 @@ impl NoArgsAttributeParser for RustcDoNotConstCheckParser {
9781022 Allow(Target::Method(MethodKind::Trait { body: false })),
9791023 Allow(Target::Method(MethodKind::Trait { body: true })),
9801024 ]);
1025 const STABILITY: AttributeStability = unstable!(
1026 rustc_attrs,
1027 "`#[rustc_do_not_const_check]` skips const-check for this function's body"
1028 );
9811029 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDoNotConstCheck;
9821030}
9831031
......@@ -986,6 +1034,11 @@ pub(crate) struct RustcNonnullOptimizationGuaranteedParser;
9861034impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser {
9871035 const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed];
9881036 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
1037 const STABILITY: AttributeStability = unstable!(
1038 rustc_attrs,
1039 "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in the standard library",
1040 "the compiler does not even check whether the type indeed is being non-null-optimized; it is your responsibility to ensure that the attribute is only used on types that are optimized"
1041 );
9891042 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed;
9901043}
9911044
......@@ -1000,6 +1053,7 @@ impl NoArgsAttributeParser for RustcStrictCoherenceParser {
10001053 Allow(Target::Union),
10011054 Allow(Target::ForeignTy),
10021055 ]);
1056 const STABILITY: AttributeStability = unstable!(rustc_attrs);
10031057 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence;
10041058}
10051059
......@@ -1009,8 +1063,8 @@ impl SingleAttributeParser for RustcReservationImplParser {
10091063 const PATH: &[Symbol] = &[sym::rustc_reservation_impl];
10101064 const ALLOWED_TARGETS: AllowedTargets =
10111065 AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]);
1012
10131066 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message");
1067 const STABILITY: AttributeStability = unstable!(rustc_attrs);
10141068
10151069 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
10161070 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -1025,6 +1079,7 @@ pub(crate) struct PreludeImportParser;
10251079impl NoArgsAttributeParser for PreludeImportParser {
10261080 const PATH: &[Symbol] = &[sym::prelude_import];
10271081 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]);
1082 const STABILITY: AttributeStability = unstable!(prelude_import);
10281083 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport;
10291084}
10301085
......@@ -1034,6 +1089,10 @@ impl SingleAttributeParser for RustcDocPrimitiveParser {
10341089 const PATH: &[Symbol] = &[sym::rustc_doc_primitive];
10351090 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]);
10361091 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
1092 const STABILITY: AttributeStability = unstable!(
1093 rustc_attrs,
1094 "the `#[rustc_doc_primitive]` attribute is used by the standard library to provide a way to generate documentation for primitive types"
1095 );
10371096
10381097 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
10391098 let nv = cx.expect_name_value(args, cx.attr_span, None)?;
......@@ -1048,6 +1107,7 @@ pub(crate) struct RustcIntrinsicParser;
10481107impl NoArgsAttributeParser for RustcIntrinsicParser {
10491108 const PATH: &[Symbol] = &[sym::rustc_intrinsic];
10501109 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
1110 const STABILITY: AttributeStability = unstable!(intrinsics);
10511111 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic;
10521112}
10531113
......@@ -1056,6 +1116,7 @@ pub(crate) struct RustcIntrinsicConstStableIndirectParser;
10561116impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectParser {
10571117 const PATH: &'static [Symbol] = &[sym::rustc_intrinsic_const_stable_indirect];
10581118 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
1119 const STABILITY: AttributeStability = unstable!(rustc_attrs);
10591120 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect;
10601121}
10611122
......@@ -1064,5 +1125,6 @@ pub(crate) struct RustcExhaustiveParser;
10641125impl NoArgsAttributeParser for RustcExhaustiveParser {
10651126 const PATH: &'static [Symbol] = &[sym::rustc_must_match_exhaustively];
10661127 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Enum)]);
1128 const STABILITY: AttributeStability = unstable!(rustc_attrs);
10671129 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively;
10681130}
compiler/rustc_attr_parsing/src/attributes/semantics.rs+3
......@@ -1,8 +1,11 @@
1use rustc_feature::AttributeStability;
2
13use super::prelude::*;
24
35pub(crate) struct MayDangleParser;
46impl NoArgsAttributeParser for MayDangleParser {
57 const PATH: &[Symbol] = &[sym::may_dangle];
68 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
9 const STABILITY: AttributeStability = unstable!(dropck_eyepatch);
710 const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
811}
compiler/rustc_attr_parsing/src/attributes/stability.rs+10-25
......@@ -1,7 +1,7 @@
11use std::num::NonZero;
22
33use rustc_errors::ErrorGuaranteed;
4use rustc_feature::ACCEPTED_LANG_FEATURES;
4use rustc_feature::{ACCEPTED_LANG_FEATURES, AttributeStability};
55use rustc_hir::attrs::UnstableRemovedFeature;
66use rustc_hir::target::GenericParamKind;
77use rustc_hir::{
......@@ -13,16 +13,6 @@ use super::prelude::*;
1313use super::util::parse_version;
1414use crate::session_diagnostics;
1515
16macro_rules! reject_outside_std {
17 ($cx: ident) => {
18 // Emit errors for non-staged-api crates.
19 if !$cx.features().staged_api() {
20 $cx.emit_err(session_diagnostics::StabilityOutsideStd { span: $cx.attr_span });
21 return;
22 }
23 };
24}
25
2616const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
2717 Allow(Target::Fn),
2818 Allow(Target::Struct),
......@@ -76,8 +66,8 @@ impl AttributeParser for StabilityParser {
7666 (
7767 &[sym::stable],
7868 template!(List: &[r#"feature = "name", since = "version""#]),
69 unstable!(staged_api),
7970 |this, cx, args| {
80 reject_outside_std!(cx);
8171 if !this.check_duplicate(cx)
8272 && let Some((feature, level)) = parse_stability(cx, args)
8373 {
......@@ -88,8 +78,8 @@ impl AttributeParser for StabilityParser {
8878 (
8979 &[sym::unstable],
9080 template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]),
81 unstable!(staged_api),
9182 |this, cx, args| {
92 reject_outside_std!(cx);
9383 if !this.check_duplicate(cx)
9484 && let Some((feature, level)) = parse_unstability(cx, args)
9585 {
......@@ -100,8 +90,8 @@ impl AttributeParser for StabilityParser {
10090 (
10191 &[sym::rustc_allowed_through_unstable_modules],
10292 template!(NameValueStr: "deprecation message"),
93 unstable!(staged_api),
10394 |this, cx, args| {
104 reject_outside_std!(cx);
10595 let Some(nv) = cx.expect_name_value(args, cx.attr_span, None) else {
10696 return;
10797 };
......@@ -158,8 +148,8 @@ impl AttributeParser for BodyStabilityParser {
158148 const ATTRIBUTES: AcceptMapping<Self> = &[(
159149 &[sym::rustc_default_body_unstable],
160150 template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]),
151 unstable!(staged_api),
161152 |this, cx, args| {
162 reject_outside_std!(cx);
163153 if this.stability.is_some() {
164154 cx.dcx()
165155 .emit_err(session_diagnostics::MultipleStabilityLevels { span: cx.attr_span });
......@@ -185,6 +175,7 @@ impl NoArgsAttributeParser for RustcConstStableIndirectParser {
185175 Allow(Target::Fn),
186176 Allow(Target::Method(MethodKind::Inherent)),
187177 ]);
178 const STABILITY: AttributeStability = unstable!(rustc_attrs);
188179 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcConstStableIndirect;
189180}
190181
......@@ -211,9 +202,8 @@ impl AttributeParser for ConstStabilityParser {
211202 (
212203 &[sym::rustc_const_stable],
213204 template!(List: &[r#"feature = "name""#]),
205 unstable!(staged_api),
214206 |this, cx, args| {
215 reject_outside_std!(cx);
216
217207 if !this.check_duplicate(cx)
218208 && let Some((feature, level)) = parse_stability(cx, args)
219209 {
......@@ -227,8 +217,8 @@ impl AttributeParser for ConstStabilityParser {
227217 (
228218 &[sym::rustc_const_unstable],
229219 template!(List: &[r#"feature = "name""#]),
220 unstable!(staged_api),
230221 |this, cx, args| {
231 reject_outside_std!(cx);
232222 if !this.check_duplicate(cx)
233223 && let Some((feature, level)) = parse_unstability(cx, args)
234224 {
......@@ -239,8 +229,7 @@ impl AttributeParser for ConstStabilityParser {
239229 }
240230 },
241231 ),
242 (&[sym::rustc_promotable], template!(Word), |this, cx, _| {
243 reject_outside_std!(cx);
232 (&[sym::rustc_promotable], template!(Word), unstable!(staged_api), |this, _cx, _| {
244233 this.promotable = true;
245234 }),
246235 ];
......@@ -474,6 +463,7 @@ impl CombineAttributeParser for UnstableRemovedParser {
474463 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
475464 const TEMPLATE: AttributeTemplate =
476465 template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]);
466 const STABILITY: AttributeStability = unstable!(staged_api);
477467
478468 const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableRemoved(items);
479469
......@@ -486,11 +476,6 @@ impl CombineAttributeParser for UnstableRemovedParser {
486476 let mut link = None;
487477 let mut since = None;
488478
489 if !cx.features().staged_api() {
490 cx.emit_err(session_diagnostics::StabilityOutsideStd { span: cx.attr_span });
491 return None;
492 }
493
494479 let list = cx.expect_list(args, cx.attr_span)?;
495480
496481 for param in list.mixed() {
compiler/rustc_attr_parsing/src/attributes/test_attrs.rs+9
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_hir::attrs::RustcAbiAttrKind;
23use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
34
......@@ -14,6 +15,7 @@ impl SingleAttributeParser for IgnoreParser {
1415 Word, NameValueStr: "reason",
1516 "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute"
1617 );
18 const STABILITY: AttributeStability = AttributeStability::Stable;
1719
1820 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1921 Some(AttributeKind::Ignore {
......@@ -55,6 +57,7 @@ impl SingleAttributeParser for ShouldPanicParser {
5557 Word, List: &[r#"expected = "reason""#], NameValueStr: "reason",
5658 "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute"
5759 );
60 const STABILITY: AttributeStability = AttributeStability::Stable;
5861
5962 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
6063 Some(AttributeKind::ShouldPanic {
......@@ -82,6 +85,7 @@ impl SingleAttributeParser for ReexportTestHarnessMainParser {
8285 const PATH: &[Symbol] = &[sym::reexport_test_harness_main];
8386 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
8487 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
88 const STABILITY: AttributeStability = unstable!(custom_test_frameworks);
8589
8690 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
8791 let nv = cx.expect_name_value(
......@@ -110,6 +114,7 @@ impl SingleAttributeParser for RustcAbiParser {
110114 Allow(Target::Method(MethodKind::Trait { body: false })),
111115 Allow(Target::Method(MethodKind::TraitImpl)),
112116 ]);
117 const STABILITY: AttributeStability = unstable!(rustc_attrs);
113118
114119 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
115120 let Some(args) = args.as_list() else {
......@@ -146,6 +151,7 @@ pub(crate) struct RustcDelayedBugFromInsideQueryParser;
146151impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser {
147152 const PATH: &[Symbol] = &[sym::rustc_delayed_bug_from_inside_query];
148153 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
154 const STABILITY: AttributeStability = unstable!(rustc_attrs);
149155 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery;
150156}
151157
......@@ -160,6 +166,7 @@ impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser {
160166 Allow(Target::Method(MethodKind::TraitImpl)),
161167 Allow(Target::Method(MethodKind::Trait { body: false })),
162168 ]);
169 const STABILITY: AttributeStability = unstable!(rustc_attrs);
163170 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEvaluateWhereClauses;
164171}
165172
......@@ -169,6 +176,7 @@ impl SingleAttributeParser for TestRunnerParser {
169176 const PATH: &[Symbol] = &[sym::test_runner];
170177 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
171178 const TEMPLATE: AttributeTemplate = template!(List: &["path"]);
179 const STABILITY: AttributeStability = unstable!(custom_test_frameworks);
172180
173181 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
174182 let single = cx.expect_single_element_list(args, cx.attr_span)?;
......@@ -191,6 +199,7 @@ impl SingleAttributeParser for RustcTestMarkerParser {
191199 Allow(Target::Fn),
192200 Allow(Target::Static),
193201 ]);
202 const STABILITY: AttributeStability = unstable!(rustc_attrs);
194203 const TEMPLATE: AttributeTemplate = template!(NameValueStr: "test_path");
195204
196205 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
compiler/rustc_attr_parsing/src/attributes/traits.rs+12
......@@ -1,5 +1,7 @@
11use std::mem;
22
3use rustc_feature::AttributeStability;
4
35use super::prelude::*;
46use crate::attributes::{NoArgsAttributeParser, SingleAttributeParser};
57use crate::context::AcceptContext;
......@@ -13,6 +15,7 @@ impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser {
1315 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
1416
1517 const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]);
18 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1619
1720 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
1821 let mut array = false;
......@@ -50,6 +53,7 @@ pub(crate) struct RustcParenSugarParser;
5053impl NoArgsAttributeParser for RustcParenSugarParser {
5154 const PATH: &[Symbol] = &[sym::rustc_paren_sugar];
5255 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
56 const STABILITY: AttributeStability = unstable!(rustc_attrs);
5357 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar;
5458}
5559
......@@ -64,6 +68,7 @@ impl NoArgsAttributeParser for MarkerParser {
6468 Warn(Target::Arm),
6569 Warn(Target::MacroDef),
6670 ]);
71 const STABILITY: AttributeStability = unstable!(marker_trait_attr);
6772 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Marker;
6873}
6974
......@@ -71,6 +76,7 @@ pub(crate) struct RustcDenyExplicitImplParser;
7176impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
7277 const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
7378 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
79 const STABILITY: AttributeStability = unstable!(rustc_attrs);
7480 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl;
7581}
7682
......@@ -78,6 +84,7 @@ pub(crate) struct RustcDynIncompatibleTraitParser;
7884impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
7985 const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
8086 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
87 const STABILITY: AttributeStability = unstable!(rustc_attrs);
8188 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
8289}
8390
......@@ -87,6 +94,7 @@ pub(crate) struct RustcSpecializationTraitParser;
8794impl NoArgsAttributeParser for RustcSpecializationTraitParser {
8895 const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
8996 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
97 const STABILITY: AttributeStability = unstable!(rustc_attrs);
9098 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait;
9199}
92100
......@@ -94,6 +102,7 @@ pub(crate) struct RustcUnsafeSpecializationMarkerParser;
94102impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser {
95103 const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker];
96104 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
105 const STABILITY: AttributeStability = unstable!(rustc_attrs);
97106 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcUnsafeSpecializationMarker;
98107}
99108
......@@ -103,6 +112,7 @@ pub(crate) struct RustcCoinductiveParser;
103112impl NoArgsAttributeParser for RustcCoinductiveParser {
104113 const PATH: &[Symbol] = &[sym::rustc_coinductive];
105114 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
115 const STABILITY: AttributeStability = unstable!(rustc_attrs);
106116 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive;
107117}
108118
......@@ -111,6 +121,7 @@ impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
111121 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
112122 const ALLOWED_TARGETS: AllowedTargets =
113123 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
124 const STABILITY: AttributeStability = unstable!(rustc_attrs);
114125 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
115126}
116127
......@@ -119,5 +130,6 @@ impl NoArgsAttributeParser for FundamentalParser {
119130 const PATH: &[Symbol] = &[sym::fundamental];
120131 const ALLOWED_TARGETS: AllowedTargets =
121132 AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
133 const STABILITY: AttributeStability = unstable!(fundamental);
122134 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
123135}
compiler/rustc_attr_parsing/src/attributes/transparency.rs+2
......@@ -1,3 +1,4 @@
1use rustc_feature::AttributeStability;
12use rustc_span::hygiene::Transparency;
23
34use super::prelude::*;
......@@ -9,6 +10,7 @@ impl SingleAttributeParser for RustcMacroTransparencyParser {
910 const ON_DUPLICATE: OnDuplicate = OnDuplicate::Custom(|cx, used, unused| {
1011 cx.dcx().span_err(vec![used, unused], "multiple macro transparency attributes");
1112 });
13 const STABILITY: AttributeStability = unstable!(rustc_attrs);
1214 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
1315 const TEMPLATE: AttributeTemplate =
1416 template!(NameValueStr: ["transparent", "semiopaque", "opaque"]);
compiler/rustc_attr_parsing/src/context.rs+5-3
......@@ -10,7 +10,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
1010use rustc_ast::{AttrStyle, MetaItemLit, Safety};
1111use rustc_data_structures::sync::{DynSend, DynSync};
1212use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan};
13use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
13use rustc_feature::{AttrSuggestionStyle, AttributeStability, AttributeTemplate};
1414use rustc_hir::AttrPath;
1515use rustc_hir::attrs::AttributeKind;
1616use rustc_parse::parser::Recovery;
......@@ -83,6 +83,7 @@ pub(super) struct GroupTypeInnerAccept {
8383 pub(super) accept_fn: AcceptFn,
8484 pub(super) allowed_targets: AllowedTargets,
8585 pub(super) safety: AttributeSafety,
86 pub(super) stability: AttributeStability,
8687 pub(super) finalizer: FinalizeFn,
8788}
8889
......@@ -102,7 +103,7 @@ macro_rules! attribute_parsers {
102103 static STATE_OBJECT: RefCell<$names> = RefCell::new(<$names>::default());
103104 };
104105
105 for (path, template, accept_fn) in <$names>::ATTRIBUTES {
106 for (path, template, stability, accept_fn) in <$names>::ATTRIBUTES {
106107 match accepters.entry(*path) {
107108 Entry::Vacant(e) => {
108109 e.insert(GroupTypeInnerAccept {
......@@ -113,6 +114,7 @@ macro_rules! attribute_parsers {
113114 })
114115 }),
115116 safety: <$names as crate::attributes::AttributeParser>::SAFETY,
117 stability: *stability,
116118 allowed_targets: <$names as crate::attributes::AttributeParser>::ALLOWED_TARGETS,
117119 finalizer: |cx| {
118120 let state = STATE_OBJECT.take();
......@@ -154,7 +156,7 @@ attribute_parsers!(
154156 // tidy-alphabetical-start
155157 Combine<AllowInternalUnstableParser>,
156158 Combine<CrateTypeParser>,
157 Combine<DebuggerViualizerParser>,
159 Combine<DebuggerVisualizerParser>,
158160 Combine<FeatureParser>,
159161 Combine<ForceTargetFeatureParser>,
160162 Combine<LinkParser>,
compiler/rustc_attr_parsing/src/errors.rs-20
......@@ -132,26 +132,6 @@ pub(crate) struct EmptyAttributeList {
132132 pub valid_without_list: bool,
133133}
134134
135#[derive(Diagnostic)]
136#[diag("`#[{$name}]` attribute cannot be used on {$target}")]
137#[warning(
138 "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
139)]
140#[help("`#[{$name}]` can {$only}be applied to {$applied}")]
141pub(crate) struct InvalidTargetLint {
142 pub name: String,
143 pub target: &'static str,
144 pub applied: DiagArgValue,
145 pub only: &'static str,
146 #[suggestion(
147 "remove the attribute",
148 code = "",
149 applicability = "machine-applicable",
150 style = "tool-only"
151 )]
152 pub attr_span: Span,
153}
154
155135#[derive(Diagnostic)]
156136#[diag(
157137 "{$is_used_as_inner ->
compiler/rustc_attr_parsing/src/interface.rs+1
......@@ -351,6 +351,7 @@ impl<'sess> AttributeParser<'sess> {
351351 accept.safety,
352352 &mut emit_lint,
353353 );
354 self.check_attribute_stability(&attr_path, attr_span, accept.stability);
354355
355356 let Some(args) = ArgParser::from_attr_args(
356357 args,
compiler/rustc_attr_parsing/src/lib.rs+1
......@@ -111,6 +111,7 @@ mod early_parsed;
111111mod errors;
112112mod safety;
113113mod session_diagnostics;
114mod stability;
114115mod target_checking;
115116pub mod validate_attr;
116117
compiler/rustc_attr_parsing/src/session_diagnostics.rs+4-7
......@@ -323,13 +323,6 @@ pub(crate) struct ObjcSelectorExpectedStringLiteral {
323323 pub span: Span,
324324}
325325
326#[derive(Diagnostic)]
327#[diag("stability attributes may not be used outside of the standard library", code = E0734)]
328pub(crate) struct StabilityOutsideStd {
329 #[primary_span]
330 pub span: Span,
331}
332
333326#[derive(Diagnostic)]
334327#[diag("expected at least one confusable name")]
335328pub(crate) struct EmptyConfusables {
......@@ -353,6 +346,10 @@ pub(crate) struct InvalidTarget {
353346 pub target: &'static str,
354347 pub applied: DiagArgValue,
355348 pub only: &'static str,
349 #[warning(
350 "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
351 )]
352 pub previously_accepted: bool,
356353}
357354
358355#[derive(Diagnostic)]
compiler/rustc_attr_parsing/src/stability.rs created+77
......@@ -0,0 +1,77 @@
1use rustc_feature::AttributeStability;
2use rustc_hir::AttrPath;
3use rustc_session::errors::feature_err;
4use rustc_span::{Span, sym};
5
6use crate::{AttributeParser, ShouldEmit};
7
8#[macro_export]
9macro_rules! unstable {
10 ($feat: ident $(, $notes:expr)*) => {
11 AttributeStability::Unstable {
12 gate_name: rustc_span::sym::$feat,
13 gate_check: rustc_feature::Features::$feat,
14 notes: &[$($notes),*],
15 }
16 };
17}
18
19impl<'sess> AttributeParser<'sess> {
20 pub fn check_attribute_stability(
21 &mut self,
22 attr_path: &AttrPath,
23 attr_span: Span,
24 expected_stability: AttributeStability,
25 ) {
26 if matches!(self.should_emit, ShouldEmit::Nothing) {
27 return;
28 }
29
30 let AttributeStability::Unstable { gate_check, gate_name, notes } = expected_stability
31 else {
32 return;
33 };
34
35 if gate_check(self.features()) || attr_span.allows_unstable(gate_name) {
36 return;
37 }
38
39 let (explain, default_notes): (String, &[String]) = match gate_name {
40 sym::rustc_attrs => ("use of an internal attribute".to_string(), &[
41 format!("the `#[{attr_path}]` attribute is an internal implementation detail that will never be stable"
42 )]),
43 sym::staged_api => ("stability attributes may not be used outside of the standard library".to_string(), &[]),
44 sym::custom_mir => ("the `#[custom_mir]` attribute is just used for the Rust test suite".to_string(), &[]),
45 sym::allow_internal_unsafe => ("allow_internal_unsafe side-steps the unsafe_code lint".to_string(), &[]),
46 sym::allow_internal_unstable => ("allow_internal_unstable side-steps feature gating and stability checks".to_string(), &[]),
47 sym::compiler_builtins => ("the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate which contains compiler-rt intrinsics and will never be stable".to_string(), &[]),
48 sym::custom_test_frameworks => ("custom test frameworks are an unstable feature".to_string(), &[]),
49 sym::linkage => ("the `linkage` attribute is experimental and not portable across platforms".to_string(), &[]),
50 sym::dropck_eyepatch => ("`may_dangle` has unstable semantics and may be removed in the future".to_string(), &[]),
51 sym::intrinsics => ("the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items".to_string(), &[]),
52 sym::lang_items => ("lang items are subject to change".to_string(), &[]),
53 sym::prelude_import => ("`#[prelude_import]` is for use by rustc only".to_string(), &[]),
54 sym::profiler_runtime => ("the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate which contains the profiler runtime and will never be stable".to_string(), &[]),
55 sym::thread_local => ("`#[thread_local]` is an experimental feature, and does not currently handle destructors".to_string(), &[]),
56 _ => (format!("the `#[{attr_path}]` attribute is an experimental feature"), &[]),
57 };
58
59 let mut diag = feature_err(self.sess, gate_name, attr_span, explain);
60
61 // Remove the suggestion for `#![feature(staged_api)]` as these attributes are currently
62 // not usable outside std. If we do ever expose `#[stable]` etc under a different feature
63 // name then it would be unfortunate to have nightlies out there suggesting `staged_api`.
64 if gate_name == sym::staged_api {
65 diag.children.clear();
66 }
67
68 for note in default_notes {
69 diag.note(note.clone());
70 }
71 for note in notes {
72 diag.note(*note);
73 }
74
75 diag.emit();
76 }
77}
compiler/rustc_attr_parsing/src/target_checking.rs+24-42
......@@ -1,7 +1,7 @@
11use std::borrow::Cow;
22
33use rustc_ast::AttrStyle;
4use rustc_errors::{DiagArgValue, Diagnostic, MultiSpan, StashKey};
4use rustc_errors::{DiagArgValue, MultiSpan, StashKey};
55use rustc_feature::Features;
66use rustc_hir::attrs::AttributeKind;
77use rustc_hir::{AttrItem, Attribute, MethodKind, Target};
......@@ -9,8 +9,7 @@ use rustc_span::{BytePos, FileName, RemapPathScopeComponents, Span, Symbol, sym}
99
1010use crate::context::AcceptContext;
1111use crate::errors::{
12 InvalidAttrAtCrateLevel, InvalidTargetLint, ItemFollowingInnerAttr,
13 UnsupportedAttributesInWhere,
12 InvalidAttrAtCrateLevel, ItemFollowingInnerAttr, UnsupportedAttributesInWhere,
1413};
1514use crate::session_diagnostics::InvalidTarget;
1615use crate::target_checking::Policy::Allow;
......@@ -122,15 +121,26 @@ impl<'sess> AttributeParser<'sess> {
122121 .emit();
123122 }
124123
125 match allowed_targets.is_allowed(cx.target) {
126 AllowedResult::Allowed => {}
127 AllowedResult::Warn => {
128 let allowed_targets = allowed_targets.allowed_targets();
129 let (applied, only) =
130 allowed_targets_applied(allowed_targets, cx.target, cx.features);
131 let name = cx.attr_path.clone();
124 let result = allowed_targets.is_allowed(cx.target);
125 if matches!(result, AllowedResult::Allowed) {
126 return;
127 }
132128
133 let lint = if name.segments[0] == sym::deprecated
129 let allowed_targets = allowed_targets.allowed_targets();
130 let (applied, only) = allowed_targets_applied(allowed_targets, cx.target, cx.features);
131 let diag = InvalidTarget {
132 span: cx.attr_span.clone(),
133 name: cx.attr_path.clone(),
134 target: cx.target.plural_name(),
135 only: if only { "only " } else { "" },
136 applied: DiagArgValue::StrListSepByAnd(applied.into_iter().map(Cow::Owned).collect()),
137 previously_accepted: matches!(result, AllowedResult::Warn),
138 };
139
140 match result {
141 AllowedResult::Allowed => unreachable!("Should have early returned above"),
142 AllowedResult::Warn => {
143 let lint = if cx.attr_path.segments[0] == sym::deprecated
134144 && ![
135145 Target::Closure,
136146 Target::Expression,
......@@ -145,39 +155,11 @@ impl<'sess> AttributeParser<'sess> {
145155 rustc_session::lint::builtin::UNUSED_ATTRIBUTES
146156 };
147157
148 let attr_span = cx.attr_span;
149 let target = cx.target;
150 cx.emit_lint_with_sess(
151 lint,
152 move |dcx, level, _| {
153 InvalidTargetLint {
154 name: name.to_string(),
155 target: target.plural_name(),
156 only: if only { "only " } else { "" },
157 applied: DiagArgValue::StrListSepByAnd(
158 applied.iter().map(|i| Cow::Owned(i.to_string())).collect(),
159 ),
160 attr_span,
161 }
162 .into_diag(dcx, level)
163 },
164 attr_span,
165 );
158 let attr_span = cx.attr_span.clone();
159 cx.emit_lint(lint, diag, attr_span);
166160 }
167161 AllowedResult::Error => {
168 let allowed_targets = allowed_targets.allowed_targets();
169 let (applied, only) =
170 allowed_targets_applied(allowed_targets, cx.target, cx.features);
171 let name = cx.attr_path.clone();
172 cx.dcx().emit_err(InvalidTarget {
173 span: cx.attr_span.clone(),
174 name,
175 target: cx.target.plural_name(),
176 only: if only { "only " } else { "" },
177 applied: DiagArgValue::StrListSepByAnd(
178 applied.into_iter().map(Cow::Owned).collect(),
179 ),
180 });
162 cx.dcx().emit_err(diag);
181163 }
182164 }
183165 }
compiler/rustc_attr_parsing/src/validate_attr.rs+2-2
......@@ -9,7 +9,7 @@ use rustc_ast::{
99 self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
1010};
1111use rustc_errors::{Applicability, Diagnostic, PResult};
12use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, template};
12use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, template};
1313use rustc_hir::AttrPath;
1414use rustc_parse::parse_in;
1515use rustc_session::errors::report_lit_error;
......@@ -29,7 +29,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
2929
3030 // Check input tokens for built-in and key-value attributes.
3131 match builtin_attr_info {
32 Some(BuiltinAttribute { name, .. }) => {
32 Some(name) => {
3333 if AttributeParser::is_parsed_attribute(slice::from_ref(&name)) {
3434 return;
3535 }
compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs+2-3
......@@ -44,9 +44,9 @@ fn apply_attrs_to_abi_param(param: AbiParam, arg_attrs: ArgAttributes) -> AbiPar
4444
4545fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[(Size, AbiParam); 2]> {
4646 if let Some(offset_from_start) = cast.rest_offset {
47 assert!(cast.prefix[1..].iter().all(|p| p.is_none()));
47 assert_eq!(cast.prefix.len(), 1);
4848 assert_eq!(cast.rest.unit.size, cast.rest.total);
49 let first = cast.prefix[0].unwrap();
49 let first = cast.prefix[0];
5050 let second = cast.rest.unit;
5151 return smallvec![
5252 (Size::ZERO, reg_to_abi_param(first)),
......@@ -71,7 +71,6 @@ fn cast_target_to_abi_params(cast: &CastTarget) -> SmallVec<[(Size, AbiParam); 2
7171 let args = cast
7272 .prefix
7373 .iter()
74 .flatten()
7574 .map(|&reg| reg_to_abi_param(reg))
7675 .chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit)));
7776
compiler/rustc_codegen_gcc/src/abi.rs+2-2
......@@ -46,7 +46,7 @@ impl GccType for CastTarget {
4646 )
4747 };
4848
49 if self.prefix.iter().all(|x| x.is_none()) {
49 if self.prefix.is_empty() {
5050 // Simplify to a single unit when there is no prefix and size <= unit size
5151 if self.rest.total <= self.rest.unit.size {
5252 return rest_gcc_unit;
......@@ -62,7 +62,7 @@ impl GccType for CastTarget {
6262 let mut args: Vec<_> = self
6363 .prefix
6464 .iter()
65 .flat_map(|option_reg| option_reg.map(|reg| reg.gcc_type(cx)))
65 .map(|reg| reg.gcc_type(cx))
6666 .chain((0..rest_count).map(|_| rest_gcc_unit))
6767 .collect();
6868
compiler/rustc_codegen_llvm/src/abi.rs+2-3
......@@ -187,7 +187,7 @@ impl LlvmType for CastTarget {
187187
188188 // Simplify to a single unit or an array if there's no prefix.
189189 // This produces the same layout, but using a simpler type.
190 if self.prefix.iter().all(|x| x.is_none()) {
190 if self.prefix.is_empty() {
191191 // We can't do this if is_consecutive is set and the unit would get
192192 // split on the target. Currently, this is only relevant for i128
193193 // registers.
......@@ -199,8 +199,7 @@ impl LlvmType for CastTarget {
199199 }
200200
201201 // Generate a struct type with the prefix and the "rest" arguments.
202 let prefix_args =
203 self.prefix.iter().flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx)));
202 let prefix_args = self.prefix.iter().map(|reg| reg.llvm_type(cx));
204203 let rest_args = (0..rest_count).map(|_| rest_ll_unit);
205204 let args: Vec<_> = prefix_args.chain(rest_args).collect();
206205 cx.type_struct(&args, false)
compiler/rustc_codegen_llvm/src/consts.rs+1
......@@ -206,6 +206,7 @@ fn check_and_apply_linkage<'ll, 'tcx>(
206206 })
207207 });
208208 llvm::set_linkage(g2, llvm::Linkage::InternalLinkage);
209 llvm::set_unnamed_address(g2, llvm::UnnamedAddr::Global);
209210 llvm::set_initializer(g2, g1);
210211 g2
211212 } else if cx.tcx.sess.target.arch == Arch::X86
compiler/rustc_codegen_ssa/src/mir/block.rs+3-4
......@@ -2234,9 +2234,9 @@ fn load_cast<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
22342234) -> Bx::Value {
22352235 let cast_ty = bx.cast_backend_type(cast);
22362236 if let Some(offset_from_start) = cast.rest_offset {
2237 assert!(cast.prefix[1..].iter().all(|p| p.is_none()));
2237 assert_eq!(cast.prefix.len(), 1);
22382238 assert_eq!(cast.rest.unit.size, cast.rest.total);
2239 let first_ty = bx.reg_backend_type(&cast.prefix[0].unwrap());
2239 let first_ty = bx.reg_backend_type(&cast.prefix[0]);
22402240 let second_ty = bx.reg_backend_type(&cast.rest.unit);
22412241 let first = bx.load(first_ty, ptr, align);
22422242 let second_ptr = bx.inbounds_ptradd(ptr, bx.const_usize(offset_from_start.bytes()));
......@@ -2257,9 +2257,8 @@ pub fn store_cast<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
22572257 align: Align,
22582258) {
22592259 if let Some(offset_from_start) = cast.rest_offset {
2260 assert!(cast.prefix[1..].iter().all(|p| p.is_none()));
2260 assert_eq!(cast.prefix.len(), 1);
22612261 assert_eq!(cast.rest.unit.size, cast.rest.total);
2262 assert!(cast.prefix[0].is_some());
22632262 let first = bx.extract_value(value, 0);
22642263 let second = bx.extract_value(value, 1);
22652264 bx.store(first, ptr, align);
compiler/rustc_codegen_ssa/src/mir/naked_asm.rs+1-1
......@@ -451,7 +451,7 @@ fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_t
451451 PassMode::Cast { pad_i32, ref cast } => {
452452 // For wasm, Cast is used for single-field primitive wrappers like `struct Wrapper(i64);`
453453 assert!(!pad_i32, "not currently used by wasm calling convention");
454 assert!(cast.prefix[0].is_none(), "no prefix");
454 assert!(cast.prefix.is_empty(), "no prefix");
455455 assert_eq!(cast.rest.total, arg_abi.layout.size, "single item");
456456
457457 let wrapped_wasm_type = match cast.rest.unit.kind {
compiler/rustc_error_codes/src/error_codes/E0734.md+5-1
......@@ -1,8 +1,12 @@
1#### Note: this error code is no longer emitted by the compiler.
2
3This error code was replaced by the more generic E0658.
4
15A stability attribute has been used outside of the standard library.
26
37Erroneous code example:
48
5```compile_fail,E0734
9```compile_fail,E0658
610#[stable(feature = "a", since = "b")] // invalid
711#[unstable(feature = "b", issue = "none")] // invalid
812fn foo(){}
compiler/rustc_feature/src/builtin_attrs.rs+213-483
......@@ -2,9 +2,8 @@
22
33use std::sync::LazyLock;
44
5use AttributeGate::*;
65use rustc_ast::ast::Safety;
7use rustc_data_structures::fx::FxHashMap;
6use rustc_data_structures::fx::FxHashSet;
87use rustc_hir::AttrStyle;
98use rustc_span::{Symbol, sym};
109
......@@ -63,20 +62,18 @@ pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg
6362}
6463
6564#[derive(Clone, Debug, Copy)]
66pub enum AttributeGate {
67 /// A gated attribute which requires a feature gate to be enabled.
68 Gated {
69 /// The feature gate, for example `#![feature(rustc_attrs)]` for rustc_* attributes.
70 feature: Symbol,
71 /// The error message displayed when an attempt is made to use the attribute without its feature gate.
72 message: &'static str,
73 /// Check function to be called during the `PostExpansionVisitor` pass.
74 check: fn(&Features) -> bool,
65pub enum AttributeStability {
66 /// An attribute that is unstable behind a specified feature fagte
67 Unstable {
68 /// The feature gate, for example `rustc_attrs` for rustc_* attributes.
69 gate_name: Symbol,
70 /// Check function to be called during the `PostExpansionVisitor` pass, which will be one of the `Features::*` functions
71 gate_check: fn(&Features) -> bool,
7572 /// Notes to be displayed when an attempt is made to use the attribute without its feature gate.
7673 notes: &'static [&'static str],
7774 },
78 /// Ungated attribute, can be used on all release channels
79 Ungated,
75 /// A stable attribute, can be used on all release channels
76 Stable,
8077}
8178
8279// FIXME(jdonszelmann): move to rustc_hir::attrs
......@@ -195,608 +192,341 @@ macro_rules! template {
195192 } };
196193}
197194
198macro_rules! ungated {
199 ($attr:ident $(,)?) => {
200 BuiltinAttribute { name: sym::$attr, gate: Ungated }
201 };
202}
203
204macro_rules! gated {
205 ($attr:ident, $gate:ident, $message:expr $(,)?) => {
206 BuiltinAttribute {
207 name: sym::$attr,
208 gate: Gated {
209 feature: sym::$gate,
210 message: $message,
211 check: Features::$gate,
212 notes: &[],
213 },
214 }
215 };
216 ($attr:ident, $message:expr $(,)?) => {
217 BuiltinAttribute {
218 name: sym::$attr,
219 gate: Gated {
220 feature: sym::$attr,
221 message: $message,
222 check: Features::$attr,
223 notes: &[],
224 },
225 }
226 };
227}
228
229macro_rules! rustc_attr {
230 (TEST, $attr:ident $(,)?) => {
231 rustc_attr!(
232 $attr,
233 concat!(
234 "the `#[",
235 stringify!($attr),
236 "]` attribute is used for rustc unit tests"
237 ),
238 )
239 };
240 ($attr:ident $(, $notes:expr)* $(,)?) => {
241 BuiltinAttribute {
242 name: sym::$attr,
243 gate: Gated {
244 feature: sym::rustc_attrs,
245 message: "use of an internal attribute",
246 check: Features::rustc_attrs,
247 notes: &[
248 concat!("the `#[",
249 stringify!($attr),
250 "]` attribute is an internal implementation detail that will never be stable"),
251 $($notes),*
252 ]
253 },
254 }
255 };
256}
257
258macro_rules! experimental {
259 ($attr:ident) => {
260 concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature")
261 };
262}
263
264pub struct BuiltinAttribute {
265 pub name: Symbol,
266 pub gate: AttributeGate,
267}
268
269195/// Attributes that have a special meaning to rustc or rustdoc.
270196#[rustfmt::skip]
271pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
197pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[
272198 // ==========================================================================
273199 // Stable attributes:
274200 // ==========================================================================
275201
276202 // Conditional compilation:
277 ungated!(cfg),
278 ungated!(cfg_attr),
203 sym::cfg,
204 sym::cfg_attr,
279205
280206 // Testing:
281 ungated!(ignore),
282 ungated!(should_panic),
207 sym::ignore,
208 sym::should_panic,
283209
284210 // Macros:
285 ungated!(automatically_derived),
286 ungated!(macro_use),
287 ungated!(macro_escape), // Deprecated synonym for `macro_use`.
288 ungated!(macro_export),
289 ungated!(proc_macro),
290 ungated!(proc_macro_derive),
291 ungated!(proc_macro_attribute),
211 sym::automatically_derived,
212 sym::macro_use,
213 sym::macro_escape, // Deprecated synonym for `macro_use`.
214 sym::macro_export,
215 sym::proc_macro,
216 sym::proc_macro_derive,
217 sym::proc_macro_attribute,
292218
293219 // Lints:
294 ungated!(warn),
295 ungated!(allow),
296 ungated!(expect),
297 ungated!(forbid),
298 ungated!(deny),
299 ungated!(must_use),
300 gated!(must_not_suspend, experimental!(must_not_suspend)),
301 ungated!(deprecated),
220 sym::warn,
221 sym::allow,
222 sym::expect,
223 sym::forbid,
224 sym::deny,
225 sym::must_use,
226 sym::must_not_suspend,
227 sym::deprecated,
302228
303229 // Crate properties:
304 ungated!(crate_name),
305 ungated!(crate_type),
230 sym::crate_name,
231 sym::crate_type,
306232
307233 // ABI, linking, symbols, and FFI
308 ungated!(link),
309 ungated!(link_name),
310 ungated!(no_link),
311 ungated!(repr),
234 sym::link,
235 sym::link_name,
236 sym::no_link,
237 sym::repr,
312238 // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
313 gated!(rustc_align, fn_align, experimental!(rustc_align)),
314 gated!(rustc_align_static, static_align, experimental!(rustc_align_static)),
315 ungated!(export_name),
316 ungated!(link_section),
317 ungated!(no_mangle),
318 ungated!(used),
319 ungated!(link_ordinal),
320 ungated!(naked),
239 sym::rustc_align,
240 sym::rustc_align_static,
241 sym::export_name,
242 sym::link_section,
243 sym::no_mangle,
244 sym::used,
245 sym::link_ordinal,
246 sym::naked,
321247 // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details.
322 rustc_attr!(rustc_pass_indirectly_in_non_rustic_abis, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs"),
248 sym::rustc_pass_indirectly_in_non_rustic_abis,
323249
324250 // Limits:
325 ungated!(recursion_limit),
326 ungated!(type_length_limit),
327 gated!(move_size_limit, large_assignments, experimental!(move_size_limit)),
251 sym::recursion_limit,
252 sym::type_length_limit,
253 sym::move_size_limit,
328254
329255 // Entry point:
330 ungated!(no_main),
256 sym::no_main,
331257
332258 // Modules, prelude, and resolution:
333 ungated!(path),
334 ungated!(no_std),
335 ungated!(no_implicit_prelude),
336 ungated!(non_exhaustive),
259 sym::path,
260 sym::no_std,
261 sym::no_implicit_prelude,
262 sym::non_exhaustive,
337263
338264 // Runtime
339 ungated!(windows_subsystem),
340 ungated!(panic_handler), // RFC 2070
265 sym::windows_subsystem,
266 sym::panic_handler, // RFC 2070
341267
342268 // Code generation:
343 ungated!(inline),
344 ungated!(cold),
345 ungated!(no_builtins),
346 ungated!(target_feature),
347 ungated!(track_caller),
348 ungated!(instruction_set),
349 gated!(force_target_feature, effective_target_features, experimental!(force_target_feature)),
350 gated!(sanitize, sanitize, experimental!(sanitize)),
351 gated!(coverage, coverage_attribute, experimental!(coverage)),
352
353 ungated!(doc),
269 sym::inline,
270 sym::cold,
271 sym::no_builtins,
272 sym::target_feature,
273 sym::track_caller,
274 sym::instruction_set,
275 sym::force_target_feature,
276 sym::sanitize,
277 sym::coverage,
278
279 sym::doc,
354280
355281 // Debugging
356 ungated!(debugger_visualizer),
357 ungated!(collapse_debuginfo),
282 sym::debugger_visualizer,
283 sym::collapse_debuginfo,
358284
359285 // ==========================================================================
360286 // Unstable attributes:
361287 // ==========================================================================
362288
363289 // Linking:
364 gated!(export_stable, experimental!(export_stable)),
290 sym::export_stable,
365291
366292 // Testing:
367 gated!(test_runner, custom_test_frameworks, "custom test frameworks are an unstable feature"),
293 sym::test_runner,
368294
369 gated!(reexport_test_harness_main, custom_test_frameworks, "custom test frameworks are an unstable feature"),
295 sym::reexport_test_harness_main,
370296
371297 // RFC #1268
372 gated!(marker, marker_trait_attr, experimental!(marker)),
373 gated!(thread_local, "`#[thread_local]` is an experimental feature, and does not currently handle destructors"),
374 gated!(no_core, experimental!(no_core)),
298 sym::marker,
299 sym::thread_local,
300 sym::no_core,
375301 // RFC 2412
376 gated!(optimize, optimize_attribute, experimental!(optimize)),
302 sym::optimize,
377303
378 gated!(ffi_pure, experimental!(ffi_pure)),
379 gated!(ffi_const, experimental!(ffi_const)),
380 gated!(register_tool, experimental!(register_tool)),
304 sym::ffi_pure,
305 sym::ffi_const,
306 sym::register_tool,
381307 // `#[cfi_encoding = ""]`
382 gated!(cfi_encoding, experimental!(cfi_encoding)),
308 sym::cfi_encoding,
383309
384310 // `#[coroutine]` attribute to be applied to closures to make them coroutines instead
385 gated!(coroutine, coroutines, experimental!(coroutine)),
311 sym::coroutine,
386312
387313 // RFC 3543
388314 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
389 gated!(patchable_function_entry, experimental!(patchable_function_entry)),
315 sym::patchable_function_entry,
390316
391317 // The `#[loop_match]` and `#[const_continue]` attributes are part of the
392318 // lang experiment for RFC 3720 tracked in:
393319 //
394320 // - https://github.com/rust-lang/rust/issues/132306
395 gated!(const_continue, loop_match, experimental!(const_continue)),
396 gated!(loop_match, loop_match, experimental!(loop_match)),
321 sym::const_continue,
322 sym::loop_match,
397323
398324 // The `#[pin_v2]` attribute is part of the `pin_ergonomics` experiment
399325 // that allows structurally pinning, tracked in:
400326 //
401327 // - https://github.com/rust-lang/rust/issues/130494
402 gated!(pin_v2, pin_ergonomics, experimental!(pin_v2)),
328 sym::pin_v2,
403329
404330 // ==========================================================================
405331 // Internal attributes: Stability, deprecation, and unsafe:
406332 // ==========================================================================
407333
408 ungated!(feature),
334 sym::feature,
409335 // DuplicatesOk since it has its own validation
410 ungated!(stable),
411 ungated!(unstable),
412 ungated!(unstable_feature_bound),
413 ungated!(unstable_removed),
414 ungated!(rustc_const_unstable),
415 ungated!(rustc_const_stable),
416 ungated!(rustc_default_body_unstable),
417 gated!(
418 allow_internal_unstable,
419 "allow_internal_unstable side-steps feature gating and stability checks",
420 ),
421 gated!(
422 allow_internal_unsafe,
423 "allow_internal_unsafe side-steps the unsafe_code lint",
424 ),
425 gated!(
426 rustc_eii_foreign_item,
427 eii_internals,
428 "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
429 ),
430 rustc_attr!(
431 rustc_allowed_through_unstable_modules,
432 "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
433 through unstable paths"
434 ),
435 rustc_attr!(
436 rustc_deprecated_safe_2024,
437 "`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary",
438 ),
439 rustc_attr!(
440 rustc_pub_transparent,
441 "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
442 ),
336 sym::stable,
337 sym::unstable,
338 sym::unstable_feature_bound,
339 sym::unstable_removed,
340 sym::rustc_const_unstable,
341 sym::rustc_const_stable,
342 sym::rustc_default_body_unstable,
343 sym::allow_internal_unstable,
344 sym::allow_internal_unsafe,
345 sym::rustc_eii_foreign_item,
346 sym::rustc_allowed_through_unstable_modules,
347 sym::rustc_deprecated_safe_2024,
348 sym::rustc_pub_transparent,
443349
444350
445351 // ==========================================================================
446352 // Internal attributes: Type system related:
447353 // ==========================================================================
448354
449 gated!(fundamental, experimental!(fundamental)),
450 gated!(
451 may_dangle,
452 dropck_eyepatch,
453 "`may_dangle` has unstable semantics and may be removed in the future",
454 ),
355 sym::fundamental,
356 sym::may_dangle,
455357
456 rustc_attr!(
457 rustc_never_type_options,
458 "`rustc_never_type_options` is used to experiment with never type fallback and work on \
459 never type stabilization"
460 ),
358 sym::rustc_never_type_options,
461359
462360 // ==========================================================================
463361 // Internal attributes: Runtime related:
464362 // ==========================================================================
465363
466 rustc_attr!(rustc_allocator),
467 rustc_attr!(rustc_nounwind),
468 rustc_attr!(rustc_reallocator),
469 rustc_attr!(rustc_deallocator),
470 rustc_attr!(rustc_allocator_zeroed),
471 rustc_attr!(rustc_allocator_zeroed_variant),
472 gated!(
473 default_lib_allocator,
474 allocator_internals, experimental!(default_lib_allocator),
475 ),
476 gated!(
477 needs_allocator,
478 allocator_internals, experimental!(needs_allocator),
479 ),
480 gated!(
481 panic_runtime,
482 experimental!(panic_runtime)
483 ),
484 gated!(
485 needs_panic_runtime,
486 experimental!(needs_panic_runtime)
487 ),
488 gated!(
489 compiler_builtins,
490 "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
491 which contains compiler-rt intrinsics and will never be stable",
492 ),
493 gated!(
494 profiler_runtime,
495 "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
496 which contains the profiler runtime and will never be stable",
497 ),
364 sym::rustc_allocator,
365 sym::rustc_nounwind,
366 sym::rustc_reallocator,
367 sym::rustc_deallocator,
368 sym::rustc_allocator_zeroed,
369 sym::rustc_allocator_zeroed_variant,
370 sym::default_lib_allocator,
371 sym::needs_allocator,
372 sym::panic_runtime,
373 sym::needs_panic_runtime,
374 sym::compiler_builtins,
375 sym::profiler_runtime,
498376
499377 // ==========================================================================
500378 // Internal attributes, Linkage:
501379 // ==========================================================================
502380
503 gated!(
504 linkage,
505 "the `linkage` attribute is experimental and not portable across platforms",
506 ),
507 rustc_attr!(rustc_std_internal_symbol),
508 rustc_attr!(rustc_objc_class),
509 rustc_attr!(rustc_objc_selector),
381 sym::linkage,
382 sym::rustc_std_internal_symbol,
383 sym::rustc_objc_class,
384 sym::rustc_objc_selector,
510385
511386 // ==========================================================================
512387 // Internal attributes, Macro related:
513388 // ==========================================================================
514389
515 rustc_attr!(rustc_builtin_macro),
516 rustc_attr!(rustc_proc_macro_decls),
517 rustc_attr!(
518 rustc_macro_transparency,
519 "used internally for testing macro hygiene",
520 ),
521 rustc_attr!(rustc_autodiff),
522 rustc_attr!(rustc_offload_kernel),
390 sym::rustc_builtin_macro,
391 sym::rustc_proc_macro_decls,
392 sym::rustc_macro_transparency,
393 sym::rustc_autodiff,
394 sym::rustc_offload_kernel,
523395 // Traces that are left when `cfg` and `cfg_attr` attributes are expanded.
524396 // The attributes are not gated, to avoid stability errors, but they cannot be used in stable
525397 // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they
526398 // can only be generated by the compiler.
527 ungated!(cfg_trace),
528 ungated!(cfg_attr_trace),
399 sym::cfg_trace,
400 sym::cfg_attr_trace,
529401
530402 // ==========================================================================
531403 // Internal attributes, Diagnostics related:
532404 // ==========================================================================
533405
534 rustc_attr!(
535 rustc_on_unimplemented,
536 "see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute"
537 ),
538 rustc_attr!(rustc_confusables),
406 sym::rustc_on_unimplemented,
407 sym::rustc_confusables,
539408 // Enumerates "identity-like" conversion methods to suggest on type mismatch.
540 rustc_attr!(rustc_conversion_suggestion),
409 sym::rustc_conversion_suggestion,
541410 // Prevents field reads in the marked trait or method to be considered
542411 // during dead code analysis.
543 rustc_attr!(rustc_trivial_field_reads),
412 sym::rustc_trivial_field_reads,
544413 // Used by the `rustc::potential_query_instability` lint to warn methods which
545414 // might not be stable during incremental compilation.
546 rustc_attr!(rustc_lint_query_instability),
415 sym::rustc_lint_query_instability,
547416 // Used by the `rustc::untracked_query_information` lint to warn methods which
548417 // might not be stable during incremental compilation.
549 rustc_attr!(rustc_lint_untracked_query_information),
418 sym::rustc_lint_untracked_query_information,
550419 // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions`
551420 // types (as well as any others in future).
552 rustc_attr!(rustc_lint_opt_ty),
421 sym::rustc_lint_opt_ty,
553422 // Used by the `rustc::bad_opt_access` lint on fields
554423 // types (as well as any others in future).
555 rustc_attr!(rustc_lint_opt_deny_field_access),
424 sym::rustc_lint_opt_deny_field_access,
556425
557426 // ==========================================================================
558427 // Internal attributes, Const related:
559428 // ==========================================================================
560429
561 rustc_attr!(rustc_promotable),
562 rustc_attr!(rustc_legacy_const_generics),
430 sym::rustc_promotable,
431 sym::rustc_legacy_const_generics,
563432 // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`.
564 rustc_attr!(
565 rustc_do_not_const_check,
566 "`#[rustc_do_not_const_check]` skips const-check for this function's body",
567 ),
568 rustc_attr!(
569 rustc_const_stable_indirect,
570 "this is an internal implementation detail",
571 ),
572 rustc_attr!(
573 rustc_intrinsic_const_stable_indirect,
574 "this is an internal implementation detail",
575 ),
576 rustc_attr!(
577 rustc_allow_const_fn_unstable,
578 "rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
579 ),
433 sym::rustc_do_not_const_check,
434 sym::rustc_const_stable_indirect,
435 sym::rustc_intrinsic_const_stable_indirect,
436 sym::rustc_allow_const_fn_unstable,
580437
581438 // ==========================================================================
582439 // Internal attributes, Layout related:
583440 // ==========================================================================
584441
585 rustc_attr!(
586 rustc_simd_monomorphize_lane_limit,
587 "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \
588 for better error messages",
589 ),
590 rustc_attr!(
591 rustc_nonnull_optimization_guaranteed,
592 "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \
593 guaranteed niche optimizations in the standard library",
594 "the compiler does not even check whether the type indeed is being non-null-optimized; \
595 it is your responsibility to ensure that the attribute is only used on types that are optimized",
596 ),
442 sym::rustc_simd_monomorphize_lane_limit,
443 sym::rustc_nonnull_optimization_guaranteed,
597444
598445 // ==========================================================================
599446 // Internal attributes, Misc:
600447 // ==========================================================================
601 gated!(
602 lang, lang_items,
603 "lang items are subject to change",
604 ),
605 rustc_attr!(
606 rustc_as_ptr,
607 "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations"
608 ),
609 rustc_attr!(
610 rustc_should_not_be_called_on_const_items,
611 "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts"
612 ),
613 rustc_attr!(
614 rustc_pass_by_value,
615 "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference"
616 ),
617 rustc_attr!(
618 rustc_never_returns_null_ptr,
619 "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers"
620 ),
621 rustc_attr!(
622 rustc_no_implicit_autorefs,
623 "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument"
624 ),
625 rustc_attr!(
626 rustc_coherence_is_core,
627 "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`"
628 ),
629 rustc_attr!(
630 rustc_coinductive,
631 "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver"
632 ),
633 rustc_attr!(
634 rustc_allow_incoherent_impl,
635 "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl"
636 ),
637 rustc_attr!(
638 rustc_preserve_ub_checks,
639 "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR",
640 ),
641 rustc_attr!(
642 rustc_deny_explicit_impl,
643 "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls"
644 ),
645 rustc_attr!(
646 rustc_dyn_incompatible_trait,
647 "`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \
648 even if it otherwise satisfies the requirements to be dyn-compatible."
649 ),
650 rustc_attr!(
651 rustc_has_incoherent_inherent_impls,
652 "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \
653 the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`"
654 ),
655 rustc_attr!(
656 rustc_non_const_trait_method,
657 "`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \
658 as non-const to allow large traits an easier transition to const"
659 ),
660
661 BuiltinAttribute {
662 name: sym::rustc_diagnostic_item,
663 gate: Gated {
664 feature: sym::rustc_attrs,
665 message: "use of an internal attribute",
666 check: Features::rustc_attrs,
667 notes: &["the `#[rustc_diagnostic_item]` attribute allows the compiler to reference types \
668 from the standard library for diagnostic purposes"],
669 },
670 },
671 gated!(
672 // Used in resolve:
673 prelude_import,
674 "`#[prelude_import]` is for use by rustc only",
675 ),
676 gated!(
677 rustc_paren_sugar,
678 unboxed_closures, "unboxed_closures are still evolving",
679 ),
680 rustc_attr!(
681 rustc_inherit_overflow_checks,
682 "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
683 overflow checking behavior of several functions in the standard library that are inlined \
684 across crates",
685 ),
686 rustc_attr!(
687 rustc_reservation_impl,
688 "the `#[rustc_reservation_impl]` attribute is internally used \
689 for reserving `impl<T> From<!> for T` as part of the effort to stabilize `!`"
690 ),
691 rustc_attr!(
692 rustc_test_marker,
693 "the `#[rustc_test_marker]` attribute is used internally to track tests",
694 ),
695 rustc_attr!(
696 rustc_unsafe_specialization_marker,
697 "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations"
698 ),
699 rustc_attr!(
700 rustc_specialization_trait,
701 "the `#[rustc_specialization_trait]` attribute is used to check specializations"
702 ),
703 rustc_attr!(
704 rustc_main,
705 "the `#[rustc_main]` attribute is used internally to specify test entry point function",
706 ),
707 rustc_attr!(
708 rustc_skip_during_method_dispatch,
709 "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \
710 from method dispatch when the receiver is of the following type, for compatibility in \
711 editions < 2021 (array) or editions < 2024 (boxed_slice)"
712 ),
713 rustc_attr!(
714 rustc_must_implement_one_of,
715 "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \
716 definition of a trait. Its syntax and semantics are highly experimental and will be \
717 subject to change before stabilization",
718 ),
719 rustc_attr!(
720 rustc_doc_primitive,
721 "the `#[rustc_doc_primitive]` attribute is used by the standard library \
722 to provide a way to generate documentation for primitive types",
723 ),
724 gated!(
725 rustc_intrinsic, intrinsics,
726 "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",
727 ),
728 rustc_attr!(
729 rustc_no_mir_inline,
730 "`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen"
731 ),
732 rustc_attr!(
733 rustc_force_inline,
734 "`#[rustc_force_inline]` forces a free function to be inlined"
735 ),
736 rustc_attr!(
737 rustc_scalable_vector,
738 "`#[rustc_scalable_vector]` defines a scalable vector type"
739 ),
740 rustc_attr!(
741 rustc_must_match_exhaustively,
742 "enums with `#[rustc_must_match_exhaustively]` must be matched on with a match block that mentions all variants explicitly"
743 ),
744 rustc_attr!(
745 rustc_no_writable,
746 "`#[rustc_no_writable]` stops the compiler from considering mutable reference arguments of this function as implicitly writable"
747 ),
448 sym::lang,
449 sym::rustc_as_ptr,
450 sym::rustc_should_not_be_called_on_const_items,
451 sym::rustc_pass_by_value,
452 sym::rustc_never_returns_null_ptr,
453 sym::rustc_no_implicit_autorefs,
454 sym::rustc_coherence_is_core,
455 sym::rustc_coinductive,
456 sym::rustc_allow_incoherent_impl,
457 sym::rustc_preserve_ub_checks,
458 sym::rustc_deny_explicit_impl,
459 sym::rustc_dyn_incompatible_trait,
460 sym::rustc_has_incoherent_inherent_impls,
461 sym::rustc_non_const_trait_method,
462
463 sym::rustc_diagnostic_item,
464 sym::prelude_import,
465 sym::rustc_paren_sugar,
466 sym::rustc_inherit_overflow_checks,
467 sym::rustc_reservation_impl,
468 sym::rustc_test_marker,
469 sym::rustc_unsafe_specialization_marker,
470 sym::rustc_specialization_trait,
471 sym::rustc_main,
472 sym::rustc_skip_during_method_dispatch,
473 sym::rustc_must_implement_one_of,
474 sym::rustc_doc_primitive,
475 sym::rustc_intrinsic,
476 sym::rustc_no_mir_inline,
477 sym::rustc_force_inline,
478 sym::rustc_scalable_vector,
479 sym::rustc_must_match_exhaustively,
480 sym::rustc_no_writable,
748481
749482 // ==========================================================================
750483 // Internal attributes, Testing:
751484 // ==========================================================================
752485
753 rustc_attr!(TEST, rustc_effective_visibility),
754 rustc_attr!(TEST, rustc_dump_inferred_outlives),
755 rustc_attr!(TEST, rustc_capture_analysis,),
756 rustc_attr!(TEST, rustc_insignificant_dtor),
757 rustc_attr!(TEST, rustc_no_implicit_bounds),
758 rustc_attr!(TEST, rustc_strict_coherence),
759 rustc_attr!(TEST, rustc_dump_variances),
760 rustc_attr!(TEST, rustc_dump_variances_of_opaques),
761 rustc_attr!(TEST, rustc_dump_hidden_type_of_opaques),
762 rustc_attr!(TEST, rustc_dump_layout),
763 rustc_attr!(TEST, rustc_abi),
764 rustc_attr!(TEST, rustc_regions),
765 rustc_attr!(TEST, rustc_delayed_bug_from_inside_query),
766 rustc_attr!(TEST, rustc_dump_user_args),
767 rustc_attr!(TEST, rustc_evaluate_where_clauses),
768 rustc_attr!(TEST, rustc_if_this_changed),
769 rustc_attr!(TEST, rustc_then_this_would_need),
770 rustc_attr!(TEST, rustc_clean),
771 rustc_attr!(TEST, rustc_partition_reused),
772 rustc_attr!(TEST, rustc_partition_codegened),
773 rustc_attr!(TEST, rustc_expected_cgu_reuse),
774 rustc_attr!(TEST, rustc_dump_symbol_name),
775 rustc_attr!(TEST, rustc_dump_def_path),
776 rustc_attr!(TEST, rustc_mir),
777 gated!(
778 custom_mir, "the `#[custom_mir]` attribute is just used for the Rust test suite",
779 ),
780 rustc_attr!(TEST, rustc_dump_item_bounds),
781 rustc_attr!(TEST, rustc_dump_predicates),
782 rustc_attr!(TEST, rustc_dump_def_parents),
783 rustc_attr!(TEST, rustc_dump_object_lifetime_defaults),
784 rustc_attr!(TEST, rustc_dump_vtable),
785 rustc_attr!(TEST, rustc_dummy),
786 rustc_attr!(TEST, pattern_complexity_limit),
486 sym::rustc_effective_visibility,
487 sym::rustc_dump_inferred_outlives,
488 sym::rustc_capture_analysis,
489 sym::rustc_insignificant_dtor,
490 sym::rustc_no_implicit_bounds,
491 sym::rustc_strict_coherence,
492 sym::rustc_dump_variances,
493 sym::rustc_dump_variances_of_opaques,
494 sym::rustc_dump_hidden_type_of_opaques,
495 sym::rustc_dump_layout,
496 sym::rustc_abi,
497 sym::rustc_regions,
498 sym::rustc_delayed_bug_from_inside_query,
499 sym::rustc_dump_user_args,
500 sym::rustc_evaluate_where_clauses,
501 sym::rustc_if_this_changed,
502 sym::rustc_then_this_would_need,
503 sym::rustc_clean,
504 sym::rustc_partition_reused,
505 sym::rustc_partition_codegened,
506 sym::rustc_expected_cgu_reuse,
507 sym::rustc_dump_symbol_name,
508 sym::rustc_dump_def_path,
509 sym::rustc_mir,
510 sym::custom_mir,
511 sym::rustc_dump_item_bounds,
512 sym::rustc_dump_predicates,
513 sym::rustc_dump_def_parents,
514 sym::rustc_dump_object_lifetime_defaults,
515 sym::rustc_dump_vtable,
516 sym::rustc_dummy,
517 sym::pattern_complexity_limit,
787518];
788519
789520pub fn is_builtin_attr_name(name: Symbol) -> bool {
790521 BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
791522}
792523
793pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
794 LazyLock::new(|| {
795 let mut map = FxHashMap::default();
796 for attr in BUILTIN_ATTRIBUTES.iter() {
797 if map.insert(attr.name, attr).is_some() {
798 panic!("duplicate builtin attribute `{}`", attr.name);
799 }
524pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashSet<Symbol>> = LazyLock::new(|| {
525 let mut map = FxHashSet::default();
526 for attr in BUILTIN_ATTRIBUTES.iter() {
527 if !map.insert(*attr) {
528 panic!("duplicate builtin attribute `{}`", attr);
800529 }
801 map
802 });
530 }
531 map
532});
compiler/rustc_feature/src/lib.rs+2-2
......@@ -129,8 +129,8 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZero<u
129129
130130pub use accepted::ACCEPTED_LANG_FEATURES;
131131pub use builtin_attrs::{
132 AttrSuggestionStyle, AttributeGate, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP,
133 BUILTIN_ATTRIBUTES, BuiltinAttribute, GatedCfg, find_gated_cfg, is_builtin_attr_name,
132 AttrSuggestionStyle, AttributeStability, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP,
133 BUILTIN_ATTRIBUTES, GatedCfg, find_gated_cfg, is_builtin_attr_name,
134134};
135135pub use removed::REMOVED_LANG_FEATURES;
136136pub use unstable::{
compiler/rustc_monomorphize/src/mono_checks/abi_check.rs+1-4
......@@ -25,10 +25,7 @@ fn passes_vectors_by_value(mode: &PassMode, repr: &BackendRepr) -> UsesVectorReg
2525 match mode {
2626 PassMode::Ignore | PassMode::Indirect { .. } => UsesVectorRegisters::No,
2727 PassMode::Cast { pad_i32: _, cast }
28 if cast
29 .prefix
30 .iter()
31 .any(|r| r.is_some_and(|x| matches!(x.kind, RegKind::Vector { .. })))
28 if cast.prefix.iter().any(|x| matches!(x.kind, RegKind::Vector { .. }))
3229 || matches!(cast.rest.unit.kind, RegKind::Vector { .. }) =>
3330 {
3431 UsesVectorRegisters::FixedVector
compiler/rustc_passes/src/eii.rs+1
......@@ -141,6 +141,7 @@ pub(crate) fn check_externally_implementable_items<'tcx>(tcx: TyCtxt<'tcx>, ():
141141 decl_crate_name: tcx.crate_name(decl_crate),
142142 // FIXME: shouldn't call `item_name`
143143 name: decl.name.name,
144 kind: tcx.def_kind(decl.foreign_item).descr(decl.foreign_item),
144145 span: decl.name.span,
145146 help: (),
146147 });
compiler/rustc_passes/src/errors.rs+2-1
......@@ -1209,12 +1209,13 @@ pub(crate) struct EiiWithTrackCaller {
12091209}
12101210
12111211#[derive(Diagnostic)]
1212#[diag("`#[{$name}]` required, but not found")]
1212#[diag("`#[{$name}]` {$kind} required, but not found")]
12131213pub(crate) struct EiiWithoutImpl {
12141214 #[primary_span]
12151215 #[label("expected because `#[{$name}]` was declared here in crate `{$decl_crate_name}`")]
12161216 pub span: Span,
12171217 pub name: Symbol,
1218 pub kind: &'static str,
12181219
12191220 pub current_crate_name: Symbol,
12201221 pub decl_crate_name: Symbol,
compiler/rustc_resolve/src/check_unused.rs+4-1
......@@ -438,7 +438,10 @@ impl Resolver<'_, '_> {
438438 && !tcx.is_panic_runtime(cnum)
439439 && !tcx.has_global_allocator(cnum)
440440 && !tcx.has_panic_handler(cnum)
441 && tcx.externally_implementable_items(cnum).is_empty()
441 && tcx
442 .externally_implementable_items(cnum)
443 .values()
444 .all(|(_, defs)| defs.is_empty())
442445 }) {
443446 maybe_unused_extern_crates.insert(id, import.span);
444447 }
compiler/rustc_resolve/src/diagnostics.rs+2-2
......@@ -1282,9 +1282,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12821282 // These trace attributes are compiler-generated and have
12831283 // deliberately invalid names.
12841284 .filter(|attr| {
1285 !matches!(attr.name, sym::cfg_trace | sym::cfg_attr_trace)
1285 !matches!(**attr, sym::cfg_trace | sym::cfg_attr_trace)
12861286 })
1287 .map(|attr| TypoSuggestion::typo_from_name(attr.name, res)),
1287 .map(|attr| TypoSuggestion::typo_from_name(*attr, res)),
12881288 );
12891289 }
12901290 }
compiler/rustc_resolve/src/effective_visibilities.rs+3-7
......@@ -278,9 +278,8 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
278278 // all the parents in the loop below are also guaranteed to be modules.
279279 let mut module_def_id = macro_module_def_id;
280280 loop {
281 let changed_reachability =
282 self.update_macro_reachable(module_def_id, macro_module_def_id, macro_ev);
283 if changed_reachability || module_def_id == CRATE_DEF_ID {
281 self.update_macro_reachable(module_def_id, macro_module_def_id, macro_ev);
282 if module_def_id == CRATE_DEF_ID {
284283 break;
285284 }
286285 module_def_id = self.r.tcx.local_parent(module_def_id);
......@@ -294,7 +293,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
294293 module_def_id: LocalDefId,
295294 defining_mod: LocalDefId,
296295 macro_ev: EffectiveVisibility,
297 ) -> bool {
296 ) {
298297 if self.macro_reachable.insert((module_def_id, defining_mod)) {
299298 let module = self.r.expect_module(module_def_id.to_def_id());
300299 for (_, name_resolution) in self.r.resolutions(module).borrow().iter() {
......@@ -311,9 +310,6 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
311310 self.update_macro_reachable_def(def_id, def_kind, vis, defining_mod, macro_ev);
312311 }
313312 }
314 true
315 } else {
316 false
317313 }
318314 }
319315
compiler/rustc_resolve/src/lib.rs+2-2
......@@ -1838,9 +1838,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18381838 builtin_attr_decls: BUILTIN_ATTRIBUTES
18391839 .iter()
18401840 .map(|builtin_attr| {
1841 let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name));
1841 let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(*builtin_attr));
18421842 let decl = arenas.new_pub_def_decl(res, DUMMY_SP, LocalExpnId::ROOT);
1843 (builtin_attr.name, decl)
1843 (*builtin_attr, decl)
18441844 })
18451845 .collect(),
18461846 registered_tool_decls: registered_tools
compiler/rustc_target/Cargo.toml+1
......@@ -5,6 +5,7 @@ edition = "2024"
55
66[dependencies]
77# tidy-alphabetical-start
8arrayvec = { version = "0.7", default-features = false }
89bitflags = "2.4.1"
910object = { version = "0.37.0", default-features = false, features = ["elf", "macho"] }
1011rustc_abi = { path = "../rustc_abi" }
compiler/rustc_target/src/callconv/mips64.rs+9-13
......@@ -1,3 +1,4 @@
1use arrayvec::ArrayVec;
12use rustc_abi::{
23 BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Size, TyAbiInterface,
34};
......@@ -81,8 +82,7 @@ where
8182{
8283 let dl = cx.data_layout();
8384 let size = arg.layout.size;
84 let mut prefix = [None; 8];
85 let mut prefix_index = 0;
85 let mut prefix = ArrayVec::new();
8686
8787 // Detect need for padding
8888 let align = Ord::clamp(arg.layout.align.abi, dl.i64_align, dl.i128_align);
......@@ -107,7 +107,7 @@ where
107107 // doubles not part of another aggregate are passed as floats.
108108 let mut last_offset = Size::ZERO;
109109
110 for i in 0..arg.layout.fields.count() {
110 'outer: for i in 0..arg.layout.fields.count() {
111111 let field = arg.layout.field(cx, i);
112112 let offset = arg.layout.fields.offset(i);
113113
......@@ -117,19 +117,15 @@ where
117117 if offset.is_aligned(dl.f64_align) {
118118 // Insert enough integers to cover [last_offset, offset)
119119 assert!(last_offset.is_aligned(dl.f64_align));
120 for _ in 0..((offset - last_offset).bits() / 64)
121 .min((prefix.len() - prefix_index) as u64)
122 {
123 prefix[prefix_index] = Some(Reg::i64());
124 prefix_index += 1;
120 for _ in 0..((offset - last_offset).bits() / 64) {
121 if prefix.try_push(Reg::i64()).is_err() {
122 break 'outer;
123 }
125124 }
126125
127 if prefix_index == prefix.len() {
126 if prefix.try_push(Reg::f64()).is_err() {
128127 break;
129128 }
130
131 prefix[prefix_index] = Some(Reg::f64());
132 prefix_index += 1;
133129 last_offset = offset + Reg::f64().size;
134130 }
135131 }
......@@ -139,7 +135,7 @@ where
139135 };
140136
141137 // Extract first 8 chunks as the prefix
142 let rest_size = size - Size::from_bytes(8) * prefix_index as u64;
138 let rest_size = size - Size::from_bytes(8) * prefix.len() as u64;
143139 arg.cast_to_and_pad_i32(
144140 CastTarget::prefixed(prefix, Uniform::new(Reg::i64(), rest_size)),
145141 pad_i32,
compiler/rustc_target/src/callconv/mod.rs+16-10
......@@ -1,5 +1,6 @@
11use std::{fmt, iter};
22
3use arrayvec::ArrayVec;
34use rustc_abi::{
45 AddressSpace, Align, BackendRepr, CanonAbi, ExternAbi, FieldsShape, HasDataLayout, Primitive,
56 Reg, RegKind, Scalar, Size, TyAbiInterface, TyAndLayout, Variants,
......@@ -264,7 +265,11 @@ impl Uniform {
264265/// (and all data in the padding between the registers is dropped).
265266#[derive(Clone, PartialEq, Eq, Hash, Debug, StableHash)]
266267pub struct CastTarget {
267 pub prefix: [Option<Reg>; 8],
268 // Note that this is fixed to 8 elements for now as ABIs currently don't
269 // need anything further beyond that, and when this code was originally
270 // refactored to use `ArrayVec` it was already using 8, so that stuck
271 // around.
272 pub prefix: ArrayVec<Reg, 8>,
268273 /// The offset of `rest` from the start of the value. Currently only implemented for a `Reg`
269274 /// pair created by the `offset_pair` method.
270275 pub rest_offset: Option<Size>,
......@@ -280,18 +285,20 @@ impl From<Reg> for CastTarget {
280285
281286impl From<Uniform> for CastTarget {
282287 fn from(uniform: Uniform) -> CastTarget {
283 Self::prefixed([None; 8], uniform)
288 Self::prefixed(Default::default(), uniform)
284289 }
285290}
286291
287292impl CastTarget {
288 pub fn prefixed(prefix: [Option<Reg>; 8], rest: Uniform) -> Self {
293 pub fn prefixed(prefix: ArrayVec<Reg, 8>, rest: Uniform) -> Self {
289294 Self { prefix, rest_offset: None, rest, attrs: ArgAttributes::new() }
290295 }
291296
292297 pub fn offset_pair(a: Reg, offset_from_start: Size, b: Reg) -> Self {
298 let mut prefix = ArrayVec::new();
299 prefix.push(a);
293300 Self {
294 prefix: [Some(a), None, None, None, None, None, None, None],
301 prefix,
295302 rest_offset: Some(offset_from_start),
296303 rest: b.into(),
297304 attrs: ArgAttributes::new(),
......@@ -304,7 +311,9 @@ impl CastTarget {
304311 }
305312
306313 pub fn pair(a: Reg, b: Reg) -> CastTarget {
307 Self::prefixed([Some(a), None, None, None, None, None, None, None], Uniform::from(b))
314 let mut prefix = ArrayVec::new();
315 prefix.push(a);
316 Self::prefixed(prefix, Uniform::from(b))
308317 }
309318
310319 /// When you only access the range containing valid data, you can use this unaligned size;
......@@ -314,10 +323,7 @@ impl CastTarget {
314323 let prefix_size = if let Some(offset_from_start) = self.rest_offset {
315324 offset_from_start
316325 } else {
317 self.prefix
318 .iter()
319 .filter_map(|x| x.map(|reg| reg.size))
320 .fold(Size::ZERO, |acc, size| acc + size)
326 self.prefix.iter().map(|reg| reg.size).fold(Size::ZERO, |acc, size| acc + size)
321327 };
322328 // Remaining arguments are passed in chunks of the unit size
323329 let rest_size =
......@@ -333,7 +339,7 @@ impl CastTarget {
333339 pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
334340 self.prefix
335341 .iter()
336 .filter_map(|x| x.map(|reg| reg.align(cx)))
342 .map(|reg| reg.align(cx))
337343 .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), |acc, align| {
338344 acc.max(align)
339345 })
compiler/rustc_target/src/callconv/nvptx64.rs+7-8
......@@ -1,3 +1,4 @@
1use arrayvec::ArrayVec;
12use rustc_abi::{HasDataLayout, Reg, Size, TyAbiInterface};
23
34use super::CastTarget;
......@@ -41,10 +42,9 @@ fn classify_aggregate<Ty>(arg: &mut ArgAbi<'_, Ty>) {
4142 };
4243
4344 if align_bytes == size.bytes() {
44 arg.cast_to(CastTarget::prefixed(
45 [Some(reg), None, None, None, None, None, None, None],
46 Uniform::new(Reg::i8(), Size::ZERO),
47 ));
45 let mut prefix = ArrayVec::new();
46 prefix.push(reg);
47 arg.cast_to(CastTarget::prefixed(prefix, Uniform::new(Reg::i8(), Size::ZERO)));
4848 } else {
4949 arg.cast_to(Uniform::new(reg, size));
5050 }
......@@ -79,10 +79,9 @@ where
7979 };
8080 if arg.layout.size.bytes() / align_bytes == 1 {
8181 // Make sure we pass the struct as array at the LLVM IR level and not as a single integer.
82 arg.cast_to(CastTarget::prefixed(
83 [Some(unit), None, None, None, None, None, None, None],
84 Uniform::new(unit, Size::ZERO),
85 ));
82 let mut prefix = ArrayVec::new();
83 prefix.push(unit);
84 arg.cast_to(CastTarget::prefixed(prefix, Uniform::new(unit, Size::ZERO)));
8685 } else {
8786 arg.cast_to(Uniform::new(unit, arg.layout.size));
8887 }
compiler/rustc_target/src/callconv/sparc64.rs+12-19
......@@ -1,3 +1,4 @@
1use arrayvec::ArrayVec;
12use rustc_abi::{
23 Align, BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Size, TyAbiInterface,
34 TyAndLayout, Variants,
......@@ -147,12 +148,7 @@ fn classify_arg<'a, Ty, C>(
147148 let mut double_words = [DoubleWord::Words([Word::Integer; 2]); ARGUMENT_REGISTERS / 2];
148149 classify(cx, &arg.layout, Size::ZERO, &mut double_words);
149150
150 let mut regs = [None; ARGUMENT_REGISTERS];
151 let mut i = 0;
152 let mut push = |reg| {
153 regs[i] = Some(reg);
154 i += 1;
155 };
151 let mut regs = ArrayVec::new();
156152 let mut attrs = ArgAttribute::empty();
157153
158154 for (index, double_word) in double_words.into_iter().enumerate() {
......@@ -162,7 +158,7 @@ fn classify_arg<'a, Ty, C>(
162158 match double_word {
163159 // `f128` must be aligned to be assigned a float register.
164160 DoubleWord::F128Start if (start_double_word_count + index).is_multiple_of(2) => {
165 push(Reg::f128());
161 regs.push(Reg::f128());
166162 }
167163 DoubleWord::F128Start => {
168164 // Clang currently handles this case nonsensically, always returning a packed
......@@ -170,30 +166,27 @@ fn classify_arg<'a, Ty, C>(
170166 // the `long double` isn't aligned on the stack, which also makes all future
171167 // arguments get passed in the wrong registers. This passes the `f128` in integer
172168 // registers when it is unaligned, same as with `f32` and `f64`.
173 push(Reg::i64());
174 push(Reg::i64());
169 regs.push(Reg::i64());
170 regs.push(Reg::i64());
175171 }
176172 DoubleWord::F128End => {} // Already handled by `F128Start`
177 DoubleWord::F64 => push(Reg::f64()),
178 DoubleWord::Words([Word::Integer, Word::Integer]) => push(Reg::i64()),
173 DoubleWord::F64 => regs.push(Reg::f64()),
174 DoubleWord::Words([Word::Integer, Word::Integer]) => regs.push(Reg::i64()),
179175 DoubleWord::Words(words) => {
180176 attrs |= ArgAttribute::InReg;
181177 for word in words {
182178 match word {
183 Word::F32 => push(Reg::f32()),
184 Word::Integer => push(Reg::i32()),
179 Word::F32 => regs.push(Reg::f32()),
180 Word::Integer => regs.push(Reg::i32()),
185181 }
186182 }
187183 }
188184 }
189185 }
190186
191 let cast_target = match regs {
192 [Some(reg), None, rest @ ..] => {
193 // Just a single register is needed for this value.
194 debug_assert!(rest.iter().all(|x| x.is_none()));
195 CastTarget::from(reg)
196 }
187 let cast_target = match regs.as_slice() {
188 // Just a single register is needed for this value.
189 [reg] => CastTarget::from(*reg),
197190 _ => CastTarget::prefixed(regs, Uniform::new(Reg::i8(), Size::ZERO)),
198191 };
199192
src/ci/github-actions/jobs.yml+1-1
......@@ -517,7 +517,7 @@ auto:
517517 - name: dist-aarch64-apple
518518 env:
519519 SCRIPT: >-
520 ./x.py dist bootstrap
520 ./x.py dist bootstrap enzyme
521521 --include-default-paths
522522 --host=aarch64-apple-darwin
523523 --target=aarch64-apple-darwin
src/doc/reference+1-1
......@@ -1 +1 @@
1Subproject commit ad35aca481751a06afeb23820a672b0f3b11a476
1Subproject commit 01b0ee707f4571e803c8b2c471d8335a448f5d60
src/doc/rust-by-example+1-1
......@@ -1 +1 @@
1Subproject commit 898f0ac1479223d332309e0fce88d44b39927d28
1Subproject commit d3117f6c873acbbf331c1d510371d061dfcc975c
src/librustdoc/html/render/mod.rs+22-4
......@@ -79,6 +79,7 @@ use crate::html::format::{
7979use crate::html::markdown::{
8080 HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine, short_markdown_summary,
8181};
82use crate::html::render::print_item::compare_names;
8283use crate::html::render::search_index::get_function_type_for_search;
8384use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD;
8485use crate::html::{highlight, sources};
......@@ -941,6 +942,16 @@ fn short_item_info(
941942 extra_info
942943}
943944
945// Prints the polarity and path of an impl's trait, if it has one, e.g. `Send`, `!Sync`.
946fn impl_trait_key(cx: &Context<'_>, i: &Impl) -> Option<String> {
947 let trait_ = i.inner_impl().trait_.as_ref()?;
948 let prefix = match i.inner_impl().polarity {
949 ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
950 ty::ImplPolarity::Negative => "!",
951 };
952 Some(format!("{prefix}{:#}", print_path(trait_, cx)))
953}
954
944955// Render the list of items inside one of the sections "Trait Implementations",
945956// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
946957fn render_impls(
......@@ -950,7 +961,9 @@ fn render_impls(
950961 containing_item: &clean::Item,
951962 toggle_open_by_default: bool,
952963) -> fmt::Result {
953 let mut rendered_impls = impls
964 // Render each impl alongside its `impl_trait_key`, which is used as the primary sorting key
965 // to match the impl order in the sidebar.
966 let mut keyed_rendered_impls = impls
954967 .iter()
955968 .map(|i| {
956969 let did = i.trait_did().unwrap();
......@@ -971,11 +984,16 @@ fn render_impls(
971984 toggle_open_by_default,
972985 },
973986 );
974 imp.to_string()
987 (impl_trait_key(cx, i).unwrap(), imp.to_string())
975988 })
976989 .collect::<Vec<_>>();
977 rendered_impls.sort();
978 w.write_str(&rendered_impls.join(""))
990
991 // Sort and then remove the `impl_trait_key`s, which are no longer needed after sorting.
992 keyed_rendered_impls
993 .sort_by(|(k1, h1), (k2, h2)| compare_names(k1, k2).then_with(|| h1.cmp(h2)));
994 let joined: String = keyed_rendered_impls.into_iter().map(|a| a.1).collect();
995
996 w.write_str(&joined)
979997}
980998
981999/// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item.
src/librustdoc/html/render/sidebar.rs+5-11
......@@ -6,10 +6,10 @@ use askama::Template;
66use rustc_data_structures::fx::FxHashSet;
77use rustc_hir::def::CtorKind;
88use rustc_hir::def_id::{DefIdMap, DefIdSet};
9use rustc_middle::ty::{self, TyCtxt};
9use rustc_middle::ty::TyCtxt;
1010use tracing::debug;
1111
12use super::{Context, ItemSection, item_ty_to_section};
12use super::{Context, ItemSection, impl_trait_key, item_ty_to_section};
1313use crate::clean;
1414use crate::formats::Impl;
1515use crate::formats::item_type::ItemType;
......@@ -707,15 +707,9 @@ fn sidebar_render_assoc_items(
707707
708708 let mut ret = impls
709709 .iter()
710 .filter_map(|it| {
711 let trait_ = it.inner_impl().trait_.as_ref()?;
712 let encoded = id_map.derive(super::get_id_for_impl(cx.tcx(), it.impl_item.item_id));
713
714 let prefix = match it.inner_impl().polarity {
715 ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
716 ty::ImplPolarity::Negative => "!",
717 };
718 let generated = Link::new(encoded, format!("{prefix}{:#}", print_path(trait_, cx)));
710 .filter_map(|i| {
711 let encoded = id_map.derive(super::get_id_for_impl(cx.tcx(), i.impl_item.item_id));
712 let generated = Link::new(encoded, impl_trait_key(cx, i)?);
719713 if links.insert(generated.clone()) { Some(generated) } else { None }
720714 })
721715 .collect::<Vec<Link<'static>>>();
src/tools/miri/.github/workflows/ci.yml+14-2
......@@ -155,6 +155,18 @@ jobs:
155155 cd ../rust # ./x does not seem to like being invoked from elsewhere
156156 ./x check miri
157157
158 # This job is intentionally separate from `test` so that Priroda can be
159 # developed as a separate crate inside the Miri repository for now.
160 priroda-build:
161 name: Priroda
162 runs-on: ubuntu-latest
163 steps:
164 - uses: actions/checkout@v6
165 - uses: ./.github/workflows/setup
166 - name: build Priroda
167 working-directory: priroda
168 run: cargo build --locked
169
158170 coverage:
159171 name: coverage report
160172 runs-on: ubuntu-latest
......@@ -168,7 +180,7 @@ jobs:
168180 # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
169181 # And they should be added below in `cron-fail-notify` as well.
170182 conclusion:
171 needs: [test, style, bootstrap, coverage]
183 needs: [test, style, bootstrap, coverage, priroda-build]
172184 # We need to ensure this job does *not* get skipped if its dependencies fail,
173185 # because a skipped job is considered a success by GitHub. So we have to
174186 # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
......@@ -252,7 +264,7 @@ jobs:
252264 cron-fail-notify:
253265 name: cronjob failure notification
254266 runs-on: ubuntu-latest
255 needs: [test, style, bootstrap, coverage]
267 needs: [test, style, bootstrap, coverage, priroda-build]
256268 if: ${{ github.event_name == 'schedule' && failure() }}
257269 steps:
258270 # Send a Zulip notification
src/tools/miri/README.md+4
......@@ -517,6 +517,10 @@ to Miri failing to detect cases of undefined behavior in a program.
517517 track interior mutable data on the level of references instead of on the
518518 byte-level as is done by default. Therefore, with this flag, Tree
519519 Borrows will be more permissive.
520* `-Zmiri-tree-borrows-relax-custom-allocator-uniqueness` disables uniqueness assumptions for
521 `Box<T, A>` where `A` is not `Global`. The exact aliasing rules for such custom allocators are
522 still up in the air, and by default Miri is conservative and rejects some allocator
523 implementations that incur relevant aliasing between the allocation and the allocator.
520524* `-Zmiri-force-page-size=<num>` overrides the default page size for an architecture, in multiples of 1k.
521525 `4` is default for most targets. This value should always be a power of 2 and nonzero.
522526
src/tools/miri/ci/ci.sh+3-4
......@@ -150,11 +150,10 @@ case $HOST_TARGET in
150150 i686-unknown-linux-gnu)
151151 # Host
152152 MIR_OPT=1 MANY_SEEDS=64 TEST_BENCH=1 CARGO_MIRI_ENV=1 run_tests
153 # Fully, but not officially, supported tier 2
153 # Not officially supported tier 2
154154 MANY_SEEDS=16 TEST_TARGET=aarch64-linux-android run_tests
155 # Partially supported targets (tier 2)
156 BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
157 UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
155 MANY_SEEDS=16 TEST_TARGET=loongarch64-unknown-linux-gnu run_tests
156 # Partially supported targets (no_std, tier 2)
158157 TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
159158 TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
160159 ;;
src/tools/miri/priroda/Cargo.lock created+1260
......@@ -0,0 +1,1260 @@
1# This file is automatically @generated by Cargo.
2# It is not intended for manual editing.
3version = 4
4
5[[package]]
6name = "aes"
7version = "0.9.0"
8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8"
10dependencies = [
11 "cipher",
12 "cpubits",
13 "cpufeatures",
14]
15
16[[package]]
17name = "anyhow"
18version = "1.0.102"
19source = "registry+https://github.com/rust-lang/crates.io-index"
20checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
21
22[[package]]
23name = "autocfg"
24version = "1.5.0"
25source = "registry+https://github.com/rust-lang/crates.io-index"
26checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
27
28[[package]]
29name = "bincode"
30version = "1.3.3"
31source = "registry+https://github.com/rust-lang/crates.io-index"
32checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
33dependencies = [
34 "serde",
35]
36
37[[package]]
38name = "bitflags"
39version = "2.11.1"
40source = "registry+https://github.com/rust-lang/crates.io-index"
41checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
42
43[[package]]
44name = "bumpalo"
45version = "3.20.2"
46source = "registry+https://github.com/rust-lang/crates.io-index"
47checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
48
49[[package]]
50name = "capstone"
51version = "0.14.0"
52source = "registry+https://github.com/rust-lang/crates.io-index"
53checksum = "f442ae0f2f3f1b923334b4a5386c95c69c1cfa072bafa23d6fae6d9682eb1dd4"
54dependencies = [
55 "capstone-sys",
56 "static_assertions",
57]
58
59[[package]]
60name = "capstone-sys"
61version = "0.18.0"
62source = "registry+https://github.com/rust-lang/crates.io-index"
63checksum = "a4e8087cab6731295f5a2a2bd82989ba4f41d3a428aab2e7c98d8f4db38aac05"
64dependencies = [
65 "cc",
66]
67
68[[package]]
69name = "cc"
70version = "1.2.62"
71source = "registry+https://github.com/rust-lang/crates.io-index"
72checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
73dependencies = [
74 "find-msvc-tools",
75 "shlex",
76]
77
78[[package]]
79name = "cfg-if"
80version = "1.0.4"
81source = "registry+https://github.com/rust-lang/crates.io-index"
82checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
83
84[[package]]
85name = "cfg_aliases"
86version = "0.2.1"
87source = "registry+https://github.com/rust-lang/crates.io-index"
88checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
89
90[[package]]
91name = "chacha20"
92version = "0.10.0"
93source = "registry+https://github.com/rust-lang/crates.io-index"
94checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
95dependencies = [
96 "cfg-if",
97 "cpufeatures",
98 "rand_core 0.10.1",
99]
100
101[[package]]
102name = "chrono"
103version = "0.4.44"
104source = "registry+https://github.com/rust-lang/crates.io-index"
105checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
106dependencies = [
107 "num-traits",
108]
109
110[[package]]
111name = "chrono-tz"
112version = "0.10.4"
113source = "registry+https://github.com/rust-lang/crates.io-index"
114checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3"
115dependencies = [
116 "chrono",
117 "phf",
118]
119
120[[package]]
121name = "cipher"
122version = "0.5.1"
123source = "registry+https://github.com/rust-lang/crates.io-index"
124checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea"
125dependencies = [
126 "crypto-common",
127 "inout",
128]
129
130[[package]]
131name = "cpubits"
132version = "0.1.1"
133source = "registry+https://github.com/rust-lang/crates.io-index"
134checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae"
135
136[[package]]
137name = "cpufeatures"
138version = "0.3.0"
139source = "registry+https://github.com/rust-lang/crates.io-index"
140checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
141dependencies = [
142 "libc",
143]
144
145[[package]]
146name = "crossbeam-channel"
147version = "0.5.15"
148source = "registry+https://github.com/rust-lang/crates.io-index"
149checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
150dependencies = [
151 "crossbeam-utils",
152]
153
154[[package]]
155name = "crossbeam-utils"
156version = "0.8.21"
157source = "registry+https://github.com/rust-lang/crates.io-index"
158checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
159
160[[package]]
161name = "crypto-common"
162version = "0.2.1"
163source = "registry+https://github.com/rust-lang/crates.io-index"
164checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710"
165dependencies = [
166 "hybrid-array",
167]
168
169[[package]]
170name = "directories"
171version = "6.0.0"
172source = "registry+https://github.com/rust-lang/crates.io-index"
173checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d"
174dependencies = [
175 "dirs-sys",
176]
177
178[[package]]
179name = "dirs-sys"
180version = "0.5.0"
181source = "registry+https://github.com/rust-lang/crates.io-index"
182checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
183dependencies = [
184 "libc",
185 "option-ext",
186 "redox_users",
187 "windows-sys",
188]
189
190[[package]]
191name = "equivalent"
192version = "1.0.2"
193source = "registry+https://github.com/rust-lang/crates.io-index"
194checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
195
196[[package]]
197name = "errno"
198version = "0.3.14"
199source = "registry+https://github.com/rust-lang/crates.io-index"
200checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
201dependencies = [
202 "libc",
203 "windows-sys",
204]
205
206[[package]]
207name = "fastrand"
208version = "2.4.1"
209source = "registry+https://github.com/rust-lang/crates.io-index"
210checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
211
212[[package]]
213name = "find-msvc-tools"
214version = "0.1.9"
215source = "registry+https://github.com/rust-lang/crates.io-index"
216checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
217
218[[package]]
219name = "fnv"
220version = "1.0.7"
221source = "registry+https://github.com/rust-lang/crates.io-index"
222checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
223
224[[package]]
225name = "foldhash"
226version = "0.1.5"
227source = "registry+https://github.com/rust-lang/crates.io-index"
228checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
229
230[[package]]
231name = "futures-core"
232version = "0.3.32"
233source = "registry+https://github.com/rust-lang/crates.io-index"
234checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
235
236[[package]]
237name = "futures-task"
238version = "0.3.32"
239source = "registry+https://github.com/rust-lang/crates.io-index"
240checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
241
242[[package]]
243name = "futures-util"
244version = "0.3.32"
245source = "registry+https://github.com/rust-lang/crates.io-index"
246checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
247dependencies = [
248 "futures-core",
249 "futures-task",
250 "pin-project-lite",
251 "slab",
252]
253
254[[package]]
255name = "getrandom"
256version = "0.2.17"
257source = "registry+https://github.com/rust-lang/crates.io-index"
258checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
259dependencies = [
260 "cfg-if",
261 "libc",
262 "wasi",
263]
264
265[[package]]
266name = "getrandom"
267version = "0.3.4"
268source = "registry+https://github.com/rust-lang/crates.io-index"
269checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
270dependencies = [
271 "cfg-if",
272 "libc",
273 "r-efi 5.3.0",
274 "wasip2",
275]
276
277[[package]]
278name = "getrandom"
279version = "0.4.2"
280source = "registry+https://github.com/rust-lang/crates.io-index"
281checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
282dependencies = [
283 "cfg-if",
284 "libc",
285 "r-efi 6.0.0",
286 "rand_core 0.10.1",
287 "wasip2",
288 "wasip3",
289]
290
291[[package]]
292name = "hashbrown"
293version = "0.15.5"
294source = "registry+https://github.com/rust-lang/crates.io-index"
295checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
296dependencies = [
297 "foldhash",
298]
299
300[[package]]
301name = "hashbrown"
302version = "0.17.1"
303source = "registry+https://github.com/rust-lang/crates.io-index"
304checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
305
306[[package]]
307name = "heck"
308version = "0.5.0"
309source = "registry+https://github.com/rust-lang/crates.io-index"
310checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
311
312[[package]]
313name = "hybrid-array"
314version = "0.4.12"
315source = "registry+https://github.com/rust-lang/crates.io-index"
316checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
317dependencies = [
318 "typenum",
319]
320
321[[package]]
322name = "id-arena"
323version = "2.3.0"
324source = "registry+https://github.com/rust-lang/crates.io-index"
325checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
326
327[[package]]
328name = "indexmap"
329version = "2.14.0"
330source = "registry+https://github.com/rust-lang/crates.io-index"
331checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
332dependencies = [
333 "equivalent",
334 "hashbrown 0.17.1",
335 "serde",
336 "serde_core",
337]
338
339[[package]]
340name = "inout"
341version = "0.2.2"
342source = "registry+https://github.com/rust-lang/crates.io-index"
343checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
344dependencies = [
345 "hybrid-array",
346]
347
348[[package]]
349name = "ipc-channel"
350version = "0.20.2"
351source = "registry+https://github.com/rust-lang/crates.io-index"
352checksum = "f93600b5616c2d075f8af8dbd23c1d69278c5d24e4913d220cbc60b14c95c180"
353dependencies = [
354 "bincode",
355 "crossbeam-channel",
356 "fnv",
357 "libc",
358 "mio",
359 "rand 0.9.4",
360 "serde",
361 "tempfile",
362 "uuid",
363 "windows",
364]
365
366[[package]]
367name = "itoa"
368version = "1.0.18"
369source = "registry+https://github.com/rust-lang/crates.io-index"
370checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
371
372[[package]]
373name = "js-sys"
374version = "0.3.98"
375source = "registry+https://github.com/rust-lang/crates.io-index"
376checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
377dependencies = [
378 "cfg-if",
379 "futures-util",
380 "once_cell",
381 "wasm-bindgen",
382]
383
384[[package]]
385name = "leb128fmt"
386version = "0.1.0"
387source = "registry+https://github.com/rust-lang/crates.io-index"
388checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
389
390[[package]]
391name = "libc"
392version = "0.2.186"
393source = "registry+https://github.com/rust-lang/crates.io-index"
394checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
395
396[[package]]
397name = "libffi"
398version = "5.1.0"
399source = "registry+https://github.com/rust-lang/crates.io-index"
400checksum = "0498fe5655f857803e156523e644dcdcdc3b3c7edda42ea2afdae2e09b2db87b"
401dependencies = [
402 "libc",
403 "libffi-sys",
404]
405
406[[package]]
407name = "libffi-sys"
408version = "4.1.0"
409source = "registry+https://github.com/rust-lang/crates.io-index"
410checksum = "71d4f1d4ce15091955144350b75db16a96d4a63728500122706fb4d29a26afbb"
411dependencies = [
412 "cc",
413]
414
415[[package]]
416name = "libloading"
417version = "0.9.0"
418source = "registry+https://github.com/rust-lang/crates.io-index"
419checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
420dependencies = [
421 "cfg-if",
422 "windows-link 0.2.1",
423]
424
425[[package]]
426name = "libredox"
427version = "0.1.16"
428source = "registry+https://github.com/rust-lang/crates.io-index"
429checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
430dependencies = [
431 "libc",
432]
433
434[[package]]
435name = "linux-raw-sys"
436version = "0.12.1"
437source = "registry+https://github.com/rust-lang/crates.io-index"
438checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
439
440[[package]]
441name = "lock_api"
442version = "0.4.14"
443source = "registry+https://github.com/rust-lang/crates.io-index"
444checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
445dependencies = [
446 "scopeguard",
447]
448
449[[package]]
450name = "log"
451version = "0.4.29"
452source = "registry+https://github.com/rust-lang/crates.io-index"
453checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
454
455[[package]]
456name = "measureme"
457version = "12.0.3"
458source = "registry+https://github.com/rust-lang/crates.io-index"
459checksum = "6ebd1ebda747ae161a4a377bf93f87e18d46faad2331cc0c7d25b84b1d445f49"
460dependencies = [
461 "log",
462 "memmap2",
463 "parking_lot",
464 "perf-event-open-sys",
465 "rustc-hash",
466 "smallvec",
467]
468
469[[package]]
470name = "memchr"
471version = "2.8.0"
472source = "registry+https://github.com/rust-lang/crates.io-index"
473checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
474
475[[package]]
476name = "memmap2"
477version = "0.2.3"
478source = "registry+https://github.com/rust-lang/crates.io-index"
479checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4"
480dependencies = [
481 "libc",
482]
483
484[[package]]
485name = "mio"
486version = "1.2.0"
487source = "registry+https://github.com/rust-lang/crates.io-index"
488checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
489dependencies = [
490 "libc",
491 "log",
492 "wasi",
493 "windows-sys",
494]
495
496[[package]]
497name = "miri"
498version = "0.1.0"
499dependencies = [
500 "aes",
501 "bitflags",
502 "capstone",
503 "chrono",
504 "chrono-tz",
505 "directories",
506 "getrandom 0.4.2",
507 "ipc-channel",
508 "libc",
509 "libffi",
510 "libloading",
511 "measureme",
512 "mio",
513 "nix",
514 "rand 0.10.1",
515 "serde",
516 "smallvec",
517]
518
519[[package]]
520name = "nix"
521version = "0.30.1"
522source = "registry+https://github.com/rust-lang/crates.io-index"
523checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
524dependencies = [
525 "bitflags",
526 "cfg-if",
527 "cfg_aliases",
528 "libc",
529]
530
531[[package]]
532name = "num-traits"
533version = "0.2.19"
534source = "registry+https://github.com/rust-lang/crates.io-index"
535checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
536dependencies = [
537 "autocfg",
538]
539
540[[package]]
541name = "once_cell"
542version = "1.21.4"
543source = "registry+https://github.com/rust-lang/crates.io-index"
544checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
545
546[[package]]
547name = "option-ext"
548version = "0.2.0"
549source = "registry+https://github.com/rust-lang/crates.io-index"
550checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
551
552[[package]]
553name = "parking_lot"
554version = "0.12.5"
555source = "registry+https://github.com/rust-lang/crates.io-index"
556checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
557dependencies = [
558 "lock_api",
559 "parking_lot_core",
560]
561
562[[package]]
563name = "parking_lot_core"
564version = "0.9.12"
565source = "registry+https://github.com/rust-lang/crates.io-index"
566checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
567dependencies = [
568 "cfg-if",
569 "libc",
570 "redox_syscall",
571 "smallvec",
572 "windows-link 0.2.1",
573]
574
575[[package]]
576name = "perf-event-open-sys"
577version = "3.0.0"
578source = "registry+https://github.com/rust-lang/crates.io-index"
579checksum = "b29be2ba35c12c6939f6bc73187f728bba82c3c062ecdc5fa90ea739282a1f58"
580dependencies = [
581 "libc",
582]
583
584[[package]]
585name = "phf"
586version = "0.12.1"
587source = "registry+https://github.com/rust-lang/crates.io-index"
588checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7"
589dependencies = [
590 "phf_shared",
591]
592
593[[package]]
594name = "phf_shared"
595version = "0.12.1"
596source = "registry+https://github.com/rust-lang/crates.io-index"
597checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981"
598dependencies = [
599 "siphasher",
600]
601
602[[package]]
603name = "pin-project-lite"
604version = "0.2.17"
605source = "registry+https://github.com/rust-lang/crates.io-index"
606checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
607
608[[package]]
609name = "ppv-lite86"
610version = "0.2.21"
611source = "registry+https://github.com/rust-lang/crates.io-index"
612checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
613dependencies = [
614 "zerocopy",
615]
616
617[[package]]
618name = "prettyplease"
619version = "0.2.37"
620source = "registry+https://github.com/rust-lang/crates.io-index"
621checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
622dependencies = [
623 "proc-macro2",
624 "syn",
625]
626
627[[package]]
628name = "priroda"
629version = "0.1.0"
630dependencies = [
631 "miri",
632]
633
634[[package]]
635name = "proc-macro2"
636version = "1.0.106"
637source = "registry+https://github.com/rust-lang/crates.io-index"
638checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
639dependencies = [
640 "unicode-ident",
641]
642
643[[package]]
644name = "quote"
645version = "1.0.45"
646source = "registry+https://github.com/rust-lang/crates.io-index"
647checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
648dependencies = [
649 "proc-macro2",
650]
651
652[[package]]
653name = "r-efi"
654version = "5.3.0"
655source = "registry+https://github.com/rust-lang/crates.io-index"
656checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
657
658[[package]]
659name = "r-efi"
660version = "6.0.0"
661source = "registry+https://github.com/rust-lang/crates.io-index"
662checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
663
664[[package]]
665name = "rand"
666version = "0.9.4"
667source = "registry+https://github.com/rust-lang/crates.io-index"
668checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
669dependencies = [
670 "rand_chacha",
671 "rand_core 0.9.5",
672]
673
674[[package]]
675name = "rand"
676version = "0.10.1"
677source = "registry+https://github.com/rust-lang/crates.io-index"
678checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
679dependencies = [
680 "chacha20",
681 "getrandom 0.4.2",
682 "rand_core 0.10.1",
683]
684
685[[package]]
686name = "rand_chacha"
687version = "0.9.0"
688source = "registry+https://github.com/rust-lang/crates.io-index"
689checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
690dependencies = [
691 "ppv-lite86",
692 "rand_core 0.9.5",
693]
694
695[[package]]
696name = "rand_core"
697version = "0.9.5"
698source = "registry+https://github.com/rust-lang/crates.io-index"
699checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
700dependencies = [
701 "getrandom 0.3.4",
702]
703
704[[package]]
705name = "rand_core"
706version = "0.10.1"
707source = "registry+https://github.com/rust-lang/crates.io-index"
708checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
709
710[[package]]
711name = "redox_syscall"
712version = "0.5.18"
713source = "registry+https://github.com/rust-lang/crates.io-index"
714checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
715dependencies = [
716 "bitflags",
717]
718
719[[package]]
720name = "redox_users"
721version = "0.5.2"
722source = "registry+https://github.com/rust-lang/crates.io-index"
723checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
724dependencies = [
725 "getrandom 0.2.17",
726 "libredox",
727 "thiserror",
728]
729
730[[package]]
731name = "rustc-hash"
732version = "1.1.0"
733source = "registry+https://github.com/rust-lang/crates.io-index"
734checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
735
736[[package]]
737name = "rustix"
738version = "1.1.4"
739source = "registry+https://github.com/rust-lang/crates.io-index"
740checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
741dependencies = [
742 "bitflags",
743 "errno",
744 "libc",
745 "linux-raw-sys",
746 "windows-sys",
747]
748
749[[package]]
750name = "rustversion"
751version = "1.0.22"
752source = "registry+https://github.com/rust-lang/crates.io-index"
753checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
754
755[[package]]
756name = "scopeguard"
757version = "1.2.0"
758source = "registry+https://github.com/rust-lang/crates.io-index"
759checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
760
761[[package]]
762name = "semver"
763version = "1.0.28"
764source = "registry+https://github.com/rust-lang/crates.io-index"
765checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
766
767[[package]]
768name = "serde"
769version = "1.0.228"
770source = "registry+https://github.com/rust-lang/crates.io-index"
771checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
772dependencies = [
773 "serde_core",
774 "serde_derive",
775]
776
777[[package]]
778name = "serde_core"
779version = "1.0.228"
780source = "registry+https://github.com/rust-lang/crates.io-index"
781checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
782dependencies = [
783 "serde_derive",
784]
785
786[[package]]
787name = "serde_derive"
788version = "1.0.228"
789source = "registry+https://github.com/rust-lang/crates.io-index"
790checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
791dependencies = [
792 "proc-macro2",
793 "quote",
794 "syn",
795]
796
797[[package]]
798name = "serde_json"
799version = "1.0.149"
800source = "registry+https://github.com/rust-lang/crates.io-index"
801checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
802dependencies = [
803 "itoa",
804 "memchr",
805 "serde",
806 "serde_core",
807 "zmij",
808]
809
810[[package]]
811name = "shlex"
812version = "1.3.0"
813source = "registry+https://github.com/rust-lang/crates.io-index"
814checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
815
816[[package]]
817name = "siphasher"
818version = "1.0.3"
819source = "registry+https://github.com/rust-lang/crates.io-index"
820checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
821
822[[package]]
823name = "slab"
824version = "0.4.12"
825source = "registry+https://github.com/rust-lang/crates.io-index"
826checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
827
828[[package]]
829name = "smallvec"
830version = "1.15.1"
831source = "registry+https://github.com/rust-lang/crates.io-index"
832checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
833
834[[package]]
835name = "static_assertions"
836version = "1.1.0"
837source = "registry+https://github.com/rust-lang/crates.io-index"
838checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
839
840[[package]]
841name = "syn"
842version = "2.0.117"
843source = "registry+https://github.com/rust-lang/crates.io-index"
844checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
845dependencies = [
846 "proc-macro2",
847 "quote",
848 "unicode-ident",
849]
850
851[[package]]
852name = "tempfile"
853version = "3.27.0"
854source = "registry+https://github.com/rust-lang/crates.io-index"
855checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
856dependencies = [
857 "fastrand",
858 "getrandom 0.4.2",
859 "once_cell",
860 "rustix",
861 "windows-sys",
862]
863
864[[package]]
865name = "thiserror"
866version = "2.0.18"
867source = "registry+https://github.com/rust-lang/crates.io-index"
868checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
869dependencies = [
870 "thiserror-impl",
871]
872
873[[package]]
874name = "thiserror-impl"
875version = "2.0.18"
876source = "registry+https://github.com/rust-lang/crates.io-index"
877checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
878dependencies = [
879 "proc-macro2",
880 "quote",
881 "syn",
882]
883
884[[package]]
885name = "typenum"
886version = "1.20.0"
887source = "registry+https://github.com/rust-lang/crates.io-index"
888checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
889
890[[package]]
891name = "unicode-ident"
892version = "1.0.24"
893source = "registry+https://github.com/rust-lang/crates.io-index"
894checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
895
896[[package]]
897name = "unicode-xid"
898version = "0.2.6"
899source = "registry+https://github.com/rust-lang/crates.io-index"
900checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
901
902[[package]]
903name = "uuid"
904version = "1.23.1"
905source = "registry+https://github.com/rust-lang/crates.io-index"
906checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
907dependencies = [
908 "getrandom 0.4.2",
909 "js-sys",
910 "wasm-bindgen",
911]
912
913[[package]]
914name = "wasi"
915version = "0.11.1+wasi-snapshot-preview1"
916source = "registry+https://github.com/rust-lang/crates.io-index"
917checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
918
919[[package]]
920name = "wasip2"
921version = "1.0.3+wasi-0.2.9"
922source = "registry+https://github.com/rust-lang/crates.io-index"
923checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
924dependencies = [
925 "wit-bindgen 0.57.1",
926]
927
928[[package]]
929name = "wasip3"
930version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
931source = "registry+https://github.com/rust-lang/crates.io-index"
932checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
933dependencies = [
934 "wit-bindgen 0.51.0",
935]
936
937[[package]]
938name = "wasm-bindgen"
939version = "0.2.121"
940source = "registry+https://github.com/rust-lang/crates.io-index"
941checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790"
942dependencies = [
943 "cfg-if",
944 "once_cell",
945 "rustversion",
946 "wasm-bindgen-macro",
947 "wasm-bindgen-shared",
948]
949
950[[package]]
951name = "wasm-bindgen-macro"
952version = "0.2.121"
953source = "registry+https://github.com/rust-lang/crates.io-index"
954checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578"
955dependencies = [
956 "quote",
957 "wasm-bindgen-macro-support",
958]
959
960[[package]]
961name = "wasm-bindgen-macro-support"
962version = "0.2.121"
963source = "registry+https://github.com/rust-lang/crates.io-index"
964checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2"
965dependencies = [
966 "bumpalo",
967 "proc-macro2",
968 "quote",
969 "syn",
970 "wasm-bindgen-shared",
971]
972
973[[package]]
974name = "wasm-bindgen-shared"
975version = "0.2.121"
976source = "registry+https://github.com/rust-lang/crates.io-index"
977checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441"
978dependencies = [
979 "unicode-ident",
980]
981
982[[package]]
983name = "wasm-encoder"
984version = "0.244.0"
985source = "registry+https://github.com/rust-lang/crates.io-index"
986checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
987dependencies = [
988 "leb128fmt",
989 "wasmparser",
990]
991
992[[package]]
993name = "wasm-metadata"
994version = "0.244.0"
995source = "registry+https://github.com/rust-lang/crates.io-index"
996checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
997dependencies = [
998 "anyhow",
999 "indexmap",
1000 "wasm-encoder",
1001 "wasmparser",
1002]
1003
1004[[package]]
1005name = "wasmparser"
1006version = "0.244.0"
1007source = "registry+https://github.com/rust-lang/crates.io-index"
1008checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
1009dependencies = [
1010 "bitflags",
1011 "hashbrown 0.15.5",
1012 "indexmap",
1013 "semver",
1014]
1015
1016[[package]]
1017name = "windows"
1018version = "0.61.3"
1019source = "registry+https://github.com/rust-lang/crates.io-index"
1020checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
1021dependencies = [
1022 "windows-collections",
1023 "windows-core",
1024 "windows-future",
1025 "windows-link 0.1.3",
1026 "windows-numerics",
1027]
1028
1029[[package]]
1030name = "windows-collections"
1031version = "0.2.0"
1032source = "registry+https://github.com/rust-lang/crates.io-index"
1033checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
1034dependencies = [
1035 "windows-core",
1036]
1037
1038[[package]]
1039name = "windows-core"
1040version = "0.61.2"
1041source = "registry+https://github.com/rust-lang/crates.io-index"
1042checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
1043dependencies = [
1044 "windows-implement",
1045 "windows-interface",
1046 "windows-link 0.1.3",
1047 "windows-result",
1048 "windows-strings",
1049]
1050
1051[[package]]
1052name = "windows-future"
1053version = "0.2.1"
1054source = "registry+https://github.com/rust-lang/crates.io-index"
1055checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
1056dependencies = [
1057 "windows-core",
1058 "windows-link 0.1.3",
1059 "windows-threading",
1060]
1061
1062[[package]]
1063name = "windows-implement"
1064version = "0.60.2"
1065source = "registry+https://github.com/rust-lang/crates.io-index"
1066checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
1067dependencies = [
1068 "proc-macro2",
1069 "quote",
1070 "syn",
1071]
1072
1073[[package]]
1074name = "windows-interface"
1075version = "0.59.3"
1076source = "registry+https://github.com/rust-lang/crates.io-index"
1077checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
1078dependencies = [
1079 "proc-macro2",
1080 "quote",
1081 "syn",
1082]
1083
1084[[package]]
1085name = "windows-link"
1086version = "0.1.3"
1087source = "registry+https://github.com/rust-lang/crates.io-index"
1088checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
1089
1090[[package]]
1091name = "windows-link"
1092version = "0.2.1"
1093source = "registry+https://github.com/rust-lang/crates.io-index"
1094checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
1095
1096[[package]]
1097name = "windows-numerics"
1098version = "0.2.0"
1099source = "registry+https://github.com/rust-lang/crates.io-index"
1100checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
1101dependencies = [
1102 "windows-core",
1103 "windows-link 0.1.3",
1104]
1105
1106[[package]]
1107name = "windows-result"
1108version = "0.3.4"
1109source = "registry+https://github.com/rust-lang/crates.io-index"
1110checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
1111dependencies = [
1112 "windows-link 0.1.3",
1113]
1114
1115[[package]]
1116name = "windows-strings"
1117version = "0.4.2"
1118source = "registry+https://github.com/rust-lang/crates.io-index"
1119checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
1120dependencies = [
1121 "windows-link 0.1.3",
1122]
1123
1124[[package]]
1125name = "windows-sys"
1126version = "0.61.2"
1127source = "registry+https://github.com/rust-lang/crates.io-index"
1128checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
1129dependencies = [
1130 "windows-link 0.2.1",
1131]
1132
1133[[package]]
1134name = "windows-threading"
1135version = "0.1.0"
1136source = "registry+https://github.com/rust-lang/crates.io-index"
1137checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
1138dependencies = [
1139 "windows-link 0.1.3",
1140]
1141
1142[[package]]
1143name = "wit-bindgen"
1144version = "0.51.0"
1145source = "registry+https://github.com/rust-lang/crates.io-index"
1146checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
1147dependencies = [
1148 "wit-bindgen-rust-macro",
1149]
1150
1151[[package]]
1152name = "wit-bindgen"
1153version = "0.57.1"
1154source = "registry+https://github.com/rust-lang/crates.io-index"
1155checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
1156
1157[[package]]
1158name = "wit-bindgen-core"
1159version = "0.51.0"
1160source = "registry+https://github.com/rust-lang/crates.io-index"
1161checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
1162dependencies = [
1163 "anyhow",
1164 "heck",
1165 "wit-parser",
1166]
1167
1168[[package]]
1169name = "wit-bindgen-rust"
1170version = "0.51.0"
1171source = "registry+https://github.com/rust-lang/crates.io-index"
1172checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
1173dependencies = [
1174 "anyhow",
1175 "heck",
1176 "indexmap",
1177 "prettyplease",
1178 "syn",
1179 "wasm-metadata",
1180 "wit-bindgen-core",
1181 "wit-component",
1182]
1183
1184[[package]]
1185name = "wit-bindgen-rust-macro"
1186version = "0.51.0"
1187source = "registry+https://github.com/rust-lang/crates.io-index"
1188checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
1189dependencies = [
1190 "anyhow",
1191 "prettyplease",
1192 "proc-macro2",
1193 "quote",
1194 "syn",
1195 "wit-bindgen-core",
1196 "wit-bindgen-rust",
1197]
1198
1199[[package]]
1200name = "wit-component"
1201version = "0.244.0"
1202source = "registry+https://github.com/rust-lang/crates.io-index"
1203checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
1204dependencies = [
1205 "anyhow",
1206 "bitflags",
1207 "indexmap",
1208 "log",
1209 "serde",
1210 "serde_derive",
1211 "serde_json",
1212 "wasm-encoder",
1213 "wasm-metadata",
1214 "wasmparser",
1215 "wit-parser",
1216]
1217
1218[[package]]
1219name = "wit-parser"
1220version = "0.244.0"
1221source = "registry+https://github.com/rust-lang/crates.io-index"
1222checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
1223dependencies = [
1224 "anyhow",
1225 "id-arena",
1226 "indexmap",
1227 "log",
1228 "semver",
1229 "serde",
1230 "serde_derive",
1231 "serde_json",
1232 "unicode-xid",
1233 "wasmparser",
1234]
1235
1236[[package]]
1237name = "zerocopy"
1238version = "0.8.48"
1239source = "registry+https://github.com/rust-lang/crates.io-index"
1240checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
1241dependencies = [
1242 "zerocopy-derive",
1243]
1244
1245[[package]]
1246name = "zerocopy-derive"
1247version = "0.8.48"
1248source = "registry+https://github.com/rust-lang/crates.io-index"
1249checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
1250dependencies = [
1251 "proc-macro2",
1252 "quote",
1253 "syn",
1254]
1255
1256[[package]]
1257name = "zmij"
1258version = "1.0.21"
1259source = "registry+https://github.com/rust-lang/crates.io-index"
1260checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
src/tools/miri/priroda/Cargo.toml created+19
......@@ -0,0 +1,19 @@
1[package]
2description = "Debugger for Rust MIR."
3license = "MIT OR Apache-2.0"
4name = "priroda"
5repository = "https://github.com/rust-lang/miri"
6version = "0.1.0"
7edition = "2024"
8
9
10[[bin]]
11name = "priroda"
12path = "src/main.rs"
13doctest = false # and no doc tests
14
15[dependencies]
16miri = { path = ".." }
17
18[package.metadata.rust-analyzer]
19rustc_private = true
src/tools/miri/priroda/README.md created+37
......@@ -0,0 +1,37 @@
1# Priroda
2
3Priroda is a step-through debugger for Rust programs running under
4Miri.
5
6Current focus:
7
8- simple CLI prototype
9- single-threaded stepping with Miri's interpreter
10- commands: empty Enter, `s`, or `step`
11
12## Setup
13
14From `miri/`, install the pinned toolchain and the local `cargo-miri`
15command:
16
17```sh
18./miri toolchain
19./miri install
20```
21
22Then build the Miri sysroot and export it for Priroda:
23
24```sh
25cargo +miri miri setup
26export MIRI_SYSROOT="$(cargo +miri miri setup --print-sysroot)"
27```
28
29## Run
30
31Priroda currently reads `MIRI_SYSROOT` directly. After setup:
32
33```sh
34cargo run -p priroda -- tests/pass/empty_main.rs
35```
36
37At the prompt, press Enter or type `s` / `step`.
src/tools/miri/priroda/rust-toolchain.toml created+2
......@@ -0,0 +1,2 @@
1[toolchain]
2channel = "miri"
src/tools/miri/priroda/src/main.rs created+147
......@@ -0,0 +1,147 @@
1#![feature(rustc_private)]
2
3extern crate miri;
4extern crate rustc_codegen_ssa;
5extern crate rustc_data_structures;
6extern crate rustc_driver;
7extern crate rustc_hir;
8extern crate rustc_hir_analysis;
9extern crate rustc_interface;
10extern crate rustc_log;
11extern crate rustc_middle;
12extern crate rustc_session;
13
14use std::io::{self, Write};
15
16use miri::*;
17use rustc_driver::Compilation;
18use rustc_hir::attrs::CrateType;
19use rustc_interface::interface;
20use rustc_middle::ty::TyCtxt;
21use rustc_session::EarlyDiagCtxt;
22use rustc_session::config::ErrorOutputType;
23fn find_sysroot() -> String {
24 std::env::var("MIRI_SYSROOT")
25 .expect("set MIRI_SYSROOT to the path from `cargo miri setup --print-sysroot`")
26}
27
28fn main() {
29 let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
30 rustc_driver::init_rustc_env_logger(&early_dcx);
31
32 let mut args: Vec<String> = std::env::args().collect();
33
34 args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string));
35
36 let sysroot_flag = String::from("--sysroot");
37 if !args.contains(&sysroot_flag) {
38 args.push(sysroot_flag);
39 args.push(find_sysroot());
40 }
41 //TODO: handle the same `-Z` flags that Miri accepts.
42 rustc_driver::run_compiler(&args, &mut PrirodaCompilerCalls::new());
43}
44
45struct PrirodaCompilerCalls;
46
47impl PrirodaCompilerCalls {
48 fn new() -> Self {
49 Self
50 }
51}
52
53impl rustc_driver::Callbacks for PrirodaCompilerCalls {
54 fn after_analysis<'tcx>(&mut self, _: &interface::Compiler, tcx: TyCtxt<'tcx>) -> Compilation {
55 tcx.dcx().emit_stashed_diagnostics();
56 tcx.dcx().abort_if_errors();
57
58 if !tcx.crate_types().contains(&CrateType::Executable) {
59 //TODO: support non-bin crates by listing functions and letting users call them with manually entered arguments.
60 tcx.dcx().fatal("priroda only makes sense on bin crates");
61 }
62
63 let ecx = create_ecx(tcx);
64
65 let mut session = PrirodaContext::new(ecx);
66 let result = run_cli_loop(&mut session);
67
68 match result.report_err() {
69 Ok(()) => {}
70 Err(err) =>
71 if let Some((return_code, _leak_check)) = report_result(&session.ecx, err) {
72 //TODO: print the evaluated program's exit code and return to the debugger prompt instead of exiting Priroda.
73 if return_code != 0 {
74 std::process::exit(return_code);
75 }
76 },
77 }
78
79 Compilation::Stop
80 }
81}
82
83fn create_ecx<'tcx>(tcx: TyCtxt<'tcx>) -> MiriInterpCx<'tcx> {
84 let (entry_id, entry_type) = miri::entry_fn(tcx);
85 let config = MiriConfig::default();
86 miri::create_ecx(tcx, entry_id, entry_type, &config, None).unwrap()
87}
88
89pub struct PrirodaContext<'tcx> {
90 ecx: MiriInterpCx<'tcx>,
91}
92
93impl<'tcx> PrirodaContext<'tcx> {
94 fn new(ecx: MiriInterpCx<'tcx>) -> Self {
95 Self { ecx }
96 }
97
98 // TODO: return a StepResult enum once we distinguish breakpoint stops,
99 // program exit, and other debugger states.
100 pub fn step(&mut self) -> InterpResult<'tcx> {
101 self.ecx.miri_step()
102 }
103
104 pub fn print_location(&self) {
105 let span = self.ecx.machine.current_user_relevant_span();
106 let location = self.ecx.tcx.sess.source_map().span_to_diagnostic_string(span);
107 // TODO: skip noisy std/runtime spans and avoid printing `no-location`
108 // once the basic command loop is solid.
109 println!("{location}");
110 io::stdout().flush().unwrap();
111 }
112 fn run_command(&mut self, command: SessionCommand) -> InterpResult<'tcx> {
113 match command {
114 SessionCommand::Step => self.step(),
115 }
116 }
117}
118
119enum SessionCommand {
120 Step,
121}
122
123fn parse_command(input: &str) -> Option<SessionCommand> {
124 match input.trim() {
125 "" | "s" | "step" => Some(SessionCommand::Step),
126 _ => None,
127 }
128}
129
130fn run_cli_loop<'tcx>(session: &mut PrirodaContext<'tcx>) -> InterpResult<'tcx> {
131 loop {
132 print!("(priroda) ");
133 io::stdout().flush().unwrap();
134
135 let mut input = String::new();
136 // TODO: handle EOF explicitly so scripted input can stop the CLI instead
137 // of being treated like an empty Enter step.
138 io::stdin().read_line(&mut input).unwrap();
139
140 if let Some(command) = parse_command(&input) {
141 session.run_command(command)?;
142 session.print_location();
143 } else {
144 println!("no command");
145 }
146 }
147}
src/tools/miri/rust-version+1-1
......@@ -1 +1 @@
11f8e04d34ab0c1fd9574840aa6db670e41593bfb
1bef8e620f19adbfd1530e916ab8caa296ef9c3ee
src/tools/miri/src/bin/miri.rs+15-56
......@@ -12,12 +12,10 @@ extern crate rustc_codegen_ssa;
1212extern crate rustc_data_structures;
1313extern crate rustc_driver;
1414extern crate rustc_hir;
15extern crate rustc_hir_analysis;
1615extern crate rustc_interface;
1716extern crate rustc_log;
1817extern crate rustc_middle;
1918extern crate rustc_session;
20extern crate rustc_span;
2119
2220/// See docs in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs
2321/// and https://github.com/rust-lang/rust/pull/146627 for why we need this.
......@@ -44,15 +42,13 @@ use std::str::FromStr;
4442use std::sync::atomic::{AtomicU32, Ordering};
4543
4644use miri::{
47 BacktraceStyle, BorrowTrackerMethod, GenmcConfig, GenmcCtx, MiriConfig, MiriEntryFnType,
48 ProvenanceMode, TreeBorrowsParams, ValidationMode, run_genmc_mode,
45 BacktraceStyle, BorrowTrackerMethod, GenmcConfig, GenmcCtx, MiriConfig, ProvenanceMode,
46 TreeBorrowsParams, ValidationMode, entry_fn, run_genmc_mode,
4947};
5048use rustc_codegen_ssa::traits::CodegenBackend;
5149use rustc_data_structures::sync::{self, DynSync};
5250use rustc_driver::Compilation;
53use rustc_hir::def_id::LOCAL_CRATE;
5451use rustc_hir::{self as hir, Node};
55use rustc_hir_analysis::check::check_function_signature;
5652use rustc_interface::interface::Config;
5753use rustc_interface::util::DummyCodegenBackend;
5854use rustc_log::tracing::debug;
......@@ -61,11 +57,9 @@ use rustc_middle::middle::exported_symbols::{
6157 ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
6258};
6359use rustc_middle::query::LocalCrate;
64use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
65use rustc_middle::ty::{self, Ty, TyCtxt};
60use rustc_middle::ty::TyCtxt;
6661use rustc_session::config::{CrateType, ErrorOutputType, OptLevel};
6762use rustc_session::{EarlyDiagCtxt, Session};
68use rustc_span::def_id::DefId;
6963
7064use crate::log::setup::{deinit_loggers, init_early_loggers, init_late_loggers};
7165
......@@ -85,53 +79,6 @@ impl MiriCompilerCalls {
8579 }
8680}
8781
88fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
89 if let Some((def_id, entry_type)) = tcx.entry_fn(()) {
90 return (def_id, MiriEntryFnType::Rustc(entry_type));
91 }
92 // Look for a symbol in the local crate named `miri_start`, and treat that as the entry point.
93 let sym = tcx.exported_non_generic_symbols(LOCAL_CRATE).iter().find_map(|(sym, _)| {
94 if sym.symbol_name_for_local_instance(tcx).name == "miri_start" { Some(sym) } else { None }
95 });
96 if let Some(ExportedSymbol::NonGeneric(id)) = sym {
97 let start_def_id = id.expect_local();
98 let start_span = tcx.def_span(start_def_id);
99
100 let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi(
101 [tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
102 tcx.types.isize,
103 ));
104
105 let correct_func_sig = check_function_signature(
106 tcx,
107 ObligationCause::new(start_span, start_def_id, ObligationCauseCode::Misc),
108 *id,
109 expected_sig,
110 )
111 .is_ok();
112
113 if correct_func_sig {
114 (*id, MiriEntryFnType::MiriStart)
115 } else {
116 tcx.dcx().fatal(
117 "`miri_start` must have the following signature:\n\
118 fn miri_start(argc: isize, argv: *const *const u8) -> isize",
119 );
120 }
121 } else {
122 tcx.dcx().fatal(
123 "Miri can only run programs that have a main function.\n\
124 Alternatively, you can export a `miri_start` function:\n\
125 \n\
126 #[cfg(miri)]\n\
127 #[unsafe(no_mangle)]\n\
128 fn miri_start(argc: isize, argv: *const *const u8) -> isize {\
129 \n // Call the actual start function that your project implements, based on your target's conventions.\n\
130 }"
131 );
132 }
133}
134
13582fn run_many_seeds(
13683 many_seeds: ManySeedsConfig,
13784 eval_entry_once: impl Fn(u64) -> Result<(), NonZeroI32> + DynSync,
......@@ -526,6 +473,8 @@ fn main() -> ExitCode {
526473 Some(BorrowTrackerMethod::TreeBorrows(TreeBorrowsParams {
527474 precise_interior_mut: true,
528475 implicit_writes: false,
476 // We default this to "unique" for now to keep the design space open.
477 box_custom_allocator_unique: true,
529478 }));
530479 } else if arg == "-Zmiri-tree-borrows-no-precise-interior-mut" {
531480 match &mut miri_config.borrow_tracker {
......@@ -547,6 +496,16 @@ fn main() -> ExitCode {
547496 "`-Zmiri-tree-borrows` is required before `-Zmiri-tree-borrows-implicit-writes`"
548497 ),
549498 };
499 } else if arg == "-Zmiri-tree-borrows-relax-custom-allocator-uniqueness" {
500 match &mut miri_config.borrow_tracker {
501 Some(BorrowTrackerMethod::TreeBorrows(params)) => {
502 params.box_custom_allocator_unique = false;
503 }
504 _ =>
505 fatal_error!(
506 "`-Zmiri-tree-borrows` is required before `-Zmiri-tree-borrows-relax-custom-allocator-uniqueness`"
507 ),
508 };
550509 } else if arg == "-Zmiri-disable-data-race-detector" {
551510 miri_config.data_race_detector = false;
552511 miri_config.weak_memory_emulation = false;
src/tools/miri/src/borrow_tracker/mod.rs+4
......@@ -226,9 +226,12 @@ pub enum BorrowTrackerMethod {
226226/// Parameters that Tree Borrows can take.
227227#[derive(Debug, Copy, Clone, PartialEq, Eq)]
228228pub struct TreeBorrowsParams {
229 /// Controls whether we track `UnsafeCell` with byte precision.
229230 pub precise_interior_mut: bool,
230231 /// Controls whether `&mut` function arguments are immediately activated with an implicit write.
231232 pub implicit_writes: bool,
233 /// Controls whether `Box` with custom allocator is considered unique.
234 pub box_custom_allocator_unique: bool,
232235}
233236
234237impl BorrowTrackerMethod {
......@@ -236,6 +239,7 @@ impl BorrowTrackerMethod {
236239 RefCell::new(GlobalStateInner::new(self, config.tracked_pointer_tags.clone()))
237240 }
238241
242 #[track_caller]
239243 pub fn get_tree_borrows_params(self) -> TreeBorrowsParams {
240244 match self {
241245 BorrowTrackerMethod::TreeBorrows(params) => params,
src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs+1-6
......@@ -869,12 +869,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
869869 RetagMode::None => return interp_ok(None), // no retagging
870870 };
871871 let new_perm = if ty.is_box() {
872 if ty.is_box_global(*this.tcx) {
873 NewPermission::from_box_ty(val.layout.ty, mode, this)
874 } else {
875 // Boxes with local allocator are not retagged.
876 return interp_ok(None);
877 }
872 NewPermission::from_box_ty(val.layout.ty, mode, this)
878873 } else {
879874 NewPermission::from_ref_ty(val.layout.ty, mode, this)
880875 };
src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs+22-27
......@@ -127,7 +127,7 @@ impl<'tcx> NewPermission {
127127 pointee: Ty<'tcx>,
128128 ref_mutability: Option<Mutability>,
129129 mode: RetagMode,
130 cx: &crate::MiriInterpCx<'tcx>,
130 cx: &MiriInterpCx<'tcx>,
131131 ) -> Option<Self> {
132132 if mode == RetagMode::None {
133133 return None;
......@@ -143,15 +143,7 @@ impl<'tcx> NewPermission {
143143 // `#[rustc_no_writable]` attribute. For performance reasons, only performs the lookup if
144144 // is_protected is true as implicit writes are only performed for protected references.
145145 let implicit_writes_enabled = is_protected && {
146 let implicit_writes = cx
147 .machine
148 .borrow_tracker
149 .as_ref()
150 .unwrap()
151 .borrow()
152 .borrow_tracker_method
153 .get_tree_borrows_params()
154 .implicit_writes;
146 let implicit_writes = cx.get_tree_borrows_params().implicit_writes;
155147 let def_id = cx.frame().instance().def_id();
156148 implicit_writes && !find_attr!(cx.tcx, def_id, RustcNoWritable)
157149 };
......@@ -234,6 +226,14 @@ impl<'tcx> NewPermission {
234226/// the implementation of NewPermission.
235227impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {}
236228trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
229 #[track_caller]
230 #[inline]
231 fn get_tree_borrows_params(&self) -> TreeBorrowsParams {
232 let this = self.eval_context_ref();
233 let borrow_tracker = this.machine.borrow_tracker.as_ref().unwrap().borrow();
234 borrow_tracker.borrow_tracker_method.get_tree_borrows_params()
235 }
236
237237 /// Returns the provenance that should be used henceforth.
238238 fn tb_reborrow(
239239 &mut self,
......@@ -326,15 +326,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
326326 }
327327
328328 let protected = new_perm.protector.is_some();
329 let precise_interior_mut = this
330 .machine
331 .borrow_tracker
332 .as_mut()
333 .unwrap()
334 .get_mut()
335 .borrow_tracker_method
336 .get_tree_borrows_params()
337 .precise_interior_mut;
329 let precise_interior_mut = this.get_tree_borrows_params().precise_interior_mut;
338330
339331 // Compute initial "inside" permissions.
340332 let loc_state = |frozen: bool| -> LocationState {
......@@ -487,22 +479,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
487479 ) -> InterpResult<'tcx, Option<ImmTy<'tcx>>> {
488480 let this = self.eval_context_mut();
489481 let new_perm = match *ty.kind() {
490 _ if ty.is_box_global(*this.tcx) => {
491 // The `None` marks this as a Box.
492 NewPermission::new(ty.builtin_deref(true).unwrap(), None, mode, this)
493 }
494482 ty::Ref(_, pointee, mutability) =>
495483 NewPermission::new(pointee, Some(mutability), mode, this),
484 _ if ty.is_box() => {
485 let box_custom_allocator_unique =
486 this.get_tree_borrows_params().box_custom_allocator_unique;
487 if box_custom_allocator_unique || ty.is_box_global(*this.tcx) {
488 // The `None` marks this as a Box.
489 NewPermission::new(ty.builtin_deref(true).unwrap(), None, mode, this)
490 } else {
491 // No retagging for boxes with custom allocators.
492 None
493 }
494 }
496495
497496 ty::RawPtr(..) => {
498497 assert!(mode == RetagMode::Raw);
499498 // We don't give new tags to raw pointers.
500499 None
501500 }
502 _ if ty.is_box() => {
503 // No retagging for boxes with local allocators.
504 None
505 }
506501 _ => panic!("tb_retag_ptr_value: invalid type {ty}"),
507502 };
508503 if let Some(new_perm) = new_perm {
src/tools/miri/src/concurrency/thread.rs+18-8
......@@ -856,6 +856,23 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
856856// Public interface to thread management.
857857impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
858858pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
859 /// Public because this is used by Priroda.
860 fn miri_step(&mut self) -> InterpResult<'tcx> {
861 let this = self.eval_context_mut();
862
863 if !this.step()? {
864 // See if this thread can do something else.
865 match this.run_on_stack_empty()? {
866 Poll::Pending => {} //keep going
867 Poll::Ready(()) => {
868 this.terminate_active_thread(TlsAllocAction::Deallocate)?;
869 }
870 }
871 }
872
873 interp_ok(())
874 }
875
859876 #[inline]
860877 fn thread_id_try_from(&self, id: impl TryInto<u32>) -> Result<ThreadId, ThreadLookupError> {
861878 self.eval_context_ref().machine.threads.thread_id_try_from(id)
......@@ -1289,14 +1306,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12891306 }
12901307 match this.schedule()? {
12911308 SchedulingAction::ExecuteStep => {
1292 if !this.step()? {
1293 // See if this thread can do something else.
1294 match this.run_on_stack_empty()? {
1295 Poll::Pending => {} // keep going
1296 Poll::Ready(()) =>
1297 this.terminate_active_thread(TlsAllocAction::Deallocate)?,
1298 }
1299 }
1309 this.miri_step()?;
13001310 }
13011311 SchedulingAction::SleepAndWaitForIo(duration) => {
13021312 if this.machine.communicate() {
src/tools/miri/src/eval.rs+54-1
......@@ -12,7 +12,10 @@ use rustc_abi::ExternAbi;
1212use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1313use rustc_errors::FatalErrorMarker;
1414use rustc_hir::def::Namespace;
15use rustc_hir::def_id::DefId;
15use rustc_hir::def_id::{DefId, LOCAL_CRATE};
16use rustc_hir_analysis::check::check_function_signature;
17use rustc_middle::middle::exported_symbols::ExportedSymbol;
18use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
1619use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutCx};
1720use rustc_middle::ty::{self, Ty, TyCtxt};
1821use rustc_session::config::EntryFnType;
......@@ -31,6 +34,56 @@ pub enum MiriEntryFnType {
3134 Rustc(EntryFnType),
3235}
3336
37/// Finds the entry point Miri should execute.
38///
39/// Public because this is used by Priroda.
40pub fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) {
41 if let Some((def_id, entry_type)) = tcx.entry_fn(()) {
42 return (def_id, MiriEntryFnType::Rustc(entry_type));
43 }
44 // Look for a symbol in the local crate named `miri_start`, and treat that as the entry point.
45 let sym = tcx.exported_non_generic_symbols(LOCAL_CRATE).iter().find_map(|(sym, _)| {
46 if sym.symbol_name_for_local_instance(tcx).name == "miri_start" { Some(sym) } else { None }
47 });
48 if let Some(ExportedSymbol::NonGeneric(id)) = sym {
49 let start_def_id = id.expect_local();
50 let start_span = tcx.def_span(start_def_id);
51
52 let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi(
53 [tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))],
54 tcx.types.isize,
55 ));
56
57 let correct_func_sig = check_function_signature(
58 tcx,
59 ObligationCause::new(start_span, start_def_id, ObligationCauseCode::Misc),
60 *id,
61 expected_sig,
62 )
63 .is_ok();
64
65 if correct_func_sig {
66 (*id, MiriEntryFnType::MiriStart)
67 } else {
68 tcx.dcx().fatal(
69 "`miri_start` must have the following signature:\n\
70 fn miri_start(argc: isize, argv: *const *const u8) -> isize",
71 );
72 }
73 } else {
74 tcx.dcx().fatal(
75 "Miri can only run programs that have a main function.\n\
76 Alternatively, you can export a `miri_start` function:\n\
77 \n\
78 #[cfg(miri)]\n\
79 #[unsafe(no_mangle)]\n\
80 fn miri_start(argc: isize, argv: *const *const u8) -> isize {\
81 \n // Call the actual start function that your project implements, based on your target's conventions.\n\
82 }"
83 );
84 }
85}
86
3487/// When the main thread would exit, we will yield to any other thread that is ready to execute.
3588/// But we must only do that a finite number of times, or a background thread running `loop {}`
3689/// will hang the program.
src/tools/miri/src/lib.rs+4-2
......@@ -9,6 +9,7 @@
99 feature(abort_unwind)
1010)]
1111#![feature(rustc_private)]
12#![feature(dirfd)]
1213#![feature(f16)]
1314#![feature(float_gamma)]
1415#![feature(float_erf)]
......@@ -69,6 +70,7 @@ extern crate rustc_const_eval;
6970extern crate rustc_data_structures;
7071extern crate rustc_errors;
7172extern crate rustc_hir;
73extern crate rustc_hir_analysis;
7274extern crate rustc_index;
7375extern crate rustc_log;
7476extern crate rustc_middle;
......@@ -146,7 +148,7 @@ pub use crate::concurrency::init_once::{EvalContextExt as _, InitOnceRef};
146148pub use crate::concurrency::sync::{CondvarRef, EvalContextExt as _, MutexRef, RwLockRef};
147149pub use crate::concurrency::thread::{
148150 BlockReason, DynUnblockCallback, EvalContextExt as _, StackEmptyCallback, ThreadId,
149 ThreadManager, UnblockKind,
151 ThreadManager, TlsAllocAction, UnblockKind,
150152};
151153pub use crate::concurrency::{GenmcConfig, GenmcCtx, run_genmc_mode};
152154pub use crate::data_structures::dedup_range_map::DedupRangeMap;
......@@ -154,7 +156,7 @@ pub use crate::data_structures::mono_hash_map::MonoHashMap;
154156pub use crate::diagnostics::{
155157 EvalContextExt as _, NonHaltingDiagnostic, TerminationInfo, report_result,
156158};
157pub use crate::eval::{MiriConfig, MiriEntryFnType, create_ecx, eval_entry};
159pub use crate::eval::{MiriConfig, MiriEntryFnType, create_ecx, entry_fn, eval_entry};
158160pub use crate::helpers::{EvalContextExt as _, ToU64 as _, ToUsize as _};
159161pub use crate::intrinsics::EvalContextExt as _;
160162pub use crate::machine::{
src/tools/miri/src/shims/aarch64.rs+29-7
......@@ -196,10 +196,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
196196 _ => unreachable!(),
197197 };
198198
199 let [left, right] =
200 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
201 let left = this.read_scalar(left)?;
202 let right = this.read_scalar(right)?;
199 let [crc, data] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
200 let crc = this.read_scalar(crc)?;
201 let data = this.read_scalar(data)?;
203202
204203 // The CRC accumulator is always u32. The data argument is u32 for
205204 // b/h/w variants and u64 for the x variant, per the LLVM intrinsic
......@@ -207,13 +206,36 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
207206 // https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsAArch64.td
208207 // If the higher bits are non-zero, `compute_crc32` will panic. We should probably
209208 // raise a proper error instead, but outside stdarch nobody can trigger this anyway.
210 let crc = left.to_u32()?;
211 let data =
212 if bit_size == 64 { right.to_u64()? } else { u64::from(right.to_u32()?) };
209 let crc = crc.to_u32()?;
210 let data = if bit_size == 64 { data.to_u64()? } else { u64::from(data.to_u32()?) };
213211
214212 let result = compute_crc32(crc, data, bit_size, polynomial);
215213 this.write_scalar(Scalar::from_u32(result), dest)?;
216214 }
215 // Polynomial multiply long (64-bit x 64-bit -> 128-bit).
216 //
217 // This is the same as "carryless" multiplication, see
218 // <https://en.wikipedia.org/wiki/Carry-less_product#Multiplication_of_polynomials>.
219 //
220 // Used to implement the vmull_p64 and vmull_high_p64 functions.
221 // https://developer.arm.com/architectures/instruction-sets/intrinsics/vmull_p64
222 "neon.pmull64" => {
223 // LLVM and GCC group pmull with the AES intrinsics.
224 // Also see <https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612088.html>.
225 this.expect_target_feature_for_intrinsic(link_name, "aes")?;
226
227 let [left, right] =
228 this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
229 let left = this.read_scalar(left)?.to_u64()?;
230 let right = this.read_scalar(right)?.to_u64()?;
231
232 let result = left.widening_carryless_mul(right);
233
234 // dest is int8x16_t, transmute to u128 for the write.
235 let dest = dest.transmute(this.machine.layouts.u128, this)?;
236 this.write_scalar(Scalar::from_u128(result), &dest)?;
237 }
238
217239 _ => return interp_ok(EmulateItemResult::NotSupported),
218240 }
219241 interp_ok(EmulateItemResult::NeedsReturn)
src/tools/miri/src/shims/files.rs+40-1
......@@ -1,9 +1,10 @@
11use std::any::Any;
22use std::collections::BTreeMap;
3use std::fs::File;
3use std::fs::{Dir, File};
44use std::io::{ErrorKind, IsTerminal, Read, Seek, SeekFrom, Write};
55use std::marker::CoercePointee;
66use std::ops::Deref;
7use std::path::PathBuf;
78use std::rc::{Rc, Weak};
89use std::{fs, io};
910
......@@ -362,6 +363,7 @@ impl FileDescription for io::Stderr {
362363#[derive(Debug)]
363364pub struct FileHandle {
364365 pub(crate) file: File,
366 pub(crate) readable: bool,
365367 pub(crate) writable: bool,
366368}
367369
......@@ -380,6 +382,10 @@ impl FileDescription for FileHandle {
380382 ) -> InterpResult<'tcx> {
381383 assert!(communicate_allowed, "isolation should have prevented even opening a file");
382384
385 if !self.readable {
386 return finish.call(ecx, Err(ErrorKind::PermissionDenied.into()));
387 }
388
383389 let mut file = &self.file;
384390 let result = ecx.read_from_host(|buf| file.read(buf), len, ptr)?;
385391 finish.call(ecx, result)
......@@ -468,6 +474,39 @@ impl FileDescription for FileHandle {
468474 }
469475}
470476
477#[derive(Debug)]
478pub struct DirHandle {
479 #[cfg_attr(bootstrap, allow(unused))]
480 pub(crate) dir: Dir,
481 /// Fallback used under `cfg(bootstrap)`.
482 #[cfg_attr(not(bootstrap), allow(unused))]
483 pub(crate) path: PathBuf,
484}
485
486impl FileDescription for DirHandle {
487 fn name(&self) -> &'static str {
488 "directory"
489 }
490
491 fn metadata<'tcx>(
492 &self,
493 ) -> InterpResult<'tcx, Either<io::Result<std::fs::Metadata>, &'static str>> {
494 #[cfg(not(bootstrap))]
495 return interp_ok(Either::Left(self.dir.metadata()));
496 #[cfg(bootstrap)]
497 return interp_ok(Either::Left(std::fs::metadata(&self.path)));
498 }
499
500 fn destroy<'tcx>(
501 self,
502 _self_id: FdId,
503 _communicate_allowed: bool,
504 _ecx: &mut MiriInterpCx<'tcx>,
505 ) -> InterpResult<'tcx, io::Result<()>> {
506 interp_ok(Ok(()))
507 }
508}
509
471510/// Like /dev/null
472511#[derive(Debug)]
473512pub struct NullOutput;
src/tools/miri/src/shims/foreign_items.rs+8
......@@ -857,6 +857,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
857857 this, link_name, abi, args, dest,
858858 );
859859 }
860 name if name.starts_with("llvm.loongarch.")
861 && matches!(this.tcx.sess.target.arch, Arch::LoongArch32 | Arch::LoongArch64)
862 && this.tcx.sess.target.endian == Endian::Little =>
863 {
864 return shims::loongarch::EvalContextExt::emulate_loongarch_intrinsic(
865 this, link_name, abi, args, dest,
866 );
867 }
860868
861869 // Fallback to shims in submodules.
862870 _ => {
src/tools/miri/src/shims/loongarch.rs created+70
......@@ -0,0 +1,70 @@
1use rustc_abi::CanonAbi;
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::math::compute_crc32;
7use crate::*;
8
9impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
10pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11 fn emulate_loongarch_intrinsic(
12 &mut self,
13 link_name: Symbol,
14 abi: &FnAbi<'tcx, Ty<'tcx>>,
15 args: &[OpTy<'tcx>],
16 dest: &MPlaceTy<'tcx>,
17 ) -> InterpResult<'tcx, EmulateItemResult> {
18 let this = self.eval_context_mut();
19 // Prefix should have already been checked.
20 let unprefixed_name = link_name.as_str().strip_prefix("llvm.loongarch.").unwrap();
21 match unprefixed_name {
22 // Used to implement the crc.w.{b,h,w,d}.w and crcc.w.{b,h,w,d}.w functions.
23 // https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#crc-check-instructions
24 // These are only available on LA64, not on LA32, and are part of
25 // the LA64 1.0 baseline and therefore always available and don't
26 // require a target feature to be enabled.
27 "crc.w.b.w" | "crc.w.h.w" | "crc.w.w.w" | "crc.w.d.w" | "crcc.w.b.w" | "crcc.w.h.w"
28 | "crcc.w.w.w" | "crcc.w.d.w"
29 if this.tcx.pointer_size().bits() == 64 =>
30 {
31 // The polynomial constants below include the leading 1 bit
32 // (e.g. 0x104C11DB7 instead of 0x04C11DB7) which the the
33 // polynomial division algorithm requires.
34 // Note that Loongson's documentation mentions the numbers
35 // 0xEDB88320 for IEEE802.3 and 0x82F63B78 for Castagnoli,
36 // which is because their docs put the least significant bit
37 // first.
38 let (bit_size, polynomial): (u32, u128) = match unprefixed_name {
39 "crc.w.b.w" => (8, 0x104C11DB7),
40 "crc.w.h.w" => (16, 0x104C11DB7),
41 "crc.w.w.w" => (32, 0x104C11DB7),
42 "crc.w.d.w" => (64, 0x104C11DB7),
43 "crcc.w.b.w" => (8, 0x11EDC6F41),
44 "crcc.w.h.w" => (16, 0x11EDC6F41),
45 "crcc.w.w.w" => (32, 0x11EDC6F41),
46 "crcc.w.d.w" => (64, 0x11EDC6F41),
47 _ => unreachable!(),
48 };
49
50 let [data, crc] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
51 let data = this.read_scalar(data)?;
52 let crc = this.read_scalar(crc)?;
53
54 // The CRC accumulator is always i32. The data argument is i32 for
55 // b/h/w variants and i64 for the d variant, per the LLVM intrinsic
56 // definitions.
57 // https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsLoongArch.td
58 // If the higher bits are non-zero, `compute_crc32` will panic. We should probably
59 // raise a proper error instead, but outside stdarch nobody can trigger this anyway.
60 let crc = crc.to_u32()?;
61 let data = if bit_size == 64 { data.to_u64()? } else { u64::from(data.to_u32()?) };
62
63 let result = compute_crc32(crc, data, bit_size, polynomial);
64 this.write_scalar(Scalar::from_u32(result), dest)?;
65 }
66 _ => return interp_ok(EmulateItemResult::NotSupported),
67 }
68 interp_ok(EmulateItemResult::NeedsReturn)
69 }
70}
src/tools/miri/src/shims/mod.rs+1
......@@ -4,6 +4,7 @@ mod aarch64;
44mod alloc;
55mod backtrace;
66mod files;
7mod loongarch;
78mod math;
89#[cfg(all(feature = "native-lib", unix))]
910pub mod native_lib;
src/tools/miri/src/shims/unix/android/foreign_items.rs+1-13
......@@ -3,11 +3,11 @@ use rustc_middle::ty::Ty;
33use rustc_span::Symbol;
44use rustc_target::callconv::FnAbi;
55
6use crate::shims::unix::android::thread::prctl;
76use crate::shims::unix::env::EvalContextExt as _;
87use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
98use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
109use crate::shims::unix::linux_like::syscall::syscall;
10use crate::shims::unix::linux_like::thread::prctl;
1111use crate::shims::unix::*;
1212use crate::*;
1313
......@@ -27,18 +27,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2727 let this = self.eval_context_mut();
2828 match link_name.as_str() {
2929 // File related shims
30 "stat" => {
31 // FIXME: This does not have a direct test (#3179).
32 let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
33 let result = this.stat(path, buf)?;
34 this.write_scalar(result, dest)?;
35 }
36 "lstat" => {
37 // FIXME: This does not have a direct test (#3179).
38 let [path, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
39 let result = this.lstat(path, buf)?;
40 this.write_scalar(result, dest)?;
41 }
4230 "pread64" => {
4331 // FIXME: This does not have a direct test (#3179).
4432 let [fd, buf, count, offset] = this.check_shim_sig(
src/tools/miri/src/shims/unix/android/mod.rs-1
......@@ -1,2 +1 @@
11pub mod foreign_items;
2pub mod thread;
src/tools/miri/src/shims/unix/android/thread.rs deleted-55
......@@ -1,55 +0,0 @@
1use rustc_abi::{CanonAbi, Size};
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::sig::check_min_vararg_count;
7use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
8use crate::*;
9
10const TASK_COMM_LEN: u64 = 16;
11
12pub fn prctl<'tcx>(
13 ecx: &mut MiriInterpCx<'tcx>,
14 link_name: Symbol,
15 abi: &FnAbi<'tcx, Ty<'tcx>>,
16 args: &[OpTy<'tcx>],
17 dest: &MPlaceTy<'tcx>,
18) -> InterpResult<'tcx> {
19 let ([op], varargs) = ecx.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?;
20
21 // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
22 let pr_set_name = 15;
23 let pr_get_name = 16;
24
25 let res = match ecx.read_scalar(op)?.to_i32()? {
26 op if op == pr_set_name => {
27 let [name] = check_min_vararg_count("prctl(PR_SET_NAME, ...)", varargs)?;
28 let name = ecx.read_scalar(name)?;
29 let thread = ecx.pthread_self()?;
30 // The Linux kernel silently truncates long names.
31 // https://www.man7.org/linux/man-pages/man2/PR_SET_NAME.2const.html
32 let res =
33 ecx.pthread_setname_np(thread, name, TASK_COMM_LEN, /* truncate */ true)?;
34 assert_eq!(res, ThreadNameResult::Ok);
35 Scalar::from_u32(0)
36 }
37 op if op == pr_get_name => {
38 let [name] = check_min_vararg_count("prctl(PR_GET_NAME, ...)", varargs)?;
39 let name = ecx.read_scalar(name)?;
40 let thread = ecx.pthread_self()?;
41 let len = Scalar::from_target_usize(TASK_COMM_LEN, ecx);
42 ecx.check_ptr_access(
43 name.to_pointer(ecx)?,
44 Size::from_bytes(TASK_COMM_LEN),
45 CheckInAllocMsg::MemoryAccess,
46 )?;
47 let res = ecx.pthread_getname_np(thread, name, len, /* truncate*/ false)?;
48 assert_eq!(res, ThreadNameResult::Ok);
49 Scalar::from_u32(0)
50 }
51 op => throw_unsup_format!("Miri does not support `prctl` syscall with op={}", op),
52 };
53 ecx.write_scalar(res, dest)?;
54 interp_ok(())
55}
src/tools/miri/src/shims/unix/foreign_items.rs+14-1
......@@ -342,7 +342,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
342342 }
343343 "flock" => {
344344 // Currently this function does not exist on all Unixes, e.g. on Solaris.
345 this.check_target_os(&[Os::Linux, Os::Android, Os::FreeBsd, Os::MacOs, Os::Illumos], link_name)?;
345 this.check_target_os(
346 &[Os::Linux, Os::Android, Os::FreeBsd, Os::MacOs, Os::Illumos],
347 link_name,
348 )?;
346349
347350 let [fd, op] = this.check_shim_sig(
348351 shim_sig!(extern "C" fn(i32, i32) -> i32),
......@@ -393,6 +396,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
393396 let result = this.symlink(target, linkpath)?;
394397 this.write_scalar(result, dest)?;
395398 }
399 "linkat" => {
400 let [oldfd, oldpath, newfd, newpath, flags] = this.check_shim_sig(
401 shim_sig!(extern "C" fn(i32, *const _, i32, *const _, i32) -> i32),
402 link_name,
403 abi,
404 args,
405 )?;
406 let result = this.linkat(oldfd, oldpath, newfd, newpath, flags)?;
407 this.write_scalar(result, dest)?;
408 }
396409 "fstat" => {
397410 let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
398411 let result = this.fstat(fd, buf)?;
src/tools/miri/src/shims/unix/fs.rs+90-46
......@@ -64,6 +64,10 @@ impl UnixFileDescription for FileHandle {
6464 finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
6565 ) -> InterpResult<'tcx> {
6666 assert!(communicate_allowed, "isolation should have prevented even opening a file");
67 if !self.readable {
68 return finish.call(ecx, Err(LibcError("EBADF")));
69 }
70
6771 let mut bytes = vec![0; len];
6872 // Emulates pread using seek + read + seek to restore cursor position.
6973 // Correctness of this emulation relies on sequential nature of Miri execution.
......@@ -101,6 +105,10 @@ impl UnixFileDescription for FileHandle {
101105 finish: DynMachineCallback<'tcx, Result<usize, IoError>>,
102106 ) -> InterpResult<'tcx> {
103107 assert!(communicate_allowed, "isolation should have prevented even opening a file");
108 if !self.writable {
109 return finish.call(ecx, Err(LibcError("EBADF")));
110 }
111
104112 // Emulates pwrite using seek + write + seek to restore cursor position.
105113 // Correctness of this emulation relies on sequential nature of Miri execution.
106114 // The closure is used to emulate `try` block, since we "bubble" `io::Error` using `?`.
......@@ -387,6 +395,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
387395 throw_unsup_format!("access mode flags on this target are unsupported");
388396 }
389397 let mut writable = true;
398 let mut readable = true;
390399
391400 // Now we check the access mode
392401 let access_mode = flag & 0b11;
......@@ -396,6 +405,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
396405 writable = false;
397406 options.read(true);
398407 } else if access_mode == o_wronly {
408 readable = false;
399409 options.write(true);
400410 } else if access_mode == o_rdwr {
401411 options.read(true).write(true);
......@@ -495,7 +505,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
495505
496506 let fd = options
497507 .open(path)
498 .map(|file| this.machine.fds.insert_new(FileHandle { file, writable }));
508 .map(|file| this.machine.fds.insert_new(FileHandle { file, writable, readable }));
499509
500510 interp_ok(Scalar::from_i32(this.try_unwrap_io_result(fd)?))
501511 }
......@@ -584,6 +594,59 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
584594 interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))
585595 }
586596
597 fn linkat(
598 &mut self,
599 oldfd_op: &OpTy<'tcx>,
600 oldpath_op: &OpTy<'tcx>,
601 newfd_op: &OpTy<'tcx>,
602 newpath_op: &OpTy<'tcx>,
603 flags_op: &OpTy<'tcx>,
604 ) -> InterpResult<'tcx, Scalar> {
605 let this = self.eval_context_mut();
606
607 // Load all arguments
608 let flags = this.read_scalar(flags_op)?.to_i32()?;
609 let oldfd = this.read_scalar(oldfd_op)?.to_i32()?;
610 let newfd = this.read_scalar(newfd_op)?.to_i32()?;
611 let oldpath_ptr = this.read_pointer(oldpath_op)?;
612 let newpath_ptr = this.read_pointer(newpath_op)?;
613
614 // Relevant libc constants
615 let at_fdcwd = this.eval_libc_i32("AT_FDCWD");
616
617 // Reject if isolation is enabled.
618 if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
619 this.reject_in_isolation("`linkat`", reject_with)?;
620 return this.set_errno_and_return_neg1_i32(ErrorKind::PermissionDenied);
621 }
622
623 // Read flags - only support 0.
624 if flags != 0 {
625 throw_unsup_format!("unsupported linkat flags {:#x}", flags);
626 }
627
628 // Resolve oldpath
629 if oldfd != at_fdcwd {
630 throw_unsup_format!("linkat with `olddirfd` not equal to `AT_FDCWD` is not supported");
631 }
632 if oldpath_ptr == Pointer::null() {
633 return this.set_errno_and_return_neg1_i32(LibcError("EFAULT"));
634 }
635 let oldpath = this.read_path_from_c_str(oldpath_ptr)?.into_owned();
636
637 // Resolve newpath
638 if newfd != at_fdcwd {
639 throw_unsup_format!("linkat with `newdirfd` not equal to `AT_FDCWD` is not supported");
640 }
641 if newpath_ptr == Pointer::null() {
642 return this.set_errno_and_return_neg1_i32(LibcError("EFAULT"));
643 }
644 let newpath = this.read_path_from_c_str(newpath_ptr)?.into_owned();
645
646 let result = fs::hard_link(&oldpath, &newpath).map(|()| 0);
647 interp_ok(Scalar::from_i32(this.try_unwrap_io_result(result)?))
648 }
649
587650 fn stat(&mut self, path_op: &OpTy<'tcx>, buf_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
588651 let this = self.eval_context_mut();
589652
......@@ -892,12 +955,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
892955 // The docs don't talk about what happens for non-regular files...
893956 throw_unsup_format!("`fchmod` is only supported on regular files")
894957 };
895
896 // Reject if isolation is enabled.
897 if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
898 this.reject_in_isolation("`fchmod`", reject_with)?;
899 return this.set_errno_and_return_neg1_i32(LibcError("EACCES"));
958 if !file.writable && !file.readable {
959 // Apparently, `fchmod` on a read-only file is fine. But let's not allow it on a
960 // path-only file.
961 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
900962 }
963 assert!(this.machine.communicate(), "isolation should have prevented even opening a file");
901964
902965 let permissions = this.host_permissions_from_mode(mode.try_into().unwrap())?;
903966 if let Err(err) = file.file.set_permissions(permissions) {
......@@ -1253,33 +1316,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12531316 fn ftruncate64(&mut self, fd_num: i32, length: i128) -> InterpResult<'tcx, Scalar> {
12541317 let this = self.eval_context_mut();
12551318
1256 // Reject if isolation is enabled.
1257 if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
1258 this.reject_in_isolation("`ftruncate64`", reject_with)?;
1259 // Set error code as "EBADF" (bad fd)
1260 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
1261 }
1262
12631319 let Some(fd) = this.machine.fds.get(fd_num) else {
12641320 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
12651321 };
1266
12671322 let Some(file) = fd.downcast::<FileHandle>() else {
12681323 // The docs say that EINVAL is returned when the FD "does not reference a regular file
12691324 // or a POSIX shared memory object" (and we don't support shmem objects).
1270 return interp_ok(this.eval_libc("EINVAL"));
1325 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
12711326 };
1327 if !file.writable {
1328 // man page says "EBADF or EINVAL", Linux seems to use EINVAL.
1329 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
1330 }
1331 assert!(this.machine.communicate(), "isolation should have prevented even opening a file");
12721332
1273 if file.writable {
1274 if let Ok(length) = length.try_into() {
1275 let result = file.file.set_len(length);
1276 let result = this.try_unwrap_io_result(result.map(|_| 0i32))?;
1277 interp_ok(Scalar::from_i32(result))
1278 } else {
1279 this.set_errno_and_return_neg1_i32(LibcError("EINVAL"))
1280 }
1333 if let Ok(length) = length.try_into() {
1334 let result = file.file.set_len(length);
1335 let result = this.try_unwrap_io_result(result.map(|_| 0i32))?;
1336 interp_ok(Scalar::from_i32(result))
12811337 } else {
1282 // The file is not writable
12831338 this.set_errno_and_return_neg1_i32(LibcError("EINVAL"))
12841339 }
12851340 }
......@@ -1352,13 +1407,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13521407
13531408 let fd = this.read_scalar(fd_op)?.to_i32()?;
13541409
1355 // Reject if isolation is enabled.
1356 if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
1357 this.reject_in_isolation("`fsync`", reject_with)?;
1358 // Set error code as "EBADF" (bad fd)
1359 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
1360 }
1361
13621410 self.ffullsync_fd(fd)
13631411 }
13641412
......@@ -1371,6 +1419,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13711419 let file = fd.downcast::<FileHandle>().ok_or_else(|| {
13721420 err_unsup_format!("`fsync` is only supported on file-backed file descriptors")
13731421 })?;
1422 assert!(this.machine.communicate(), "isolation should have prevented even opening a file");
1423
13741424 let io_result = maybe_sync_file(&file.file, file.writable, File::sync_all);
13751425 interp_ok(Scalar::from_i32(this.try_unwrap_io_result(io_result)?))
13761426 }
......@@ -1380,13 +1430,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13801430
13811431 let fd = this.read_scalar(fd_op)?.to_i32()?;
13821432
1383 // Reject if isolation is enabled.
1384 if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
1385 this.reject_in_isolation("`fdatasync`", reject_with)?;
1386 // Set error code as "EBADF" (bad fd)
1387 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
1388 }
1389
13901433 let Some(fd) = this.machine.fds.get(fd) else {
13911434 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
13921435 };
......@@ -1394,6 +1437,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13941437 let file = fd.downcast::<FileHandle>().ok_or_else(|| {
13951438 err_unsup_format!("`fdatasync` is only supported on file-backed file descriptors")
13961439 })?;
1440 assert!(this.machine.communicate(), "isolation should have prevented even opening a file");
1441
13971442 let io_result = maybe_sync_file(&file.file, file.writable, File::sync_data);
13981443 interp_ok(Scalar::from_i32(this.try_unwrap_io_result(io_result)?))
13991444 }
......@@ -1422,13 +1467,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
14221467 return this.set_errno_and_return_neg1_i32(LibcError("EINVAL"));
14231468 }
14241469
1425 // Reject if isolation is enabled.
1426 if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
1427 this.reject_in_isolation("`sync_file_range`", reject_with)?;
1428 // Set error code as "EBADF" (bad fd)
1429 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
1430 }
1431
14321470 let Some(fd) = this.machine.fds.get(fd) else {
14331471 return this.set_errno_and_return_neg1_i32(LibcError("EBADF"));
14341472 };
......@@ -1436,6 +1474,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
14361474 let file = fd.downcast::<FileHandle>().ok_or_else(|| {
14371475 err_unsup_format!("`sync_data_range` is only supported on file-backed file descriptors")
14381476 })?;
1477 assert!(this.machine.communicate(), "isolation should have prevented even opening a file");
1478
14391479 let io_result = maybe_sync_file(&file.file, file.writable, File::sync_data);
14401480 interp_ok(Scalar::from_i32(this.try_unwrap_io_result(io_result)?))
14411481 }
......@@ -1661,7 +1701,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
16611701 let file = fopts.open(bytes_to_os_str(template_bytes)?);
16621702 match file {
16631703 Ok(f) => {
1664 let fd = this.machine.fds.insert_new(FileHandle { file: f, writable: true });
1704 let fd = this.machine.fds.insert_new(FileHandle {
1705 file: f,
1706 writable: true,
1707 readable: true,
1708 });
16651709 return interp_ok(Scalar::from_i32(fd));
16661710 }
16671711 Err(e) =>
src/tools/miri/src/shims/unix/linux/foreign_items.rs+2
......@@ -8,6 +8,7 @@ use self::shims::unix::linux_like::eventfd::EvalContextExt as _;
88use self::shims::unix::linux_like::syscall::syscall;
99use crate::machine::{SIGRTMAX, SIGRTMIN};
1010use crate::shims::unix::foreign_items::EvalContextExt as _;
11use crate::shims::unix::linux_like::thread::prctl;
1112use crate::shims::unix::*;
1213use crate::*;
1314
......@@ -197,6 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
197198 let result = this.unix_gettid(link_name.as_str())?;
198199 this.write_scalar(result, dest)?;
199200 }
201 "prctl" => prctl(this, link_name, abi, args, dest)?,
200202
201203 // Dynamically invoked syscalls
202204 "syscall" => {
src/tools/miri/src/shims/unix/linux_like/epoll.rs+58-38
......@@ -1,7 +1,6 @@
11use std::cell::RefCell;
2use std::collections::{BTreeMap, BTreeSet, VecDeque};
2use std::collections::{BTreeMap, VecDeque};
33use std::io;
4use std::ops::Bound;
54use std::time::Duration;
65
76use rustc_abi::FieldIdx;
......@@ -23,7 +22,9 @@ pub struct Epoll {
2322 interest_list: RefCell<BTreeMap<EpollEventKey, EpollEventInterest>>,
2423 /// The subset of interests that is currently considered "ready". Stored separately so we
2524 /// can access it more efficiently.
26 ready_set: RefCell<BTreeSet<EpollEventKey>>,
25 /// This is implemented as a queue so that for level-triggered epoll, all events eventually
26 /// get returned from `epoll_wait`. The queue does not contain any duplicates.
27 ready_events: RefCell<VecDeque<EpollEventKey>>,
2728 /// The queue of threads blocked on this epoll instance.
2829 queue: RefCell<VecDeque<ThreadId>>,
2930}
......@@ -46,6 +47,9 @@ pub struct EpollEventInterest {
4647 relevant_events: u32,
4748 /// The currently active events for this file descriptor.
4849 active_events: u32,
50 /// Boolean whether this is an edge-triggered interest.
51 /// When [`false`] it's a level-triggered interest instead.
52 is_edge_triggered: bool,
4953 /// The vector clock for wakeups.
5054 clock: VClock,
5155 /// User-defined data associated with this interest.
......@@ -203,12 +207,8 @@ impl EpollInterestTable {
203207 .extract_if(range_for_id(id), |_, _| true)
204208 // Consume the iterator.
205209 .for_each(drop);
206 epoll
207 .ready_set
208 .borrow_mut()
209 .extract_if(range_for_id(id), |_| true)
210 // Consume the iterator.
211 .for_each(drop);
210 // Remove the ready events for this file description.
211 epoll.ready_events.borrow_mut().retain(|(fd_id, _)| fd_id != &id);
212212 }
213213 }
214214 }
......@@ -303,6 +303,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
303303 this.read_scalar(&this.project_field(&event, FieldIdx::ZERO)?)?.to_u32()?;
304304 let data = this.read_scalar(&this.project_field(&event, FieldIdx::ONE)?)?.to_u64()?;
305305
306 let is_edge_triggered = if events & epollet == epollet {
307 events &= !epollet;
308 true
309 } else {
310 false
311 };
312
306313 // Unset the flag we support to discover if any unsupported flags are used.
307314 let mut flags = events;
308315 // epoll_wait(2) will always wait for epollhup and epollerr; it is not
......@@ -311,12 +318,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
311318 events |= epollhup;
312319 events |= epollerr;
313320
314 if events & epollet != epollet {
315 // We only support edge-triggered notification for now.
316 throw_unsup_format!("epoll_ctl: epollet flag must be included.");
317 } else {
318 flags &= !epollet;
319 }
320321 if flags & epollin == epollin {
321322 flags &= !epollin;
322323 }
......@@ -350,6 +351,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
350351 }
351352 let new_interest = EpollEventInterest {
352353 relevant_events: events,
354 is_edge_triggered,
353355 data,
354356 active_events: 0,
355357 clock: VClock::default(),
......@@ -364,6 +366,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
364366 return this.set_errno_and_return_neg1_i32(LibcError("ENOENT"));
365367 };
366368 interest.relevant_events = events;
369 interest.is_edge_triggered = is_edge_triggered;
367370 interest.data = data;
368371 }
369372
......@@ -391,7 +394,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
391394 // We did not have interest in this.
392395 return this.set_errno_and_return_neg1_i32(LibcError("ENOENT"));
393396 };
394 epfd.ready_set.borrow_mut().remove(&epoll_key);
397 // Remove the ready event for this key, should one exist.
398 let mut ready_events = epfd.ready_events.borrow_mut();
399 if let Some(idx) = ready_events.iter().position(|k| k == &epoll_key) {
400 ready_events.remove(idx);
401 }
395402 // If this was the last interest in this FD, remove us from the global list
396403 // of who is interested in this FD.
397404 if interest_list.range(range_for_id(id)).next().is_none() {
......@@ -469,7 +476,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
469476 return this.set_errno_and_return_neg1(LibcError("EBADF"), dest);
470477 };
471478
472 if timeout == 0 || !epfd.ready_set.borrow().is_empty() {
479 if timeout == 0 || !epfd.ready_events.borrow().is_empty() {
473480 // If the timeout is 0 or there is a ready event, we can return immediately.
474481 return_ready_list(&epfd, dest, &event, this)?;
475482 } else {
......@@ -590,18 +597,29 @@ fn update_readiness<'tcx>(
590597 &mut dyn FnMut(EpollEventKey, &mut EpollEventInterest) -> InterpResult<'tcx>,
591598 ) -> InterpResult<'tcx>,
592599) -> InterpResult<'tcx> {
593 let mut ready_set = epoll.ready_set.borrow_mut();
600 let mut ready_events = epoll.ready_events.borrow_mut();
594601 for_each_interest(&mut |key, interest| {
595602 // Update the ready events tracked in this interest.
596603 let new_readiness = interest.relevant_events & active_events;
597604 let prev_readiness = std::mem::replace(&mut interest.active_events, new_readiness);
598605 if new_readiness == 0 {
599606 // Un-trigger this, there's nothing left to report here.
600 ready_set.remove(&key);
607 if let Some(idx) = ready_events.iter().position(|k| k == &key) {
608 ready_events.remove(idx);
609 }
601610 } else if force_edge || new_readiness != prev_readiness & new_readiness {
602 // Either we force an "edge" to be detected, or there's a bit set in `new`
603 // that was not set in `prev`. In both cases, this is ready now.
604 ready_set.insert(key);
611 // Either we force an "edge" to be detected or there's a bit set in `new_readiness`
612 // that was not set in `prev_readiness`. In both cases, this is ready now.
613
614 // We need to ensure that this event is not already part of the
615 // `ready_events` queue before enqueueing:
616 // <https://github.com/torvalds/linux/blob/HEAD/fs/eventpoll.c#L1292-L1296>
617 if !ready_events.contains(&key) {
618 ready_events.push_back(key);
619 }
620
621 // No matter whether this is newly ready or just re-triggered,
622 // the `epoll_wait` fetching this event should sync with the current thread.
605623 ecx.release_clock(|clock| {
606624 interest.clock.join(clock);
607625 })?;
......@@ -609,12 +627,12 @@ fn update_readiness<'tcx>(
609627 interp_ok(())
610628 })?;
611629 // While there are events ready to be delivered, wake up a thread to receive them.
612 while !ready_set.is_empty()
630 while !ready_events.is_empty()
613631 && let Some(thread_id) = epoll.queue.borrow_mut().pop_front()
614632 {
615 drop(ready_set); // release the "lock" so the unblocked thread can have it
633 drop(ready_events); // release the "lock" so the unblocked thread can have it
616634 ecx.unblock_thread(thread_id, BlockReason::Epoll { epfd: epoll.clone() })?;
617 ready_set = epoll.ready_set.borrow_mut();
635 ready_events = epoll.ready_events.borrow_mut();
618636 }
619637
620638 interp_ok(())
......@@ -629,7 +647,7 @@ fn return_ready_list<'tcx>(
629647 ecx: &mut MiriInterpCx<'tcx>,
630648) -> InterpResult<'tcx, i32> {
631649 let mut interest_list = epfd.interest_list.borrow_mut();
632 let mut ready_set = epfd.ready_set.borrow_mut();
650 let mut ready_events = epfd.ready_events.borrow_mut();
633651 let mut num_of_events: i32 = 0;
634652 let mut array_iter = ecx.project_array_fields(events)?;
635653
......@@ -644,27 +662,29 @@ fn return_ready_list<'tcx>(
644662 }
645663 }
646664
647 // While there is a slot to store another event, and an event to store, deliver that event.
648 // We can't use an iterator over `ready_set` as we want to remove elements as we go,
649 // so we track the most recently delivered event to find the next one. We track it as a lower
650 // bound that we can pass to `BTreeSet::range`.
651 let mut event_lower_bound = Bound::Unbounded;
652 while let Some(slot) = array_iter.next(ecx)?
653 && let Some(&key) = ready_set.range((event_lower_bound, Bound::Unbounded)).next()
665 // We will fill at most the first `ready_events_len` slots of the array.
666 // Bounding the iterator this way ensures that we can re-add events
667 // to the end of the queue during the loop without having them show up in the array.
668 let ready_events_len = u64::try_from(ready_events.len()).unwrap();
669 while let Some((idx, slot)) = array_iter.next(ecx)?
670 && idx < ready_events_len
671 && let Some(key) = ready_events.pop_front()
654672 {
655673 let interest = interest_list.get_mut(&key).expect("non-existent event in ready set");
656674 // Deliver event to caller.
657675 ecx.write_int_fields_named(
658676 &[("events", interest.active_events.into()), ("u64", interest.data.into())],
659 &slot.1,
677 &slot,
660678 )?;
661679 num_of_events = num_of_events.strict_add(1);
662680 // Synchronize receiving thread with the event of interest.
663681 ecx.acquire_clock(&interest.clock)?;
664 // This was an edge-triggered event, so remove it from the ready set.
665 ready_set.remove(&key);
666 // Go find the next event.
667 event_lower_bound = Bound::Excluded(key);
682 if !interest.is_edge_triggered {
683 // This is a level-triggered interest, so we need to re-add the event
684 // at the end of the ready queue:
685 // <https://github.com/torvalds/linux/blob/HEAD/fs/eventpoll.c#L1835-L1847>
686 ready_events.push_back(key);
687 }
668688 }
669689 ecx.write_int(num_of_events, dest)?;
670690 interp_ok(num_of_events)
src/tools/miri/src/shims/unix/linux_like/mod.rs+1
......@@ -2,3 +2,4 @@ pub mod epoll;
22pub mod eventfd;
33pub mod sync;
44pub mod syscall;
5pub mod thread;
src/tools/miri/src/shims/unix/linux_like/thread.rs created+54
......@@ -0,0 +1,54 @@
1use rustc_abi::{CanonAbi, Size};
2use rustc_middle::ty::Ty;
3use rustc_span::Symbol;
4use rustc_target::callconv::FnAbi;
5
6use crate::shims::sig::check_min_vararg_count;
7use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
8use crate::*;
9
10const TASK_COMM_LEN: u64 = 16;
11
12pub fn prctl<'tcx>(
13 ecx: &mut MiriInterpCx<'tcx>,
14 link_name: Symbol,
15 abi: &FnAbi<'tcx, Ty<'tcx>>,
16 args: &[OpTy<'tcx>],
17 dest: &MPlaceTy<'tcx>,
18) -> InterpResult<'tcx> {
19 let ([op], varargs) = ecx.check_shim_sig_variadic_lenient(abi, CanonAbi::C, link_name, args)?;
20
21 let pr_set_name = ecx.eval_libc_i32("PR_SET_NAME");
22 let pr_get_name = ecx.eval_libc_i32("PR_GET_NAME");
23
24 let res = match ecx.read_scalar(op)?.to_i32()? {
25 op if op == pr_set_name => {
26 let [name] = check_min_vararg_count("prctl(PR_SET_NAME, ...)", varargs)?;
27 let name = ecx.read_scalar(name)?;
28 let thread = ecx.pthread_self()?;
29 // The Linux kernel silently truncates long names.
30 // https://www.man7.org/linux/man-pages/man2/PR_SET_NAME.2const.html
31 let res =
32 ecx.pthread_setname_np(thread, name, TASK_COMM_LEN, /* truncate */ true)?;
33 assert_eq!(res, ThreadNameResult::Ok);
34 Scalar::from_u32(0)
35 }
36 op if op == pr_get_name => {
37 let [name] = check_min_vararg_count("prctl(PR_GET_NAME, ...)", varargs)?;
38 let name = ecx.read_scalar(name)?;
39 let thread = ecx.pthread_self()?;
40 let len = Scalar::from_target_usize(TASK_COMM_LEN, ecx);
41 ecx.check_ptr_access(
42 name.to_pointer(ecx)?,
43 Size::from_bytes(TASK_COMM_LEN),
44 CheckInAllocMsg::MemoryAccess,
45 )?;
46 let res = ecx.pthread_getname_np(thread, name, len, /* truncate*/ false)?;
47 assert_eq!(res, ThreadNameResult::Ok);
48 Scalar::from_u32(0)
49 }
50 op => throw_unsup_format!("Miri does not support `prctl` syscall with op={}", op),
51 };
52 ecx.write_scalar(res, dest)?;
53 interp_ok(())
54}
src/tools/miri/src/shims/windows/fs.rs+38-72
......@@ -1,72 +1,16 @@
1use std::fs::{Metadata, OpenOptions};
1use std::fs::{self, Dir};
22use std::io;
33use std::io::SeekFrom;
4use std::path::PathBuf;
54use std::time::SystemTime;
65
76use bitflags::bitflags;
87use rustc_abi::Size;
98use rustc_target::spec::Os;
109
11use crate::shims::files::{FdId, FileDescription, FileHandle};
10use crate::shims::files::{DirHandle, FileHandle};
1211use crate::shims::windows::handle::{EvalContextExt as _, Handle};
1312use crate::*;
1413
15#[derive(Debug)]
16pub struct DirHandle {
17 pub(crate) path: PathBuf,
18}
19
20impl FileDescription for DirHandle {
21 fn name(&self) -> &'static str {
22 "directory"
23 }
24
25 fn metadata<'tcx>(
26 &self,
27 ) -> InterpResult<'tcx, Either<io::Result<std::fs::Metadata>, &'static str>> {
28 interp_ok(Either::Left(self.path.metadata()))
29 }
30
31 fn destroy<'tcx>(
32 self,
33 _self_id: FdId,
34 _communicate_allowed: bool,
35 _ecx: &mut MiriInterpCx<'tcx>,
36 ) -> InterpResult<'tcx, io::Result<()>> {
37 interp_ok(Ok(()))
38 }
39}
40
41/// Windows supports handles without any read/write/delete permissions - these handles can get
42/// metadata, but little else. We represent that by storing the metadata from the time the handle
43/// was opened.
44#[derive(Debug)]
45pub struct MetadataHandle {
46 pub(crate) meta: Metadata,
47}
48
49impl FileDescription for MetadataHandle {
50 fn name(&self) -> &'static str {
51 "metadata-only"
52 }
53
54 fn metadata<'tcx>(
55 &self,
56 ) -> InterpResult<'tcx, Either<io::Result<std::fs::Metadata>, &'static str>> {
57 interp_ok(Either::Left(Ok(self.meta.clone())))
58 }
59
60 fn destroy<'tcx>(
61 self,
62 _self_id: FdId,
63 _communicate_allowed: bool,
64 _ecx: &mut MiriInterpCx<'tcx>,
65 ) -> InterpResult<'tcx, io::Result<()>> {
66 interp_ok(Ok(()))
67 }
68}
69
7014#[derive(Copy, Clone, Debug, PartialEq)]
7115enum CreationDisposition {
7216 CreateAlways,
......@@ -213,8 +157,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
213157 throw_unsup_format!("CreateFileW: Template files are not supported");
214158 }
215159
216 // We need to know if the file is a directory to correctly open directory handles.
217 // This is racy, but currently the stdlib doesn't appear to offer a better solution.
160 // We need to know if the file is a directory to correctly open directory handles. This is
161 // racy, but currently the stdlib doesn't appear to offer a better solution. We do later
162 // verify that our guess was correct so worst-case, Miri ICEs here.
163 // FIXME: retry in a loop if we get an error indicating we got the wrong file type?
218164 let is_dir = file_name.is_dir();
219165
220166 // BACKUP_SEMANTICS is how Windows calls the act of opening a directory handle.
......@@ -226,7 +172,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
226172 let desired_read = desired_access & generic_read != 0;
227173 let desired_write = desired_access & generic_write != 0;
228174
229 let mut options = OpenOptions::new();
175 let mut options = fs::OpenOptions::new();
230176 if desired_read {
231177 desired_access &= !generic_read;
232178 options.read(true);
......@@ -261,17 +207,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
261207
262208 let handle = if is_dir {
263209 // Open this as a directory.
264 let fd_num = this.machine.fds.insert_new(DirHandle { path: file_name });
265 Ok(Handle::File(fd_num))
266 } else if creation_disposition == OpenExisting && !(desired_read || desired_write) {
267 // Windows supports handles with no permissions. These allow things such as reading
268 // metadata, but not file content.
269 file_name.metadata().map(|meta| {
270 let fd_num = this.machine.fds.insert_new(MetadataHandle { meta });
210 // FIXME: shouldn't we check `creation_disposition` here?
211 Dir::open(&file_name).map(|dir| {
212 #[cfg(not(bootstrap))]
213 assert!(
214 dir.metadata().unwrap().is_dir(),
215 "we tried to open a directory and got a file"
216 );
217 let fd_num = this.machine.fds.insert_new(DirHandle { dir, path: file_name });
271218 Handle::File(fd_num)
272219 })
273220 } else {
274 // Open this as a standard file.
221 // Open this as a standard file. We already set the `read`/`write` flags above,
222 // but we still need to represent the `creation_disposition`.
275223 match creation_disposition {
276224 CreateAlways | OpenAlways => {
277225 options.create(true);
......@@ -288,15 +236,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
288236 options.append(true);
289237 }
290238 }
291 OpenExisting => {} // Default options
239 OpenExisting => {
240 if !desired_read && !desired_write {
241 // Windows supports handles with no permissions. These allow things such as
242 // reading metadata, but not file content. This is used by `Path::metadata`.
243 // `std` does not support this. To ensure we behave correctly as often as
244 // possible, we open the file for reading and live with the fact that this
245 // might incorrectly return `PermissionDenied`.
246 // FIXME: We could probably use `OpenOptionsExt`? On a Unix host,
247 // `O_PATH` apparently can open files for metadata use only.
248 options.read(true);
249 }
250 }
292251 TruncateExisting => {
293252 options.truncate(true);
294253 }
295254 }
296255
297256 options.open(file_name).map(|file| {
298 let fd_num =
299 this.machine.fds.insert_new(FileHandle { file, writable: desired_write });
257 assert!(
258 !file.metadata().unwrap().is_dir(),
259 "we tried to open a file and got a directory"
260 );
261 let fd_num = this.machine.fds.insert_new(FileHandle {
262 file,
263 writable: desired_write,
264 readable: desired_read,
265 });
300266 Handle::File(fd_num)
301267 })
302268 };
src/tools/miri/tests/fail-dep/libc/libc-epoll-data-race.rs+11-43
......@@ -6,33 +6,13 @@
66// ensure deterministic schedule
77//@compile-flags: -Zmiri-deterministic-concurrency
88
9use std::convert::TryInto;
109use std::thread;
1110use std::thread::spawn;
1211
1312#[path = "../../utils/libc.rs"]
1413mod libc_utils;
15
16#[track_caller]
17fn check_epoll_wait<const N: usize>(epfd: i32, expected_notifications: &[(u32, u64)]) {
18 let epoll_event = libc::epoll_event { events: 0, u64: 0 };
19 let mut array: [libc::epoll_event; N] = [epoll_event; N];
20 let maxsize = N;
21 let array_ptr = array.as_mut_ptr();
22 let res = unsafe { libc::epoll_wait(epfd, array_ptr, maxsize.try_into().unwrap(), 0) };
23 if res < 0 {
24 panic!("epoll_wait failed: {}", std::io::Error::last_os_error());
25 }
26 assert_eq!(
27 res,
28 expected_notifications.len().try_into().unwrap(),
29 "got wrong number of notifications"
30 );
31 let got_notifications =
32 unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) };
33 let got_notifications = got_notifications.iter().map(|e| (e.events, e.u64)).collect::<Vec<_>>();
34 assert_eq!(got_notifications, expected_notifications, "got wrong notifications");
35}
14use libc_utils::epoll::*;
15use libc_utils::*;
3616
3717fn main() {
3818 // Create an epoll instance.
......@@ -41,27 +21,17 @@ fn main() {
4121
4222 // Create two socketpair instances.
4323 let mut fds_a = [-1, -1];
44 let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds_a.as_mut_ptr()) };
45 assert_eq!(res, 0);
46
24 unsafe {
25 errno_check(libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds_a.as_mut_ptr()))
26 };
4727 let mut fds_b = [-1, -1];
48 let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds_b.as_mut_ptr()) };
49 assert_eq!(res, 0);
50
51 // Register both pipe read ends.
52 let mut ev = libc::epoll_event {
53 events: (libc::EPOLLIN | libc::EPOLLET) as _,
54 u64: u64::try_from(fds_a[1]).unwrap(),
28 unsafe {
29 errno_check(libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds_b.as_mut_ptr()))
5530 };
56 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds_a[1], &mut ev) };
57 assert_eq!(res, 0);
5831
59 let mut ev = libc::epoll_event {
60 events: (libc::EPOLLIN | libc::EPOLLET) as _,
61 u64: u64::try_from(fds_b[1]).unwrap(),
62 };
63 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds_b[1], &mut ev) };
64 assert_eq!(res, 0);
32 // Register both pipe read ends.
33 epoll_ctl_add(epfd, fds_a[1], EPOLLIN | EPOLLET).unwrap();
34 epoll_ctl_add(epfd, fds_b[1], EPOLLIN | EPOLLET).unwrap();
6535
6636 static mut VAL_ONE: u8 = 40; // This one will be read soundly.
6737 static mut VAL_TWO: u8 = 50; // This one will be read unsoundly.
......@@ -78,9 +48,7 @@ fn main() {
7848 thread::yield_now();
7949
8050 // With room for one event: check result from epoll_wait.
81 let expected_event = u32::try_from(libc::EPOLLIN).unwrap();
82 let expected_value = u64::try_from(fds_a[1]).unwrap();
83 check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)]);
51 check_epoll_wait_partial(epfd, &[Ev { events: EPOLLIN, data: fds_a[1] }], 1, -1);
8452
8553 // Since we only received one event, we have synchronized with
8654 // the write to VAL_ONE but not with the one to VAL_TWO.
src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.rs+19-43
......@@ -2,42 +2,11 @@
22//@only-target: linux android illumos
33//@error-in-other-file: deadlock
44
5use std::convert::TryInto;
65use std::thread;
76
87#[path = "../../utils/libc.rs"]
98mod libc_utils;
10
11// Using `as` cast since `EPOLLET` wraps around
12const EPOLL_IN_OUT_ET: u32 = (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _;
13
14#[track_caller]
15fn check_epoll_wait<const N: usize>(
16 epfd: i32,
17 expected_notifications: &[(u32, u64)],
18 timeout: i32,
19) {
20 let epoll_event = libc::epoll_event { events: 0, u64: 0 };
21 let mut array: [libc::epoll_event; N] = [epoll_event; N];
22 let maxsize = N;
23 let array_ptr = array.as_mut_ptr();
24 let res = unsafe { libc::epoll_wait(epfd, array_ptr, maxsize.try_into().unwrap(), timeout) };
25 if res < 0 {
26 panic!("epoll_wait failed: {}", std::io::Error::last_os_error());
27 }
28 assert_eq!(
29 res,
30 expected_notifications.len().try_into().unwrap(),
31 "got wrong number of notifications"
32 );
33 let slice = unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) };
34 for (return_event, expected_event) in slice.iter().zip(expected_notifications.iter()) {
35 let event = return_event.events;
36 let data = return_event.u64;
37 assert_eq!(event, expected_event.0, "got wrong events");
38 assert_eq!(data, expected_event.1, "got wrong data");
39 }
40}
9use libc_utils::epoll::*;
4110
4211// Test if only one thread is unblocked if multiple threads blocked on same epfd.
4312// Expected execution:
......@@ -57,23 +26,30 @@ fn main() {
5726 let fd2 = unsafe { libc::dup(fd1) };
5827
5928 // Register both with epoll.
60 let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd1 as u64 };
61 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd1, &mut ev) };
62 assert_eq!(res, 0);
63 let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fd2 as u64 };
64 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd2, &mut ev) };
65 assert_eq!(res, 0);
29 epoll_ctl_add(epfd, fd1, EPOLLIN | EPOLLOUT | EPOLLET).unwrap();
30 epoll_ctl_add(epfd, fd2, EPOLLIN | EPOLLOUT | EPOLLET).unwrap();
6631
6732 // Consume the initial events.
68 let expected = [(libc::EPOLLOUT as u32, fd1 as u64), (libc::EPOLLOUT as u32, fd2 as u64)];
69 check_epoll_wait::<8>(epfd, &expected, -1);
33 check_epoll_wait(
34 epfd,
35 &[Ev { events: EPOLLOUT, data: fd1 }, Ev { events: EPOLLOUT, data: fd2 }],
36 -1,
37 );
7038
7139 let thread1 = thread::spawn(move || {
72 check_epoll_wait::<2>(epfd, &expected, -1);
40 check_epoll_wait(
41 epfd,
42 &[Ev { events: EPOLLOUT, data: fd1 }, Ev { events: EPOLLOUT, data: fd2 }],
43 -1,
44 );
7345 });
7446 let thread2 = thread::spawn(move || {
75 check_epoll_wait::<2>(epfd, &expected, -1);
76 //~^ERROR: deadlocked
47 //~vERROR: deadlocked
48 check_epoll_wait(
49 epfd,
50 &[Ev { events: EPOLLOUT, data: fd1 }, Ev { events: EPOLLOUT, data: fd2 }],
51 -1,
52 );
7753 });
7854 // Yield so the threads are both blocked.
7955 thread::yield_now();
src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr+10-3
......@@ -18,8 +18,12 @@ LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
1818error: the evaluated program deadlocked
1919 --> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC
2020 |
21LL | check_epoll_wait::<TAG>(epfd, &expected, -1);
22 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread got stuck here
21LL | / check_epoll_wait(
22LL | | epfd,
23LL | | &[Ev { events: EPOLLOUT, data: fd1 }, Ev { events: EPOLLOUT, data: fd2 }],
24LL | | -1,
25LL | | );
26 | |_________^ thread got stuck here
2327 |
2428 = note: this is on thread `unnamed-ID`
2529note: the current function got called indirectly due to this code
......@@ -27,8 +31,11 @@ note: the current function got called indirectly due to this code
2731 |
2832LL | let thread2 = thread::spawn(move || {
2933 | ___________________^
30LL | | check_epoll_wait::<TAG>(epfd, &expected, -1);
3134LL | |
35LL | | check_epoll_wait(
36LL | | epfd,
37... |
38LL | | );
3239LL | | });
3340 | |______^
3441
src/tools/miri/tests/fail-dep/libc/socket-connect-after-failed-connection.rs+1-1
......@@ -41,7 +41,7 @@ fn main() {
4141 epoll_ctl_add(epfd, client_sockfd, EPOLLOUT | EPOLLET | libc::EPOLLERR).unwrap();
4242
4343 // Wait until the socket has an error.
44 check_epoll_wait::<8>(
44 check_epoll_wait(
4545 epfd,
4646 &[Ev { events: libc::EPOLLERR | EPOLLOUT | EPOLLHUP, data: client_sockfd }],
4747 -1,
src/tools/miri/tests/fail/async-shared-mutable.rs+1-1
......@@ -3,7 +3,7 @@
33//! `UnsafePinned` must include the effects of `UnsafeCell`.
44//@revisions: stack tree
55//@[tree]compile-flags: -Zmiri-tree-borrows
6//@normalize-stderr-test: "\[0x[a-fx\d.]+\]" -> "[OFFSET]"
6//@normalize-stderr-test: "\[0x[a-fx\d.]+\]" -> "[RANGE]"
77
88use core::future::Future;
99use core::pin::{Pin, pin};
src/tools/miri/tests/fail/async-shared-mutable.stack.stderr+4-4
......@@ -1,12 +1,12 @@
1error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[OFFSET], but that tag does not exist in the borrow stack for this location
1error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[RANGE], but that tag does not exist in the borrow stack for this location
22 --> tests/fail/async-shared-mutable.rs:LL:CC
33 |
44LL | *x = 1;
5 | ^^^^^^ this error occurs as part of an access at ALLOC[OFFSET]
5 | ^^^^^^ this error occurs as part of an access at ALLOC[RANGE]
66 |
77 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
88 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
9help: <TAG> was created by a Unique retag at offsets [OFFSET]
9help: <TAG> was created by a Unique retag at offsets [RANGE]
1010 --> tests/fail/async-shared-mutable.rs:LL:CC
1111 |
1212LL | / core::future::poll_fn(move |_| {
......@@ -15,7 +15,7 @@ LL | | Poll::<()>::Pending
1515LL | | })
1616LL | | .await
1717 | |______________^
18help: <TAG> was later invalidated at offsets [OFFSET] by a SharedReadOnly retag
18help: <TAG> was later invalidated at offsets [RANGE] by a SharedReadOnly retag
1919 --> tests/fail/async-shared-mutable.rs:LL:CC
2020 |
2121LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
src/tools/miri/tests/fail/async-shared-mutable.tree.stderr+3-3
......@@ -1,4 +1,4 @@
1error: Undefined Behavior: write access through <TAG> at ALLOC[OFFSET] is forbidden
1error: Undefined Behavior: write access through <TAG> at ALLOC[RANGE] is forbidden
22 --> tests/fail/async-shared-mutable.rs:LL:CC
33 |
44LL | *x = 1;
......@@ -16,13 +16,13 @@ LL | | Poll::<()>::Pending
1616LL | | })
1717LL | | .await
1818 | |______________^
19help: the accessed tag <TAG> later transitioned to Unique due to a child write access at offsets [OFFSET]
19help: the accessed tag <TAG> later transitioned to Unique due to a child write access at offsets [RANGE]
2020 --> tests/fail/async-shared-mutable.rs:LL:CC
2121 |
2222LL | *x = 1;
2323 | ^^^^^^
2424 = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
25help: the accessed tag <TAG> later transitioned to Frozen due to a reborrow (acting as a foreign read access) at offsets [OFFSET]
25help: the accessed tag <TAG> later transitioned to Frozen due to a reborrow (acting as a foreign read access) at offsets [RANGE]
2626 --> tests/fail/async-shared-mutable.rs:LL:CC
2727 |
2828LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.rs created+131
......@@ -0,0 +1,131 @@
1//! Test related to <https://github.com/rust-lang/miri/issues/3341>:
2//! `Box` with custom allocators are still `noalias`, leading to UB.
3
4//@revisions: stack tree
5//@[tree]compile-flags: -Zmiri-tree-borrows
6//@normalize-stderr-test: "\[0x[a-fx\d.]+\]" -> "[RANGE]"
7#![feature(allocator_api)]
8
9use std::alloc::{AllocError, Allocator, Layout};
10use std::cell::{Cell, UnsafeCell};
11use std::mem;
12use std::ptr::{self, NonNull, addr_of};
13use std::thread::{self, ThreadId};
14
15const BIN_SIZE: usize = 8;
16
17// A bin represents a collection of blocks of a specific layout.
18#[repr(align(128))]
19struct MyBin {
20 top: Cell<usize>,
21 thread_id: ThreadId,
22 memory: UnsafeCell<[usize; BIN_SIZE]>,
23}
24
25impl MyBin {
26 fn pop(&self) -> Option<NonNull<u8>> {
27 let top = self.top.get();
28 if top == BIN_SIZE {
29 return None;
30 }
31 // Cast the *entire* thing to a raw pointer to not restrict its provenance.
32 let bin = self as *const MyBin;
33 let base_ptr = UnsafeCell::raw_get(unsafe { addr_of!((*bin).memory) }).cast::<usize>();
34 let ptr = unsafe { NonNull::new_unchecked(base_ptr.add(top)) };
35 self.top.set(top + 1);
36 Some(ptr.cast())
37 }
38
39 // Pretends to not be a throwaway allocation method like this. A more realistic
40 // substitute is using intrusive linked lists, which requires access to the
41 // metadata of this bin as well.
42 unsafe fn push(&self, ptr: NonNull<u8>) {
43 // For now just check that this really is in this bin.
44 let start = self.memory.get().addr();
45 let end = start + BIN_SIZE * mem::size_of::<usize>();
46 let addr = ptr.addr().get();
47 assert!((start..end).contains(&addr));
48
49 // We can't update `top` as this may not be the last bin, but we can pretend to do so
50 // such that the aliasing model checks things.
51 // We access this via raw pointers so that the error span is in this file.
52 let top_ptr = (&raw const self.top) as *mut usize;
53 let top = top_ptr.read();
54 //~[tree]^ERROR: /read access .* is forbidden/
55 top_ptr.write(top);
56 }
57}
58
59// A collection of bins.
60struct MyAllocator {
61 thread_id: ThreadId,
62 // Pretends to be some complex collection of bins, such as an array of linked lists.
63 bins: Box<[MyBin; 1]>,
64}
65
66impl MyAllocator {
67 fn new() -> Self {
68 let thread_id = thread::current().id();
69 MyAllocator {
70 thread_id,
71 bins: Box::new(
72 [MyBin { top: Cell::new(0), thread_id, memory: UnsafeCell::default() }; 1],
73 ),
74 }
75 }
76
77 // Pretends to be expensive finding a suitable bin for the layout.
78 fn find_bin(&self, layout: Layout) -> Option<&MyBin> {
79 if layout == Layout::new::<usize>() { Some(&self.bins[0]) } else { None }
80 }
81}
82
83unsafe impl Allocator for MyAllocator {
84 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
85 // Expensive bin search.
86 let bin = self.find_bin(layout).ok_or(AllocError)?;
87 let ptr = bin.pop().ok_or(AllocError)?;
88 Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
89 }
90
91 unsafe fn deallocate(&self, ptr: NonNull<u8>, _layout: Layout) {
92 // Make sure accesses via `self` don't disturb anything.
93 let _val = self.bins[0].top.get();
94 // Since manually finding the corresponding bin of `ptr` is very expensive,
95 // doing pointer arithmetics is preferred.
96 // But this means we access `top` via `ptr` rather than `self`!
97 // That is fundamentally the source of the aliasing trouble in this example.
98 let their_bin = ptr.as_ptr().map_addr(|addr| addr & !127).cast::<MyBin>();
99 let thread_id = ptr::read(ptr::addr_of!((*their_bin).thread_id));
100 //~[stack]^ERROR: tag does not exist in the borrow stack
101 if self.thread_id == thread_id {
102 unsafe { (*their_bin).push(ptr) };
103 } else {
104 todo!("Deallocating from another thread");
105 }
106 // Make sure we can also still access this via `self` after the rest is done.
107 let _val = self.bins[0].top.get();
108 }
109}
110
111// Make sure to involve `Box` in allocating these,
112// as that's where `noalias` may come from.
113fn v1<T, A: Allocator>(t: T, a: A) -> Vec<T, A> {
114 (Box::new_in([t], a) as Box<[T], A>).into_vec()
115}
116fn v2<T, A: Allocator>(t: T, a: A) -> Vec<T, A> {
117 let v = v1(t, a);
118 // There was a bug in `into_boxed_slice` that caused aliasing issues,
119 // so round-trip through that as well.
120 v.into_boxed_slice().into_vec()
121}
122
123fn main() {
124 assert!(mem::size_of::<MyBin>() <= 128); // if it grows bigger, the trick to access the "header" no longer works
125 let my_alloc = MyAllocator::new();
126 let a = v1(1usize, &my_alloc);
127 let b = v2(2usize, &my_alloc);
128 assert_eq!(a[0] + 1, b[0]);
129 assert_eq!(addr_of!(a[0]).wrapping_add(1), addr_of!(b[0]));
130 drop((a, b));
131}
src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.stack.stderr created+37
......@@ -0,0 +1,37 @@
1error: Undefined Behavior: attempting a read access using <TAG> at ALLOC[RANGE], but that tag does not exist in the borrow stack for this location
2 --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
3 |
4LL | let thread_id = ptr::read(ptr::addr_of!((*their_bin).thread_id));
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of an access at ALLOC[RANGE]
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
9help: <TAG> was created by a Unique retag at offsets [RANGE]
10 --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
11 |
12LL | (Box::new_in([t], a) as Box<[T], A>).into_vec()
13 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14 = note: stack backtrace:
15 0: <MyAllocator as std::alloc::Allocator>::deallocate
16 at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
17 1: <&MyAllocator as std::alloc::Allocator>::deallocate
18 at RUSTLIB/core/src/alloc/mod.rs:LL:CC
19 2: alloc::raw_vec::RawVecInner::<&MyAllocator>::deallocate
20 at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC
21 3: <alloc::raw_vec::RawVec<usize, &MyAllocator> as std::ops::Drop>::drop
22 at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC
23 4: std::ptr::drop_glue::<alloc::raw_vec::RawVec<usize, &MyAllocator>> - shim(Some(alloc::raw_vec::RawVec<usize, &MyAllocator>))
24 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
25 5: std::ptr::drop_glue::<std::vec::Vec<usize, &MyAllocator>> - shim(Some(std::vec::Vec<usize, &MyAllocator>))
26 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
27 6: std::ptr::drop_glue::<(std::vec::Vec<usize, &MyAllocator>, std::vec::Vec<usize, &MyAllocator>)> - shim(Some((std::vec::Vec<usize, &MyAllocator>, std::vec::Vec<usize, &MyAllocator>)))
28 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
29 7: std::mem::drop::<(std::vec::Vec<usize, &MyAllocator>, std::vec::Vec<usize, &MyAllocator>)>
30 at RUSTLIB/core/src/mem/mod.rs:LL:CC
31 8: main
32 at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
33
34note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
35
36error: aborting due to 1 previous error
37
src/tools/miri/tests/fail/both_borrows/box-custom-alloc-aliasing.tree.stderr created+52
......@@ -0,0 +1,52 @@
1error: Undefined Behavior: read access through <TAG> at ALLOC[RANGE] is forbidden
2 --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
3 |
4LL | let top = top_ptr.read();
5 | ^^^^^^^^^^^^^^ Undefined Behavior occurred here
6 |
7 = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
8 = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
9 = help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
10 = help: the conflicting tag <TAG> has state Disabled which forbids this child read access
11help: the accessed tag <TAG> was created here
12 --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
13 |
14LL | unsafe fn push(&self, ptr: NonNull<u8>) {
15 | ^^^^^
16help: the conflicting tag <TAG> was created here, in the initial state Reserved
17 --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
18 |
19LL | (Box::new_in([t], a) as Box<[T], A>).into_vec()
20 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21help: the conflicting tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [RANGE]
22 --> tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
23 |
24LL | self.top.set(top + 1);
25 | ^^^^^^^^^^^^^^^^^^^^^
26 = help: this transition corresponds to a loss of read and write permissions
27 = note: stack backtrace:
28 0: MyBin::push
29 at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
30 1: <MyAllocator as std::alloc::Allocator>::deallocate
31 at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
32 2: <&MyAllocator as std::alloc::Allocator>::deallocate
33 at RUSTLIB/core/src/alloc/mod.rs:LL:CC
34 3: alloc::raw_vec::RawVecInner::<&MyAllocator>::deallocate
35 at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC
36 4: <alloc::raw_vec::RawVec<usize, &MyAllocator> as std::ops::Drop>::drop
37 at RUSTLIB/alloc/src/raw_vec/mod.rs:LL:CC
38 5: std::ptr::drop_glue::<alloc::raw_vec::RawVec<usize, &MyAllocator>> - shim(Some(alloc::raw_vec::RawVec<usize, &MyAllocator>))
39 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
40 6: std::ptr::drop_glue::<std::vec::Vec<usize, &MyAllocator>> - shim(Some(std::vec::Vec<usize, &MyAllocator>))
41 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
42 7: std::ptr::drop_glue::<(std::vec::Vec<usize, &MyAllocator>, std::vec::Vec<usize, &MyAllocator>)> - shim(Some((std::vec::Vec<usize, &MyAllocator>, std::vec::Vec<usize, &MyAllocator>)))
43 at RUSTLIB/core/src/ptr/mod.rs:LL:CC
44 8: std::mem::drop::<(std::vec::Vec<usize, &MyAllocator>, std::vec::Vec<usize, &MyAllocator>)>
45 at RUSTLIB/core/src/mem/mod.rs:LL:CC
46 9: main
47 at tests/fail/both_borrows/box-custom-alloc-aliasing.rs:LL:CC
48
49note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
50
51error: aborting due to 1 previous error
52
src/tools/miri/tests/fail/data_race/dangling_thread_async_race.rs+1-1
......@@ -25,7 +25,7 @@ fn main() {
2525
2626 // Detach the thread and sleep until it terminates
2727 mem::drop(join);
28 sleep(Duration::from_millis(200));
28 sleep(Duration::from_millis(100));
2929
3030 // Spawn and immediately join a thread
3131 // to execute the join code-path
src/tools/miri/tests/fail/data_race/dangling_thread_race.rs+1-1
......@@ -25,7 +25,7 @@ fn main() {
2525
2626 // Detach the thread and sleep until it terminates
2727 mem::drop(join);
28 sleep(Duration::from_millis(200));
28 sleep(Duration::from_millis(100));
2929
3030 // Spawn and immediately join a thread
3131 // to execute the join code-path
src/tools/miri/tests/fail/data_race/dealloc_read_race_stack.rs+1-1
......@@ -34,7 +34,7 @@ fn main() {
3434
3535 pointer.store(&mut stack_var as *mut _, Ordering::Release);
3636
37 sleep(Duration::from_millis(200));
37 sleep(Duration::from_millis(100));
3838
3939 // Now `stack_var` gets deallocated.
4040 } //~ ERROR: Data race detected between (1) non-atomic read on thread `unnamed-2` and (2) deallocation on thread `unnamed-1`
src/tools/miri/tests/fail/data_race/dealloc_write_race_stack.rs+1-1
......@@ -34,7 +34,7 @@ fn main() {
3434
3535 pointer.store(&mut stack_var as *mut _, Ordering::Release);
3636
37 sleep(Duration::from_millis(200));
37 sleep(Duration::from_millis(100));
3838
3939 // Now `stack_var` gets deallocated.
4040 } //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-2` and (2) deallocation on thread `unnamed-1`
src/tools/miri/tests/fail/data_race/read_write_race_stack.rs+1-1
......@@ -39,7 +39,7 @@ fn main() {
3939
4040 pointer.store(&mut stack_var as *mut _, Ordering::Release);
4141
42 sleep(Duration::from_millis(200));
42 sleep(Duration::from_millis(100));
4343
4444 stack_var //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-2` and (2) non-atomic read on thread `unnamed-1`
4545 });
src/tools/miri/tests/fail/data_race/release_seq_race.rs+1-1
......@@ -31,7 +31,7 @@ fn main() {
3131 let c = c; // avoid field capturing
3232 *c.0 = 1;
3333 SYNC.store(1, Ordering::Release);
34 sleep(Duration::from_millis(200));
34 sleep(Duration::from_millis(100));
3535 SYNC.store(3, Ordering::Relaxed);
3636 });
3737
src/tools/miri/tests/fail/data_race/write_write_race_stack.rs+1-1
......@@ -39,7 +39,7 @@ fn main() {
3939
4040 pointer.store(&mut stack_var as *mut _, Ordering::Release);
4141
42 sleep(Duration::from_millis(200));
42 sleep(Duration::from_millis(100));
4343
4444 stack_var = 1usize; //~ ERROR: Data race detected between (1) non-atomic write on thread `unnamed-2` and (2) non-atomic write on thread `unnamed-1`
4545
src/tools/miri/tests/pass-dep/concurrency/apple-futex.rs+11-13
......@@ -62,7 +62,7 @@ fn wait_timeout() {
6262
6363 let futex: i32 = 123;
6464
65 // Wait for 200ms, with nobody waking us up early.
65 // Wait for 100ms, with nobody waking us up early.
6666 unsafe {
6767 assert_eq!(
6868 libc::os_sync_wait_on_address_with_timeout(
......@@ -71,14 +71,14 @@ fn wait_timeout() {
7171 size_of::<i32>(),
7272 libc::OS_SYNC_WAIT_ON_ADDRESS_NONE,
7373 libc::OS_CLOCK_MACH_ABSOLUTE_TIME,
74 200_000_000,
74 100_000_000,
7575 ),
7676 -1,
7777 );
7878 assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
7979 }
8080
81 assert!((200..1000).contains(&start.elapsed().as_millis()));
81 assert!((100..1000).contains(&start.elapsed().as_millis()));
8282}
8383
8484fn wait_absolute_timeout() {
......@@ -88,15 +88,15 @@ fn wait_absolute_timeout() {
8888 #[allow(deprecated)]
8989 let mut deadline = unsafe { libc::mach_absolute_time() };
9090
91 // Add 200ms.
91 // Add 100ms.
9292 // What we should be doing here is call `mach_timebase_info` to determine the
9393 // unit used for `deadline`, but we know what Miri returns for that function:
9494 // the unit is nanoseconds.
95 deadline += 200_000_000;
95 deadline += 100_000_000;
9696
9797 let futex: i32 = 123;
9898
99 // Wait for 200ms from now, with nobody waking us up early.
99 // Wait for 100ms from now, with nobody waking us up early.
100100 unsafe {
101101 assert_eq!(
102102 libc::os_sync_wait_on_address_with_deadline(
......@@ -112,16 +112,14 @@ fn wait_absolute_timeout() {
112112 assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
113113 }
114114
115 assert!((200..1000).contains(&start.elapsed().as_millis()));
115 assert!((100..1000).contains(&start.elapsed().as_millis()));
116116}
117117
118118fn wait_wake() {
119 let start = Instant::now();
120
121119 static mut FUTEX: i32 = 0;
122120
123121 let t = thread::spawn(move || {
124 thread::sleep(Duration::from_millis(200));
122 thread::sleep(Duration::from_millis(100));
125123 unsafe {
126124 assert_eq!(
127125 libc::os_sync_wake_by_address_any(
......@@ -134,6 +132,8 @@ fn wait_wake() {
134132 }
135133 });
136134
135 let start = Instant::now();
136
137137 unsafe {
138138 assert_eq!(
139139 libc::os_sync_wait_on_address(
......@@ -146,9 +146,7 @@ fn wait_wake() {
146146 );
147147 }
148148
149 // When running this in stress-gc mode, things can take quite long.
150 // So the timeout is 3000 ms.
151 assert!((200..3000).contains(&start.elapsed().as_millis()));
149 assert!((100..1000).contains(&start.elapsed().as_millis()));
152150 t.join().unwrap();
153151}
154152
src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs+19-21
......@@ -78,7 +78,7 @@ fn wait_timeout() {
7878
7979 let futex: i32 = 123;
8080
81 // Wait for 200ms, with nobody waking us up early.
81 // Wait for 100ms, with nobody waking us up early.
8282 unsafe {
8383 assert_eq!(
8484 libc::syscall(
......@@ -86,17 +86,19 @@ fn wait_timeout() {
8686 addr_of!(futex),
8787 libc::FUTEX_WAIT,
8888 123,
89 &libc::timespec { tv_sec: 0, tv_nsec: 200_000_000 },
89 &libc::timespec { tv_sec: 0, tv_nsec: 100_000_000 },
9090 ),
9191 -1,
9292 );
9393 assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
9494 }
9595
96 assert!((200..1000).contains(&start.elapsed().as_millis()));
96 assert!((100..1000).contains(&start.elapsed().as_millis()));
9797}
9898
9999fn wait_absolute_timeout() {
100 static mut FUTEX: i32 = 123;
101
100102 let start = Instant::now();
101103
102104 // Get the current monotonic timestamp as timespec.
......@@ -106,21 +108,19 @@ fn wait_absolute_timeout() {
106108 now.assume_init()
107109 };
108110
109 // Add 200ms.
110 timeout.tv_nsec += 200_000_000;
111 // Add 100ms.
112 timeout.tv_nsec += 100_000_000;
111113 if timeout.tv_nsec > 1_000_000_000 {
112114 timeout.tv_nsec -= 1_000_000_000;
113115 timeout.tv_sec += 1;
114116 }
115117
116 let futex: i32 = 123;
117
118 // Wait for 200ms from now, with nobody waking us up early.
118 // Wait for 100ms from now, with nobody waking us up early.
119119 unsafe {
120120 assert_eq!(
121121 libc::syscall(
122122 libc::SYS_futex,
123 addr_of!(futex),
123 addr_of!(FUTEX),
124124 libc::FUTEX_WAIT_BITSET,
125125 123,
126126 &timeout,
......@@ -132,16 +132,14 @@ fn wait_absolute_timeout() {
132132 assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::ETIMEDOUT);
133133 }
134134
135 assert!((200..1000).contains(&start.elapsed().as_millis()));
135 assert!((100..1000).contains(&start.elapsed().as_millis()));
136136}
137137
138138fn wait_wake() {
139 let start = Instant::now();
140
141139 static mut FUTEX: i32 = 0;
142140
143141 let t = thread::spawn(move || {
144 thread::sleep(Duration::from_millis(200));
142 thread::sleep(Duration::from_millis(100));
145143 unsafe {
146144 assert_eq!(
147145 libc::syscall(
......@@ -155,6 +153,8 @@ fn wait_wake() {
155153 }
156154 });
157155
156 let start = Instant::now();
157
158158 unsafe {
159159 assert_eq!(
160160 libc::syscall(
......@@ -168,19 +168,15 @@ fn wait_wake() {
168168 );
169169 }
170170
171 // When running this in stress-gc mode, things can take quite long.
172 // So the timeout is 3000 ms.
173 assert!((200..3000).contains(&start.elapsed().as_millis()));
171 assert!((100..1000).contains(&start.elapsed().as_millis()));
174172 t.join().unwrap();
175173}
176174
177175fn wait_wake_bitset() {
178 let start = Instant::now();
179
180176 static mut FUTEX: i32 = 0;
181177
182178 let t = thread::spawn(move || {
183 thread::sleep(Duration::from_millis(200));
179 thread::sleep(Duration::from_millis(100));
184180 unsafe {
185181 assert_eq!(
186182 libc::syscall(
......@@ -195,7 +191,7 @@ fn wait_wake_bitset() {
195191 0, // Didn't match any thread.
196192 );
197193 }
198 thread::sleep(Duration::from_millis(200));
194 thread::sleep(Duration::from_millis(100));
199195 unsafe {
200196 assert_eq!(
201197 libc::syscall(
......@@ -212,6 +208,8 @@ fn wait_wake_bitset() {
212208 }
213209 });
214210
211 let start = Instant::now();
212
215213 unsafe {
216214 assert_eq!(
217215 libc::syscall(
......@@ -227,7 +225,7 @@ fn wait_wake_bitset() {
227225 );
228226 }
229227
230 assert!((400..1000).contains(&start.elapsed().as_millis()));
228 assert!((200..1000).contains(&start.elapsed().as_millis()));
231229 t.join().unwrap();
232230}
233231
src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs+64-34
......@@ -1,6 +1,7 @@
11//@only-target: linux android illumos
22// test_epoll_block_then_unblock and test_epoll_race depend on a deterministic schedule.
33//@compile-flags: -Zmiri-deterministic-concurrency
4//@revisions: edge_triggered level_triggered
45
56use std::convert::TryInto;
67use std::thread;
......@@ -10,6 +11,10 @@ mod libc_utils;
1011use libc_utils::epoll::*;
1112use libc_utils::*;
1213
14/// When the `edge_triggered` revision is active, this is EPOLLET, otherwise
15/// it's zero which means we perform level-triggered epolls.
16const EPOLLET_OR_ZERO: libc::c_int = if cfg!(edge_triggered) { EPOLLET } else { 0 };
17
1318// This is a set of testcases for blocking epoll.
1419
1520fn main() {
......@@ -21,7 +26,9 @@ fn main() {
2126 multiple_events_wake_multiple_threads();
2227}
2328
24// This test allows epoll_wait to block, then unblock without notification.
29// This test allows edge-triggered epoll_wait to block and then unblock
30// without notification because the timeout expired.
31// The level-triggered epoll_wait should not block.
2532fn test_epoll_block_without_notification() {
2633 // Create an epoll instance.
2734 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
......@@ -31,16 +38,24 @@ fn test_epoll_block_without_notification() {
3138 let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
3239
3340 // Register eventfd with epoll.
34 epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
41 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
3542
3643 // epoll_wait to clear notification.
37 check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT, data: fd }], 0);
38
39 // This epoll wait blocks, and timeout without notification.
40 check_epoll_wait::<1>(epfd, &[], 5);
44 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: fd }], -1);
45
46 if cfg!(edge_triggered) {
47 // This epoll wait blocks, and timeout without notification.
48 check_epoll_wait(epfd, &[], 5);
49 } else {
50 // In level-triggered mode we should receive the same events
51 // as before without timing out.
52 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: fd }], -1);
53 }
4154}
4255
43// This test triggers notification and unblocks the epoll_wait before timeout.
56// This test triggers notification and unblocks the edge-triggered epoll_wait
57// before the timeout exceeds.
58// The level-triggered epoll_wait should not block.
4459fn test_epoll_block_then_unblock() {
4560 // Create an epoll instance.
4661 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
......@@ -50,21 +65,33 @@ fn test_epoll_block_then_unblock() {
5065 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
5166
5267 // Register one side of the socketpair with epoll.
53 epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
68 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
5469
5570 // epoll_wait to clear notification.
56 check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT, data: fds[0] }], 0);
71 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: fds[0] }], -1);
5772
58 // epoll_wait before triggering notification so it will block then get unblocked before timeout.
5973 let thread1 = thread::spawn(move || {
6074 thread::yield_now();
75 // Due to deterministic concurrency, we'll only get here when the other thread blocks.
6176 write_all(fds[1], b"abcde").unwrap();
6277 });
63 check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLIN | libc::EPOLLOUT, data: fds[0] }], 10);
78
79 if cfg!(edge_triggered) {
80 // Edge-triggered epoll will block until the write succeeds and the buffer
81 // becomes readable. This is because we already read the writable edge
82 // before so at the time of calling `epoll_wait` there is no active readiness.
83 check_epoll_wait(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[0] }], 10);
84 } else {
85 // Level-triggered epoll won't wait for the write to succeed because
86 // _some_ readiness is already set (in this case the EPOLLOUT).
87 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: fds[0] }], -1);
88 }
89
6490 thread1.join().unwrap();
6591}
6692
67// This test triggers a notification after epoll_wait times out.
93// This test triggers a notification after epoll_wait times out in edge-triggered mode.
94// In level-triggered the epoll_wait should not time out.
6895fn test_notification_after_timeout() {
6996 // Create an epoll instance.
7097 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
......@@ -74,19 +101,26 @@ fn test_notification_after_timeout() {
74101 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
75102
76103 // Register one side of the socketpair with epoll.
77 epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
104 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
78105
79106 // epoll_wait to clear notification.
80 check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLOUT, data: fds[0] }], 0);
81
82 // epoll_wait timeouts without notification.
83 check_epoll_wait::<1>(epfd, &[], 10);
107 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: fds[0] }], -1);
108
109 if cfg!(edge_triggered) {
110 // Edge-triggered epoll wait times out without notification because
111 // we just processed the edge.
112 check_epoll_wait(epfd, &[], 10);
113 } else {
114 // Level-triggered epoll just returns the same events as before
115 // without blocking.
116 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: fds[0] }], -1);
117 }
84118
85119 // Trigger epoll notification after timeout.
86120 write_all(fds[1], b"abcde").unwrap();
87121
88122 // Check the result of the notification.
89 check_epoll_wait::<1>(epfd, &[Ev { events: libc::EPOLLIN | libc::EPOLLOUT, data: fds[0] }], 10);
123 check_epoll_wait(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[0] }], 10);
90124}
91125
92126// This test shows a data race before epoll had vector clocks added.
......@@ -99,7 +133,7 @@ fn test_epoll_race() {
99133 let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
100134
101135 // Register eventfd with the epoll instance.
102 epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLET).unwrap();
136 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLET_OR_ZERO).unwrap();
103137
104138 static mut VAL: u8 = 0;
105139 let thread1 = thread::spawn(move || {
......@@ -110,7 +144,7 @@ fn test_epoll_race() {
110144 });
111145 thread::yield_now();
112146 // epoll_wait for EPOLLIN.
113 check_epoll_wait::<8>(epfd, &[Ev { events: libc::EPOLLIN, data: fd }], -1);
147 check_epoll_wait(epfd, &[Ev { events: EPOLLIN, data: fd }], -1);
114148 // Read from the static mut variable.
115149 assert_eq!(unsafe { VAL }, 1);
116150 thread1.join().unwrap();
......@@ -131,18 +165,14 @@ fn wakeup_on_new_interest() {
131165
132166 // Block a thread on the epoll instance.
133167 let t = std::thread::spawn(move || {
134 check_epoll_wait::<8>(
135 epfd,
136 &[Ev { events: libc::EPOLLIN | libc::EPOLLOUT, data: fds[1] }],
137 -1,
138 );
168 check_epoll_wait(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[1] }], -1);
139169 });
140170 // Ensure the thread is blocked.
141171 std::thread::yield_now();
142172
143 // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP
144 epoll_ctl_add(epfd, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP)
145 .unwrap();
173 // Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLRDHUP (and EPOLLET if we're in the
174 // `edge_triggered` revision).
175 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET_OR_ZERO).unwrap();
146176
147177 // This should wake up the thread.
148178 t.join().unwrap();
......@@ -161,13 +191,12 @@ fn multiple_events_wake_multiple_threads() {
161191 let fd2 = errno_result(unsafe { libc::dup(fd1) }).unwrap();
162192
163193 // Register both with epoll.
164 epoll_ctl_add(epfd, fd1, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
165 epoll_ctl_add(epfd, fd2, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
194 epoll_ctl_add(epfd, fd1, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
195 epoll_ctl_add(epfd, fd2, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
166196
167197 // Consume the initial events.
168 let expected =
169 [Ev { events: libc::EPOLLOUT, data: fd1 }, Ev { events: libc::EPOLLOUT, data: fd2 }];
170 check_epoll_wait::<8>(epfd, &expected, -1);
198 let expected = [Ev { events: EPOLLOUT, data: fd1 }, Ev { events: EPOLLOUT, data: fd2 }];
199 check_epoll_wait(epfd, &expected, -1);
171200
172201 // Block two threads on the epoll, both wanting to get just one event.
173202 let t1 = thread::spawn(move || {
......@@ -191,6 +220,7 @@ fn multiple_events_wake_multiple_threads() {
191220 // Both threads should have been woken up so that both events can be consumed.
192221 let e1 = t1.join().unwrap();
193222 let e2 = t2.join().unwrap();
194 // Ensure that across the two threads we got both events.
223
224 // In both modes we should get both events across the two threads.
195225 assert!(expected == [e1, e2] || expected == [e2, e1]);
196226}
src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs+229-185
......@@ -1,12 +1,15 @@
11//@only-target: linux android illumos
2
3use std::convert::TryInto;
2//@revisions: edge_triggered level_triggered
43
54#[path = "../../utils/libc.rs"]
65mod libc_utils;
76use libc_utils::epoll::*;
87use libc_utils::*;
98
9/// When the `edge_triggered` revision is active, this is EPOLLET, otherwise
10/// it's zero which means we perform level-triggered epolls.
11const EPOLLET_OR_ZERO: libc::c_int = if cfg!(edge_triggered) { EPOLLET } else { 0 };
12
1013fn main() {
1114 test_epoll_socketpair();
1215 test_epoll_socketpair_both_sides();
......@@ -27,27 +30,13 @@ fn main() {
2730 test_ready_list_fetching_logic();
2831 test_epoll_ctl_epfd_equal_fd();
2932 test_epoll_ctl_notification();
33 test_epoll_mixed_modes();
34 test_epoll_registered_mode_switch();
3035 test_issue_3858();
3136 test_issue_4374();
3237 test_issue_4374_reads();
3338}
3439
35#[track_caller]
36fn check_epoll_wait<const N: usize>(epfd: i32, expected_notifications: &[(u32, u64)]) {
37 let epoll_event = libc::epoll_event { events: 0, u64: 0 };
38 let mut array: [libc::epoll_event; N] = [epoll_event; N];
39 let maxsize = N;
40 let array_ptr = array.as_mut_ptr();
41 let res = unsafe { libc::epoll_wait(epfd, array_ptr, maxsize.try_into().unwrap(), 0) };
42 if res < 0 {
43 panic!("epoll_wait failed: {}", std::io::Error::last_os_error());
44 }
45 let got_notifications =
46 unsafe { std::slice::from_raw_parts(array_ptr, res.try_into().unwrap()) };
47 let got_notifications = got_notifications.iter().map(|e| (e.events, e.u64)).collect::<Vec<_>>();
48 assert_eq!(got_notifications, expected_notifications, "got wrong notifications");
49}
50
5140fn test_epoll_socketpair() {
5241 // Create an epoll instance.
5342 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
......@@ -59,14 +48,22 @@ fn test_epoll_socketpair() {
5948 // Write to fds[0]
6049 write_all(fds[0], b"abcde").unwrap();
6150
62 // Register fds[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP
63 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLET | EPOLLRDHUP).unwrap();
51 // Register fds[1] with EPOLLIN|EPOLLOUT|EPOLLRDHUP (and EPOLLET if we're
52 // in the `edge_triggered` revision).
53 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET_OR_ZERO).unwrap();
6454
6555 // Check result from epoll_wait.
66 check_epoll_wait_noblock::<8>(epfd, &[Ev { data: fds[1], events: EPOLLIN | EPOLLOUT }]);
67
68 // Check that this is indeed using "ET" (edge-trigger) semantics: a second epoll should return nothing.
69 check_epoll_wait_noblock::<8>(epfd, &[]);
56 check_epoll_wait_noblock(epfd, &[Ev { data: fds[1], events: EPOLLIN | EPOLLOUT }]);
57
58 if cfg!(edge_triggered) {
59 // Check that this is indeed using "ET" (edge-trigger) semantics: a second wait
60 // should return nothing.
61 check_epoll_wait_noblock(epfd, &[]);
62 } else {
63 // Check that this is indeed using "LT" (level-trigger) semantics: a second wait
64 // should return the same readiness.
65 check_epoll_wait_noblock(epfd, &[Ev { data: fds[1], events: EPOLLIN | EPOLLOUT }]);
66 }
7067
7168 // Write some more to fds[0].
7269 write_all(fds[0], b"abcde").unwrap();
......@@ -74,14 +71,14 @@ fn test_epoll_socketpair() {
7471 // This did not change the readiness of fds[1], so we should get no event.
7572 // However, Linux seems to always deliver spurious events to the peer on each write,
7673 // so we match that.
77 check_epoll_wait_noblock::<8>(epfd, &[Ev { data: fds[1], events: EPOLLIN | EPOLLOUT }]);
74 check_epoll_wait_noblock(epfd, &[Ev { data: fds[1], events: EPOLLIN | EPOLLOUT }]);
7875
7976 // Close the peer socketpair.
8077 errno_check(unsafe { libc::close(fds[0]) });
8178
8279 // Check result from epoll_wait. We expect to get a read, write, HUP notification from the close
8380 // since closing an FD always unblocks reads and writes on its peer.
84 check_epoll_wait_noblock::<8>(
81 check_epoll_wait_noblock(
8582 epfd,
8683 &[Ev { data: fds[1], events: EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLRDHUP }],
8784 );
......@@ -98,17 +95,19 @@ fn test_epoll_ctl_mod() {
9895 let mut fds = [-1, -1];
9996 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
10097
101 // Register fds[1] with EPOLLIN|EPOLLET, and data of "0".
102 epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], Ev { events: EPOLLIN | EPOLLET, data: 0 }).unwrap();
98 // Register fds[1] with EPOLLIN (and EPOLLET if we're in the `edge_triggered` revision), and data of "0".
99 epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], Ev { events: EPOLLIN | EPOLLET_OR_ZERO, data: 0 })
100 .unwrap();
103101
104102 // Check result from epoll_wait. No notification would be returned.
105 check_epoll_wait_noblock::<8>(epfd, &[]);
103 check_epoll_wait_noblock(epfd, &[]);
106104
107105 // Use EPOLL_CTL_MOD to change to EPOLLOUT flag and data.
108 epoll_ctl(epfd, EPOLL_CTL_MOD, fds[1], Ev { events: EPOLLOUT | EPOLLET, data: 1 }).unwrap();
106 epoll_ctl(epfd, EPOLL_CTL_MOD, fds[1], Ev { events: EPOLLOUT | EPOLLET_OR_ZERO, data: 1 })
107 .unwrap();
109108
110109 // Check result from epoll_wait. EPOLLOUT notification and new data is expected.
111 check_epoll_wait_noblock::<8>(epfd, &[Ev { events: EPOLLOUT, data: 1 }]);
110 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: 1 }]);
112111
113112 // Write to fds[1] and read from fds[0] to make the notification ready again
114113 // (relying on there always being an event when the buffer gets emptied).
......@@ -116,16 +115,18 @@ fn test_epoll_ctl_mod() {
116115 read_exact_array::<3>(fds[0]).unwrap();
117116
118117 // Now that the event is already ready, change the "data" value.
119 epoll_ctl(epfd, EPOLL_CTL_MOD, fds[1], Ev { events: EPOLLOUT | EPOLLET, data: 2 }).unwrap();
118 epoll_ctl(epfd, EPOLL_CTL_MOD, fds[1], Ev { events: EPOLLOUT | EPOLLET_OR_ZERO, data: 2 })
119 .unwrap();
120120
121121 // Receive event, with latest data value.
122 check_epoll_wait_noblock::<8>(epfd, &[Ev { events: EPOLLOUT, data: 2 }]);
122 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: 2 }]);
123123
124124 // Do another update that changes nothing.
125 epoll_ctl(epfd, EPOLL_CTL_MOD, fds[1], Ev { events: EPOLLOUT | EPOLLET, data: 2 }).unwrap();
125 epoll_ctl(epfd, EPOLL_CTL_MOD, fds[1], Ev { events: EPOLLOUT | EPOLLET_OR_ZERO, data: 2 })
126 .unwrap();
126127
127128 // This re-triggers the event, even if it's the same flags as before.
128 check_epoll_wait_noblock::<8>(epfd, &[Ev { events: EPOLLOUT, data: 2 }]);
129 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: 2 }]);
129130}
130131
131132fn test_epoll_ctl_del() {
......@@ -139,18 +140,18 @@ fn test_epoll_ctl_del() {
139140 // Write to fds[0]
140141 libc_utils::write_all(fds[0], b"abcde").unwrap();
141142
142 // Register fds[1] with EPOLLIN|EPOLLOUT|EPOLLET
143 // Register fds[1] with EPOLLIN|EPOLLOUT (and EPOLLET if we're in the `edge_triggered` revision).
143144 let mut ev = libc::epoll_event {
144 events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as u32,
145 events: (EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO) as u32,
145146 u64: u64::try_from(fds[1]).unwrap(),
146147 };
147148 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
148149 assert_eq!(res, 0);
149150
150151 // Test EPOLL_CTL_DEL.
151 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_DEL, fds[1], &mut ev) };
152 let res = unsafe { libc::epoll_ctl(epfd, EPOLL_CTL_DEL, fds[1], &mut ev) };
152153 assert_eq!(res, 0);
153 check_epoll_wait::<8>(epfd, &[]);
154 check_epoll_wait_noblock(epfd, &[]);
154155}
155156
156157// This test is for one fd registered under two different epoll instance.
......@@ -168,15 +169,14 @@ fn test_two_epoll_instance() {
168169 // Write to the socketpair.
169170 libc_utils::write_all(fds[0], b"abcde").unwrap();
170171
171 // Register one side of the socketpair with EPOLLIN | EPOLLOUT | EPOLLET.
172 epoll_ctl_add(epfd1, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
173 epoll_ctl_add(epfd2, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
172 // Register one side of the socketpair with EPOLLIN | EPOLLOUT (and EPOLLET
173 // if we're in the `edge_triggered` revision).
174 epoll_ctl_add(epfd1, fds[1], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
175 epoll_ctl_add(epfd2, fds[1], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
174176
175177 // Notification should be received from both instance of epoll.
176 let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
177 let expected_value = u64::try_from(fds[1]).unwrap();
178 check_epoll_wait::<8>(epfd1, &[(expected_event, expected_value)]);
179 check_epoll_wait::<8>(epfd2, &[(expected_event, expected_value)]);
178 check_epoll_wait_noblock(epfd1, &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[1] }]);
179 check_epoll_wait_noblock(epfd2, &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[1] }]);
180180}
181181
182182// This test is for two same file description registered under the same epoll instance through dup.
......@@ -194,24 +194,19 @@ fn test_two_same_fd_in_same_epoll_instance() {
194194 assert_ne!(newfd, -1);
195195
196196 // Register both fd to the same epoll instance.
197 let mut ev = libc::epoll_event {
198 events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(),
199 u64: 5u64,
200 };
201 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
202 assert_eq!(res, 0);
203 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, newfd, &mut ev) };
204 assert_eq!(res, 0);
197 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
198 epoll_ctl_add(epfd, newfd, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
205199
206200 // Write to the socketpair.
207201 libc_utils::write_all(fds[0], b"abcde").unwrap();
208202
209203 // Two notification should be received.
210 let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
211 let expected_value = 5u64;
212 check_epoll_wait::<8>(
204 check_epoll_wait_noblock(
213205 epfd,
214 &[(expected_event, expected_value), (expected_event, expected_value)],
206 &[
207 Ev { events: EPOLLIN | EPOLLOUT, data: fds[1] },
208 Ev { events: EPOLLIN | EPOLLOUT, data: newfd },
209 ],
215210 );
216211}
217212
......@@ -226,20 +221,19 @@ fn test_epoll_eventfd() {
226221 // Create an epoll instance.
227222 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
228223
229 // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
230 epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
224 // Register eventfd with EPOLLIN | EPOLLOUT (and EPOLLET if we're in the `edge_triggered`
225 // revision).
226 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
231227
232228 // Check result from epoll_wait.
233 let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
234 let expected_value = u64::try_from(fd).unwrap();
235 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
229 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fd }]);
236230
237231 // Write 0 to the eventfd.
238232 libc_utils::write_all(fd, &0_u64.to_ne_bytes()).unwrap();
239233
240234 // This does not change the status, so we should get no event.
241235 // However, Linux performs a spurious wakeup.
242 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
236 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fd }]);
243237
244238 // Read from the eventfd.
245239 libc_utils::read_exact_array::<8>(fd).unwrap();
......@@ -247,15 +241,13 @@ fn test_epoll_eventfd() {
247241 // This consumes the event, so the read status is gone. However, deactivation
248242 // does not trigger an event.
249243 // Still, we see a spurious wakeup.
250 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
251 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
244 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fd }]);
252245
253246 // Write the maximum possible value.
254247 libc_utils::write_all(fd, &(u64::MAX - 1).to_ne_bytes()).unwrap();
255248
256249 // This reactivates reads, therefore triggering an event. Writing is no longer possible.
257 let expected_event = u32::try_from(libc::EPOLLIN).unwrap();
258 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
250 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLIN, data: fd }]);
259251}
260252
261253// When read/write happened on one side of the socketpair, only the other side will be notified.
......@@ -268,8 +260,8 @@ fn test_epoll_socketpair_both_sides() {
268260 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
269261
270262 // Register both fd to the same epoll instance.
271 epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
272 epoll_ctl_add(epfd, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
263 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
264 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
273265
274266 // Write to fds[1].
275267 // (We do the write after the register here, unlike in `test_epoll_socketpair`, to ensure
......@@ -277,23 +269,28 @@ fn test_epoll_socketpair_both_sides() {
277269 libc_utils::write_all(fds[1], b"abcde").unwrap();
278270
279271 // Two notification should be received.
280 let expected_event0 = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
281 let expected_value0 = fds[0] as u64;
282 let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
283 let expected_value1 = fds[1] as u64;
284 check_epoll_wait::<8>(
272 check_epoll_wait_noblock(
285273 epfd,
286 &[(expected_event0, expected_value0), (expected_event1, expected_value1)],
274 &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[0] }, Ev { events: EPOLLOUT, data: fds[1] }],
287275 );
288276
289277 // Read from fds[0].
290278 let buf = libc_utils::read_exact_array::<5>(fds[0]).unwrap();
291279 assert_eq!(buf, *b"abcde");
292280
293 // The state of fds[1] does not change (was writable, is writable).
294 // However, we force a spurious wakeup as the read buffer just got emptied.
295 // fds[0] lost its readability, but becoming less active is not considered an "edge".
296 check_epoll_wait::<8>(epfd, &[(expected_event1, expected_value1)]);
281 if cfg!(edge_triggered) {
282 // The state of fds[1] does not change (was writable, is writable).
283 // However, we force a spurious wakeup as the read buffer just got emptied.
284 // fds[0] lost its readability, but becoming less active is not considered an "edge".
285 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fds[1] }])
286 } else {
287 // With level-triggered epoll, only the readable readiness for fds[0] should
288 // no longer be reported. The rest stays the same.
289 check_epoll_wait_noblock(
290 epfd,
291 &[Ev { events: EPOLLOUT, data: fds[0] }, Ev { events: EPOLLOUT, data: fds[1] }],
292 );
293 }
297294}
298295
299296// When file description is fully closed, epoll_wait should not provide any notification for
......@@ -306,8 +303,8 @@ fn test_closed_fd() {
306303 let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
307304 let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
308305
309 // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
310 epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
306 // Register eventfd with EPOLLIN | EPOLLOUT (and EPOLLET if we're in the `edge_triggered` revision).
307 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
311308
312309 // Write to the eventfd instance.
313310 libc_utils::write_all(fd, &1_u64.to_ne_bytes()).unwrap();
......@@ -316,7 +313,7 @@ fn test_closed_fd() {
316313 errno_check(unsafe { libc::close(fd) });
317314
318315 // No notification should be provided because the file description is closed.
319 check_epoll_wait::<8>(epfd, &[]);
316 check_epoll_wait_noblock(epfd, &[]);
320317}
321318
322319// When a certain file descriptor registered with epoll is closed, but the underlying file description
......@@ -336,16 +333,14 @@ fn test_not_fully_closed_fd() {
336333 // Dup the fd.
337334 let newfd = errno_result(unsafe { libc::dup(fd) }).unwrap();
338335
339 // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
340 epoll_ctl_add(epfd, fd, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
336 // Register eventfd with EPOLLIN | EPOLLOUT (and EPOLLET if we're in the `edge_triggered` revision).
337 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
341338
342339 // Close the original fd that being used to register with epoll.
343340 errno_check(unsafe { libc::close(fd) });
344341
345342 // Notification should still be provided because the file description is not closed.
346 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
347 let expected_value = fd as u64;
348 check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)]);
343 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fd }]);
349344
350345 // Write to the eventfd instance to produce notification.
351346 libc_utils::write_all(newfd, &1_u64.to_ne_bytes()).unwrap();
......@@ -354,7 +349,7 @@ fn test_not_fully_closed_fd() {
354349 errno_check(unsafe { libc::close(newfd) });
355350
356351 // No notification should be provided.
357 check_epoll_wait::<1>(epfd, &[]);
352 check_epoll_wait_noblock(epfd, &[]);
358353}
359354
360355// Each time a notification is provided, it should reflect the file description's readiness
......@@ -370,13 +365,8 @@ fn test_event_overwrite() {
370365 // Create an epoll instance.
371366 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
372367
373 // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
374 let mut ev = libc::epoll_event {
375 events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(),
376 u64: u64::try_from(fd).unwrap(),
377 };
378 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
379 assert_eq!(res, 0);
368 // Register eventfd with EPOLLIN | EPOLLOUT (and EPOLLET if we're in the `edge_triggered` revision).
369 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
380370
381371 // Read from the eventfd instance.
382372 let mut buf: [u8; 8] = [0; 8];
......@@ -384,9 +374,7 @@ fn test_event_overwrite() {
384374 assert_eq!(res, 8);
385375
386376 // Check result from epoll_wait.
387 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
388 let expected_value = u64::try_from(fd).unwrap();
389 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
377 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fd }]);
390378}
391379
392380// An epoll notification will be provided for every succesful read in a socketpair.
......@@ -400,53 +388,58 @@ fn test_socketpair_read() {
400388 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
401389
402390 // Register both fd to the same epoll instance.
403 let mut ev = libc::epoll_event {
404 events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(),
405 u64: fds[0] as u64,
406 };
407 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) };
408 assert_eq!(res, 0);
409 let mut ev = libc::epoll_event {
410 events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(),
411 u64: fds[1] as u64,
412 };
413 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
414 assert_eq!(res, 0);
391 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
392 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
415393
416394 // Write a bunch of data bytes to fds[1].
417395 let data = [42u8; 1024];
418396 libc_utils::write_all(fds[1], &data).unwrap();
419397
420398 // Two notification should be received.
421 let expected_event0 = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
422 let expected_value0 = fds[0] as u64;
423 let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
424 let expected_value1 = fds[1] as u64;
425 check_epoll_wait::<8>(
399 check_epoll_wait_noblock(
426400 epfd,
427 &[(expected_event0, expected_value0), (expected_event1, expected_value1)],
401 &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[0] }, Ev { events: EPOLLOUT, data: fds[1] }],
428402 );
429403
430404 // Read some of the data from fds[0].
431405 let mut buf = [0; 512];
432406 libc_utils::read_exact(fds[0], &mut buf).unwrap();
433
434 // fds[1] did not change, it is still writable, so we get no event.
435 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
436 let expected_value = fds[1] as u64;
437 check_epoll_wait::<8>(epfd, &[]);
407 if cfg!(edge_triggered) {
408 // fds[1] did not change, it is still writable, so we get no event
409 // in edge-triggered mode.
410 check_epoll_wait_noblock(epfd, &[]);
411 } else {
412 // In level-triggered mode we expect the same events as before because
413 // we didn't read everything in the buffer.
414 check_epoll_wait_noblock(
415 epfd,
416 &[
417 Ev { events: EPOLLIN | EPOLLOUT, data: fds[0] },
418 Ev { events: EPOLLOUT, data: fds[1] },
419 ],
420 );
421 }
438422
439423 // Read until the buffer is empty.
440424 let rest = data.len() - buf.len();
441425 libc_utils::read_exact(fds[0], &mut buf[..rest]).unwrap();
442426
443 // Now we get a notification that fds[1] can be written. This is spurious since it
444 // could already be written before, but Linux seems to always emit a notification for
445 // the writer when a read empties the buffer.
446 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
427 if cfg!(edge_triggered) {
428 // Now we get a notification that fds[1] can be written. This is spurious since it
429 // could already be written before, but Linux seems to always emit a notification for
430 // the writer when a read empties the buffer.
431 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fds[1] }]);
432 } else {
433 // In level-triggered mode we expect the same events as before just without
434 // the readable readiness of fds[0] because we now read everything.
435 check_epoll_wait_noblock(
436 epfd,
437 &[Ev { events: EPOLLOUT, data: fds[0] }, Ev { events: EPOLLOUT, data: fds[1] }],
438 );
439 }
447440}
448441
449// This is to test whether flag that we don't register won't trigger notification.
442// This is to test whether a flag that we don't register won't trigger notification.
450443fn test_no_notification_for_unregister_flag() {
451444 // Create an epoll instance.
452445 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
......@@ -455,22 +448,15 @@ fn test_no_notification_for_unregister_flag() {
455448 let mut fds = [-1, -1];
456449 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
457450
458 // Register fds[0] with EPOLLOUT|EPOLLET.
459 let mut ev = libc::epoll_event {
460 events: (libc::EPOLLOUT | libc::EPOLLET).cast_unsigned(),
461 u64: u64::try_from(fds[0]).unwrap(),
462 };
463 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) };
464 assert_eq!(res, 0);
451 // Register fds[0] with EPOLLOUT (and EPOLLET when we're in the `edge_triggered` revision).
452 epoll_ctl_add(epfd, fds[0], EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
465453
466454 // Write to fds[1].
467455 libc_utils::write_all(fds[1], b"abcde").unwrap();
468456
469457 // Check result from epoll_wait. Since we didn't register EPOLLIN flag, the notification won't
470458 // contain EPOLLIN even though fds[0] is now readable.
471 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
472 let expected_value = u64::try_from(fds[0]).unwrap();
473 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
459 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fds[0] }]);
474460}
475461
476462fn test_epoll_wait_maxevent_zero() {
......@@ -500,17 +486,15 @@ fn test_socketpair_epollerr() {
500486 // EPOLLERR will be triggered if we close peer fd that still has data in its read buffer.
501487 errno_check(unsafe { libc::close(fds[1]) });
502488
503 // Register fds[1] with EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP
504 epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP)
505 .unwrap();
489 // Register fds[1] with EPOLLIN|EPOLLOUT|EPOLLRDHUP (and EPOLLET when we're in the
490 // `edge_triggered` revision).
491 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET_OR_ZERO).unwrap();
506492
507493 // Check result from epoll_wait.
508 let expected_event = u32::try_from(
509 libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP | libc::EPOLLRDHUP | libc::EPOLLERR,
510 )
511 .unwrap();
512 let expected_value = u64::try_from(fds[0]).unwrap();
513 check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
494 check_epoll_wait_noblock(
495 epfd,
496 &[Ev { events: EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLRDHUP | EPOLLERR, data: fds[0] }],
497 );
514498}
515499
516500// This is a test for https://github.com/rust-lang/miri/issues/3812,
......@@ -524,18 +508,24 @@ fn test_epoll_lost_events() {
524508 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
525509
526510 // Register both fd to the same epoll instance.
527 epoll_ctl_add(epfd, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
528 epoll_ctl_add(epfd, fds[1], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
511 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
512 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
529513
530514 // Two notification should be received. But we only provide buffer for one event.
531 let expected_event0 = u32::try_from(libc::EPOLLOUT).unwrap();
532 let expected_value0 = fds[0] as u64;
533 check_epoll_wait::<1>(epfd, &[(expected_event0, expected_value0)]);
534
535 // Previous event should be returned for the second epoll_wait.
536 let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
537 let expected_value1 = fds[1] as u64;
538 check_epoll_wait::<1>(epfd, &[(expected_event1, expected_value1)]);
515 check_epoll_wait_partial(epfd, &[Ev { events: EPOLLOUT, data: fds[0] }], 1, 0);
516
517 if cfg!(edge_triggered) {
518 // Previous event should be returned for the second epoll_wait but because we're
519 // edge-triggered the first event should no longer be returned.
520 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fds[1] }]);
521 } else {
522 // Both events should be returned in level-triggered mode when
523 // we provide a big enough buffer.
524 check_epoll_wait_noblock(
525 epfd,
526 &[Ev { events: EPOLLOUT, data: fds[1] }, Ev { events: EPOLLOUT, data: fds[0] }],
527 );
528 }
539529}
540530
541531// This is testing if closing an fd that is already in ready list will cause an empty entry in
......@@ -551,16 +541,14 @@ fn test_ready_list_fetching_logic() {
551541 let fd1 = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
552542
553543 // Register both fd to the same epoll instance. At this point, both of them are on the ready list.
554 epoll_ctl_add(epfd, fd0, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
555 epoll_ctl_add(epfd, fd1, libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
544 epoll_ctl_add(epfd, fd0, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
545 epoll_ctl_add(epfd, fd1, EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
556546
557547 // Close fd0 so the first entry in the ready list will be empty.
558548 errno_check(unsafe { libc::close(fd0) });
559549
560550 // Notification for fd1 should be returned.
561 let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
562 let expected_value1 = fd1 as u64;
563 check_epoll_wait::<1>(epfd, &[(expected_event1, expected_value1)]);
551 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fd1 }]);
564552}
565553
566554// In epoll_ctl, if the value of epfd equals to fd, EFAULT should be returned.
......@@ -570,7 +558,7 @@ fn test_epoll_ctl_epfd_equal_fd() {
570558 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
571559
572560 let array_ptr = std::ptr::without_provenance_mut::<libc::epoll_event>(0x100);
573 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, epfd, array_ptr) };
561 let res = unsafe { libc::epoll_ctl(epfd, EPOLL_CTL_ADD, epfd, array_ptr) };
574562 let e = std::io::Error::last_os_error();
575563 assert_eq!(e.raw_os_error(), Some(libc::EFAULT));
576564 assert_eq!(res, -1);
......@@ -578,7 +566,7 @@ fn test_epoll_ctl_epfd_equal_fd() {
578566
579567// We previously used check_and_update_readiness the moment a file description is registered in an
580568// epoll instance. But this has an unfortunate side effect of returning notification to another
581// epfd that shouldn't receive notification.
569// epfd that shouldn't receive a notification in edge-triggered mode.
582570fn test_epoll_ctl_notification() {
583571 // Create an epoll instance.
584572 let epfd0 = unsafe { libc::epoll_create1(0) };
......@@ -589,24 +577,87 @@ fn test_epoll_ctl_notification() {
589577 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
590578
591579 // Register one side of the socketpair with epoll.
592 epoll_ctl_add(epfd0, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
580 epoll_ctl_add(epfd0, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
593581
594582 // epoll_wait to clear notification for epfd0.
595 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
596 let expected_value = fds[0] as u64;
597 check_epoll_wait::<1>(epfd0, &[(expected_event, expected_value)]);
583 check_epoll_wait_noblock(epfd0, &[Ev { events: EPOLLOUT, data: fds[0] }]);
598584
599585 // Create another epoll instance.
600586 let epfd1 = unsafe { libc::epoll_create1(0) };
601587 assert_ne!(epfd1, -1);
602588
603589 // Register the same file description for epfd1.
604 epoll_ctl_add(epfd1, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
605 check_epoll_wait::<1>(epfd1, &[(expected_event, expected_value)]);
590 epoll_ctl_add(epfd1, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
591 check_epoll_wait_noblock(epfd1, &[Ev { events: EPOLLOUT, data: fds[0] }]);
592
593 if cfg!(edge_triggered) {
594 // Previously this epoll_wait will receive a notification, but we shouldn't return notification
595 // for this epfd, because there is no I/O event between the two epoll_wait.
596 check_epoll_wait_noblock(epfd0, &[]);
597 } else {
598 // We should still get the same events in level-triggered mode.
599 check_epoll_wait_noblock(epfd0, &[Ev { events: EPOLLOUT, data: fds[0] }]);
600 }
601}
602
603/// Test storing a level-triggered and an edge-triggered file descriptor
604/// in the same epoll instance and calling `epoll_wait` multiple times.
605fn test_epoll_mixed_modes() {
606 // Create an epoll instance.
607 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
608
609 // Create a socketpair instance.
610 let mut fds = [-1, -1];
611 errno_check(unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) });
612
613 // Register both fd to the same epoll instance.
614 // `fds[0]` is added in edge-triggered mode whilst `fds[1]` is added in level-triggered mode.
615 epoll_ctl_add(epfd, fds[0], EPOLLIN | EPOLLOUT | EPOLLET).unwrap();
616 epoll_ctl_add(epfd, fds[1], EPOLLIN | EPOLLOUT | 0).unwrap();
617
618 // Write to `fds[1]`.
619 libc_utils::write_all(fds[1], b"abcde").unwrap();
620
621 // Two events should be received.
622 check_epoll_wait_noblock(
623 epfd,
624 &[Ev { events: EPOLLIN | EPOLLOUT, data: fds[0] }, Ev { events: EPOLLOUT, data: fds[1] }],
625 );
626
627 // If we call epoll_wait again immediately, only the level-triggered interests should be received again.
628 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLOUT, data: fds[1] }]);
629}
630
631/// Test first registering a file descriptor in edge-triggered mode,
632/// then consuming it's readiness and then changing it to level-triggered
633/// mode.
634fn test_epoll_registered_mode_switch() {
635 // Create an eventfd instance.
636 let flags = libc::EFD_NONBLOCK | libc::EFD_CLOEXEC;
637 let fd = errno_result(unsafe { libc::eventfd(0, flags) }).unwrap();
638
639 // Write 1 to the eventfd instance.
640 libc_utils::write_all(fd, &1_u64.to_ne_bytes()).unwrap();
641
642 // Create an epoll instance.
643 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
644
645 // Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET.
646 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLOUT | EPOLLET).unwrap();
647
648 // Check result from `epoll_wait`.
649 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fd }]);
650
651 // Because `fd` is registered in edge-triggered mode, the next `epoll_wait` shouldn't
652 // return any events.
653 check_epoll_wait_noblock(epfd, &[]);
606654
607 // Previously this epoll_wait will receive a notification, but we shouldn't return notification
608 // for this epfd, because there is no I/O event between the two epoll_wait.
609 check_epoll_wait::<1>(epfd0, &[]);
655 // Update the registration for `fd` to switch to level-triggered mode.
656 epoll_ctl(epfd, EPOLL_CTL_MOD, fd, Ev { events: EPOLLIN | EPOLLOUT, data: fd }).unwrap();
657
658 // Because `fd` is now registered in level-triggered mode, we should see
659 // the same events as from the first `epoll_wait`.
660 check_epoll_wait_noblock(epfd, &[Ev { events: EPOLLIN | EPOLLOUT, data: fd }]);
610661}
611662
612663// Test for ICE caused by weak epoll interest upgrade succeed, but the attempt to retrieve
......@@ -623,13 +674,8 @@ fn test_issue_3858() {
623674 // Create an epoll instance.
624675 let epfd = errno_result(unsafe { libc::epoll_create1(0) }).unwrap();
625676
626 // Register eventfd with EPOLLIN | EPOLLET.
627 let mut ev = libc::epoll_event {
628 events: (libc::EPOLLIN | libc::EPOLLET).cast_unsigned(),
629 u64: u64::try_from(fd).unwrap(),
630 };
631 let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
632 assert_eq!(res, 0);
677 // Register eventfd with EPOLLIN (and EPOLLET if we're in the `edge_triggered` revision).
678 epoll_ctl_add(epfd, fd, EPOLLIN | EPOLLET_OR_ZERO).unwrap();
633679
634680 // Dup the epoll instance.
635681 let newfd = unsafe { libc::dup(epfd) };
......@@ -655,7 +701,7 @@ fn test_issue_4374() {
655701 assert_eq!(unsafe { libc::fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK) }, 0);
656702
657703 // Register fds[0] with epoll while it is writable (but not readable).
658 epoll_ctl_add(epfd0, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
704 epoll_ctl_add(epfd0, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
659705
660706 // Fill up fds[0] so that it is not writable any more.
661707 let zeros = [0u8; 512];
......@@ -668,7 +714,7 @@ fn test_issue_4374() {
668714 }
669715
670716 // This should have canceled the previous readiness, so now we get nothing.
671 check_epoll_wait::<1>(epfd0, &[]);
717 check_epoll_wait_noblock(epfd0, &[]);
672718}
673719
674720/// Same as above, but for becoming un-readable.
......@@ -687,13 +733,11 @@ fn test_issue_4374_reads() {
687733 libc_utils::write_all(fds[1], b"abcde").unwrap();
688734
689735 // Register fds[0] with epoll while it is readable.
690 epoll_ctl_add(epfd0, fds[0], libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET).unwrap();
736 epoll_ctl_add(epfd0, fds[0], EPOLLIN | EPOLLOUT | EPOLLET_OR_ZERO).unwrap();
691737
692738 // Read fds[0] so it is no longer readable.
693739 libc_utils::read_exact_array::<5>(fds[0]).unwrap();
694740
695741 // We should now still see a notification, but only about it being writable.
696 let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
697 let expected_value = fds[0] as u64;
698 check_epoll_wait::<1>(epfd0, &[(expected_event, expected_value)]);
742 check_epoll_wait_noblock(epfd0, &[Ev { events: EPOLLOUT, data: fds[0] }]);
699743}
src/tools/miri/tests/pass-dep/libc/libc-fs-flock.rs+40-6
......@@ -2,6 +2,10 @@
22//@ignore-target: solaris # Does not have flock
33//@compile-flags: -Zmiri-disable-isolation
44
5//@revisions: windows_host unix_host
6//@[unix_host] ignore-host: windows
7//@[windows_host] only-host: windows
8
59use std::fs::File;
610use std::os::fd::AsRawFd;
711
......@@ -17,12 +21,12 @@ fn main() {
1721
1822 let files: Vec<File> = (0..3).map(|_| File::open(&path).unwrap()).collect();
1923
20 // Test that we can apply many shared locks
24 // Test that we can apply many shared locks.
2125 for file in files.iter() {
2226 errno_check(unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_SH) });
2327 }
2428
25 // Test that shared lock prevents exclusive lock
29 // Test that shared lock prevents exclusive lock.
2630 {
2731 let fd = files[0].as_raw_fd();
2832 let err =
......@@ -30,18 +34,18 @@ fn main() {
3034 assert_eq!(err.raw_os_error().unwrap(), libc::EWOULDBLOCK);
3135 }
3236
33 // Unlock shared lock
37 // Unlock shared lock.
3438 for file in files.iter() {
3539 errno_check(unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_UN) });
3640 }
3741
38 // Take exclusive lock
42 // Take exclusive lock.
3943 {
4044 let fd = files[0].as_raw_fd();
4145 errno_check(unsafe { libc::flock(fd, libc::LOCK_EX) });
4246 }
4347
44 // Test that shared lock prevents exclusive and shared locks
48 // Test that exclusive lock prevents exclusive and shared locks.
4549 {
4650 let fd = files[1].as_raw_fd();
4751 let err =
......@@ -54,9 +58,39 @@ fn main() {
5458 assert_eq!(err.raw_os_error().unwrap(), libc::EWOULDBLOCK);
5559 }
5660
57 // Unlock exclusive lock
61 // Unlock exclusive lock.
5862 {
5963 let fd = files[0].as_raw_fd();
6064 errno_check(unsafe { libc::flock(fd, libc::LOCK_UN) });
65 // Redundant unlock also works.
66 // FIXME(#miri/5074): except on Windows hosts...
67 if !cfg!(windows_host) {
68 errno_check(unsafe { libc::flock(fd, libc::LOCK_UN) });
69 }
70 }
71
72 // Test behavior when we acquire multiple locks on the same FD.
73 // FIXME(#miri/5074): this does not behave correctly on Windows hosts.
74 if !cfg!(windows_host) {
75 let fd1 = files[1].as_raw_fd();
76 let fd2 = files[2].as_raw_fd();
77
78 errno_check(unsafe { libc::flock(fd1, libc::LOCK_EX | libc::LOCK_NB) });
79 // This converts the exclusive lock to a shared lock.
80 errno_check(unsafe { libc::flock(fd1, libc::LOCK_SH | libc::LOCK_NB) });
81 // Now the other fd can have the shared lock as well.
82 errno_check(unsafe { libc::flock(fd2, libc::LOCK_SH | libc::LOCK_NB) });
83
84 // Reset.
85 errno_check(unsafe { libc::flock(fd1, libc::LOCK_UN) });
86 errno_check(unsafe { libc::flock(fd2, libc::LOCK_UN) });
87
88 // Getting first a shared lock and then upgrading to exclusive should also work.
89 errno_check(unsafe { libc::flock(fd1, libc::LOCK_SH | libc::LOCK_NB) });
90 errno_check(unsafe { libc::flock(fd1, libc::LOCK_EX | libc::LOCK_NB) });
91 // This is truly exclusive: fd2 is locked out.
92 let err =
93 errno_result(unsafe { libc::flock(fd2, libc::LOCK_SH | libc::LOCK_NB) }).unwrap_err();
94 assert_eq!(err.raw_os_error().unwrap(), libc::EWOULDBLOCK);
6195 }
6296}
src/tools/miri/tests/pass-dep/libc/libc-fs.rs+62-6
......@@ -2,7 +2,7 @@
22//@compile-flags: -Zmiri-disable-isolation
33
44use std::ffi::{CStr, CString, OsString};
5use std::fs::{File, canonicalize, create_dir, remove_dir, remove_file};
5use std::fs::{self, File, canonicalize, create_dir, remove_dir, remove_file};
66use std::io::{Error, ErrorKind, Write};
77use std::os::unix::ffi::OsStrExt;
88use std::os::unix::io::AsRawFd;
......@@ -28,6 +28,7 @@ fn main() {
2828 test_file_open_unix_allow_two_args();
2929 test_file_open_unix_needs_three_args();
3030 test_file_open_unix_extra_third_arg();
31 test_file_open_dir();
3132 #[cfg(target_os = "linux")]
3233 test_o_tmpfile_flag();
3334 test_posix_mkstemp();
......@@ -68,11 +69,12 @@ fn main() {
6869 #[cfg(not(target_os = "solaris"))]
6970 test_pwritev();
7071 test_pwrite();
72 test_linkat();
7173}
7274
7375#[cfg(target_os = "linux")]
7476#[track_caller]
75fn assert_statx_matches_metadata(stx: &libc::statx, meta: &std::fs::Metadata, expected_size: u64) {
77fn assert_statx_matches_metadata(stx: &libc::statx, meta: &fs::Metadata, expected_size: u64) {
7678 use std::os::unix::fs::MetadataExt;
7779 let mask = stx.stx_mask;
7880
......@@ -152,7 +154,7 @@ fn test_statx_on_file_path() {
152154 assert_eq!(ret, 0, "statx failed: {}", std::io::Error::last_os_error());
153155
154156 let stx = stx.assume_init();
155 let meta = std::fs::metadata(&path).unwrap();
157 let meta = fs::metadata(&path).unwrap();
156158 assert_statx_matches_metadata(&stx, &meta, bytes.len() as u64);
157159 }
158160
......@@ -211,21 +213,46 @@ fn test_file_open_unix_allow_two_args() {
211213 let path = utils::prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]);
212214 let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap();
213215
214 let _fd = unsafe { libc::open(name.as_ptr(), libc::O_RDONLY) };
216 let _fd = errno_result(unsafe { libc::open(name.as_ptr(), libc::O_RDONLY) }).unwrap();
215217}
216218
217219fn test_file_open_unix_needs_three_args() {
218220 let path = utils::prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]);
219221 let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap();
220222
221 let _fd = unsafe { libc::open(name.as_ptr(), libc::O_CREAT, 0o666) };
223 let _fd =
224 errno_result(unsafe { libc::open(name.as_ptr(), libc::O_CREAT | libc::O_RDWR, 0o666) })
225 .unwrap();
222226}
223227
224228fn test_file_open_unix_extra_third_arg() {
225229 let path = utils::prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]);
226230 let name = CString::new(path.into_os_string().into_encoded_bytes()).unwrap();
227231
228 let _fd = unsafe { libc::open(name.as_ptr(), libc::O_RDONLY, 42) };
232 let _fd = errno_result(unsafe { libc::open(name.as_ptr(), libc::O_RDONLY, 42) }).unwrap();
233}
234
235fn test_file_open_dir() {
236 let dir_path = utils::prepare_dir("miri_test_fs_dir");
237 create_dir(&dir_path).unwrap();
238 let dir_name = CString::new(dir_path.into_os_string().into_encoded_bytes()).unwrap();
239
240 // Opening it for read-write fails. The error code differs between Unix and Windows hosts.
241 let err = errno_result(unsafe { libc::open(dir_name.as_ptr(), libc::O_RDWR) }).unwrap_err();
242 assert!(
243 [libc::EISDIR, libc::EPERM].contains(&err.raw_os_error().unwrap()),
244 "unexpected errno: {err}"
245 );
246
247 // Opening it for reading succeeds, but then reading fails.
248 // FIXME: currently does not behave as expected on Windows hosts.
249 // See <https://github.com/rust-lang/miri/issues/5084>.
250 // let fd = errno_result(unsafe { libc::open(dir_name.as_ptr(), libc::O_RDONLY) }).unwrap();
251 // let mut buf = [0u8; 4];
252 // let err =
253 // errno_result(unsafe { libc::read(fd, buf.as_mut_ptr().cast(), buf.len()) }).unwrap_err();
254 // assert_eq!(err.raw_os_error().unwrap(), libc::EISDIR, "unexpected errno: {err}");
255 // libc_utils::errno_check(unsafe { libc::close(fd) });
229256}
230257
231258fn test_dup_stdout_stderr() {
......@@ -1147,3 +1174,32 @@ fn test_pwrite() {
11471174 // The write should start at the provided byte offset.
11481175 assert_eq!(&write_buffer[0..bytes_written], &read_buffer[OFFSET..(bytes_written + OFFSET)]);
11491176}
1177
1178fn test_linkat() {
1179 let source = utils::prepare_with_content("miri_test_libc_linkat_source.txt", b"hello");
1180 let link = utils::prepare("miri_test_libc_linkat_link.txt");
1181
1182 let c_source = CString::new(source.as_os_str().as_bytes()).expect("CString::new failed");
1183 let c_link = CString::new(link.as_os_str().as_bytes()).expect("CString::new failed");
1184
1185 // Call linkat
1186 unsafe {
1187 libc_utils::errno_check(libc::linkat(
1188 libc::AT_FDCWD,
1189 c_source.as_ptr(),
1190 libc::AT_FDCWD,
1191 c_link.as_ptr(),
1192 0,
1193 ));
1194 }
1195
1196 // Verify that the hard link works:
1197 // Modifications to one are visible through the other.
1198 fs::write(&source, b"hello world").unwrap();
1199 let contents = fs::read(&link).unwrap();
1200 assert_eq!(contents, b"hello world");
1201
1202 // Cleanup
1203 remove_file(&source).unwrap();
1204 remove_file(&link).unwrap();
1205}
src/tools/miri/tests/pass-dep/libc/libc-socket-no-blocking-epoll.rs+12-12
......@@ -61,7 +61,7 @@ fn test_connect_nonblock() {
6161 epoll_ctl_add(epfd, client_sockfd, EPOLLOUT | EPOLLET | EPOLLERR).unwrap();
6262
6363 // Wait until we are done connecting.
64 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
64 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
6565
6666 // There should be no error during async connection.
6767 let errno =
......@@ -95,7 +95,7 @@ fn test_accept_nonblock() {
9595 epoll_ctl_add(epfd, server_sockfd, EPOLLIN | EPOLLET | EPOLLERR).unwrap();
9696
9797 // Wait until we get a readable event on the server socket.
98 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLIN, data: server_sockfd }], -1);
98 check_epoll_wait(epfd, &[Ev { events: EPOLLIN, data: server_sockfd }], -1);
9999
100100 // Accepting should now be possible.
101101 net::accept_ipv4(server_sockfd).unwrap();
......@@ -149,7 +149,7 @@ fn test_connect_nonblock_err() {
149149 epoll_ctl_add(epfd, client_sockfd, EPOLLOUT | EPOLLET | libc::EPOLLERR).unwrap();
150150
151151 // Wait until the socket has an error.
152 check_epoll_wait::<8>(
152 check_epoll_wait(
153153 epfd,
154154 &[Ev { events: libc::EPOLLERR | EPOLLOUT | EPOLLHUP, data: client_sockfd }],
155155 -1,
......@@ -229,7 +229,7 @@ fn test_recv_nonblock() {
229229 Ok(received) => bytes_received += received as usize,
230230 Err(err) if err.kind() == ErrorKind::WouldBlock => {
231231 // Use epoll to block until there's data available again.
232 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLIN, data: client_sockfd }], -1);
232 check_epoll_wait(epfd, &[Ev { events: EPOLLIN, data: client_sockfd }], -1);
233233 }
234234 Err(err) => panic!("unexpected error whilst receiving: {err}"),
235235 }
......@@ -339,7 +339,7 @@ fn test_send_nonblock() {
339339 });
340340
341341 // Wait until the socket is again writable.
342 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
342 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
343343
344344 let fill_buf = [1u8; 100];
345345 // We should be able to write again without blocking because we just received
......@@ -371,7 +371,7 @@ fn test_shutdown_read_write() {
371371 unsafe { libc::shutdown(client_sockfd, libc::SHUT_RDWR) };
372372
373373 // Ensure that the "read end closed", "write end closed", and "readable" readiness are set.
374 check_epoll_wait::<8>(
374 check_epoll_wait(
375375 epfd,
376376 &[Ev { events: EPOLLRDHUP | EPOLLHUP | EPOLLIN, data: client_sockfd }],
377377 -1,
......@@ -399,7 +399,7 @@ fn test_shutdown_read() {
399399 unsafe { libc::shutdown(client_sockfd, libc::SHUT_RD) };
400400
401401 // Ensure that the "read end closed" readiness is set.
402 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLRDHUP, data: client_sockfd }], -1);
402 check_epoll_wait(epfd, &[Ev { events: EPOLLRDHUP, data: client_sockfd }], -1);
403403
404404 server_thread.join().unwrap();
405405}
......@@ -425,7 +425,7 @@ fn test_shutdown_write() {
425425
426426 // Ensure that the "read end closed" readiness is set when
427427 // the write end of the peer is closed.
428 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLRDHUP, data: client_sockfd }], -1);
428 check_epoll_wait(epfd, &[Ev { events: EPOLLRDHUP, data: client_sockfd }], -1);
429429
430430 server_thread.join().unwrap();
431431}
......@@ -460,7 +460,7 @@ fn test_readiness_after_short_read() {
460460 epoll_ctl_add(epfd, client_sockfd, EPOLLET | EPOLLIN).unwrap();
461461
462462 // Wait until the socket becomes readable.
463 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLIN, data: client_sockfd }], -1);
463 check_epoll_wait(epfd, &[Ev { events: EPOLLIN, data: client_sockfd }], -1);
464464
465465 let mut buffer = [0u8; 1024];
466466
......@@ -499,7 +499,7 @@ fn test_readiness_after_short_read() {
499499
500500 // Wait until the client socket becomes readable again.
501501 // If this blocks indefinitely, Miri lost track of the proper status of this socket.
502 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLIN, data: client_sockfd }], -1);
502 check_epoll_wait(epfd, &[Ev { events: EPOLLIN, data: client_sockfd }], -1);
503503
504504 // Now we can read the 2nd chunk of data.
505505 unsafe {
......@@ -583,7 +583,7 @@ fn test_readiness_after_short_write() {
583583 epoll_ctl_add(epfd, client_sockfd, EPOLLET | EPOLLOUT).unwrap();
584584
585585 // Wait until the socket becomes writable.
586 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
586 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
587587
588588 // We now want to fill the write buffer of the socket by repeatedly writing
589589 // `buffer` into it. The last write should then be a short write.
......@@ -630,7 +630,7 @@ fn test_readiness_after_short_write() {
630630
631631 // Wait until the socket becomes writable again.
632632 // If this blocks indefinitely, Miri lost track of the proper status of this socket.
633 check_epoll_wait::<8>(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
633 check_epoll_wait(epfd, &[Ev { events: EPOLLOUT, data: client_sockfd }], -1);
634634
635635 // We should again be able to write into the socket.
636636 libc_utils::write_all(client_sockfd, &buffer).unwrap();
src/tools/miri/tests/pass-dep/libc/prctl-threadname.rs+1-1
......@@ -1,4 +1,4 @@
1//@only-target: android # Miri supports prctl for Android only
1//@only-target: linux android # Linux-specific API
22use std::ffi::{CStr, CString};
33use std::thread;
44
src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs+1-1
......@@ -1,5 +1,5 @@
11//@ignore-target: windows # No pthreads on Windows
2//@ignore-target: android # No pthread_{get,set}_name on Android
2//@ignore-target: android # No pthread_{get,set}name_np on Android
33use std::ffi::{CStr, CString};
44use std::thread;
55
src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs+10-3
......@@ -1,10 +1,10 @@
11//! Regression test for <https://github.com/rust-lang/miri/issues/3341>:
22//! If `Box` has a local allocator, then it can't be `noalias` as the allocator
33//! may want to access allocator state based on the data pointer.
4//! Ensure that the `-Zmiri-tree-borrows-relax-custom-allocator-uniqueness` flag makes us
5//! accept such code.
46
5//@revisions: stack tree tree_implicit_writes
6//@[tree_implicit_writes]compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-implicit-writes
7//@[tree]compile-flags: -Zmiri-tree-borrows
7//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-relax-custom-allocator-uniqueness -Zmiri-tree-borrows-implicit-writes
88#![feature(allocator_api)]
99
1010use std::alloc::{AllocError, Allocator, Layout};
......@@ -46,6 +46,13 @@ impl MyBin {
4646 let end = start + BIN_SIZE * mem::size_of::<usize>();
4747 let addr = ptr.addr().get();
4848 assert!((start..end).contains(&addr));
49
50 // We can't update `top` as this may not be the last bin, but we can pretend to do so
51 // such that the aliasing model checks things.
52 // We access this via raw pointers so that the error span is in this file.
53 let top_ptr = (&raw const self.top) as *mut usize;
54 let top = top_ptr.read();
55 top_ptr.write(top);
4956 }
5057}
5158
src/tools/miri/tests/pass/concurrency/thread_park_isolated.rs+3-3
......@@ -5,8 +5,8 @@ use std::time::{Duration, Instant};
55fn main() {
66 let start = Instant::now();
77
8 thread::park_timeout(Duration::from_millis(200));
8 thread::park_timeout(Duration::from_millis(100));
99
10 // Thanks to deterministic execution, this will wait *exactly* 200ms, plus the time for the surrounding code.
11 assert!((200..210).contains(&start.elapsed().as_millis()), "{}", start.elapsed().as_millis());
10 // Thanks to deterministic execution, this will wait *exactly* 100ms, plus the time for the surrounding code.
11 assert!((100..110).contains(&start.elapsed().as_millis()), "{}", start.elapsed().as_millis());
1212}
src/tools/miri/tests/pass/shims/aarch64/intrinsics-aarch64-aes.rs created+45
......@@ -0,0 +1,45 @@
1// We're testing aarch64 AES target specific features.
2//@only-target: aarch64
3//@compile-flags: -C target-feature=+neon,+aes
4
5use std::arch::aarch64::*;
6use std::arch::is_aarch64_feature_detected;
7
8fn main() {
9 assert!(is_aarch64_feature_detected!("neon"));
10 assert!(is_aarch64_feature_detected!("aes"));
11
12 unsafe {
13 test_vmull_p64();
14 test_vmull_high_p64();
15 }
16}
17
18#[target_feature(enable = "neon,aes")]
19unsafe fn test_vmull_p64() {
20 assert_eq!(vmull_p64(0, 0), 0);
21 assert_eq!(vmull_p64(0, 0xffffffffffffffff), 0);
22 assert_eq!(vmull_p64(1, 1), 1);
23 assert_eq!(vmull_p64(1, 0x8000000000000000), 0x8000000000000000);
24
25 assert_eq!(vmull_p64(0b11, 0b11), 0b101);
26
27 // Check with the same inputs that are used in the x86_64 pclmulqdq test.
28 assert_eq!(
29 vmull_p64(0x7fffffffffffffff, 0xdd358416f52ecd34),
30 (2704901987789626761u128 << 64) | 13036940098130298092u128,
31 );
32}
33
34#[target_feature(enable = "neon,aes")]
35unsafe fn test_vmull_high_p64() {
36 // The lower (first) element is ignored.
37 let a = vcombine_p64(vcreate_p64(123), vcreate_p64(0b11));
38 let b = vcombine_p64(vcreate_p64(456), vcreate_p64(0b11));
39 assert_eq!(vmull_high_p64(a, b), 0b101);
40
41 // Check with the same inputs that are used in the x86_64 pclmulqdq test.
42 let a = vcombine_p64(vcreate_p64(0), vcreate_p64(0x7fffffffffffffff));
43 let b = vcombine_p64(vcreate_p64(0), vcreate_p64(0xdd358416f52ecd34));
44 assert_eq!(vmull_high_p64(a, b), (2704901987789626761u128 << 64) | 13036940098130298092u128);
45}
src/tools/miri/tests/pass/shims/fs.rs+46-10
......@@ -38,11 +38,14 @@ fn main() {
3838 if cfg!(not(windows)) {
3939 test_directory();
4040 test_canonicalize();
41 #[cfg(unix)]
42 test_pread_pwrite();
4341 #[cfg(not(target_os = "solaris"))]
4442 test_flock();
43 #[cfg(not(target_os = "android"))]
44 test_hard_link();
45
4546 test_readv_writev();
47 #[cfg(unix)]
48 test_pread_pwrite();
4649 #[cfg(all(unix, not(any(target_os = "solaris", target_os = "android"))))]
4750 test_preadv_pwritev();
4851 }
......@@ -221,9 +224,10 @@ fn test_file_set_len() {
221224 let file = OpenOptions::new().read(true).open(&path).unwrap();
222225 // Due to https://github.com/rust-lang/miri/issues/4457, we have to assume the failure could
223226 // be either of the Windows or Unix kind, no matter which platform we're on.
227 let err = file.set_len(14).unwrap_err();
224228 assert!(
225 [ErrorKind::PermissionDenied, ErrorKind::InvalidInput]
226 .contains(&file.set_len(14).unwrap_err().kind())
229 [ErrorKind::PermissionDenied, ErrorKind::InvalidInput].contains(&err.kind()),
230 "unexpected error: {err}"
227231 );
228232
229233 remove_file(&path).unwrap();
......@@ -415,20 +419,21 @@ fn test_flock() {
415419 let file1 = OpenOptions::new().read(true).write(true).open(&path).unwrap();
416420 let file2 = OpenOptions::new().read(true).write(true).open(&path).unwrap();
417421
418 // Test that we can apply many shared locks
422 // Test that we can apply many shared locks.
419423 file1.lock_shared().unwrap();
420424 file2.lock_shared().unwrap();
421 // Test that shared lock prevents exclusive lock
425 // Test that shared lock prevents exclusive lock.
422426 assert!(matches!(file1.try_lock().unwrap_err(), fs::TryLockError::WouldBlock));
423 // Unlock shared lock
427 // Unlock both files.
424428 file1.unlock().unwrap();
425429 file2.unlock().unwrap();
426 // Take exclusive lock
430
431 // Take exclusive lock.
427432 file1.lock().unwrap();
428 // Test that shared lock prevents exclusive and shared locks
433 // Test that shared lock prevents exclusive and shared locks.
429434 assert!(matches!(file2.try_lock().unwrap_err(), fs::TryLockError::WouldBlock));
430435 assert!(matches!(file2.try_lock_shared().unwrap_err(), fs::TryLockError::WouldBlock));
431 // Unlock exclusive lock
436 // Unlock exclusive lock.
432437 file1.unlock().unwrap();
433438}
434439
......@@ -510,3 +515,34 @@ fn test_preadv_pwritev() {
510515 f.read_exact(&mut written_bytes).unwrap();
511516 assert_eq!(written_bytes.as_slice(), &write_buffer[0..bytes_written]);
512517}
518
519// std uses `libc::link` on Android which we do not support.
520#[cfg(not(target_os = "android"))]
521fn test_hard_link() {
522 let source = utils::prepare_with_content("miri_test_fs_hard_link_source.txt", b"hello");
523 let link = utils::prepare("miri_test_fs_hard_link_link.txt");
524
525 fs::hard_link(&source, &link).unwrap();
526
527 // Verify that the hard link works:
528 // Modifications to one are visible through the other.
529 fs::write(&source, b"hello world").unwrap();
530 let contents = fs::read(&link).unwrap();
531 assert_eq!(contents, b"hello world");
532
533 // Only on Unix: verify both files have same inode
534 #[cfg(unix)]
535 {
536 use std::os::unix::fs::MetadataExt;
537 let source_meta = std::fs::metadata(&source).unwrap();
538 let link_meta = std::fs::metadata(&link).unwrap();
539 assert_eq!(source_meta.ino(), link_meta.ino());
540 }
541
542 // Test error: link already exists
543 assert_eq!(ErrorKind::AlreadyExists, fs::hard_link(&source, &link).unwrap_err().kind());
544
545 // Cleanup after test
546 remove_file(&source).unwrap();
547 remove_file(&link).unwrap();
548}
src/tools/miri/tests/pass/shims/loongarch/intrinsics-loongarch64-crc.rs created+54
......@@ -0,0 +1,54 @@
1// We're testing loongarch64-specific intrinsics
2//@only-target: loongarch64
3#![feature(stdarch_loongarch)]
4
5use std::arch::loongarch64::*;
6
7fn main() {
8 test_crc_ieee();
9 test_crc_castagnoli();
10}
11
12fn test_crc_ieee() {
13 // crc.w.b.w: 8-bit input
14 assert_eq!(crc_w_b_w(0x01, 0x00000000), 0x77073096);
15 assert_eq!(crc_w_b_w(0x61, 0xffffffff_u32 as i32), 0x174841bc);
16 assert_eq!(crc_w_b_w(0x2a, 0x2aa1e72b), 0x772d9171);
17
18 // crc.w.h.w: 16-bit input
19 assert_eq!(crc_w_h_w(0x0001, 0x00000000), 0x191b3141);
20 assert_eq!(crc_w_h_w(0x1234, 0xffffffff_u32 as i32), 0xf6b56fbf_u32 as i32);
21 assert_eq!(crc_w_h_w(0x022b, 0x8ecec3b5_u32 as i32), 0x03a1db7c);
22
23 // crc.w.w.w: 32-bit input
24 assert_eq!(crc_w_w_w(0x00000001, 0x00000000), 0xb8bc6765_u32 as i32);
25 assert_eq!(crc_w_w_w(0x12345678, 0xffffffff_u32 as i32), 0x5092782d);
26 assert_eq!(crc_w_w_w(0x00845fed, 0xae2912c8_u32 as i32), 0xc5690dd4_u32 as i32);
27
28 // crc.w.d.w: 64-bit input
29 assert_eq!(crc_w_d_w(0x0000000000000001, 0x00000000), 0xccaa009e_u32 as i32);
30 assert_eq!(crc_w_d_w(0x123456789abcdef0, 0xffffffff_u32 as i32), 0xe6ddf8b5_u32 as i32);
31 assert_eq!(crc_w_d_w(0xc0febeefdadafefe_u64 as i64, 0x0badeafe), 0x61a45fba);
32}
33
34fn test_crc_castagnoli() {
35 // crcc.w.b.w: 8-bit input
36 assert_eq!(crcc_w_b_w(0x01, 0x00000000), 0xf26b8303_u32 as i32);
37 assert_eq!(crcc_w_b_w(0x61, 0xffffffff_u32 as i32), 0x3e2fbccf);
38 assert_eq!(crcc_w_b_w(0x2a, 0x2aa1e72b), 0xf24122e4_u32 as i32);
39
40 // crcc.w.h.w: 16-bit input
41 assert_eq!(crcc_w_h_w(0x0001, 0x00000000), 0x13a29877);
42 assert_eq!(crcc_w_h_w(0x1234, 0xffffffff_u32 as i32), 0xf13f4cea_u32 as i32);
43 assert_eq!(crcc_w_h_w(0x022b, 0x8ecec3b5_u32 as i32), 0x013bb2fb);
44
45 // crcc.w.w.w: 32-bit input
46 assert_eq!(crcc_w_w_w(0x00000001, 0x00000000), 0xdd45aab8_u32 as i32);
47 assert_eq!(crcc_w_w_w(0x12345678, 0xffffffff_u32 as i32), 0x4dece20c);
48 assert_eq!(crcc_w_w_w(0x00845fed, 0xae2912c8_u32 as i32), 0xffae2ed1_u32 as i32);
49
50 // crcc.w.d.w: 64-bit input
51 assert_eq!(crcc_w_d_w(0x0000000000000001, 0x00000000), 0x493c7d27);
52 assert_eq!(crcc_w_d_w(0x123456789abcdef0, 0xffffffff_u32 as i32), 0xd95b664b_u32 as i32);
53 assert_eq!(crcc_w_d_w(0xc0febeefdadafefe_u64 as i64, 0x0badeafe), 0x5b44f54f);
54}
src/tools/miri/tests/utils/libc.rs+21-8
......@@ -164,24 +164,37 @@ pub mod epoll {
164164 epoll_ctl(epfd, EPOLL_CTL_ADD, fd, Ev { events, data: fd })
165165 }
166166
167 /// Call `epoll_wait` on `epfd` with the provided `timeout`.
168 /// It fetches at most `max_events` events from `epfd` and
169 /// ensures that the returned events match the `expected` events.
167170 #[track_caller]
168 pub fn check_epoll_wait<const N: usize>(epfd: i32, expected: &[Ev], timeout: i32) {
169 let mut array: [libc::epoll_event; N] = [libc::epoll_event { events: 0, u64: 0 }; N];
171 pub fn check_epoll_wait_partial(epfd: i32, expected: &[Ev], max_events: usize, timeout: i32) {
172 let mut events = vec![libc::epoll_event { events: 0, u64: 0 }; max_events];
170173 let num = errno_result(unsafe {
171 libc::epoll_wait(epfd, array.as_mut_ptr(), N.try_into().unwrap(), timeout)
174 libc::epoll_wait(epfd, events.as_mut_ptr(), i32::try_from(max_events).unwrap(), timeout)
172175 })
173176 .expect("epoll_wait returned an error");
174 let got = &mut array[..num.try_into().unwrap()];
175 let got = got
177 let got = events
176178 .iter()
179 .take(num as usize)
177180 .map(|e| Ev { events: e.events.cast_signed(), data: e.u64.try_into().unwrap() })
178181 .collect::<Vec<_>>();
179 assert_eq!(got, expected, "got wrong notifications");
182 assert_eq!(got, expected, "got wrong ready events");
183 }
184
185 /// Call `epoll_wait` on `epfd` with the provided `timeout` and ensure
186 /// that the set of *all* ready events matches `expected`.
187 #[track_caller]
188 pub fn check_epoll_wait(epfd: i32, expected: &[Ev], timeout: i32) {
189 // We set `max_events` to `expected.len() + 1` to ensure that there are no additional ready
190 // events besides those which are contained in `expected`.
191 check_epoll_wait_partial(epfd, &expected, expected.len() + 1, timeout);
180192 }
181193
194 /// This does the same as [`check_epoll_wait`] just without blocking (zero `timeout`).
182195 #[track_caller]
183 pub fn check_epoll_wait_noblock<const N: usize>(epfd: i32, expected: &[Ev]) {
184 check_epoll_wait::<N>(epfd, expected, 0);
196 pub fn check_epoll_wait_noblock(epfd: i32, expected: &[Ev]) {
197 check_epoll_wait(epfd, expected, 0);
185198 }
186199
187200 /// Query the current epoll readiness of a file descriptor.
tests/assembly-llvm/simd-bitmask.rs+18-5
......@@ -1,5 +1,5 @@
11//@ add-minicore
2//@ revisions: x86 x86-avx2 x86-avx512 aarch64
2//@ revisions: x86 x86-avx2 x86-avx512 aarch64-llvm-pre-23 aarch64
33//@ [x86] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
44//@ [x86] needs-llvm-components: x86
55//@ [x86-avx2] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
......@@ -8,8 +8,12 @@
88//@ [x86-avx512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
99//@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq
1010//@ [x86-avx512] needs-llvm-components: x86
11//@ [aarch64] min-llvm-version: 23
1112//@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu
1213//@ [aarch64] needs-llvm-components: aarch64
14//@ [aarch64-llvm-pre-23] ignore-llvm-version: 23 - 99
15//@ [aarch64-llvm-pre-23] compile-flags: --target=aarch64-unknown-linux-gnu
16//@ [aarch64-llvm-pre-23] needs-llvm-components: aarch64
1317//@ assembly-output: emit-asm
1418//@ compile-flags: --crate-type=lib -Copt-level=3 -C panic=abort
1519
......@@ -54,14 +58,23 @@ pub unsafe extern "C" fn bitmask_m8x16(mask: m8x16) -> u16 {
5458 // x86-avx512-NOT: vpsllw xmm0
5559 // x86-avx512: vpmovmskb eax, xmm0
5660 //
61 // aarch64-pre-llvm-23: adrp
62 // aarch64-pre-llvm-23-NEXT: cmlt
63 // aarch64-pre-llvm-23-NEXT: ldr
64 // aarch64-pre-llvm-23-NEXT: and
65 // aarch64-pre-llvm-23-NEXT: ext
66 // aarch64-pre-llvm-23-NEXT: zip1
67 // aarch64-pre-llvm-23-NEXT: addv
68 // aarch64-pre-llvm-23-NEXT: fmov
69 //
5770 // aarch64: adrp
5871 // aarch64-NEXT: cmlt
5972 // aarch64-NEXT: ldr
6073 // aarch64-NEXT: and
61 // aarch64-NEXT: ext
62 // aarch64-NEXT: zip1
63 // aarch64-NEXT: addv
64 // aarch64-NEXT: fmov
74 // aarch64-NEXT: addp
75 // aarch64-NEXT: addp
76 // aarch64-NEXT: addp
77 // aarch64-NEXT: umov
6578 simd_bitmask(mask)
6679}
6780
tests/codegen-llvm/sanitizer/cfi/external_weak_symbols.rs+1-1
......@@ -10,7 +10,7 @@ unsafe extern "C" {
1010 #[linkage = "extern_weak"]
1111 static FOO: Option<unsafe extern "C" fn(f64) -> ()>;
1212}
13// CHECK: @_rust_extern_with_linkage_{{.*}}_FOO = internal global ptr @FOO
13// CHECK: @_rust_extern_with_linkage_{{.*}}_FOO = internal unnamed_addr global ptr @FOO
1414
1515fn main() {
1616 unsafe {
tests/rustdoc-gui/search-tab.goml+1-1
......@@ -81,7 +81,7 @@ set-window-size: (851, 600)
8181// Check the size and count in tabs
8282assert-text: ("#search-tabs > button:nth-child(1) > .count", " (25) ")
8383assert-text: ("#search-tabs > button:nth-child(2) > .count", " (7)  ")
84assert-text: ("#search-tabs > button:nth-child(3) > .count", " (0)  ")
84assert-text: ("#search-tabs > button:nth-child(3) > .count", " (1)  ")
8585store-property: ("#search-tabs > button:nth-child(1)", {"offsetWidth": buttonWidth})
8686assert-property: ("#search-tabs > button:nth-child(2)", {"offsetWidth": |buttonWidth|})
8787assert-property: ("#search-tabs > button:nth-child(3)", {"offsetWidth": |buttonWidth|})
tests/rustdoc-gui/sidebar-foreign-impl-sort.goml+1-1
......@@ -1,4 +1,4 @@
1// Checks sidebar resizing close the Settings popover
1// Checks sidebar foreign impl ordering
22go-to: "file://" + |DOC_PATH| + "/test_docs/SidebarSort/trait.Sort.html#foreign-impls"
33
44// Check that the sidebar contains the expected foreign implementations
tests/rustdoc-gui/src/test_docs/lib.rs+14
......@@ -10,6 +10,7 @@
1010#![feature(associated_type_defaults)]
1111#![feature(macro_attr)]
1212#![feature(macro_derive)]
13#![feature(negative_impls)]
1314
1415/*!
1516Enable the feature <span class="stab portability"><code>some-feature</code></span> to enjoy
......@@ -89,6 +90,19 @@ impl AsRef<str> for Foo {
8990 }
9091}
9192
93unsafe impl Send for Foo {}
94impl !Sync for Foo {}
95
96impl From<u8> for Foo {
97 fn from(value: u8) -> Self { todo!(); }
98}
99impl From<u16> for Foo {
100 fn from(value: u16) -> Self { todo!(); }
101}
102impl From<u32> for Foo {
103 fn from(value: u32) -> Self { todo!(); }
104}
105
92106/// <div id="doc-warning-0" class="warning">I have warnings!</div>
93107pub struct WarningStruct;
94108
tests/rustdoc-gui/trait-impl-sort.goml created+19
......@@ -0,0 +1,19 @@
1// Check that trait impls in the sidebar and the main section have the same
2// ordering.
3
4go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
5
6// .sidebar .trait-implementation li:nth-child(3) a
7assert-text: (".sidebar-elems .trait-implementation li:nth-child(1) a", "!Sync")
8assert-text: (".sidebar-elems .trait-implementation li:nth-child(2) a", "AsRef<str>")
9assert-text: (".sidebar-elems .trait-implementation li:nth-child(3) a", "From<u8>")
10assert-text: (".sidebar-elems .trait-implementation li:nth-child(4) a", "From<u16>")
11assert-text: (".sidebar-elems .trait-implementation li:nth-child(5) a", "From<u32>")
12assert-text: (".sidebar-elems .trait-implementation li:nth-child(6) a", "Send")
13
14assert-text: ("#trait-implementations-list section:nth-child(1) .code-header", "impl !Sync for Foo")
15assert-text: ("#trait-implementations-list details:nth-child(2) .code-header", "impl AsRef<str> for Foo")
16assert-text: ("#trait-implementations-list details:nth-child(3) .code-header", "impl From<u8> for Foo")
17assert-text: ("#trait-implementations-list details:nth-child(4) .code-header", "impl From<u16> for Foo")
18assert-text: ("#trait-implementations-list details:nth-child(5) .code-header", "impl From<u32> for Foo")
19assert-text: ("#trait-implementations-list section:nth-child(6) .code-header", "impl Send for Foo")
tests/ui/abi/pass-indirectly-attr.stderr+1-10
......@@ -123,16 +123,7 @@ error: fn_abi_of(extern_rust) = FnAbi {
123123 mode: Cast {
124124 pad_i32: false,
125125 cast: CastTarget {
126 prefix: [
127 None,
128 None,
129 None,
130 None,
131 None,
132 None,
133 None,
134 None,
135 ],
126 prefix: [],
136127 rest_offset: None,
137128 rest: Uniform {
138129 unit: Reg {
tests/ui/attributes/attr-on-mac-call.stderr+22-22
......@@ -4,8 +4,8 @@ warning: `#[export_name]` attribute cannot be used on macro calls
44LL | #[export_name = "x"]
55 | ^^^^^^^^^^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[export_name]` can be applied to functions and statics
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/attr-on-mac-call.rs:3:9
1111 |
......@@ -18,8 +18,8 @@ warning: `#[naked]` attribute cannot be used on macro calls
1818LL | #[unsafe(naked)]
1919 | ^^^^^^^^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[naked]` can only be applied to functions
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424warning: `#[track_caller]` attribute cannot be used on macro calls
2525 --> $DIR/attr-on-mac-call.rs:12:5
......@@ -27,8 +27,8 @@ warning: `#[track_caller]` attribute cannot be used on macro calls
2727LL | #[track_caller]
2828 | ^^^^^^^^^^^^^^^
2929 |
30 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3130 = help: `#[track_caller]` can only be applied to functions
31 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3232
3333warning: `#[used]` attribute cannot be used on macro calls
3434 --> $DIR/attr-on-mac-call.rs:15:5
......@@ -36,8 +36,8 @@ warning: `#[used]` attribute cannot be used on macro calls
3636LL | #[used]
3737 | ^^^^^^^
3838 |
39 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4039 = help: `#[used]` can only be applied to statics
40 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4141
4242warning: `#[target_feature]` attribute cannot be used on macro calls
4343 --> $DIR/attr-on-mac-call.rs:18:5
......@@ -45,8 +45,8 @@ warning: `#[target_feature]` attribute cannot be used on macro calls
4545LL | #[target_feature(enable = "x")]
4646 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4747 |
48 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4948 = help: `#[target_feature]` can only be applied to functions
49 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5050
5151warning: `#[deprecated]` attribute cannot be used on macro calls
5252 --> $DIR/attr-on-mac-call.rs:21:5
......@@ -54,8 +54,8 @@ warning: `#[deprecated]` attribute cannot be used on macro calls
5454LL | #[deprecated]
5555 | ^^^^^^^^^^^^^
5656 |
57 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5857 = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements
58 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5959
6060warning: `#[inline]` attribute cannot be used on macro calls
6161 --> $DIR/attr-on-mac-call.rs:24:5
......@@ -63,8 +63,8 @@ warning: `#[inline]` attribute cannot be used on macro calls
6363LL | #[inline]
6464 | ^^^^^^^^^
6565 |
66 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6766 = help: `#[inline]` can only be applied to functions
67 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6868
6969warning: `#[link_name]` attribute cannot be used on macro calls
7070 --> $DIR/attr-on-mac-call.rs:27:5
......@@ -72,8 +72,8 @@ warning: `#[link_name]` attribute cannot be used on macro calls
7272LL | #[link_name = "x"]
7373 | ^^^^^^^^^^^^^^^^^^
7474 |
75 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7675 = help: `#[link_name]` can be applied to foreign functions and foreign statics
76 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7777
7878warning: `#[link_section]` attribute cannot be used on macro calls
7979 --> $DIR/attr-on-mac-call.rs:30:5
......@@ -81,8 +81,8 @@ warning: `#[link_section]` attribute cannot be used on macro calls
8181LL | #[link_section = "__TEXT,__text"]
8282 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8383 |
84 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8584 = help: `#[link_section]` can be applied to functions and statics
85 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8686
8787warning: `#[link_ordinal]` attribute cannot be used on macro calls
8888 --> $DIR/attr-on-mac-call.rs:33:5
......@@ -90,8 +90,8 @@ warning: `#[link_ordinal]` attribute cannot be used on macro calls
9090LL | #[link_ordinal(42)]
9191 | ^^^^^^^^^^^^^^^^^^^
9292 |
93 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9493 = help: `#[link_ordinal]` can be applied to foreign functions and foreign statics
94 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9595
9696warning: `#[non_exhaustive]` attribute cannot be used on macro calls
9797 --> $DIR/attr-on-mac-call.rs:36:5
......@@ -99,8 +99,8 @@ warning: `#[non_exhaustive]` attribute cannot be used on macro calls
9999LL | #[non_exhaustive]
100100 | ^^^^^^^^^^^^^^^^^
101101 |
102 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
103102 = help: `#[non_exhaustive]` can be applied to data types and enum variants
103 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
104104
105105warning: `#[proc_macro]` attribute cannot be used on macro calls
106106 --> $DIR/attr-on-mac-call.rs:39:5
......@@ -108,8 +108,8 @@ warning: `#[proc_macro]` attribute cannot be used on macro calls
108108LL | #[proc_macro]
109109 | ^^^^^^^^^^^^^
110110 |
111 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
112111 = help: `#[proc_macro]` can only be applied to functions
112 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
113113
114114warning: `#[cold]` attribute cannot be used on macro calls
115115 --> $DIR/attr-on-mac-call.rs:42:5
......@@ -117,8 +117,8 @@ warning: `#[cold]` attribute cannot be used on macro calls
117117LL | #[cold]
118118 | ^^^^^^^
119119 |
120 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
121120 = help: `#[cold]` can only be applied to functions
121 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
122122
123123warning: `#[no_mangle]` attribute cannot be used on macro calls
124124 --> $DIR/attr-on-mac-call.rs:45:5
......@@ -126,8 +126,8 @@ warning: `#[no_mangle]` attribute cannot be used on macro calls
126126LL | #[no_mangle]
127127 | ^^^^^^^^^^^^
128128 |
129 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
130129 = help: `#[no_mangle]` can be applied to functions and statics
130 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
131131
132132warning: `#[deprecated]` attribute cannot be used on macro calls
133133 --> $DIR/attr-on-mac-call.rs:48:5
......@@ -135,8 +135,8 @@ warning: `#[deprecated]` attribute cannot be used on macro calls
135135LL | #[deprecated]
136136 | ^^^^^^^^^^^^^
137137 |
138 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
139138 = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements
139 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
140140
141141warning: `#[automatically_derived]` attribute cannot be used on macro calls
142142 --> $DIR/attr-on-mac-call.rs:51:5
......@@ -144,8 +144,8 @@ warning: `#[automatically_derived]` attribute cannot be used on macro calls
144144LL | #[automatically_derived]
145145 | ^^^^^^^^^^^^^^^^^^^^^^^^
146146 |
147 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
148147 = help: `#[automatically_derived]` can only be applied to trait impl blocks
148 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
149149
150150warning: `#[macro_use]` attribute cannot be used on macro calls
151151 --> $DIR/attr-on-mac-call.rs:54:5
......@@ -153,8 +153,8 @@ warning: `#[macro_use]` attribute cannot be used on macro calls
153153LL | #[macro_use]
154154 | ^^^^^^^^^^^^
155155 |
156 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
157156 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
157 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
158158
159159warning: `#[must_use]` attribute cannot be used on macro calls
160160 --> $DIR/attr-on-mac-call.rs:57:5
......@@ -162,8 +162,8 @@ warning: `#[must_use]` attribute cannot be used on macro calls
162162LL | #[must_use]
163163 | ^^^^^^^^^^^
164164 |
165 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
166165 = help: `#[must_use]` can be applied to data types, functions, and traits
166 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
167167
168168warning: `#[no_implicit_prelude]` attribute cannot be used on macro calls
169169 --> $DIR/attr-on-mac-call.rs:60:5
......@@ -171,8 +171,8 @@ warning: `#[no_implicit_prelude]` attribute cannot be used on macro calls
171171LL | #[no_implicit_prelude]
172172 | ^^^^^^^^^^^^^^^^^^^^^^
173173 |
174 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
175174 = help: `#[no_implicit_prelude]` can be applied to crates and modules
175 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
176176
177177warning: `#[path]` attribute cannot be used on macro calls
178178 --> $DIR/attr-on-mac-call.rs:63:5
......@@ -180,8 +180,8 @@ warning: `#[path]` attribute cannot be used on macro calls
180180LL | #[path = ""]
181181 | ^^^^^^^^^^^^
182182 |
183 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
184183 = help: `#[path]` can only be applied to modules
184 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
185185
186186warning: `#[ignore]` attribute cannot be used on macro calls
187187 --> $DIR/attr-on-mac-call.rs:66:5
......@@ -189,8 +189,8 @@ warning: `#[ignore]` attribute cannot be used on macro calls
189189LL | #[ignore]
190190 | ^^^^^^^^^
191191 |
192 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
193192 = help: `#[ignore]` can only be applied to functions
193 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
194194
195195warning: `#[should_panic]` attribute cannot be used on macro calls
196196 --> $DIR/attr-on-mac-call.rs:69:5
......@@ -198,8 +198,8 @@ warning: `#[should_panic]` attribute cannot be used on macro calls
198198LL | #[should_panic]
199199 | ^^^^^^^^^^^^^^^
200200 |
201 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
202201 = help: `#[should_panic]` can only be applied to functions
202 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
203203
204204warning: 22 warnings emitted
205205
tests/ui/attributes/codegen_attr_on_required_trait_method.stderr+3-3
......@@ -4,8 +4,8 @@ error: `#[cold]` attribute cannot be used on required trait methods
44LL | #[cold]
55 | ^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[cold]` can be applied to closures, foreign functions, functions, inherent methods, provided trait methods, and trait methods in impl blocks
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/codegen_attr_on_required_trait_method.rs:1:9
1111 |
......@@ -18,8 +18,8 @@ error: `#[link_section]` attribute cannot be used on required trait methods
1818LL | #[link_section = "__TEXT,__text"]
1919 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424error: `#[linkage]` attribute cannot be used on required trait methods
2525 --> $DIR/codegen_attr_on_required_trait_method.rs:14:5
......@@ -27,8 +27,8 @@ error: `#[linkage]` attribute cannot be used on required trait methods
2727LL | #[linkage = "common"]
2828 | ^^^^^^^^^^^^^^^^^^^^^
2929 |
30 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3130 = help: `#[linkage]` can be applied to foreign functions, foreign statics, functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
31 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3232
3333error: aborting due to 3 previous errors
3434
tests/ui/attributes/cold-attribute-application-54044.stderr+2-2
......@@ -4,8 +4,8 @@ error: `#[cold]` attribute cannot be used on structs
44LL | #[cold]
55 | ^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[cold]` can only be applied to functions
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/cold-attribute-application-54044.rs:2:9
1111 |
......@@ -18,8 +18,8 @@ error: `#[cold]` attribute cannot be used on expressions
1818LL | #[cold]
1919 | ^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[cold]` can only be applied to functions
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424error: aborting due to 2 previous errors
2525
tests/ui/attributes/inline/attr-usage-inline.stderr+3-3
......@@ -18,8 +18,8 @@ warning: `#[inline]` attribute cannot be used on struct fields
1818LL | #[inline]
1919 | ^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[inline]` can only be applied to functions
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323 = note: requested on the command line with `-W unused-attributes`
2424
2525warning: `#[inline]` attribute cannot be used on macro defs
......@@ -28,8 +28,8 @@ warning: `#[inline]` attribute cannot be used on macro defs
2828LL | #[inline]
2929 | ^^^^^^^^^
3030 |
31 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3231 = help: `#[inline]` can only be applied to functions
32 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3333
3434warning: `#[inline]` attribute cannot be used on macro defs
3535 --> $DIR/attr-usage-inline.rs:25:1
......@@ -37,8 +37,8 @@ warning: `#[inline]` attribute cannot be used on macro defs
3737LL | #[inline]
3838 | ^^^^^^^^^
3939 |
40 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4140 = help: `#[inline]` can only be applied to functions
41 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4242
4343error: aborting due to 2 previous errors; 3 warnings emitted
4444
tests/ui/attributes/malformed-attrs.stderr+12-12
......@@ -126,15 +126,6 @@ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `p
126126LL | #[proc_macro_derive]
127127 | ^^^^^^^^^^^^^^^^^^^^
128128
129error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint
130 --> $DIR/malformed-attrs.rs:215:1
131 |
132LL | #[allow_internal_unsafe = 1]
133 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
134 |
135 = help: add `#![feature(allow_internal_unsafe)]` to the crate attributes to enable
136 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
137
138129error[E0539]: malformed `windows_subsystem` attribute input
139130 --> $DIR/malformed-attrs.rs:26:1
140131 |
......@@ -788,6 +779,15 @@ LL - #[macro_export = 18]
788779LL + #[macro_export]
789780 |
790781
782error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint
783 --> $DIR/malformed-attrs.rs:215:1
784 |
785LL | #[allow_internal_unsafe = 1]
786 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
787 |
788 = help: add `#![feature(allow_internal_unsafe)]` to the crate attributes to enable
789 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
790
791791error[E0565]: malformed `allow_internal_unsafe` attribute input
792792 --> $DIR/malformed-attrs.rs:215:1
793793 |
......@@ -890,8 +890,8 @@ warning: `#[link_name]` attribute cannot be used on functions
890890LL | #[link_name]
891891 | ^^^^^^^^^^^^
892892 |
893 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
894893 = help: `#[link_name]` can be applied to foreign functions and foreign statics
894 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
895895
896896error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
897897 --> $DIR/malformed-attrs.rs:96:1
......@@ -908,8 +908,8 @@ warning: `#[no_implicit_prelude]` attribute cannot be used on functions
908908LL | #[no_implicit_prelude = 23]
909909 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
910910 |
911 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
912911 = help: `#[no_implicit_prelude]` can be applied to crates and modules
912 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
913913
914914warning: missing options for `diagnostic::on_unimplemented` attribute
915915 --> $DIR/malformed-attrs.rs:138:1
......@@ -940,8 +940,8 @@ warning: `#[automatically_derived]` attribute cannot be used on modules
940940LL | #[automatically_derived = 18]
941941 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
942942 |
943 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
944943 = help: `#[automatically_derived]` can only be applied to trait impl blocks
944 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
945945
946946error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]`
947947 --> $DIR/malformed-attrs.rs:222:1
tests/ui/attributes/unstable_removed.stderr+2-2
......@@ -1,4 +1,4 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/unstable_removed.rs:9:1
33 |
44LL | / #![unstable_removed(
......@@ -30,5 +30,5 @@ LL | #![feature(concat_idents)]
3030
3131error: aborting due to 3 previous errors
3232
33Some errors have detailed explanations: E0557, E0734.
33Some errors have detailed explanations: E0557, E0658.
3434For more information about an error, try `rustc --explain E0557`.
tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr+1-1
......@@ -171,8 +171,8 @@ warning: `#[link_section]` attribute cannot be used on structs
171171LL | #[cfg_attr(true, link_section)]
172172 | ^^^^^^^^^^^^
173173 |
174 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
175174 = help: `#[link_section]` can be applied to functions and statics
175 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
176176 = note: requested on the command line with `-W unused-attributes`
177177
178178error: aborting due to 13 previous errors; 1 warning emitted
tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr+3-3
......@@ -46,8 +46,8 @@ error: `#[cold]` attribute cannot be used on const parameters
4646LL | pub struct Bar<#[cold] const N: usize>;
4747 | ^^^^^^^
4848 |
49 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5049 = help: `#[cold]` can only be applied to functions
50 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5151note: the lint level is defined here
5252 --> $DIR/invalid-attributes-on-const-params-78957.rs:2:9
5353 |
......@@ -60,8 +60,8 @@ error: `#[cold]` attribute cannot be used on lifetime parameters
6060LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>);
6161 | ^^^^^^^
6262 |
63 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6463 = help: `#[cold]` can only be applied to functions
64 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6565
6666error: `#[cold]` attribute cannot be used on type parameters
6767 --> $DIR/invalid-attributes-on-const-params-78957.rs:24:17
......@@ -69,8 +69,8 @@ error: `#[cold]` attribute cannot be used on type parameters
6969LL | pub struct Bar3<#[cold] T>(PhantomData<T>);
7070 | ^^^^^^^
7171 |
72 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7372 = help: `#[cold]` can only be applied to functions
73 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7474
7575error: aborting due to 9 previous errors
7676
tests/ui/coroutine/gen_block.e2024.stderr+11-11
......@@ -1,3 +1,14 @@
1error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
2 --> $DIR/gen_block.rs:16:16
3 |
4LL | let _ = || yield true;
5 | ^^^^^^^^^^
6 |
7help: use `#[coroutine]` to make this closure a coroutine
8 |
9LL | let _ = #[coroutine] || yield true;
10 | ++++++++++++
11
112error[E0658]: the `#[coroutine]` attribute is an experimental feature
213 --> $DIR/gen_block.rs:20:13
314 |
......@@ -18,17 +29,6 @@ LL | let _ = #[coroutine] || {};
1829 = help: add `#![feature(coroutines)]` to the crate attributes to enable
1930 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2031
21error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
22 --> $DIR/gen_block.rs:16:16
23 |
24LL | let _ = || yield true;
25 | ^^^^^^^^^^
26 |
27help: use `#[coroutine]` to make this closure a coroutine
28 |
29LL | let _ = #[coroutine] || yield true;
30 | ++++++++++++
31
3232error[E0282]: type annotations needed
3333 --> $DIR/gen_block.rs:7:13
3434 |
tests/ui/coroutine/gen_block.none.stderr+20-20
......@@ -44,26 +44,6 @@ LL | let _ = #[coroutine] || yield true;
4444 = help: add `#![feature(yield_expr)]` to the crate attributes to enable
4545 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4646
47error[E0658]: the `#[coroutine]` attribute is an experimental feature
48 --> $DIR/gen_block.rs:20:13
49 |
50LL | let _ = #[coroutine] || yield true;
51 | ^^^^^^^^^^^^
52 |
53 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
54 = help: add `#![feature(coroutines)]` to the crate attributes to enable
55 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
56
57error[E0658]: the `#[coroutine]` attribute is an experimental feature
58 --> $DIR/gen_block.rs:24:13
59 |
60LL | let _ = #[coroutine] || {};
61 | ^^^^^^^^^^^^
62 |
63 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
64 = help: add `#![feature(coroutines)]` to the crate attributes to enable
65 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
66
6747error[E0658]: yield syntax is experimental
6848 --> $DIR/gen_block.rs:16:16
6949 |
......@@ -85,6 +65,16 @@ help: use `#[coroutine]` to make this closure a coroutine
8565LL | let _ = #[coroutine] || yield true;
8666 | ++++++++++++
8767
68error[E0658]: the `#[coroutine]` attribute is an experimental feature
69 --> $DIR/gen_block.rs:20:13
70 |
71LL | let _ = #[coroutine] || yield true;
72 | ^^^^^^^^^^^^
73 |
74 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
75 = help: add `#![feature(coroutines)]` to the crate attributes to enable
76 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
77
8878error[E0658]: yield syntax is experimental
8979 --> $DIR/gen_block.rs:20:29
9080 |
......@@ -95,6 +85,16 @@ LL | let _ = #[coroutine] || yield true;
9585 = help: add `#![feature(yield_expr)]` to the crate attributes to enable
9686 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
9787
88error[E0658]: the `#[coroutine]` attribute is an experimental feature
89 --> $DIR/gen_block.rs:24:13
90 |
91LL | let _ = #[coroutine] || {};
92 | ^^^^^^^^^^^^
93 |
94 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
95 = help: add `#![feature(coroutines)]` to the crate attributes to enable
96 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
97
9898error: aborting due to 11 previous errors
9999
100100Some errors have detailed explanations: E0422, E0658.
tests/ui/definition-reachable/auxiliary/field-access-macro.rs created+16
......@@ -0,0 +1,16 @@
1#![feature(decl_macro)]
2
3mod n {
4 pub struct Struct(i32);
5 pub fn get_struct() -> Struct { Struct(0) }
6
7 pub macro allow_field_access($x:expr) {
8 &mut $x.0
9 }
10}
11
12pub use n::{allow_field_access, get_struct};
13
14pub macro deny_field_access($x:expr) {
15 &mut $x.0
16}
tests/ui/definition-reachable/auxiliary/transitive-macro.rs created+15
......@@ -0,0 +1,15 @@
1#![feature(decl_macro)]
2
3mod mod1 {
4 mod mod2 {
5 pub fn foo() {}
6 }
7
8 pub(crate) macro m1() {
9 mod2::foo()
10 }
11}
12
13pub macro m() {
14 mod1::m1!()
15}
tests/ui/definition-reachable/field-access.rs created+11
......@@ -0,0 +1,11 @@
1//@ aux-build:field-access-macro.rs
2
3extern crate field_access_macro;
4
5fn main() {
6 let mut s = field_access_macro::get_struct();
7
8 let try_field_access = field_access_macro::allow_field_access!(s); // Ok
9 let try_field_access = field_access_macro::deny_field_access!(s);
10 //~^ ERROR field `0` of struct `field_access_macro::n::Struct` is private
11}
tests/ui/definition-reachable/field-access.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0616]: field `0` of struct `field_access_macro::n::Struct` is private
2 --> $DIR/field-access.rs:9:28
3 |
4LL | let try_field_access = field_access_macro::deny_field_access!(s);
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private field
6 |
7 = note: this error originates in the macro `field_access_macro::deny_field_access` (in Nightly builds, run with -Z macro-backtrace for more info)
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0616`.
tests/ui/definition-reachable/field-method.rs+4-4
......@@ -1,11 +1,11 @@
1// Check that functions accessible through a field visible to a macro are
1// Check that functions visible to macros through paths with >2 segments are
22// considered reachable
33
4//@ aux-build:nested-fn-macro.rs
4//@ aux-build:field-method-macro.rs
55//@ run-pass
66
7extern crate nested_fn_macro;
7extern crate field_method_macro;
88
99fn main() {
10 assert_eq!(nested_fn_macro::m!(), 12);
10 assert_eq!(field_method_macro::m!(), 33);
1111}
tests/ui/definition-reachable/nested-fn.rs+4-4
......@@ -1,11 +1,11 @@
1// Check that functions visible to macros through paths with >2 segments are
1// Check that functions accessible through a field visible to a macro are
22// considered reachable
33
4//@ aux-build:field-method-macro.rs
4//@ aux-build:nested-fn-macro.rs
55//@ run-pass
66
7extern crate field_method_macro;
7extern crate nested_fn_macro;
88
99fn main() {
10 assert_eq!(field_method_macro::m!(), 33);
10 assert_eq!(nested_fn_macro::m!(), 12);
1111}
tests/ui/definition-reachable/transitive.rs created+10
......@@ -0,0 +1,10 @@
1//@ aux-build:transitive-macro.rs
2//@ build-fail
3
4extern crate transitive_macro;
5
6fn main() {
7 transitive_macro::m!();
8}
9
10//~? ERROR missing optimized MIR for `transitive_macro::mod1::mod2::foo` in the crate `transitive_macro`
tests/ui/definition-reachable/transitive.stderr created+10
......@@ -0,0 +1,10 @@
1error: missing optimized MIR for `transitive_macro::mod1::mod2::foo` in the crate `transitive_macro`
2 |
3note: missing optimized MIR for this item (was the crate `transitive_macro` compiled with `--emit=metadata`?)
4 --> $DIR/auxiliary/transitive-macro.rs:5:9
5 |
6LL | pub fn foo() {}
7 | ^^^^^^^^^^^^
8
9error: aborting due to 1 previous error
10
tests/ui/delegation/hir-crate-items-before-lowering-ices.ice_155127.stderr+1-1
......@@ -4,8 +4,8 @@ error: `#[deprecated]` attribute cannot be used on delegations
44LL | #[deprecated]
55 | ^^^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99 = note: `#[deny(useless_deprecated)]` on by default
1010
1111error: aborting due to 1 previous error
tests/ui/deprecation/deprecated-expr-precedence.stderr+1-1
......@@ -4,8 +4,8 @@ warning: `#[deprecated]` attribute cannot be used on expressions
44LL | #[deprecated] 0
55 | ^^^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99 = note: requested on the command line with `-W unused-attributes`
1010
1111error[E0308]: mismatched types
tests/ui/deprecation/deprecation-sanity.stderr+1-1
......@@ -101,8 +101,8 @@ error: `#[deprecated]` attribute cannot be used on trait impl blocks
101101LL | #[deprecated = "hello"]
102102 | ^^^^^^^^^^^^^^^^^^^^^^^
103103 |
104 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
105104 = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements
105 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
106106 = note: `#[deny(useless_deprecated)]` on by default
107107
108108error: aborting due to 11 previous errors
tests/ui/eii/auxiliary/unused_extern_crate_decl.rs created+6
......@@ -0,0 +1,6 @@
1//@ no-prefer-dynamic
2#![crate_type = "rlib"]
3#![feature(extern_item_impls)]
4
5#[eii(eii1)]
6pub fn decl1(x: u64);
tests/ui/eii/auxiliary/unused_extern_crate_impl.rs created+9
......@@ -0,0 +1,9 @@
1//@ no-prefer-dynamic
2//@ aux-build:unused_extern_crate_decl.rs
3#![crate_type = "rlib"]
4#![feature(extern_item_impls)]
5
6extern crate unused_extern_crate_decl;
7
8#[unused_extern_crate_decl::eii1]
9fn impl1(x: u64) {}
tests/ui/eii/dylib_needs_impl.rs+1-1
......@@ -3,5 +3,5 @@
33#![crate_type = "dylib"]
44#![feature(extern_item_impls)]
55
6#[eii(eii1)] //~ ERROR `#[eii1]` required, but not found
6#[eii(eii1)] //~ ERROR `#[eii1]` function required, but not found
77fn decl1(x: u64);
tests/ui/eii/dylib_needs_impl.stderr+1-1
......@@ -1,4 +1,4 @@
1error: `#[eii1]` required, but not found
1error: `#[eii1]` function required, but not found
22 --> $DIR/dylib_needs_impl.rs:6:7
33 |
44LL | #[eii(eii1)]
tests/ui/eii/privacy2.rs+2-2
......@@ -5,8 +5,8 @@
55extern crate other_crate_privacy2 as codegen;
66
77// has a span but in the other crate
8//~? ERROR `#[eii2]` required, but not found
9//~? ERROR `#[eii3]` required, but not found
8//~? ERROR `#[eii2]` function required, but not found
9//~? ERROR `#[eii3]` function required, but not found
1010
1111#[codegen::eii1]
1212fn eii1_impl(x: u64) {
tests/ui/eii/privacy2.stderr+2-2
......@@ -16,7 +16,7 @@ note: the function `decl1` is defined here
1616LL | fn decl1(x: u64);
1717 | ^^^^^^^^^^^^^^^^^
1818
19error: `#[eii2]` required, but not found
19error: `#[eii2]` function required, but not found
2020 --> $DIR/auxiliary/other_crate_privacy2.rs:9:7
2121 |
2222LL | #[eii(eii2)]
......@@ -24,7 +24,7 @@ LL | #[eii(eii2)]
2424 |
2525 = help: expected at least one implementation in crate `privacy2` or any of its dependencies
2626
27error: `#[eii3]` required, but not found
27error: `#[eii3]` function required, but not found
2828 --> $DIR/auxiliary/other_crate_privacy2.rs:13:11
2929 |
3030LL | #[eii(eii3)]
tests/ui/eii/shadow_builtin.rs+2-2
......@@ -5,7 +5,7 @@
55#![feature(extern_item_impls)]
66
77#[eii(inline)]
8//~^ ERROR `#[inline]` required, but not found
8//~^ ERROR `#[inline]` function required, but not found
99fn test(x: u64);
1010
1111#[inline]
......@@ -14,4 +14,4 @@ fn test_impl(x: u64) {
1414 println!("{x:?}")
1515}
1616
17fn main() { }
17fn main() {}
tests/ui/eii/shadow_builtin.stderr+1-1
......@@ -13,7 +13,7 @@ LL | #[eii(inline)]
1313 | ^^^^^^^^^^^^^^
1414 = help: use `crate::inline` to refer to this attribute macro unambiguously
1515
16error: `#[inline]` required, but not found
16error: `#[inline]` function required, but not found
1717 --> $DIR/shadow_builtin.rs:7:7
1818 |
1919LL | #[eii(inline)]
tests/ui/eii/unused_extern_crate.rs created+11
......@@ -0,0 +1,11 @@
1//@ aux-build:unused_extern_crate_decl.rs
2//@ aux-build:unused_extern_crate_impl.rs
3// Tests that dependencies that contain an EII decl without any EII impl are
4// still considered unused.
5#![feature(extern_item_impls)]
6#![deny(unused_extern_crates)]
7
8extern crate unused_extern_crate_decl; //~ ERROR unused extern crate
9extern crate unused_extern_crate_impl;
10
11fn main() {}
tests/ui/eii/unused_extern_crate.stderr created+19
......@@ -0,0 +1,19 @@
1error: unused extern crate
2 --> $DIR/unused_extern_crate.rs:8:1
3 |
4LL | extern crate unused_extern_crate_decl;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unused
6 |
7note: the lint level is defined here
8 --> $DIR/unused_extern_crate.rs:6:9
9 |
10LL | #![deny(unused_extern_crates)]
11 | ^^^^^^^^^^^^^^^^^^^^
12help: remove the unused `extern crate`
13 |
14LL - extern crate unused_extern_crate_decl;
15LL +
16 |
17
18error: aborting due to 1 previous error
19
tests/ui/error-codes/E0152-duplicate-lang-items.rs-4
......@@ -8,10 +8,6 @@
88
99#![feature(lang_items)]
1010
11extern crate core;
12
13use core::panic::PanicInfo;
14
1511#[lang = "eh_personality"]
1612fn personality() {
1713 //~^ ERROR: found duplicate lang item `eh_personality`
tests/ui/error-codes/E0152-duplicate-lang-items.stderr+1-1
......@@ -1,5 +1,5 @@
11error[E0152]: found duplicate lang item `eh_personality`
2 --> $DIR/E0152-duplicate-lang-items.rs:16:1
2 --> $DIR/E0152-duplicate-lang-items.rs:12:1
33 |
44LL | / fn personality() {
55LL | |
tests/ui/extern/extern-no-mangle.stderr+3-3
......@@ -4,8 +4,8 @@ warning: `#[no_mangle]` attribute cannot be used on foreign statics
44LL | #[no_mangle]
55 | ^^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[no_mangle]` can be applied to functions and statics
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/extern-no-mangle.rs:1:9
1111 |
......@@ -18,8 +18,8 @@ warning: `#[no_mangle]` attribute cannot be used on foreign functions
1818LL | #[no_mangle]
1919 | ^^^^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[no_mangle]` can be applied to functions, methods, and statics
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424warning: `#[no_mangle]` attribute cannot be used on statements
2525 --> $DIR/extern-no-mangle.rs:24:5
......@@ -27,8 +27,8 @@ warning: `#[no_mangle]` attribute cannot be used on statements
2727LL | #[no_mangle]
2828 | ^^^^^^^^^^^^
2929 |
30 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3130 = help: `#[no_mangle]` can be applied to functions and statics
31 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3232
3333warning: 3 warnings emitted
3434
tests/ui/extern/issue-47725.stderr+3-3
......@@ -16,8 +16,8 @@ warning: `#[link_name]` attribute cannot be used on structs
1616LL | #[link_name = "foo"]
1717 | ^^^^^^^^^^^^^^^^^^^^
1818 |
19 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2019 = help: `#[link_name]` can be applied to foreign functions and foreign statics
20 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2121note: the lint level is defined here
2222 --> $DIR/issue-47725.rs:2:9
2323 |
......@@ -30,8 +30,8 @@ warning: `#[link_name]` attribute cannot be used on foreign modules
3030LL | #[link_name = "foobar"]
3131 | ^^^^^^^^^^^^^^^^^^^^^^^
3232 |
33 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3433 = help: `#[link_name]` can be applied to foreign functions and foreign statics
34 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3535
3636warning: `#[link_name]` attribute cannot be used on foreign modules
3737 --> $DIR/issue-47725.rs:20:1
......@@ -39,8 +39,8 @@ warning: `#[link_name]` attribute cannot be used on foreign modules
3939LL | #[link_name]
4040 | ^^^^^^^^^^^^
4141 |
42 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4342 = help: `#[link_name]` can be applied to foreign functions and foreign statics
43 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4444
4545error: aborting due to 1 previous error; 3 warnings emitted
4646
tests/ui/feature-gates/feature-gate-rustc_const_unstable.rs+3-1
......@@ -1,6 +1,8 @@
11// Test internal const fn feature gate.
22
3#[rustc_const_unstable(feature="fzzzzzt")] //~ ERROR stability attributes may not be used outside
3#[rustc_const_unstable(feature="fzzzzzt")]
4//~^ ERROR stability attributes may not be used outside
5//~| ERROR missing 'issue'
46pub const fn bazinga() {}
57
68fn main() {
tests/ui/feature-gates/feature-gate-rustc_const_unstable.stderr+10-3
......@@ -1,9 +1,16 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/feature-gate-rustc_const_unstable.rs:3:1
33 |
44LL | #[rustc_const_unstable(feature="fzzzzzt")]
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
7error: aborting due to 1 previous error
7error[E0547]: missing 'issue'
8 --> $DIR/feature-gate-rustc_const_unstable.rs:3:1
9 |
10LL | #[rustc_const_unstable(feature="fzzzzzt")]
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
13error: aborting due to 2 previous errors
814
9For more information about this error, try `rustc --explain E0734`.
15Some errors have detailed explanations: E0547, E0658.
16For more information about an error, try `rustc --explain E0547`.
tests/ui/feature-gates/feature-gate-staged_api.stderr+3-3
......@@ -1,10 +1,10 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/feature-gate-staged_api.rs:1:1
33 |
44LL | #![stable(feature = "a", since = "3.3.3")]
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
7error[E0734]: stability attributes may not be used outside of the standard library
7error[E0658]: stability attributes may not be used outside of the standard library
88 --> $DIR/feature-gate-staged_api.rs:8:1
99 |
1010LL | #[stable(feature = "a", since = "3.3.3")]
......@@ -12,4 +12,4 @@ LL | #[stable(feature = "a", since = "3.3.3")]
1212
1313error: aborting due to 2 previous errors
1414
15For more information about this error, try `rustc --explain E0734`.
15For more information about this error, try `rustc --explain E0658`.
tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr+12-12
......@@ -1,3 +1,11 @@
1error: `#[macro_export]` attribute cannot be used on crates
2 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:9:1
3 |
4LL | #![macro_export]
5 | ^^^^^^^^^^^^^^^^
6 |
7 = help: `#[macro_export]` can only be applied to macro defs
8
19error[E0658]: use of an internal attribute
210 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1
311 |
......@@ -8,14 +16,6 @@ LL | #![rustc_main]
816 = note: the `#[rustc_main]` attribute is an internal implementation detail that will never be stable
917 = note: the `#[rustc_main]` attribute is used internally to specify test entry point function
1018
11error: `#[macro_export]` attribute cannot be used on crates
12 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:9:1
13 |
14LL | #![macro_export]
15 | ^^^^^^^^^^^^^^^^
16 |
17 = help: `#[macro_export]` can only be applied to macro defs
18
1919error: `#[rustc_main]` attribute cannot be used on crates
2020 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1
2121 |
......@@ -322,8 +322,8 @@ warning: `#[no_link]` attribute cannot be used on match arms
322322LL | #[no_link]
323323 | ^^^^^^^^^^
324324 |
325 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
326325 = help: `#[no_link]` can only be applied to extern crates
326 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
327327
328328warning: `#[no_link]` attribute cannot be used on struct fields
329329 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:9
......@@ -331,8 +331,8 @@ warning: `#[no_link]` attribute cannot be used on struct fields
331331LL | #[no_link]
332332 | ^^^^^^^^^^
333333 |
334 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
335334 = help: `#[no_link]` can only be applied to extern crates
335 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
336336
337337warning: `#[no_link]` attribute cannot be used on macro defs
338338 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:92:5
......@@ -340,8 +340,8 @@ warning: `#[no_link]` attribute cannot be used on macro defs
340340LL | #[no_link]
341341 | ^^^^^^^^^^
342342 |
343 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
344343 = help: `#[no_link]` can only be applied to extern crates
344 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
345345
346346warning: unused attribute
347347 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1
......@@ -357,8 +357,8 @@ warning: `#[no_mangle]` attribute cannot be used on crates
357357LL | #![no_mangle]
358358 | ^^^^^^^^^^^^^
359359 |
360 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
361360 = help: `#[no_mangle]` can be applied to functions and statics
361 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
362362
363363error: aborting due to 37 previous errors; 6 warnings emitted
364364
tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr+76-76
......@@ -277,8 +277,8 @@ warning: `#[macro_use]` attribute cannot be used on functions
277277LL | #[macro_use] fn f() { }
278278 | ^^^^^^^^^^^^
279279 |
280 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
281280 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
281 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
282282
283283warning: `#[macro_use]` attribute cannot be used on structs
284284 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
......@@ -286,8 +286,8 @@ warning: `#[macro_use]` attribute cannot be used on structs
286286LL | #[macro_use] struct S;
287287 | ^^^^^^^^^^^^
288288 |
289 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
290289 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
290 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
291291
292292warning: `#[macro_use]` attribute cannot be used on type aliases
293293 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
......@@ -295,8 +295,8 @@ warning: `#[macro_use]` attribute cannot be used on type aliases
295295LL | #[macro_use] type T = S;
296296 | ^^^^^^^^^^^^
297297 |
298 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
299298 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
299 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
300300
301301warning: `#[macro_use]` attribute cannot be used on inherent impl blocks
302302 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:5
......@@ -304,8 +304,8 @@ warning: `#[macro_use]` attribute cannot be used on inherent impl blocks
304304LL | #[macro_use] impl S { }
305305 | ^^^^^^^^^^^^
306306 |
307 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
308307 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
308 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
309309
310310warning: `#[macro_export]` attribute cannot be used on modules
311311 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:214:1
......@@ -313,8 +313,8 @@ warning: `#[macro_export]` attribute cannot be used on modules
313313LL | #[macro_export]
314314 | ^^^^^^^^^^^^^^^
315315 |
316 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
317316 = help: `#[macro_export]` can only be applied to macro defs
317 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
318318
319319warning: `#[macro_export]` attribute cannot be used on modules
320320 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:17
......@@ -322,8 +322,8 @@ warning: `#[macro_export]` attribute cannot be used on modules
322322LL | mod inner { #![macro_export] }
323323 | ^^^^^^^^^^^^^^^^
324324 |
325 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
326325 = help: `#[macro_export]` can only be applied to macro defs
326 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
327327
328328warning: `#[macro_export]` attribute cannot be used on functions
329329 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:5
......@@ -331,8 +331,8 @@ warning: `#[macro_export]` attribute cannot be used on functions
331331LL | #[macro_export] fn f() { }
332332 | ^^^^^^^^^^^^^^^
333333 |
334 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
335334 = help: `#[macro_export]` can only be applied to macro defs
335 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
336336
337337warning: `#[macro_export]` attribute cannot be used on structs
338338 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:232:5
......@@ -340,8 +340,8 @@ warning: `#[macro_export]` attribute cannot be used on structs
340340LL | #[macro_export] struct S;
341341 | ^^^^^^^^^^^^^^^
342342 |
343 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
344343 = help: `#[macro_export]` can only be applied to macro defs
344 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
345345
346346warning: `#[macro_export]` attribute cannot be used on type aliases
347347 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5
......@@ -349,8 +349,8 @@ warning: `#[macro_export]` attribute cannot be used on type aliases
349349LL | #[macro_export] type T = S;
350350 | ^^^^^^^^^^^^^^^
351351 |
352 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
353352 = help: `#[macro_export]` can only be applied to macro defs
353 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
354354
355355warning: `#[macro_export]` attribute cannot be used on inherent impl blocks
356356 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:5
......@@ -358,8 +358,8 @@ warning: `#[macro_export]` attribute cannot be used on inherent impl blocks
358358LL | #[macro_export] impl S { }
359359 | ^^^^^^^^^^^^^^^
360360 |
361 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
362361 = help: `#[macro_export]` can only be applied to macro defs
362 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
363363
364364warning: `#[path]` attribute cannot be used on functions
365365 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:255:5
......@@ -367,8 +367,8 @@ warning: `#[path]` attribute cannot be used on functions
367367LL | #[path = "3800"] fn f() { }
368368 | ^^^^^^^^^^^^^^^^
369369 |
370 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
371370 = help: `#[path]` can only be applied to modules
371 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
372372
373373warning: `#[path]` attribute cannot be used on structs
374374 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:261:5
......@@ -376,8 +376,8 @@ warning: `#[path]` attribute cannot be used on structs
376376LL | #[path = "3800"] struct S;
377377 | ^^^^^^^^^^^^^^^^
378378 |
379 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
380379 = help: `#[path]` can only be applied to modules
380 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
381381
382382warning: `#[path]` attribute cannot be used on type aliases
383383 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:267:5
......@@ -385,8 +385,8 @@ warning: `#[path]` attribute cannot be used on type aliases
385385LL | #[path = "3800"] type T = S;
386386 | ^^^^^^^^^^^^^^^^
387387 |
388 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
389388 = help: `#[path]` can only be applied to modules
389 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
390390
391391warning: `#[path]` attribute cannot be used on inherent impl blocks
392392 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
......@@ -394,8 +394,8 @@ warning: `#[path]` attribute cannot be used on inherent impl blocks
394394LL | #[path = "3800"] impl S { }
395395 | ^^^^^^^^^^^^^^^^
396396 |
397 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
398397 = help: `#[path]` can only be applied to modules
398 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
399399
400400warning: `#[automatically_derived]` attribute cannot be used on modules
401401 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:280:1
......@@ -403,8 +403,8 @@ warning: `#[automatically_derived]` attribute cannot be used on modules
403403LL | #[automatically_derived]
404404 | ^^^^^^^^^^^^^^^^^^^^^^^^
405405 |
406 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
407406 = help: `#[automatically_derived]` can only be applied to trait impl blocks
407 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
408408
409409warning: `#[automatically_derived]` attribute cannot be used on modules
410410 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:286:17
......@@ -412,8 +412,8 @@ warning: `#[automatically_derived]` attribute cannot be used on modules
412412LL | mod inner { #![automatically_derived] }
413413 | ^^^^^^^^^^^^^^^^^^^^^^^^^
414414 |
415 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
416415 = help: `#[automatically_derived]` can only be applied to trait impl blocks
416 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
417417
418418warning: `#[automatically_derived]` attribute cannot be used on functions
419419 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:292:5
......@@ -421,8 +421,8 @@ warning: `#[automatically_derived]` attribute cannot be used on functions
421421LL | #[automatically_derived] fn f() { }
422422 | ^^^^^^^^^^^^^^^^^^^^^^^^
423423 |
424 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
425424 = help: `#[automatically_derived]` can only be applied to trait impl blocks
425 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
426426
427427warning: `#[automatically_derived]` attribute cannot be used on structs
428428 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:298:5
......@@ -430,8 +430,8 @@ warning: `#[automatically_derived]` attribute cannot be used on structs
430430LL | #[automatically_derived] struct S;
431431 | ^^^^^^^^^^^^^^^^^^^^^^^^
432432 |
433 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
434433 = help: `#[automatically_derived]` can only be applied to trait impl blocks
434 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
435435
436436warning: `#[automatically_derived]` attribute cannot be used on type aliases
437437 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:304:5
......@@ -439,8 +439,8 @@ warning: `#[automatically_derived]` attribute cannot be used on type aliases
439439LL | #[automatically_derived] type T = S;
440440 | ^^^^^^^^^^^^^^^^^^^^^^^^
441441 |
442 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
443442 = help: `#[automatically_derived]` can only be applied to trait impl blocks
443 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
444444
445445warning: `#[automatically_derived]` attribute cannot be used on traits
446446 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:5
......@@ -448,8 +448,8 @@ warning: `#[automatically_derived]` attribute cannot be used on traits
448448LL | #[automatically_derived] trait W { }
449449 | ^^^^^^^^^^^^^^^^^^^^^^^^
450450 |
451 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
452451 = help: `#[automatically_derived]` can only be applied to trait impl blocks
452 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
453453
454454warning: `#[automatically_derived]` attribute cannot be used on inherent impl blocks
455455 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:5
......@@ -457,8 +457,8 @@ warning: `#[automatically_derived]` attribute cannot be used on inherent impl bl
457457LL | #[automatically_derived] impl S { }
458458 | ^^^^^^^^^^^^^^^^^^^^^^^^
459459 |
460 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
461460 = help: `#[automatically_derived]` can only be applied to trait impl blocks
461 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
462462
463463warning: `#[no_mangle]` attribute cannot be used on modules
464464 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:325:1
......@@ -466,8 +466,8 @@ warning: `#[no_mangle]` attribute cannot be used on modules
466466LL | #[no_mangle]
467467 | ^^^^^^^^^^^^
468468 |
469 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
470469 = help: `#[no_mangle]` can be applied to functions and statics
470 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
471471
472472warning: `#[no_mangle]` attribute cannot be used on modules
473473 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:331:17
......@@ -475,8 +475,8 @@ warning: `#[no_mangle]` attribute cannot be used on modules
475475LL | mod inner { #![no_mangle] }
476476 | ^^^^^^^^^^^^^
477477 |
478 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
479478 = help: `#[no_mangle]` can be applied to functions and statics
479 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
480480
481481warning: `#[no_mangle]` attribute cannot be used on structs
482482 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:339:5
......@@ -484,8 +484,8 @@ warning: `#[no_mangle]` attribute cannot be used on structs
484484LL | #[no_mangle] struct S;
485485 | ^^^^^^^^^^^^
486486 |
487 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
488487 = help: `#[no_mangle]` can be applied to functions and statics
488 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
489489
490490warning: `#[no_mangle]` attribute cannot be used on type aliases
491491 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5
......@@ -493,8 +493,8 @@ warning: `#[no_mangle]` attribute cannot be used on type aliases
493493LL | #[no_mangle] type T = S;
494494 | ^^^^^^^^^^^^
495495 |
496 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
497496 = help: `#[no_mangle]` can be applied to functions and statics
497 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
498498
499499warning: `#[no_mangle]` attribute cannot be used on inherent impl blocks
500500 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
......@@ -502,8 +502,8 @@ warning: `#[no_mangle]` attribute cannot be used on inherent impl blocks
502502LL | #[no_mangle] impl S { }
503503 | ^^^^^^^^^^^^
504504 |
505 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
506505 = help: `#[no_mangle]` can be applied to functions and statics
506 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
507507
508508warning: `#[no_mangle]` attribute cannot be used on required trait methods
509509 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:9
......@@ -511,8 +511,8 @@ warning: `#[no_mangle]` attribute cannot be used on required trait methods
511511LL | #[no_mangle] fn foo();
512512 | ^^^^^^^^^^^^
513513 |
514 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
515514 = help: `#[no_mangle]` can be applied to functions, inherent methods, statics, and trait methods in impl blocks
515 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
516516
517517warning: `#[no_mangle]` attribute cannot be used on provided trait methods
518518 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:9
......@@ -520,8 +520,8 @@ warning: `#[no_mangle]` attribute cannot be used on provided trait methods
520520LL | #[no_mangle] fn bar() {}
521521 | ^^^^^^^^^^^^
522522 |
523 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
524523 = help: `#[no_mangle]` can be applied to functions, inherent methods, statics, and trait methods in impl blocks
524 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
525525
526526warning: `#[should_panic]` attribute cannot be used on modules
527527 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:372:1
......@@ -529,8 +529,8 @@ warning: `#[should_panic]` attribute cannot be used on modules
529529LL | #[should_panic]
530530 | ^^^^^^^^^^^^^^^
531531 |
532 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
533532 = help: `#[should_panic]` can only be applied to functions
533 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
534534
535535warning: `#[should_panic]` attribute cannot be used on modules
536536 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:378:17
......@@ -538,8 +538,8 @@ warning: `#[should_panic]` attribute cannot be used on modules
538538LL | mod inner { #![should_panic] }
539539 | ^^^^^^^^^^^^^^^^
540540 |
541 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
542541 = help: `#[should_panic]` can only be applied to functions
542 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
543543
544544warning: `#[should_panic]` attribute cannot be used on structs
545545 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5
......@@ -547,8 +547,8 @@ warning: `#[should_panic]` attribute cannot be used on structs
547547LL | #[should_panic] struct S;
548548 | ^^^^^^^^^^^^^^^
549549 |
550 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
551550 = help: `#[should_panic]` can only be applied to functions
551 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
552552
553553warning: `#[should_panic]` attribute cannot be used on type aliases
554554 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:5
......@@ -556,8 +556,8 @@ warning: `#[should_panic]` attribute cannot be used on type aliases
556556LL | #[should_panic] type T = S;
557557 | ^^^^^^^^^^^^^^^
558558 |
559 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
560559 = help: `#[should_panic]` can only be applied to functions
560 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
561561
562562warning: `#[should_panic]` attribute cannot be used on inherent impl blocks
563563 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:5
......@@ -565,8 +565,8 @@ warning: `#[should_panic]` attribute cannot be used on inherent impl blocks
565565LL | #[should_panic] impl S { }
566566 | ^^^^^^^^^^^^^^^
567567 |
568 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
569568 = help: `#[should_panic]` can only be applied to functions
569 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
570570
571571warning: `#[ignore]` attribute cannot be used on modules
572572 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:1
......@@ -574,8 +574,8 @@ warning: `#[ignore]` attribute cannot be used on modules
574574LL | #[ignore]
575575 | ^^^^^^^^^
576576 |
577 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
578577 = help: `#[ignore]` can only be applied to functions
578 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
579579
580580warning: `#[ignore]` attribute cannot be used on modules
581581 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:17
......@@ -583,8 +583,8 @@ warning: `#[ignore]` attribute cannot be used on modules
583583LL | mod inner { #![ignore] }
584584 | ^^^^^^^^^^
585585 |
586 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
587586 = help: `#[ignore]` can only be applied to functions
587 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
588588
589589warning: `#[ignore]` attribute cannot be used on structs
590590 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:5
......@@ -592,8 +592,8 @@ warning: `#[ignore]` attribute cannot be used on structs
592592LL | #[ignore] struct S;
593593 | ^^^^^^^^^
594594 |
595 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
596595 = help: `#[ignore]` can only be applied to functions
596 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
597597
598598warning: `#[ignore]` attribute cannot be used on type aliases
599599 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:425:5
......@@ -601,8 +601,8 @@ warning: `#[ignore]` attribute cannot be used on type aliases
601601LL | #[ignore] type T = S;
602602 | ^^^^^^^^^
603603 |
604 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
605604 = help: `#[ignore]` can only be applied to functions
605 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
606606
607607warning: `#[ignore]` attribute cannot be used on inherent impl blocks
608608 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:431:5
......@@ -610,8 +610,8 @@ warning: `#[ignore]` attribute cannot be used on inherent impl blocks
610610LL | #[ignore] impl S { }
611611 | ^^^^^^^^^
612612 |
613 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
614613 = help: `#[ignore]` can only be applied to functions
614 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
615615
616616warning: `#[no_implicit_prelude]` attribute cannot be used on functions
617617 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5
......@@ -619,8 +619,8 @@ warning: `#[no_implicit_prelude]` attribute cannot be used on functions
619619LL | #[no_implicit_prelude] fn f() { }
620620 | ^^^^^^^^^^^^^^^^^^^^^^
621621 |
622 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
623622 = help: `#[no_implicit_prelude]` can be applied to crates and modules
623 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
624624
625625warning: `#[no_implicit_prelude]` attribute cannot be used on structs
626626 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
......@@ -628,8 +628,8 @@ warning: `#[no_implicit_prelude]` attribute cannot be used on structs
628628LL | #[no_implicit_prelude] struct S;
629629 | ^^^^^^^^^^^^^^^^^^^^^^
630630 |
631 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
632631 = help: `#[no_implicit_prelude]` can be applied to crates and modules
632 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
633633
634634warning: `#[no_implicit_prelude]` attribute cannot be used on type aliases
635635 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:5
......@@ -637,8 +637,8 @@ warning: `#[no_implicit_prelude]` attribute cannot be used on type aliases
637637LL | #[no_implicit_prelude] type T = S;
638638 | ^^^^^^^^^^^^^^^^^^^^^^
639639 |
640 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
641640 = help: `#[no_implicit_prelude]` can be applied to crates and modules
641 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
642642
643643warning: `#[no_implicit_prelude]` attribute cannot be used on inherent impl blocks
644644 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:5
......@@ -646,8 +646,8 @@ warning: `#[no_implicit_prelude]` attribute cannot be used on inherent impl bloc
646646LL | #[no_implicit_prelude] impl S { }
647647 | ^^^^^^^^^^^^^^^^^^^^^^
648648 |
649 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
650649 = help: `#[no_implicit_prelude]` can be applied to crates and modules
650 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
651651
652652warning: `#[macro_escape]` attribute cannot be used on functions
653653 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5
......@@ -655,8 +655,8 @@ warning: `#[macro_escape]` attribute cannot be used on functions
655655LL | #[macro_escape] fn f() { }
656656 | ^^^^^^^^^^^^^^^
657657 |
658 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
659658 = help: `#[macro_escape]` can be applied to crates, extern crates, and modules
659 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
660660
661661warning: `#[macro_escape]` attribute cannot be used on structs
662662 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:481:5
......@@ -664,8 +664,8 @@ warning: `#[macro_escape]` attribute cannot be used on structs
664664LL | #[macro_escape] struct S;
665665 | ^^^^^^^^^^^^^^^
666666 |
667 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
668667 = help: `#[macro_escape]` can be applied to crates, extern crates, and modules
668 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
669669
670670warning: `#[macro_escape]` attribute cannot be used on type aliases
671671 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5
......@@ -673,8 +673,8 @@ warning: `#[macro_escape]` attribute cannot be used on type aliases
673673LL | #[macro_escape] type T = S;
674674 | ^^^^^^^^^^^^^^^
675675 |
676 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
677676 = help: `#[macro_escape]` can be applied to crates, extern crates, and modules
677 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
678678
679679warning: `#[macro_escape]` attribute cannot be used on inherent impl blocks
680680 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:5
......@@ -682,8 +682,8 @@ warning: `#[macro_escape]` attribute cannot be used on inherent impl blocks
682682LL | #[macro_escape] impl S { }
683683 | ^^^^^^^^^^^^^^^
684684 |
685 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
686685 = help: `#[macro_escape]` can be applied to crates, extern crates, and modules
686 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
687687
688688warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
689689 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1
......@@ -761,8 +761,8 @@ warning: `#[cold]` attribute cannot be used on modules
761761LL | #[cold]
762762 | ^^^^^^^
763763 |
764 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
765764 = help: `#[cold]` can only be applied to functions
765 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
766766
767767warning: `#[cold]` attribute cannot be used on modules
768768 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:548:17
......@@ -770,8 +770,8 @@ warning: `#[cold]` attribute cannot be used on modules
770770LL | mod inner { #![cold] }
771771 | ^^^^^^^^
772772 |
773 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
774773 = help: `#[cold]` can only be applied to functions
774 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
775775
776776warning: `#[cold]` attribute cannot be used on structs
777777 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:556:5
......@@ -779,8 +779,8 @@ warning: `#[cold]` attribute cannot be used on structs
779779LL | #[cold] struct S;
780780 | ^^^^^^^
781781 |
782 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
783782 = help: `#[cold]` can only be applied to functions
783 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
784784
785785warning: `#[cold]` attribute cannot be used on type aliases
786786 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:562:5
......@@ -788,8 +788,8 @@ warning: `#[cold]` attribute cannot be used on type aliases
788788LL | #[cold] type T = S;
789789 | ^^^^^^^
790790 |
791 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
792791 = help: `#[cold]` can only be applied to functions
792 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
793793
794794warning: `#[cold]` attribute cannot be used on inherent impl blocks
795795 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:568:5
......@@ -797,8 +797,8 @@ warning: `#[cold]` attribute cannot be used on inherent impl blocks
797797LL | #[cold] impl S { }
798798 | ^^^^^^^
799799 |
800 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
801800 = help: `#[cold]` can only be applied to functions
801 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
802802
803803warning: `#[link_name]` attribute cannot be used on modules
804804 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:575:1
......@@ -806,8 +806,8 @@ warning: `#[link_name]` attribute cannot be used on modules
806806LL | #[link_name = "1900"]
807807 | ^^^^^^^^^^^^^^^^^^^^^
808808 |
809 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
810809 = help: `#[link_name]` can be applied to foreign functions and foreign statics
810 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
811811
812812warning: `#[link_name]` attribute cannot be used on foreign modules
813813 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:5
......@@ -815,8 +815,8 @@ warning: `#[link_name]` attribute cannot be used on foreign modules
815815LL | #[link_name = "1900"]
816816 | ^^^^^^^^^^^^^^^^^^^^^
817817 |
818 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
819818 = help: `#[link_name]` can be applied to foreign functions and foreign statics
819 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
820820
821821warning: `#[link_name]` attribute cannot be used on modules
822822 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:588:17
......@@ -824,8 +824,8 @@ warning: `#[link_name]` attribute cannot be used on modules
824824LL | mod inner { #![link_name="1900"] }
825825 | ^^^^^^^^^^^^^^^^^^^^
826826 |
827 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
828827 = help: `#[link_name]` can be applied to foreign functions and foreign statics
828 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
829829
830830warning: `#[link_name]` attribute cannot be used on functions
831831 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:594:5
......@@ -833,8 +833,8 @@ warning: `#[link_name]` attribute cannot be used on functions
833833LL | #[link_name = "1900"] fn f() { }
834834 | ^^^^^^^^^^^^^^^^^^^^^
835835 |
836 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
837836 = help: `#[link_name]` can be applied to foreign functions and foreign statics
837 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
838838
839839warning: `#[link_name]` attribute cannot be used on structs
840840 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:600:5
......@@ -842,8 +842,8 @@ warning: `#[link_name]` attribute cannot be used on structs
842842LL | #[link_name = "1900"] struct S;
843843 | ^^^^^^^^^^^^^^^^^^^^^
844844 |
845 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
846845 = help: `#[link_name]` can be applied to foreign functions and foreign statics
846 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
847847
848848warning: `#[link_name]` attribute cannot be used on type aliases
849849 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:606:5
......@@ -851,8 +851,8 @@ warning: `#[link_name]` attribute cannot be used on type aliases
851851LL | #[link_name = "1900"] type T = S;
852852 | ^^^^^^^^^^^^^^^^^^^^^
853853 |
854 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
855854 = help: `#[link_name]` can be applied to foreign functions and foreign statics
855 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
856856
857857warning: `#[link_name]` attribute cannot be used on inherent impl blocks
858858 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:612:5
......@@ -860,8 +860,8 @@ warning: `#[link_name]` attribute cannot be used on inherent impl blocks
860860LL | #[link_name = "1900"] impl S { }
861861 | ^^^^^^^^^^^^^^^^^^^^^
862862 |
863 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
864863 = help: `#[link_name]` can be applied to foreign functions and foreign statics
864 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
865865
866866warning: `#[link_section]` attribute cannot be used on modules
867867 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:619:1
......@@ -869,8 +869,8 @@ warning: `#[link_section]` attribute cannot be used on modules
869869LL | #[link_section = ",1800"]
870870 | ^^^^^^^^^^^^^^^^^^^^^^^^^
871871 |
872 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
873872 = help: `#[link_section]` can be applied to functions and statics
873 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
874874
875875warning: `#[link_section]` attribute cannot be used on modules
876876 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:625:17
......@@ -878,8 +878,8 @@ warning: `#[link_section]` attribute cannot be used on modules
878878LL | mod inner { #![link_section=",1800"] }
879879 | ^^^^^^^^^^^^^^^^^^^^^^^^
880880 |
881 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
882881 = help: `#[link_section]` can be applied to functions and statics
882 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
883883
884884warning: `#[link_section]` attribute cannot be used on structs
885885 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:633:5
......@@ -887,8 +887,8 @@ warning: `#[link_section]` attribute cannot be used on structs
887887LL | #[link_section = ",1800"] struct S;
888888 | ^^^^^^^^^^^^^^^^^^^^^^^^^
889889 |
890 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
891890 = help: `#[link_section]` can be applied to functions and statics
891 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
892892
893893warning: `#[link_section]` attribute cannot be used on type aliases
894894 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639:5
......@@ -896,8 +896,8 @@ warning: `#[link_section]` attribute cannot be used on type aliases
896896LL | #[link_section = ",1800"] type T = S;
897897 | ^^^^^^^^^^^^^^^^^^^^^^^^^
898898 |
899 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
900899 = help: `#[link_section]` can be applied to functions and statics
900 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
901901
902902warning: `#[link_section]` attribute cannot be used on inherent impl blocks
903903 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:645:5
......@@ -905,8 +905,8 @@ warning: `#[link_section]` attribute cannot be used on inherent impl blocks
905905LL | #[link_section = ",1800"] impl S { }
906906 | ^^^^^^^^^^^^^^^^^^^^^^^^^
907907 |
908 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
909908 = help: `#[link_section]` can be applied to functions and statics
909 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
910910
911911warning: `#[link_section]` attribute cannot be used on traits
912912 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:5
......@@ -914,8 +914,8 @@ warning: `#[link_section]` attribute cannot be used on traits
914914LL | #[link_section = ",1800"]
915915 | ^^^^^^^^^^^^^^^^^^^^^^^^^
916916 |
917 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
918917 = help: `#[link_section]` can be applied to functions and statics
918 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
919919
920920warning: `#[link_section]` attribute cannot be used on required trait methods
921921 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:9
......@@ -923,8 +923,8 @@ warning: `#[link_section]` attribute cannot be used on required trait methods
923923LL | #[link_section = ",1800"]
924924 | ^^^^^^^^^^^^^^^^^^^^^^^^^
925925 |
926 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
927926 = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
927 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
928928
929929warning: `#[must_use]` attribute cannot be used on modules
930930 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:1
......@@ -932,8 +932,8 @@ warning: `#[must_use]` attribute cannot be used on modules
932932LL | #[must_use]
933933 | ^^^^^^^^^^^
934934 |
935 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
936935 = help: `#[must_use]` can be applied to data types, functions, and traits
936 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
937937
938938warning: `#[must_use]` attribute cannot be used on modules
939939 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:17
......@@ -941,8 +941,8 @@ warning: `#[must_use]` attribute cannot be used on modules
941941LL | mod inner { #![must_use] }
942942 | ^^^^^^^^^^^^
943943 |
944 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
945944 = help: `#[must_use]` can be applied to data types, functions, and traits
945 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
946946
947947warning: `#[must_use]` attribute cannot be used on type aliases
948948 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:5
......@@ -950,8 +950,8 @@ warning: `#[must_use]` attribute cannot be used on type aliases
950950LL | #[must_use] type T = S;
951951 | ^^^^^^^^^^^
952952 |
953 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
954953 = help: `#[must_use]` can be applied to data types, functions, and traits
954 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
955955
956956warning: `#[must_use]` attribute cannot be used on inherent impl blocks
957957 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
......@@ -959,8 +959,8 @@ warning: `#[must_use]` attribute cannot be used on inherent impl blocks
959959LL | #[must_use] impl S { }
960960 | ^^^^^^^^^^^
961961 |
962 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
963962 = help: `#[must_use]` can be applied to data types, functions, and traits
963 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
964964
965965warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
966966 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:1
......@@ -1528,8 +1528,8 @@ warning: `#[should_panic]` attribute cannot be used on crates
15281528LL | #![should_panic]
15291529 | ^^^^^^^^^^^^^^^^
15301530 |
1531 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15321531 = help: `#[should_panic]` can only be applied to functions
1532 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15331533
15341534warning: `#[ignore]` attribute cannot be used on crates
15351535 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:1
......@@ -1537,8 +1537,8 @@ warning: `#[ignore]` attribute cannot be used on crates
15371537LL | #![ignore]
15381538 | ^^^^^^^^^^
15391539 |
1540 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15411540 = help: `#[ignore]` can only be applied to functions
1541 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15421542
15431543warning: `#[proc_macro_derive]` attribute cannot be used on crates
15441544 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:61:1
......@@ -1546,8 +1546,8 @@ warning: `#[proc_macro_derive]` attribute cannot be used on crates
15461546LL | #![proc_macro_derive(Test)]
15471547 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
15481548 |
1549 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15501549 = help: `#[proc_macro_derive]` can only be applied to functions
1550 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15511551
15521552warning: `#[cold]` attribute cannot be used on crates
15531553 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
......@@ -1555,8 +1555,8 @@ warning: `#[cold]` attribute cannot be used on crates
15551555LL | #![cold]
15561556 | ^^^^^^^^
15571557 |
1558 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15591558 = help: `#[cold]` can only be applied to functions
1559 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15601560
15611561warning: `#[link_name]` attribute cannot be used on crates
15621562 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
......@@ -1564,8 +1564,8 @@ warning: `#[link_name]` attribute cannot be used on crates
15641564LL | #![link_name = "1900"]
15651565 | ^^^^^^^^^^^^^^^^^^^^^^
15661566 |
1567 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15681567 = help: `#[link_name]` can be applied to foreign functions and foreign statics
1568 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15691569
15701570warning: `#[link_section]` attribute cannot be used on crates
15711571 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:77:1
......@@ -1573,8 +1573,8 @@ warning: `#[link_section]` attribute cannot be used on crates
15731573LL | #![link_section = ",1800"]
15741574 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
15751575 |
1576 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15771576 = help: `#[link_section]` can be applied to functions and statics
1577 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15781578
15791579warning: `#[must_use]` attribute cannot be used on crates
15801580 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:82:1
......@@ -1582,8 +1582,8 @@ warning: `#[must_use]` attribute cannot be used on crates
15821582LL | #![must_use]
15831583 | ^^^^^^^^^^^^
15841584 |
1585 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15861585 = help: `#[must_use]` can be applied to data types, functions, and traits
1586 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15871587
15881588warning: 169 warnings emitted
15891589
tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr+4-4
......@@ -40,8 +40,8 @@ warning: `#[macro_use]` attribute cannot be used on structs
4040LL | #[macro_use = "2700"] struct S;
4141 | ^^^^^^^^^^^^^^^^^^^^^
4242 |
43 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4443 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
44 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4545 = note: requested on the command line with `-W unused-attributes`
4646
4747warning: `#[macro_use]` attribute cannot be used on functions
......@@ -50,8 +50,8 @@ warning: `#[macro_use]` attribute cannot be used on functions
5050LL | #[macro_use] fn f() { }
5151 | ^^^^^^^^^^^^
5252 |
53 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5453 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
54 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5555
5656warning: `#[macro_use]` attribute cannot be used on type aliases
5757 --> $DIR/issue-43106-gating-of-macro_use.rs:24:5
......@@ -59,8 +59,8 @@ warning: `#[macro_use]` attribute cannot be used on type aliases
5959LL | #[macro_use] type T = S;
6060 | ^^^^^^^^^^^^
6161 |
62 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6362 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
63 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6464
6565warning: `#[macro_use]` attribute cannot be used on inherent impl blocks
6666 --> $DIR/issue-43106-gating-of-macro_use.rs:28:5
......@@ -68,8 +68,8 @@ warning: `#[macro_use]` attribute cannot be used on inherent impl blocks
6868LL | #[macro_use] impl S { }
6969 | ^^^^^^^^^^^^
7070 |
71 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7271 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
72 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7373
7474error: aborting due to 4 previous errors; 4 warnings emitted
7575
tests/ui/feature-gates/issue-43106-gating-of-stable.rs+14
......@@ -6,29 +6,43 @@
66
77#![stable()]
88//~^ ERROR stability attributes may not be used outside of the standard library
9//~| ERROR missing 'since'
10//~| ERROR missing 'feature'
911
1012#[stable()]
1113//~^ ERROR stability attributes may not be used outside of the standard library
14//~| ERROR missing 'since'
15//~| ERROR missing 'feature'
1216mod stable {
1317 mod inner {
1418 #![stable()]
1519 //~^ ERROR stability attributes may not be used outside of the standard library
20 //~| ERROR missing 'since'
21 //~| ERROR missing 'feature'
1622 }
1723
1824 #[stable()]
1925 //~^ ERROR stability attributes may not be used outside of the standard library
26 //~| ERROR missing 'since'
27 //~| ERROR missing 'feature'
2028 fn f() {}
2129
2230 #[stable()]
2331 //~^ ERROR stability attributes may not be used outside of the standard library
32 //~| ERROR missing 'since'
33 //~| ERROR missing 'feature'
2434 struct S;
2535
2636 #[stable()]
2737 //~^ ERROR stability attributes may not be used outside of the standard library
38 //~| ERROR missing 'since'
39 //~| ERROR missing 'feature'
2840 type T = S;
2941
3042 #[stable()]
3143 //~^ ERROR stability attributes may not be used outside of the standard library
44 //~| ERROR missing 'since'
45 //~| ERROR missing 'feature'
3246 impl S {}
3347}
3448
tests/ui/feature-gates/issue-43106-gating-of-stable.stderr+99-14
......@@ -1,45 +1,130 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/issue-43106-gating-of-stable.rs:7:1
33 |
44LL | #![stable()]
55 | ^^^^^^^^^^^^
66
7error[E0734]: stability attributes may not be used outside of the standard library
8 --> $DIR/issue-43106-gating-of-stable.rs:10:1
7error[E0546]: missing 'feature'
8 --> $DIR/issue-43106-gating-of-stable.rs:7:1
9 |
10LL | #![stable()]
11 | ^^^^^^^^^^^^
12
13error[E0542]: missing 'since'
14 --> $DIR/issue-43106-gating-of-stable.rs:7:1
15 |
16LL | #![stable()]
17 | ^^^^^^^^^^^^
18
19error[E0658]: stability attributes may not be used outside of the standard library
20 --> $DIR/issue-43106-gating-of-stable.rs:12:1
21 |
22LL | #[stable()]
23 | ^^^^^^^^^^^
24
25error[E0546]: missing 'feature'
26 --> $DIR/issue-43106-gating-of-stable.rs:12:1
27 |
28LL | #[stable()]
29 | ^^^^^^^^^^^
30
31error[E0542]: missing 'since'
32 --> $DIR/issue-43106-gating-of-stable.rs:12:1
933 |
1034LL | #[stable()]
1135 | ^^^^^^^^^^^
1236
13error[E0734]: stability attributes may not be used outside of the standard library
14 --> $DIR/issue-43106-gating-of-stable.rs:14:9
37error[E0658]: stability attributes may not be used outside of the standard library
38 --> $DIR/issue-43106-gating-of-stable.rs:18:9
39 |
40LL | #![stable()]
41 | ^^^^^^^^^^^^
42
43error[E0546]: missing 'feature'
44 --> $DIR/issue-43106-gating-of-stable.rs:18:9
1545 |
1646LL | #![stable()]
1747 | ^^^^^^^^^^^^
1848
19error[E0734]: stability attributes may not be used outside of the standard library
20 --> $DIR/issue-43106-gating-of-stable.rs:18:5
49error[E0542]: missing 'since'
50 --> $DIR/issue-43106-gating-of-stable.rs:18:9
51 |
52LL | #![stable()]
53 | ^^^^^^^^^^^^
54
55error[E0658]: stability attributes may not be used outside of the standard library
56 --> $DIR/issue-43106-gating-of-stable.rs:24:5
57 |
58LL | #[stable()]
59 | ^^^^^^^^^^^
60
61error[E0546]: missing 'feature'
62 --> $DIR/issue-43106-gating-of-stable.rs:24:5
2163 |
2264LL | #[stable()]
2365 | ^^^^^^^^^^^
2466
25error[E0734]: stability attributes may not be used outside of the standard library
26 --> $DIR/issue-43106-gating-of-stable.rs:22:5
67error[E0542]: missing 'since'
68 --> $DIR/issue-43106-gating-of-stable.rs:24:5
2769 |
2870LL | #[stable()]
2971 | ^^^^^^^^^^^
3072
31error[E0734]: stability attributes may not be used outside of the standard library
32 --> $DIR/issue-43106-gating-of-stable.rs:26:5
73error[E0658]: stability attributes may not be used outside of the standard library
74 --> $DIR/issue-43106-gating-of-stable.rs:30:5
75 |
76LL | #[stable()]
77 | ^^^^^^^^^^^
78
79error[E0546]: missing 'feature'
80 --> $DIR/issue-43106-gating-of-stable.rs:30:5
3381 |
3482LL | #[stable()]
3583 | ^^^^^^^^^^^
3684
37error[E0734]: stability attributes may not be used outside of the standard library
85error[E0542]: missing 'since'
3886 --> $DIR/issue-43106-gating-of-stable.rs:30:5
3987 |
4088LL | #[stable()]
4189 | ^^^^^^^^^^^
4290
43error: aborting due to 7 previous errors
91error[E0658]: stability attributes may not be used outside of the standard library
92 --> $DIR/issue-43106-gating-of-stable.rs:36:5
93 |
94LL | #[stable()]
95 | ^^^^^^^^^^^
96
97error[E0546]: missing 'feature'
98 --> $DIR/issue-43106-gating-of-stable.rs:36:5
99 |
100LL | #[stable()]
101 | ^^^^^^^^^^^
102
103error[E0542]: missing 'since'
104 --> $DIR/issue-43106-gating-of-stable.rs:36:5
105 |
106LL | #[stable()]
107 | ^^^^^^^^^^^
108
109error[E0658]: stability attributes may not be used outside of the standard library
110 --> $DIR/issue-43106-gating-of-stable.rs:42:5
111 |
112LL | #[stable()]
113 | ^^^^^^^^^^^
114
115error[E0546]: missing 'feature'
116 --> $DIR/issue-43106-gating-of-stable.rs:42:5
117 |
118LL | #[stable()]
119 | ^^^^^^^^^^^
120
121error[E0542]: missing 'since'
122 --> $DIR/issue-43106-gating-of-stable.rs:42:5
123 |
124LL | #[stable()]
125 | ^^^^^^^^^^^
126
127error: aborting due to 21 previous errors
44128
45For more information about this error, try `rustc --explain E0734`.
129Some errors have detailed explanations: E0542, E0546, E0658.
130For more information about an error, try `rustc --explain E0542`.
tests/ui/feature-gates/issue-43106-gating-of-unstable.rs+14
......@@ -6,29 +6,43 @@
66
77#![unstable()]
88//~^ ERROR stability attributes may not be used outside of the standard library
9//~| ERROR missing 'issue'
10//~| ERROR missing 'feature'
911
1012#[unstable()]
1113//~^ ERROR stability attributes may not be used outside of the standard library
14//~| ERROR missing 'issue'
15//~| ERROR missing 'feature'
1216mod unstable {
1317 mod inner {
1418 #![unstable()]
1519 //~^ ERROR stability attributes may not be used outside of the standard library
20 //~| ERROR missing 'issue'
21 //~| ERROR missing 'feature'
1622 }
1723
1824 #[unstable()]
1925 //~^ ERROR stability attributes may not be used outside of the standard library
26 //~| ERROR missing 'issue'
27 //~| ERROR missing 'feature'
2028 fn f() {}
2129
2230 #[unstable()]
2331 //~^ ERROR stability attributes may not be used outside of the standard library
32 //~| ERROR missing 'issue'
33 //~| ERROR missing 'feature'
2434 struct S;
2535
2636 #[unstable()]
2737 //~^ ERROR stability attributes may not be used outside of the standard library
38 //~| ERROR missing 'issue'
39 //~| ERROR missing 'feature'
2840 type T = S;
2941
3042 #[unstable()]
3143 //~^ ERROR stability attributes may not be used outside of the standard library
44 //~| ERROR missing 'issue'
45 //~| ERROR missing 'feature'
3246 impl S {}
3347}
3448
tests/ui/feature-gates/issue-43106-gating-of-unstable.stderr+99-14
......@@ -1,45 +1,130 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/issue-43106-gating-of-unstable.rs:7:1
33 |
44LL | #![unstable()]
55 | ^^^^^^^^^^^^^^
66
7error[E0734]: stability attributes may not be used outside of the standard library
8 --> $DIR/issue-43106-gating-of-unstable.rs:10:1
7error[E0546]: missing 'feature'
8 --> $DIR/issue-43106-gating-of-unstable.rs:7:1
9 |
10LL | #![unstable()]
11 | ^^^^^^^^^^^^^^
12
13error[E0547]: missing 'issue'
14 --> $DIR/issue-43106-gating-of-unstable.rs:7:1
15 |
16LL | #![unstable()]
17 | ^^^^^^^^^^^^^^
18
19error[E0658]: stability attributes may not be used outside of the standard library
20 --> $DIR/issue-43106-gating-of-unstable.rs:12:1
21 |
22LL | #[unstable()]
23 | ^^^^^^^^^^^^^
24
25error[E0546]: missing 'feature'
26 --> $DIR/issue-43106-gating-of-unstable.rs:12:1
27 |
28LL | #[unstable()]
29 | ^^^^^^^^^^^^^
30
31error[E0547]: missing 'issue'
32 --> $DIR/issue-43106-gating-of-unstable.rs:12:1
933 |
1034LL | #[unstable()]
1135 | ^^^^^^^^^^^^^
1236
13error[E0734]: stability attributes may not be used outside of the standard library
14 --> $DIR/issue-43106-gating-of-unstable.rs:14:9
37error[E0658]: stability attributes may not be used outside of the standard library
38 --> $DIR/issue-43106-gating-of-unstable.rs:18:9
39 |
40LL | #![unstable()]
41 | ^^^^^^^^^^^^^^
42
43error[E0546]: missing 'feature'
44 --> $DIR/issue-43106-gating-of-unstable.rs:18:9
1545 |
1646LL | #![unstable()]
1747 | ^^^^^^^^^^^^^^
1848
19error[E0734]: stability attributes may not be used outside of the standard library
20 --> $DIR/issue-43106-gating-of-unstable.rs:18:5
49error[E0547]: missing 'issue'
50 --> $DIR/issue-43106-gating-of-unstable.rs:18:9
51 |
52LL | #![unstable()]
53 | ^^^^^^^^^^^^^^
54
55error[E0658]: stability attributes may not be used outside of the standard library
56 --> $DIR/issue-43106-gating-of-unstable.rs:24:5
57 |
58LL | #[unstable()]
59 | ^^^^^^^^^^^^^
60
61error[E0546]: missing 'feature'
62 --> $DIR/issue-43106-gating-of-unstable.rs:24:5
2163 |
2264LL | #[unstable()]
2365 | ^^^^^^^^^^^^^
2466
25error[E0734]: stability attributes may not be used outside of the standard library
26 --> $DIR/issue-43106-gating-of-unstable.rs:22:5
67error[E0547]: missing 'issue'
68 --> $DIR/issue-43106-gating-of-unstable.rs:24:5
2769 |
2870LL | #[unstable()]
2971 | ^^^^^^^^^^^^^
3072
31error[E0734]: stability attributes may not be used outside of the standard library
32 --> $DIR/issue-43106-gating-of-unstable.rs:26:5
73error[E0658]: stability attributes may not be used outside of the standard library
74 --> $DIR/issue-43106-gating-of-unstable.rs:30:5
75 |
76LL | #[unstable()]
77 | ^^^^^^^^^^^^^
78
79error[E0546]: missing 'feature'
80 --> $DIR/issue-43106-gating-of-unstable.rs:30:5
3381 |
3482LL | #[unstable()]
3583 | ^^^^^^^^^^^^^
3684
37error[E0734]: stability attributes may not be used outside of the standard library
85error[E0547]: missing 'issue'
3886 --> $DIR/issue-43106-gating-of-unstable.rs:30:5
3987 |
4088LL | #[unstable()]
4189 | ^^^^^^^^^^^^^
4290
43error: aborting due to 7 previous errors
91error[E0658]: stability attributes may not be used outside of the standard library
92 --> $DIR/issue-43106-gating-of-unstable.rs:36:5
93 |
94LL | #[unstable()]
95 | ^^^^^^^^^^^^^
96
97error[E0546]: missing 'feature'
98 --> $DIR/issue-43106-gating-of-unstable.rs:36:5
99 |
100LL | #[unstable()]
101 | ^^^^^^^^^^^^^
102
103error[E0547]: missing 'issue'
104 --> $DIR/issue-43106-gating-of-unstable.rs:36:5
105 |
106LL | #[unstable()]
107 | ^^^^^^^^^^^^^
108
109error[E0658]: stability attributes may not be used outside of the standard library
110 --> $DIR/issue-43106-gating-of-unstable.rs:42:5
111 |
112LL | #[unstable()]
113 | ^^^^^^^^^^^^^
114
115error[E0546]: missing 'feature'
116 --> $DIR/issue-43106-gating-of-unstable.rs:42:5
117 |
118LL | #[unstable()]
119 | ^^^^^^^^^^^^^
120
121error[E0547]: missing 'issue'
122 --> $DIR/issue-43106-gating-of-unstable.rs:42:5
123 |
124LL | #[unstable()]
125 | ^^^^^^^^^^^^^
126
127error: aborting due to 21 previous errors
44128
45For more information about this error, try `rustc --explain E0734`.
129Some errors have detailed explanations: E0546, E0547, E0658.
130For more information about an error, try `rustc --explain E0546`.
tests/ui/internal/internal-unstable.stderr+2-2
......@@ -65,8 +65,8 @@ warning: `#[allow_internal_unstable]` attribute cannot be used on struct fields
6565LL | #[allow_internal_unstable]
6666 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
6767 |
68 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6968 = help: `#[allow_internal_unstable]` can be applied to functions and macro defs
69 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7070 = note: requested on the command line with `-W unused-attributes`
7171
7272warning: `#[allow_internal_unstable]` attribute cannot be used on match arms
......@@ -75,8 +75,8 @@ warning: `#[allow_internal_unstable]` attribute cannot be used on match arms
7575LL | #[allow_internal_unstable]
7676 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
7777 |
78 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7978 = help: `#[allow_internal_unstable]` can be applied to functions and macro defs
79 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8080
8181error: aborting due to 7 previous errors; 2 warnings emitted
8282
tests/ui/lang-items/issue-83471.stderr+19-19
......@@ -4,6 +4,25 @@ error[E0573]: expected type, found built-in attribute `export_name`
44LL | fn call(export_name);
55 | ^^^^^^^^^^^ not a type
66
7warning: anonymous parameters are deprecated and will be removed in the next edition
8 --> $DIR/issue-83471.rs:24:13
9 |
10LL | fn call(export_name);
11 | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name`
12 |
13 = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
14 = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2018/trait-fn-parameters.html>
15 = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default
16
17error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument
18 --> $DIR/issue-83471.rs:20:1
19 |
20LL | #[lang = "fn"]
21 | ^^^^^^^^^^^^^^
22...
23LL | trait Fn {
24 | - this trait has 0 generic arguments
25
726error[E0658]: lang items are subject to change
827 --> $DIR/issue-83471.rs:8:1
928 |
......@@ -40,25 +59,6 @@ LL | #[lang = "fn"]
4059 = help: add `#![feature(lang_items)]` to the crate attributes to enable
4160 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4261
43warning: anonymous parameters are deprecated and will be removed in the next edition
44 --> $DIR/issue-83471.rs:24:13
45 |
46LL | fn call(export_name);
47 | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name`
48 |
49 = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
50 = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2018/trait-fn-parameters.html>
51 = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default
52
53error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument
54 --> $DIR/issue-83471.rs:20:1
55 |
56LL | #[lang = "fn"]
57 | ^^^^^^^^^^^^^^
58...
59LL | trait Fn {
60 | - this trait has 0 generic arguments
61
6262error[E0425]: cannot find function `a` in this scope
6363 --> $DIR/issue-83471.rs:30:5
6464 |
tests/ui/lint/fn_must_use.stderr+1-1
......@@ -4,8 +4,8 @@ warning: `#[must_use]` attribute cannot be used on trait methods in impl blocks
44LL | #[must_use]
55 | ^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, and traits
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99 = note: requested on the command line with `-W unused-attributes`
1010
1111warning: unused return value of `need_to_use_this_value` that must be used
tests/ui/lint/inert-attr-macro.stderr+2-2
......@@ -4,8 +4,8 @@ warning: `#[inline]` attribute cannot be used on macro calls
44LL | #[inline] foo!();
55 | ^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[inline]` can only be applied to functions
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/inert-attr-macro.rs:3:9
1111 |
......@@ -31,8 +31,8 @@ warning: `#[inline]` attribute cannot be used on macro calls
3131LL | #[allow(warnings)] #[inline] foo!();
3232 | ^^^^^^^^^
3333 |
34 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3534 = help: `#[inline]` can only be applied to functions
35 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3636
3737warning: 3 warnings emitted
3838
tests/ui/lint/inline-trait-and-foreign-items.stderr+2-2
......@@ -44,8 +44,8 @@ warning: `#[inline]` attribute cannot be used on associated consts
4444LL | #[inline]
4545 | ^^^^^^^^^
4646 |
47 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4847 = help: `#[inline]` can only be applied to functions
48 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4949note: the lint level is defined here
5050 --> $DIR/inline-trait-and-foreign-items.rs:4:9
5151 |
......@@ -58,8 +58,8 @@ warning: `#[inline]` attribute cannot be used on associated consts
5858LL | #[inline]
5959 | ^^^^^^^^^
6060 |
61 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6261 = help: `#[inline]` can only be applied to functions
62 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6363
6464error: unconstrained opaque type
6565 --> $DIR/inline-trait-and-foreign-items.rs:26:14
tests/ui/lint/unused/unused-attr-macro-rules.stderr+2-2
......@@ -4,8 +4,8 @@ error: `#[macro_use]` attribute cannot be used on macro defs
44LL | #[macro_use]
55 | ^^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[macro_use]` can be applied to crates, extern crates, and modules
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/unused-attr-macro-rules.rs:1:9
1111 |
......@@ -18,8 +18,8 @@ error: `#[path]` attribute cannot be used on macro defs
1818LL | #[path="foo"]
1919 | ^^^^^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[path]` can only be applied to modules
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
2525 --> $DIR/unused-attr-macro-rules.rs:11:1
tests/ui/lint/unused/unused_attributes-must_use.stderr+22-22
......@@ -4,8 +4,8 @@ error: `#[must_use]` attribute cannot be used on macro calls
44LL | #[must_use]
55 | ^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[must_use]` can be applied to data types, functions, and traits
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/unused_attributes-must_use.rs:4:9
1111 |
......@@ -18,8 +18,8 @@ error: `#[must_use]` attribute cannot be used on extern crates
1818LL | #[must_use]
1919 | ^^^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[must_use]` can be applied to data types, functions, and traits
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424error: `#[must_use]` attribute cannot be used on modules
2525 --> $DIR/unused_attributes-must_use.rs:11:1
......@@ -27,8 +27,8 @@ error: `#[must_use]` attribute cannot be used on modules
2727LL | #[must_use]
2828 | ^^^^^^^^^^^
2929 |
30 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3130 = help: `#[must_use]` can be applied to data types, functions, and traits
31 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3232
3333error: `#[must_use]` attribute cannot be used on use statements
3434 --> $DIR/unused_attributes-must_use.rs:15:1
......@@ -36,8 +36,8 @@ error: `#[must_use]` attribute cannot be used on use statements
3636LL | #[must_use]
3737 | ^^^^^^^^^^^
3838 |
39 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4039 = help: `#[must_use]` can be applied to data types, functions, and traits
40 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4141
4242error: `#[must_use]` attribute cannot be used on constants
4343 --> $DIR/unused_attributes-must_use.rs:19:1
......@@ -45,8 +45,8 @@ error: `#[must_use]` attribute cannot be used on constants
4545LL | #[must_use]
4646 | ^^^^^^^^^^^
4747 |
48 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4948 = help: `#[must_use]` can be applied to data types, functions, and traits
49 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5050
5151error: `#[must_use]` attribute cannot be used on statics
5252 --> $DIR/unused_attributes-must_use.rs:22:1
......@@ -54,8 +54,8 @@ error: `#[must_use]` attribute cannot be used on statics
5454LL | #[must_use]
5555 | ^^^^^^^^^^^
5656 |
57 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5857 = help: `#[must_use]` can be applied to data types, functions, and traits
58 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5959
6060error: `#[must_use]` attribute cannot be used on inherent impl blocks
6161 --> $DIR/unused_attributes-must_use.rs:40:1
......@@ -63,8 +63,8 @@ error: `#[must_use]` attribute cannot be used on inherent impl blocks
6363LL | #[must_use]
6464 | ^^^^^^^^^^^
6565 |
66 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6766 = help: `#[must_use]` can be applied to data types, functions, and traits
67 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6868
6969error: `#[must_use]` attribute cannot be used on foreign modules
7070 --> $DIR/unused_attributes-must_use.rs:55:1
......@@ -72,8 +72,8 @@ error: `#[must_use]` attribute cannot be used on foreign modules
7272LL | #[must_use]
7373 | ^^^^^^^^^^^
7474 |
75 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7675 = help: `#[must_use]` can be applied to data types, functions, and traits
76 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7777
7878error: `#[must_use]` attribute cannot be used on foreign statics
7979 --> $DIR/unused_attributes-must_use.rs:59:5
......@@ -81,8 +81,8 @@ error: `#[must_use]` attribute cannot be used on foreign statics
8181LL | #[must_use]
8282 | ^^^^^^^^^^^
8383 |
84 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8584 = help: `#[must_use]` can be applied to data types, functions, and traits
85 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8686
8787error: `#[must_use]` attribute cannot be used on type aliases
8888 --> $DIR/unused_attributes-must_use.rs:73:1
......@@ -90,8 +90,8 @@ error: `#[must_use]` attribute cannot be used on type aliases
9090LL | #[must_use]
9191 | ^^^^^^^^^^^
9292 |
93 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9493 = help: `#[must_use]` can be applied to data types, functions, and traits
94 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9595
9696error: `#[must_use]` attribute cannot be used on type parameters
9797 --> $DIR/unused_attributes-must_use.rs:77:8
......@@ -99,8 +99,8 @@ error: `#[must_use]` attribute cannot be used on type parameters
9999LL | fn qux<#[must_use] T>(_: T) {}
100100 | ^^^^^^^^^^^
101101 |
102 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
103102 = help: `#[must_use]` can be applied to data types, functions, and traits
103 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
104104
105105error: `#[must_use]` attribute cannot be used on associated consts
106106 --> $DIR/unused_attributes-must_use.rs:82:5
......@@ -108,8 +108,8 @@ error: `#[must_use]` attribute cannot be used on associated consts
108108LL | #[must_use]
109109 | ^^^^^^^^^^^
110110 |
111 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
112111 = help: `#[must_use]` can be applied to data types, functions, and traits
112 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
113113
114114error: `#[must_use]` attribute cannot be used on associated types
115115 --> $DIR/unused_attributes-must_use.rs:85:5
......@@ -117,8 +117,8 @@ error: `#[must_use]` attribute cannot be used on associated types
117117LL | #[must_use]
118118 | ^^^^^^^^^^^
119119 |
120 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
121120 = help: `#[must_use]` can be applied to data types, functions, and traits
121 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
122122
123123error: `#[must_use]` attribute cannot be used on trait impl blocks
124124 --> $DIR/unused_attributes-must_use.rs:95:1
......@@ -126,8 +126,8 @@ error: `#[must_use]` attribute cannot be used on trait impl blocks
126126LL | #[must_use]
127127 | ^^^^^^^^^^^
128128 |
129 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
130129 = help: `#[must_use]` can be applied to data types, functions, and traits
130 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
131131
132132error: `#[must_use]` attribute cannot be used on trait methods in impl blocks
133133 --> $DIR/unused_attributes-must_use.rs:100:5
......@@ -135,8 +135,8 @@ error: `#[must_use]` attribute cannot be used on trait methods in impl blocks
135135LL | #[must_use]
136136 | ^^^^^^^^^^^
137137 |
138 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
139138 = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, and traits
139 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
140140
141141error: `#[must_use]` attribute cannot be used on trait aliases
142142 --> $DIR/unused_attributes-must_use.rs:107:1
......@@ -144,8 +144,8 @@ error: `#[must_use]` attribute cannot be used on trait aliases
144144LL | #[must_use]
145145 | ^^^^^^^^^^^
146146 |
147 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
148147 = help: `#[must_use]` can be applied to data types, functions, and traits
148 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
149149
150150error: `#[must_use]` attribute cannot be used on macro defs
151151 --> $DIR/unused_attributes-must_use.rs:111:1
......@@ -153,8 +153,8 @@ error: `#[must_use]` attribute cannot be used on macro defs
153153LL | #[must_use]
154154 | ^^^^^^^^^^^
155155 |
156 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
157156 = help: `#[must_use]` can be applied to data types, functions, and traits
157 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
158158
159159error: `#[must_use]` attribute cannot be used on statements
160160 --> $DIR/unused_attributes-must_use.rs:120:5
......@@ -162,8 +162,8 @@ error: `#[must_use]` attribute cannot be used on statements
162162LL | #[must_use]
163163 | ^^^^^^^^^^^
164164 |
165 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
166165 = help: `#[must_use]` can be applied to data types, functions, and traits
166 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
167167
168168error: `#[must_use]` attribute cannot be used on closures
169169 --> $DIR/unused_attributes-must_use.rs:125:13
......@@ -171,8 +171,8 @@ error: `#[must_use]` attribute cannot be used on closures
171171LL | let x = #[must_use]
172172 | ^^^^^^^^^^^
173173 |
174 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
175174 = help: `#[must_use]` can be applied to data types, foreign functions, functions, methods, and traits
175 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
176176
177177error: `#[must_use]` attribute cannot be used on match arms
178178 --> $DIR/unused_attributes-must_use.rs:148:9
......@@ -180,8 +180,8 @@ error: `#[must_use]` attribute cannot be used on match arms
180180LL | #[must_use]
181181 | ^^^^^^^^^^^
182182 |
183 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
184183 = help: `#[must_use]` can be applied to data types, functions, and traits
184 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
185185
186186error: `#[must_use]` attribute cannot be used on struct fields
187187 --> $DIR/unused_attributes-must_use.rs:157:28
......@@ -189,8 +189,8 @@ error: `#[must_use]` attribute cannot be used on struct fields
189189LL | let s = PatternField { #[must_use] foo: 123 };
190190 | ^^^^^^^^^^^
191191 |
192 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
193192 = help: `#[must_use]` can be applied to data types, functions, and traits
193 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
194194
195195error: `#[must_use]` attribute cannot be used on pattern fields
196196 --> $DIR/unused_attributes-must_use.rs:159:24
......@@ -198,8 +198,8 @@ error: `#[must_use]` attribute cannot be used on pattern fields
198198LL | let PatternField { #[must_use] foo } = s;
199199 | ^^^^^^^^^^^
200200 |
201 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
202201 = help: `#[must_use]` can be applied to data types, functions, and traits
202 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
203203
204204error: unused `X` that must be used
205205 --> $DIR/unused_attributes-must_use.rs:130:5
tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr+2-2
......@@ -4,8 +4,8 @@ error: `#[inline]` attribute cannot be used on required trait methods
44LL | #[inline]
55 | ^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[inline]` can be applied to closures, functions, inherent methods, provided trait methods, and trait methods in impl blocks
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99note: the lint level is defined here
1010 --> $DIR/warn-unused-inline-on-fn-prototypes.rs:1:9
1111 |
......@@ -18,8 +18,8 @@ error: `#[inline]` attribute cannot be used on foreign functions
1818LL | #[inline]
1919 | ^^^^^^^^^
2020 |
21 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2221 = help: `#[inline]` can be applied to closures, functions, and methods
22 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
2424error: aborting due to 2 previous errors
2525
tests/ui/privacy/effective-visibilities-macro-2.rs created+26
......@@ -0,0 +1,26 @@
1// Make sure that `Placeholder` will be marked as reachable without `use crate::ty` like in
2// `effective-visibility-macro.rs` test.
3
4#![feature(rustc_attrs, decl_macro)]
5
6pub mod ty {
7 pub mod print {
8 mod pretty {
9 #[rustc_effective_visibility]
10 pub macro with_no_queries() {}
11 //~^ ERROR Direct: pub(in crate::ty::print), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
12 }
13
14 pub use self::pretty::with_no_queries;
15 }
16
17 #[rustc_effective_visibility]
18 mod sty {
19 //~^ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
20 #[rustc_effective_visibility]
21 pub type Placeholder = ();
22 //~^ ERROR Direct: pub(in crate::ty), Reexported: pub(in crate::ty), Reachable: pub, ReachableThroughImplTrait: pub
23 }
24}
25
26fn main() {}
tests/ui/privacy/effective-visibilities-macro-2.stderr created+20
......@@ -0,0 +1,20 @@
1error: Direct: pub(in crate::ty::print), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
2 --> $DIR/effective-visibilities-macro-2.rs:10:13
3 |
4LL | pub macro with_no_queries() {}
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^
6
7error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
8 --> $DIR/effective-visibilities-macro-2.rs:18:5
9 |
10LL | mod sty {
11 | ^^^^^^^
12
13error: Direct: pub(in crate::ty), Reexported: pub(in crate::ty), Reachable: pub, ReachableThroughImplTrait: pub
14 --> $DIR/effective-visibilities-macro-2.rs:21:9
15 |
16LL | pub type Placeholder = ();
17 | ^^^^^^^^^^^^^^^^^^^^
18
19error: aborting due to 3 previous errors
20
tests/ui/privacy/effective-visibilities-macro.rs created+25
......@@ -0,0 +1,25 @@
1#![feature(rustc_attrs, decl_macro)]
2
3pub mod ty {
4 pub mod print {
5 mod pretty {
6 #[rustc_effective_visibility]
7 pub macro with_no_queries() {}
8 //~^ ERROR Direct: pub(in crate::ty::print), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
9 }
10
11 pub use self::pretty::with_no_queries;
12 // Start visiting outer modules during macro-reachable phase.
13 use crate::ty;
14 }
15
16 #[rustc_effective_visibility]
17 mod sty {
18 //~^ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
19 #[rustc_effective_visibility]
20 pub type Placeholder = ();
21 //~^ ERROR Direct: pub(in crate::ty), Reexported: pub(in crate::ty), Reachable: pub, ReachableThroughImplTrait: pub
22 }
23}
24
25fn main() {}
tests/ui/privacy/effective-visibilities-macro.stderr created+20
......@@ -0,0 +1,20 @@
1error: Direct: pub(in crate::ty::print), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
2 --> $DIR/effective-visibilities-macro.rs:7:13
3 |
4LL | pub macro with_no_queries() {}
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^
6
7error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
8 --> $DIR/effective-visibilities-macro.rs:17:5
9 |
10LL | mod sty {
11 | ^^^^^^^
12
13error: Direct: pub(in crate::ty), Reexported: pub(in crate::ty), Reachable: pub, ReachableThroughImplTrait: pub
14 --> $DIR/effective-visibilities-macro.rs:20:9
15 |
16LL | pub type Placeholder = ();
17 | ^^^^^^^^^^^^^^^^^^^^
18
19error: aborting due to 3 previous errors
20
tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.stderr+1-1
......@@ -4,8 +4,8 @@ warning: `#[track_caller]` attribute cannot be used on macro defs
44LL | #[track_caller]
55 | ^^^^^^^^^^^^^^^
66 |
7 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
87 = help: `#[track_caller]` can only be applied to functions
8 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
99 = note: requested on the command line with `-W unused-attributes`
1010
1111warning: 1 warning emitted
tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr+16-16
......@@ -388,8 +388,8 @@ warning: `#[must_use]` attribute cannot be used on function params
388388LL | #[must_use]
389389 | ^^^^^^^^^^^
390390 |
391 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
392391 = help: `#[must_use]` can be applied to data types, functions, and traits
392 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
393393 = note: requested on the command line with `-W unused-attributes`
394394
395395warning: `#[no_mangle]` attribute cannot be used on function params
......@@ -398,8 +398,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
398398LL | #[no_mangle] b: i32,
399399 | ^^^^^^^^^^^^
400400 |
401 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
402401 = help: `#[no_mangle]` can be applied to functions and statics
402 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
403403
404404warning: `#[must_use]` attribute cannot be used on function params
405405 --> $DIR/param-attrs-builtin-attrs.rs:64:9
......@@ -407,8 +407,8 @@ warning: `#[must_use]` attribute cannot be used on function params
407407LL | #[must_use]
408408 | ^^^^^^^^^^^
409409 |
410 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
411410 = help: `#[must_use]` can be applied to data types, functions, and traits
411 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
412412
413413warning: `#[no_mangle]` attribute cannot be used on function params
414414 --> $DIR/param-attrs-builtin-attrs.rs:70:9
......@@ -416,8 +416,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
416416LL | #[no_mangle] b: i32,
417417 | ^^^^^^^^^^^^
418418 |
419 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
420419 = help: `#[no_mangle]` can be applied to functions and statics
420 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
421421
422422warning: `#[must_use]` attribute cannot be used on function params
423423 --> $DIR/param-attrs-builtin-attrs.rs:83:9
......@@ -425,8 +425,8 @@ warning: `#[must_use]` attribute cannot be used on function params
425425LL | #[must_use]
426426 | ^^^^^^^^^^^
427427 |
428 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
429428 = help: `#[must_use]` can be applied to data types, functions, and traits
429 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
430430
431431warning: `#[no_mangle]` attribute cannot be used on function params
432432 --> $DIR/param-attrs-builtin-attrs.rs:89:9
......@@ -434,8 +434,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
434434LL | #[no_mangle] b: i32,
435435 | ^^^^^^^^^^^^
436436 |
437 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
438437 = help: `#[no_mangle]` can be applied to functions and statics
438 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
439439
440440warning: `#[must_use]` attribute cannot be used on function params
441441 --> $DIR/param-attrs-builtin-attrs.rs:108:9
......@@ -443,8 +443,8 @@ warning: `#[must_use]` attribute cannot be used on function params
443443LL | #[must_use]
444444 | ^^^^^^^^^^^
445445 |
446 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
447446 = help: `#[must_use]` can be applied to data types, functions, and traits
447 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
448448
449449warning: `#[no_mangle]` attribute cannot be used on function params
450450 --> $DIR/param-attrs-builtin-attrs.rs:114:9
......@@ -452,8 +452,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
452452LL | #[no_mangle] b: i32,
453453 | ^^^^^^^^^^^^
454454 |
455 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
456455 = help: `#[no_mangle]` can be applied to functions and statics
456 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
457457
458458warning: `#[must_use]` attribute cannot be used on function params
459459 --> $DIR/param-attrs-builtin-attrs.rs:131:9
......@@ -461,8 +461,8 @@ warning: `#[must_use]` attribute cannot be used on function params
461461LL | #[must_use]
462462 | ^^^^^^^^^^^
463463 |
464 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
465464 = help: `#[must_use]` can be applied to data types, functions, and traits
465 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
466466
467467warning: `#[no_mangle]` attribute cannot be used on function params
468468 --> $DIR/param-attrs-builtin-attrs.rs:137:9
......@@ -470,8 +470,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
470470LL | #[no_mangle] b: i32,
471471 | ^^^^^^^^^^^^
472472 |
473 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
474473 = help: `#[no_mangle]` can be applied to functions and statics
474 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
475475
476476warning: `#[must_use]` attribute cannot be used on function params
477477 --> $DIR/param-attrs-builtin-attrs.rs:150:9
......@@ -479,8 +479,8 @@ warning: `#[must_use]` attribute cannot be used on function params
479479LL | #[must_use]
480480 | ^^^^^^^^^^^
481481 |
482 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
483482 = help: `#[must_use]` can be applied to data types, functions, and traits
483 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
484484
485485warning: `#[no_mangle]` attribute cannot be used on function params
486486 --> $DIR/param-attrs-builtin-attrs.rs:156:9
......@@ -488,8 +488,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
488488LL | #[no_mangle] b: i32,
489489 | ^^^^^^^^^^^^
490490 |
491 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
492491 = help: `#[no_mangle]` can be applied to functions and statics
492 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
493493
494494warning: `#[must_use]` attribute cannot be used on function params
495495 --> $DIR/param-attrs-builtin-attrs.rs:174:9
......@@ -497,8 +497,8 @@ warning: `#[must_use]` attribute cannot be used on function params
497497LL | #[must_use]
498498 | ^^^^^^^^^^^
499499 |
500 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
501500 = help: `#[must_use]` can be applied to data types, functions, and traits
501 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
502502
503503warning: `#[no_mangle]` attribute cannot be used on function params
504504 --> $DIR/param-attrs-builtin-attrs.rs:180:9
......@@ -506,8 +506,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
506506LL | #[no_mangle] b: i32,
507507 | ^^^^^^^^^^^^
508508 |
509 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
510509 = help: `#[no_mangle]` can be applied to functions and statics
510 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
511511
512512warning: `#[must_use]` attribute cannot be used on function params
513513 --> $DIR/param-attrs-builtin-attrs.rs:195:9
......@@ -515,8 +515,8 @@ warning: `#[must_use]` attribute cannot be used on function params
515515LL | #[must_use]
516516 | ^^^^^^^^^^^
517517 |
518 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
519518 = help: `#[must_use]` can be applied to data types, functions, and traits
519 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
520520
521521warning: `#[no_mangle]` attribute cannot be used on function params
522522 --> $DIR/param-attrs-builtin-attrs.rs:201:9
......@@ -524,8 +524,8 @@ warning: `#[no_mangle]` attribute cannot be used on function params
524524LL | #[no_mangle] b: i32
525525 | ^^^^^^^^^^^^
526526 |
527 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
528527 = help: `#[no_mangle]` can be applied to functions and statics
528 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
529529
530530error: aborting due to 64 previous errors; 16 warnings emitted
531531
tests/ui/stability-attribute/issue-106589.stderr+3-3
......@@ -1,10 +1,10 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/issue-106589.rs:3:1
33 |
44LL | #![stable(feature = "foo", since = "1.0.0")]
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
7error[E0734]: stability attributes may not be used outside of the standard library
7error[E0658]: stability attributes may not be used outside of the standard library
88 --> $DIR/issue-106589.rs:6:1
99 |
1010LL | #[unstable(feature = "foo", issue = "none")]
......@@ -12,4 +12,4 @@ LL | #[unstable(feature = "foo", issue = "none")]
1212
1313error: aborting due to 2 previous errors
1414
15For more information about this error, try `rustc --explain E0734`.
15For more information about this error, try `rustc --explain E0658`.
tests/ui/stability-attribute/stability-attribute-non-staged-force-unstable.rs+8-2
......@@ -1,5 +1,11 @@
11//@ compile-flags:-Zforce-unstable-if-unmarked
22
3#[unstable()] //~ ERROR: stability attributes may not be used
4#[stable()] //~ ERROR: stability attributes may not be used
3#[unstable()]
4//~^ ERROR stability attributes may not be used
5//~| ERROR missing 'feature'
6//~| ERROR missing 'issue'
7#[stable()]
8//~^ ERROR stability attributes may not be used
9//~| ERROR missing 'feature'
10//~| ERROR missing 'since'
511fn main() {}
tests/ui/stability-attribute/stability-attribute-non-staged-force-unstable.stderr+30-5
......@@ -1,15 +1,40 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/stability-attribute-non-staged-force-unstable.rs:3:1
33 |
44LL | #[unstable()]
55 | ^^^^^^^^^^^^^
66
7error[E0734]: stability attributes may not be used outside of the standard library
8 --> $DIR/stability-attribute-non-staged-force-unstable.rs:4:1
7error[E0546]: missing 'feature'
8 --> $DIR/stability-attribute-non-staged-force-unstable.rs:3:1
9 |
10LL | #[unstable()]
11 | ^^^^^^^^^^^^^
12
13error[E0547]: missing 'issue'
14 --> $DIR/stability-attribute-non-staged-force-unstable.rs:3:1
15 |
16LL | #[unstable()]
17 | ^^^^^^^^^^^^^
18
19error[E0658]: stability attributes may not be used outside of the standard library
20 --> $DIR/stability-attribute-non-staged-force-unstable.rs:7:1
21 |
22LL | #[stable()]
23 | ^^^^^^^^^^^
24
25error[E0546]: missing 'feature'
26 --> $DIR/stability-attribute-non-staged-force-unstable.rs:7:1
27 |
28LL | #[stable()]
29 | ^^^^^^^^^^^
30
31error[E0542]: missing 'since'
32 --> $DIR/stability-attribute-non-staged-force-unstable.rs:7:1
933 |
1034LL | #[stable()]
1135 | ^^^^^^^^^^^
1236
13error: aborting due to 2 previous errors
37error: aborting due to 6 previous errors
1438
15For more information about this error, try `rustc --explain E0734`.
39Some errors have detailed explanations: E0542, E0546, E0547, E0658.
40For more information about an error, try `rustc --explain E0542`.
tests/ui/stability-attribute/stability-attribute-non-staged.rs+8-2
......@@ -1,3 +1,9 @@
1#[unstable()] //~ ERROR: stability attributes may not be used
2#[stable()] //~ ERROR: stability attributes may not be used
1#[unstable()]
2//~^ ERROR: stability attributes may not be used
3//~| ERROR missing 'feature'
4//~| ERROR missing 'issue'
5#[stable()]
6//~^ ERROR: stability attributes may not be used
7//~| ERROR missing 'feature'
8//~| ERROR missing 'since'
39fn main() {}
tests/ui/stability-attribute/stability-attribute-non-staged.stderr+30-5
......@@ -1,15 +1,40 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/stability-attribute-non-staged.rs:1:1
33 |
44LL | #[unstable()]
55 | ^^^^^^^^^^^^^
66
7error[E0734]: stability attributes may not be used outside of the standard library
8 --> $DIR/stability-attribute-non-staged.rs:2:1
7error[E0546]: missing 'feature'
8 --> $DIR/stability-attribute-non-staged.rs:1:1
9 |
10LL | #[unstable()]
11 | ^^^^^^^^^^^^^
12
13error[E0547]: missing 'issue'
14 --> $DIR/stability-attribute-non-staged.rs:1:1
15 |
16LL | #[unstable()]
17 | ^^^^^^^^^^^^^
18
19error[E0658]: stability attributes may not be used outside of the standard library
20 --> $DIR/stability-attribute-non-staged.rs:5:1
21 |
22LL | #[stable()]
23 | ^^^^^^^^^^^
24
25error[E0546]: missing 'feature'
26 --> $DIR/stability-attribute-non-staged.rs:5:1
27 |
28LL | #[stable()]
29 | ^^^^^^^^^^^
30
31error[E0542]: missing 'since'
32 --> $DIR/stability-attribute-non-staged.rs:5:1
933 |
1034LL | #[stable()]
1135 | ^^^^^^^^^^^
1236
13error: aborting due to 2 previous errors
37error: aborting due to 6 previous errors
1438
15For more information about this error, try `rustc --explain E0734`.
39Some errors have detailed explanations: E0542, E0546, E0547, E0658.
40For more information about an error, try `rustc --explain E0542`.
tests/ui/tool-attributes/diagnostic_item.rs+1
......@@ -1,5 +1,6 @@
11#[rustc_diagnostic_item = "foomp"]
22//~^ ERROR use of an internal attribute [E0658]
3//~| NOTE the `#[rustc_diagnostic_item]` attribute is an internal implementation detail that will never be stable
34//~| NOTE the `#[rustc_diagnostic_item]` attribute allows the compiler to reference types from the standard library for diagnostic purposes
45struct Foomp;
56fn main() {}
tests/ui/tool-attributes/diagnostic_item.stderr+1
......@@ -5,6 +5,7 @@ LL | #[rustc_diagnostic_item = "foomp"]
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66 |
77 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
8 = note: the `#[rustc_diagnostic_item]` attribute is an internal implementation detail that will never be stable
89 = note: the `#[rustc_diagnostic_item]` attribute allows the compiler to reference types from the standard library for diagnostic purposes
910
1011error: aborting due to 1 previous error
tests/ui/traits/unhandled-crate-mod-issue-144888.rs created+34
......@@ -0,0 +1,34 @@
1// Regression test for <https://github.com/rust-lang/rust/issues/144888>.
2// This used to ICE with `unhandled node Crate(Mod)`.
3
4trait Super {
5 type Assoc;
6}
7
8impl dyn Foo<()> {}
9
10trait Foo<T>: Super<Assoc = T>
11//~^ ERROR type mismatch resolving
12//~| ERROR the size for values of type `Self` cannot be known at compilation time
13where
14 <Self as Mirror>::Assoc: Clone,
15 //~^ ERROR type mismatch resolving
16 //~| ERROR the size for values of type `Self` cannot be known at compilation time
17 //~| ERROR type mismatch resolving
18 //~| ERROR the size for values of type `Self` cannot be known at compilation time
19{
20 fn transmute(&self) {}
21 //~^ ERROR type mismatch resolving
22 //~| ERROR the size for values of type `Self` cannot be known at compilation time
23 //~| ERROR type mismatch resolving
24 //~| ERROR the size for values of type `Self` cannot be known at compilation time
25}
26
27trait Mirror {
28 type Assoc;
29}
30
31impl<T: Super<Assoc = ()>> Mirror for T {}
32//~^ ERROR not all trait items implemented
33
34fn main() {}
tests/ui/traits/unhandled-crate-mod-issue-144888.stderr created+189
......@@ -0,0 +1,189 @@
1error[E0271]: type mismatch resolving `<Self as Super>::Assoc == ()`
2 --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5
3 |
4LL | fn transmute(&self) {}
5 | ^^^^^^^^^^^^^^^^^^^ expected `()`, found type parameter `T`
6 |
7 = note: expected unit type `()`
8 found type parameter `T`
9note: required for `Self` to implement `Mirror`
10 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
11 |
12LL | impl<T: Super<Assoc = ()>> Mirror for T {}
13 | ---------- ^^^^^^ ^
14 | |
15 | unsatisfied trait bound introduced here
16
17error[E0277]: the size for values of type `Self` cannot be known at compilation time
18 --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5
19 |
20LL | fn transmute(&self) {}
21 | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
22 |
23note: required for `Self` to implement `Mirror`
24 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
25 |
26LL | impl<T: Super<Assoc = ()>> Mirror for T {}
27 | - ^^^^^^ ^
28 | |
29 | unsatisfied trait bound implicitly introduced here
30
31error[E0271]: type mismatch resolving `<Self as Super>::Assoc == ()`
32 --> $DIR/unhandled-crate-mod-issue-144888.rs:10:1
33 |
34LL | trait Foo<T>: Super<Assoc = T>
35 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found type parameter `T`
36 |
37 = note: expected unit type `()`
38 found type parameter `T`
39note: required for `Self` to implement `Mirror`
40 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
41 |
42LL | impl<T: Super<Assoc = ()>> Mirror for T {}
43 | ---------- ^^^^^^ ^
44 | |
45 | unsatisfied trait bound introduced here
46
47error[E0277]: the size for values of type `Self` cannot be known at compilation time
48 --> $DIR/unhandled-crate-mod-issue-144888.rs:10:1
49 |
50LL | trait Foo<T>: Super<Assoc = T>
51 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
52 |
53note: required for `Self` to implement `Mirror`
54 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
55 |
56LL | impl<T: Super<Assoc = ()>> Mirror for T {}
57 | - ^^^^^^ ^
58 | |
59 | unsatisfied trait bound implicitly introduced here
60help: consider further restricting `Self`
61 |
62LL | trait Foo<T>: Super<Assoc = T> + Sized
63 | +++++++
64
65error[E0271]: type mismatch resolving `<Self as Super>::Assoc == ()`
66 --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30
67 |
68LL | trait Foo<T>: Super<Assoc = T>
69 | - found this type parameter
70...
71LL | <Self as Mirror>::Assoc: Clone,
72 | ^^^^^ expected `()`, found type parameter `T`
73 |
74 = note: expected unit type `()`
75 found type parameter `T`
76note: required for `Self` to implement `Mirror`
77 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
78 |
79LL | impl<T: Super<Assoc = ()>> Mirror for T {}
80 | ---------- ^^^^^^ ^
81 | |
82 | unsatisfied trait bound introduced here
83
84error[E0277]: the size for values of type `Self` cannot be known at compilation time
85 --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30
86 |
87LL | <Self as Mirror>::Assoc: Clone,
88 | ^^^^^ doesn't have a size known at compile-time
89 |
90note: required for `Self` to implement `Mirror`
91 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
92 |
93LL | impl<T: Super<Assoc = ()>> Mirror for T {}
94 | - ^^^^^^ ^
95 | |
96 | unsatisfied trait bound implicitly introduced here
97help: consider further restricting `Self`
98 |
99LL | trait Foo<T>: Super<Assoc = T> + Sized
100 | +++++++
101
102error[E0046]: not all trait items implemented, missing: `Assoc`
103 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:1
104 |
105LL | type Assoc;
106 | ---------- `Assoc` from trait
107...
108LL | impl<T: Super<Assoc = ()>> Mirror for T {}
109 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation
110
111error[E0271]: type mismatch resolving `<Self as Super>::Assoc == ()`
112 --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5
113 |
114LL | trait Foo<T>: Super<Assoc = T>
115 | - found this type parameter
116...
117LL | fn transmute(&self) {}
118 | ^^^^^^^^^^^^^^^^^^^ expected `()`, found type parameter `T`
119 |
120 = note: expected unit type `()`
121 found type parameter `T`
122note: required for `Self` to implement `Mirror`
123 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
124 |
125LL | impl<T: Super<Assoc = ()>> Mirror for T {}
126 | ---------- ^^^^^^ ^
127 | |
128 | unsatisfied trait bound introduced here
129
130error[E0277]: the size for values of type `Self` cannot be known at compilation time
131 --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5
132 |
133LL | fn transmute(&self) {}
134 | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
135 |
136note: required for `Self` to implement `Mirror`
137 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
138 |
139LL | impl<T: Super<Assoc = ()>> Mirror for T {}
140 | - ^^^^^^ ^
141 | |
142 | unsatisfied trait bound implicitly introduced here
143help: consider further restricting `Self`
144 |
145LL | fn transmute(&self) where Self: Sized {}
146 | +++++++++++++++++
147
148error[E0271]: type mismatch resolving `<Self as Super>::Assoc == ()`
149 --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30
150 |
151LL | trait Foo<T>: Super<Assoc = T>
152 | - found this type parameter
153...
154LL | <Self as Mirror>::Assoc: Clone,
155 | ^^^^^ expected `()`, found type parameter `T`
156 |
157 = note: expected unit type `()`
158 found type parameter `T`
159note: required for `Self` to implement `Mirror`
160 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
161 |
162LL | impl<T: Super<Assoc = ()>> Mirror for T {}
163 | ---------- ^^^^^^ ^
164 | |
165 | unsatisfied trait bound introduced here
166 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
167
168error[E0277]: the size for values of type `Self` cannot be known at compilation time
169 --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30
170 |
171LL | <Self as Mirror>::Assoc: Clone,
172 | ^^^^^ doesn't have a size known at compile-time
173 |
174note: required for `Self` to implement `Mirror`
175 --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28
176 |
177LL | impl<T: Super<Assoc = ()>> Mirror for T {}
178 | - ^^^^^^ ^
179 | |
180 | unsatisfied trait bound implicitly introduced here
181help: consider further restricting `Self`
182 |
183LL | fn transmute(&self) where Self: Sized {}
184 | +++++++++++++++++
185
186error: aborting due to 11 previous errors
187
188Some errors have detailed explanations: E0046, E0271, E0277.
189For more information about an error, try `rustc --explain E0046`.
tests/ui/unstable-feature-bound/unstable_feature_bound_staged_api.stderr+2-2
......@@ -1,4 +1,4 @@
1error[E0734]: stability attributes may not be used outside of the standard library
1error[E0658]: stability attributes may not be used outside of the standard library
22 --> $DIR/unstable_feature_bound_staged_api.rs:8:1
33 |
44LL | #[unstable_feature_bound(feat_bar)]
......@@ -6,4 +6,4 @@ LL | #[unstable_feature_bound(feat_bar)]
66
77error: aborting due to 1 previous error
88
9For more information about this error, try `rustc --explain E0734`.
9For more information about this error, try `rustc --explain E0658`.
triagebot.toml+1
......@@ -1496,6 +1496,7 @@ libs = [
14961496 "@thomcc",
14971497 "@joboet",
14981498 "@nia-e",
1499 "@LawnGnome",
14991500]
15001501infra-ci = [
15011502 "@Mark-Simulacrum",