authorbors <bors@rust-lang.org> 2025-12-09 08:20:51 UTC
committerbors <bors@rust-lang.org> 2025-12-09 08:20:51 UTC
logd5525a73009e2c61b09daa69df79064530bd4dcf
treea5ee6c736ec6c1ac5566d9242778e45ce6fc62b7
parent018d26972e523b8d28f9579056185a1713949dfd
parent288e97018a5b98959d01af990a50cac960dc9d5f

Auto merge of #149798 - matthiaskrgr:rollup-wjgs9x6, r=matthiaskrgr

Rollup of 11 pull requests Successful merges: - rust-lang/rust#147585 (Suppress the error for private fields with non_exhaustive attribute) - rust-lang/rust#149215 (Emit `check-cfg` lints during attribute parsing rather than evaluation) - rust-lang/rust#149652 (Add release notes for 1.92.0) - rust-lang/rust#149720 (rustdoc book: mention inner doc attribute) - rust-lang/rust#149730 (lint: emit proper diagnostic for unsafe binders in improper_ctypes instead of ICE) - rust-lang/rust#149754 (Retire `opt_str2` from compiletest cli parsing) - rust-lang/rust#149755 (bootstrap: Use a `CompiletestMode` enum instead of bare strings) - rust-lang/rust#149763 (Add inline attribute to generated delegation function if needed) - rust-lang/rust#149772 (test: Add a test for 146133) - rust-lang/rust#149779 (Fix typo "an" → "and") - rust-lang/rust#149782 (Remove `[no-mentions]` handler in the triagebot config) Failed merges: - rust-lang/rust#148491 ( Correctly provide suggestions when encountering `async fn` with a `dyn Trait` return type) r? `@ghost` `@rustbot` modify labels: rollup

45 files changed, 771 insertions(+), 217 deletions(-)

