authorbors <bors@rust-lang.org> 2024-08-12 16:31:22 UTC
committerbors <bors@rust-lang.org> 2024-08-12 16:31:22 UTC
log91376f416222a238227c84a848d168835ede2cc3
tree0dc7b9f6c09c2de39e702cb4751563c12b254835
parente08b80c0fb7667bdcd040761891701e576c42ec8
parent99a785d62d8414e5db435f4e699eabd185257d49

Auto merge of #129008 - GuillaumeGomez:rollup-6citttb, r=GuillaumeGomez

Rollup of 10 pull requests Successful merges: - #128149 (nontemporal_store: make sure that the intrinsic is truly just a hint) - #128394 (Unify run button display with "copy code" button and with mdbook buttons) - #128537 (const vector passed through to codegen) - #128632 (std: do not overwrite style in `get_backtrace_style`) - #128878 (Slightly refactor `Flags` in bootstrap) - #128886 (Get rid of some `#[allow(rustc::untranslatable_diagnostic)]`) - #128929 (Fix codegen-units tests that were disabled 8 years ago) - #128937 (Fix warnings in rmake tests on `x86_64-unknown-linux-gnu`) - #128978 (Use `assert_matches` around the compiler more) - #128994 (Fix bug in `Parser::look_ahead`.) r? `@ghost` `@rustbot` modify labels: rollup

132 files changed, 789 insertions(+), 449 deletions(-)