RELEASES.md+85
...@@ -1,3 +1,88 @@...@@ -1,3 +1,88 @@
1Version 1.92.0 (2025-12-11)
2==========================
3
4<a id="1.92.0-Language"></a>
5
6Language
7--------
8- [Document `MaybeUninit` representation and validity](https://github.com/rust-lang/rust/pull/140463)
9- [Allow `&raw [mut | const]` for union field in safe code](https://github.com/rust-lang/rust/pull/141469)
10- [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](https://github.com/rust-lang/rust/pull/144064)
11- [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](https://github.com/rust-lang/rust/pull/145277)
12- [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](https://github.com/rust-lang/rust/pull/145724)
13- [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](https://github.com/rust-lang/rust/pull/146167)
14- [Allow specifying multiple bounds for same associated item, except in trait objects](https://github.com/rust-lang/rust/pull/146593)
15- [Slightly strengthen higher-ranked region handling in coherence](https://github.com/rust-lang/rust/pull/146725)
16- [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow<Uninhabited, ()>`](https://github.com/rust-lang/rust/pull/147382). This avoids having to check for an error that can never happen.
17
18<a id="1.92.0-Compiler"></a>
19
20Compiler
21--------
22- [Make `mips64el-unknown-linux-muslabi64` link dynamically](https://github.com/rust-lang/rust/pull/146858)
23- [Remove current code for embedding command-line args in PDB](https://github.com/rust-lang/rust/pull/147022)
24 Command-line information is typically not needed by debugging tools, and the removed code
25 was causing problems for incremental builds even on targets that don't use PDB debuginfo.
26
27<a id="1.92.0-Libraries"></a>
28
29Libraries
30---------
31- [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](https://github.com/rust-lang/rust/pull/137122)
32- [Simplify `Extend` for tuples](https://github.com/rust-lang/rust/pull/138799)
33- [Added details to `Debug` for `EncodeWide`](https://github.com/rust-lang/rust/pull/140153).
34- [`iter::Repeat::last`](https://github.com/rust-lang/rust/pull/147258) and [`count`](https://github.com/rust-lang/rust/pull/146410) will now panic, rather than looping infinitely.
35
36<a id="1.92.0-Stabilized-APIs"></a>
37
38Stabilized APIs
39---------------
40
41- [`NonZero<u{N}>::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil)
42- [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str)
43- [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade)
44- [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed)
45- [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice)
46- [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed)
47- [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice)
48- [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed)
49- [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice)
50- [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry)
51- [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry)
52- [`impl Extend<proc_macro::Group> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream)
53- [`impl Extend<proc_macro::Literal> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream)
54- [`impl Extend<proc_macro::Punct> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream)
55- [`impl Extend<proc_macro::Ident> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream)
56
57These previously stable APIs are now stable in const contexts:
58
59- [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left)
60- [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right)
61
62<a id="1.92.0-Cargo"></a>
63
64Cargo
65-----
66- [Added a new chapter](https://github.com/rust-lang/cargo/issues/16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html).
67
68<a id="1.92.0-Rustdoc"></a>
69
70Rustdoc
71-----
72- [If a trait item appears in rustdoc search, hide the corresponding impl items](https://github.com/rust-lang/rust/pull/145898). Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`. Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`.
73- [Relax rules for identifiers in search](https://github.com/rust-lang/rust/pull/147860). Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier. For example, you can now perform a search that starts with a digit.
74
75<a id="1.92.0-Compatibility-Notes"></a>
76
77Compatibility Notes
78-------------------
79* [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](https://github.com/rust-lang/rust/pull/143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables.
80- As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](https://github.com/rust-lang/rust/pull/143857)
81- [Update the minimum external LLVM to 20](https://github.com/rust-lang/rust/pull/145071)
82- [Prevent downstream `impl DerefMut for Pin<LocalType>`](https://github.com/rust-lang/rust/pull/145608)
83- [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](https://github.com/rust-lang/rust/pull/145838)
84
85
1Version 1.91.1 (2025-11-10)86Version 1.91.1 (2025-11-10)
2===========================87===========================
388
compiler/rustc_ast_lowering/src/delegation.rs+28
...@@ -44,6 +44,7 @@ use hir::{BodyId, HirId};...@@ -44,6 +44,7 @@ use hir::{BodyId, HirId};
44use rustc_abi::ExternAbi;44use rustc_abi::ExternAbi;
45use rustc_ast::*;45use rustc_ast::*;
46use rustc_errors::ErrorGuaranteed;46use rustc_errors::ErrorGuaranteed;
47use rustc_hir::attrs::{AttributeKind, InlineAttr};
47use rustc_hir::def_id::DefId;48use rustc_hir::def_id::DefId;
48use rustc_middle::span_bug;49use rustc_middle::span_bug;
49use rustc_middle::ty::{Asyncness, ResolverAstLowering};50use rustc_middle::ty::{Asyncness, ResolverAstLowering};
...@@ -87,6 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> {...@@ -87,6 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
87 let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);88 let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
88 match sig_id {89 match sig_id {
89 Ok(sig_id) => {90 Ok(sig_id) => {
91 self.add_inline_attribute_if_needed(span);
92
90 let is_method = self.is_method(sig_id, span);93 let is_method = self.is_method(sig_id, span);
91 let (param_count, c_variadic) = self.param_count(sig_id);94 let (param_count, c_variadic) = self.param_count(sig_id);
92 let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);95 let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
...@@ -100,6 +103,31 @@ impl<'hir> LoweringContext<'_, 'hir> {...@@ -100,6 +103,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
100 }103 }
101 }104 }
102105
106 fn add_inline_attribute_if_needed(&mut self, span: Span) {
107 const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
108 let create_inline_attr_slice =
109 || [hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span))];
110
111 let new_attributes = match self.attrs.get(&PARENT_ID) {
112 Some(attrs) => {
113 // Check if reuse already specifies any inline attribute, if so, do nothing
114 if attrs
115 .iter()
116 .any(|a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))))
117 {
118 return;
119 }
120
121 self.arena.alloc_from_iter(
122 attrs.into_iter().map(|a| a.clone()).chain(create_inline_attr_slice()),
123 )
124 }
125 None => self.arena.alloc_from_iter(create_inline_attr_slice()),
126 };
127
128 self.attrs.insert(PARENT_ID, new_attributes);
129 }
130
103 fn get_delegation_sig_id(131 fn get_delegation_sig_id(
104 &self,132 &self,
105 item_id: NodeId,133 item_id: NodeId,
compiler/rustc_attr_parsing/src/attributes/cfg.rs+29-53
...@@ -2,16 +2,16 @@ use std::convert::identity;...@@ -2,16 +2,16 @@ use std::convert::identity;
22
3use rustc_ast::token::Delimiter;3use rustc_ast::token::Delimiter;
4use rustc_ast::tokenstream::DelimSpan;4use rustc_ast::tokenstream::DelimSpan;
5use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token};5use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token};
6use rustc_errors::{Applicability, PResult};6use rustc_errors::{Applicability, PResult};
7use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template};7use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template};
8use rustc_hir::attrs::CfgEntry;8use rustc_hir::attrs::CfgEntry;
9use rustc_hir::lints::AttributeLintKind;
9use rustc_hir::{AttrPath, RustcVersion};10use rustc_hir::{AttrPath, RustcVersion};
10use rustc_parse::parser::{ForceCollect, Parser};11use rustc_parse::parser::{ForceCollect, Parser};
11use rustc_parse::{exp, parse_in};12use rustc_parse::{exp, parse_in};
12use rustc_session::Session;13use rustc_session::Session;
13use rustc_session::config::ExpectedValues;14use rustc_session::config::ExpectedValues;
14use rustc_session::lint::BuiltinLintDiag;
15use rustc_session::lint::builtin::UNEXPECTED_CFGS;15use rustc_session::lint::builtin::UNEXPECTED_CFGS;
16use rustc_session::parse::{ParseSess, feature_err};16use rustc_session::parse::{ParseSess, feature_err};
17use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};17use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
...@@ -23,10 +23,7 @@ use crate::session_diagnostics::{...@@ -23,10 +23,7 @@ use crate::session_diagnostics::{
23 AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,23 AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
24 ParsedDescription,24 ParsedDescription,
25};25};
26use crate::{26use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics, try_gate_cfg};
27 AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics,
28 try_gate_cfg,
29};
3027
31pub const CFG_TEMPLATE: AttributeTemplate = template!(28pub const CFG_TEMPLATE: AttributeTemplate = template!(
32 List: &["predicate"],29 List: &["predicate"],
...@@ -195,43 +192,46 @@ fn parse_name_value<S: Stage>(...@@ -195,43 +192,46 @@ fn parse_name_value<S: Stage>(
195 }192 }
196 };193 };
197194
198 Ok(CfgEntry::NameValue { name, name_span, value, span })195 match cx.sess.psess.check_config.expecteds.get(&name) {
196 Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => cx
197 .emit_lint(
198 UNEXPECTED_CFGS,
199 AttributeLintKind::UnexpectedCfgValue((name, name_span), value),
200 span,
201 ),
202 None if cx.sess.psess.check_config.exhaustive_names => cx.emit_lint(
203 UNEXPECTED_CFGS,
204 AttributeLintKind::UnexpectedCfgName((name, name_span), value),
205 span,
206 ),
207 _ => { /* not unexpected */ }
208 }
209
210 Ok(CfgEntry::NameValue { name, value: value.map(|(v, _)| v), span })
199}211}
200212
201pub fn eval_config_entry(213pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResult {
202 sess: &Session,
203 cfg_entry: &CfgEntry,
204 id: NodeId,
205 emit_lints: ShouldEmit,
206) -> EvalConfigResult {
207 match cfg_entry {214 match cfg_entry {
208 CfgEntry::All(subs, ..) => {215 CfgEntry::All(subs, ..) => {
209 let mut all = None;
210 for sub in subs {216 for sub in subs {
211 let res = eval_config_entry(sess, sub, id, emit_lints);217 let res = eval_config_entry(sess, sub);
212 // We cannot short-circuit because `eval_config_entry` emits some lints
213 if !res.as_bool() {218 if !res.as_bool() {
214 all.get_or_insert(res);219 return res;
215 }220 }
216 }221 }
217 all.unwrap_or_else(|| EvalConfigResult::True)222 EvalConfigResult::True
218 }223 }
219 CfgEntry::Any(subs, span) => {224 CfgEntry::Any(subs, span) => {
220 let mut any = None;
221 for sub in subs {225 for sub in subs {
222 let res = eval_config_entry(sess, sub, id, emit_lints);226 let res = eval_config_entry(sess, sub);
223 // We cannot short-circuit because `eval_config_entry` emits some lints
224 if res.as_bool() {227 if res.as_bool() {
225 any.get_or_insert(res);228 return res;
226 }229 }
227 }230 }
228 any.unwrap_or_else(|| EvalConfigResult::False {231 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
229 reason: cfg_entry.clone(),
230 reason_span: *span,
231 })
232 }232 }
233 CfgEntry::Not(sub, span) => {233 CfgEntry::Not(sub, span) => {
234 if eval_config_entry(sess, sub, id, emit_lints).as_bool() {234 if eval_config_entry(sess, sub).as_bool() {
235 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }235 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
236 } else {236 } else {
237 EvalConfigResult::True237 EvalConfigResult::True
...@@ -244,32 +244,8 @@ pub fn eval_config_entry(...@@ -244,32 +244,8 @@ pub fn eval_config_entry(
244 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }244 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
245 }245 }
246 }246 }
247 CfgEntry::NameValue { name, name_span, value, span } => {247 CfgEntry::NameValue { name, value, span } => {
248 if let ShouldEmit::ErrorsAndLints = emit_lints {248 if sess.psess.config.contains(&(*name, *value)) {
249 match sess.psess.check_config.expecteds.get(name) {
250 Some(ExpectedValues::Some(values))
251 if !values.contains(&value.map(|(v, _)| v)) =>
252 {
253 id.emit_span_lint(
254 sess,
255 UNEXPECTED_CFGS,
256 *span,
257 BuiltinLintDiag::UnexpectedCfgValue((*name, *name_span), *value),
258 );
259 }
260 None if sess.psess.check_config.exhaustive_names => {
261 id.emit_span_lint(
262 sess,
263 UNEXPECTED_CFGS,
264 *span,
265 BuiltinLintDiag::UnexpectedCfgName((*name, *name_span), *value),
266 );
267 }
268 _ => { /* not unexpected */ }
269 }
270 }
271
272 if sess.psess.config.contains(&(*name, value.map(|(v, _)| v))) {
273 EvalConfigResult::True249 EvalConfigResult::True
274 } else {250 } else {
275 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }251 EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
compiler/rustc_attr_parsing/src/attributes/cfg_old.rs+5-4
...@@ -2,6 +2,7 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, Nod...@@ -2,6 +2,7 @@ use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, Nod
2use rustc_ast_pretty::pprust;2use rustc_ast_pretty::pprust;
3use rustc_feature::{Features, GatedCfg, find_gated_cfg};3use rustc_feature::{Features, GatedCfg, find_gated_cfg};
4use rustc_hir::RustcVersion;4use rustc_hir::RustcVersion;
5use rustc_hir::lints::AttributeLintKind;
5use rustc_session::Session;6use rustc_session::Session;
6use rustc_session::config::ExpectedValues;7use rustc_session::config::ExpectedValues;
7use rustc_session::lint::builtin::UNEXPECTED_CFGS;8use rustc_session::lint::builtin::UNEXPECTED_CFGS;
...@@ -51,10 +52,10 @@ pub fn cfg_matches(...@@ -51,10 +52,10 @@ pub fn cfg_matches(
51 sess,52 sess,
52 UNEXPECTED_CFGS,53 UNEXPECTED_CFGS,
53 cfg.span,54 cfg.span,
54 BuiltinLintDiag::UnexpectedCfgValue(55 BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgValue(
55 (cfg.name, cfg.name_span),56 (cfg.name, cfg.name_span),
56 cfg.value.map(|v| (v, cfg.value_span.unwrap())),57 cfg.value.map(|v| (v, cfg.value_span.unwrap())),
57 ),58 )),
58 );59 );
59 }60 }
60 None if sess.psess.check_config.exhaustive_names => {61 None if sess.psess.check_config.exhaustive_names => {
...@@ -62,10 +63,10 @@ pub fn cfg_matches(...@@ -62,10 +63,10 @@ pub fn cfg_matches(
62 sess,63 sess,
63 UNEXPECTED_CFGS,64 UNEXPECTED_CFGS,
64 cfg.span,65 cfg.span,
65 BuiltinLintDiag::UnexpectedCfgName(66 BuiltinLintDiag::AttributeLint(AttributeLintKind::UnexpectedCfgName(
66 (cfg.name, cfg.name_span),67 (cfg.name, cfg.name_span),
67 cfg.value.map(|v| (v, cfg.value_span.unwrap())),68 cfg.value.map(|v| (v, cfg.value_span.unwrap())),
68 ),69 )),
69 );70 );
70 }71 }
71 _ => { /* not unexpected */ }72 _ => { /* not unexpected */ }
compiler/rustc_builtin_macros/src/cfg.rs+1-7
...@@ -26,13 +26,7 @@ pub(crate) fn expand_cfg(...@@ -26,13 +26,7 @@ pub(crate) fn expand_cfg(
2626
27 ExpandResult::Ready(match parse_cfg(cx, sp, tts) {27 ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
28 Ok(cfg) => {28 Ok(cfg) => {
29 let matches_cfg = attr::eval_config_entry(29 let matches_cfg = attr::eval_config_entry(cx.sess, &cfg).as_bool();
30 cx.sess,
31 &cfg,
32 cx.current_expansion.lint_node_id,
33 ShouldEmit::ErrorsAndLints,
34 )
35 .as_bool();
3630
37 MacEager::expr(cx.expr_bool(sp, matches_cfg))31 MacEager::expr(cx.expr_bool(sp, matches_cfg))
38 }32 }
compiler/rustc_builtin_macros/src/cfg_select.rs+4-12
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1use rustc_ast::tokenstream::TokenStream;1use rustc_ast::tokenstream::TokenStream;
2use rustc_attr_parsing as attr;2use rustc_attr_parsing as attr;
3use rustc_attr_parsing::{3use rustc_attr_parsing::{
4 CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, ShouldEmit, parse_cfg_select,4 CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, parse_cfg_select,
5};5};
6use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};6use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
7use rustc_span::{Ident, Span, sym};7use rustc_span::{Ident, Span, sym};
...@@ -10,21 +10,13 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};...@@ -10,21 +10,13 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};
1010
11/// Selects the first arm whose predicate evaluates to true.11/// Selects the first arm whose predicate evaluates to true.
12fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {12fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
13 let mut result = None;
14 for (cfg, tt, arm_span) in branches.reachable {13 for (cfg, tt, arm_span) in branches.reachable {
15 if let EvalConfigResult::True = attr::eval_config_entry(14 if let EvalConfigResult::True = attr::eval_config_entry(&ecx.sess, &cfg) {
16 &ecx.sess,15 return Some((tt, arm_span));
17 &cfg,
18 ecx.current_expansion.lint_node_id,
19 ShouldEmit::ErrorsAndLints,
20 ) {
21 // FIXME(#149215) Ideally we should short-circuit here, but `eval_config_entry` currently emits lints so we cannot do this yet.
22 result.get_or_insert((tt, arm_span));
23 }16 }
24 }17 }
2518
26 let wildcard = branches.wildcard.map(|(_, tt, span)| (tt, span));19 branches.wildcard.map(|(_, tt, span)| (tt, span))
27 result.or(wildcard)
28}20}
2921
30pub(super) fn expand_cfg_select<'cx>(22pub(super) fn expand_cfg_select<'cx>(
compiler/rustc_codegen_ssa/src/back/link.rs+2-5
...@@ -13,8 +13,7 @@ use find_msvc_tools;...@@ -13,8 +13,7 @@ use find_msvc_tools;
13use itertools::Itertools;13use itertools::Itertools;
14use regex::Regex;14use regex::Regex;
15use rustc_arena::TypedArena;15use rustc_arena::TypedArena;
16use rustc_ast::CRATE_NODE_ID;16use rustc_attr_parsing::eval_config_entry;
17use rustc_attr_parsing::{ShouldEmit, eval_config_entry};
18use rustc_data_structures::fx::FxIndexSet;17use rustc_data_structures::fx::FxIndexSet;
19use rustc_data_structures::memmap::Mmap;18use rustc_data_structures::memmap::Mmap;
20use rustc_data_structures::temp_dir::MaybeTempDir;19use rustc_data_structures::temp_dir::MaybeTempDir;
...@@ -3029,9 +3028,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {...@@ -3029,9 +3028,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
30293028
3030fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {3029fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
3031 match lib.cfg {3030 match lib.cfg {
3032 Some(ref cfg) => {3031 Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(),
3033 eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool()
3034 }
3035 None => true,3032 None => true,
3036 }3033 }
3037}3034}
compiler/rustc_expand/src/config.rs+8-24
...@@ -163,10 +163,7 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec...@@ -163,10 +163,7 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
163 .iter()163 .iter()
164 .flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))164 .flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
165 .take_while(|attr| {165 .take_while(|attr| {
166 !is_cfg(attr)166 !is_cfg(attr) || strip_unconfigured.cfg_true(attr, ShouldEmit::Nothing).as_bool()
167 || strip_unconfigured
168 .cfg_true(attr, strip_unconfigured.lint_node_id, ShouldEmit::Nothing)
169 .as_bool()
170 })167 })
171 .collect()168 .collect()
172}169}
...@@ -309,14 +306,7 @@ impl<'a> StripUnconfigured<'a> {...@@ -309,14 +306,7 @@ impl<'a> StripUnconfigured<'a> {
309 );306 );
310 }307 }
311308
312 if !attr::eval_config_entry(309 if !attr::eval_config_entry(self.sess, &cfg_predicate).as_bool() {
313 self.sess,
314 &cfg_predicate,
315 ast::CRATE_NODE_ID,
316 ShouldEmit::ErrorsAndLints,
317 )
318 .as_bool()
319 {
320 return vec![trace_attr];310 return vec![trace_attr];
321 }311 }
322312
...@@ -400,23 +390,17 @@ impl<'a> StripUnconfigured<'a> {...@@ -400,23 +390,17 @@ impl<'a> StripUnconfigured<'a> {
400390
401 /// Determines if a node with the given attributes should be included in this configuration.391 /// Determines if a node with the given attributes should be included in this configuration.
402 fn in_cfg(&self, attrs: &[Attribute]) -> bool {392 fn in_cfg(&self, attrs: &[Attribute]) -> bool {
403 attrs.iter().all(|attr| {393 attrs
404 !is_cfg(attr)394 .iter()
405 || self.cfg_true(attr, self.lint_node_id, ShouldEmit::ErrorsAndLints).as_bool()395 .all(|attr| !is_cfg(attr) || self.cfg_true(attr, ShouldEmit::ErrorsAndLints).as_bool())
406 })
407 }396 }
408397
409 pub(crate) fn cfg_true(398 pub(crate) fn cfg_true(&self, attr: &Attribute, emit_errors: ShouldEmit) -> EvalConfigResult {
410 &self,
411 attr: &Attribute,
412 node: NodeId,
413 emit_errors: ShouldEmit,
414 ) -> EvalConfigResult {
415 let Some(cfg) = AttributeParser::parse_single(399 let Some(cfg) = AttributeParser::parse_single(
416 self.sess,400 self.sess,
417 attr,401 attr,
418 attr.span,402 attr.span,
419 node,403 self.lint_node_id,
420 self.features,404 self.features,
421 emit_errors,405 emit_errors,
422 parse_cfg,406 parse_cfg,
...@@ -426,7 +410,7 @@ impl<'a> StripUnconfigured<'a> {...@@ -426,7 +410,7 @@ impl<'a> StripUnconfigured<'a> {
426 return EvalConfigResult::True;410 return EvalConfigResult::True;
427 };411 };
428412
429 eval_config_entry(self.sess, &cfg, self.lint_node_id, emit_errors)413 eval_config_entry(self.sess, &cfg)
430 }414 }
431415
432 /// If attributes are not allowed on expressions, emit an error for `attr`416 /// If attributes are not allowed on expressions, emit an error for `attr`
compiler/rustc_expand/src/expand.rs+1-1
...@@ -2213,7 +2213,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {...@@ -2213,7 +2213,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
2213 attr: ast::Attribute,2213 attr: ast::Attribute,
2214 pos: usize,2214 pos: usize,
2215 ) -> EvalConfigResult {2215 ) -> EvalConfigResult {
2216 let res = self.cfg().cfg_true(&attr, node.node_id(), ShouldEmit::ErrorsAndLints);2216 let res = self.cfg().cfg_true(&attr, ShouldEmit::ErrorsAndLints);
2217 if res.as_bool() {2217 if res.as_bool() {
2218 // A trace attribute left in AST in place of the original `cfg` attribute.2218 // A trace attribute left in AST in place of the original `cfg` attribute.
2219 // It can later be used by lints or other diagnostics.2219 // It can later be used by lints or other diagnostics.
compiler/rustc_hir/src/attrs/data_structures.rs+1-1
...@@ -190,7 +190,7 @@ pub enum CfgEntry {...@@ -190,7 +190,7 @@ pub enum CfgEntry {
190 Any(ThinVec<CfgEntry>, Span),190 Any(ThinVec<CfgEntry>, Span),
191 Not(Box<CfgEntry>, Span),191 Not(Box<CfgEntry>, Span),
192 Bool(bool, Span),192 Bool(bool, Span),
193 NameValue { name: Symbol, name_span: Span, value: Option<(Symbol, Span)>, span: Span },193 NameValue { name: Symbol, value: Option<Symbol>, span: Span },
194 Version(Option<RustcVersion>, Span),194 Version(Option<RustcVersion>, Span),
195}195}
196196
compiler/rustc_hir_typeck/src/expr.rs+5-1
...@@ -2191,7 +2191,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {...@@ -2191,7 +2191,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2191 }2191 }
2192 };2192 };
2193 self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys);2193 self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr.hir_id, fru_tys);
2194 } else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() {2194 } else if adt_kind != AdtKind::Union
2195 && !remaining_fields.is_empty()
2196 //~ non_exhaustive already reported, which will only happen for extern modules
2197 && !variant.field_list_has_applicable_non_exhaustive()
2198 {
2195 debug!(?remaining_fields);2199 debug!(?remaining_fields);
2196 let private_fields: Vec<&ty::FieldDef> = variant2200 let private_fields: Vec<&ty::FieldDef> = variant
2197 .fields2201 .fields
compiler/rustc_lint/messages.ftl+2
...@@ -416,6 +416,8 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re...@@ -416,6 +416,8 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
416lint_improper_ctypes_union_layout_reason = this union has unspecified layout416lint_improper_ctypes_union_layout_reason = this union has unspecified layout
417lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive417lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
418418
419lint_improper_ctypes_unsafe_binder = unsafe binders are incompatible with foreign function interfaces
420
419lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance421lint_int_to_ptr_transmutes = transmuting an integer to a pointer creates a pointer without provenance
420 .note = this is dangerous because dereferencing the resulting pointer is undefined behavior422 .note = this is dangerous because dereferencing the resulting pointer is undefined behavior
421 .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance423 .note_exposed_provenance = exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
compiler/rustc_lint/src/early/diagnostics.rs+8-8
...@@ -169,12 +169,6 @@ pub fn decorate_builtin_lint(...@@ -169,12 +169,6 @@ pub fn decorate_builtin_lint(
169 }169 }
170 .decorate_lint(diag);170 .decorate_lint(diag);
171 }171 }
172 BuiltinLintDiag::UnexpectedCfgName(name, value) => {
173 check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag);
174 }
175 BuiltinLintDiag::UnexpectedCfgValue(name, value) => {
176 check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag);
177 }
178 BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => {172 BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => {
179 let suggestion = match sugg {173 let suggestion = match sugg {
180 Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd {174 Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd {
...@@ -310,8 +304,8 @@ pub fn decorate_builtin_lint(...@@ -310,8 +304,8 @@ pub fn decorate_builtin_lint(
310}304}
311305
312pub fn decorate_attribute_lint(306pub fn decorate_attribute_lint(
313 _sess: &Session,307 sess: &Session,
314 _tcx: Option<TyCtxt<'_>>,308 tcx: Option<TyCtxt<'_>>,
315 kind: &AttributeLintKind,309 kind: &AttributeLintKind,
316 diag: &mut Diag<'_, ()>,310 diag: &mut Diag<'_, ()>,
317) {311) {
...@@ -367,5 +361,11 @@ pub fn decorate_attribute_lint(...@@ -367,5 +361,11 @@ pub fn decorate_attribute_lint(
367 suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },361 suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right },
368 }362 }
369 .decorate_lint(diag),363 .decorate_lint(diag),
364 &AttributeLintKind::UnexpectedCfgName(name, value) => {
365 check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag)
366 }
367 &AttributeLintKind::UnexpectedCfgValue(name, value) => {
368 check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag)
369 }
370 }370 }
371}371}
compiler/rustc_lint/src/types/improper_ctypes.rs+3-1
...@@ -669,7 +669,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {...@@ -669,7 +669,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
669 FfiSafe669 FfiSafe
670 }670 }
671671
672 ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"),672 ty::UnsafeBinder(_) => {
673 FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_unsafe_binder, help: None }
674 }
673675
674 ty::Param(..)676 ty::Param(..)
675 | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)677 | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
compiler/rustc_lint_defs/src/lib.rs+2-2
...@@ -636,8 +636,6 @@ pub enum BuiltinLintDiag {...@@ -636,8 +636,6 @@ pub enum BuiltinLintDiag {
636 },636 },
637 BreakWithLabelAndLoop(Span),637 BreakWithLabelAndLoop(Span),
638 UnicodeTextFlow(Span, String),638 UnicodeTextFlow(Span, String),
639 UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
640 UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
641 DeprecatedWhereclauseLocation(Span, Option<(Span, String)>),639 DeprecatedWhereclauseLocation(Span, Option<(Span, String)>),
642 SingleUseLifetime {640 SingleUseLifetime {
643 /// Span of the parameter which declares this lifetime.641 /// Span of the parameter which declares this lifetime.
...@@ -733,6 +731,8 @@ pub enum AttributeLintKind {...@@ -733,6 +731,8 @@ pub enum AttributeLintKind {
733 attribute_name_span: Span,731 attribute_name_span: Span,
734 sugg_spans: (Span, Span),732 sugg_spans: (Span, Span),
735 },733 },
734 UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
735 UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
736}736}
737737
738pub type RegisteredTools = FxIndexSet<Ident>;738pub type RegisteredTools = FxIndexSet<Ident>;
compiler/rustc_metadata/src/native_libs.rs+2-5
...@@ -2,8 +2,7 @@ use std::ops::ControlFlow;...@@ -2,8 +2,7 @@ use std::ops::ControlFlow;
2use std::path::{Path, PathBuf};2use std::path::{Path, PathBuf};
33
4use rustc_abi::ExternAbi;4use rustc_abi::ExternAbi;
5use rustc_ast::CRATE_NODE_ID;5use rustc_attr_parsing::eval_config_entry;
6use rustc_attr_parsing::{ShouldEmit, eval_config_entry};
7use rustc_data_structures::fx::FxHashSet;6use rustc_data_structures::fx::FxHashSet;
8use rustc_hir::attrs::{AttributeKind, NativeLibKind, PeImportNameType};7use rustc_hir::attrs::{AttributeKind, NativeLibKind, PeImportNameType};
9use rustc_hir::find_attr;8use rustc_hir::find_attr;
...@@ -188,9 +187,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib>...@@ -188,9 +187,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec<NativeLib>
188187
189pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {188pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
190 match lib.cfg {189 match lib.cfg {
191 Some(ref cfg) => {190 Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(),
192 eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool()
193 }
194 None => true,191 None => true,
195 }192 }
196}193}
compiler/rustc_resolve/src/diagnostics.rs+1-1
...@@ -3070,7 +3070,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {...@@ -3070,7 +3070,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
3070 continue;3070 continue;
3071 }3071 }
30723072
3073 let item_was = if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {3073 let item_was = if let CfgEntry::NameValue { value: Some(feature), .. } = cfg.0 {
3074 errors::ItemWas::BehindFeature { feature, span: cfg.1 }3074 errors::ItemWas::BehindFeature { feature, span: cfg.1 }
3075 } else {3075 } else {
3076 errors::ItemWas::CfgOut { span: cfg.1 }3076 errors::ItemWas::CfgOut { span: cfg.1 }
library/std/src/fs.rs+2-2
...@@ -1324,7 +1324,7 @@ impl Read for &File {...@@ -1324,7 +1324,7 @@ impl Read for &File {
1324 ///1324 ///
1325 /// # Platform-specific behavior1325 /// # Platform-specific behavior
1326 ///1326 ///
1327 /// This function currently returns `true` on Unix an `false` on Windows.1327 /// This function currently returns `true` on Unix and `false` on Windows.
1328 /// Note that this [may change in the future][changes].1328 /// Note that this [may change in the future][changes].
1329 ///1329 ///
1330 /// [changes]: io#platform-specific-behavior1330 /// [changes]: io#platform-specific-behavior
...@@ -1385,7 +1385,7 @@ impl Write for &File {...@@ -1385,7 +1385,7 @@ impl Write for &File {
1385 ///1385 ///
1386 /// # Platform-specific behavior1386 /// # Platform-specific behavior
1387 ///1387 ///
1388 /// This function currently returns `true` on Unix an `false` on Windows.1388 /// This function currently returns `true` on Unix and `false` on Windows.
1389 /// Note that this [may change in the future][changes].1389 /// Note that this [may change in the future][changes].
1390 ///1390 ///
1391 /// [changes]: io#platform-specific-behavior1391 /// [changes]: io#platform-specific-behavior
src/bootstrap/src/core/build_steps/test.rs+70-48
...@@ -3,6 +3,9 @@...@@ -3,6 +3,9 @@
3//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.3//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
4//! However, this contains ~all test parts we expect people to be able to build and run locally.4//! However, this contains ~all test parts we expect people to be able to build and run locally.
55
6// (This file should be split up, but having tidy block all changes is not helpful.)
7// ignore-tidy-filelength
8
6use std::collections::HashSet;9use std::collections::HashSet;
7use std::env::split_paths;10use std::env::split_paths;
8use std::ffi::{OsStr, OsString};11use std::ffi::{OsStr, OsString};
...@@ -17,6 +20,7 @@ use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};...@@ -17,6 +20,7 @@ use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};
17use crate::core::build_steps::llvm::get_llvm_version;20use crate::core::build_steps::llvm::get_llvm_version;
18use crate::core::build_steps::run::{get_completion_paths, get_help_path};21use crate::core::build_steps::run::{get_completion_paths, get_help_path};
19use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;22use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
23use crate::core::build_steps::test::compiletest::CompiletestMode;
20use crate::core::build_steps::tool::{24use crate::core::build_steps::tool::{
21 self, RustcPrivateCompilers, SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, Tool,25 self, RustcPrivateCompilers, SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, Tool,
22 ToolTargetBuildMode, get_tool_target_compiler,26 ToolTargetBuildMode, get_tool_target_compiler,
...@@ -39,6 +43,8 @@ use crate::utils::helpers::{...@@ -39,6 +43,8 @@ use crate::utils::helpers::{
39use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};43use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests};
40use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify};44use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify};
4145
46mod compiletest;
47
42/// Runs `cargo test` on various internal tools used by bootstrap.48/// Runs `cargo test` on various internal tools used by bootstrap.
43#[derive(Debug, Clone, PartialEq, Eq, Hash)]49#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44pub struct CrateBootstrap {50pub struct CrateBootstrap {
...@@ -1085,7 +1091,7 @@ impl Step for RustdocJSNotStd {...@@ -1085,7 +1091,7 @@ impl Step for RustdocJSNotStd {
1085 builder.ensure(Compiletest {1091 builder.ensure(Compiletest {
1086 test_compiler: self.compiler,1092 test_compiler: self.compiler,
1087 target: self.target,1093 target: self.target,
1088 mode: "rustdoc-js",1094 mode: CompiletestMode::RustdocJs,
1089 suite: "rustdoc-js",1095 suite: "rustdoc-js",
1090 path: "tests/rustdoc-js",1096 path: "tests/rustdoc-js",
1091 compare_mode: None,1097 compare_mode: None,
...@@ -1478,7 +1484,7 @@ macro_rules! test {...@@ -1478,7 +1484,7 @@ macro_rules! test {
1478 builder.ensure(Compiletest {1484 builder.ensure(Compiletest {
1479 test_compiler: self.test_compiler,1485 test_compiler: self.test_compiler,
1480 target: self.target,1486 target: self.target,
1481 mode: $mode,1487 mode: const { $mode },
1482 suite: $suite,1488 suite: $suite,
1483 path: $path,1489 path: $path,
1484 compare_mode: (const {1490 compare_mode: (const {
...@@ -1493,34 +1499,39 @@ macro_rules! test {...@@ -1493,34 +1499,39 @@ macro_rules! test {
1493 };1499 };
1494}1500}
14951501
1496test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true });1502test!(Ui { path: "tests/ui", mode: CompiletestMode::Ui, suite: "ui", default: true });
14971503
1498test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true });1504test!(Crashes {
1505 path: "tests/crashes",
1506 mode: CompiletestMode::Crashes,
1507 suite: "crashes",
1508 default: true,
1509});
14991510
1500test!(CodegenLlvm {1511test!(CodegenLlvm {
1501 path: "tests/codegen-llvm",1512 path: "tests/codegen-llvm",
1502 mode: "codegen",1513 mode: CompiletestMode::Codegen,
1503 suite: "codegen-llvm",1514 suite: "codegen-llvm",
1504 default: true1515 default: true
1505});1516});
15061517
1507test!(CodegenUnits {1518test!(CodegenUnits {
1508 path: "tests/codegen-units",1519 path: "tests/codegen-units",
1509 mode: "codegen-units",1520 mode: CompiletestMode::CodegenUnits,
1510 suite: "codegen-units",1521 suite: "codegen-units",
1511 default: true,1522 default: true,
1512});1523});
15131524
1514test!(Incremental {1525test!(Incremental {
1515 path: "tests/incremental",1526 path: "tests/incremental",
1516 mode: "incremental",1527 mode: CompiletestMode::Incremental,
1517 suite: "incremental",1528 suite: "incremental",
1518 default: true,1529 default: true,
1519});1530});
15201531
1521test!(Debuginfo {1532test!(Debuginfo {
1522 path: "tests/debuginfo",1533 path: "tests/debuginfo",
1523 mode: "debuginfo",1534 mode: CompiletestMode::Debuginfo,
1524 suite: "debuginfo",1535 suite: "debuginfo",
1525 default: true,1536 default: true,
1526 compare_mode: Some("split-dwarf"),1537 compare_mode: Some("split-dwarf"),
...@@ -1528,7 +1539,7 @@ test!(Debuginfo {...@@ -1528,7 +1539,7 @@ test!(Debuginfo {
15281539
1529test!(UiFullDeps {1540test!(UiFullDeps {
1530 path: "tests/ui-fulldeps",1541 path: "tests/ui-fulldeps",
1531 mode: "ui",1542 mode: CompiletestMode::Ui,
1532 suite: "ui-fulldeps",1543 suite: "ui-fulldeps",
1533 default: true,1544 default: true,
1534 IS_HOST: true,1545 IS_HOST: true,
...@@ -1536,14 +1547,14 @@ test!(UiFullDeps {...@@ -1536,14 +1547,14 @@ test!(UiFullDeps {
15361547
1537test!(Rustdoc {1548test!(Rustdoc {
1538 path: "tests/rustdoc",1549 path: "tests/rustdoc",
1539 mode: "rustdoc",1550 mode: CompiletestMode::Rustdoc,
1540 suite: "rustdoc",1551 suite: "rustdoc",
1541 default: true,1552 default: true,
1542 IS_HOST: true,1553 IS_HOST: true,
1543});1554});
1544test!(RustdocUi {1555test!(RustdocUi {
1545 path: "tests/rustdoc-ui",1556 path: "tests/rustdoc-ui",
1546 mode: "ui",1557 mode: CompiletestMode::Ui,
1547 suite: "rustdoc-ui",1558 suite: "rustdoc-ui",
1548 default: true,1559 default: true,
1549 IS_HOST: true,1560 IS_HOST: true,
...@@ -1551,7 +1562,7 @@ test!(RustdocUi {...@@ -1551,7 +1562,7 @@ test!(RustdocUi {
15511562
1552test!(RustdocJson {1563test!(RustdocJson {
1553 path: "tests/rustdoc-json",1564 path: "tests/rustdoc-json",
1554 mode: "rustdoc-json",1565 mode: CompiletestMode::RustdocJson,
1555 suite: "rustdoc-json",1566 suite: "rustdoc-json",
1556 default: true,1567 default: true,
1557 IS_HOST: true,1568 IS_HOST: true,
...@@ -1559,40 +1570,46 @@ test!(RustdocJson {...@@ -1559,40 +1570,46 @@ test!(RustdocJson {
15591570
1560test!(Pretty {1571test!(Pretty {
1561 path: "tests/pretty",1572 path: "tests/pretty",
1562 mode: "pretty",1573 mode: CompiletestMode::Pretty,
1563 suite: "pretty",1574 suite: "pretty",
1564 default: true,1575 default: true,
1565 IS_HOST: true,1576 IS_HOST: true,
1566});1577});
15671578
1568test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true });1579test!(RunMake {
1580 path: "tests/run-make",
1581 mode: CompiletestMode::RunMake,
1582 suite: "run-make",
1583 default: true,
1584});
1569test!(RunMakeCargo {1585test!(RunMakeCargo {
1570 path: "tests/run-make-cargo",1586 path: "tests/run-make-cargo",
1571 mode: "run-make",1587 mode: CompiletestMode::RunMake,
1572 suite: "run-make-cargo",1588 suite: "run-make-cargo",
1573 default: true1589 default: true
1574});1590});
15751591
1576test!(AssemblyLlvm {1592test!(AssemblyLlvm {
1577 path: "tests/assembly-llvm",1593 path: "tests/assembly-llvm",
1578 mode: "assembly",1594 mode: CompiletestMode::Assembly,
1579 suite: "assembly-llvm",1595 suite: "assembly-llvm",
1580 default: true1596 default: true
1581});1597});
15821598
1583/// Runs the coverage test suite at `tests/coverage` in some or all of the1599/// Runs the coverage test suite at `tests/coverage` in some or all of the
1584/// coverage test modes.1600/// coverage test modes.
1585#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]1601#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1586pub struct Coverage {1602pub struct Coverage {
1587 pub compiler: Compiler,1603 pub compiler: Compiler,
1588 pub target: TargetSelection,1604 pub target: TargetSelection,
1589 pub mode: &'static str,1605 pub(crate) mode: CompiletestMode,
1590}1606}
15911607
1592impl Coverage {1608impl Coverage {
1593 const PATH: &'static str = "tests/coverage";1609 const PATH: &'static str = "tests/coverage";
1594 const SUITE: &'static str = "coverage";1610 const SUITE: &'static str = "coverage";
1595 const ALL_MODES: &[&str] = &["coverage-map", "coverage-run"];1611 const ALL_MODES: &[CompiletestMode] =
1612 &[CompiletestMode::CoverageMap, CompiletestMode::CoverageRun];
1596}1613}
15971614
1598impl Step for Coverage {1615impl Step for Coverage {
...@@ -1608,7 +1625,7 @@ impl Step for Coverage {...@@ -1608,7 +1625,7 @@ impl Step for Coverage {
1608 // - `./x test coverage-run -- tests/coverage/trivial.rs`1625 // - `./x test coverage-run -- tests/coverage/trivial.rs`
1609 run = run.suite_path(Self::PATH);1626 run = run.suite_path(Self::PATH);
1610 for mode in Self::ALL_MODES {1627 for mode in Self::ALL_MODES {
1611 run = run.alias(mode);1628 run = run.alias(mode.as_str());
1612 }1629 }
1613 run1630 run
1614 }1631 }
...@@ -1631,15 +1648,15 @@ impl Step for Coverage {...@@ -1631,15 +1648,15 @@ impl Step for Coverage {
1631 for path in &run.paths {1648 for path in &run.paths {
1632 match path {1649 match path {
1633 PathSet::Set(_) => {1650 PathSet::Set(_) => {
1634 for mode in Self::ALL_MODES {1651 for &mode in Self::ALL_MODES {
1635 if path.assert_single_path().path == Path::new(mode) {1652 if path.assert_single_path().path == Path::new(mode.as_str()) {
1636 modes.push(mode);1653 modes.push(mode);
1637 break;1654 break;
1638 }1655 }
1639 }1656 }
1640 }1657 }
1641 PathSet::Suite(_) => {1658 PathSet::Suite(_) => {
1642 modes.extend(Self::ALL_MODES);1659 modes.extend_from_slice(Self::ALL_MODES);
1643 break;1660 break;
1644 }1661 }
1645 }1662 }
...@@ -1647,7 +1664,9 @@ impl Step for Coverage {...@@ -1647,7 +1664,9 @@ impl Step for Coverage {
16471664
1648 // Skip any modes that were explicitly skipped/excluded on the command-line.1665 // Skip any modes that were explicitly skipped/excluded on the command-line.
1649 // FIXME(Zalathar): Integrate this into central skip handling somehow?1666 // FIXME(Zalathar): Integrate this into central skip handling somehow?
1650 modes.retain(|mode| !run.builder.config.skip.iter().any(|skip| skip == Path::new(mode)));1667 modes.retain(|mode| {
1668 !run.builder.config.skip.iter().any(|skip| skip == Path::new(mode.as_str()))
1669 });
16511670
1652 // FIXME(Zalathar): Make these commands skip all coverage tests, as expected:1671 // FIXME(Zalathar): Make these commands skip all coverage tests, as expected:
1653 // - `./x test --skip=tests`1672 // - `./x test --skip=tests`
...@@ -1678,7 +1697,7 @@ impl Step for Coverage {...@@ -1678,7 +1697,7 @@ impl Step for Coverage {
16781697
1679test!(CoverageRunRustdoc {1698test!(CoverageRunRustdoc {
1680 path: "tests/coverage-run-rustdoc",1699 path: "tests/coverage-run-rustdoc",
1681 mode: "coverage-run",1700 mode: CompiletestMode::CoverageRun,
1682 suite: "coverage-run-rustdoc",1701 suite: "coverage-run-rustdoc",
1683 default: true,1702 default: true,
1684 IS_HOST: true,1703 IS_HOST: true,
...@@ -1712,7 +1731,7 @@ impl Step for MirOpt {...@@ -1712,7 +1731,7 @@ impl Step for MirOpt {
1712 builder.ensure(Compiletest {1731 builder.ensure(Compiletest {
1713 test_compiler: self.compiler,1732 test_compiler: self.compiler,
1714 target,1733 target,
1715 mode: "mir-opt",1734 mode: CompiletestMode::MirOpt,
1716 suite: "mir-opt",1735 suite: "mir-opt",
1717 path: "tests/mir-opt",1736 path: "tests/mir-opt",
1718 compare_mode: None,1737 compare_mode: None,
...@@ -1755,7 +1774,7 @@ struct Compiletest {...@@ -1755,7 +1774,7 @@ struct Compiletest {
1755 /// The compiler that we're testing.1774 /// The compiler that we're testing.
1756 test_compiler: Compiler,1775 test_compiler: Compiler,
1757 target: TargetSelection,1776 target: TargetSelection,
1758 mode: &'static str,1777 mode: CompiletestMode,
1759 suite: &'static str,1778 suite: &'static str,
1760 path: &'static str,1779 path: &'static str,
1761 compare_mode: Option<&'static str>,1780 compare_mode: Option<&'static str>,
...@@ -1791,7 +1810,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the...@@ -1791,7 +1810,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
1791 let suite_path = self.path;1810 let suite_path = self.path;
17921811
1793 // Skip codegen tests if they aren't enabled in configuration.1812 // Skip codegen tests if they aren't enabled in configuration.
1794 if !builder.config.codegen_tests && mode == "codegen" {1813 if !builder.config.codegen_tests && mode == CompiletestMode::Codegen {
1795 return;1814 return;
1796 }1815 }
17971816
...@@ -1829,7 +1848,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the...@@ -1829,7 +1848,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
1829 target,1848 target,
1830 });1849 });
1831 }1850 }
1832 if mode == "run-make" {1851 if mode == CompiletestMode::RunMake {
1833 builder.tool_exe(Tool::RunMakeSupport);1852 builder.tool_exe(Tool::RunMakeSupport);
1834 }1853 }
18351854
...@@ -1886,7 +1905,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the...@@ -1886,7 +1905,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
1886 // suites, `run-make` and `run-make-cargo`. That way, contributors who do not need to run1905 // suites, `run-make` and `run-make-cargo`. That way, contributors who do not need to run
1887 // the `run-make` tests that need in-tree cargo do not need to spend time building in-tree1906 // the `run-make` tests that need in-tree cargo do not need to spend time building in-tree
1888 // cargo.1907 // cargo.
1889 if mode == "run-make" {1908 if mode == CompiletestMode::RunMake {
1890 // We need to pass the compiler that was used to compile run-make-support,1909 // We need to pass the compiler that was used to compile run-make-support,
1891 // because we have to use the same compiler to compile rmake.rs recipes.1910 // because we have to use the same compiler to compile rmake.rs recipes.
1892 let stage0_rustc_path = builder.compiler(0, test_compiler.host);1911 let stage0_rustc_path = builder.compiler(0, test_compiler.host);
...@@ -1910,17 +1929,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the...@@ -1910,17 +1929,18 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
1910 }1929 }
19111930
1912 // Avoid depending on rustdoc when we don't need it.1931 // Avoid depending on rustdoc when we don't need it.
1913 if mode == "rustdoc"1932 if matches!(
1914 || mode == "run-make"1933 mode,
1915 || (mode == "ui" && is_rustdoc)1934 CompiletestMode::RunMake
1916 || mode == "rustdoc-js"1935 | CompiletestMode::Rustdoc
1917 || mode == "rustdoc-json"1936 | CompiletestMode::RustdocJs
1918 || suite == "coverage-run-rustdoc"1937 | CompiletestMode::RustdocJson
1938 ) || matches!(suite, "rustdoc-ui" | "coverage-run-rustdoc")
1919 {1939 {
1920 cmd.arg("--rustdoc-path").arg(builder.rustdoc_for_compiler(test_compiler));1940 cmd.arg("--rustdoc-path").arg(builder.rustdoc_for_compiler(test_compiler));
1921 }1941 }
19221942
1923 if mode == "rustdoc-json" {1943 if mode == CompiletestMode::RustdocJson {
1924 // Use the stage0 compiler for jsondocck1944 // Use the stage0 compiler for jsondocck
1925 let json_compiler = builder.compiler(0, builder.host_target);1945 let json_compiler = builder.compiler(0, builder.host_target);
1926 cmd.arg("--jsondocck-path")1946 cmd.arg("--jsondocck-path")
...@@ -1930,7 +1950,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the...@@ -1930,7 +1950,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
1930 );1950 );
1931 }1951 }
19321952
1933 if matches!(mode, "coverage-map" | "coverage-run") {1953 if matches!(mode, CompiletestMode::CoverageMap | CompiletestMode::CoverageRun) {
1934 let coverage_dump = builder.tool_exe(Tool::CoverageDump);1954 let coverage_dump = builder.tool_exe(Tool::CoverageDump);
1935 cmd.arg("--coverage-dump-path").arg(coverage_dump);1955 cmd.arg("--coverage-dump-path").arg(coverage_dump);
1936 }1956 }
...@@ -1957,7 +1977,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the...@@ -1957,7 +1977,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
1957 cmd.arg("--sysroot-base").arg(sysroot);1977 cmd.arg("--sysroot-base").arg(sysroot);
19581978
1959 cmd.arg("--suite").arg(suite);1979 cmd.arg("--suite").arg(suite);
1960 cmd.arg("--mode").arg(mode);1980 cmd.arg("--mode").arg(mode.as_str());
1961 cmd.arg("--target").arg(target.rustc_target_arg());1981 cmd.arg("--target").arg(target.rustc_target_arg());
1962 cmd.arg("--host").arg(&*test_compiler.host.triple);1982 cmd.arg("--host").arg(&*test_compiler.host.triple);
1963 cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));1983 cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));
...@@ -2036,7 +2056,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2036,7 +2056,7 @@ Please disable assertions with `rust.debug-assertions = false`.
20362056
2037 if let Some(ref nodejs) = builder.config.nodejs {2057 if let Some(ref nodejs) = builder.config.nodejs {
2038 cmd.arg("--nodejs").arg(nodejs);2058 cmd.arg("--nodejs").arg(nodejs);
2039 } else if mode == "rustdoc-js" {2059 } else if mode == CompiletestMode::RustdocJs {
2040 panic!("need nodejs to run rustdoc-js suite");2060 panic!("need nodejs to run rustdoc-js suite");
2041 }2061 }
2042 if builder.config.rust_optimize_tests {2062 if builder.config.rust_optimize_tests {
...@@ -2055,7 +2075,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2055,7 +2075,7 @@ Please disable assertions with `rust.debug-assertions = false`.
2055 let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };2075 let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
2056 flags.push(format!(2076 flags.push(format!(
2057 "-Cdebuginfo={}",2077 "-Cdebuginfo={}",
2058 if mode == "codegen" {2078 if mode == CompiletestMode::Codegen {
2059 // codegen tests typically check LLVM IR and are sensitive to additional debuginfo.2079 // codegen tests typically check LLVM IR and are sensitive to additional debuginfo.
2060 // So do not apply `rust.debuginfo-level-tests` for codegen tests.2080 // So do not apply `rust.debuginfo-level-tests` for codegen tests.
2061 if builder.config.rust_debuginfo_level_tests2081 if builder.config.rust_debuginfo_level_tests
...@@ -2122,7 +2142,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2122,7 +2142,7 @@ Please disable assertions with `rust.debug-assertions = false`.
2122 cmd.arg("--android-cross-path").arg(android_cross_path);2142 cmd.arg("--android-cross-path").arg(android_cross_path);
2123 }2143 }
21242144
2125 if mode == "debuginfo" {2145 if mode == CompiletestMode::Debuginfo {
2126 if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder, android.as_ref())2146 if let Some(debuggers::Gdb { gdb }) = debuggers::discover_gdb(builder, android.as_ref())
2127 {2147 {
2128 cmd.arg("--gdb").arg(gdb.as_ref());2148 cmd.arg("--gdb").arg(gdb.as_ref());
...@@ -2155,7 +2175,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2155,7 +2175,7 @@ Please disable assertions with `rust.debug-assertions = false`.
2155 // in rustdoc-js mode, allow filters to be rs files or js files.2175 // in rustdoc-js mode, allow filters to be rs files or js files.
2156 // use a late-initialized Vec to avoid cloning for other modes.2176 // use a late-initialized Vec to avoid cloning for other modes.
2157 let mut paths_v;2177 let mut paths_v;
2158 if mode == "rustdoc-js" {2178 if mode == CompiletestMode::RustdocJs {
2159 paths_v = paths.to_vec();2179 paths_v = paths.to_vec();
2160 for p in &mut paths_v {2180 for p in &mut paths_v {
2161 if let Some(ext) = p.extension()2181 if let Some(ext) = p.extension()
...@@ -2237,7 +2257,9 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2237,7 +2257,9 @@ Please disable assertions with `rust.debug-assertions = false`.
2237 cmd.arg("--host-rustcflags").arg(link_llvm);2257 cmd.arg("--host-rustcflags").arg(link_llvm);
2238 }2258 }
22392259
2240 if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") {2260 if !builder.config.dry_run()
2261 && matches!(mode, CompiletestMode::RunMake | CompiletestMode::CoverageRun)
2262 {
2241 // The llvm/bin directory contains many useful cross-platform2263 // The llvm/bin directory contains many useful cross-platform
2242 // tools. Pass the path to run-make tests so they can use them.2264 // tools. Pass the path to run-make tests so they can use them.
2243 // (The coverage-run tests also need these tools to process2265 // (The coverage-run tests also need these tools to process
...@@ -2249,7 +2271,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2249,7 +2271,7 @@ Please disable assertions with `rust.debug-assertions = false`.
2249 cmd.arg("--llvm-bin-dir").arg(llvm_bin_path);2271 cmd.arg("--llvm-bin-dir").arg(llvm_bin_path);
2250 }2272 }
22512273
2252 if !builder.config.dry_run() && mode == "run-make" {2274 if !builder.config.dry_run() && mode == CompiletestMode::RunMake {
2253 // If LLD is available, add it to the PATH2275 // If LLD is available, add it to the PATH
2254 if builder.config.lld_enabled {2276 if builder.config.lld_enabled {
2255 let lld_install_root =2277 let lld_install_root =
...@@ -2269,7 +2291,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2269,7 +2291,7 @@ Please disable assertions with `rust.debug-assertions = false`.
22692291
2270 // Only pass correct values for these flags for the `run-make` suite as it2292 // Only pass correct values for these flags for the `run-make` suite as it
2271 // requires that a C++ compiler was configured which isn't always the case.2293 // requires that a C++ compiler was configured which isn't always the case.
2272 if !builder.config.dry_run() && mode == "run-make" {2294 if !builder.config.dry_run() && mode == CompiletestMode::RunMake {
2273 let mut cflags = builder.cc_handled_clags(target, CLang::C);2295 let mut cflags = builder.cc_handled_clags(target, CLang::C);
2274 cflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C));2296 cflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C));
2275 let mut cxxflags = builder.cc_handled_clags(target, CLang::Cxx);2297 let mut cxxflags = builder.cc_handled_clags(target, CLang::Cxx);
...@@ -2385,7 +2407,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2385,7 +2407,7 @@ Please disable assertions with `rust.debug-assertions = false`.
2385 builder.metrics.begin_test_suite(2407 builder.metrics.begin_test_suite(
2386 build_helper::metrics::TestSuiteMetadata::Compiletest {2408 build_helper::metrics::TestSuiteMetadata::Compiletest {
2387 suite: suite.into(),2409 suite: suite.into(),
2388 mode: mode.into(),2410 mode: mode.to_string(),
2389 compare_mode: None,2411 compare_mode: None,
2390 target: self.target.triple.to_string(),2412 target: self.target.triple.to_string(),
2391 host: self.test_compiler.host.triple.to_string(),2413 host: self.test_compiler.host.triple.to_string(),
...@@ -2408,7 +2430,7 @@ Please disable assertions with `rust.debug-assertions = false`....@@ -2408,7 +2430,7 @@ Please disable assertions with `rust.debug-assertions = false`.
2408 builder.metrics.begin_test_suite(2430 builder.metrics.begin_test_suite(
2409 build_helper::metrics::TestSuiteMetadata::Compiletest {2431 build_helper::metrics::TestSuiteMetadata::Compiletest {
2410 suite: suite.into(),2432 suite: suite.into(),
2411 mode: mode.into(),2433 mode: mode.to_string(),
2412 compare_mode: Some(compare_mode.into()),2434 compare_mode: Some(compare_mode.into()),
2413 target: self.target.triple.to_string(),2435 target: self.target.triple.to_string(),
2414 host: self.test_compiler.host.triple.to_string(),2436 host: self.test_compiler.host.triple.to_string(),
src/bootstrap/src/core/build_steps/test/compiletest.rs created+71
...@@ -0,0 +1,71 @@
1use std::fmt;
2
3/// Enum of all the "test modes" understood by compiletest.
4///
5/// Some of these mode names happen to overlap with the names of test suite
6/// directories, but the relationship between modes and suites is not 1:1.
7/// For example:
8/// - Mode `ui` is used by suites `tests/ui` and `tests/rustdoc-ui`
9/// - Suite `tests/coverage` uses modes `coverage-map` and `coverage-run`
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11pub(crate) enum CompiletestMode {
12 // tidy-alphabetical-start
13 Assembly,
14 Codegen,
15 CodegenUnits,
16 CoverageMap,
17 CoverageRun,
18 Crashes,
19 Debuginfo,
20 Incremental,
21 MirOpt,
22 Pretty,
23 RunMake,
24 Rustdoc,
25 RustdocJs,
26 RustdocJson,
27 Ui,
28 // tidy-alphabetical-end
29}
30
31impl CompiletestMode {
32 /// Returns a string representing this mode, which can be passed to
33 /// compiletest via a command-line argument.
34 ///
35 /// These mode names must be kept in sync with the ones understood by
36 /// compiletest's `TestMode`, but they change so rarely that doing so
37 /// manually should not be burdensome.
38 pub(crate) const fn as_str(self) -> &'static str {
39 match self {
40 // tidy-alphabetical-start
41 Self::Assembly => "assembly",
42 Self::Codegen => "codegen",
43 Self::CodegenUnits => "codegen-units",
44 Self::CoverageMap => "coverage-map",
45 Self::CoverageRun => "coverage-run",
46 Self::Crashes => "crashes",
47 Self::Debuginfo => "debuginfo",
48 Self::Incremental => "incremental",
49 Self::MirOpt => "mir-opt",
50 Self::Pretty => "pretty",
51 Self::RunMake => "run-make",
52 Self::Rustdoc => "rustdoc",
53 Self::RustdocJs => "rustdoc-js",
54 Self::RustdocJson => "rustdoc-json",
55 Self::Ui => "ui",
56 // tidy-alphabetical-end
57 }
58 }
59}
60
61impl fmt::Display for CompiletestMode {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 f.write_str(self.as_str())
64 }
65}
66
67impl fmt::Debug for CompiletestMode {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 <Self as fmt::Display>::fmt(self, f)
70 }
71}
src/bootstrap/src/core/builder/tests.rs+1-1
...@@ -346,7 +346,7 @@ fn test_test_coverage() {...@@ -346,7 +346,7 @@ fn test_test_coverage() {
346 let mut cache = run_build(&config.paths.clone(), config);346 let mut cache = run_build(&config.paths.clone(), config);
347347
348 let modes =348 let modes =
349 cache.all::<test::Coverage>().iter().map(|(step, ())| step.mode).collect::<Vec<_>>();349 cache.inspect_all_steps_of_type::<test::Coverage, _>(|step, ()| step.mode.as_str());
350 assert_eq!(modes, expected);350 assert_eq!(modes, expected);
351 }351 }
352}352}
src/bootstrap/src/utils/cache.rs+11-9
...@@ -270,16 +270,18 @@ impl Cache {...@@ -270,16 +270,18 @@ impl Cache {
270270
271#[cfg(test)]271#[cfg(test)]
272impl Cache {272impl Cache {
273 pub fn all<S: Ord + Step>(&mut self) -> Vec<(S, S::Output)> {273 pub(crate) fn inspect_all_steps_of_type<S: Step, T: Ord>(
274 let cache = self.cache.get_mut();274 &self,
275 let type_id = TypeId::of::<S>();275 map_fn: impl Fn(&S, &S::Output) -> T,
276 let mut v = cache276 ) -> Vec<T> {
277 .remove(&type_id)277 let cache = self.cache.borrow();
278 .map(|b| b.downcast::<HashMap<S, S::Output>>().expect("correct type"))278 let mut values = cache
279 .map(|m| m.into_iter().collect::<Vec<_>>())279 .get(&TypeId::of::<S>())
280 .map(|any| any.downcast_ref::<HashMap<S, S::Output>>().expect("correct type"))
281 .map(|m| m.iter().map(|(step, output)| map_fn(step, output)).collect::<Vec<_>>())
280 .unwrap_or_default();282 .unwrap_or_default();
281 v.sort_by_key(|(s, _)| s.clone());283 values.sort();
282 v284 values
283 }285 }
284286
285 pub fn contains<S: Step>(&self) -> bool {287 pub fn contains<S: Step>(&self) -> bool {
src/doc/rustdoc/src/write-documentation/the-doc-attribute.md+2-2
...@@ -4,8 +4,8 @@ The `#[doc]` attribute lets you control various aspects of how `rustdoc` does...@@ -4,8 +4,8 @@ The `#[doc]` attribute lets you control various aspects of how `rustdoc` does
4its job.4its job.
55
6The most basic function of `#[doc]` is to handle the actual documentation6The most basic function of `#[doc]` is to handle the actual documentation
7text. That is, `///` is syntax sugar for `#[doc]`. This means that these two7text. That is, `///` is syntax sugar for `#[doc]` (as is `//!` for `#![doc]`).
8are the same:8This means that these two are the same:
99
10```rust,no_run10```rust,no_run
11/// This is a doc comment.11/// This is a doc comment.
src/tools/compiletest/src/lib.rs+14-14
...@@ -255,8 +255,17 @@ fn parse_config(args: Vec<String>) -> Config {...@@ -255,8 +255,17 @@ fn parse_config(args: Vec<String>) -> Config {
255 }255 }
256 }256 }
257257
258 let target = opt_str2(matches.opt_str("target"));258 let host = matches.opt_str("host").expect("`--host` must be unconditionally specified");
259 let target = matches.opt_str("target").expect("`--target` must be unconditionally specified");
260
259 let android_cross_path = matches.opt_str("android-cross-path").map(Utf8PathBuf::from);261 let android_cross_path = matches.opt_str("android-cross-path").map(Utf8PathBuf::from);
262
263 // FIXME: `adb_path` should be an `Option<Utf8PathBuf>`...
264 let adb_path = matches.opt_str("adb-path").map(Utf8PathBuf::from).unwrap_or_default();
265 // FIXME: `adb_test_dir` should be an `Option<Utf8PathBuf>`...
266 let adb_test_dir = matches.opt_str("adb-test-dir").map(Utf8PathBuf::from).unwrap_or_default();
267 let adb_device_status = target.contains("android") && !adb_test_dir.as_str().is_empty();
268
260 // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config!269 // FIXME: `cdb_version` is *derived* from cdb, but it's *not* technically a config!
261 let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target);270 let cdb = debuggers::discover_cdb(matches.opt_str("cdb"), &target);
262 let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version);271 let cdb_version = cdb.as_deref().and_then(debuggers::query_cdb_version);
...@@ -433,7 +442,7 @@ fn parse_config(args: Vec<String>) -> Config {...@@ -433,7 +442,7 @@ fn parse_config(args: Vec<String>) -> Config {
433 optimize_tests: matches.opt_present("optimize-tests"),442 optimize_tests: matches.opt_present("optimize-tests"),
434 rust_randomized_layout: matches.opt_present("rust-randomized-layout"),443 rust_randomized_layout: matches.opt_present("rust-randomized-layout"),
435 target,444 target,
436 host: opt_str2(matches.opt_str("host")),445 host,
437 cdb,446 cdb,
438 cdb_version,447 cdb_version,
439 gdb,448 gdb,
...@@ -443,11 +452,9 @@ fn parse_config(args: Vec<String>) -> Config {...@@ -443,11 +452,9 @@ fn parse_config(args: Vec<String>) -> Config {
443 llvm_version,452 llvm_version,
444 system_llvm: matches.opt_present("system-llvm"),453 system_llvm: matches.opt_present("system-llvm"),
445 android_cross_path,454 android_cross_path,
446 adb_path: Utf8PathBuf::from(opt_str2(matches.opt_str("adb-path"))),455 adb_path,
447 adb_test_dir: Utf8PathBuf::from(opt_str2(matches.opt_str("adb-test-dir"))),456 adb_test_dir,
448 adb_device_status: opt_str2(matches.opt_str("target")).contains("android")457 adb_device_status,
449 && "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
450 && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
451 verbose: matches.opt_present("verbose"),458 verbose: matches.opt_present("verbose"),
452 only_modified: matches.opt_present("only-modified"),459 only_modified: matches.opt_present("only-modified"),
453 color,460 color,
...@@ -493,13 +500,6 @@ fn parse_config(args: Vec<String>) -> Config {...@@ -493,13 +500,6 @@ fn parse_config(args: Vec<String>) -> Config {
493 }500 }
494}501}
495502
496fn opt_str2(maybestr: Option<String>) -> String {
497 match maybestr {
498 None => "(none)".to_owned(),
499 Some(s) => s,
500 }
501}
502
503/// Called by `main` after the config has been parsed.503/// Called by `main` after the config has been parsed.
504fn run_tests(config: Arc<Config>) {504fn run_tests(config: Arc<Config>) {
505 debug!(?config, "run_tests");505 debug!(?config, "run_tests");
tests/pretty/delegation_inline_attribute.pp created+94
...@@ -0,0 +1,94 @@
1//@ pretty-compare-only
2//@ pretty-mode:hir
3//@ pp-exact:delegation_inline_attribute.pp
4
5#![allow(incomplete_features)]
6#![feature(fn_delegation)]
7#[attr = MacroUse {arguments: UseAll}]
8extern crate std;
9#[prelude_import]
10use ::std::prelude::rust_2015::*;
11
12mod to_reuse {
13 fn foo(x: usize) -> usize { x }
14}
15
16// Check that #[inline(hint)] is added to foo reuse
17#[attr = Inline(Hint)]
18fn bar(arg0: _) -> _ { to_reuse::foo(self + 1) }
19
20trait Trait {
21 fn foo(&self) { }
22 fn foo1(&self) { }
23 fn foo2(&self) { }
24 fn foo3(&self) { }
25 fn foo4(&self) { }
26}
27
28impl Trait for u8 { }
29
30struct S(u8);
31
32mod to_import {
33 fn check(arg: &'_ u8) -> &'_ u8 { arg }
34}
35
36impl Trait for S {
37 // Check that #[inline(hint)] is added to foo reuse
38 #[attr = Inline(Hint)]
39 fn foo(self: _)
40 ->
41 _ {
42 {
43 // Check that #[inline(hint)] is added to foo0 reuse inside another reuse
44 #[attr = Inline(Hint)]
45 fn foo0(arg0: _) -> _ { to_reuse::foo(self + 1) }
46
47 // Check that #[inline(hint)] is added when other attributes present in inner reuse
48 #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
49 #[attr = MustUse]
50 #[attr = Cold]
51 #[attr = Inline(Hint)]
52 fn foo1(arg0: _) -> _ { to_reuse::foo(self / 2) }
53
54 // Check that #[inline(never)] is preserved in inner reuse
55 #[attr = Inline(Never)]
56 fn foo2(arg0: _) -> _ { to_reuse::foo(self / 2) }
57
58 // Check that #[inline(always)] is preserved in inner reuse
59 #[attr = Inline(Always)]
60 fn foo3(arg0: _) -> _ { to_reuse::foo(self / 2) }
61
62 // Check that #[inline(never)] is preserved when there are other attributes in inner reuse
63 #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
64 #[attr = Inline(Never)]
65 #[attr = MustUse]
66 #[attr = Cold]
67 fn foo4(arg0: _) -> _ { to_reuse::foo(self / 2) }
68 }.foo()
69 }
70
71 // Check that #[inline(hint)] is added when there are other attributes present in trait reuse
72 #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
73 #[attr = MustUse]
74 #[attr = Cold]
75 #[attr = Inline(Hint)]
76 fn foo1(self: _) -> _ { self.0.foo1() }
77
78 // Check that #[inline(never)] is preserved in trait reuse
79 #[attr = Inline(Never)]
80 fn foo2(self: _) -> _ { self.0.foo2() }
81
82 // Check that #[inline(always)] is preserved in trait reuse
83 #[attr = Inline(Always)]
84 fn foo3(self: _) -> _ { self.0.foo3() }
85
86 // Check that #[inline(never)] is preserved when there are other attributes in trait reuse
87 #[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
88 #[attr = Inline(Never)]
89 #[attr = MustUse]
90 #[attr = Cold]
91 fn foo4(self: _) -> _ { self.0.foo4() }
92}
93
94fn main() { }
tests/pretty/delegation_inline_attribute.rs created+104
...@@ -0,0 +1,104 @@
1//@ pretty-compare-only
2//@ pretty-mode:hir
3//@ pp-exact:delegation_inline_attribute.pp
4
5#![allow(incomplete_features)]
6#![feature(fn_delegation)]
7
8mod to_reuse {
9 pub fn foo(x: usize) -> usize {
10 x
11 }
12}
13
14// Check that #[inline(hint)] is added to foo reuse
15reuse to_reuse::foo as bar {
16 self + 1
17}
18
19trait Trait {
20 fn foo(&self) {}
21 fn foo1(&self) {}
22 fn foo2(&self) {}
23 fn foo3(&self) {}
24 fn foo4(&self) {}
25}
26
27impl Trait for u8 {}
28
29struct S(u8);
30
31mod to_import {
32 pub fn check(arg: &u8) -> &u8 { arg }
33}
34
35impl Trait for S {
36 // Check that #[inline(hint)] is added to foo reuse
37 reuse Trait::foo {
38 // Check that #[inline(hint)] is added to foo0 reuse inside another reuse
39 reuse to_reuse::foo as foo0 {
40 self + 1
41 }
42
43 // Check that #[inline(hint)] is added when other attributes present in inner reuse
44 #[cold]
45 #[must_use]
46 #[deprecated]
47 reuse to_reuse::foo as foo1 {
48 self / 2
49 }
50
51 // Check that #[inline(never)] is preserved in inner reuse
52 #[inline(never)]
53 reuse to_reuse::foo as foo2 {
54 self / 2
55 }
56
57 // Check that #[inline(always)] is preserved in inner reuse
58 #[inline(always)]
59 reuse to_reuse::foo as foo3 {
60 self / 2
61 }
62
63 // Check that #[inline(never)] is preserved when there are other attributes in inner reuse
64 #[cold]
65 #[must_use]
66 #[inline(never)]
67 #[deprecated]
68 reuse to_reuse::foo as foo4 {
69 self / 2
70 }
71 }
72
73 // Check that #[inline(hint)] is added when there are other attributes present in trait reuse
74 #[cold]
75 #[must_use]
76 #[deprecated]
77 reuse Trait::foo1 {
78 self.0
79 }
80
81 // Check that #[inline(never)] is preserved in trait reuse
82 #[inline(never)]
83 reuse Trait::foo2 {
84 self.0
85 }
86
87 // Check that #[inline(always)] is preserved in trait reuse
88 #[inline(always)]
89 reuse Trait::foo3 {
90 self.0
91 }
92
93 // Check that #[inline(never)] is preserved when there are other attributes in trait reuse
94 #[cold]
95 #[must_use]
96 #[inline(never)]
97 #[deprecated]
98 reuse Trait::foo4 {
99 self.0
100 }
101}
102
103fn main() {
104}
tests/pretty/hir-delegation.pp+2
...@@ -12,6 +12,7 @@ use ::std::prelude::rust_2015::*;...@@ -12,6 +12,7 @@ use ::std::prelude::rust_2015::*;
12fn b<C>(e: C) { }12fn b<C>(e: C) { }
1313
14trait G {14trait G {
15 #[attr = Inline(Hint)]
15 fn b(arg0: _) -> _ { b({ }) }16 fn b(arg0: _) -> _ { b({ }) }
16}17}
1718
...@@ -19,6 +20,7 @@ mod m {...@@ -19,6 +20,7 @@ mod m {
19 fn add(a: u32, b: u32) -> u32 { a + b }20 fn add(a: u32, b: u32) -> u32 { a + b }
20}21}
2122
23#[attr = Inline(Hint)]
22fn add(arg0: _, arg1: _) -> _ { m::add(arg0, arg1) }24fn add(arg0: _, arg1: _) -> _ { m::add(arg0, arg1) }
2325
24fn main() { { let _ = add(1, 2); }; }26fn main() { { let _ = add(1, 2); }; }
tests/run-make/no-builtins-linker-plugin-lto/main.rs created+3
...@@ -0,0 +1,3 @@
1fn main() {
2 no_builtins::foo();
3}
tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs created+4
...@@ -0,0 +1,4 @@
1#![no_builtins]
2
3#[inline(never)]
4pub fn foo() {}
tests/run-make/no-builtins-linker-plugin-lto/rmake.rs created+53
...@@ -0,0 +1,53 @@
1//@ only-x86_64-unknown-linux-gnu
2
3use std::fs;
4use std::path::Path;
5
6use run_make_support::{cwd, has_extension, llvm_ar, llvm_bcanalyzer, rust_lib_name, rustc};
7
8// A regression test for #146133.
9
10fn main() {
11 // Compile a `#![no_builtins]` rlib crate with `-Clinker-plugin-lto`.
12 // It is acceptable to generate bitcode for rlib, so there is no need to check something.
13 rustc().input("no_builtins.rs").crate_type("rlib").linker_plugin_lto("on").run();
14
15 // Checks that rustc's LTO doesn't emit any bitcode to the linker.
16 let stdout = rustc()
17 .input("main.rs")
18 .extern_("no_builtins", rust_lib_name("no_builtins"))
19 .lto("thin")
20 .print("link-args")
21 .arg("-Csave-temps")
22 .arg("-Clinker-features=-lld")
23 .run()
24 .stdout_utf8();
25 for object in stdout
26 .split_whitespace()
27 .map(|s| s.trim_matches('"'))
28 .filter(|path| has_extension(path, "rlib") || has_extension(path, "o"))
29 {
30 let object_path = if !fs::exists(object).unwrap() {
31 cwd().join(object)
32 } else {
33 Path::new(object).to_path_buf()
34 };
35 if has_extension(object, "rlib") {
36 let ar_stdout = llvm_ar().arg("t").arg(&object_path).run().stdout_utf8();
37 llvm_ar().extract().arg(&object_path).run();
38 for object in ar_stdout.split_whitespace().filter(|o| has_extension(o, "o")) {
39 let object_path = cwd().join(object);
40 not_bitcode(&object_path);
41 }
42 } else {
43 not_bitcode(&object_path);
44 }
45 }
46}
47
48fn not_bitcode(object: &Path) {
49 llvm_bcanalyzer()
50 .input(object)
51 .run_fail()
52 .assert_stderr_contains("llvm-bcanalyzer: Invalid record at top-level");
53}
tests/ui/check-cfg/nested-cfg.rs created+8
...@@ -0,0 +1,8 @@
1//@ check-pass
2
3#[cfg(unknown)] //~ WARN unexpected `cfg` condition name
4#[cfg(false)]
5#[cfg(unknown)] // Should not warn
6fn foo() {}
7
8fn main() {}
tests/ui/check-cfg/nested-cfg.stderr created+23
...@@ -0,0 +1,23 @@
1warning: unexpected `cfg` condition name: `unknown`
2 --> $DIR/nested-cfg.rs:3:7
3 |
4LL | #[cfg(unknown)]
5 | ^^^^^^^
6 |
7 = help: expected names are: `FALSE` and `test` and 31 more
8 = help: to expect this configuration use `--check-cfg=cfg(unknown)`
9 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
10 = note: `#[warn(unexpected_cfgs)]` on by default
11help: found config with similar value
12 |
13LL - #[cfg(unknown)]
14LL + #[cfg(target_os = "unknown")]
15 |
16help: found config with similar value
17 |
18LL - #[cfg(unknown)]
19LL + #[cfg(target_vendor = "unknown")]
20 |
21
22warning: 1 warning emitted
23
tests/ui/feature-gates/feature-gate-link_cfg.rs+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1#[link(name = "foo", cfg(foo))]1#[link(name = "foo", cfg(false))]
2//~^ ERROR: is unstable2//~^ ERROR: is unstable
3extern "C" {}3extern "C" {}
44
tests/ui/feature-gates/feature-gate-link_cfg.stderr+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1error[E0658]: link cfg is unstable1error[E0658]: link cfg is unstable
2 --> $DIR/feature-gate-link_cfg.rs:1:222 --> $DIR/feature-gate-link_cfg.rs:1:22
3 |3 |
4LL | #[link(name = "foo", cfg(foo))]4LL | #[link(name = "foo", cfg(false))]
5 | ^^^^^^^^5 | ^^^^^^^^^^
6 |6 |
7 = help: add `#![feature(link_cfg)]` to the crate attributes to enable7 = help: add `#![feature(link_cfg)]` to the crate attributes to enable
8 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date8 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
tests/ui/link-native-libs/link-cfg-works.rs+1-1
...@@ -7,7 +7,7 @@...@@ -7,7 +7,7 @@
7extern crate link_cfg_works_transitive_dylib;7extern crate link_cfg_works_transitive_dylib;
8extern crate link_cfg_works_transitive_rlib;8extern crate link_cfg_works_transitive_rlib;
99
10#[link(name = "foo", cfg(foo))]10#[link(name = "foo", cfg(false))]
11extern "C" {}11extern "C" {}
1212
13fn main() {}13fn main() {}
tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs created+10
...@@ -0,0 +1,10 @@
1#![feature(unsafe_binders)]
2#![expect(incomplete_features)]
3#![deny(improper_ctypes)]
4
5extern "C" {
6 fn exit_2(x: unsafe<'a> &'a ());
7 //~^ ERROR `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe
8}
9
10fn main() {}
tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr created+15
...@@ -0,0 +1,15 @@
1error: `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe
2 --> $DIR/unsafe-binder-basic.rs:6:18
3 |
4LL | fn exit_2(x: unsafe<'a> &'a ());
5 | ^^^^^^^^^^^^^^^^^ not FFI-safe
6 |
7 = note: unsafe binders are incompatible with foreign function interfaces
8note: the lint level is defined here
9 --> $DIR/unsafe-binder-basic.rs:3:9
10 |
11LL | #![deny(improper_ctypes)]
12 | ^^^^^^^^^^^^^^^
13
14error: aborting due to 1 previous error
15
tests/ui/macros/cfg.rs+2-1
...@@ -2,5 +2,6 @@ fn main() {...@@ -2,5 +2,6 @@ fn main() {
2 cfg!(); //~ ERROR macro requires a cfg-pattern2 cfg!(); //~ ERROR macro requires a cfg-pattern
3 cfg!(123); //~ ERROR malformed `cfg` macro input3 cfg!(123); //~ ERROR malformed `cfg` macro input
4 cfg!(foo = 123); //~ ERROR malformed `cfg` macro input4 cfg!(foo = 123); //~ ERROR malformed `cfg` macro input
5 cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern5 cfg!(false, false); //~ ERROR expected 1 cfg-pattern
6 cfg!(foo); //~ WARN unexpected `cfg` condition name: `foo`
6}7}
tests/ui/macros/cfg.stderr+14-3
...@@ -29,9 +29,20 @@ LL | cfg!(foo = 123);...@@ -29,9 +29,20 @@ LL | cfg!(foo = 123);
29error: expected 1 cfg-pattern29error: expected 1 cfg-pattern
30 --> $DIR/cfg.rs:5:530 --> $DIR/cfg.rs:5:5
31 |31 |
32LL | cfg!(foo, bar);32LL | cfg!(false, false);
33 | ^^^^^^^^^^^^^^33 | ^^^^^^^^^^^^^^^^^^
3434
35error: aborting due to 4 previous errors35warning: unexpected `cfg` condition name: `foo`
36 --> $DIR/cfg.rs:6:10
37 |
38LL | cfg!(foo);
39 | ^^^
40 |
41 = help: expected names are: `FALSE` and `test` and 31 more
42 = help: to expect this configuration use `--check-cfg=cfg(foo)`
43 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
44 = note: `#[warn(unexpected_cfgs)]` on by default
45
46error: aborting due to 4 previous errors; 1 warning emitted
3647
37For more information about this error, try `rustc --explain E0539`.48For more information about this error, try `rustc --explain E0539`.
tests/ui/macros/cfg_select.rs+2
...@@ -89,9 +89,11 @@ cfg_select! {...@@ -89,9 +89,11 @@ cfg_select! {
89cfg_select! {89cfg_select! {
90 a + 1 => {}90 a + 1 => {}
91 //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `+`91 //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `+`
92 //~| WARN unexpected `cfg` condition name
92}93}
9394
94cfg_select! {95cfg_select! {
95 cfg!() => {}96 cfg!() => {}
96 //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `!`97 //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `!`
98 //~| WARN unexpected `cfg` condition name
97}99}
tests/ui/macros/cfg_select.stderr+22-2
...@@ -60,12 +60,32 @@ LL | a + 1 => {}...@@ -60,12 +60,32 @@ LL | a + 1 => {}
60 | ^ expected one of `(`, `::`, `=>`, or `=`60 | ^ expected one of `(`, `::`, `=>`, or `=`
6161
62error: expected one of `(`, `::`, `=>`, or `=`, found `!`62error: expected one of `(`, `::`, `=>`, or `=`, found `!`
63 --> $DIR/cfg_select.rs:95:863 --> $DIR/cfg_select.rs:96:8
64 |64 |
65LL | cfg!() => {}65LL | cfg!() => {}
66 | ^ expected one of `(`, `::`, `=>`, or `=`66 | ^ expected one of `(`, `::`, `=>`, or `=`
6767
68error: aborting due to 9 previous errors; 1 warning emitted68warning: unexpected `cfg` condition name: `a`
69 --> $DIR/cfg_select.rs:90:5
70 |
71LL | a + 1 => {}
72 | ^ help: found config with similar value: `target_feature = "a"`
73 |
74 = help: expected names are: `FALSE` and `test` and 31 more
75 = help: to expect this configuration use `--check-cfg=cfg(a)`
76 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
77 = note: `#[warn(unexpected_cfgs)]` on by default
78
79warning: unexpected `cfg` condition name: `cfg`
80 --> $DIR/cfg_select.rs:96:5
81 |
82LL | cfg!() => {}
83 | ^^^
84 |
85 = help: to expect this configuration use `--check-cfg=cfg(cfg)`
86 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
87
88error: aborting due to 9 previous errors; 3 warnings emitted
6989
70Some errors have detailed explanations: E0537, E0539.90Some errors have detailed explanations: E0537, E0539.
71For more information about an error, try `rustc --explain E0537`.91For more information about an error, try `rustc --explain E0537`.
tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs created+13
...@@ -0,0 +1,13 @@
1// Auxiliary crate for testing non-exhaustive struct with private fields
2
3#[non_exhaustive]
4pub struct Foo {
5 pub my_field: u32,
6 private_field: i32,
7}
8
9#[non_exhaustive]
10pub struct Bar {
11 pub my_field: u32,
12 pub missing_field: i32,
13}
tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs created+17
...@@ -0,0 +1,17 @@
1//@ aux-build:non_exhaustive_with_private.rs
2
3extern crate non_exhaustive_with_private;
4
5use non_exhaustive_with_private::{Bar, Foo};
6
7fn main() {
8 let foo = Foo {
9 //~^ ERROR cannot create non-exhaustive struct using struct expression
10 my_field: 10,
11 };
12
13 let bar = Bar {
14 //~^ ERROR cannot create non-exhaustive struct using struct expression
15 my_field: 10,
16 };
17}
tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr created+23
...@@ -0,0 +1,23 @@
1error[E0639]: cannot create non-exhaustive struct using struct expression
2 --> $DIR/non-exhaustive-with-private-fields-147513.rs:8:15
3 |
4LL | let foo = Foo {
5 | _______________^
6LL | |
7LL | | my_field: 10,
8LL | | };
9 | |_____^
10
11error[E0639]: cannot create non-exhaustive struct using struct expression
12 --> $DIR/non-exhaustive-with-private-fields-147513.rs:13:15
13 |
14LL | let bar = Bar {
15 | _______________^
16LL | |
17LL | | my_field: 10,
18LL | | };
19 | |_____^
20
21error: aborting due to 2 previous errors
22
23For more information about this error, try `rustc --explain E0639`.
triagebot.toml-6
...@@ -1679,12 +1679,6 @@ days-threshold = 28...@@ -1679,12 +1679,6 @@ days-threshold = 28
1679# Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html1679# Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html
1680[issue-links]1680[issue-links]
16811681
1682# Prevents mentions in commits to avoid users being spammed
1683# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html
1684[no-mentions]
1685# Subtree update authors can't fix it, no point in warning.
1686exclude-titles = ["subtree update"]
1687
1688# Allow members to formally register concerns (`@rustbot concern my concern`)1682# Allow members to formally register concerns (`@rustbot concern my concern`)
1689# Documentation at: https://forge.rust-lang.org/triagebot/concern.html1683# Documentation at: https://forge.rust-lang.org/triagebot/concern.html
1690[concern]1684[concern]