compiler/rustc_ast_lowering/messages.ftl+12
......@@ -167,11 +167,23 @@ ast_lowering_template_modifier = template modifier
167167
168168ast_lowering_this_not_async = this is not `async`
169169
170ast_lowering_underscore_array_length_unstable =
171 using `_` for array lengths is unstable
172
170173ast_lowering_underscore_expr_lhs_assign =
171174 in expressions, `_` can only be used on the left-hand side of an assignment
172175 .label = `_` not allowed here
173176
177ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
178ast_lowering_unstable_inline_assembly_const_operands =
179 const operands for inline assembly are unstable
180ast_lowering_unstable_inline_assembly_label_operands =
181 label operands for inline assembly are unstable
182ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
183
174184ast_lowering_use_angle_brackets = use angle brackets instead
185
186ast_lowering_yield = yield syntax is experimental
175187ast_lowering_yield_in_closure =
176188 `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
177189 .suggestion = use `#[coroutine]` to make this closure a coroutine
compiler/rustc_ast_lowering/src/asm.rs+14-7
......@@ -19,10 +19,12 @@ use super::errors::{
1919 InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict,
2020};
2121use super::LoweringContext;
22use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt};
22use crate::{
23 fluent_generated as fluent, ImplTraitContext, ImplTraitPosition, ParamMode,
24 ResolverAstLoweringExt,
25};
2326
2427impl<'a, 'hir> LoweringContext<'a, 'hir> {
25 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
2628 pub(crate) fn lower_inline_asm(
2729 &mut self,
2830 sp: Span,
......@@ -52,7 +54,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
5254 &self.tcx.sess,
5355 sym::asm_experimental_arch,
5456 sp,
55 "inline assembly is not stable yet on this architecture",
57 fluent::ast_lowering_unstable_inline_assembly,
5658 )
5759 .emit();
5860 }
......@@ -64,8 +66,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6466 self.dcx().emit_err(AttSyntaxOnlyX86 { span: sp });
6567 }
6668 if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
67 feature_err(&self.tcx.sess, sym::asm_unwind, sp, "the `may_unwind` option is unstable")
68 .emit();
69 feature_err(
70 &self.tcx.sess,
71 sym::asm_unwind,
72 sp,
73 fluent::ast_lowering_unstable_may_unwind,
74 )
75 .emit();
6976 }
7077
7178 let mut clobber_abis = FxIndexMap::default();
......@@ -182,7 +189,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
182189 sess,
183190 sym::asm_const,
184191 *op_sp,
185 "const operands for inline assembly are unstable",
192 fluent::ast_lowering_unstable_inline_assembly_const_operands,
186193 )
187194 .emit();
188195 }
......@@ -246,7 +253,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
246253 sess,
247254 sym::asm_goto,
248255 *op_sp,
249 "label operands for inline assembly are unstable",
256 fluent::ast_lowering_unstable_inline_assembly_label_operands,
250257 )
251258 .emit();
252259 }
compiler/rustc_ast_lowering/src/expr.rs+3-4
......@@ -23,7 +23,7 @@ use super::{
2323 ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs, ResolverAstLoweringExt,
2424};
2525use crate::errors::YieldInClosure;
26use crate::{FnDeclKind, ImplTraitPosition};
26use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
2727
2828impl<'hir> LoweringContext<'_, 'hir> {
2929 fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
......@@ -1540,7 +1540,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
15401540 }
15411541 }
15421542
1543 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
15441543 fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
15451544 let yielded =
15461545 opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
......@@ -1575,7 +1574,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15751574 &self.tcx.sess,
15761575 sym::coroutines,
15771576 span,
1578 "yield syntax is experimental",
1577 fluent_generated::ast_lowering_yield,
15791578 )
15801579 .emit();
15811580 }
......@@ -1587,7 +1586,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15871586 &self.tcx.sess,
15881587 sym::coroutines,
15891588 span,
1590 "yield syntax is experimental",
1589 fluent_generated::ast_lowering_yield,
15911590 )
15921591 .emit();
15931592 }
compiler/rustc_ast_lowering/src/lib.rs+1-2
......@@ -2326,7 +2326,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23262326 self.expr_block(block)
23272327 }
23282328
2329 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
23302329 fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen<'hir> {
23312330 match c.value.kind {
23322331 ExprKind::Underscore => {
......@@ -2340,7 +2339,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23402339 &self.tcx.sess,
23412340 sym::generic_arg_infer,
23422341 c.value.span,
2343 "using `_` for array lengths is unstable",
2342 fluent_generated::ast_lowering_underscore_array_length_unstable,
23442343 )
23452344 .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
23462345 hir::ArrayLen::Body(self.lower_anon_const_to_const_arg(c))
compiler/rustc_attr/messages.ftl+3
......@@ -104,6 +104,9 @@ attr_unknown_meta_item =
104104attr_unknown_version_literal =
105105 unknown version literal format, assuming it refers to a future version
106106
107attr_unstable_cfg_target_compact =
108 compact `cfg(target(..))` is experimental and subject to change
109
107110attr_unsupported_literal_cfg_string =
108111 literal in `cfg` predicate value must be a string
109112attr_unsupported_literal_deprecated_kv_pair =
compiler/rustc_attr/src/builtin.rs+2-3
......@@ -20,6 +20,7 @@ use rustc_span::hygiene::Transparency;
2020use rustc_span::symbol::{sym, Symbol};
2121use rustc_span::Span;
2222
23use crate::fluent_generated;
2324use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
2425
2526/// The version placeholder that recently stabilized features contain inside the
......@@ -521,7 +522,6 @@ pub struct Condition {
521522}
522523
523524/// Tests if a cfg-pattern matches the cfg set
524#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
525525pub fn cfg_matches(
526526 cfg: &ast::MetaItem,
527527 sess: &Session,
......@@ -593,7 +593,6 @@ pub fn parse_version(s: Symbol) -> Option<RustcVersion> {
593593
594594/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
595595/// evaluate individual items.
596#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
597596pub fn eval_condition(
598597 cfg: &ast::MetaItem,
599598 sess: &Session,
......@@ -680,7 +679,7 @@ pub fn eval_condition(
680679 sess,
681680 sym::cfg_target_compact,
682681 cfg.span,
683 "compact `cfg(target(..))` is experimental and subject to change",
682 fluent_generated::attr_unstable_cfg_target_compact,
684683 )
685684 .emit();
686685 }
compiler/rustc_borrowck/messages.ftl+21
......@@ -62,6 +62,9 @@ borrowck_could_not_normalize =
6262borrowck_could_not_prove =
6363 could not prove `{$predicate}`
6464
65borrowck_dereference_suggestion =
66 dereference the return value
67
6568borrowck_func_take_self_moved_place =
6669 `{$func}` takes ownership of the receiver `self`, which moves {$place_name}
6770
......@@ -74,9 +77,24 @@ borrowck_higher_ranked_lifetime_error =
7477borrowck_higher_ranked_subtype_error =
7578 higher-ranked subtype error
7679
80borrowck_implicit_static =
81 this has an implicit `'static` lifetime requirement
82
83borrowck_implicit_static_introduced =
84 calling this method introduces the `impl`'s `'static` requirement
85
86borrowck_implicit_static_relax =
87 consider relaxing the implicit `'static` requirement
88
7789borrowck_lifetime_constraints_error =
7890 lifetime may not live long enough
7991
92borrowck_limitations_implies_static =
93 due to current limitations in the borrow checker, this implies a `'static` lifetime
94
95borrowck_move_closure_suggestion =
96 consider adding 'move' keyword before the nested closure
97
8098borrowck_move_out_place_here =
8199 {$place} is moved here
82100
......@@ -163,6 +181,9 @@ borrowck_partial_var_move_by_use_in_coroutine =
163181 *[false] moved
164182 } due to use in coroutine
165183
184borrowck_restrict_to_static =
185 consider restricting the type parameter to the `'static` lifetime
186
166187borrowck_returned_async_block_escaped =
167188 returns an `async` block that contains a reference to a captured variable, which then escapes the closure body
168189
compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs+4-2
......@@ -3,6 +3,8 @@
33#![allow(rustc::diagnostic_outside_of_impl)]
44#![allow(rustc::untranslatable_diagnostic)]
55
6use std::assert_matches::assert_matches;
7
68use rustc_errors::{Applicability, Diag};
79use rustc_hir as hir;
810use rustc_hir::intravisit::Visitor;
......@@ -116,7 +118,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
116118 // path_span must be `Some` as otherwise the if condition is true
117119 let path_span = path_span.unwrap();
118120 // path_span is only present in the case of closure capture
119 assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
121 assert_matches!(later_use_kind, LaterUseKind::ClosureCapture);
120122 if !borrow_span.is_some_and(|sp| sp.overlaps(var_or_use_span)) {
121123 let path_label = "used here by closure";
122124 let capture_kind_label = message;
......@@ -147,7 +149,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
147149 // path_span must be `Some` as otherwise the if condition is true
148150 let path_span = path_span.unwrap();
149151 // path_span is only present in the case of closure capture
150 assert!(matches!(later_use_kind, LaterUseKind::ClosureCapture));
152 assert_matches!(later_use_kind, LaterUseKind::ClosureCapture);
151153 if borrow_span.map(|sp| !sp.overlaps(var_or_use_span)).unwrap_or(true) {
152154 let path_label = "used here by closure";
153155 let capture_kind_label = message;
compiler/rustc_borrowck/src/diagnostics/region_errors.rs+31-33
......@@ -35,7 +35,7 @@ use crate::session_diagnostics::{
3535 LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
3636};
3737use crate::universal_regions::DefiningTy;
38use crate::{borrowck_errors, MirBorrowckCtxt};
38use crate::{borrowck_errors, fluent_generated as fluent, MirBorrowckCtxt};
3939
4040impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
4141 fn description(&self) -> &'static str {
......@@ -198,7 +198,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
198198 // from higher-ranked trait bounds (HRTB). Try to locate span of the trait
199199 // and the span which bounded to the trait for adding 'static lifetime suggestion
200200 #[allow(rustc::diagnostic_outside_of_impl)]
201 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
202201 fn suggest_static_lifetime_for_gat_from_hrtb(
203202 &self,
204203 diag: &mut Diag<'_>,
......@@ -251,23 +250,28 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
251250 debug!(?hrtb_bounds);
252251
253252 hrtb_bounds.iter().for_each(|bound| {
254 let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; };
255 diag.span_note(
256 *trait_span,
257 "due to current limitations in the borrow checker, this implies a `'static` lifetime"
258 );
259 let Some(generics_fn) = hir.get_generics(self.body.source.def_id().expect_local()) else { return; };
260 let Def(_, trait_res_defid) = trait_ref.path.res else { return; };
253 let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else {
254 return;
255 };
256 diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static);
257 let Some(generics_fn) = hir.get_generics(self.body.source.def_id().expect_local())
258 else {
259 return;
260 };
261 let Def(_, trait_res_defid) = trait_ref.path.res else {
262 return;
263 };
261264 debug!(?generics_fn);
262265 generics_fn.predicates.iter().for_each(|predicate| {
263 let BoundPredicate(
264 WhereBoundPredicate {
265 span: bounded_span,
266 bounded_ty,
267 bounds,
268 ..
269 }
270 ) = predicate else { return; };
266 let BoundPredicate(WhereBoundPredicate {
267 span: bounded_span,
268 bounded_ty,
269 bounds,
270 ..
271 }) = predicate
272 else {
273 return;
274 };
271275 bounds.iter().for_each(|bd| {
272276 if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }, _) = bd
273277 && let Def(_, res_defid) = tr_ref.path.res
......@@ -277,16 +281,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
277281 && generics_fn.params
278282 .iter()
279283 .rfind(|param| param.def_id.to_def_id() == defid)
280 .is_some() {
281 suggestions.push((bounded_span.shrink_to_hi(), " + 'static".to_string()));
282 }
284 .is_some()
285 {
286 suggestions.push((bounded_span.shrink_to_hi(), " + 'static".to_string()));
287 }
283288 });
284289 });
285290 });
286291 if suggestions.len() > 0 {
287292 suggestions.dedup();
288293 diag.multipart_suggestion_verbose(
289 "consider restricting the type parameter to the `'static` lifetime",
294 fluent::borrowck_restrict_to_static,
290295 suggestions,
291296 Applicability::MaybeIncorrect,
292297 );
......@@ -976,7 +981,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
976981 }
977982
978983 #[allow(rustc::diagnostic_outside_of_impl)]
979 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
980984 #[instrument(skip(self, err), level = "debug")]
981985 fn suggest_constrain_dyn_trait_in_impl(
982986 &self,
......@@ -994,16 +998,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
994998 debug!("trait spans found: {:?}", traits);
995999 for span in &traits {
9961000 let mut multi_span: MultiSpan = vec![*span].into();
997 multi_span
998 .push_span_label(*span, "this has an implicit `'static` lifetime requirement");
999 multi_span.push_span_label(
1000 ident.span,
1001 "calling this method introduces the `impl`'s `'static` requirement",
1002 );
1001 multi_span.push_span_label(*span, fluent::borrowck_implicit_static);
1002 multi_span.push_span_label(ident.span, fluent::borrowck_implicit_static_introduced);
10031003 err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span });
10041004 err.span_suggestion_verbose(
10051005 span.shrink_to_hi(),
1006 "consider relaxing the implicit `'static` requirement",
1006 fluent::borrowck_implicit_static_relax,
10071007 " + '_",
10081008 Applicability::MaybeIncorrect,
10091009 );
......@@ -1045,7 +1045,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
10451045 }
10461046
10471047 #[allow(rustc::diagnostic_outside_of_impl)]
1048 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
10491048 /// When encountering a lifetime error caused by the return type of a closure, check the
10501049 /// corresponding trait bound and see if dereferencing the closure return value would satisfy
10511050 /// them. If so, we produce a structured suggestion.
......@@ -1166,7 +1165,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
11661165 if ocx.select_all_or_error().is_empty() && count > 0 {
11671166 diag.span_suggestion_verbose(
11681167 tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(),
1169 "dereference the return value",
1168 fluent::borrowck_dereference_suggestion,
11701169 "*".repeat(count),
11711170 Applicability::MachineApplicable,
11721171 );
......@@ -1174,7 +1173,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
11741173 }
11751174
11761175 #[allow(rustc::diagnostic_outside_of_impl)]
1177 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
11781176 fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) {
11791177 let map = self.infcx.tcx.hir();
11801178 let body = map.body_owned_by(self.mir_def_id());
......@@ -1213,7 +1211,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
12131211 if let Some(closure_span) = closure_span {
12141212 diag.span_suggestion_verbose(
12151213 closure_span,
1216 "consider adding 'move' keyword before the nested closure",
1214 fluent::borrowck_move_closure_suggestion,
12171215 "move ",
12181216 Applicability::MaybeIncorrect,
12191217 );
compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs+2-1
......@@ -725,7 +725,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
725725
726726 // Cranelift treats stores as volatile by default
727727 // FIXME correctly handle unaligned_volatile_store
728 // FIXME actually do nontemporal stores if requested
728 // FIXME actually do nontemporal stores if requested (but do not just emit MOVNT on x86;
729 // see the LLVM backend for details)
729730 let dest = CPlace::for_ptr(Pointer::new(ptr), val.layout());
730731 dest.write_cvalue(fx, val);
731732 }
compiler/rustc_codegen_gcc/src/builder.rs+2
......@@ -1127,6 +1127,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
11271127 self.llbb().add_assignment(self.location, aligned_destination, val);
11281128 // TODO(antoyo): handle align and flags.
11291129 // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here?
1130 // When adding support for NONTEMPORAL, make sure to not just emit MOVNT on x86; see the
1131 // LLVM backend for details.
11301132 self.cx.context.new_rvalue_zero(self.type_i32())
11311133 }
11321134
compiler/rustc_codegen_gcc/src/common.rs+5
......@@ -160,6 +160,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
160160 self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
161161 }
162162
163 fn const_vector(&self, values: &[RValue<'gcc>]) -> RValue<'gcc> {
164 let typ = self.type_vector(values[0].get_type(), values.len() as u64);
165 self.context.new_rvalue_from_vector(None, typ, values)
166 }
167
163168 fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
164169 // TODO(antoyo)
165170 None
compiler/rustc_codegen_llvm/src/asm.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use libc::{c_char, c_uint};
24use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
35use rustc_codegen_ssa::mir::operand::OperandValue;
......@@ -89,7 +91,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
8991 // if the target feature needed by the register class is
9092 // disabled. This is necessary otherwise LLVM will try
9193 // to actually allocate a register for the dummy output.
92 assert!(matches!(reg, InlineAsmRegOrRegClass::Reg(_)));
94 assert_matches!(reg, InlineAsmRegOrRegClass::Reg(_));
9395 clobbers.push(format!("~{}", reg_to_llvm(reg, None)));
9496 continue;
9597 } else {
compiler/rustc_codegen_llvm/src/builder.rs+26-7
......@@ -728,13 +728,32 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
728728 llvm::LLVMSetVolatile(store, llvm::True);
729729 }
730730 if flags.contains(MemFlags::NONTEMPORAL) {
731 // According to LLVM [1] building a nontemporal store must
732 // *always* point to a metadata value of the integer 1.
733 //
734 // [1]: https://llvm.org/docs/LangRef.html#store-instruction
735 let one = self.cx.const_i32(1);
736 let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
737 llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
731 // Make sure that the current target architectures supports "sane" non-temporal
732 // stores, i.e., non-temporal stores that are equivalent to regular stores except
733 // for performance. LLVM doesn't seem to care about this, and will happily treat
734 // `!nontemporal` stores as-if they were normal stores (for reordering optimizations
735 // etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
736 // regular stores but require special fences.
737 // So we keep a list of architectures where `!nontemporal` is known to be truly just
738 // a hint, and use regular stores everywhere else.
739 // (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt
740 // before any kind of synchronizing operation. But it's not clear how to do that with LLVM.)
741 // For more context, see <https://github.com/rust-lang/rust/issues/114582> and
742 // <https://github.com/llvm/llvm-project/issues/64521>.
743 const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] =
744 &["aarch64", "arm", "riscv32", "riscv64"];
745
746 let use_nontemporal =
747 WELL_BEHAVED_NONTEMPORAL_ARCHS.contains(&&*self.cx.tcx.sess.target.arch);
748 if use_nontemporal {
749 // According to LLVM [1] building a nontemporal store must
750 // *always* point to a metadata value of the integer 1.
751 //
752 // [1]: https://llvm.org/docs/LangRef.html#store-instruction
753 let one = self.cx.const_i32(1);
754 let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
755 llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
756 }
738757 }
739758 store
740759 }
compiler/rustc_codegen_llvm/src/common.rs+5-5
......@@ -97,11 +97,6 @@ impl<'ll> CodegenCx<'ll, '_> {
9797 unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) }
9898 }
9999
100 pub fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
101 let len = c_uint::try_from(elts.len()).expect("LLVMConstVector elements len overflow");
102 unsafe { llvm::LLVMConstVector(elts.as_ptr(), len) }
103 }
104
105100 pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
106101 bytes_in_context(self.llcx, bytes)
107102 }
......@@ -221,6 +216,11 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
221216 struct_in_context(self.llcx, elts, packed)
222217 }
223218
219 fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
220 let len = c_uint::try_from(elts.len()).expect("LLVMConstVector elements len overflow");
221 unsafe { llvm::LLVMConstVector(elts.as_ptr(), len) }
222 }
223
224224 fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
225225 try_as_const_integral(v).and_then(|v| unsafe {
226226 let mut i = 0u64;
compiler/rustc_codegen_llvm/src/intrinsic.rs+2-1
......@@ -1,3 +1,4 @@
1use std::assert_matches::assert_matches;
12use std::cmp::Ordering;
23
34use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
......@@ -1142,7 +1143,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
11421143 if cfg!(debug_assertions) {
11431144 for (ty, arg) in arg_tys.iter().zip(args) {
11441145 if ty.is_simd() {
1145 assert!(matches!(arg.val, OperandValue::Immediate(_)));
1146 assert_matches!(arg.val, OperandValue::Immediate(_));
11461147 }
11471148 }
11481149 }
compiler/rustc_codegen_llvm/src/lib.rs+1
......@@ -8,6 +8,7 @@
88#![allow(internal_features)]
99#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1010#![doc(rust_logo)]
11#![feature(assert_matches)]
1112#![feature(exact_size_is_empty)]
1213#![feature(extern_types)]
1314#![feature(hash_raw_entry)]
compiler/rustc_codegen_ssa/src/back/write.rs+2-1
......@@ -1,4 +1,5 @@
11use std::any::Any;
2use std::assert_matches::assert_matches;
23use std::marker::PhantomData;
34use std::path::{Path, PathBuf};
45use std::sync::mpsc::{channel, Receiver, Sender};
......@@ -1963,7 +1964,7 @@ impl SharedEmitterMain {
19631964 sess.dcx().abort_if_errors();
19641965 }
19651966 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
1966 assert!(matches!(level, Level::Error | Level::Warning | Level::Note));
1967 assert_matches!(level, Level::Error | Level::Warning | Level::Note);
19671968 let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
19681969 let mut err = Diag::<()>::new(sess.dcx(), level, msg);
19691970
compiler/rustc_codegen_ssa/src/lib.rs+1
......@@ -4,6 +4,7 @@
44#![allow(rustc::untranslatable_diagnostic)]
55#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
66#![doc(rust_logo)]
7#![feature(assert_matches)]
78#![feature(box_patterns)]
89#![feature(if_let_guard)]
910#![feature(let_chains)]
compiler/rustc_codegen_ssa/src/mir/block.rs+5-1
......@@ -923,8 +923,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
923923 // third argument must be constant. This is
924924 // checked by the type-checker.
925925 if i == 2 && intrinsic.name == sym::simd_shuffle {
926 // FIXME: the simd_shuffle argument is actually an array,
927 // not a vector, so we need this special hack to make sure
928 // it is passed as an immediate. We should pass the
929 // shuffle indices as a vector instead to avoid this hack.
926930 if let mir::Operand::Constant(constant) = &arg.node {
927 let (llval, ty) = self.simd_shuffle_indices(bx, constant);
931 let (llval, ty) = self.immediate_const_vector(bx, constant);
928932 return OperandRef {
929933 val: Immediate(llval),
930934 layout: bx.layout_of(ty),
compiler/rustc_codegen_ssa/src/mir/constant.rs+29-10
......@@ -1,6 +1,6 @@
11use rustc_middle::mir::interpret::ErrorHandled;
22use rustc_middle::ty::layout::HasTyCtxt;
3use rustc_middle::ty::{self, Ty};
3use rustc_middle::ty::{self, Ty, ValTree};
44use rustc_middle::{bug, mir, span_bug};
55use rustc_target::abi::Abi;
66
......@@ -28,7 +28,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2828 .expect("erroneous constant missed by mono item collection")
2929 }
3030
31 /// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
31 /// This is a convenience helper for `immediate_const_vector`. It has the precondition
3232 /// that the given `constant` is an `Const::Unevaluated` and must be convertible to
3333 /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
3434 ///
......@@ -59,23 +59,42 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
5959 self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span)
6060 }
6161
62 /// process constant containing SIMD shuffle indices
63 pub fn simd_shuffle_indices(
62 /// process constant containing SIMD shuffle indices & constant vectors
63 pub fn immediate_const_vector(
6464 &mut self,
6565 bx: &Bx,
6666 constant: &mir::ConstOperand<'tcx>,
6767 ) -> (Bx::Value, Ty<'tcx>) {
6868 let ty = self.monomorphize(constant.ty());
69 let ty_is_simd = ty.is_simd();
70 // FIXME: ideally we'd assert that this is a SIMD type, but simd_shuffle
71 // in its current form relies on a regular array being passed as an
72 // immediate argument. This hack can be removed once that is fixed.
73 let field_ty = if ty_is_simd {
74 ty.simd_size_and_type(bx.tcx()).1
75 } else {
76 ty.builtin_index().unwrap()
77 };
78
6979 let val = self
7080 .eval_unevaluated_mir_constant_to_valtree(constant)
7181 .ok()
7282 .map(|x| x.ok())
7383 .flatten()
7484 .map(|val| {
75 let field_ty = ty.builtin_index().unwrap();
76 let values: Vec<_> = val
77 .unwrap_branch()
78 .iter()
85 // Depending on whether this is a SIMD type with an array field
86 // or a type with many fields (one for each elements), the valtree
87 // is either a single branch with N children, or a root node
88 // with exactly one child which then in turn has many children.
89 // So we look at the first child to determine whether it is a
90 // leaf or whether we have to go one more layer down.
91 let branch_or_leaf = val.unwrap_branch();
92 let first = branch_or_leaf.get(0).unwrap();
93 let field_iter = match first {
94 ValTree::Branch(_) => first.unwrap_branch().iter(),
95 ValTree::Leaf(_) => branch_or_leaf.iter(),
96 };
97 let values: Vec<_> = field_iter
7998 .map(|field| {
8099 if let Some(prim) = field.try_to_scalar() {
81100 let layout = bx.layout_of(field_ty);
......@@ -84,11 +103,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
84103 };
85104 bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
86105 } else {
87 bug!("simd shuffle field {:?}", field)
106 bug!("field is not a scalar {:?}", field)
88107 }
89108 })
90109 .collect();
91 bx.const_struct(&values, false)
110 if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) }
92111 })
93112 .unwrap_or_else(|| {
94113 bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
compiler/rustc_codegen_ssa/src/mir/operand.rs+20-2
......@@ -1,3 +1,4 @@
1use std::assert_matches::assert_matches;
12use std::fmt;
23
34use arrayvec::ArrayVec;
......@@ -389,7 +390,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
389390 }
390391 // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
391392 (OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => {
392 assert!(matches!(self.layout.abi, Abi::Vector { .. }));
393 assert_matches!(self.layout.abi, Abi::Vector { .. });
393394
394395 let llfield_ty = bx.cx().backend_type(field);
395396
......@@ -635,7 +636,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
635636 self.codegen_consume(bx, place.as_ref())
636637 }
637638
638 mir::Operand::Constant(ref constant) => self.eval_mir_constant_to_operand(bx, constant),
639 mir::Operand::Constant(ref constant) => {
640 let constant_ty = self.monomorphize(constant.ty());
641 // Most SIMD vector constants should be passed as immediates.
642 // (In particular, some intrinsics really rely on this.)
643 if constant_ty.is_simd() {
644 // However, some SIMD types do not actually use the vector ABI
645 // (in particular, packed SIMD types do not). Ensure we exclude those.
646 let layout = bx.layout_of(constant_ty);
647 if let Abi::Vector { .. } = layout.abi {
648 let (llval, ty) = self.immediate_const_vector(bx, constant);
649 return OperandRef {
650 val: OperandValue::Immediate(llval),
651 layout: bx.layout_of(ty),
652 };
653 }
654 }
655 self.eval_mir_constant_to_operand(bx, constant)
656 }
639657 }
640658 }
641659}
compiler/rustc_codegen_ssa/src/mir/rvalue.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use arrayvec::ArrayVec;
24use rustc_middle::ty::adjustment::PointerCoercion;
35use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
......@@ -220,7 +222,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
220222 match operand.val {
221223 OperandValue::Ref(source_place_val) => {
222224 assert_eq!(source_place_val.llextra, None);
223 assert!(matches!(operand_kind, OperandValueKind::Ref));
225 assert_matches!(operand_kind, OperandValueKind::Ref);
224226 Some(bx.load_operand(source_place_val.with_type(cast)).val)
225227 }
226228 OperandValue::ZeroSized => {
compiler/rustc_codegen_ssa/src/traits/builder.rs+4-2
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
24use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
35use rustc_middle::ty::{Instance, Ty};
......@@ -254,10 +256,10 @@ pub trait BuilderMethods<'a, 'tcx>:
254256 } else {
255257 (in_ty, dest_ty)
256258 };
257 assert!(matches!(
259 assert_matches!(
258260 self.cx().type_kind(float_ty),
259261 TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::FP128
260 ));
262 );
261263 assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer);
262264
263265 if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts {
compiler/rustc_codegen_ssa/src/traits/consts.rs+1
......@@ -30,6 +30,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
3030
3131 fn const_str(&self, s: &str) -> (Self::Value, Self::Value);
3232 fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
33 fn const_vector(&self, elts: &[Self::Value]) -> Self::Value;
3334
3435 fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
3536 fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
compiler/rustc_const_eval/messages.ftl+5
......@@ -41,6 +41,8 @@ const_eval_const_context = {$kind ->
4141 *[other] {""}
4242}
4343
44const_eval_const_stable = const-stable functions can only call other const-stable functions
45
4446const_eval_copy_nonoverlapping_overlapping =
4547 `copy_nonoverlapping` called on overlapping ranges
4648
......@@ -201,6 +203,9 @@ const_eval_invalid_vtable_pointer =
201203const_eval_invalid_vtable_trait =
202204 using vtable for trait `{$vtable_trait}` but trait `{$expected_trait}` was expected
203205
206const_eval_lazy_lock =
207 consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
208
204209const_eval_live_drop =
205210 destructor of `{$dropped_ty}` cannot be evaluated at compile-time
206211 .label = the destructor for this type cannot be evaluated in {const_eval_const_context}s
compiler/rustc_const_eval/src/check_consts/check.rs+3-2
......@@ -1,5 +1,6 @@
11//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
22
3use std::assert_matches::assert_matches;
34use std::mem;
45use std::ops::Deref;
56
......@@ -590,7 +591,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
590591 if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
591592 // Int, bool, and char operations are fine.
592593 } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
593 assert!(matches!(
594 assert_matches!(
594595 op,
595596 BinOp::Eq
596597 | BinOp::Ne
......@@ -599,7 +600,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
599600 | BinOp::Ge
600601 | BinOp::Gt
601602 | BinOp::Offset
602 ));
603 );
603604
604605 self.check_op(ops::RawPtrComparison);
605606 } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
compiler/rustc_const_eval/src/check_consts/ops.rs+3-5
......@@ -23,7 +23,7 @@ use rustc_trait_selection::traits::SelectionContext;
2323use tracing::debug;
2424
2525use super::ConstCx;
26use crate::errors;
26use crate::{errors, fluent_generated};
2727
2828#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2929pub enum Status {
......@@ -310,7 +310,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
310310 }
311311
312312 if let ConstContext::Static(_) = ccx.const_kind() {
313 err.note("consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`");
313 err.note(fluent_generated::const_eval_lazy_lock);
314314 }
315315
316316 err
......@@ -334,7 +334,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
334334 // FIXME: make this translatable
335335 #[allow(rustc::untranslatable_diagnostic)]
336336 if ccx.is_const_stable_const_fn() {
337 err.help("const-stable functions can only call other const-stable functions");
337 err.help(fluent_generated::const_eval_const_stable);
338338 } else if ccx.tcx.sess.is_nightly_build() {
339339 if let Some(feature) = feature {
340340 err.help(format!("add `#![feature({feature})]` to the crate attributes to enable"));
......@@ -605,8 +605,6 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
605605 span,
606606 format!("referencing statics in {}s is unstable", ccx.const_kind(),),
607607 );
608 // FIXME: make this translatable
609 #[allow(rustc::untranslatable_diagnostic)]
610608 err
611609 .note("`static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.")
612610 .help("to fix this, the value can be extracted to a `const` and then used.");
compiler/rustc_const_eval/src/interpret/call.rs+2-1
......@@ -1,5 +1,6 @@
11//! Manages calling a concrete function (with known MIR body) with argument passing,
22//! and returning the return value to the caller.
3use std::assert_matches::assert_matches;
34use std::borrow::Cow;
45
56use either::{Left, Right};
......@@ -557,7 +558,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
557558 unwind,
558559 )? {
559560 assert!(!self.tcx.intrinsic(fallback.def_id()).unwrap().must_be_overridden);
560 assert!(matches!(fallback.def, ty::InstanceKind::Item(_)));
561 assert_matches!(fallback.def, ty::InstanceKind::Item(_));
561562 return self.init_fn_call(
562563 FnVal::Instance(fallback),
563564 (caller_abi, caller_fn_abi),
compiler/rustc_const_eval/src/interpret/intrinsics.rs+5-3
......@@ -2,6 +2,8 @@
22//! looking at their MIR. Intrinsics/functions supported here are shared by CTFE
33//! and miri.
44
5use std::assert_matches::assert_matches;
6
57use rustc_hir::def_id::DefId;
68use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
79use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement};
......@@ -510,7 +512,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
510512 dest: &MPlaceTy<'tcx, M::Provenance>,
511513 ) -> InterpResult<'tcx> {
512514 assert_eq!(a.layout.ty, b.layout.ty);
513 assert!(matches!(a.layout.ty.kind(), ty::Int(..) | ty::Uint(..)));
515 assert_matches!(a.layout.ty.kind(), ty::Int(..) | ty::Uint(..));
514516
515517 // Performs an exact division, resulting in undefined behavior where
516518 // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
......@@ -536,8 +538,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
536538 r: &ImmTy<'tcx, M::Provenance>,
537539 ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
538540 assert_eq!(l.layout.ty, r.layout.ty);
539 assert!(matches!(l.layout.ty.kind(), ty::Int(..) | ty::Uint(..)));
540 assert!(matches!(mir_op, BinOp::Add | BinOp::Sub));
541 assert_matches!(l.layout.ty.kind(), ty::Int(..) | ty::Uint(..));
542 assert_matches!(mir_op, BinOp::Add | BinOp::Sub);
541543
542544 let (val, overflowed) =
543545 self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair();
compiler/rustc_const_eval/src/interpret/operand.rs+1-1
......@@ -342,7 +342,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
342342 }
343343 // extract fields from types with `ScalarPair` ABI
344344 (Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
345 assert!(matches!(layout.abi, Abi::Scalar(..)));
345 assert_matches!(layout.abi, Abi::Scalar(..));
346346 Immediate::from(if offset.bytes() == 0 {
347347 debug_assert_eq!(layout.size, a.size(cx));
348348 a_val
compiler/rustc_data_structures/src/graph/scc/mod.rs+2-1
......@@ -8,6 +8,7 @@
88//! Typical examples would include: minimum element in SCC, maximum element
99//! reachable from it, etc.
1010
11use std::assert_matches::debug_assert_matches;
1112use std::fmt::Debug;
1213use std::ops::Range;
1314
......@@ -569,7 +570,7 @@ where
569570 // This None marks that we still have the initialize this node's frame.
570571 debug!(?depth, ?node);
571572
572 debug_assert!(matches!(self.node_states[node], NodeState::NotVisited));
573 debug_assert_matches!(self.node_states[node], NodeState::NotVisited);
573574
574575 // Push `node` onto the stack.
575576 self.node_states[node] = NodeState::BeingVisited {
compiler/rustc_data_structures/src/lib.rs+1
......@@ -18,6 +18,7 @@
1818#![feature(array_windows)]
1919#![feature(ascii_char)]
2020#![feature(ascii_char_variants)]
21#![feature(assert_matches)]
2122#![feature(auto_traits)]
2223#![feature(cfg_match)]
2324#![feature(core_intrinsics)]
compiler/rustc_errors/src/lib.rs+3-1
......@@ -10,6 +10,7 @@
1010#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1111#![doc(rust_logo)]
1212#![feature(array_windows)]
13#![feature(assert_matches)]
1314#![feature(associated_type_defaults)]
1415#![feature(box_into_inner)]
1516#![feature(box_patterns)]
......@@ -28,6 +29,7 @@
2829
2930extern crate self as rustc_errors;
3031
32use std::assert_matches::assert_matches;
3133use std::backtrace::{Backtrace, BacktraceStatus};
3234use std::borrow::Cow;
3335use std::cell::Cell;
......@@ -1490,7 +1492,7 @@ impl DiagCtxtInner {
14901492 // Future breakages aren't emitted if they're `Level::Allow` or
14911493 // `Level::Expect`, but they still need to be constructed and
14921494 // stashed below, so they'll trigger the must_produce_diag check.
1493 assert!(matches!(diagnostic.level, Error | Warning | Allow | Expect(_)));
1495 assert_matches!(diagnostic.level, Error | Warning | Allow | Expect(_));
14941496 self.future_breakage_diagnostics.push(diagnostic.clone());
14951497 }
14961498
compiler/rustc_expand/messages.ftl+3
......@@ -129,6 +129,9 @@ expand_module_multiple_candidates =
129129expand_must_repeat_once =
130130 this must repeat at least once
131131
132expand_non_inline_modules_in_proc_macro_input_are_unstable =
133 non-inline modules in proc macro input are unstable
134
132135expand_not_a_meta_item =
133136 not a meta item
134137
compiler/rustc_expand/src/base.rs-2
......@@ -1398,8 +1398,6 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) {
13981398 };
13991399
14001400 if crate_matches {
1401 // FIXME: make this translatable
1402 #[allow(rustc::untranslatable_diagnostic)]
14031401 sess.dcx().emit_fatal(errors::ProcMacroBackCompat {
14041402 crate_name: "rental".to_string(),
14051403 fixed_version: "0.5.6".to_string(),
compiler/rustc_expand/src/expand.rs+2-3
......@@ -39,6 +39,7 @@ use crate::errors::{
3939 RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
4040 WrongFragmentKind,
4141};
42use crate::fluent_generated;
4243use crate::mbe::diagnostics::annotate_err_with_kind;
4344use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
4445use crate::placeholders::{placeholder, PlaceholderExpander};
......@@ -882,7 +883,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
882883 }
883884
884885 impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
885 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
886886 fn visit_item(&mut self, item: &'ast ast::Item) {
887887 match &item.kind {
888888 ItemKind::Mod(_, mod_kind)
......@@ -892,7 +892,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
892892 self.sess,
893893 sym::proc_macro_hygiene,
894894 item.span,
895 "non-inline modules in proc macro input are unstable",
895 fluent_generated::expand_non_inline_modules_in_proc_macro_input_are_unstable,
896896 )
897897 .emit();
898898 }
......@@ -1876,7 +1876,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
18761876
18771877 // Detect use of feature-gated or invalid attributes on macro invocations
18781878 // since they will not be detected after macro expansion.
1879 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
18801879 fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
18811880 let features = self.cx.ecfg.features;
18821881 let mut attrs = attrs.iter().peekable();
compiler/rustc_hir_analysis/src/check/intrinsicck.rs+6-4
......@@ -1,3 +1,5 @@
1use std::assert_matches::debug_assert_matches;
2
13use rustc_ast::InlineAsmTemplatePiece;
24use rustc_data_structures::fx::FxIndexSet;
35use rustc_hir::{self as hir, LangItem};
......@@ -457,17 +459,17 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
457459 }
458460 // Typeck has checked that Const operands are integers.
459461 hir::InlineAsmOperand::Const { anon_const } => {
460 debug_assert!(matches!(
462 debug_assert_matches!(
461463 self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
462464 ty::Error(_) | ty::Int(_) | ty::Uint(_)
463 ));
465 );
464466 }
465467 // Typeck has checked that SymFn refers to a function.
466468 hir::InlineAsmOperand::SymFn { anon_const } => {
467 debug_assert!(matches!(
469 debug_assert_matches!(
468470 self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
469471 ty::Error(_) | ty::FnDef(..)
470 ));
472 );
471473 }
472474 // AST lowering guarantees that SymStatic points to a static.
473475 hir::InlineAsmOperand::SymStatic { .. } => {}
compiler/rustc_hir_analysis/src/coherence/builtin.rs+2-1
......@@ -1,6 +1,7 @@
11//! Check properties that are required by built-in traits and set
22//! up data structures required by type-checking/codegen.
33
4use std::assert_matches::assert_matches;
45use std::collections::BTreeMap;
56
67use rustc_data_structures::fx::FxHashSet;
......@@ -129,7 +130,7 @@ fn visit_implementation_of_const_param_ty(
129130 checker: &Checker<'_>,
130131 kind: LangItem,
131132) -> Result<(), ErrorGuaranteed> {
132 assert!(matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy));
133 assert_matches!(kind, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy);
133134
134135 let tcx = checker.tcx;
135136 let header = checker.impl_header;
compiler/rustc_hir_analysis/src/collect/generics_of.rs+5-4
......@@ -1,3 +1,4 @@
1use std::assert_matches::assert_matches;
12use std::ops::ControlFlow;
23
34use hir::intravisit::{self, Visitor};
......@@ -207,9 +208,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
207208 ..
208209 }) => {
209210 if in_trait {
210 assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
211 assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
211212 } else {
212 assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
213 assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
213214 }
214215 Some(fn_def_id.to_def_id())
215216 }
......@@ -218,9 +219,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
218219 ..
219220 }) => {
220221 if in_assoc_ty {
221 assert!(matches!(tcx.def_kind(parent), DefKind::AssocTy));
222 assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
222223 } else {
223 assert!(matches!(tcx.def_kind(parent), DefKind::TyAlias));
224 assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
224225 }
225226 debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
226227 // Opaque types are always nested within another item, and
compiler/rustc_hir_analysis/src/collect/predicates_of.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use hir::{HirId, Node};
24use rustc_data_structures::fx::FxIndexSet;
35use rustc_hir as hir;
......@@ -601,7 +603,7 @@ pub(super) fn implied_predicates_with_filter(
601603 let Some(trait_def_id) = trait_def_id.as_local() else {
602604 // if `assoc_name` is None, then the query should've been redirected to an
603605 // external provider
604 assert!(matches!(filter, PredicateFilter::SelfThatDefines(_)));
606 assert_matches!(filter, PredicateFilter::SelfThatDefines(_));
605607 return tcx.explicit_super_predicates_of(trait_def_id);
606608 };
607609
compiler/rustc_hir_analysis/src/delegation.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::debug_assert_matches;
2
13use rustc_data_structures::fx::FxHashMap;
24use rustc_hir::def::DefKind;
35use rustc_hir::def_id::{DefId, LocalDefId};
......@@ -63,7 +65,7 @@ enum FnKind {
6365}
6466
6567fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind {
66 debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn));
68 debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
6769
6870 let parent = tcx.parent(def_id);
6971 match tcx.def_kind(parent) {
compiler/rustc_hir_analysis/src/impl_wf_check.rs+3-1
......@@ -8,6 +8,8 @@
88//! specialization errors. These things can (and probably should) be
99//! fixed, but for the moment it's easier to do these checks early.
1010
11use std::assert_matches::debug_assert_matches;
12
1113use min_specialization::check_min_specialization;
1214use rustc_data_structures::fx::FxHashSet;
1315use rustc_errors::codes::*;
......@@ -54,7 +56,7 @@ mod min_specialization;
5456pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
5557 let min_specialization = tcx.features().min_specialization;
5658 let mut res = Ok(());
57 debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }));
59 debug_assert_matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. });
5860 res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
5961 if min_specialization {
6062 res = res.and(check_min_specialization(tcx, impl_def_id));
compiler/rustc_hir_analysis/src/lib.rs+1
......@@ -62,6 +62,7 @@ This API is completely unstable and subject to change.
6262#![allow(rustc::untranslatable_diagnostic)]
6363#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
6464#![doc(rust_logo)]
65#![feature(assert_matches)]
6566#![feature(control_flow_enum)]
6667#![feature(if_let_guard)]
6768#![feature(iter_intersperse)]
compiler/rustc_infer/src/infer/outlives/verify.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
24use rustc_type_ir::outlives::{compute_alias_components_recursive, Component};
35use smallvec::smallvec;
......@@ -181,7 +183,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
181183 &self,
182184 generic_ty: Ty<'tcx>,
183185 ) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
184 assert!(matches!(generic_ty.kind(), ty::Param(_) | ty::Placeholder(_)));
186 assert_matches!(generic_ty.kind(), ty::Param(_) | ty::Placeholder(_));
185187 self.declared_generic_bounds_from_env_for_erased_ty(generic_ty)
186188 }
187189
compiler/rustc_infer/src/lib.rs+1
......@@ -18,6 +18,7 @@
1818#![allow(rustc::untranslatable_diagnostic)]
1919#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
2020#![doc(rust_logo)]
21#![feature(assert_matches)]
2122#![feature(box_patterns)]
2223#![feature(control_flow_enum)]
2324#![feature(extend_one)]
compiler/rustc_interface/src/util.rs-1
......@@ -386,7 +386,6 @@ fn get_codegen_sysroot(
386386 }
387387}
388388
389#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
390389pub(crate) fn check_attr_crate_type(
391390 sess: &Session,
392391 attrs: &[ast::Attribute],
compiler/rustc_lint/src/levels.rs-2
......@@ -717,7 +717,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
717717 };
718718 }
719719
720 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
721720 fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option<HirId>) {
722721 let sess = self.sess;
723722 for (attr_index, attr) in attrs.iter().enumerate() {
......@@ -1039,7 +1038,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
10391038 let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
10401039 // FIXME: make this translatable
10411040 #[allow(rustc::diagnostic_outside_of_impl)]
1042 #[allow(rustc::untranslatable_diagnostic)]
10431041 lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
10441042 lint.primary_message(fluent::lint_unknown_gated_lint);
10451043 lint.arg("name", lint_id.lint.name_lower());
compiler/rustc_metadata/messages.ftl+6
......@@ -134,12 +134,18 @@ metadata_lib_framework_apple =
134134metadata_lib_required =
135135 crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
136136
137metadata_link_arg_unstable =
138 link kind `link-arg` is unstable
139
137140metadata_link_cfg_form =
138141 link cfg must be of the form `cfg(/* predicate */)`
139142
140143metadata_link_cfg_single_predicate =
141144 link cfg must have a single predicate argument
142145
146metadata_link_cfg_unstable =
147 link cfg is unstable
148
143149metadata_link_framework_apple =
144150 link kind `framework` is only supported on Apple targets
145151
compiler/rustc_metadata/src/creader.rs-1
......@@ -949,7 +949,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
949949 }
950950 }
951951
952 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
953952 fn report_unused_deps(&mut self, krate: &ast::Crate) {
954953 // Make a point span rather than covering the whole file
955954 let span = krate.spans.inner_span.shrink_to_lo();
compiler/rustc_metadata/src/native_libs.rs+11-5
......@@ -17,7 +17,7 @@ use rustc_span::def_id::{DefId, LOCAL_CRATE};
1717use rustc_span::symbol::{sym, Symbol};
1818use rustc_target::spec::abi::Abi;
1919
20use crate::errors;
20use crate::{errors, fluent_generated};
2121
2222pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
2323 let formats = if verbatim {
......@@ -87,7 +87,6 @@ struct Collector<'tcx> {
8787}
8888
8989impl<'tcx> Collector<'tcx> {
90 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
9190 fn process_module(&mut self, module: &ForeignModule) {
9291 let ForeignModule { def_id, abi, ref foreign_items } = *module;
9392 let def_id = def_id.expect_local();
......@@ -161,7 +160,7 @@ impl<'tcx> Collector<'tcx> {
161160 sess,
162161 sym::link_arg_attribute,
163162 span,
164 "link kind `link-arg` is unstable",
163 fluent_generated::metadata_link_arg_unstable,
165164 )
166165 .emit();
167166 }
......@@ -201,8 +200,13 @@ impl<'tcx> Collector<'tcx> {
201200 continue;
202201 };
203202 if !features.link_cfg {
204 feature_err(sess, sym::link_cfg, item.span(), "link cfg is unstable")
205 .emit();
203 feature_err(
204 sess,
205 sym::link_cfg,
206 item.span(),
207 fluent_generated::metadata_link_cfg_unstable,
208 )
209 .emit();
206210 }
207211 cfg = Some(link_cfg.clone());
208212 }
......@@ -266,6 +270,8 @@ impl<'tcx> Collector<'tcx> {
266270
267271 macro report_unstable_modifier($feature: ident) {
268272 if !features.$feature {
273 // FIXME: make this translatable
274 #[expect(rustc::untranslatable_diagnostic)]
269275 feature_err(
270276 sess,
271277 sym::$feature,
compiler/rustc_middle/src/ty/consts/kind.rs+6-4
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
24
35use super::Const;
......@@ -80,7 +82,7 @@ impl<'tcx> Expr<'tcx> {
8082 }
8183
8284 pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) {
83 assert!(matches!(self.kind, ExprKind::Binop(_)));
85 assert_matches!(self.kind, ExprKind::Binop(_));
8486
8587 match self.args().as_slice() {
8688 [lhs_ty, rhs_ty, lhs_ct, rhs_ct] => (
......@@ -101,7 +103,7 @@ impl<'tcx> Expr<'tcx> {
101103 }
102104
103105 pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) {
104 assert!(matches!(self.kind, ExprKind::UnOp(_)));
106 assert_matches!(self.kind, ExprKind::UnOp(_));
105107
106108 match self.args().as_slice() {
107109 [ty, ct] => (ty.expect_ty(), ct.expect_const()),
......@@ -125,7 +127,7 @@ impl<'tcx> Expr<'tcx> {
125127 }
126128
127129 pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator<Item = Const<'tcx>>) {
128 assert!(matches!(self.kind, ExprKind::FunctionCall));
130 assert_matches!(self.kind, ExprKind::FunctionCall);
129131
130132 match self.args().as_slice() {
131133 [func_ty, func, rest @ ..] => (
......@@ -152,7 +154,7 @@ impl<'tcx> Expr<'tcx> {
152154 }
153155
154156 pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) {
155 assert!(matches!(self.kind, ExprKind::Cast(_)));
157 assert_matches!(self.kind, ExprKind::Cast(_));
156158
157159 match self.args().as_slice() {
158160 [value_ty, value, to_ty] => {
compiler/rustc_mir_dataflow/src/impls/initialized.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use rustc_index::bit_set::{BitSet, ChunkedBitSet};
24use rustc_index::Idx;
35use rustc_middle::bug;
......@@ -496,7 +498,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
496498 });
497499 if self.skip_unreachable_unwind.contains(location.block) {
498500 let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() };
499 assert!(matches!(unwind, mir::UnwindAction::Cleanup(_)));
501 assert_matches!(unwind, mir::UnwindAction::Cleanup(_));
500502 TerminatorEdges::Single(target)
501503 } else {
502504 terminator.edges()
compiler/rustc_mir_dataflow/src/lib.rs+1
......@@ -1,4 +1,5 @@
11// tidy-alphabetical-start
2#![feature(assert_matches)]
23#![feature(associated_type_defaults)]
34#![feature(box_patterns)]
45#![feature(exact_size_is_empty)]
compiler/rustc_mir_dataflow/src/value_analysis.rs+3-2
......@@ -32,6 +32,7 @@
3232//! Because of that, we can assume that the only way to change the value behind a tracked place is
3333//! by direct assignment.
3434
35use std::assert_matches::assert_matches;
3536use std::fmt::{Debug, Formatter};
3637use std::ops::Range;
3738
......@@ -54,7 +55,7 @@ use crate::{Analysis, AnalysisDomain, JoinSemiLattice, SwitchIntEdgeEffects};
5455
5556pub trait ValueAnalysis<'tcx> {
5657 /// For each place of interest, the analysis tracks a value of the given type.
57 type Value: Clone + JoinSemiLattice + HasBottom + HasTop;
58 type Value: Clone + JoinSemiLattice + HasBottom + HasTop + Debug;
5859
5960 const NAME: &'static str;
6061
......@@ -344,7 +345,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper
344345
345346 fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
346347 // The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥.
347 assert!(matches!(state, State::Unreachable));
348 assert_matches!(state, State::Unreachable);
348349 *state = State::new_reachable();
349350 for arg in body.args_iter() {
350351 state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map());
compiler/rustc_mir_transform/src/promote_consts.rs+2-2
......@@ -468,7 +468,7 @@ impl<'tcx> Validator<'_, 'tcx> {
468468
469469 if let ty::RawPtr(_, _) | ty::FnPtr(..) = lhs_ty.kind() {
470470 // Raw and fn pointer operations are not allowed inside consts and thus not promotable.
471 assert!(matches!(
471 assert_matches!(
472472 op,
473473 BinOp::Eq
474474 | BinOp::Ne
......@@ -477,7 +477,7 @@ impl<'tcx> Validator<'_, 'tcx> {
477477 | BinOp::Ge
478478 | BinOp::Gt
479479 | BinOp::Offset
480 ));
480 );
481481 return Err(Unpromotable);
482482 }
483483
compiler/rustc_mir_transform/src/shim.rs+1-1
......@@ -996,7 +996,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
996996/// }
997997/// ```
998998fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
999 assert!(matches!(self_ty.kind(), ty::FnPtr(..)), "expected fn ptr, found {self_ty}");
999 assert_matches!(self_ty.kind(), ty::FnPtr(..), "expected fn ptr, found {self_ty}");
10001000 let span = tcx.def_span(def_id);
10011001 let Some(sig) = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).no_bound_vars() else {
10021002 span_bug!(span, "FnPtr::addr with bound vars for `{self_ty}`");
compiler/rustc_parse/src/lib.rs+1
......@@ -5,6 +5,7 @@
55#![allow(rustc::diagnostic_outside_of_impl)]
66#![allow(rustc::untranslatable_diagnostic)]
77#![feature(array_windows)]
8#![feature(assert_matches)]
89#![feature(box_patterns)]
910#![feature(debug_closure_helpers)]
1011#![feature(if_let_guard)]
compiler/rustc_parse/src/parser/mod.rs+8-5
......@@ -10,6 +10,7 @@ mod path;
1010mod stmt;
1111mod ty;
1212
13use std::assert_matches::debug_assert_matches;
1314use std::ops::Range;
1415use std::{fmt, mem, slice};
1516
......@@ -1166,10 +1167,12 @@ impl<'a> Parser<'a> {
11661167 match self.token_cursor.tree_cursor.look_ahead(0) {
11671168 Some(tree) => {
11681169 // Indexing stayed within the current token tree.
1169 return match tree {
1170 TokenTree::Token(token, _) => looker(token),
1171 TokenTree::Delimited(dspan, _, delim, _) => {
1172 looker(&Token::new(token::OpenDelim(*delim), dspan.open))
1170 match tree {
1171 TokenTree::Token(token, _) => return looker(token),
1172 &TokenTree::Delimited(dspan, _, delim, _) => {
1173 if delim != Delimiter::Invisible {
1174 return looker(&Token::new(token::OpenDelim(delim), dspan.open));
1175 }
11731176 }
11741177 };
11751178 }
......@@ -1385,7 +1388,7 @@ impl<'a> Parser<'a> {
13851388 // can capture these tokens if necessary.
13861389 self.bump();
13871390 if self.token_cursor.stack.len() == target_depth {
1388 debug_assert!(matches!(self.token.kind, token::CloseDelim(_)));
1391 debug_assert_matches!(self.token.kind, token::CloseDelim(_));
13891392 break;
13901393 }
13911394 }
compiler/rustc_parse/src/parser/tests.rs+2-1
......@@ -1,3 +1,4 @@
1use std::assert_matches::assert_matches;
12use std::io::prelude::*;
23use std::iter::Peekable;
34use std::path::{Path, PathBuf};
......@@ -1747,7 +1748,7 @@ fn out_of_line_mod() {
17471748 .unwrap();
17481749
17491750 let ast::ItemKind::Mod(_, mod_kind) = &item.kind else { panic!() };
1750 assert!(matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2));
1751 assert_matches!(mod_kind, ast::ModKind::Loaded(items, ..) if items.len() == 2);
17511752 });
17521753}
17531754
compiler/rustc_passes/messages.ftl+6
......@@ -223,6 +223,9 @@ passes_doc_masked_only_extern_crate =
223223 .not_an_extern_crate_label = not an `extern crate` item
224224 .note = read <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> for more information
225225
226passes_doc_rust_logo =
227 the `#[doc(rust_logo)]` attribute is used for Rust branding
228
226229passes_doc_test_literal = `#![doc(test(...)]` does not take a literal
227230
228231passes_doc_test_takes_list =
......@@ -595,6 +598,9 @@ passes_remove_fields =
595598 *[other] fields
596599 }
597600
601passes_repr_align_function =
602 `repr(align)` attributes on functions are unstable
603
598604passes_repr_conflicting =
599605 conflicting representation hints
600606
compiler/rustc_passes/src/check_attr.rs+2-4
......@@ -1142,7 +1142,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
11421142 /// of one item. Read the documentation of [`check_doc_inline`] for more information.
11431143 ///
11441144 /// [`check_doc_inline`]: Self::check_doc_inline
1145 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
11461145 fn check_doc_attrs(
11471146 &self,
11481147 attr: &Attribute,
......@@ -1220,7 +1219,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
12201219 &self.tcx.sess,
12211220 sym::rustdoc_internals,
12221221 meta.span(),
1223 "the `#[doc(rust_logo)]` attribute is used for Rust branding",
1222 fluent::passes_doc_rust_logo,
12241223 )
12251224 .emit();
12261225 }
......@@ -1736,7 +1735,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17361735 }
17371736
17381737 /// Checks if the `#[repr]` attributes on `item` are valid.
1739 #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
17401738 fn check_repr(
17411739 &self,
17421740 attrs: &[Attribute],
......@@ -1793,7 +1791,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
17931791 &self.tcx.sess,
17941792 sym::fn_align,
17951793 hint.span(),
1796 "`repr(align)` attributes on functions are unstable",
1794 fluent::passes_repr_align_function,
17971795 )
17981796 .emit();
17991797 }
compiler/rustc_passes/src/entry.rs-1
......@@ -106,7 +106,6 @@ fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
106106 }
107107}
108108
109#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
110109fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
111110 if let Some((def_id, _)) = visitor.start_fn {
112111 Some((def_id.to_def_id(), EntryFnType::Start))
compiler/rustc_target/src/spec/abi/tests.rs+3-1
......@@ -1,3 +1,5 @@
1use std::assert_matches::assert_matches;
2
13use super::*;
24
35#[allow(non_snake_case)]
......@@ -16,7 +18,7 @@ fn lookup_cdecl() {
1618#[test]
1719fn lookup_baz() {
1820 let abi = lookup("baz");
19 assert!(matches!(abi, Err(AbiUnsupported::Unrecognized)))
21 assert_matches!(abi, Err(AbiUnsupported::Unrecognized));
2022}
2123
2224#[test]
compiler/rustc_trait_selection/src/solve/inspect/analyse.rs+4-2
......@@ -9,6 +9,8 @@
99//! coherence right now and was annoying to implement, so I am leaving it
1010//! as is until we start using it for something else.
1111
12use std::assert_matches::assert_matches;
13
1214use rustc_ast_ir::try_visit;
1315use rustc_ast_ir::visit::VisitorResult;
1416use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
......@@ -273,10 +275,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
273275 steps.push(step)
274276 }
275277 inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
276 assert!(matches!(
278 assert_matches!(
277279 shallow_certainty.replace(c),
278280 None | Some(Certainty::Maybe(MaybeCause::Ambiguity))
279 ));
281 );
280282 }
281283 inspect::ProbeStep::NestedProbe(ref probe) => {
282284 match probe.kind {
compiler/rustc_trait_selection/src/solve/normalize.rs+2-1
......@@ -1,3 +1,4 @@
1use std::assert_matches::assert_matches;
12use std::fmt::Debug;
23use std::marker::PhantomData;
34
......@@ -63,7 +64,7 @@ where
6364 E: FromSolverError<'tcx, NextSolverError<'tcx>>,
6465{
6566 fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
66 assert!(matches!(alias_ty.kind(), ty::Alias(..)));
67 assert_matches!(alias_ty.kind(), ty::Alias(..));
6768
6869 let infcx = self.at.infcx;
6970 let tcx = infcx.tcx;
compiler/rustc_trait_selection/src/traits/misc.rs+3-1
......@@ -1,5 +1,7 @@
11//! Miscellaneous type-system utilities that are too small to deserve their own modules.
22
3use std::assert_matches::assert_matches;
4
35use hir::LangItem;
46use rustc_ast::Mutability;
57use rustc_data_structures::fx::FxIndexSet;
......@@ -92,7 +94,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
9294 lang_item: LangItem,
9395 parent_cause: ObligationCause<'tcx>,
9496) -> Result<(), ConstParamTyImplementationError<'tcx>> {
95 assert!(matches!(lang_item, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy));
97 assert_matches!(lang_item, LangItem::ConstParamTy | LangItem::UnsizedConstParamTy);
9698
9799 let inner_tys: Vec<_> = match *self_type.kind() {
98100 // Trivially okay as these types are all:
compiler/rustc_ty_utils/src/layout_sanity_check.rs+1-1
......@@ -249,7 +249,7 @@ pub(super) fn sanity_check_layout<'tcx>(
249249 if let Variants::Multiple { variants, .. } = &layout.variants {
250250 for variant in variants.iter() {
251251 // No nested "multiple".
252 assert!(matches!(variant.variants, Variants::Single { .. }));
252 assert_matches!(variant.variants, Variants::Single { .. });
253253 // Variants should have the same or a smaller size as the full thing,
254254 // and same for alignment.
255255 if variant.size > layout.size {
library/core/src/intrinsics.rs+5-5
......@@ -2675,12 +2675,12 @@ extern "rust-intrinsic" {
26752675 #[rustc_nounwind]
26762676 pub fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
26772677
2678 /// Emits a `!nontemporal` store according to LLVM (see their docs).
2679 /// Probably will never become stable.
2678 /// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held
2679 /// in cache. Except for performance, this is fully equivalent to `ptr.write(val)`.
26802680 ///
2681 /// Do NOT use this intrinsic; "nontemporal" operations do not exist in our memory model!
2682 /// It exists to support current stdarch, but the plan is to change stdarch and remove this intrinsic.
2683 /// See <https://github.com/rust-lang/rust/issues/114582> for some more discussion.
2681 /// Not all architectures provide such an operation. For instance, x86 does not: while `MOVNT`
2682 /// exists, that operation is *not* equivalent to `ptr.write(val)` (`MOVNT` writes can be reordered
2683 /// in ways that are not allowed for regular writes).
26842684 #[rustc_nounwind]
26852685 pub fn nontemporal_store<T>(ptr: *mut T, val: T);
26862686
library/std/src/panic.rs+15-11
......@@ -440,13 +440,12 @@ impl BacktraceStyle {
440440 }
441441
442442 fn from_u8(s: u8) -> Option<Self> {
443 Some(match s {
444 0 => return None,
445 1 => BacktraceStyle::Short,
446 2 => BacktraceStyle::Full,
447 3 => BacktraceStyle::Off,
448 _ => unreachable!(),
449 })
443 match s {
444 1 => Some(BacktraceStyle::Short),
445 2 => Some(BacktraceStyle::Full),
446 3 => Some(BacktraceStyle::Off),
447 _ => None,
448 }
450449 }
451450}
452451
......@@ -465,7 +464,7 @@ static SHOULD_CAPTURE: AtomicU8 = AtomicU8::new(0);
465464pub fn set_backtrace_style(style: BacktraceStyle) {
466465 if cfg!(feature = "backtrace") {
467466 // If the `backtrace` feature of this crate is enabled, set the backtrace style.
468 SHOULD_CAPTURE.store(style.as_u8(), Ordering::Release);
467 SHOULD_CAPTURE.store(style.as_u8(), Ordering::Relaxed);
469468 }
470469}
471470
......@@ -498,7 +497,9 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
498497 // to optimize away callers.
499498 return None;
500499 }
501 if let Some(style) = BacktraceStyle::from_u8(SHOULD_CAPTURE.load(Ordering::Acquire)) {
500
501 let current = SHOULD_CAPTURE.load(Ordering::Relaxed);
502 if let Some(style) = BacktraceStyle::from_u8(current) {
502503 return Some(style);
503504 }
504505
......@@ -509,8 +510,11 @@ pub fn get_backtrace_style() -> Option<BacktraceStyle> {
509510 None if crate::sys::FULL_BACKTRACE_DEFAULT => BacktraceStyle::Full,
510511 None => BacktraceStyle::Off,
511512 };
512 set_backtrace_style(format);
513 Some(format)
513
514 match SHOULD_CAPTURE.compare_exchange(0, format.as_u8(), Ordering::Relaxed, Ordering::Relaxed) {
515 Ok(_) => Some(format),
516 Err(new) => BacktraceStyle::from_u8(new),
517 }
514518}
515519
516520#[cfg(test)]
src/bootstrap/src/bin/main.rs+8-2
......@@ -11,13 +11,19 @@ use std::str::FromStr;
1111use std::{env, process};
1212
1313use bootstrap::{
14 find_recent_config_change_ids, human_readable_changes, t, Build, Config, Subcommand,
14 find_recent_config_change_ids, human_readable_changes, t, Build, Config, Flags, Subcommand,
1515 CONFIG_CHANGE_HISTORY,
1616};
1717
1818fn main() {
1919 let args = env::args().skip(1).collect::<Vec<_>>();
20 let config = Config::parse(&args);
20
21 if Flags::try_parse_verbose_help(&args) {
22 return;
23 }
24
25 let flags = Flags::parse(&args);
26 let config = Config::parse(flags);
2127
2228 let mut build_lock;
2329 let _build_lock_guard;
src/bootstrap/src/core/builder/tests.rs+3-2
......@@ -3,13 +3,14 @@ use std::thread;
33use super::*;
44use crate::core::build_steps::doc::DocumentationFormat;
55use crate::core::config::Config;
6use crate::Flags;
67
78fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
89 configure_with_args(&[cmd.to_owned()], host, target)
910}
1011
1112fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config {
12 let mut config = Config::parse(cmd);
13 let mut config = Config::parse(Flags::parse(cmd));
1314 // don't save toolstates
1415 config.save_toolstates = None;
1516 config.dry_run = DryRun::SelfCheck;
......@@ -23,7 +24,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
2324 let submodule_build = Build::new(Config {
2425 // don't include LLVM, so CI doesn't require ninja/cmake to be installed
2526 rust_codegen_backends: vec![],
26 ..Config::parse(&["check".to_owned()])
27 ..Config::parse(Flags::parse(&["check".to_owned()]))
2728 });
2829 submodule_build.require_submodule("src/doc/book", None);
2930 config.submodules = Some(false);
src/bootstrap/src/core/config/config.rs+3-4
......@@ -1191,7 +1191,7 @@ impl Config {
11911191 }
11921192 }
11931193
1194 pub fn parse(args: &[String]) -> Config {
1194 pub fn parse(flags: Flags) -> Config {
11951195 #[cfg(test)]
11961196 fn get_toml(_: &Path) -> TomlConfig {
11971197 TomlConfig::default()
......@@ -1221,11 +1221,10 @@ impl Config {
12211221 exit!(2);
12221222 })
12231223 }
1224 Self::parse_inner(args, get_toml)
1224 Self::parse_inner(flags, get_toml)
12251225 }
12261226
1227 pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
1228 let mut flags = Flags::parse(args);
1227 pub(crate) fn parse_inner(mut flags: Flags, get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
12291228 let mut config = Config::default_opts();
12301229
12311230 // Set flags.
src/bootstrap/src/core/config/flags.rs+17-7
......@@ -183,9 +183,9 @@ pub struct Flags {
183183}
184184
185185impl Flags {
186 pub fn parse(args: &[String]) -> Self {
187 let first = String::from("x.py");
188 let it = std::iter::once(&first).chain(args.iter());
186 /// Check if `<cmd> -h -v` was passed.
187 /// If yes, print the available paths and return `true`.
188 pub fn try_parse_verbose_help(args: &[String]) -> bool {
189189 // We need to check for `<cmd> -h -v`, in which case we list the paths
190190 #[derive(Parser)]
191191 #[command(disable_help_flag(true))]
......@@ -198,10 +198,10 @@ impl Flags {
198198 cmd: Kind,
199199 }
200200 if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
201 HelpVerboseOnly::try_parse_from(it.clone())
201 HelpVerboseOnly::try_parse_from(normalize_args(args))
202202 {
203203 println!("NOTE: updating submodules before printing available paths");
204 let config = Config::parse(&[String::from("build")]);
204 let config = Config::parse(Self::parse(&[String::from("build")]));
205205 let build = Build::new(config);
206206 let paths = Builder::get_help(&build, subcommand);
207207 if let Some(s) = paths {
......@@ -209,13 +209,23 @@ impl Flags {
209209 } else {
210210 panic!("No paths available for subcommand `{}`", subcommand.as_str());
211211 }
212 crate::exit!(0);
212 true
213 } else {
214 false
213215 }
216 }
214217
215 Flags::parse_from(it)
218 pub fn parse(args: &[String]) -> Self {
219 Flags::parse_from(normalize_args(args))
216220 }
217221}
218222
223fn normalize_args(args: &[String]) -> Vec<String> {
224 let first = String::from("x.py");
225 let it = std::iter::once(first).chain(args.iter().cloned());
226 it.collect()
227}
228
219229#[derive(Debug, Clone, Default, clap::Subcommand)]
220230pub enum Subcommand {
221231 #[command(aliases = ["b"], long_about = "\n
src/bootstrap/src/core/config/mod.rs+1-1
......@@ -1,6 +1,6 @@
11#[allow(clippy::module_inception)]
22mod config;
3pub(crate) mod flags;
3pub mod flags;
44#[cfg(test)]
55mod tests;
66
src/bootstrap/src/core/config/tests.rs+10-9
......@@ -12,9 +12,10 @@ use crate::core::build_steps::clippy::get_clippy_rules_in_order;
1212use crate::core::config::{LldMode, Target, TargetSelection, TomlConfig};
1313
1414fn parse(config: &str) -> Config {
15 Config::parse_inner(&["check".to_string(), "--config=/does/not/exist".to_string()], |&_| {
16 toml::from_str(&config).unwrap()
17 })
15 Config::parse_inner(
16 Flags::parse(&["check".to_string(), "--config=/does/not/exist".to_string()]),
17 |&_| toml::from_str(&config).unwrap(),
18 )
1819}
1920
2021#[test]
......@@ -108,7 +109,7 @@ fn clap_verify() {
108109#[test]
109110fn override_toml() {
110111 let config = Config::parse_inner(
111 &[
112 Flags::parse(&[
112113 "check".to_owned(),
113114 "--config=/does/not/exist".to_owned(),
114115 "--set=change-id=1".to_owned(),
......@@ -121,7 +122,7 @@ fn override_toml() {
121122 "--set=target.x86_64-unknown-linux-gnu.rpath=false".to_owned(),
122123 "--set=target.aarch64-unknown-linux-gnu.sanitizers=false".to_owned(),
123124 "--set=target.aarch64-apple-darwin.runner=apple".to_owned(),
124 ],
125 ]),
125126 |&_| {
126127 toml::from_str(
127128 r#"
......@@ -201,12 +202,12 @@ runner = "x86_64-runner"
201202#[should_panic]
202203fn override_toml_duplicate() {
203204 Config::parse_inner(
204 &[
205 Flags::parse(&[
205206 "check".to_owned(),
206207 "--config=/does/not/exist".to_string(),
207208 "--set=change-id=1".to_owned(),
208209 "--set=change-id=2".to_owned(),
209 ],
210 ]),
210211 |&_| toml::from_str("change-id = 0").unwrap(),
211212 );
212213}
......@@ -226,7 +227,7 @@ fn profile_user_dist() {
226227 .and_then(|table: toml::Value| TomlConfig::deserialize(table))
227228 .unwrap()
228229 }
229 Config::parse_inner(&["check".to_owned()], get_toml);
230 Config::parse_inner(Flags::parse(&["check".to_owned()]), get_toml);
230231}
231232
232233#[test]
......@@ -301,7 +302,7 @@ fn order_of_clippy_rules() {
301302 "-Aclippy::foo1".to_string(),
302303 "-Aclippy::foo2".to_string(),
303304 ];
304 let config = Config::parse(&args);
305 let config = Config::parse(Flags::parse(&args));
305306
306307 let actual = match &config.cmd {
307308 crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
src/bootstrap/src/lib.rs+1-1
......@@ -43,7 +43,7 @@ mod core;
4343mod utils;
4444
4545pub use core::builder::PathSet;
46pub use core::config::flags::Subcommand;
46pub use core::config::flags::{Flags, Subcommand};
4747pub use core::config::Config;
4848
4949pub use utils::change_tracker::{
src/bootstrap/src/utils/helpers/tests.rs+5-3
......@@ -5,7 +5,7 @@ use std::path::PathBuf;
55use crate::utils::helpers::{
66 check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
77};
8use crate::Config;
8use crate::{Config, Flags};
99
1010#[test]
1111fn test_make() {
......@@ -58,7 +58,8 @@ fn test_check_cfg_arg() {
5858
5959#[test]
6060fn test_program_out_of_date() {
61 let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
61 let config =
62 Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
6263 let tempfile = config.tempdir().join(".tmp-stamp-file");
6364 File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
6465 assert!(tempfile.exists());
......@@ -73,7 +74,8 @@ fn test_program_out_of_date() {
7374
7475#[test]
7576fn test_symlink_dir() {
76 let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
77 let config =
78 Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
7779 let tempdir = config.tempdir().join(".tmp-dir");
7880 let link_path = config.tempdir().join(".tmp-link");
7981
src/librustdoc/html/markdown.rs+2-1
......@@ -304,7 +304,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
304304 Some(format!(
305305 "<a class=\"test-arrow\" \
306306 target=\"_blank\" \
307 href=\"{url}?code={test_escaped}{channel}&amp;edition={edition}\">Run</a>",
307 title=\"Run code\" \
308 href=\"{url}?code={test_escaped}{channel}&amp;edition={edition}\"></a>",
308309 ))
309310 });
310311
src/librustdoc/html/static/css/noscript.css-8
......@@ -104,10 +104,6 @@ nav.sub {
104104 --code-highlight-doc-comment-color: #4d4d4c;
105105 --src-line-numbers-span-color: #c67e2d;
106106 --src-line-number-highlighted-background-color: #fdffd3;
107 --test-arrow-color: #f5f5f5;
108 --test-arrow-background-color: rgba(78, 139, 202, 0.2);
109 --test-arrow-hover-color: #f5f5f5;
110 --test-arrow-hover-background-color: rgb(78, 139, 202);
111107 --target-background-color: #fdffd3;
112108 --target-border-color: #ad7c37;
113109 --kbd-color: #000;
......@@ -210,10 +206,6 @@ nav.sub {
210206 --code-highlight-doc-comment-color: #8ca375;
211207 --src-line-numbers-span-color: #3b91e2;
212208 --src-line-number-highlighted-background-color: #0a042f;
213 --test-arrow-color: #dedede;
214 --test-arrow-background-color: rgba(78, 139, 202, 0.2);
215 --test-arrow-hover-color: #dedede;
216 --test-arrow-hover-background-color: #4e8bca;
217209 --target-background-color: #494a3d;
218210 --target-border-color: #bb7410;
219211 --kbd-color: #000;
src/librustdoc/html/static/css/rustdoc.css+21-33
......@@ -353,7 +353,7 @@ details:not(.toggle) summary {
353353 margin-bottom: .6em;
354354}
355355
356code, pre, a.test-arrow, .code-header {
356code, pre, .code-header {
357357 font-family: "Source Code Pro", monospace;
358358}
359359.docblock code, .docblock-short code {
......@@ -946,8 +946,8 @@ because of the `[-]` element which would overlap with it. */
946946.main-heading a:hover,
947947.example-wrap .rust a:hover,
948948.all-items a:hover,
949.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover:not(.doc-anchor),
950.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,
949.docblock a:not(.scrape-help):not(.tooltip):hover:not(.doc-anchor),
950.docblock-short a:not(.scrape-help):not(.tooltip):hover,
951951.item-info a {
952952 text-decoration: underline;
953953}
......@@ -1461,22 +1461,17 @@ documentation. */
14611461 z-index: 1;
14621462}
14631463a.test-arrow {
1464 padding: 5px 7px;
1465 border-radius: var(--button-border-radius);
1466 font-size: 1rem;
1467 color: var(--test-arrow-color);
1468 background-color: var(--test-arrow-background-color);
1464 height: var(--copy-path-height);
1465 padding: 6px 4px 0 11px;
14691466}
1470a.test-arrow:hover {
1471 color: var(--test-arrow-hover-color);
1472 background-color: var(--test-arrow-hover-background-color);
1467a.test-arrow::before {
1468 content: url('data:image/svg+xml,<svg viewBox="0 0 20 20" width="18" height="20" \
1469 xmlns="http://www.w3.org/2000/svg"><path d="M0 0l18 10-18 10z"/></svg>');
14731470}
14741471.example-wrap .button-holder {
14751472 display: flex;
14761473}
1477.example-wrap:hover > .test-arrow {
1478 padding: 2px 7px;
1479}
1474
14801475/*
14811476On iPad, the ":hover" state sticks around, making things work not greatly. Do work around
14821477it, we move it into this media query. More information can be found at:
......@@ -1486,29 +1481,34 @@ However, using `@media (hover: hover)` makes this rule never to be applied in GU
14861481instead, we check that it's not a "finger" cursor.
14871482*/
14881483@media not (pointer: coarse) {
1489 .example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder {
1484 .example-wrap:hover > a.test-arrow, .example-wrap:hover > .button-holder {
14901485 visibility: visible;
14911486 }
14921487}
14931488.example-wrap .button-holder.keep-visible {
14941489 visibility: visible;
14951490}
1496.example-wrap .button-holder .copy-button {
1497 color: var(--copy-path-button-color);
1491.example-wrap .button-holder .copy-button, .example-wrap .test-arrow {
14981492 background: var(--main-background-color);
1493 cursor: pointer;
1494 border-radius: var(--button-border-radius);
14991495 height: var(--copy-path-height);
15001496 width: var(--copy-path-width);
1497}
1498.example-wrap .button-holder .copy-button {
15011499 margin-left: var(--button-left-margin);
15021500 padding: 2px 0 0 4px;
15031501 border: 0;
1504 cursor: pointer;
1505 border-radius: var(--button-border-radius);
15061502}
1507.example-wrap .button-holder .copy-button::before {
1503.example-wrap .button-holder .copy-button::before,
1504.example-wrap .test-arrow::before {
15081505 filter: var(--copy-path-img-filter);
1506}
1507.example-wrap .button-holder .copy-button::before {
15091508 content: var(--clipboard-image);
15101509}
1511.example-wrap .button-holder .copy-button:hover::before {
1510.example-wrap .button-holder .copy-button:hover::before,
1511.example-wrap .test-arrow:hover::before {
15121512 filter: var(--copy-path-img-hover-filter);
15131513}
15141514.example-wrap .button-holder .copy-button.clicked::before {
......@@ -2552,10 +2552,6 @@ by default.
25522552 --code-highlight-doc-comment-color: #4d4d4c;
25532553 --src-line-numbers-span-color: #c67e2d;
25542554 --src-line-number-highlighted-background-color: #fdffd3;
2555 --test-arrow-color: #f5f5f5;
2556 --test-arrow-background-color: rgba(78, 139, 202, 0.2);
2557 --test-arrow-hover-color: #f5f5f5;
2558 --test-arrow-hover-background-color: rgb(78, 139, 202);
25592555 --target-background-color: #fdffd3;
25602556 --target-border-color: #ad7c37;
25612557 --kbd-color: #000;
......@@ -2658,10 +2654,6 @@ by default.
26582654 --code-highlight-doc-comment-color: #8ca375;
26592655 --src-line-numbers-span-color: #3b91e2;
26602656 --src-line-number-highlighted-background-color: #0a042f;
2661 --test-arrow-color: #dedede;
2662 --test-arrow-background-color: rgba(78, 139, 202, 0.2);
2663 --test-arrow-hover-color: #dedede;
2664 --test-arrow-hover-background-color: #4e8bca;
26652657 --target-background-color: #494a3d;
26662658 --target-border-color: #bb7410;
26672659 --kbd-color: #000;
......@@ -2771,10 +2763,6 @@ Original by Dempfi (https://github.com/dempfi/ayu)
27712763 --code-highlight-doc-comment-color: #a1ac88;
27722764 --src-line-numbers-span-color: #5c6773;
27732765 --src-line-number-highlighted-background-color: rgba(255, 236, 164, 0.06);
2774 --test-arrow-color: #788797;
2775 --test-arrow-background-color: rgba(57, 175, 215, 0.09);
2776 --test-arrow-hover-color: #c5c5c5;
2777 --test-arrow-hover-background-color: rgba(57, 175, 215, 0.368);
27782766 --target-background-color: rgba(255, 236, 164, 0.06);
27792767 --target-border-color: rgba(255, 180, 76, 0.85);
27802768 --kbd-color: #c5c5c5;
src/librustdoc/html/static/js/main.js+6-2
......@@ -1835,10 +1835,14 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
18351835 function getExampleWrap(event) {
18361836 let elem = event.target;
18371837 while (!hasClass(elem, "example-wrap")) {
1838 elem = elem.parentElement;
1839 if (elem === document.body || hasClass(elem, "docblock")) {
1838 if (elem === document.body ||
1839 elem.tagName === "A" ||
1840 elem.tagName === "BUTTON" ||
1841 hasClass(elem, "docblock")
1842 ) {
18401843 return null;
18411844 }
1845 elem = elem.parentElement;
18421846 }
18431847 return elem;
18441848 }
src/tools/compiletest/src/runtest.rs+7-1
......@@ -3027,11 +3027,17 @@ impl<'test> TestCx<'test> {
30273027 const PREFIX: &str = "MONO_ITEM ";
30283028 const CGU_MARKER: &str = "@@";
30293029
3030 // Some MonoItems can contain {closure@/path/to/checkout/tests/codgen-units/test.rs}
3031 // To prevent the current dir from leaking, we just replace the entire path to the test
3032 // file with TEST_PATH.
30303033 let actual: Vec<MonoItem> = proc_res
30313034 .stdout
30323035 .lines()
30333036 .filter(|line| line.starts_with(PREFIX))
3034 .map(|line| str_to_mono_item(line, true))
3037 .map(|line| {
3038 line.replace(&self.testpaths.file.display().to_string(), "TEST_PATH").to_string()
3039 })
3040 .map(|line| str_to_mono_item(&line, true))
30353041 .collect();
30363042
30373043 let expected: Vec<MonoItem> = errors::load_errors(&self.testpaths.file, None)
tests/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs+2
......@@ -1,3 +1,5 @@
1//@ compile-flags: -Zinline-mir=no
2
13#![crate_type = "lib"]
24
35#[inline]
tests/codegen-units/item-collection/cross-crate-closures.rs+8-13
......@@ -1,9 +1,6 @@
1// In the current version of the collector that still has to support
2// legacy-codegen, closures do not generate their own MonoItems, so we are
3// ignoring this test until MIR codegen has taken over completely
4//@ ignore-test
5
6//@ compile-flags:-Zprint-mono-items=eager
1// We need to disable MIR inlining in both this and its aux-build crate. The MIR inliner
2// will just inline everything into our start function if we let it. As it should.
3//@ compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
74
85#![deny(dead_code)]
96#![feature(start)]
......@@ -11,15 +8,15 @@
118//@ aux-build:cgu_extern_closures.rs
129extern crate cgu_extern_closures;
1310
14//~ MONO_ITEM fn cross_crate_closures::start[0]
11//~ MONO_ITEM fn start @@ cross_crate_closures-cgu.0[Internal]
1512#[start]
1613fn start(_: isize, _: *const *const u8) -> isize {
17 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]
18 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]::{{closure}}[0]
14 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn @@ cross_crate_closures-cgu.0[Internal]
15 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn::{closure#0} @@ cross_crate_closures-cgu.0[Internal]
1916 let _ = cgu_extern_closures::inlined_fn(1, 2);
2017
21 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic[0]<i32>
22 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic[0]::{{closure}}[0]<i32>
18 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic::<i32> @@ cross_crate_closures-cgu.0[Internal]
19 //~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic::<i32>::{closure#0} @@ cross_crate_closures-cgu.0[Internal]
2320 let _ = cgu_extern_closures::inlined_fn_generic(3, 4, 5i32);
2421
2522 // Nothing should be generated for this call, we just link to the instance
......@@ -28,5 +25,3 @@ fn start(_: isize, _: *const *const u8) -> isize {
2825
2926 0
3027}
31
32//~ MONO_ITEM drop-glue i8
tests/codegen-units/item-collection/non-generic-closures.rs+13-17
......@@ -1,49 +1,45 @@
1// In the current version of the collector that still has to support
2// legacy-codegen, closures do not generate their own MonoItems, so we are
3// ignoring this test until MIR codegen has taken over completely
4//@ ignore-test
5
6//
7//@ compile-flags:-Zprint-mono-items=eager
1//@ compile-flags:-Zprint-mono-items=eager -Zinline-mir=no
82
93#![deny(dead_code)]
104#![feature(start)]
115
12//~ MONO_ITEM fn non_generic_closures::temporary[0]
6//~ MONO_ITEM fn temporary @@ non_generic_closures-cgu.0[Internal]
137fn temporary() {
14 //~ MONO_ITEM fn non_generic_closures::temporary[0]::{{closure}}[0]
8 //~ MONO_ITEM fn temporary::{closure#0} @@ non_generic_closures-cgu.0[Internal]
159 (|a: u32| {
1610 let _ = a;
1711 })(4);
1812}
1913
20//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_but_not_executed[0]
14//~ MONO_ITEM fn assigned_to_variable_but_not_executed @@ non_generic_closures-cgu.0[Internal]
2115fn assigned_to_variable_but_not_executed() {
22 //~ MONO_ITEM fn non_generic_closures::assigned_to_variable_but_not_executed[0]::{{closure}}[0]
2316 let _x = |a: i16| {
2417 let _ = a + 1;
2518 };
2619}
2720
28//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_directly[0]
21//~ MONO_ITEM fn assigned_to_variable_executed_indirectly @@ non_generic_closures-cgu.0[Internal]
2922fn assigned_to_variable_executed_indirectly() {
30 //~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_directly[0]::{{closure}}[0]
23 //~ MONO_ITEM fn assigned_to_variable_executed_indirectly::{closure#0} @@ non_generic_closures-cgu.0[Internal]
24 //~ MONO_ITEM fn <{closure@TEST_PATH:27:13: 27:21} as std::ops::FnOnce<(i32,)>>::call_once - shim @@ non_generic_closures-cgu.0[Internal]
25 //~ MONO_ITEM fn <{closure@TEST_PATH:27:13: 27:21} as std::ops::FnOnce<(i32,)>>::call_once - shim(vtable) @@ non_generic_closures-cgu.0[Internal]
26 //~ MONO_ITEM fn std::ptr::drop_in_place::<{closure@TEST_PATH:27:13: 27:21}> - shim(None) @@ non_generic_closures-cgu.0[Internal]
3127 let f = |a: i32| {
3228 let _ = a + 2;
3329 };
3430 run_closure(&f);
3531}
3632
37//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_indirectly[0]
33//~ MONO_ITEM fn assigned_to_variable_executed_directly @@ non_generic_closures-cgu.0[Internal]
3834fn assigned_to_variable_executed_directly() {
39 //~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_indirectly[0]::{{closure}}[0]
35 //~ MONO_ITEM fn assigned_to_variable_executed_directly::{closure#0} @@ non_generic_closures-cgu.0[Internal]
4036 let f = |a: i64| {
4137 let _ = a + 3;
4238 };
4339 f(4);
4440}
4541
46//~ MONO_ITEM fn non_generic_closures::start[0]
42//~ MONO_ITEM fn start @@ non_generic_closures-cgu.0[Internal]
4743#[start]
4844fn start(_: isize, _: *const *const u8) -> isize {
4945 temporary();
......@@ -54,7 +50,7 @@ fn start(_: isize, _: *const *const u8) -> isize {
5450 0
5551}
5652
57//~ MONO_ITEM fn non_generic_closures::run_closure[0]
53//~ MONO_ITEM fn run_closure @@ non_generic_closures-cgu.0[Internal]
5854fn run_closure(f: &Fn(i32)) {
5955 f(3);
6056}
tests/codegen-units/partitioning/methods-are-with-self-type.rs+15-27
......@@ -1,30 +1,23 @@
1// Currently, all generic functions are instantiated in each codegen unit that
2// uses them, even those not marked with #[inline], so this test does not make
3// much sense at the moment.
4//@ ignore-test
5
61// We specify incremental here because we want to test the partitioning for incremental compilation
72//@ incremental
83//@ compile-flags:-Zprint-mono-items=lazy
94
10#![allow(dead_code)]
11#![feature(start)]
5#![crate_type = "lib"]
126
13struct SomeType;
7pub struct SomeType;
148
159struct SomeGenericType<T1, T2>(T1, T2);
1610
17mod mod1 {
11pub mod mod1 {
1812 use super::{SomeGenericType, SomeType};
1913
2014 // Even though the impl is in `mod1`, the methods should end up in the
2115 // parent module, since that is where their self-type is.
2216 impl SomeType {
23 //~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::method[0] @@ methods_are_with_self_type[External]
24 fn method(&self) {}
25
26 //~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[0]::associated_fn[0] @@ methods_are_with_self_type[External]
27 fn associated_fn() {}
17 //~ MONO_ITEM fn mod1::<impl SomeType>::method @@ methods_are_with_self_type[External]
18 pub fn method(&self) {}
19 //~ MONO_ITEM fn mod1::<impl SomeType>::associated_fn @@ methods_are_with_self_type[External]
20 pub fn associated_fn() {}
2821 }
2922
3023 impl<T1, T2> SomeGenericType<T1, T2> {
......@@ -52,25 +45,20 @@ mod type2 {
5245 pub struct Struct;
5346}
5447
55//~ MONO_ITEM fn methods_are_with_self_type::start[0]
56#[start]
57fn start(_: isize, _: *const *const u8) -> isize {
58 //~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::method[0]<u32, u64> @@ methods_are_with_self_type.volatile[WeakODR]
48//~ MONO_ITEM fn start @@ methods_are_with_self_type[External]
49pub fn start() {
50 //~ MONO_ITEM fn mod1::<impl SomeGenericType<u32, u64>>::method @@ methods_are_with_self_type.volatile[External]
5951 SomeGenericType(0u32, 0u64).method();
60 //~ MONO_ITEM fn methods_are_with_self_type::mod1[0]::{{impl}}[1]::associated_fn[0]<char, &str> @@ methods_are_with_self_type.volatile[WeakODR]
52 //~ MONO_ITEM fn mod1::<impl SomeGenericType<char, &str>>::associated_fn @@ methods_are_with_self_type.volatile[External]
6153 SomeGenericType::associated_fn('c', "&str");
6254
63 //~ MONO_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0]<methods_are_with_self_type::type1[0]::Struct[0]> @@ methods_are_with_self_type-type1.volatile[WeakODR]
55 //~ MONO_ITEM fn <type1::Struct as Trait>::foo @@ methods_are_with_self_type-type1.volatile[External]
6456 type1::Struct.foo();
65 //~ MONO_ITEM fn methods_are_with_self_type::{{impl}}[0]::foo[0]<methods_are_with_self_type::type2[0]::Struct[0]> @@ methods_are_with_self_type-type2.volatile[WeakODR]
57 //~ MONO_ITEM fn <type2::Struct as Trait>::foo @@ methods_are_with_self_type-type2.volatile[External]
6658 type2::Struct.foo();
6759
68 //~ MONO_ITEM fn methods_are_with_self_type::Trait[0]::default[0]<methods_are_with_self_type::type1[0]::Struct[0]> @@ methods_are_with_self_type-type1.volatile[WeakODR]
60 //~ MONO_ITEM fn <type1::Struct as Trait>::default @@ methods_are_with_self_type-type1.volatile[External]
6961 type1::Struct.default();
70 //~ MONO_ITEM fn methods_are_with_self_type::Trait[0]::default[0]<methods_are_with_self_type::type2[0]::Struct[0]> @@ methods_are_with_self_type-type2.volatile[WeakODR]
62 //~ MONO_ITEM fn <type2::Struct as Trait>::default @@ methods_are_with_self_type-type2.volatile[External]
7163 type2::Struct.default();
72
73 0
7464}
75
76//~ MONO_ITEM drop-glue i8
tests/codegen/const-vector.rs created+107
......@@ -0,0 +1,107 @@
1//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
2
3// This test checks that constants of SIMD type are passed as immediate vectors.
4// We ensure that both vector representations (struct with fields and struct wrapping array) work.
5#![crate_type = "lib"]
6#![feature(abi_unadjusted)]
7#![feature(const_trait_impl)]
8#![feature(repr_simd)]
9#![feature(rustc_attrs)]
10#![feature(simd_ffi)]
11#![allow(non_camel_case_types)]
12
13// Setting up structs that can be used as const vectors
14#[repr(simd)]
15#[derive(Clone)]
16pub struct i8x2(i8, i8);
17
18#[repr(simd)]
19#[derive(Clone)]
20pub struct i8x2_arr([i8; 2]);
21
22#[repr(simd)]
23#[derive(Clone)]
24pub struct f32x2(f32, f32);
25
26#[repr(simd)]
27#[derive(Clone)]
28pub struct f32x2_arr([f32; 2]);
29
30#[repr(simd, packed)]
31#[derive(Copy, Clone)]
32pub struct Simd<T, const N: usize>([T; N]);
33
34// The following functions are required for the tests to ensure
35// that they are called with a const vector
36
37extern "unadjusted" {
38 #[no_mangle]
39 fn test_i8x2(a: i8x2);
40}
41
42extern "unadjusted" {
43 #[no_mangle]
44 fn test_i8x2_two_args(a: i8x2, b: i8x2);
45}
46
47extern "unadjusted" {
48 #[no_mangle]
49 fn test_i8x2_mixed_args(a: i8x2, c: i32, b: i8x2);
50}
51
52extern "unadjusted" {
53 #[no_mangle]
54 fn test_i8x2_arr(a: i8x2_arr);
55}
56
57extern "unadjusted" {
58 #[no_mangle]
59 fn test_f32x2(a: f32x2);
60}
61
62extern "unadjusted" {
63 #[no_mangle]
64 fn test_f32x2_arr(a: f32x2_arr);
65}
66
67extern "unadjusted" {
68 #[no_mangle]
69 fn test_simd(a: Simd<i32, 4>);
70}
71
72extern "unadjusted" {
73 #[no_mangle]
74 fn test_simd_unaligned(a: Simd<i32, 3>);
75}
76
77// Ensure the packed variant of the simd struct does not become a const vector
78// if the size is not a power of 2
79// CHECK: %"Simd<i32, 3>" = type { [3 x i32] }
80
81pub fn do_call() {
82 unsafe {
83 // CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64>
84 test_i8x2(const { i8x2(32, 64) });
85
86 // CHECK: call void @test_i8x2_two_args(<2 x i8> <i8 32, i8 64>, <2 x i8> <i8 8, i8 16>
87 test_i8x2_two_args(const { i8x2(32, 64) }, const { i8x2(8, 16) });
88
89 // CHECK: call void @test_i8x2_mixed_args(<2 x i8> <i8 32, i8 64>, i32 43, <2 x i8> <i8 8, i8 16>
90 test_i8x2_mixed_args(const { i8x2(32, 64) }, 43, const { i8x2(8, 16) });
91
92 // CHECK: call void @test_i8x2_arr(<2 x i8> <i8 32, i8 64>
93 test_i8x2_arr(const { i8x2_arr([32, 64]) });
94
95 // CHECK: call void @test_f32x2(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
96 test_f32x2(const { f32x2(0.32, 0.64) });
97
98 // CHECK: void @test_f32x2_arr(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
99 test_f32x2_arr(const { f32x2_arr([0.32, 0.64]) });
100
101 // CHECK: call void @test_simd(<4 x i32> <i32 2, i32 4, i32 6, i32 8>
102 test_simd(const { Simd::<i32, 4>([2, 4, 6, 8]) });
103
104 // CHECK: call void @test_simd_unaligned(%"Simd<i32, 3>" %1
105 test_simd_unaligned(const { Simd::<i32, 3>([2, 4, 6]) });
106 }
107}
tests/codegen/intrinsics/nontemporal.rs+27-3
......@@ -1,13 +1,37 @@
11//@ compile-flags: -O
2//@revisions: with_nontemporal without_nontemporal
3//@[with_nontemporal] compile-flags: --target aarch64-unknown-linux-gnu
4//@[with_nontemporal] needs-llvm-components: aarch64
5//@[without_nontemporal] compile-flags: --target x86_64-unknown-linux-gnu
6//@[without_nontemporal] needs-llvm-components: x86
27
3#![feature(core_intrinsics)]
8// Ensure that we *do* emit the `!nontemporal` flag on architectures where it
9// is well-behaved, but do *not* emit it on architectures where it is ill-behaved.
10// For more context, see <https://github.com/rust-lang/rust/issues/114582> and
11// <https://github.com/llvm/llvm-project/issues/64521>.
12
13#![feature(no_core, lang_items, intrinsics)]
14#![no_core]
415#![crate_type = "lib"]
516
17#[lang = "sized"]
18pub trait Sized {}
19#[lang = "copy"]
20pub trait Copy {}
21
22impl Copy for u32 {}
23impl<T> Copy for *mut T {}
24
25extern "rust-intrinsic" {
26 pub fn nontemporal_store<T>(ptr: *mut T, val: T);
27}
28
629#[no_mangle]
730pub fn a(a: &mut u32, b: u32) {
831 // CHECK-LABEL: define{{.*}}void @a
9 // CHECK: store i32 %b, ptr %a, align 4, !nontemporal
32 // with_nontemporal: store i32 %b, ptr %a, align 4, !nontemporal
33 // without_nontemporal-NOT: nontemporal
1034 unsafe {
11 std::intrinsics::nontemporal_store(a, b);
35 nontemporal_store(a, b);
1236 }
1337}
tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs-2
......@@ -3,8 +3,6 @@
33// Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current
44// `rustc` version and the `since` property in feature stability gating is properly respected.
55
6use std::path::PathBuf;
7
86use run_make_support::{aux_build, rfs, rustc, source_root};
97
108fn main() {
tests/run-make/arguments-non-c-like-enum/rmake.rs-2
......@@ -4,8 +4,6 @@
44use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib_name};
55
66pub fn main() {
7 use std::path::Path;
8
97 rustc().input("nonclike.rs").crate_type("staticlib").run();
108 cc().input("test.c")
119 .input(static_lib_name("nonclike"))
tests/run-make/c-link-to-rust-staticlib/rmake.rs-2
......@@ -3,8 +3,6 @@
33
44//@ ignore-cross-compile
55
6use std::fs;
7
86use run_make_support::rfs::remove_file;
97use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name};
108
tests/run-make/comment-section/rmake.rs+1-3
......@@ -7,9 +7,7 @@
77// FIXME(jieyouxu): check cross-compile setup
88//@ ignore-cross-compile
99
10use std::path::PathBuf;
11
12use run_make_support::{cwd, env_var, llvm_readobj, rfs, run_in_tmpdir, rustc};
10use run_make_support::{cwd, env_var, llvm_readobj, rfs, rustc};
1311
1412fn main() {
1513 let target = env_var("TARGET");
tests/run-make/compressed-debuginfo/rmake.rs+1-1
......@@ -5,7 +5,7 @@
55
66// FIXME: This test isn't comprehensive and isn't covering all possible combinations.
77
8use run_make_support::{assert_contains, cmd, llvm_readobj, run_in_tmpdir, rustc};
8use run_make_support::{assert_contains, llvm_readobj, run_in_tmpdir, rustc};
99
1010fn check_compression(compression: &str, to_find: &str) {
1111 run_in_tmpdir(|| {
tests/run-make/const_fn_mir/rmake.rs+1-1
......@@ -2,7 +2,7 @@
22
33//@ needs-unwind
44
5use run_make_support::{cwd, diff, rustc};
5use run_make_support::{diff, rustc};
66
77fn main() {
88 rustc().input("main.rs").emit("mir").output("dump-actual.mir").run();
tests/run-make/crate-loading/rmake.rs+2-3
......@@ -2,14 +2,13 @@
22//@ ignore-wasm32
33//@ ignore-wasm64
44
5use run_make_support::rfs::copy;
6use run_make_support::{assert_contains, rust_lib_name, rustc};
5use run_make_support::{rust_lib_name, rustc};
76
87fn main() {
98 rustc().input("multiple-dep-versions-1.rs").run();
109 rustc().input("multiple-dep-versions-2.rs").extra_filename("2").metadata("2").run();
1110
12 let out = rustc()
11 rustc()
1312 .input("multiple-dep-versions.rs")
1413 .extern_("dependency", rust_lib_name("dependency"))
1514 .extern_("dep_2_reexport", rust_lib_name("dependency2"))
tests/run-make/dylib-soname/rmake.rs-1
......@@ -4,7 +4,6 @@
44//@ only-linux
55//@ ignore-cross-compile
66
7use run_make_support::regex::Regex;
87use run_make_support::{cmd, run_in_tmpdir, rustc};
98
109fn main() {
tests/run-make/extern-flag-disambiguates/rmake.rs+1-1
......@@ -1,6 +1,6 @@
11//@ ignore-cross-compile
22
3use run_make_support::{cwd, run, rustc};
3use run_make_support::{run, rustc};
44
55// Attempt to build this dependency tree:
66//
tests/run-make/ice-dep-cannot-find-dep/rmake.rs+1-1
......@@ -16,7 +16,7 @@
1616// If we used `rustc` the additional '-L rmake_out' option would allow rustc to
1717// actually find the crate.
1818
19use run_make_support::{bare_rustc, rfs, rust_lib_name, rustc};
19use run_make_support::{bare_rustc, rust_lib_name, rustc};
2020
2121fn main() {
2222 rustc().crate_name("a").crate_type("rlib").input("a.rs").arg("--verbose").run();
tests/run-make/incr-test-moved-file/rmake.rs+1-1
......@@ -14,7 +14,7 @@
1414//@ ignore-nvptx64-nvidia-cuda
1515// FIXME: can't find crate for 'std'
1616
17use run_make_support::{rfs, rust_lib_name, rustc};
17use run_make_support::{rfs, rustc};
1818
1919fn main() {
2020 rfs::create_dir("incr");
tests/run-make/incremental-debugger-visualizer/rmake.rs-2
......@@ -2,8 +2,6 @@
22// (in this case, foo.py and foo.natvis) are picked up when compiling incrementally.
33// See https://github.com/rust-lang/rust/pull/111641
44
5use std::io::Read;
6
75use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rfs, rustc};
86
97fn main() {
tests/run-make/lto-readonly-lib/rmake.rs+1-1
......@@ -7,7 +7,7 @@
77
88//@ ignore-cross-compile
99
10use run_make_support::{rfs, run, rust_lib_name, rustc, test_while_readonly};
10use run_make_support::{run, rust_lib_name, rustc, test_while_readonly};
1111
1212fn main() {
1313 rustc().input("lib.rs").run();
tests/run-make/multiple-emits/rmake.rs+1-1
......@@ -1,4 +1,4 @@
1use run_make_support::{cwd, path, rustc};
1use run_make_support::{path, rustc};
22
33fn main() {
44 rustc().input("foo.rs").emit("asm,llvm-ir").output("out").run();
tests/run-make/naked-symbol-visibility/rmake.rs+1-1
......@@ -3,7 +3,7 @@
33use run_make_support::object::read::{File, Object, Symbol};
44use run_make_support::object::ObjectSymbol;
55use run_make_support::targets::is_windows;
6use run_make_support::{dynamic_lib_name, env_var, rfs, rustc};
6use run_make_support::{dynamic_lib_name, rfs, rustc};
77
88fn main() {
99 let rdylib_name = dynamic_lib_name("a_rust_dylib");
tests/run-make/non-unicode-in-incremental-dir/rmake.rs+1-1
......@@ -8,7 +8,7 @@ fn main() {
88 match std::fs::create_dir(&non_unicode) {
99 // If an error occurs, check if creating a directory with a valid Unicode name would
1010 // succeed.
11 Err(e) if std::fs::create_dir("valid_unicode").is_ok() => {
11 Err(_) if std::fs::create_dir("valid_unicode").is_ok() => {
1212 // Filesystem doesn't appear support non-Unicode paths.
1313 return;
1414 }
tests/run-make/output-type-permutations/rmake.rs+22-22
......@@ -113,7 +113,7 @@ fn main() {
113113 assert_expected_output_files(
114114 Expectations {
115115 expected_files: s!["foo"],
116 allowed_files: s![],
116 allowed_files: vec![],
117117 test_dir: "asm-emit".to_string(),
118118 },
119119 || {
......@@ -123,7 +123,7 @@ fn main() {
123123 assert_expected_output_files(
124124 Expectations {
125125 expected_files: s!["foo"],
126 allowed_files: s![],
126 allowed_files: vec![],
127127 test_dir: "asm-emit2".to_string(),
128128 },
129129 || {
......@@ -133,7 +133,7 @@ fn main() {
133133 assert_expected_output_files(
134134 Expectations {
135135 expected_files: s!["foo"],
136 allowed_files: s![],
136 allowed_files: vec![],
137137 test_dir: "asm-emit3".to_string(),
138138 },
139139 || {
......@@ -144,7 +144,7 @@ fn main() {
144144 assert_expected_output_files(
145145 Expectations {
146146 expected_files: s!["foo"],
147 allowed_files: s![],
147 allowed_files: vec![],
148148 test_dir: "llvm-ir-emit".to_string(),
149149 },
150150 || {
......@@ -154,7 +154,7 @@ fn main() {
154154 assert_expected_output_files(
155155 Expectations {
156156 expected_files: s!["foo"],
157 allowed_files: s![],
157 allowed_files: vec![],
158158 test_dir: "llvm-ir-emit2".to_string(),
159159 },
160160 || {
......@@ -164,7 +164,7 @@ fn main() {
164164 assert_expected_output_files(
165165 Expectations {
166166 expected_files: s!["foo"],
167 allowed_files: s![],
167 allowed_files: vec![],
168168 test_dir: "llvm-ir-emit3".to_string(),
169169 },
170170 || {
......@@ -175,7 +175,7 @@ fn main() {
175175 assert_expected_output_files(
176176 Expectations {
177177 expected_files: s!["foo"],
178 allowed_files: s![],
178 allowed_files: vec![],
179179 test_dir: "llvm-bc-emit".to_string(),
180180 },
181181 || {
......@@ -185,7 +185,7 @@ fn main() {
185185 assert_expected_output_files(
186186 Expectations {
187187 expected_files: s!["foo"],
188 allowed_files: s![],
188 allowed_files: vec![],
189189 test_dir: "llvm-bc-emit2".to_string(),
190190 },
191191 || {
......@@ -195,7 +195,7 @@ fn main() {
195195 assert_expected_output_files(
196196 Expectations {
197197 expected_files: s!["foo"],
198 allowed_files: s![],
198 allowed_files: vec![],
199199 test_dir: "llvm-bc-emit3".to_string(),
200200 },
201201 || {
......@@ -206,7 +206,7 @@ fn main() {
206206 assert_expected_output_files(
207207 Expectations {
208208 expected_files: s!["foo"],
209 allowed_files: s![],
209 allowed_files: vec![],
210210 test_dir: "obj-emit".to_string(),
211211 },
212212 || {
......@@ -216,7 +216,7 @@ fn main() {
216216 assert_expected_output_files(
217217 Expectations {
218218 expected_files: s!["foo"],
219 allowed_files: s![],
219 allowed_files: vec![],
220220 test_dir: "obj-emit2".to_string(),
221221 },
222222 || {
......@@ -226,7 +226,7 @@ fn main() {
226226 assert_expected_output_files(
227227 Expectations {
228228 expected_files: s!["foo"],
229 allowed_files: s![],
229 allowed_files: vec![],
230230 test_dir: "obj-emit3".to_string(),
231231 },
232232 || {
......@@ -268,7 +268,7 @@ fn main() {
268268 assert_expected_output_files(
269269 Expectations {
270270 expected_files: s!["foo"],
271 allowed_files: s![],
271 allowed_files: vec![],
272272 test_dir: "rlib".to_string(),
273273 },
274274 || {
......@@ -278,7 +278,7 @@ fn main() {
278278 assert_expected_output_files(
279279 Expectations {
280280 expected_files: s!["foo"],
281 allowed_files: s![],
281 allowed_files: vec![],
282282 test_dir: "rlib2".to_string(),
283283 },
284284 || {
......@@ -288,7 +288,7 @@ fn main() {
288288 assert_expected_output_files(
289289 Expectations {
290290 expected_files: s!["foo"],
291 allowed_files: s![],
291 allowed_files: vec![],
292292 test_dir: "rlib3".to_string(),
293293 },
294294 || {
......@@ -375,7 +375,7 @@ fn main() {
375375 assert_expected_output_files(
376376 Expectations {
377377 expected_files: s!["foo"],
378 allowed_files: s![],
378 allowed_files: vec![],
379379 test_dir: "staticlib".to_string(),
380380 },
381381 || {
......@@ -385,7 +385,7 @@ fn main() {
385385 assert_expected_output_files(
386386 Expectations {
387387 expected_files: s!["foo"],
388 allowed_files: s![],
388 allowed_files: vec![],
389389 test_dir: "staticlib2".to_string(),
390390 },
391391 || {
......@@ -395,7 +395,7 @@ fn main() {
395395 assert_expected_output_files(
396396 Expectations {
397397 expected_files: s!["foo"],
398 allowed_files: s![],
398 allowed_files: vec![],
399399 test_dir: "staticlib3".to_string(),
400400 },
401401 || {
......@@ -449,7 +449,7 @@ fn main() {
449449 assert_expected_output_files(
450450 Expectations {
451451 expected_files: s!["ir", rust_lib_name("bar")],
452 allowed_files: s![],
452 allowed_files: vec![],
453453 test_dir: "rlib-ir".to_string(),
454454 },
455455 || {
......@@ -466,7 +466,7 @@ fn main() {
466466 assert_expected_output_files(
467467 Expectations {
468468 expected_files: s!["ir", "asm", "bc", "obj", "link"],
469 allowed_files: s![],
469 allowed_files: vec![],
470470 test_dir: "staticlib-all".to_string(),
471471 },
472472 || {
......@@ -484,7 +484,7 @@ fn main() {
484484 assert_expected_output_files(
485485 Expectations {
486486 expected_files: s!["ir", "asm", "bc", "obj", "link"],
487 allowed_files: s![],
487 allowed_files: vec![],
488488 test_dir: "staticlib-all2".to_string(),
489489 },
490490 || {
......@@ -523,7 +523,7 @@ fn main() {
523523 assert_expected_output_files(
524524 Expectations {
525525 expected_files: s!["bar.bc", rust_lib_name("bar"), "foo.bc"],
526 allowed_files: s![],
526 allowed_files: vec![],
527527 test_dir: "rlib-emits".to_string(),
528528 },
529529 || {
tests/run-make/print-check-cfg/rmake.rs-1
......@@ -4,7 +4,6 @@ extern crate run_make_support;
44
55use std::collections::HashSet;
66use std::iter::FromIterator;
7use std::ops::Deref;
87
98use run_make_support::rustc;
109
tests/run-make/print-native-static-libs/rmake.rs-2
......@@ -12,8 +12,6 @@
1212//@ ignore-cross-compile
1313//@ ignore-wasm
1414
15use std::io::BufRead;
16
1715use run_make_support::{is_msvc, rustc};
1816
1917fn main() {
tests/run-make/redundant-libs/rmake.rs+1-3
......@@ -11,9 +11,7 @@
1111//@ ignore-cross-compile
1212// Reason: the compiled binary is executed
1313
14use run_make_support::{
15 build_native_dynamic_lib, build_native_static_lib, cwd, is_msvc, rfs, run, rustc,
16};
14use run_make_support::{build_native_dynamic_lib, build_native_static_lib, run, rustc};
1715
1816fn main() {
1917 build_native_dynamic_lib("foo");
tests/run-make/reproducible-build-2/rmake.rs+1-1
......@@ -13,7 +13,7 @@
1313// 2. When the sysroot gets copied, some symlinks must be re-created,
1414// which is a privileged action on Windows.
1515
16use run_make_support::{bin_name, rfs, rust_lib_name, rustc};
16use run_make_support::{rfs, rust_lib_name, rustc};
1717
1818fn main() {
1919 // test 1: fat lto
tests/run-make/reset-codegen-1/rmake.rs+1-1
......@@ -9,7 +9,7 @@
99
1010use std::path::Path;
1111
12use run_make_support::{bin_name, rfs, rustc};
12use run_make_support::{bin_name, rustc};
1313
1414fn compile(output_file: &str, emit: Option<&str>) {
1515 let mut rustc = rustc();
tests/run-make/rlib-format-packed-bundled-libs-3/rmake.rs+1-1
......@@ -6,7 +6,7 @@
66// See https://github.com/rust-lang/rust/pull/105601
77
88use run_make_support::{
9 build_native_static_lib, is_msvc, llvm_ar, regex, rfs, rust_lib_name, rustc, static_lib_name,
9 build_native_static_lib, llvm_ar, regex, rfs, rust_lib_name, rustc, static_lib_name,
1010};
1111
1212//@ ignore-cross-compile
tests/run-make/run-in-tmpdir-self-test/rmake.rs+1-1
......@@ -3,7 +3,7 @@
33//! when returning from the closure.
44
55use std::fs;
6use std::path::{Path, PathBuf};
6use std::path::PathBuf;
77
88use run_make_support::{cwd, run_in_tmpdir};
99
tests/run-make/rust-lld-by-default-nightly/rmake.rs-2
......@@ -6,8 +6,6 @@
66//@ ignore-stable
77//@ only-x86_64-unknown-linux-gnu
88
9use std::process::Output;
10
119use run_make_support::regex::Regex;
1210use run_make_support::rustc;
1311
tests/run-make/rust-lld-compress-debug-sections/rmake.rs+1-1
......@@ -6,7 +6,7 @@
66
77// FIXME: This test isn't comprehensive and isn't covering all possible combinations.
88
9use run_make_support::{assert_contains, cmd, llvm_readobj, run_in_tmpdir, rustc};
9use run_make_support::{assert_contains, llvm_readobj, run_in_tmpdir, rustc};
1010
1111fn check_compression(compression: &str, to_find: &str) {
1212 run_in_tmpdir(|| {
tests/run-make/rust-lld-custom-target/rmake.rs-2
......@@ -8,8 +8,6 @@
88//@ needs-rust-lld
99//@ only-x86_64-unknown-linux-gnu
1010
11use std::process::Output;
12
1311use run_make_support::regex::Regex;
1412use run_make_support::rustc;
1513
tests/run-make/rust-lld/rmake.rs-2
......@@ -4,8 +4,6 @@
44//@ needs-rust-lld
55//@ ignore-s390x lld does not yet support s390x as target
66
7use std::process::Output;
8
97use run_make_support::regex::Regex;
108use run_make_support::{is_msvc, rustc};
119
tests/run-make/rustdoc-io-error/rmake.rs+5-7
......@@ -14,22 +14,20 @@
1414// `mkfs.ext4 -d`, as well as mounting a loop device for the rootfs.
1515//@ ignore-windows - the `set_readonly` functions doesn't work on folders.
1616
17use std::fs;
18
19use run_make_support::{path, rustdoc};
17use run_make_support::{path, rfs, rustdoc};
2018
2119fn main() {
2220 let out_dir = path("rustdoc-io-error");
23 let output = fs::create_dir(&out_dir).unwrap();
24 let mut permissions = fs::metadata(&out_dir).unwrap().permissions();
21 rfs::create_dir(&out_dir);
22 let mut permissions = rfs::metadata(&out_dir).permissions();
2523 let original_permissions = permissions.clone();
2624
2725 permissions.set_readonly(true);
28 fs::set_permissions(&out_dir, permissions).unwrap();
26 rfs::set_permissions(&out_dir, permissions);
2927
3028 let output = rustdoc().input("foo.rs").output(&out_dir).env("RUST_BACKTRACE", "1").run_fail();
3129
32 fs::set_permissions(&out_dir, original_permissions).unwrap();
30 rfs::set_permissions(&out_dir, original_permissions);
3331
3432 output
3533 .assert_exit_code(1)
tests/run-make/rustdoc-scrape-examples-remap/scrape.rs+1-1
......@@ -1,6 +1,6 @@
11use std::path::Path;
22
3use run_make_support::{htmldocck, rfs, rustc, rustdoc, source_root};
3use run_make_support::{htmldocck, rfs, rustc, rustdoc};
44
55pub fn scrape(extra_args: &[&str]) {
66 let out_dir = Path::new("rustdoc");
tests/run-make/sepcomp-cci-copies/rmake.rs+1-4
......@@ -4,10 +4,7 @@
44// created for each source module (see `rustc_const_eval::monomorphize::partitioning`).
55// See https://github.com/rust-lang/rust/pull/16367
66
7use run_make_support::{
8 count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
9 shallow_find_files,
10};
7use run_make_support::{count_regex_matches_in_files_with_extension, regex, rustc};
118
129fn main() {
1310 rustc().input("cci_lib.rs").run();
tests/run-make/sepcomp-inlining/rmake.rs+1-4
......@@ -5,10 +5,7 @@
55// in only one compilation unit.
66// See https://github.com/rust-lang/rust/pull/16367
77
8use run_make_support::{
9 count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
10 shallow_find_files,
11};
8use run_make_support::{count_regex_matches_in_files_with_extension, regex, rustc};
129
1310fn main() {
1411 rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).arg("-Zinline-in-all-cgus").run();
tests/run-make/sepcomp-separate/rmake.rs+1-4
......@@ -3,10 +3,7 @@
33// wind up in three different compilation units.
44// See https://github.com/rust-lang/rust/pull/16367
55
6use run_make_support::{
7 count_regex_matches_in_files_with_extension, cwd, has_extension, regex, rfs, rustc,
8 shallow_find_files,
9};
6use run_make_support::{count_regex_matches_in_files_with_extension, regex, rustc};
107
118fn main() {
129 rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).run();
tests/rustdoc-gui/code-example-buttons.goml+75
......@@ -1,5 +1,6 @@
11// This test ensures that code blocks buttons are displayed on hover and when you click on them.
22go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
3include: "utils.goml"
34
45// First we check we "hover".
56move-cursor-to: ".example-wrap"
......@@ -19,3 +20,77 @@ click: ".example-wrap"
1920move-cursor-to: ".search-input"
2021assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0)
2122assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })
23
24// Clicking on the "copy code" button shouldn't make the buttons stick.
25click: ".example-wrap .copy-button"
26move-cursor-to: ".search-input"
27assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0)
28assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })
29
30define-function: (
31 "check-buttons",
32 [theme, background, filter, filter_hover],
33 block {
34 call-function: ("switch-theme", {"theme": |theme|})
35
36 assert-css: (".example-wrap .test-arrow", {"visibility": "hidden"})
37 assert-css: (".example-wrap .copy-button", {"visibility": "hidden"})
38
39 move-cursor-to: ".example-wrap"
40 assert-css: (".example-wrap .test-arrow", {
41 "visibility": "visible",
42 "background-color": |background|,
43 "border-radius": "2px",
44 })
45 assert-css: (".example-wrap .test-arrow::before", {
46 "filter": |filter|,
47 })
48 assert-css: (".example-wrap .copy-button", {
49 "visibility": "visible",
50 "background-color": |background|,
51 "border-radius": "2px",
52 })
53 assert-css: (".example-wrap .copy-button::before", {
54 "filter": |filter|,
55 })
56
57 move-cursor-to: ".example-wrap .test-arrow"
58 assert-css: (".example-wrap .test-arrow:hover", {
59 "visibility": "visible",
60 "background-color": |background|,
61 "border-radius": "2px",
62 })
63 assert-css: (".example-wrap .test-arrow:hover::before", {
64 "filter": |filter_hover|,
65 })
66
67 move-cursor-to: ".example-wrap .copy-button"
68 assert-css: (".example-wrap .copy-button:hover", {
69 "visibility": "visible",
70 "background-color": |background|,
71 "border-radius": "2px",
72 })
73 assert-css: (".example-wrap .copy-button:hover::before", {
74 "filter": |filter_hover|,
75 })
76 },
77)
78
79call-function: ("check-buttons",{
80 "theme": "ayu",
81 "background": "#0f1419",
82 "filter": "invert(0.7)",
83 "filter_hover": "invert(1)",
84})
85call-function: ("check-buttons",{
86 "theme": "dark",
87 "background": "#353535",
88 "filter": "invert(0.5)",
89 "filter_hover": "invert(0.65)",
90})
91call-function: ("check-buttons",{
92 "theme": "light",
93 "background": "#fff",
94 "filter": "invert(0.5)",
95 "filter_hover": "invert(0.35)",
96})
tests/rustdoc-gui/copy-code.goml+2-2
......@@ -24,11 +24,11 @@ define-function: (
2424)
2525
2626call-function: ("check-copy-button", {})
27// Checking that the run button and the copy button have the same height.
27// Checking that the run button and the copy button have the same height and same width.
2828compare-elements-size: (
2929 ".example-wrap:nth-of-type(1) .test-arrow",
3030 ".example-wrap:nth-of-type(1) .copy-button",
31 ["height"],
31 ["height", "width"],
3232)
3333// ... and the same y position.
3434compare-elements-position: (
tests/rustdoc-gui/run-on-hover.goml deleted-54
......@@ -1,54 +0,0 @@
1// Example code blocks sometimes have a "Run" button to run them on the
2// Playground. That button is hidden until the user hovers over the code block.
3// This test checks that it is hidden, and that it shows on hover. It also
4// checks for its color.
5include: "utils.goml"
6go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
7show-text: true
8
9define-function: (
10 "check-run-button",
11 [theme, color, background, hover_color, hover_background],
12 block {
13 call-function: ("switch-theme", {"theme": |theme|})
14 assert-css: (".test-arrow", {"visibility": "hidden"})
15 move-cursor-to: ".example-wrap"
16 assert-css: (".test-arrow", {
17 "visibility": "visible",
18 "color": |color|,
19 "background-color": |background|,
20 "font-size": "16px",
21 "border-radius": "2px",
22 })
23 move-cursor-to: ".test-arrow"
24 assert-css: (".test-arrow:hover", {
25 "visibility": "visible",
26 "color": |hover_color|,
27 "background-color": |hover_background|,
28 "font-size": "16px",
29 "border-radius": "2px",
30 })
31 },
32)
33
34call-function: ("check-run-button", {
35 "theme": "ayu",
36 "color": "#788797",
37 "background": "rgba(57, 175, 215, 0.09)",
38 "hover_color": "#c5c5c5",
39 "hover_background": "rgba(57, 175, 215, 0.37)",
40})
41call-function: ("check-run-button", {
42 "theme": "dark",
43 "color": "#dedede",
44 "background": "rgba(78, 139, 202, 0.2)",
45 "hover_color": "#dedede",
46 "hover_background": "rgb(78, 139, 202)",
47})
48call-function: ("check-run-button", {
49 "theme": "light",
50 "color": "#f5f5f5",
51 "background": "rgba(78, 139, 202, 0.2)",
52 "hover_color": "#f5f5f5",
53 "hover_background": "rgb(78, 139, 202)",
54})
tests/rustdoc/playground-arg.rs+1-1
......@@ -10,4 +10,4 @@
1010pub fn dummy() {}
1111
1212// ensure that `extern crate foo;` was inserted into code snips automatically:
13//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0A%23%5Ballow(unused_extern_crates)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0A++++use+foo::dummy;%0A++++dummy();%0A%7D&edition=2015"]' "Run"
13//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0A%23%5Ballow(unused_extern_crates)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0A++++use+foo::dummy;%0A++++dummy();%0A%7D&edition=2015"]' ""
tests/rustdoc/playground-syntax-error.rs+1-1
......@@ -17,5 +17,5 @@
1717pub fn bar() {}
1818
1919//@ has foo/fn.bar.html
20//@ has - '//a[@class="test-arrow"]' "Run"
20//@ has - '//a[@class="test-arrow"]' ""
2121//@ has - '//*[@class="docblock"]' 'foo_recursive'
tests/rustdoc/playground.rs+3-3
......@@ -22,6 +22,6 @@
2222//! }
2323//! ```
2424
25//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
26//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
27//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&version=nightly&edition=2015"]' "Run"
25//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' ""
26//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' ""
27//@ matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&version=nightly&edition=2015"]' ""
tests/ui/coroutine/gen_block.none.stderr-2
......@@ -73,7 +73,6 @@ LL | let _ = || yield true;
7373 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
7474 = help: add `#![feature(coroutines)]` to the crate attributes to enable
7575 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
76 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
7776
7877error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
7978 --> $DIR/gen_block.rs:16:16
......@@ -95,7 +94,6 @@ LL | let _ = #[coroutine] || yield true;
9594 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
9695 = help: add `#![feature(coroutines)]` to the crate attributes to enable
9796 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
98 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
9997
10098error: aborting due to 11 previous errors
10199
tests/ui/feature-gates/feature-gate-coroutines.none.stderr-2
......@@ -47,7 +47,6 @@ LL | yield true;
4747 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
4848 = help: add `#![feature(coroutines)]` to the crate attributes to enable
4949 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
50 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
5150
5251error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
5352 --> $DIR/feature-gate-coroutines.rs:5:5
......@@ -69,7 +68,6 @@ LL | let _ = || yield true;
6968 = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
7069 = help: add `#![feature(coroutines)]` to the crate attributes to enable
7170 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
72 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
7371
7472error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
7573 --> $DIR/feature-gate-coroutines.rs:10:16
tests/ui/proc-macro/auxiliary/parse-invis-delim-issue-128895.rs created+44
......@@ -0,0 +1,44 @@
1//@ force-host
2//@ no-prefer-dynamic
3
4#![crate_type = "proc-macro"]
5
6extern crate proc_macro;
7
8use proc_macro::*;
9
10// This proc macro ignores its input and returns this token stream
11//
12// impl <«A1»: Comparable> Comparable for («A1»,) {}
13//
14// where `«`/`»` are invisible delimiters. This was being misparsed in bug
15// #128895.
16#[proc_macro]
17pub fn main(_input: TokenStream) -> TokenStream {
18 let a1 = TokenTree::Group(
19 Group::new(
20 Delimiter::None,
21 std::iter::once(TokenTree::Ident(Ident::new("A1", Span::call_site()))).collect(),
22 )
23 );
24 vec![
25 TokenTree::Ident(Ident::new("impl", Span::call_site())),
26 TokenTree::Punct(Punct::new('<', Spacing::Alone)),
27 a1.clone(),
28 TokenTree::Punct(Punct::new(':', Spacing::Alone)),
29 TokenTree::Ident(Ident::new("Comparable", Span::call_site())),
30 TokenTree::Punct(Punct::new('>', Spacing::Alone)),
31 TokenTree::Ident(Ident::new("Comparable", Span::call_site())),
32 TokenTree::Ident(Ident::new("for", Span::call_site())),
33 TokenTree::Group(
34 Group::new(
35 Delimiter::Parenthesis,
36 vec![
37 a1.clone(),
38 TokenTree::Punct(Punct::new(',', Spacing::Alone)),
39 ].into_iter().collect::<TokenStream>(),
40 )
41 ),
42 TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
43 ].into_iter().collect::<TokenStream>()
44}
tests/ui/proc-macro/parse-invis-delim-issue-128895.rs created+14
......@@ -0,0 +1,14 @@
1//@ aux-build:parse-invis-delim-issue-128895.rs
2//@ check-pass
3
4#![no_std] // Don't load unnecessary hygiene information from std
5extern crate std;
6
7#[macro_use]
8extern crate parse_invis_delim_issue_128895;
9
10trait Comparable {}
11
12parse_invis_delim_issue_128895::main!();
13
14fn main() {}