authorbors <bors@rust-lang.org> 2026-04-28 19:00:23 UTC
committerbors <bors@rust-lang.org> 2026-04-28 19:00:23 UTC
log37d85e592f9ae5f20f7d9a9f99785246fa7298da
treeca150ed2ae434943dfad44c19c85385a8578d98f
parent03c609abb6638f9d7f49f34326d4137d07f5cd61
parent4dd31caab6e9fc3b3e51245cab809428a9f3d7ca

Auto merge of #155941 - JonathanBrouwer:rollup-Ak66iXR, r=JonathanBrouwer

Rollup of 15 pull requests Successful merges: - rust-lang/rust#155923 (Subtree sync for rustc_codegen_cranelift) - rust-lang/rust#155930 (Sync from portable simd 2026 04 28) - rust-lang/rust#155850 (Only exclude the rust-lang/rust#155473 change for 1-byte bool-likes) - rust-lang/rust#151994 (switch to v0 mangling by default on stable) - rust-lang/rust#154325 (Tweak irrefutable let else warning output) - rust-lang/rust#155273 (Lock stable_crate_ids once in create_crate_num) - rust-lang/rust#155361 (Document that CFI diverges from Rust wrt. ABI-compatibility rules) - rust-lang/rust#155692 (disable naked-dead-code-elimination test if no RET mnemonic is available) - rust-lang/rust#155747 (Update documentation for `wasm32-wali-linux-musl` after integrating n…) - rust-lang/rust#155768 (compiletest: Overhaul the code for running an incremental test revision) - rust-lang/rust#155907 (Handle hkl const closures) - rust-lang/rust#155910 (misc stuff from reading borrowck again :)) - rust-lang/rust#155913 (Delete the 12 year old fixme) - rust-lang/rust#155920 (remove review queue triagebot mentions) - rust-lang/rust#155936 (Rename `SharedContext::emit_dyn_lint*` into `emit_lint*`)

85 files changed, 1181 insertions(+), 603 deletions(-)

compiler/rustc_abi/src/lib.rs+2-1
......@@ -2084,7 +2084,8 @@ impl Niche {
20842084 let distance_end_zero = max_value - v.end;
20852085 // FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation
20862086 // <https://github.com/rust-lang/rust/pull/155473#issuecomment-4302036343>
2087 if count == 1 && v != (WrappingRange { start: 0, end: 1 }) {
2087 let is_bool = size.bytes() == 1 && v == WrappingRange { start: 0, end: 1 };
2088 if count == 1 && !is_bool {
20882089 // We only need one, so just pick the one closest to zero.
20892090 // Not only does that obviously use zero if it's possible, but it also
20902091 // simplifies testing things like `Option<char>`, since looking for `-1`
compiler/rustc_attr_parsing/src/attributes/cfg.rs+2-2
......@@ -224,7 +224,7 @@ pub(crate) fn parse_name_value<S: Stage>(
224224
225225 match cx.sess.psess.check_config.expecteds.get(&name) {
226226 Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => cx
227 .emit_dyn_lint_with_sess(
227 .emit_lint_with_sess(
228228 UNEXPECTED_CFGS,
229229 move |dcx, level, sess| {
230230 check_cfg::unexpected_cfg_value(sess, (name, name_span), value)
......@@ -232,7 +232,7 @@ pub(crate) fn parse_name_value<S: Stage>(
232232 },
233233 span,
234234 ),
235 None if cx.sess.psess.check_config.exhaustive_names => cx.emit_dyn_lint_with_sess(
235 None if cx.sess.psess.check_config.exhaustive_names => cx.emit_lint_with_sess(
236236 UNEXPECTED_CFGS,
237237 move |dcx, level, sess| {
238238 check_cfg::unexpected_cfg_name(sess, (name, name_span), value).into_diag(dcx, level)
compiler/rustc_attr_parsing/src/attributes/crate_level.rs+1-1
......@@ -67,7 +67,7 @@ impl<S: Stage> CombineAttributeParser<S> for CrateTypeParser {
6767 None,
6868 );
6969 let span = n.value_span;
70 cx.emit_dyn_lint(
70 cx.emit_lint(
7171 UNKNOWN_CRATE_TYPES,
7272 move |dcx, level| {
7373 UnknownCrateTypes {
compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs+2-2
......@@ -24,7 +24,7 @@ impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser {
2424 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
2525 let attr_span = cx.attr_span;
2626 if !matches!(args, ArgParser::NoArgs) {
27 cx.emit_dyn_lint(
27 cx.emit_lint(
2828 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
2929 |dcx, level| crate::errors::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level),
3030 attr_span,
......@@ -33,7 +33,7 @@ impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser {
3333
3434 if !matches!(cx.target, Target::Impl { of_trait: true }) {
3535 let target_span = cx.target_span;
36 cx.emit_dyn_lint(
36 cx.emit_lint(
3737 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
3838 move |dcx, level| {
3939 IncorrectDoNotRecommendLocation { target_span }.into_diag(dcx, level)
compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs+8-8
......@@ -140,7 +140,7 @@ fn merge<T, S: Stage>(
140140 (Some(_) | None, None) => {}
141141 (Some((first_span, _)), Some((later_span, _))) => {
142142 let first_span = *first_span;
143 cx.emit_dyn_lint(
143 cx.emit_lint(
144144 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
145145 move |dcx, level| {
146146 IgnoredDiagnosticOption { first_span, later_span, option_name }
......@@ -167,14 +167,14 @@ fn parse_list<'p, S: Stage>(
167167 // We're dealing with `#[diagnostic::attr()]`.
168168 // This can be because that is what the user typed, but that's also what we'd see
169169 // if the user used non-metaitem syntax. See `ArgParser::from_attr_args`.
170 cx.emit_dyn_lint(
170 cx.emit_lint(
171171 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
172172 move |dcx, level| NonMetaItemDiagnosticAttribute.into_diag(dcx, level),
173173 list.span,
174174 );
175175 }
176176 ArgParser::NoArgs => {
177 cx.emit_dyn_lint(
177 cx.emit_lint(
178178 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
179179 move |dcx, level| {
180180 MissingOptionsForDiagnosticAttribute {
......@@ -187,7 +187,7 @@ fn parse_list<'p, S: Stage>(
187187 );
188188 }
189189 ArgParser::NameValue(_) => {
190 cx.emit_dyn_lint(
190 cx.emit_lint(
191191 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
192192 move |dcx, level| {
193193 MalFormedDiagnosticAttributeLint {
......@@ -221,7 +221,7 @@ fn parse_directive_items<'p, S: Stage>(
221221 let span = item.span();
222222
223223 macro malformed() {{
224 cx.emit_dyn_lint(
224 cx.emit_lint(
225225 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
226226 move |dcx, level| {
227227 MalFormedDiagnosticAttributeLint {
......@@ -249,7 +249,7 @@ fn parse_directive_items<'p, S: Stage>(
249249
250250 macro duplicate($name: ident, $($first_span:tt)*) {{
251251 let first_span = $($first_span)*;
252 cx.emit_dyn_lint(
252 cx.emit_lint(
253253 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
254254 move |dcx, level| IgnoredDiagnosticOption {
255255 first_span,
......@@ -285,7 +285,7 @@ fn parse_directive_items<'p, S: Stage>(
285285 | FormatWarning::PositionalArgument { span }
286286 | FormatWarning::IndexedArgument { span }
287287 | FormatWarning::DisallowedPlaceholder { span, .. }) = warning;
288 cx.emit_dyn_lint(
288 cx.emit_lint(
289289 MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
290290 move |dcx, level| warning.into_diag(dcx, level),
291291 span,
......@@ -295,7 +295,7 @@ fn parse_directive_items<'p, S: Stage>(
295295 f
296296 }
297297 Err(e) => {
298 cx.emit_dyn_lint(
298 cx.emit_lint(
299299 MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
300300 move |dcx, level| {
301301 WrappedParserError {
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs+1-1
......@@ -28,7 +28,7 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
2828 // so non-constness is still checked in check_attr.rs
2929 if !matches!(cx.target, Target::Impl { of_trait: true }) {
3030 let target_span = cx.target_span;
31 cx.emit_dyn_lint(
31 cx.emit_lint(
3232 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
3333 move |dcx, level| {
3434 DiagnosticOnConstOnlyForTraitImpls { target_span }.into_diag(dcx, level)
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs+1-1
......@@ -33,7 +33,7 @@ impl OnMoveParser {
3333 self.span = Some(span);
3434
3535 if !matches!(cx.target, Target::Enum | Target::Struct | Target::Union) {
36 cx.emit_dyn_lint(
36 cx.emit_lint(
3737 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
3838 move |dcx, level| DiagnosticOnMoveOnlyForAdt.into_diag(dcx, level),
3939 span,
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs+1-1
......@@ -23,7 +23,7 @@ impl OnUnimplementedParser {
2323 self.span = Some(span);
2424
2525 if !matches!(cx.target, Target::Trait) {
26 cx.emit_dyn_lint(
26 cx.emit_lint(
2727 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
2828 move |dcx, level| DiagnosticOnUnimplementedOnlyForTraits.into_diag(dcx, level),
2929 span,
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs+1-1
......@@ -35,7 +35,7 @@ impl OnUnknownParser {
3535
3636 if !early && !matches!(cx.target, Target::Use) {
3737 let target_span = cx.target_span;
38 cx.emit_dyn_lint(
38 cx.emit_lint(
3939 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
4040 move |dcx, level| {
4141 DiagnosticOnUnknownOnlyForImports { target_span }.into_diag(dcx, level)
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unmatch_args.rs+1-1
......@@ -25,7 +25,7 @@ impl<S: Stage> AttributeParser<S> for OnUnmatchArgsParser {
2525 this.span = Some(span);
2626
2727 if !matches!(cx.target, Target::MacroDef) {
28 cx.emit_dyn_lint(
28 cx.emit_lint(
2929 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
3030 move |dcx, level| DiagnosticOnUnmatchArgsOnlyForMacros.into_diag(dcx, level),
3131 span,
compiler/rustc_attr_parsing/src/attributes/doc.rs+25-25
......@@ -68,7 +68,7 @@ fn check_attr_not_crate_level<S: Stage>(
6868/// Checks that an attribute is used at the crate level. Returns `true` if valid.
6969fn check_attr_crate_level<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) -> bool {
7070 if cx.shared.target != Target::Crate {
71 cx.emit_dyn_lint(
71 cx.emit_lint(
7272 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
7373 |dcx, level| AttrCrateLevelOnly.into_diag(dcx, level),
7474 span,
......@@ -84,7 +84,7 @@ fn expected_name_value<S: Stage>(
8484 span: Span,
8585 _name: Option<Symbol>,
8686) {
87 cx.emit_dyn_lint(
87 cx.emit_lint(
8888 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
8989 |dcx, level| ExpectedNameValue.into_diag(dcx, level),
9090 span,
......@@ -93,7 +93,7 @@ fn expected_name_value<S: Stage>(
9393
9494// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
9595fn expected_no_args<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) {
96 cx.emit_dyn_lint(
96 cx.emit_lint(
9797 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
9898 |dcx, level| ExpectedNoArgs.into_diag(dcx, level),
9999 span,
......@@ -107,7 +107,7 @@ fn expected_string_literal<S: Stage>(
107107 span: Span,
108108 _actual_literal: Option<&MetaItemLit>,
109109) {
110 cx.emit_dyn_lint(
110 cx.emit_lint(
111111 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
112112 |dcx, level| MalformedDoc.into_diag(dcx, level),
113113 span,
......@@ -177,7 +177,7 @@ impl DocParser {
177177
178178 if let Some(used_span) = self.attribute.no_crate_inject {
179179 let unused_span = path.span();
180 cx.emit_dyn_lint(
180 cx.emit_lint(
181181 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
182182 move |dcx, level| {
183183 rustc_errors::lints::UnusedDuplicate {
......@@ -203,7 +203,7 @@ impl DocParser {
203203 // FIXME: remove this method once merged and uncomment the line below instead.
204204 // cx.expected_list(cx.attr_span, args);
205205 let span = cx.attr_span;
206 cx.emit_dyn_lint(
206 cx.emit_lint(
207207 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
208208 |dcx, level| MalformedDoc.into_diag(dcx, level),
209209 span,
......@@ -217,14 +217,14 @@ impl DocParser {
217217 }
218218 }
219219 Some(name) => {
220 cx.emit_dyn_lint(
220 cx.emit_lint(
221221 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
222222 move |dcx, level| DocTestUnknown { name }.into_diag(dcx, level),
223223 path.span(),
224224 );
225225 }
226226 None => {
227 cx.emit_dyn_lint(
227 cx.emit_lint(
228228 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
229229 |dcx, level| DocTestLiteral.into_diag(dcx, level),
230230 path.span(),
......@@ -261,7 +261,7 @@ impl DocParser {
261261 }
262262
263263 if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() {
264 cx.emit_dyn_lint(
264 cx.emit_lint(
265265 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
266266 move |dcx, level| DocAliasDuplicated { first_definition }.into_diag(dcx, level),
267267 span,
......@@ -349,7 +349,7 @@ impl DocParser {
349349 ArgParser::List(list) => {
350350 for meta in list.mixed() {
351351 let MetaItemOrLitParser::MetaItemParser(item) = meta else {
352 cx.emit_dyn_lint(
352 cx.emit_lint(
353353 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
354354 |dcx, level| DocAutoCfgExpectsHideOrShow.into_diag(dcx, level),
355355 meta.span(),
......@@ -360,7 +360,7 @@ impl DocParser {
360360 Some(sym::hide) => (HideOrShow::Hide, sym::hide),
361361 Some(sym::show) => (HideOrShow::Show, sym::show),
362362 _ => {
363 cx.emit_dyn_lint(
363 cx.emit_lint(
364364 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
365365 |dcx, level| DocAutoCfgExpectsHideOrShow.into_diag(dcx, level),
366366 item.span(),
......@@ -369,7 +369,7 @@ impl DocParser {
369369 }
370370 };
371371 let ArgParser::List(list) = item.args() else {
372 cx.emit_dyn_lint(
372 cx.emit_lint(
373373 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
374374 move |dcx, level| {
375375 DocAutoCfgHideShowExpectsList { attr_name }.into_diag(dcx, level)
......@@ -383,7 +383,7 @@ impl DocParser {
383383
384384 for item in list.mixed() {
385385 let MetaItemOrLitParser::MetaItemParser(sub_item) = item else {
386 cx.emit_dyn_lint(
386 cx.emit_lint(
387387 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
388388 move |dcx, level| {
389389 DocAutoCfgHideShowUnexpectedItem { attr_name }
......@@ -399,7 +399,7 @@ impl DocParser {
399399 // FIXME: remove this method once merged and uncomment the line
400400 // below instead.
401401 // cx.expected_identifier(sub_item.path().span());
402 cx.emit_dyn_lint(
402 cx.emit_lint(
403403 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
404404 |dcx, level| MalformedDoc.into_diag(dcx, level),
405405 sub_item.path().span(),
......@@ -426,7 +426,7 @@ impl DocParser {
426426 }
427427 }
428428 _ => {
429 cx.emit_dyn_lint(
429 cx.emit_lint(
430430 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
431431 move |dcx, level| {
432432 DocAutoCfgHideShowUnexpectedItem { attr_name }
......@@ -444,7 +444,7 @@ impl DocParser {
444444 ArgParser::NameValue(nv) => {
445445 let MetaItemLit { kind: LitKind::Bool(bool_value), span, .. } = nv.value_as_lit()
446446 else {
447 cx.emit_dyn_lint(
447 cx.emit_lint(
448448 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
449449 move |dcx, level| DocAutoCfgWrongLiteral.into_diag(dcx, level),
450450 nv.value_span,
......@@ -588,7 +588,7 @@ impl DocParser {
588588 Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args),
589589 Some(sym::test) => {
590590 let Some(list) = args.as_list() else {
591 cx.emit_dyn_lint(
591 cx.emit_lint(
592592 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
593593 |dcx, level| DocTestTakesList.into_diag(dcx, level),
594594 args.span().unwrap_or(path.span()),
......@@ -605,7 +605,7 @@ impl DocParser {
605605 // FIXME: remove this method once merged and uncomment the line
606606 // below instead.
607607 // cx.unexpected_literal(lit.span);
608 cx.emit_dyn_lint(
608 cx.emit_lint(
609609 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
610610 |dcx, level| MalformedDoc.into_diag(dcx, level),
611611 lit.span,
......@@ -616,7 +616,7 @@ impl DocParser {
616616 }
617617 Some(sym::spotlight) => {
618618 let span = path.span();
619 cx.emit_dyn_lint(
619 cx.emit_lint(
620620 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
621621 move |dcx, level| DocUnknownSpotlight { sugg_span: span }.into_diag(dcx, level),
622622 span,
......@@ -629,7 +629,7 @@ impl DocParser {
629629 };
630630 let value = nv.value_as_lit().symbol;
631631 let span = path.span();
632 cx.emit_dyn_lint(
632 cx.emit_lint(
633633 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
634634 move |dcx, level| {
635635 DocUnknownInclude {
......@@ -644,7 +644,7 @@ impl DocParser {
644644 }
645645 Some(name @ (sym::passes | sym::no_default_passes)) => {
646646 let span = path.span();
647 cx.emit_dyn_lint(
647 cx.emit_lint(
648648 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
649649 move |dcx, level| {
650650 DocUnknownPasses { name, note_span: span }.into_diag(dcx, level)
......@@ -654,14 +654,14 @@ impl DocParser {
654654 }
655655 Some(sym::plugins) => {
656656 let span = path.span();
657 cx.emit_dyn_lint(
657 cx.emit_lint(
658658 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
659659 move |dcx, level| DocUnknownPlugins { label_span: span }.into_diag(dcx, level),
660660 span,
661661 );
662662 }
663663 Some(name) => {
664 cx.emit_dyn_lint(
664 cx.emit_lint(
665665 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
666666 move |dcx, level| DocUnknownAny { name }.into_diag(dcx, level),
667667 path.span(),
......@@ -671,7 +671,7 @@ impl DocParser {
671671 let full_name =
672672 path.segments().map(|s| s.as_str()).intersperse("::").collect::<String>();
673673 let name = Symbol::intern(&full_name);
674 cx.emit_dyn_lint(
674 cx.emit_lint(
675675 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
676676 move |dcx, level| DocUnknownAny { name }.into_diag(dcx, level),
677677 path.span(),
......@@ -689,7 +689,7 @@ impl DocParser {
689689 ArgParser::NoArgs => {
690690 let suggestions = cx.adcx().suggestions();
691691 let span = cx.attr_span;
692 cx.emit_dyn_lint(
692 cx.emit_lint(
693693 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
694694 move |dcx, level| {
695695 IllFormedAttributeInput::new(&suggestions, None, None).into_diag(dcx, level)
compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs+1-1
......@@ -122,7 +122,7 @@ fn parse_derive_like<S: Stage>(
122122 return None;
123123 }
124124 if rustc_feature::is_builtin_attr_name(ident.name) {
125 cx.emit_dyn_lint(
125 cx.emit_lint(
126126 AMBIGUOUS_DERIVE_HELPERS,
127127 |dcx, level| crate::errors::AmbiguousDeriveHelpers.into_diag(dcx, level),
128128 ident.span,
compiler/rustc_attr_parsing/src/context.rs+6-6
......@@ -462,7 +462,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
462462 /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
463463 /// must be delayed until after HIR is built. This method will take care of the details of
464464 /// that.
465 pub(crate) fn emit_dyn_lint<
465 pub(crate) fn emit_lint<
466466 F: for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static,
467467 >(
468468 &mut self,
......@@ -477,7 +477,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
477477 );
478478 }
479479
480 pub(crate) fn emit_dyn_lint_with_sess<
480 pub(crate) fn emit_lint_with_sess<
481481 F: for<'a> Fn(DiagCtxtHandle<'a>, Level, &Session) -> Diag<'a, ()>
482482 + DynSend
483483 + DynSync
......@@ -507,7 +507,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
507507 }
508508
509509 pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
510 self.emit_dyn_lint(
510 self.emit_lint(
511511 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
512512 move |dcx, level| {
513513 rustc_errors::lints::UnusedDuplicate {
......@@ -526,7 +526,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
526526 used_span: Span,
527527 unused_span: Span,
528528 ) {
529 self.emit_dyn_lint(
529 self.emit_lint(
530530 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
531531 move |dcx, level| {
532532 rustc_errors::lints::UnusedDuplicate {
......@@ -951,7 +951,7 @@ where
951951 pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
952952 let attr_path = self.attr_path.to_string();
953953 let valid_without_list = self.template.word;
954 self.emit_dyn_lint(
954 self.emit_lint(
955955 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
956956 move |dcx, level| {
957957 crate::errors::EmptyAttributeList {
......@@ -975,7 +975,7 @@ where
975975 ) {
976976 let suggestions = self.suggestions();
977977 let span = self.attr_span;
978 self.emit_dyn_lint(
978 self.emit_lint(
979979 lint,
980980 move |dcx, level| {
981981 crate::errors::IllFormedAttributeInput::new(&suggestions, None, help.as_deref())
compiler/rustc_attr_parsing/src/target_checking.rs+2-2
......@@ -142,7 +142,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
142142 };
143143
144144 let attr_span = cx.attr_span;
145 cx.emit_dyn_lint(
145 cx.emit_lint(
146146 lint,
147147 move |dcx, level| {
148148 InvalidTargetLint {
......@@ -186,7 +186,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
186186 let target_span = cx.target_span;
187187 let attr_span = cx.attr_span;
188188
189 cx.emit_dyn_lint(
189 cx.emit_lint(
190190 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
191191 move |dcx, level| {
192192 crate::errors::InvalidAttrStyle {
compiler/rustc_borrowck/src/handle_placeholders.rs+8-10
......@@ -35,18 +35,18 @@ pub(crate) struct LoweredConstraints<'tcx> {
3535 pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
3636}
3737
38impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
39 pub(crate) fn init(definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>) -> Self {
40 Self { scc_to_annotation: IndexVec::new(), definitions }
41 }
42}
43
4438/// A Visitor for SCC annotation construction.
4539pub(crate) struct SccAnnotations<'d, 'tcx, A: scc::Annotation> {
4640 pub(crate) scc_to_annotation: IndexVec<ConstraintSccIndex, A>,
4741 definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>,
4842}
4943
44impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
45 pub(crate) fn init(definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>) -> Self {
46 Self { scc_to_annotation: IndexVec::new(), definitions }
47 }
48}
49
5050impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> {
5151 fn new(&self, element: RegionVid) -> RegionTracker {
5252 RegionTracker::new(element, &self.definitions[element])
......@@ -118,7 +118,7 @@ impl RegionTracker {
118118 }
119119
120120 /// The largest universe this SCC can name. It's the smallest
121 /// largest nameable universe of any reachable region, or
121 /// max-nameable-universe of any reachable region, or
122122 /// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)`
123123 pub(crate) fn max_nameable_universe(self) -> UniverseIndex {
124124 self.max_nameable_universe.0
......@@ -208,7 +208,7 @@ pub(super) fn region_definitions<'tcx>(
208208/// graph such that there is a series of constraints
209209/// A: B: C: ... : X where
210210/// A contains a placeholder whose universe cannot be named by X,
211/// add a constraint that A: 'static. This is a safe upper bound
211/// add a constraint that X: 'static. This is a safe upper bound
212212/// in the face of borrow checker/trait solver limitations that will
213213/// eventually go away.
214214///
......@@ -327,8 +327,6 @@ pub(crate) fn rewrite_placeholder_outlives<'tcx>(
327327
328328 for scc in sccs.all_sccs() {
329329 // No point in adding 'static: 'static!
330 // This micro-optimisation makes somewhat sense
331 // because static outlives *everything*.
332330 if scc == sccs.scc(fr_static) {
333331 continue;
334332 }
compiler/rustc_borrowck/src/region_infer/mod.rs+18-13
......@@ -501,43 +501,48 @@ impl<'tcx> RegionInferenceContext<'tcx> {
501501
502502 let mut errors_buffer = RegionErrors::new(infcx.tcx);
503503
504 // If this is a closure, we can propagate unsatisfied
505 // `outlives_requirements` to our creator, so create a vector
506 // to store those. Otherwise, we'll pass in `None` to the
507 // functions below, which will trigger them to report errors
508 // eagerly.
509 let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
504 // If this is a nested body, we propagate unsatisfied
505 // outlives constraints to the parent body instead of
506 // eagerly erroing.
507 let mut propagated_outlives_requirements =
508 infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
510509
511 self.check_type_tests(infcx, outlives_requirements.as_mut(), &mut errors_buffer);
510 self.check_type_tests(infcx, propagated_outlives_requirements.as_mut(), &mut errors_buffer);
512511
513512 debug!(?errors_buffer);
514 debug!(?outlives_requirements);
513 debug!(?propagated_outlives_requirements);
515514
516515 // In Polonius mode, the errors about missing universal region relations are in the output
517516 // and need to be emitted or propagated. Otherwise, we need to check whether the
518517 // constraints were too strong, and if so, emit or propagate those errors.
519518 if infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
520519 self.check_polonius_subset_errors(
521 outlives_requirements.as_mut(),
520 propagated_outlives_requirements.as_mut(),
522521 &mut errors_buffer,
523522 polonius_output
524523 .as_ref()
525524 .expect("Polonius output is unavailable despite `-Z polonius`"),
526525 );
527526 } else {
528 self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
527 self.check_universal_regions(
528 propagated_outlives_requirements.as_mut(),
529 &mut errors_buffer,
530 );
529531 }
530532
531533 debug!(?errors_buffer);
532534
533 let outlives_requirements = outlives_requirements.unwrap_or_default();
535 let propagated_outlives_requirements = propagated_outlives_requirements.unwrap_or_default();
534536
535 if outlives_requirements.is_empty() {
537 if propagated_outlives_requirements.is_empty() {
536538 (None, errors_buffer)
537539 } else {
538540 let num_external_vids = self.universal_regions().num_global_and_external_regions();
539541 (
540 Some(ClosureRegionRequirements { num_external_vids, outlives_requirements }),
542 Some(ClosureRegionRequirements {
543 num_external_vids,
544 outlives_requirements: propagated_outlives_requirements,
545 }),
541546 errors_buffer,
542547 )
543548 }
compiler/rustc_codegen_cranelift/.github/workflows/main.yml+2-1
......@@ -242,7 +242,8 @@ jobs:
242242 runs-on: ubuntu-latest
243243 timeout-minutes: 10
244244 if: ${{ github.ref == 'refs/heads/main' }}
245 needs: [todo_check, rustfmt, test, bench, dist]
245 # FIXME add bench back once rust-lang/cargo#16925 has been fixed
246 needs: [todo_check, rustfmt, test, dist]
246247
247248 permissions:
248249 contents: write # for creating the dev tag and release
compiler/rustc_codegen_cranelift/Cargo.lock+51-42
......@@ -43,27 +43,27 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
4343
4444[[package]]
4545name = "cranelift-assembler-x64"
46version = "0.130.0"
46version = "0.131.0"
4747source = "registry+https://github.com/rust-lang/crates.io-index"
48checksum = "4f248321c6a7d4de5dcf2939368e96a397ad3f53b6a076e38d0104d1da326d37"
48checksum = "6edb5bdd1af46714e3224a017fabbbd57f70df4e840eb5ad6a7429dc456119d6"
4949dependencies = [
5050 "cranelift-assembler-x64-meta",
5151]
5252
5353[[package]]
5454name = "cranelift-assembler-x64-meta"
55version = "0.130.0"
55version = "0.131.0"
5656source = "registry+https://github.com/rust-lang/crates.io-index"
57checksum = "ab6d78ff1f7d9bf8b7e1afbedbf78ba49e38e9da479d4c8a2db094e22f64e2bc"
57checksum = "a819599186e1b1a1f88d464e06045696afc7aa3e0cc018aa0b2999cb63d1d088"
5858dependencies = [
5959 "cranelift-srcgen",
6060]
6161
6262[[package]]
6363name = "cranelift-bforest"
64version = "0.130.0"
64version = "0.131.0"
6565source = "registry+https://github.com/rust-lang/crates.io-index"
66checksum = "6b6005ba640213a5b95382aeaf6b82bf028309581c8d7349778d66f27dc1180b"
66checksum = "36e2c152d488e03c87b913bc2ed3414416eb1e0d66d61b49af60bf456a9665c7"
6767dependencies = [
6868 "cranelift-entity",
6969 "wasmtime-internal-core",
......@@ -71,18 +71,18 @@ dependencies = [
7171
7272[[package]]
7373name = "cranelift-bitset"
74version = "0.130.0"
74version = "0.131.0"
7575source = "registry+https://github.com/rust-lang/crates.io-index"
76checksum = "81fb5b134a12b559ff0c0f5af0fcd755ad380723b5016c4e0d36f74d39485340"
76checksum = "b6559d4fbc253d1396e1f6beeae57fa88a244f02aaf0cde2a735afd3492d9b2e"
7777dependencies = [
7878 "wasmtime-internal-core",
7979]
8080
8181[[package]]
8282name = "cranelift-codegen"
83version = "0.130.0"
83version = "0.131.0"
8484source = "registry+https://github.com/rust-lang/crates.io-index"
85checksum = "85837de8be7f17a4034a6b08816f05a3144345d2091937b39d415990daca28f4"
85checksum = "96d9315d98d6e0a64454d4c83be2ee0e8055c3f80c3b2d7bcad7079f281a06ff"
8686dependencies = [
8787 "bumpalo",
8888 "cranelift-assembler-x64",
......@@ -107,9 +107,9 @@ dependencies = [
107107
108108[[package]]
109109name = "cranelift-codegen-meta"
110version = "0.130.0"
110version = "0.131.0"
111111source = "registry+https://github.com/rust-lang/crates.io-index"
112checksum = "e433faa87d38e5b8ff469e44a26fea4f93e58abd7a7c10bad9810056139700c9"
112checksum = "d89c00a88081c55e3087c45bebc77e0cc973de2d7b44ef6a943c7122647b89f5"
113113dependencies = [
114114 "cranelift-assembler-x64-meta",
115115 "cranelift-codegen-shared",
......@@ -119,24 +119,24 @@ dependencies = [
119119
120120[[package]]
121121name = "cranelift-codegen-shared"
122version = "0.130.0"
122version = "0.131.0"
123123source = "registry+https://github.com/rust-lang/crates.io-index"
124checksum = "5397ba61976e13944ca71230775db13ee1cb62849701ed35b753f4761ed0a9b7"
124checksum = "879f77c497a1eb6273482aa1ac3b23cb8563ff04edb39ed5dfcfd28c8deff8f5"
125125
126126[[package]]
127127name = "cranelift-control"
128version = "0.130.0"
128version = "0.131.0"
129129source = "registry+https://github.com/rust-lang/crates.io-index"
130checksum = "cc81c88765580720eb30f4fc2c1bfdb75fcbf3094f87b3cd69cecca79d77a245"
130checksum = "498dc1f17a6910c88316d49c7176d8fa97cf10c30859c32a266040449317f963"
131131dependencies = [
132132 "arbitrary",
133133]
134134
135135[[package]]
136136name = "cranelift-entity"
137version = "0.130.0"
137version = "0.131.0"
138138source = "registry+https://github.com/rust-lang/crates.io-index"
139checksum = "463feed5d46cf8763f3ba3045284cf706dd161496e20ec9c14afbb4ba09b9e66"
139checksum = "c2acba797f6a46042ce82aaf7680d0c3567fe2001e238db9df649fd104a2727f"
140140dependencies = [
141141 "cranelift-bitset",
142142 "wasmtime-internal-core",
......@@ -144,9 +144,9 @@ dependencies = [
144144
145145[[package]]
146146name = "cranelift-frontend"
147version = "0.130.0"
147version = "0.131.0"
148148source = "registry+https://github.com/rust-lang/crates.io-index"
149checksum = "a4c5eca7696c1c04ab4c7ed8d18eadbb47d6cc9f14ec86fe0881bf1d7e97e261"
149checksum = "4dca3df1d107d98d88f159ad1d5eaa2d5cdb678b3d5bcfadc6fc83d8ebb448ea"
150150dependencies = [
151151 "cranelift-codegen",
152152 "log",
......@@ -156,15 +156,15 @@ dependencies = [
156156
157157[[package]]
158158name = "cranelift-isle"
159version = "0.130.0"
159version = "0.131.0"
160160source = "registry+https://github.com/rust-lang/crates.io-index"
161checksum = "f1153844610cc9c6da8cf10ce205e45da1a585b7688ed558aa808bbe2e4e6d77"
161checksum = "f62dd18116d88bed649871feceda79dad7b59cc685ea8998c2b3e64d0e689602"
162162
163163[[package]]
164164name = "cranelift-jit"
165version = "0.130.0"
165version = "0.131.0"
166166source = "registry+https://github.com/rust-lang/crates.io-index"
167checksum = "41836de8321b303d3d4188e58cc09c30c7645337342acfcfb363732695cae098"
167checksum = "0a4942770ce6662b44d903493d7c5b00f9a986a713a61aae148306eaef21ebd4"
168168dependencies = [
169169 "anyhow",
170170 "cranelift-codegen",
......@@ -182,9 +182,9 @@ dependencies = [
182182
183183[[package]]
184184name = "cranelift-module"
185version = "0.130.0"
185version = "0.131.0"
186186source = "registry+https://github.com/rust-lang/crates.io-index"
187checksum = "b731f66cb1b69b60a74216e632968ebdbb95c488d26aa1448ec226ae0ffec33e"
187checksum = "fb5ca0d214ecee44405ea9f0c65a5318b41ac469e8258fd9fe944e564c1c1b0b"
188188dependencies = [
189189 "anyhow",
190190 "cranelift-codegen",
......@@ -193,9 +193,9 @@ dependencies = [
193193
194194[[package]]
195195name = "cranelift-native"
196version = "0.130.0"
196version = "0.131.0"
197197source = "registry+https://github.com/rust-lang/crates.io-index"
198checksum = "a97b583fe9a60f06b0464cee6be5a17f623fd91b217aaac99b51b339d19911af"
198checksum = "f843b80360d7fdf61a6124642af7597f6d55724cf521210c34af8a1c66daca6e"
199199dependencies = [
200200 "cranelift-codegen",
201201 "libc",
......@@ -204,9 +204,9 @@ dependencies = [
204204
205205[[package]]
206206name = "cranelift-object"
207version = "0.130.0"
207version = "0.131.0"
208208source = "registry+https://github.com/rust-lang/crates.io-index"
209checksum = "9809d2d419cd18f17377f4ce64a7ad22eeda0d042c08833d3796657f1ddebc82"
209checksum = "b9d212d15015c374333b11b833111b7c7e686bfaec02385af53611050bce7e9d"
210210dependencies = [
211211 "anyhow",
212212 "cranelift-codegen",
......@@ -219,9 +219,9 @@ dependencies = [
219219
220220[[package]]
221221name = "cranelift-srcgen"
222version = "0.130.0"
222version = "0.131.0"
223223source = "registry+https://github.com/rust-lang/crates.io-index"
224checksum = "8594dc6bb4860fa8292f1814c76459dbfb933e1978d8222de6380efce45c7cee"
224checksum = "090ee5de58c6f17eb5e3a5ae8cf1695c7efea04ec4dd0ecba6a5b996c9bad7dc"
225225
226226[[package]]
227227name = "crc32fast"
......@@ -277,6 +277,15 @@ dependencies = [
277277 "foldhash",
278278]
279279
280[[package]]
281name = "hashbrown"
282version = "0.17.0"
283source = "registry+https://github.com/rust-lang/crates.io-index"
284checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
285dependencies = [
286 "foldhash",
287]
288
280289[[package]]
281290name = "heck"
282291version = "0.5.0"
......@@ -285,12 +294,12 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
285294
286295[[package]]
287296name = "indexmap"
288version = "2.13.0"
297version = "2.14.0"
289298source = "registry+https://github.com/rust-lang/crates.io-index"
290checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
299checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
291300dependencies = [
292301 "equivalent",
293 "hashbrown 0.16.1",
302 "hashbrown 0.17.0",
294303]
295304
296305[[package]]
......@@ -338,12 +347,12 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
338347
339348[[package]]
340349name = "object"
341version = "0.38.1"
350version = "0.39.1"
342351source = "registry+https://github.com/rust-lang/crates.io-index"
343checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc"
352checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b"
344353dependencies = [
345354 "crc32fast",
346 "hashbrown 0.16.1",
355 "hashbrown 0.17.0",
347356 "indexmap",
348357 "memchr",
349358]
......@@ -482,9 +491,9 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
482491
483492[[package]]
484493name = "wasmtime-internal-core"
485version = "43.0.0"
494version = "44.0.0"
486495source = "registry+https://github.com/rust-lang/crates.io-index"
487checksum = "e671917bb6856ae360cb59d7aaf26f1cfd042c7b924319dd06fd380739fc0b2e"
496checksum = "816a61a75275c6be435131fc625a4f5956daf24d9f9f59443e81cbef228929b3"
488497dependencies = [
489498 "hashbrown 0.16.1",
490499 "libm",
......@@ -492,9 +501,9 @@ dependencies = [
492501
493502[[package]]
494503name = "wasmtime-internal-jit-icache-coherence"
495version = "43.0.0"
504version = "44.0.0"
496505source = "registry+https://github.com/rust-lang/crates.io-index"
497checksum = "9b3112806515fac8495883885eb8dbdde849988ae91fe6beb544c0d7c0f4c9aa"
506checksum = "2fd683a94490bf755d016a09697b0955602c50106b1ded97d16983ab2ded9fed"
498507dependencies = [
499508 "cfg-if",
500509 "libc",
compiler/rustc_codegen_cranelift/Cargo.toml+13-13
......@@ -8,15 +8,15 @@ crate-type = ["dylib"]
88
99[dependencies]
1010# These have to be in sync with each other
11cranelift-codegen = { version = "0.130.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
12cranelift-frontend = { version = "0.130.0" }
13cranelift-module = { version = "0.130.0" }
14cranelift-native = { version = "0.130.0" }
15cranelift-jit = { version = "0.130.0", optional = true }
16cranelift-object = { version = "0.130.0" }
11cranelift-codegen = { version = "0.131.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
12cranelift-frontend = { version = "0.131.0" }
13cranelift-module = { version = "0.131.0" }
14cranelift-native = { version = "0.131.0" }
15cranelift-jit = { version = "0.131.0", optional = true }
16cranelift-object = { version = "0.131.0" }
1717target-lexicon = "0.13"
1818gimli = { version = "0.33", default-features = false, features = ["write"] }
19object = { version = "0.38.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
19object = { version = "0.39.1", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
2020
2121indexmap = "2.0.0"
2222libloading = { version = "0.9.0", optional = true }
......@@ -24,12 +24,12 @@ smallvec = "1.8.1"
2424
2525[patch.crates-io]
2626# Uncomment to use an unreleased version of cranelift
27#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" }
28#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" }
29#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" }
30#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" }
31#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" }
32#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-43.0.0" }
27#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-44.0.0" }
28#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-44.0.0" }
29#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-44.0.0" }
30#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-44.0.0" }
31#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-44.0.0" }
32#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-44.0.0" }
3333
3434# Uncomment to use local checkout of cranelift
3535#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs+12-7
......@@ -178,9 +178,7 @@ fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget {
178178 && !file_name_str.contains("rustc_std_workspace_")
179179 && !file_name_str.contains("rustc_demangle")
180180 && !file_name_str.contains("rustc_literal_escaper"))
181 || file_name_str.contains("chalk")
182 || file_name_str.contains("tracing")
183 || file_name_str.contains("regex")
181 || file_name_str.contains("LLVM")
184182 {
185183 // These are large crates that are part of the rustc-dev component and are not
186184 // necessary to run regular programs.
......@@ -208,9 +206,9 @@ fn build_clif_sysroot_for_triple(
208206
209207 apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs));
210208
211 // Cleanup the deps dir, but keep build scripts and the incremental cache for faster
212 // recompilation as they are not affected by changes in cg_clif.
213 ensure_empty_dir(&build_dir.join("deps"));
209 // Cleanup the build dir, but keep the incremental cache for faster
210 // recompilation as it is not affected by changes in cg_clif.
211 ensure_empty_dir(&build_dir.join("build"));
214212 }
215213
216214 // Build sysroot
......@@ -243,6 +241,7 @@ fn build_clif_sysroot_for_triple(
243241 build_cmd.arg("--features").arg("backtrace panic-unwind");
244242 build_cmd.arg(format!("-Zroot-dir={}", STDLIB_SRC.to_path(dirs).display()));
245243 build_cmd.arg("-Zno-embed-metadata");
244 build_cmd.arg("-Zbuild-dir-new-layout");
246245 build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true");
247246 build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
248247 if compiler.triple.contains("apple") {
......@@ -254,7 +253,13 @@ fn build_clif_sysroot_for_triple(
254253 }
255254 spawn_and_wait(build_cmd);
256255
257 for entry in fs::read_dir(build_dir.join("deps")).unwrap() {
256 for entry in fs::read_dir(build_dir.join("build"))
257 .unwrap()
258 .flat_map(|entry| entry.unwrap().path().read_dir().unwrap())
259 .map(|entry| entry.unwrap().path().join("out"))
260 .filter(|entry| entry.exists())
261 .flat_map(|entry| entry.read_dir().unwrap())
262 {
258263 let entry = entry.unwrap();
259264 if let Some(ext) = entry.path().extension() {
260265 if ext == "d" || ext == "dSYM" || ext == "clif" {
compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Disable-f16-usage-in-portable-simd.patch created+266
......@@ -0,0 +1,266 @@
1From 2aa88b261ffb51d3f18a4b9d3b79232d7445e5f3 Mon Sep 17 00:00:00 2001
2From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
3Date: Thu, 16 Apr 2026 17:29:02 +0200
4Subject: [PATCH] Disable f16 usage in portable-simd
5
6It is currently broken on x86_64-pc-windows-gnu
7---
8 Cargo.toml | 8 ++------
9 crates/core_simd/src/alias.rs | 10 ----------
10 crates/core_simd/src/cast.rs | 3 ---
11 crates/core_simd/src/lib.rs | 1 -
12 crates/core_simd/src/ops.rs | 2 +-
13 crates/core_simd/src/ops/unary.rs | 2 --
14 crates/core_simd/src/simd/cmp/eq.rs | 2 +-
15 crates/core_simd/src/simd/cmp/ord.rs | 2 +-
16 crates/core_simd/src/simd/num/float.rs | 2 +-
17 crates/core_simd/src/vector.rs | 7 -------
18 crates/core_simd/tests/f16_ops.rs | 10 ----------
19 crates/std_float/src/lib.rs | 9 ---------
20 crates/test_helpers/src/biteq.rs | 2 +-
21 crates/test_helpers/src/lib.rs | 2 --
22 crates/test_helpers/src/subnormals.rs | 2 +-
23 15 files changed, 8 insertions(+), 56 deletions(-)
24 delete mode 100644 crates/core_simd/tests/f16_ops.rs
25
26diff --git a/Cargo.toml b/Cargo.toml
27index 883140b..45296b4 100644
28--- a/Cargo.toml
29+++ b/Cargo.toml
30@@ -1,10 +1,6 @@
31 [workspace]
32 resolver = "1"
33-members = [
34- "crates/core_simd",
35- "crates/std_float",
36- "crates/test_helpers",
37-]
38+members = ["crates/core_simd", "crates/std_float", "crates/test_helpers"]
39
40 [profile.test.package."*"]
41 opt-level = 2
42@@ -15,4 +11,4 @@ opt-level = 2
43 [workspace.dependencies.proptest]
44 version = "1.11"
45 default-features = false
46-features = ["alloc", "f16"]
47+features = ["alloc"]
48diff --git a/crates/core_simd/src/alias.rs b/crates/core_simd/src/alias.rs
49index 6dcfcb6..23f121c 100644
50--- a/crates/core_simd/src/alias.rs
51+++ b/crates/core_simd/src/alias.rs
52@@ -153,16 +153,6 @@ alias! {
53 usizex64 64
54 }
55
56- f16 = {
57- f16x1 1
58- f16x2 2
59- f16x4 4
60- f16x8 8
61- f16x16 16
62- f16x32 32
63- f16x64 64
64- }
65-
66 f32 = {
67 f32x1 1
68 f32x2 2
69diff --git a/crates/core_simd/src/cast.rs b/crates/core_simd/src/cast.rs
70index 69dc7ba..1c3592f 100644
71--- a/crates/core_simd/src/cast.rs
72+++ b/crates/core_simd/src/cast.rs
73@@ -44,9 +44,6 @@ impl SimdCast for u64 {}
74 unsafe impl Sealed for usize {}
75 impl SimdCast for usize {}
76 // Safety: primitive number types can be cast to other primitive number types
77-unsafe impl Sealed for f16 {}
78-impl SimdCast for f16 {}
79-// Safety: primitive number types can be cast to other primitive number types
80 unsafe impl Sealed for f32 {}
81 impl SimdCast for f32 {}
82 // Safety: primitive number types can be cast to other primitive number types
83diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
84index 413a886..115be44 100644
85--- a/crates/core_simd/src/lib.rs
86+++ b/crates/core_simd/src/lib.rs
87@@ -1,7 +1,6 @@
88 #![no_std]
89 #![feature(
90 convert_float_to_int,
91- f16,
92 core_intrinsics,
93 decl_macro,
94 repr_simd,
95diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs
96index c0a06ed..eb6601f 100644
97--- a/crates/core_simd/src/ops.rs
98+++ b/crates/core_simd/src/ops.rs
99@@ -245,7 +245,7 @@ for_base_ops! {
100 // We don't need any special precautions here:
101 // Floats always accept arithmetic ops, but may become NaN.
102 for_base_ops! {
103- T = (f16, f32, f64);
104+ T = (f32, f64);
105 type Lhs = Simd<T, N>;
106 type Rhs = Simd<T, N>;
107 type Output = Self;
108diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs
109index af7aa8a..e1c0616 100644
110--- a/crates/core_simd/src/ops/unary.rs
111+++ b/crates/core_simd/src/ops/unary.rs
112@@ -19,8 +19,6 @@ macro_rules! neg {
113 }
114
115 neg! {
116- impl<const N: usize> Neg for Simd<f16, N>
117-
118 impl<const N: usize> Neg for Simd<f32, N>
119
120 impl<const N: usize> Neg for Simd<f64, N>
121diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs
122index 7683640..d553d6c 100644
123--- a/crates/core_simd/src/simd/cmp/eq.rs
124+++ b/crates/core_simd/src/simd/cmp/eq.rs
125@@ -42,7 +42,7 @@ macro_rules! impl_number {
126 }
127 }
128
129-impl_number! { f16, f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
130+impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
131
132 macro_rules! impl_mask {
133 { $($integer:ty),* } => {
134diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs
135index 5a4e74c..5672fbb 100644
136--- a/crates/core_simd/src/simd/cmp/ord.rs
137+++ b/crates/core_simd/src/simd/cmp/ord.rs
138@@ -144,7 +144,7 @@ macro_rules! impl_float {
139 }
140 }
141
142-impl_float! { f16, f32, f64 }
143+impl_float! { f32, f64 }
144
145 macro_rules! impl_mask {
146 { $($integer:ty),* } => {
147diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs
148index 510f4c9..175cbce 100644
149--- a/crates/core_simd/src/simd/num/float.rs
150+++ b/crates/core_simd/src/simd/num/float.rs
151@@ -444,4 +444,4 @@ macro_rules! impl_trait {
152 }
153 }
154
155-impl_trait! { f16 { bits: u16, mask: i16 }, f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } }
156+impl_trait! { f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } }
157diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
158index fbef69f..c8e0b8c 100644
159--- a/crates/core_simd/src/vector.rs
160+++ b/crates/core_simd/src/vector.rs
161@@ -1146,13 +1146,6 @@ unsafe impl SimdElement for isize {
162 type Mask = isize;
163 }
164
165-impl Sealed for f16 {}
166-
167-// Safety: f16 is a valid SIMD element type, and is supported by this API
168-unsafe impl SimdElement for f16 {
169- type Mask = i16;
170-}
171-
172 impl Sealed for f32 {}
173
174 // Safety: f32 is a valid SIMD element type, and is supported by this API
175diff --git a/crates/core_simd/tests/f16_ops.rs b/crates/core_simd/tests/f16_ops.rs
176deleted file mode 100644
177index f89bdf4..0000000
178--- a/crates/core_simd/tests/f16_ops.rs
179+++ /dev/null
180@@ -1,10 +0,0 @@
181-#![feature(portable_simd)]
182-#![feature(f16)]
183-
184-#[macro_use]
185-mod ops_macros;
186-
187-// FIXME: some f16 operations cause rustc to hang on wasm simd
188-// https://github.com/llvm/llvm-project/issues/189251
189-#[cfg(not(all(target_arch = "wasm32", target_feature = "simd128")))]
190-impl_float_tests! { f16, i16 }
191diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs
192index ff35254..acc1bfc 100644
193--- a/crates/std_float/src/lib.rs
194+++ b/crates/std_float/src/lib.rs
195@@ -2,7 +2,6 @@
196 feature = "as_crate",
197 feature(core_intrinsics),
198 feature(portable_simd),
199- feature(f16),
200 allow(internal_features)
201 )]
202 #[cfg(not(feature = "as_crate"))]
203@@ -170,17 +169,9 @@ pub trait StdFloat: Sealed + Sized {
204 fn fract(self) -> Self;
205 }
206
207-impl<const N: usize> Sealed for Simd<f16, N> {}
208 impl<const N: usize> Sealed for Simd<f32, N> {}
209 impl<const N: usize> Sealed for Simd<f64, N> {}
210
211-impl<const N: usize> StdFloat for Simd<f16, N> {
212- #[inline]
213- fn fract(self) -> Self {
214- self - self.trunc()
215- }
216-}
217-
218 impl<const N: usize> StdFloat for Simd<f32, N> {
219 #[inline]
220 fn fract(self) -> Self {
221diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs
222index 36761e3..cbc20cd 100644
223--- a/crates/test_helpers/src/biteq.rs
224+++ b/crates/test_helpers/src/biteq.rs
225@@ -53,7 +53,7 @@ macro_rules! impl_float_biteq {
226 };
227 }
228
229-impl_float_biteq! { f16, f32, f64 }
230+impl_float_biteq! { f32, f64 }
231
232 impl<T> BitEq for *const T {
233 fn biteq(&self, other: &Self) -> bool {
234diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs
235index 82adb06..4b03674 100644
236--- a/crates/test_helpers/src/lib.rs
237+++ b/crates/test_helpers/src/lib.rs
238@@ -1,4 +1,3 @@
239-#![feature(f16)]
240 #![cfg_attr(
241 any(target_arch = "powerpc", target_arch = "powerpc64"),
242 feature(powerpc_target_feature, stdarch_powerpc)
243@@ -47,7 +46,6 @@ impl_num! { u16 }
244 impl_num! { u32 }
245 impl_num! { u64 }
246 impl_num! { usize }
247-impl_num! { f16 }
248 impl_num! { f32 }
249 impl_num! { f64 }
250
251diff --git a/crates/test_helpers/src/subnormals.rs b/crates/test_helpers/src/subnormals.rs
252index 44dfbb3..b5f19ba 100644
253--- a/crates/test_helpers/src/subnormals.rs
254+++ b/crates/test_helpers/src/subnormals.rs
255@@ -39,7 +39,7 @@ macro_rules! impl_else {
256 }
257 }
258
259-impl_float! { f16, f32, f64 }
260+impl_float! { f32, f64 }
261 impl_else! { i8, i16, i32, i64, isize, u8, u16, u32, u64, usize }
262
263 /// AltiVec should flush subnormal inputs to zero, but QEMU seems to only flush outputs.
264--
2652.53.0
266
compiler/rustc_codegen_cranelift/rust-toolchain.toml+1-1
......@@ -1,4 +1,4 @@
11[toolchain]
2channel = "nightly-2026-03-25"
2channel = "nightly-2026-04-28"
33components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"]
44profile = "minimal"
compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh+3-3
......@@ -67,9 +67,9 @@ index bc68bfe396..00143ef3ed 100644
6767--- a/src/bootstrap/src/core/config/config.rs
6868+++ b/src/bootstrap/src/core/config/config.rs
6969@@ -2230,7 +2230,7 @@ pub fn download_ci_rustc_commit<'a>(
70 return None;
71 }
72
70 match freshness {
71 PathFreshness::LastModifiedUpstream { upstream } => upstream,
72 PathFreshness::HasLocalModifications { upstream, modifications } => {
7373- if dwn_ctx.is_running_on_ci() {
7474+ if false && dwn_ctx.is_running_on_ci() {
7575 eprintln!("CI rustc commit matches with HEAD and we are in CI.");
compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh+2
......@@ -50,6 +50,7 @@ rm tests/ui/c-variadic/copy.rs # same
5050rm tests/ui/sanitizer/kcfi-c-variadic.rs # same
5151rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported
5252rm tests/ui/delegation/fn-header.rs
53rm tests/ui/c-variadic/roundtrip.rs
5354
5455# inline assembly features
5556rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly
......@@ -144,6 +145,7 @@ rm tests/ui/consts/issue-33537.rs # same
144145rm tests/ui/consts/const-mut-refs-crate.rs # same
145146rm tests/ui/abi/large-byval-align.rs # exceeds implementation limit of Cranelift
146147rm -r tests/run-make/short-ice # ICE backtrace begin/end marker mismatch
148rm -r tests/run-make/naked-dead-code-elimination # function not eliminated
147149
148150# doesn't work due to the way the rustc test suite is invoked.
149151# should work when using ./x.py test the way it is intended
compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs+34
......@@ -51,6 +51,40 @@ fn f64_to_f16(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value {
5151 if ret_ty == types::I16 { fx.bcx.ins().bitcast(types::F16, MemFlags::new(), ret) } else { ret }
5252}
5353
54// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
55// been added to Cranelift.
56pub(crate) fn maybe_with_f16_to_f32(
57 fx: &mut FunctionCx<'_, '_, '_>,
58 val: Value,
59 f: impl FnOnce(&mut FunctionCx<'_, '_, '_>, Value) -> Value,
60) -> Value {
61 if fx.bcx.func.dfg.value_type(val) == types::F16 {
62 let val = f16_to_f32(fx, val);
63 let res = f(fx, val);
64 f32_to_f16(fx, res)
65 } else {
66 f(fx, val)
67 }
68}
69
70// FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
71// been added to Cranelift.
72pub(crate) fn maybe_with_f16_to_f32_pair(
73 fx: &mut FunctionCx<'_, '_, '_>,
74 a: Value,
75 b: Value,
76 f: impl FnOnce(&mut FunctionCx<'_, '_, '_>, Value, Value) -> Value,
77) -> Value {
78 if fx.bcx.func.dfg.value_type(a) == types::F16 {
79 let a = f16_to_f32(fx, a);
80 let b = f16_to_f32(fx, b);
81 let res = f(fx, a, b);
82 f32_to_f16(fx, res)
83 } else {
84 f(fx, a, b)
85 }
86}
87
5488pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs: Value) -> Value {
5589 let ty = fx.bcx.func.dfg.value_type(lhs);
5690 match ty {
compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs+1-1
......@@ -43,7 +43,7 @@ impl DebugContext {
4343 let _: Result<()> = sections.for_each(|id, section| {
4444 if let Some(section_id) = section_map.get(&id) {
4545 for reloc in &section.relocs {
46 product.add_debug_reloc(&section_map, section_id, reloc);
46 product.add_debug_reloc(&section_map, section_id, reloc, true);
4747 }
4848 }
4949 Ok(())
compiler/rustc_codegen_cranelift/src/debuginfo/object.rs+31-23
......@@ -1,7 +1,7 @@
11use cranelift_module::{DataId, FuncId};
22use cranelift_object::ObjectProduct;
33use gimli::SectionId;
4use object::write::{Relocation, StandardSegment};
4use object::write::{Relocation, StandardSection, StandardSegment};
55use object::{RelocationEncoding, RelocationFlags, SectionKind};
66use rustc_data_structures::fx::FxHashMap;
77
......@@ -16,6 +16,7 @@ pub(super) trait WriteDebugInfo {
1616 section_map: &FxHashMap<SectionId, Self::SectionId>,
1717 from: &Self::SectionId,
1818 reloc: &DebugReloc,
19 use_section_symbol: bool,
1920 );
2021}
2122
......@@ -27,29 +28,31 @@ impl WriteDebugInfo for ObjectProduct {
2728 id: SectionId,
2829 data: Vec<u8>,
2930 ) -> (object::write::SectionId, object::write::SymbolId) {
30 let name = if self.object.format() == object::BinaryFormat::MachO {
31 id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info
31 let (section_id, align);
32 if id == SectionId::EhFrame {
33 section_id = self.object.section_id(StandardSection::EhFrame);
34 align = 8;
3235 } else {
33 id.name().to_string()
34 }
35 .into_bytes();
36
37 let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
38 // FIXME use SHT_X86_64_UNWIND for .eh_frame
39 let section_id = self.object.add_section(
40 segment,
41 name,
42 if id == SectionId::DebugStr || id == SectionId::DebugLineStr {
43 SectionKind::DebugString
44 } else if id == SectionId::EhFrame {
45 SectionKind::ReadOnlyData
36 let name = if self.object.format() == object::BinaryFormat::MachO {
37 id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info
4638 } else {
47 SectionKind::Debug
48 },
49 );
50 self.object
51 .section_mut(section_id)
52 .set_data(data, if id == SectionId::EhFrame { 8 } else { 1 });
39 id.name().to_string()
40 }
41 .into_bytes();
42
43 let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
44 section_id = self.object.add_section(
45 segment,
46 name,
47 if id == SectionId::DebugStr || id == SectionId::DebugLineStr {
48 SectionKind::DebugString
49 } else {
50 SectionKind::Debug
51 },
52 );
53 align = 1;
54 }
55 self.object.section_mut(section_id).set_data(data, align);
5356 let symbol_id = self.object.section_symbol(section_id);
5457 (section_id, symbol_id)
5558 }
......@@ -59,6 +62,7 @@ impl WriteDebugInfo for ObjectProduct {
5962 section_map: &FxHashMap<SectionId, Self::SectionId>,
6063 from: &Self::SectionId,
6164 reloc: &DebugReloc,
65 use_section_symbol: bool,
6266 ) {
6367 let (symbol, symbol_offset) = match reloc.name {
6468 DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
......@@ -69,7 +73,11 @@ impl WriteDebugInfo for ObjectProduct {
6973 } else {
7074 self.data_symbol(DataId::from_u32(id & !(1 << 31)))
7175 };
72 self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0))
76 if use_section_symbol {
77 self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0))
78 } else {
79 (symbol_id, 0)
80 }
7381 }
7482 };
7583 self.object
compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs+6-6
......@@ -120,13 +120,12 @@ impl UnwindContext {
120120 func_id: FuncId,
121121 context: &Context,
122122 ) {
123 if let target_lexicon::OperatingSystem::MacOSX { .. } =
124 module.isa().triple().operating_system
123 let triple = module.isa().triple();
124 if matches!(triple.operating_system, target_lexicon::OperatingSystem::MacOSX { .. })
125 && triple.architecture == target_lexicon::Architecture::X86_64
125126 {
126127 // The object crate doesn't currently support DW_GNU_EH_PE_absptr, which macOS
127 // requires for unwinding tables. In addition on arm64 it currently doesn't
128 // support 32bit relocations as we currently use for the unwinding table.
129 // See gimli-rs/object#415 and rust-lang/rustc_codegen_cranelift#1371
128 // requires for unwinding tables. See gimli-rs/object#415.
130129 return;
131130 }
132131
......@@ -250,8 +249,9 @@ impl UnwindContext {
250249 let mut section_map = FxHashMap::default();
251250 section_map.insert(id, section_id);
252251
252 let use_section_symbol = product.object.format() != object::BinaryFormat::MachO;
253253 for reloc in &eh_frame.0.relocs {
254 product.add_debug_reloc(&section_map, &section_id, reloc);
254 product.add_debug_reloc(&section_map, &section_id, reloc, use_section_symbol);
255255 }
256256 }
257257 }
compiler/rustc_codegen_cranelift/src/driver/jit.rs+1-1
......@@ -7,7 +7,7 @@ use std::os::raw::{c_char, c_int};
77use cranelift_jit::{JITBuilder, JITModule};
88use rustc_codegen_ssa::CrateInfo;
99use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
10use rustc_middle::mir::mono::MonoItem;
10use rustc_middle::mono::MonoItem;
1111use rustc_session::Session;
1212use rustc_session::config::OutputFilenames;
1313use rustc_span::sym;
compiler/rustc_codegen_cranelift/src/global_asm.rs+3
......@@ -235,6 +235,9 @@ pub(crate) fn compile_global_asm(
235235 .arg("-")
236236 .arg("-Abad_asm_style")
237237 .arg("-Zcodegen-backend=llvm")
238 // JSON targets currently require `-Zunstable-options`
239 // Tracking issue: https://github.com/rust-lang/rust/issues/151528
240 .arg("-Zunstable-options")
238241 .stdin(Stdio::piped())
239242 .spawn()
240243 .expect("Failed to spawn `as`.");
compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs+6-12
......@@ -1197,12 +1197,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
11971197 let a = a.load_scalar(fx);
11981198 let b = b.load_scalar(fx);
11991199
1200 // FIXME(bytecodealliance/wasmtime#8312): Use `fmin` directly once
1201 // Cranelift backend lowerings are implemented.
1202 let a = codegen_f16_f128::f16_to_f32(fx, a);
1203 let b = codegen_f16_f128::f16_to_f32(fx, b);
1204 let val = fx.bcx.ins().fmin(a, b);
1205 let val = codegen_f16_f128::f32_to_f16(fx, val);
1200 let val = codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
1201 fx.bcx.ins().fmin(a, b)
1202 });
12061203 let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16));
12071204 ret.write_cvalue(fx, val);
12081205 }
......@@ -1240,12 +1237,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
12401237 let a = a.load_scalar(fx);
12411238 let b = b.load_scalar(fx);
12421239
1243 // FIXME(bytecodealliance/wasmtime#8312): Use `fmax` directly once
1244 // Cranelift backend lowerings are implemented.
1245 let a = codegen_f16_f128::f16_to_f32(fx, a);
1246 let b = codegen_f16_f128::f16_to_f32(fx, b);
1247 let val = fx.bcx.ins().fmax(a, b);
1248 let val = codegen_f16_f128::f32_to_f16(fx, val);
1240 let val = codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
1241 fx.bcx.ins().fmax(a, b)
1242 });
12491243 let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16));
12501244 ret.write_cvalue(fx, val);
12511245 }
compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs+89-57
......@@ -91,23 +91,26 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
9191 fx.bcx.ins().icmp(IntCC::SignedGreaterThanOrEqual, x_lane, y_lane)
9292 }
9393
94 // FIXME(bytecodealliance/wasmtime#8312): Replace with Cranelift
95 // `fcmp` once `f16`/`f128` backend lowerings have been added to
96 // Cranelift.
9497 (ty::Float(_), sym::simd_eq) => {
95 fx.bcx.ins().fcmp(FloatCC::Equal, x_lane, y_lane)
98 codegen_f16_f128::fcmp(fx, FloatCC::Equal, x_lane, y_lane)
9699 }
97100 (ty::Float(_), sym::simd_ne) => {
98 fx.bcx.ins().fcmp(FloatCC::NotEqual, x_lane, y_lane)
101 codegen_f16_f128::fcmp(fx, FloatCC::NotEqual, x_lane, y_lane)
99102 }
100103 (ty::Float(_), sym::simd_lt) => {
101 fx.bcx.ins().fcmp(FloatCC::LessThan, x_lane, y_lane)
104 codegen_f16_f128::fcmp(fx, FloatCC::LessThan, x_lane, y_lane)
102105 }
103106 (ty::Float(_), sym::simd_le) => {
104 fx.bcx.ins().fcmp(FloatCC::LessThanOrEqual, x_lane, y_lane)
107 codegen_f16_f128::fcmp(fx, FloatCC::LessThanOrEqual, x_lane, y_lane)
105108 }
106109 (ty::Float(_), sym::simd_gt) => {
107 fx.bcx.ins().fcmp(FloatCC::GreaterThan, x_lane, y_lane)
110 codegen_f16_f128::fcmp(fx, FloatCC::GreaterThan, x_lane, y_lane)
108111 }
109112 (ty::Float(_), sym::simd_ge) => {
110 fx.bcx.ins().fcmp(FloatCC::GreaterThanOrEqual, x_lane, y_lane)
113 codegen_f16_f128::fcmp(fx, FloatCC::GreaterThanOrEqual, x_lane, y_lane)
111114 }
112115
113116 _ => unreachable!(),
......@@ -391,6 +394,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
391394 intrinsic,
392395 ) {
393396 (ty::Int(_), sym::simd_neg) => fx.bcx.ins().ineg(lane),
397 (ty::Float(FloatTy::F16), sym::simd_neg) => codegen_f16_f128::neg_f16(fx, lane),
394398 (ty::Float(_), sym::simd_neg) => fx.bcx.ins().fneg(lane),
395399
396400 (ty::Uint(ty::UintTy::U8) | ty::Int(ty::IntTy::I8), sym::simd_bswap) => lane,
......@@ -418,50 +422,65 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
418422
419423 // FIXME use vector instructions when possible
420424 simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, _ret_lane_ty, x_lane, y_lane| {
421 match (lane_ty.kind(), intrinsic) {
422 (ty::Uint(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
423 (ty::Uint(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
424 (ty::Uint(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
425 (ty::Uint(_), sym::simd_div) => fx.bcx.ins().udiv(x_lane, y_lane),
426 (ty::Uint(_), sym::simd_rem) => fx.bcx.ins().urem(x_lane, y_lane),
427
428 (ty::Int(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
429 (ty::Int(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
430 (ty::Int(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
431 (ty::Int(_), sym::simd_div) => fx.bcx.ins().sdiv(x_lane, y_lane),
432 (ty::Int(_), sym::simd_rem) => fx.bcx.ins().srem(x_lane, y_lane),
433
434 (ty::Float(_), sym::simd_add) => fx.bcx.ins().fadd(x_lane, y_lane),
435 (ty::Float(_), sym::simd_sub) => fx.bcx.ins().fsub(x_lane, y_lane),
436 (ty::Float(_), sym::simd_mul) => fx.bcx.ins().fmul(x_lane, y_lane),
437 (ty::Float(_), sym::simd_div) => fx.bcx.ins().fdiv(x_lane, y_lane),
438 (ty::Float(FloatTy::F32), sym::simd_rem) => fx.lib_call(
439 "fmodf",
440 vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
441 vec![AbiParam::new(types::F32)],
442 &[x_lane, y_lane],
443 )[0],
444 (ty::Float(FloatTy::F64), sym::simd_rem) => fx.lib_call(
445 "fmod",
446 vec![AbiParam::new(types::F64), AbiParam::new(types::F64)],
447 vec![AbiParam::new(types::F64)],
448 &[x_lane, y_lane],
449 )[0],
450
451 (ty::Uint(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
452 (ty::Uint(_), sym::simd_shr) => fx.bcx.ins().ushr(x_lane, y_lane),
453 (ty::Uint(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
454 (ty::Uint(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
455 (ty::Uint(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
456
457 (ty::Int(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
458 (ty::Int(_), sym::simd_shr) => fx.bcx.ins().sshr(x_lane, y_lane),
459 (ty::Int(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
460 (ty::Int(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
461 (ty::Int(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
462
463 _ => unreachable!(),
464 }
425 codegen_f16_f128::maybe_with_f16_to_f32_pair(
426 fx,
427 x_lane,
428 y_lane,
429 |fx, x_lane, y_lane| match (lane_ty.kind(), intrinsic) {
430 (ty::Uint(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
431 (ty::Uint(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
432 (ty::Uint(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
433 (ty::Uint(_), sym::simd_div) => fx.bcx.ins().udiv(x_lane, y_lane),
434 (ty::Uint(_), sym::simd_rem) => fx.bcx.ins().urem(x_lane, y_lane),
435
436 (ty::Int(_), sym::simd_add) => fx.bcx.ins().iadd(x_lane, y_lane),
437 (ty::Int(_), sym::simd_sub) => fx.bcx.ins().isub(x_lane, y_lane),
438 (ty::Int(_), sym::simd_mul) => fx.bcx.ins().imul(x_lane, y_lane),
439 (ty::Int(_), sym::simd_div) => fx.bcx.ins().sdiv(x_lane, y_lane),
440 (ty::Int(_), sym::simd_rem) => fx.bcx.ins().srem(x_lane, y_lane),
441
442 (ty::Float(_), sym::simd_add) => fx.bcx.ins().fadd(x_lane, y_lane),
443 (ty::Float(_), sym::simd_sub) => fx.bcx.ins().fsub(x_lane, y_lane),
444 (ty::Float(_), sym::simd_mul) => fx.bcx.ins().fmul(x_lane, y_lane),
445 (ty::Float(_), sym::simd_div) => fx.bcx.ins().fdiv(x_lane, y_lane),
446 (ty::Float(FloatTy::F16), sym::simd_rem) => fx.lib_call(
447 "fmodf",
448 vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
449 vec![AbiParam::new(types::F32)],
450 // FIXME(bytecodealliance/wasmtime#8312): Already converted
451 // by the FIXME above.
452 // fx.bcx.ins().fpromote(types::F32, lhs),
453 // fx.bcx.ins().fpromote(types::F32, rhs),
454 &[x_lane, y_lane],
455 )[0],
456 (ty::Float(FloatTy::F32), sym::simd_rem) => fx.lib_call(
457 "fmodf",
458 vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
459 vec![AbiParam::new(types::F32)],
460 &[x_lane, y_lane],
461 )[0],
462 (ty::Float(FloatTy::F64), sym::simd_rem) => fx.lib_call(
463 "fmod",
464 vec![AbiParam::new(types::F64), AbiParam::new(types::F64)],
465 vec![AbiParam::new(types::F64)],
466 &[x_lane, y_lane],
467 )[0],
468
469 (ty::Uint(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
470 (ty::Uint(_), sym::simd_shr) => fx.bcx.ins().ushr(x_lane, y_lane),
471 (ty::Uint(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
472 (ty::Uint(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
473 (ty::Uint(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
474
475 (ty::Int(_), sym::simd_shl) => fx.bcx.ins().ishl(x_lane, y_lane),
476 (ty::Int(_), sym::simd_shr) => fx.bcx.ins().sshr(x_lane, y_lane),
477 (ty::Int(_), sym::simd_and) => fx.bcx.ins().band(x_lane, y_lane),
478 (ty::Int(_), sym::simd_or) => fx.bcx.ins().bor(x_lane, y_lane),
479 (ty::Int(_), sym::simd_xor) => fx.bcx.ins().bxor(x_lane, y_lane),
480
481 _ => unreachable!(),
482 },
483 )
465484 });
466485 }
467486
......@@ -486,7 +505,11 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
486505 let b_lane = b.value_lane(fx, lane).load_scalar(fx);
487506 let c_lane = c.value_lane(fx, lane).load_scalar(fx);
488507
489 let res_lane = fx.bcx.ins().fma(a_lane, b_lane, c_lane);
508 let res_lane = if *lane_ty.kind() == ty::Float(FloatTy::F16) {
509 codegen_f16_f128::fma_f16(fx, a_lane, b_lane, c_lane)
510 } else {
511 fx.bcx.ins().fma(a_lane, b_lane, c_lane)
512 };
490513 let res_lane = CValue::by_val(res_lane, res_lane_layout);
491514
492515 ret.place_lane(fx, lane).write_cvalue(fx, res_lane);
......@@ -584,14 +607,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
584607 ty::Float(_) => {}
585608 _ => unreachable!("{:?}", lane_ty),
586609 }
587 match intrinsic {
610
611 codegen_f16_f128::maybe_with_f16_to_f32(fx, lane, |fx, lane| match intrinsic {
588612 sym::simd_fabs => fx.bcx.ins().fabs(lane),
589613 sym::simd_fsqrt => fx.bcx.ins().sqrt(lane),
590614 sym::simd_ceil => fx.bcx.ins().ceil(lane),
591615 sym::simd_floor => fx.bcx.ins().floor(lane),
592616 sym::simd_trunc => fx.bcx.ins().trunc(lane),
593617 _ => unreachable!(),
594 }
618 })
595619 });
596620 }
597621
......@@ -607,7 +631,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
607631
608632 simd_reduce(fx, v, Some(acc), ret, &|fx, lane_ty, a, b| {
609633 if lane_ty.is_floating_point() {
610 fx.bcx.ins().fadd(a, b)
634 codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
635 fx.bcx.ins().fadd(a, b)
636 })
611637 } else {
612638 fx.bcx.ins().iadd(a, b)
613639 }
......@@ -625,7 +651,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
625651
626652 simd_reduce(fx, v, None, ret, &|fx, lane_ty, a, b| {
627653 if lane_ty.is_floating_point() {
628 fx.bcx.ins().fadd(a, b)
654 codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
655 fx.bcx.ins().fadd(a, b)
656 })
629657 } else {
630658 fx.bcx.ins().iadd(a, b)
631659 }
......@@ -644,7 +672,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
644672
645673 simd_reduce(fx, v, Some(acc), ret, &|fx, lane_ty, a, b| {
646674 if lane_ty.is_floating_point() {
647 fx.bcx.ins().fmul(a, b)
675 codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
676 fx.bcx.ins().fmul(a, b)
677 })
648678 } else {
649679 fx.bcx.ins().imul(a, b)
650680 }
......@@ -662,7 +692,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
662692
663693 simd_reduce(fx, v, None, ret, &|fx, lane_ty, a, b| {
664694 if lane_ty.is_floating_point() {
665 fx.bcx.ins().fmul(a, b)
695 codegen_f16_f128::maybe_with_f16_to_f32_pair(fx, a, b, |fx, a, b| {
696 fx.bcx.ins().fmul(a, b)
697 })
666698 } else {
667699 fx.bcx.ins().imul(a, b)
668700 }
compiler/rustc_codegen_cranelift/src/num.rs+6-17
......@@ -358,7 +358,6 @@ pub(crate) fn codegen_float_binop<'tcx>(
358358 } else {
359359 (lhs, rhs)
360360 };
361 let b = fx.bcx.ins();
362361 let res = match bin_op {
363362 // FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings
364363 // have been added to Cranelift.
......@@ -367,10 +366,10 @@ pub(crate) fn codegen_float_binop<'tcx>(
367366 {
368367 codegen_f16_f128::codegen_f128_binop(fx, bin_op, lhs, rhs)
369368 }
370 BinOp::Add => b.fadd(lhs, rhs),
371 BinOp::Sub => b.fsub(lhs, rhs),
372 BinOp::Mul => b.fmul(lhs, rhs),
373 BinOp::Div => b.fdiv(lhs, rhs),
369 BinOp::Add => fx.bcx.ins().fadd(lhs, rhs),
370 BinOp::Sub => fx.bcx.ins().fsub(lhs, rhs),
371 BinOp::Mul => fx.bcx.ins().fmul(lhs, rhs),
372 BinOp::Div => fx.bcx.ins().fdiv(lhs, rhs),
374373 BinOp::Rem => {
375374 let (name, ty, lhs, rhs) = match in_lhs.layout().ty.kind() {
376375 ty::Float(FloatTy::F16) => (
......@@ -389,22 +388,12 @@ pub(crate) fn codegen_float_binop<'tcx>(
389388 _ => bug!(),
390389 };
391390
392 let ret_val = fx.lib_call(
391 fx.lib_call(
393392 name,
394393 vec![AbiParam::new(ty), AbiParam::new(ty)],
395394 vec![AbiParam::new(ty)],
396395 &[lhs, rhs],
397 )[0];
398
399 let ret_val = if *in_lhs.layout().ty.kind() == ty::Float(FloatTy::F16) {
400 // FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
401 // operation once Cranelift backend lowerings have been
402 // implemented.
403 codegen_f16_f128::f32_to_f16(fx, ret_val)
404 } else {
405 ret_val
406 };
407 return CValue::by_val(ret_val, in_lhs.layout());
396 )[0]
408397 }
409398 BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
410399 let fltcc = match bin_op {
compiler/rustc_codegen_cranelift/src/pretty_clif.rs+1-7
......@@ -60,7 +60,6 @@ use std::fmt;
6060use std::io::Write;
6161
6262use cranelift_codegen::entity::SecondaryMap;
63use cranelift_codegen::ir::Fact;
6463use cranelift_codegen::ir::entities::AnyEntity;
6564use cranelift_codegen::write::{FuncWriter, PlainWriter};
6665use rustc_middle::ty::print::with_no_trimmed_paths;
......@@ -182,13 +181,8 @@ impl FuncWriter for &'_ CommentWriter {
182181 _func: &Function,
183182 entity: AnyEntity,
184183 value: &dyn fmt::Display,
185 maybe_fact: Option<&Fact>,
186184 ) -> fmt::Result {
187 if let Some(fact) = maybe_fact {
188 write!(w, " {} ! {} = {}", entity, fact, value)?;
189 } else {
190 write!(w, " {} = {}", entity, value)?;
191 }
185 write!(w, " {} = {}", entity, value)?;
192186
193187 if let Some(comment) = self.entity_comments.get(&entity) {
194188 writeln!(w, " ; {}", comment.replace('\n', "\n; "))
compiler/rustc_codegen_cranelift/src/value_and_place.rs+10-2
......@@ -204,7 +204,9 @@ impl<'tcx> CValue<'tcx> {
204204 let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
205205 CValue::by_ref(field_ptr, field_layout)
206206 }
207 CValueInner::ByRef(_, Some(_)) => todo!(),
207 CValueInner::ByRef(_, Some(_)) => {
208 bug!("value_field for unsized by-ref value not supported")
209 }
208210 }
209211 }
210212
......@@ -655,7 +657,13 @@ impl<'tcx> CPlace<'tcx> {
655657 flags,
656658 );
657659 }
658 CValueInner::ByRef(_, Some(_)) => todo!(),
660 CValueInner::ByRef(_from_ptr, Some(_extra)) => {
661 bug!(
662 "write_cvalue for unsized by-ref value not allowed: dst={:?} src={:?}",
663 dst_layout.ty,
664 from.layout().ty
665 );
666 }
659667 }
660668 }
661669 }
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+1
......@@ -2350,6 +2350,7 @@ unsafe extern "C" {
23502350 pub(crate) fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
23512351
23522352 pub(crate) fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
2353 pub(crate) fn LLVMRustTargetHasMnemonic(T: &TargetMachine, s: *const c_char) -> bool;
23532354
23542355 pub(crate) fn LLVMRustPrintTargetCPUs(TM: &TargetMachine, OutStr: &RustString);
23552356 pub(crate) fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
compiler/rustc_codegen_llvm/src/llvm_util.rs+11
......@@ -480,6 +480,10 @@ pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
480480 match req.kind {
481481 PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
482482 PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
483 PrintKind::BackendHasMnemonic => {
484 let mnemonic = req.arg.as_deref().expect("BackendHasMnemonic requires arg");
485 print_target_has_mnemonic(tm.raw(), mnemonic, out)
486 }
483487 _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
484488 }
485489}
......@@ -738,3 +742,10 @@ pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> {
738742 let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
739743 Some(handle_native(name))
740744}
745
746fn print_target_has_mnemonic(tm: &llvm::TargetMachine, mnemonic: &str, out: &mut String) {
747 use std::fmt::Write;
748 let cstr = SmallCStr::new(mnemonic);
749 let has_mnemonic = unsafe { llvm::LLVMRustTargetHasMnemonic(tm, cstr.as_ptr()) };
750 writeln!(out, "{}", has_mnemonic).unwrap();
751}
compiler/rustc_data_structures/src/graph/scc/mod.rs+1-1
......@@ -27,7 +27,7 @@ mod tests;
2727/// the max/min element of the SCC, or all of the above.
2828///
2929/// Concretely, the both merge operations must commute, e.g. where `merge`
30/// is `update_scc` and `update_reached`: `a.merge(b) == b.merge(a)`
30/// is `update_scc` and `update_reachable`: `a.merge(b) == b.merge(a)`
3131///
3232/// In general, what you want is probably always min/max according
3333/// to some ordering, potentially with side constraints (min x such
compiler/rustc_driver_impl/src/lib.rs+3
......@@ -804,6 +804,9 @@ fn print_crate_info(
804804 let calling_conventions = rustc_abi::all_names();
805805 println_info!("{}", calling_conventions.join("\n"));
806806 }
807 BackendHasMnemonic => {
808 codegen_backend.print(req, &mut crate_info, sess);
809 }
807810 BackendHasZstd => {
808811 let has_zstd: bool = codegen_backend.has_zstd();
809812 println_info!("{has_zstd}");
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp+20
......@@ -19,6 +19,7 @@
1919#include "llvm/IR/Verifier.h"
2020#include "llvm/IRPrinter/IRPrintingPasses.h"
2121#include "llvm/LTO/LTO.h"
22#include "llvm/MC/MCInstrInfo.h"
2223#include "llvm/MC/MCSubtargetInfo.h"
2324#include "llvm/MC/TargetRegistry.h"
2425#include "llvm/Object/ObjectFile.h"
......@@ -94,6 +95,25 @@ extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
9495 return MCInfo->checkFeatures(std::string("+") + Feature);
9596}
9697
98/// Check whether the target has a specific assembly mnemonic like `ret` or
99/// `nop`.
100/// This should be fast enough but if its not we have to look into another
101/// method of checking.
102extern "C" bool LLVMRustTargetHasMnemonic(LLVMTargetMachineRef TM,
103 const char *Mnemonic) {
104 TargetMachine *Target = unwrap(TM);
105 const MCInstrInfo *MII = Target->getMCInstrInfo();
106 StringRef MnemonicRef(Mnemonic);
107
108 for (unsigned i = 0; i < MII->getNumOpcodes(); i++) {
109 StringRef Name = MII->getName(i);
110 if (Name.equals_insensitive(MnemonicRef)) {
111 return true;
112 }
113 }
114 return false;
115}
116
97117enum class LLVMRustCodeModel {
98118 Tiny,
99119 Small,
compiler/rustc_middle/src/ty/context.rs+4-4
......@@ -1416,12 +1416,12 @@ impl<'tcx> TyCtxt<'tcx> {
14161416 self,
14171417 stable_crate_id: StableCrateId,
14181418 ) -> Result<TyCtxtFeed<'tcx, CrateNum>, CrateNum> {
1419 if let Some(&existing) = self.untracked().stable_crate_ids.read().get(&stable_crate_id) {
1419 let mut lock = self.untracked().stable_crate_ids.write();
1420 if let Some(&existing) = lock.get(&stable_crate_id) {
14201421 return Err(existing);
14211422 }
1422
1423 let num = CrateNum::new(self.untracked().stable_crate_ids.read().len());
1424 self.untracked().stable_crate_ids.write().insert(stable_crate_id, num);
1423 let num = CrateNum::new(lock.len());
1424 lock.insert(stable_crate_id, num);
14251425 Ok(TyCtxtFeed { key: num, tcx: self })
14261426 }
14271427
compiler/rustc_mir_build/src/errors.rs+17-15
......@@ -924,22 +924,24 @@ pub(crate) struct IrrefutableLetPatternsIfLetGuard {
924924}
925925
926926#[derive(Diagnostic)]
927#[diag(
928 "irrefutable `let...else` {$count ->
929 [one] pattern
930 *[other] patterns
931}"
932)]
933#[note(
934 "{$count ->
935 [one] this pattern always matches, so the else clause is unreachable
936 *[other] these patterns always match, so the else clause is unreachable
937}"
938)]
927#[diag("unreachable `else` clause")]
928#[note("this pattern always matches, so the else clause is unreachable")]
939929pub(crate) struct IrrefutableLetPatternsLetElse {
940 pub(crate) count: usize,
941 #[help("remove this `else` block")]
942 pub(crate) else_span: Option<Span>,
930 #[subdiagnostic]
931 pub(crate) be_replaced: Option<LetElseReplacementSuggestion>,
932}
933
934#[derive(Subdiagnostic, Debug)]
935#[suggestion(
936 "consider using `let {$lhs} = {$rhs}` to match on a specific variant",
937 code = "let {lhs} = {rhs}",
938 applicability = "machine-applicable"
939)]
940pub(crate) struct LetElseReplacementSuggestion {
941 #[primary_span]
942 pub(crate) span: Span,
943 pub(crate) lhs: String,
944 pub(crate) rhs: String,
943945}
944946
945947#[derive(Diagnostic)]
compiler/rustc_mir_build/src/thir/pattern/check_match.rs+64-7
......@@ -168,7 +168,7 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
168168 let Ok(()) = self.visit_land(ex, &mut chain_refutabilities) else { return };
169169 // Lint only single irrefutable let binding.
170170 if let [Some((_, Irrefutable))] = chain_refutabilities[..] {
171 self.lint_single_let(ex.span, None);
171 self.lint_single_let(ex.span, None, None);
172172 }
173173 return;
174174 }
......@@ -438,7 +438,45 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
438438 if let LetSource::PlainLet = self.let_source {
439439 self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span));
440440 } else if let Ok(Irrefutable) = self.is_let_irrefutable(pat, scrut) {
441 self.lint_single_let(span, else_span);
441 if span.from_expansion() {
442 self.lint_single_let(span, None, None);
443 return;
444 }
445 let let_else_span = self.check_irrefutable_option_some(pat, scrut, span);
446
447 let sm = self.tcx.sess.source_map();
448 let next_token_start = sm.span_extend_while_whitespace(span.clone()).hi();
449 let line_span = sm.span_extend_to_line(span.clone()).with_lo(next_token_start);
450 let else_keyword_span = sm.span_until_whitespace(line_span);
451 self.lint_single_let(span, Some(else_keyword_span), let_else_span);
452 }
453 }
454
455 /// Check case `let x = Some(y);`, user likely intended to destructure `Option`
456 fn check_irrefutable_option_some(
457 &self,
458 pat: &'p Pat<'tcx>,
459 initializer: Option<&Expr<'tcx>>,
460 span: Span,
461 ) -> Option<LetElseReplacementSuggestion> {
462 if let sm = self.tcx.sess.source_map()
463 && let Some(initializer) = initializer
464 && let Some(s_ty) = initializer.ty.ty_adt_def()
465 && self.tcx.is_diagnostic_item(rustc_span::sym::Option, s_ty.did())
466 && let ExprKind::Scope { value, .. } = initializer.kind
467 && let initializer_expr = &self.thir[value]
468 && let ExprKind::Adt(box AdtExpr { fields, .. }) = &initializer_expr.kind
469 && let Some(field) = fields.first()
470 && let inner = &self.thir[field.expr]
471 && let Some(inner_ty) = inner.ty.ty_adt_def()
472 && self.tcx.is_diagnostic_item(rustc_span::sym::Option, inner_ty.did())
473 && let Ok(rhs) = sm.span_to_snippet(inner.span)
474 && let Ok(lhs) = sm.span_to_snippet(pat.span)
475 {
476 let lhs = format!("Some({})", lhs);
477 Some(LetElseReplacementSuggestion { span, lhs, rhs })
478 } else {
479 None
442480 }
443481 }
444482
......@@ -559,14 +597,20 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
559597 }
560598
561599 #[instrument(level = "trace", skip(self))]
562 fn lint_single_let(&mut self, let_span: Span, else_span: Option<Span>) {
600 fn lint_single_let(
601 &mut self,
602 let_span: Span,
603 else_keyword_span: Option<Span>,
604 let_else_span: Option<LetElseReplacementSuggestion>,
605 ) {
563606 report_irrefutable_let_patterns(
564607 self.tcx,
565608 self.hir_source,
566609 self.let_source,
567610 1,
568611 let_span,
569 else_span,
612 else_keyword_span,
613 let_else_span,
570614 );
571615 }
572616
......@@ -862,7 +906,8 @@ fn report_irrefutable_let_patterns(
862906 source: LetSource,
863907 count: usize,
864908 span: Span,
865 else_span: Option<Span>,
909 else_keyword_span: Option<Span>,
910 let_else_span: Option<LetElseReplacementSuggestion>,
866911) {
867912 macro_rules! emit_diag {
868913 ($lint:tt) => {{
......@@ -875,11 +920,23 @@ fn report_irrefutable_let_patterns(
875920 LetSource::IfLet | LetSource::ElseIfLet => emit_diag!(IrrefutableLetPatternsIfLet),
876921 LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard),
877922 LetSource::LetElse => {
923 let spans = match else_keyword_span {
924 Some(else_keyword_span) => {
925 let mut spans = MultiSpan::from_span(else_keyword_span);
926 spans.push_span_label(
927 span,
928 msg!("assigning to binding pattern will always succeed"),
929 );
930 spans
931 }
932 None => span.into(),
933 };
934
878935 tcx.emit_node_span_lint(
879936 IRREFUTABLE_LET_PATTERNS,
880937 id,
881 span,
882 IrrefutableLetPatternsLetElse { count, else_span },
938 spans,
939 IrrefutableLetPatternsLetElse { be_replaced: let_else_span },
883940 );
884941 }
885942 LetSource::WhileLet => emit_diag!(IrrefutableLetPatternsWhileLet),
compiler/rustc_session/src/config.rs+1-5
......@@ -1487,11 +1487,7 @@ impl Options {
14871487 }
14881488
14891489 pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1490 self.cg.symbol_mangling_version.unwrap_or(if self.unstable_features.is_nightly_build() {
1491 SymbolManglingVersion::V0
1492 } else {
1493 SymbolManglingVersion::Legacy
1494 })
1490 self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::V0)
14951491 }
14961492
14971493 #[inline]
compiler/rustc_session/src/config/print_request.rs+31-6
......@@ -15,6 +15,7 @@ use crate::macros::AllVariants;
1515pub struct PrintRequest {
1616 pub kind: PrintKind,
1717 pub out: OutFileName,
18 pub arg: Option<String>,
1819}
1920
2021#[derive(Copy, Clone, PartialEq, Eq, Debug)]
......@@ -22,6 +23,7 @@ pub struct PrintRequest {
2223pub enum PrintKind {
2324 // tidy-alphabetical-start
2425 AllTargetSpecsJson,
26 BackendHasMnemonic,
2527 BackendHasZstd,
2628 CallingConventions,
2729 Cfg,
......@@ -55,6 +57,7 @@ impl PrintKind {
5557 match self {
5658 // tidy-alphabetical-start
5759 AllTargetSpecsJson => "all-target-specs-json",
60 BackendHasMnemonic => "backend-has-mnemonic",
5861 BackendHasZstd => "backend-has-zstd",
5962 CallingConventions => "calling-conventions",
6063 Cfg => "cfg",
......@@ -108,7 +111,8 @@ impl PrintKind {
108111
109112 // Unstable values:
110113 AllTargetSpecsJson => false,
111 BackendHasZstd => false, // (perma-unstable, for use by compiletest)
114 BackendHasMnemonic => false, // (perma-unstable, for use by compiletest)
115 BackendHasZstd => false, // (perma-unstable, for use by compiletest)
112116 CheckCfg => false,
113117 CrateRootLintLevels => false,
114118 SupportedCrateTypes => false,
......@@ -145,11 +149,19 @@ pub(crate) fn collect_print_requests(
145149) -> Vec<PrintRequest> {
146150 let mut prints = Vec::<PrintRequest>::new();
147151 if cg.target_cpu.as_deref() == Some("help") {
148 prints.push(PrintRequest { kind: PrintKind::TargetCPUs, out: OutFileName::Stdout });
152 prints.push(PrintRequest {
153 kind: PrintKind::TargetCPUs,
154 out: OutFileName::Stdout,
155 arg: None,
156 });
149157 cg.target_cpu = None;
150158 };
151159 if cg.target_feature == "help" {
152 prints.push(PrintRequest { kind: PrintKind::TargetFeatures, out: OutFileName::Stdout });
160 prints.push(PrintRequest {
161 kind: PrintKind::TargetFeatures,
162 out: OutFileName::Stdout,
163 arg: None,
164 });
153165 cg.target_feature = String::new();
154166 }
155167
......@@ -162,9 +174,22 @@ pub(crate) fn collect_print_requests(
162174 prints.extend(matches.opt_strs("print").into_iter().map(|req| {
163175 let (req, out) = split_out_file_name(&req);
164176
165 let kind = if let Some(print_kind) = PrintKind::from_str(req) {
177 let (kind, arg) = if let Some(mnemonic) = req.strip_prefix("backend-has-mnemonic") {
178 check_print_request_stability(early_dcx, unstable_opts, PrintKind::BackendHasMnemonic);
179 // BackendHasMnemonic requires a mnemonic argument
180 if let Some(mnemonic) = mnemonic.strip_prefix(':')
181 && !mnemonic.is_empty()
182 {
183 (PrintKind::BackendHasMnemonic, Some(mnemonic.to_string()))
184 } else {
185 early_dcx.early_fatal(
186 "expected mnemonic name after `--print=backend-has-mnemonic:`, \
187 for example: `--print=backend-has-mnemonic:RET`",
188 );
189 }
190 } else if let Some(print_kind) = PrintKind::from_str(req) {
166191 check_print_request_stability(early_dcx, unstable_opts, print_kind);
167 print_kind
192 (print_kind, None)
168193 } else {
169194 let is_nightly = nightly_options::match_is_nightly_build(matches);
170195 emit_unknown_print_request_help(early_dcx, req, is_nightly)
......@@ -180,7 +205,7 @@ pub(crate) fn collect_print_requests(
180205 }
181206 }
182207
183 PrintRequest { kind, out }
208 PrintRequest { kind, out, arg }
184209 }));
185210
186211 prints
compiler/rustc_session/src/options.rs+1-1
......@@ -2166,7 +2166,7 @@ options! {
21662166 "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
21672167 symbol_mangling_version: Option<SymbolManglingVersion> = (None,
21682168 parse_symbol_mangling_version, [TRACKED],
2169 "which mangling version to use for symbol names ('legacy' (default), 'v0', or 'hashed')"),
2169 "which mangling version to use for symbol names ('legacy', 'v0' (default), or 'hashed')"),
21702170 target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
21712171 "select target processor (`rustc --print target-cpus` for details)"),
21722172 target_feature: String = (String::new(), parse_target_feature, [TRACKED],
compiler/rustc_trait_selection/src/traits/effects.rs+1-5
......@@ -554,11 +554,7 @@ fn evaluate_host_effect_for_fn_goal<'tcx>(
554554 // but they don't really need to right now.
555555 ty::CoroutineClosure(_, _) => return Err(EvaluationFailure::NoSolution),
556556
557 ty::Closure(def, args) => {
558 // For now we limit ourselves to closures without binders. The next solver can handle them.
559 args.as_closure().sig().no_bound_vars().ok_or(EvaluationFailure::NoSolution)?;
560 (def, args)
561 }
557 ty::Closure(def, args) => (def, args),
562558
563559 // Everything else needs explicit impls or cannot have an impl
564560 _ => return Err(EvaluationFailure::NoSolution),
library/core/src/option.rs-3
......@@ -40,9 +40,6 @@
4040//! }
4141//! ```
4242//!
43//
44// FIXME: Show how `Option` is used in practice, with lots of methods
45//
4643//! # Options and pointers ("nullable" pointers)
4744//!
4845//! Rust's pointer types must always point to a valid location; there are
library/core/src/primitive_docs.rs+4-1
......@@ -1794,6 +1794,7 @@ mod prim_ref {}
17941794/// have different sizes.
17951795///
17961796/// ### ABI compatibility
1797/// [ABI compatibility]: #abi-compatibility
17971798///
17981799/// Generally, when a function is declared with one signature and called via a function pointer with
17991800/// a different signature, the two signatures must be *ABI-compatible* or else calling the function
......@@ -1831,7 +1832,7 @@ mod prim_ref {}
18311832/// - `*const T`, `*mut T`, `&T`, `&mut T`, `Box<T>` (specifically, only `Box<T, Global>`), and
18321833/// `NonNull<T>` are all ABI-compatible with each other for all `T`. They are also ABI-compatible
18331834/// with each other for _different_ `T` if they have the same metadata type (`<T as
1834/// Pointee>::Metadata`).
1835/// Pointee>::Metadata`). However, see the [Control Flow Integrity][cfi-docs] docs for caveats.
18351836/// - `usize` is ABI-compatible with the `uN` integer type of the same size, and likewise `isize` is
18361837/// ABI-compatible with the `iN` integer type of the same size.
18371838/// - `char` is ABI-compatible with `u32`.
......@@ -1890,6 +1891,8 @@ mod prim_ref {}
18901891/// Behavior since transmuting `None::<NonZero<i32>>` to `NonZero<i32>` violates the non-zero
18911892/// requirement.
18921893///
1894/// [cfi-docs]: https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#controlflowintegrity
1895///
18931896/// ### Trait implementations
18941897///
18951898/// In this documentation the shorthand `fn(T₁, T₂, …, Tₙ)` is used to represent non-variadic
library/portable-simd/crates/core_simd/src/masks.rs+9-1
......@@ -400,7 +400,15 @@ where
400400 if min_index.eq(T::TRUE) {
401401 None
402402 } else {
403 Some(min_index.to_usize())
403 let min_index = min_index.to_usize();
404
405 // Allow eliminating bounds checks when using the index
406 // Safety: the index can't exceed the number of elements in the vector
407 unsafe {
408 core::hint::assert_unchecked(min_index < N);
409 }
410
411 Some(min_index)
404412 }
405413 }
406414}
library/portable-simd/crates/core_simd/src/simd/num/float.rs+4-4
......@@ -430,14 +430,14 @@ macro_rules! impl_trait {
430430
431431 #[inline]
432432 fn reduce_max(self) -> Self::Scalar {
433 // Safety: `self` is a float vector
434 unsafe { core::intrinsics::simd::simd_reduce_max(self) }
433 // LLVM has no intrinsic we can use here
434 // (https://github.com/llvm/llvm-project/issues/185827).
435 self.as_array().iter().copied().fold(Self::Scalar::NAN, Self::Scalar::max)
435436 }
436437
437438 #[inline]
438439 fn reduce_min(self) -> Self::Scalar {
439 // Safety: `self` is a float vector
440 unsafe { core::intrinsics::simd::simd_reduce_min(self) }
440 self.as_array().iter().copied().fold(Self::Scalar::NAN, Self::Scalar::min)
441441 }
442442 }
443443 )*
library/portable-simd/crates/core_simd/src/simd/prelude.rs+4
......@@ -14,6 +14,10 @@ pub use super::{
1414 simd_swizzle,
1515};
1616
17#[rustfmt::skip]
18#[doc(no_inline)]
19pub use super::{f16x1, f16x2, f16x4, f16x8, f16x16, f16x32, f16x64};
20
1721#[rustfmt::skip]
1822#[doc(no_inline)]
1923pub use super::{f32x1, f32x2, f32x4, f32x8, f32x16, f32x32, f32x64};
library/portable-simd/crates/std_float/tests/float.rs+13-18
......@@ -33,23 +33,6 @@ macro_rules! unary_approx_test {
3333 }
3434}
3535
36macro_rules! binary_approx_test {
37 { $scalar:tt, $($func:tt),+ } => {
38 test_helpers::test_lanes! {
39 $(
40 fn $func<const LANES: usize>() {
41 test_helpers::test_binary_elementwise_approx(
42 &core_simd::simd::Simd::<$scalar, LANES>::$func,
43 &$scalar::$func,
44 &|_, _| true,
45 16,
46 )
47 }
48 )*
49 }
50 }
51}
52
5336macro_rules! ternary_test {
5437 { $scalar:tt, $($func:tt),+ } => {
5538 test_helpers::test_lanes! {
......@@ -76,7 +59,19 @@ macro_rules! impl_tests {
7659
7760 // https://github.com/rust-lang/miri/issues/3555
7861 unary_approx_test! { $scalar, sin, cos, exp, exp2, ln, log2, log10 }
79 binary_approx_test! { $scalar, log }
62
63 // The implementation of log is a.ln() / b.ln(), so there are 2 inexact operations,
64 // hence a larger ulps is needed.
65 test_helpers::test_lanes! {
66 fn log<const LANES: usize>() {
67 test_helpers::test_binary_elementwise_approx(
68 &core_simd::simd::Simd::<$scalar, LANES>::log,
69 &$scalar::log,
70 &|_, _| true,
71 32,
72 )
73 }
74 }
8075
8176 test_helpers::test_lanes! {
8277 fn fract<const LANES: usize>() {
library/portable-simd/crates/test_helpers/src/lib.rs+24-15
......@@ -122,12 +122,23 @@ pub fn make_runner() -> proptest::test_runner::TestRunner {
122122 proptest::test_runner::TestRunner::new(proptest::test_runner::Config::with_cases(4))
123123}
124124
125#[track_caller]
126fn unwrap_test_error<T, U: std::fmt::Debug>(
127 x: Result<T, proptest::test_runner::TestError<U>>,
128) -> T {
129 // Using the `Display` instance of the error is much more readable.
130 match x {
131 Ok(v) => v,
132 Err(e) => panic!("{e}"),
133 }
134}
135
125136/// Test a function that takes a single value.
126137pub fn test_1<A: core::fmt::Debug + DefaultStrategy>(
127138 f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult,
128139) {
129140 let mut runner = make_runner();
130 runner.run(&A::default_strategy(), f).unwrap();
141 unwrap_test_error(runner.run(&A::default_strategy(), f))
131142}
132143
133144/// Test a function that takes two values.
......@@ -135,11 +146,11 @@ pub fn test_2<A: core::fmt::Debug + DefaultStrategy, B: core::fmt::Debug + Defau
135146 f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult,
136147) {
137148 let mut runner = make_runner();
138 runner
139 .run(&(A::default_strategy(), B::default_strategy()), |(a, b)| {
149 unwrap_test_error(
150 runner.run(&(A::default_strategy(), B::default_strategy()), |(a, b)| {
140151 f(a, b)
141 })
142 .unwrap();
152 }),
153 )
143154}
144155
145156/// Test a function that takes two values.
......@@ -151,16 +162,14 @@ pub fn test_3<
151162 f: &dyn Fn(A, B, C) -> proptest::test_runner::TestCaseResult,
152163) {
153164 let mut runner = make_runner();
154 runner
155 .run(
156 &(
157 A::default_strategy(),
158 B::default_strategy(),
159 C::default_strategy(),
160 ),
161 |(a, b, c)| f(a, b, c),
162 )
163 .unwrap();
165 unwrap_test_error(runner.run(
166 &(
167 A::default_strategy(),
168 B::default_strategy(),
169 C::default_strategy(),
170 ),
171 |(a, b, c)| f(a, b, c),
172 ));
164173}
165174
166175/// Test a unary vector function against a unary scalar function, applied elementwise.
library/portable-simd/rust-toolchain.toml+1-1
......@@ -1,3 +1,3 @@
11[toolchain]
2channel = "nightly-2026-03-18"
2channel = "nightly-2026-04-28"
33components = ["rustfmt", "clippy", "miri", "rust-src"]
src/bootstrap/src/core/builder/cargo.rs+2-11
......@@ -687,16 +687,6 @@ impl Builder<'_> {
687687 rustflags.arg(sysroot_str);
688688 }
689689
690 let use_new_symbol_mangling = self.config.rust_new_symbol_mangling.or_else(|| {
691 if mode != Mode::Std {
692 // The compiler and tools default to the new scheme
693 Some(true)
694 } else {
695 // std follows the flag's default, which per compiler-team#938 is v0 on nightly
696 None
697 }
698 });
699
700690 // By default, windows-rs depends on a native library that doesn't get copied into the
701691 // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native
702692 // library unnecessary. This can be removed when windows-rs enables raw-dylib
......@@ -706,7 +696,8 @@ impl Builder<'_> {
706696 rustflags.arg("--cfg=windows_raw_dylib");
707697 }
708698
709 if let Some(usm) = use_new_symbol_mangling {
699 // When unset, follow the default of the compiler flag - the compiler, tools and std use v0
700 if let Some(usm) = self.config.rust_new_symbol_mangling {
710701 rustflags.arg(if usm {
711702 "-Csymbol-mangling-version=v0"
712703 } else {
src/doc/rustc-dev-guide/src/tests/compiletest.md+11
......@@ -346,6 +346,17 @@ See also the [codegen tests](#codegen-tests) for a similar set of tests.
346346If you need to work with `#![no_std]` cross-compiling tests, consult the
347347[`minicore` test auxiliary](./minicore.md) chapter.
348348
349#### Conditional assembly tests based on instruction support
350
351Tests that depend on specific assembly instructions being available can use the
352`//@ needs-asm-mnemonic: <MNEMONIC>` directive. This will skip the test if the
353target backend does not support the specified instruction mnemonic.
354
355For example, a test that requires the `RET` instruction:
356```rust,ignore
357//@ needs-asm-mnemonic: RET
358```
359
349360[`tests/assembly-llvm`]: https://github.com/rust-lang/rust/tree/HEAD/tests/assembly-llvm
350361
351362
src/doc/rustc-dev-guide/src/tests/directives.md+3
......@@ -163,6 +163,9 @@ The following directives will check rustc build settings and target settings:
163163 For tests that cross-compile to explicit targets
164164 via `--target`, use `needs-llvm-components` instead to ensure the appropriate
165165 backend is available.
166- `needs-asm-mnemonic: <MNEMONIC>` — ignores if the target backend does not
167 support the specified assembly mnemonic (e.g., `RET`, `NOP`).
168 Only supported with the LLVM backend.
166169- `needs-profiler-runtime` — ignores the test if the profiler runtime was not
167170 enabled for the target (`build.profiler = true` in `bootstrap.toml`)
168171- `needs-sanitizer-support` — ignores if the sanitizer support was not enabled
src/doc/rustc/src/platform-support/wasm32-wali-linux.md+9-19
......@@ -15,7 +15,7 @@ From the wider Wasm ecosystem perspective, implementing WALI within engines allo
1515## Requirements
1616
1717### Compilation
18This target is cross-compiled and requires an installation of the [WALI compiler/sysroot](https://github.com/arjunr2/WALI). This produces standard `wasm32` binaries with the WALI interface methods as module imports that need to be implemented by a supported engine (see the "Execution" section below).
18This target is cross-compiled and requires an installation of the [WALI sysroot](https://github.com/Wasm-Thin-Kernel-Interfaces/WALI.git). This produces standard `wasm32` binaries with the WALI interface methods as module imports that need to be implemented by a supported engine (see the "Execution" section below).
1919
2020`wali` targets *minimally require* the following LLVM feature flags:
2121
......@@ -31,7 +31,7 @@ This target is cross-compiled and requires an installation of the [WALI compiler
3131> **Note**: Users can expect that new enabled-by-default Wasm features for LLVM are transitively incorporatable into this target -- see [wasm32-unknown-unknown](wasm32-unknown-unknown.md) for detailed information on WebAssembly features.
3232
3333
34> **Note**: The WALI ABI is similar to default Clang wasm32 ABIs but *not identical*. The primary difference is 64-bit `long` types as opposed to 32-bit for wasm32. This is required to maintain minimum source code changes for 64-bit host platforms currently supported. This may change in the future as the spec evolves.
34> **Note**: The WALI ABI is *not identical* to the `wasm32-wasip2` or `wasm32-unknown-unknown` ABI. The primary difference is 64-bit `long` types as opposed to 32-bit for wasm32. This is required to maximize portability with minimum source code changes for currently supported 64-bit host platforms. These ABIs may converge in the future as the spec evolves.
3535
3636### Execution
3737Running generated WALI binaries also requires a supported compliant engine implementation -- a working implementation in the [WebAssembly Micro-Runtime (WAMR)](https://github.com/arjunr2/WALI) is included in the repo.
......@@ -41,38 +41,28 @@ Running generated WALI binaries also requires a supported compliant engine imple
4141## Building the target
4242
4343You can build Rust with support for the target by adding it to the `target`
44list in `config.toml`, and pointing to the toolchain artifacts from the previous section ("Requirements->Compilation"). A sample `config.toml` for the `musl` environment will look like this, where `<WALI-root>` is the absolute path to the root directory of the [WALI repo](https://github.com/arjunr2/WALI):
44list in `bootstrap.toml`, and pointing to the toolchain artifacts from the previous section ("Requirements->Compilation"). A sample `bootstrap.toml` for the `musl` environment will look like this, where `<WALI-root>` is the absolute path to the root directory of the [WALI repo](https://github.com/arjunr2/WALI):
4545
4646```toml
4747[build]
4848target = ["wasm32-wali-linux-musl"]
4949
5050[target.wasm32-wali-linux-musl]
51musl-root = "<WALI>/wali-musl/sysroot"
52llvm-config = "<WALI>/llvm-project/build/bin/llvm-config"
53cc = "<WALI>/llvm-project/build/bin/clang-18"
54cxx = "<WALI>/llvm-project/build/bin/clang-18"
55ar = "<WALI>/llvm-project/build/bin/llvm-ar"
56ranlib = "<WALI>/llvm-project/build/bin/llvm-ranlib"
51musl-root = "<WALI>/build/sysroot"
52cc = "<WALI>/build/llvm/bin/clang"
53cxx = "<WALI>/build/llvm/bin/clang++"
54ar = "<WALI>/build/llvm/bin/llvm-ar"
55ranlib = "<WALI>/build/llvm/bin/llvm-ranlib"
5756llvm-libunwind = "system"
5857crt-static = true
5958```
6059
61> The `llvm-config` settings are only temporary, and the changes will eventually be upstreamed into LLVM
62
6360## Building Rust programs
6461
6562Rust does not yet ship pre-compiled artifacts for this target. To compile for
6663this target, you will either need to build Rust with the target enabled (see
6764"Building the target" above), or build your own copy of `core` by using
68`build-std` or similar.
69
70Rust program builds can use this target normally. Currently, linking WALI programs may require pointing the `linker` to the llvm build in the [Cargo config](https://doc.rust-lang.org/cargo/reference/config.html) (until LLVM is upstreamed). A `config.toml` for Cargo will look like the following:
71
72```toml
73[target.wasm32-wali-linux-musl]
74linker = "<WALI>/llvm-project/build/bin/lld"
75```
65`build-std` or similar (with the appropriate sysroot links).
7666
7767Note that the following `cfg` directives are set for `wasm32-wali-linux-*`:
7868
src/doc/rustc/src/symbol-mangling/index.md+3-4
......@@ -46,7 +46,6 @@ foo::example_function
4646
4747## Mangling versions
4848
49`rustc` supports different mangling versions which encode the names in different ways.
50The legacy version (which is currently the default on beta/stable) is not described here.
51The "v0" mangling scheme addresses several limitations of the legacy format,
52and is described in the [v0 Symbol Format](v0.md) chapter.
49There is currently one stable mangling scheme version - `v0`. On nightly builds, rustc supports
50switching back to the `legacy` mangling scheme using [`-C symbol-mangling-version`]. The `v0`
51mangling scheme is described in the [v0 Symbol Format](v0.md) chapter.
src/doc/unstable-book/src/compiler-flags/sanitizer.md+31
......@@ -246,6 +246,37 @@ Cargo build-std feature (i.e., `-Zbuild-std`) when enabling CFI.
246246
247247See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details.
248248
249## Divergence from the Rust ABI
250
251There are some caveats to [the ABI-compatibility rules for Rust-to-Rust
252calls][rust-abi] due to how the CFI sanitizer is implemented. CFI is a tool
253that can be used to validate that dynamic function calls respect the ABI, but
254due to its C/C++ origins, it disagrees with the above documented guarantees in
255a few ways, see below. As CFI is unstable, the details may change in the
256future.
257
258When running the CFI sanitizer, pointer types are only ABI-compatible if the
259target type and mutability is the same. This means that `*mut String` and `*mut
260i32` are incompatible when using CFI. It also means that `*mut i32` is
261incompatible with `*const i32`. The `NonNull<_>` and `Box<_>` pointer types are
262currently considered immutable under CFI. For non-primitive target types, CFI
263uses the name of the type for its compatibility check.
264
265When not using the `-Zsanitizer-cfi-normalize-integers` flag, the CFI sanitizer
266further restricts the rules by considering `usize`/`isize` incompatible with
267the `uN`/`iN` integer type of the same size.
268
269Unlike other cases where the function ABI is violated, function calls that
270violate the CFI-specific ABI-compatibility rules are not undefined behavior.
271They are guaranteed to either function correctly, or to crash the program.
272
273This section only covers cases where CFI disagrees with the ABI-compatibility
274rules for Rust-to-Rust calls. It is not meant to be a complete explanation of
275how CFI works, and details important for C-to-Rust or Rust-to-C calls are
276omitted.
277
278[rust-abi]: https://doc.rust-lang.org/stable/std/primitive.fn.html#abi-compatibility
279
249280## Example 1: Redirecting control flow using an indirect branch/call to an invalid destination
250281
251282```rust
src/tools/compiletest/src/directives/directive_names.rs+1
......@@ -156,6 +156,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
156156 "min-llvm-version",
157157 "min-system-llvm-version",
158158 "minicore-compile-flags",
159 "needs-asm-mnemonic",
159160 "needs-asm-support",
160161 "needs-backends",
161162 "needs-crate-type",
src/tools/compiletest/src/directives/needs.rs+60
......@@ -290,6 +290,37 @@ pub(super) fn handle_needs(
290290 }
291291 }
292292
293 if name == "needs-asm-mnemonic" {
294 let Some(rest) = ln.value_after_colon() else {
295 return IgnoreDecision::Error {
296 message: "expected `needs-asm-mnemonic` to have a mnemonic name after colon"
297 .to_string(),
298 };
299 };
300
301 if !config.default_codegen_backend.is_llvm() {
302 return IgnoreDecision::Ignore {
303 reason: "skipping test as non-LLVM backend does not support mnemonic queries"
304 .to_string(),
305 };
306 }
307
308 let mnemonic = rest.trim();
309 let has_mnemonic = match mnemonic {
310 "ret" => cache.has_ret_mnemonic,
311 "nop" => cache.has_nop_mnemonic,
312 _ => has_mnemonic(config, mnemonic),
313 };
314
315 if has_mnemonic {
316 return IgnoreDecision::Continue;
317 } else {
318 return IgnoreDecision::Ignore {
319 reason: format!("skipping test as target does not have `{mnemonic}` mnemonic"),
320 };
321 }
322 }
323
293324 if !name.starts_with("needs-") {
294325 return IgnoreDecision::Continue;
295326 }
......@@ -352,6 +383,10 @@ pub(super) struct CachedNeedsConditions {
352383 symlinks: bool,
353384 /// Whether LLVM built with zstd, for the `needs-llvm-zstd` directive.
354385 llvm_zstd: bool,
386 /// Might add particular other mnemonics heavily needed by tests here.
387 /// Otherwise call into llvm for every check
388 has_ret_mnemonic: bool,
389 has_nop_mnemonic: bool,
355390}
356391
357392impl CachedNeedsConditions {
......@@ -399,6 +434,8 @@ impl CachedNeedsConditions {
399434 llvm_zstd: llvm_has_zstd(&config),
400435 dlltool: find_dlltool(&config),
401436 symlinks: has_symlinks(),
437 has_ret_mnemonic: has_mnemonic(config, "ret"),
438 has_nop_mnemonic: has_mnemonic(config, "nop"),
402439 }
403440 }
404441}
......@@ -466,3 +503,26 @@ fn llvm_has_zstd(config: &Config) -> bool {
466503 _ => panic!("unexpected output from `--print=backend-has-zstd`: {output:?}"),
467504 }
468505}
506
507fn has_mnemonic(config: &Config, mnemonic: &str) -> bool {
508 if !config.default_codegen_backend.is_llvm() {
509 return false;
510 }
511
512 let target_flag = format!("--target={}", config.target);
513 let output = query_rustc_output(
514 config,
515 &[
516 &target_flag,
517 "-Zunstable-options",
518 &format!("--print=backend-has-mnemonic:{}", mnemonic),
519 ],
520 Default::default(),
521 );
522
523 match output.trim() {
524 "true" => true,
525 "false" => false,
526 _ => panic!("unexpected output from `--print=backend-has-mnemonic:{mnemonic}`: {output:?}"),
527 }
528}
src/tools/compiletest/src/directives/tests.rs+22
......@@ -1254,3 +1254,25 @@ fn test_edition_range_edition_to_test() {
12541254 assert_edition_to_test(2018, range, Some(e2024));
12551255 assert_edition_to_test(2018, range, Some(efuture));
12561256}
1257
1258#[test]
1259fn needs_asm_mnemonic() {
1260 let config_x86_64 = cfg().target("x86_64-unknown-linux-gnu").build();
1261 let config_aarch64 = cfg().target("aarch64-unknown-linux-gnu").build();
1262
1263 // invalid mnemonic
1264 assert!(check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:GRUGGY"));
1265 assert!(check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:gruggy"));
1266
1267 // valid x86 and aarch64
1268 assert!(!check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:RET"));
1269 assert!(!check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:ret"));
1270
1271 // this is aarch64 specific
1272 assert!(check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:ldrsbwui"));
1273 assert!(!check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:LDRSBWui"));
1274
1275 // this is x86 specific
1276 assert!(check_ignore(&config_aarch64, "//@ needs-asm-mnemonic:CMPxCHG16B"));
1277 assert!(!check_ignore(&config_x86_64, "//@ needs-asm-mnemonic:CMPXchg16B"));
1278}
src/tools/compiletest/src/runtest.rs-14
......@@ -319,20 +319,6 @@ impl<'test> TestCx<'test> {
319319 TestMode::RustdocJs => true,
320320 TestMode::Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build),
321321 TestMode::Crashes => false,
322 TestMode::Incremental => {
323 let revision =
324 self.revision.expect("incremental tests require a list of revisions");
325 if revision.starts_with("cpass")
326 || revision.starts_with("bpass")
327 || revision.starts_with("rpass")
328 {
329 true
330 } else if revision.starts_with("bfail") {
331 false
332 } else {
333 panic!("revision name must begin with `cpass`, `bfail`, `bpass`, or `rpass`");
334 }
335 }
336322 mode => panic!("unimplemented for mode {:?}", mode),
337323 }
338324 }
src/tools/compiletest/src/runtest/incremental.rs+89-77
......@@ -1,26 +1,43 @@
1use super::{Emit, FailMode, PassMode, ProcRes, TestCx, WillExecute};
1use std::sync::LazyLock;
2
3use crate::runtest::{Emit, TestCx, WillExecute};
4use crate::util::string_enum;
5
6string_enum!(
7 /// How far an incremental test revision should proceed through the compile/run
8 /// sequence, and whether the last step should succeed or fail, as determined
9 /// from the start of the revision name.
10 #[derive(Clone, Copy, PartialEq, Eq)]
11 enum IncrRevKind {
12 CheckPass => "cpass",
13 BuildFail => "bfail",
14 BuildPass => "bpass",
15 RunPass => "rpass",
16 }
17);
18
19impl IncrRevKind {
20 fn for_revision_name(rev_name: &str) -> Result<Self, &'static str> {
21 static MESSAGE: LazyLock<String> = LazyLock::new(|| {
22 let values = IncrRevKind::STR_VARIANTS
23 .iter()
24 .map(|s| format!("`{s}`"))
25 .collect::<Vec<_>>()
26 .join(", ");
27 format!("incremental revision name must begin with one of: {values}")
28 });
29
30 IncrRevKind::VARIANTS
31 .iter()
32 .copied()
33 .find(|kind| rev_name.starts_with(kind.to_str()))
34 .ok_or_else(|| MESSAGE.as_str())
35 }
36}
237
338impl TestCx<'_> {
39 /// Runs a single revision of an incremental test.
440 pub(super) fn run_incremental_test(&self) {
5 // Basic plan for a test incremental/foo/bar.rs:
6 // - load list of revisions rpass1, bfail2, rpass3
7 // - each should begin with `bfail`, `bpass`, or `rpass`
8 // - if `bfail`, expect compilation to fail
9 // - if `bpass`, expect compilation to succeed, don't execute
10 // - if `rpass`, expect compilation and execution to succeed
11 // - create a directory build/foo/bar.incremental
12 // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
13 // - because name of revision starts with "rpass", expect success
14 // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C bfail2
15 // - because name of revision starts with "bfail", expect an error
16 // - load expected errors as usual, but filter for those with `[bfail2]`
17 // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass3
18 // - because name of revision starts with "rpass", expect success
19 // - execute build/foo/bar.exe and save output
20 //
21 // FIXME -- use non-incremental mode as an oracle? That doesn't apply
22 // to #[rustc_clean] tests I guess
23
2441 let revision = self.revision.expect("incremental tests require a list of revisions");
2542
2643 // Incremental workproduct directory should have already been created.
......@@ -31,68 +48,63 @@ impl TestCx<'_> {
3148 write!(self.stdout, "revision={:?} props={:#?}", revision, self.props);
3249 }
3350
34 if revision.starts_with("cpass") {
35 self.run_cpass_test();
36 } else if revision.starts_with("bpass") {
37 self.run_bpass_test();
38 } else if revision.starts_with("rpass") {
39 self.run_rpass_test();
40 } else if revision.starts_with("bfail") {
41 self.run_bfail_test();
42 } else {
43 self.fatal("revision name must begin with `bfail`, `bpass`, or `rpass`");
51 // Determine the revision kind from the revision name.
52 // The revision kind should be matched exhaustively to ensure that no cases are missed.
53 let rev_kind = IncrRevKind::for_revision_name(revision).unwrap_or_else(|e| self.fatal(e));
54
55 // Compile the test for this revision.
56 let emit = match rev_kind {
57 IncrRevKind::CheckPass => Emit::Metadata, // Do a check build.
58 IncrRevKind::BuildFail | IncrRevKind::BuildPass | IncrRevKind::RunPass => Emit::None,
59 };
60 let will_execute = match rev_kind {
61 IncrRevKind::CheckPass | IncrRevKind::BuildFail | IncrRevKind::BuildPass => {
62 WillExecute::No
63 }
64 IncrRevKind::RunPass => {
65 // Yes, unless running test binaries is disabled.
66 self.run_if_enabled()
67 }
68 };
69 let proc_res = &self.compile_test(will_execute, emit);
70
71 // Check the compiler's exit status.
72 match rev_kind {
73 IncrRevKind::CheckPass | IncrRevKind::BuildPass | IncrRevKind::RunPass => {
74 // Compilation should have succeeded.
75 if !proc_res.status.success() {
76 self.fatal_proc_rec("test compilation failed although it shouldn't!", proc_res);
77 }
78 }
79
80 IncrRevKind::BuildFail => {
81 // Compilation should have failed, with the expected status code.
82 if proc_res.status.success() {
83 self.fatal_proc_rec("incremental test did not emit an error", proc_res);
84 }
85 if !self.props.dont_check_failure_status {
86 self.check_correct_failure_status(proc_res);
87 }
88 }
4489 }
45 }
46
47 fn run_cpass_test(&self) {
48 let proc_res = self.compile_test(WillExecute::No, Emit::Metadata);
49 self.check_if_test_should_compile(None, Some(PassMode::Check), &proc_res);
50 self.check_compiler_output_for_incr(&proc_res);
51 }
52
53 fn run_bpass_test(&self) {
54 let emit_metadata = self.should_emit_metadata(self.pass_mode());
55 let proc_res = self.compile_test(WillExecute::No, emit_metadata);
56
57 if !proc_res.status.success() {
58 self.fatal_proc_rec("compilation failed!", &proc_res);
59 }
60
61 self.check_compiler_output_for_incr(&proc_res);
62 }
63
64 fn run_rpass_test(&self) {
65 let emit_metadata = self.should_emit_metadata(self.pass_mode());
66 let should_run = self.run_if_enabled();
67 let proc_res = self.compile_test(should_run, emit_metadata);
6890
69 if !proc_res.status.success() {
70 self.fatal_proc_rec("compilation failed!", &proc_res);
71 }
72
73 self.check_compiler_output_for_incr(&proc_res);
74
75 if let WillExecute::Disabled = should_run {
76 return;
77 }
78
79 let proc_res = self.exec_compiled_test();
80 if !proc_res.status.success() {
81 self.fatal_proc_rec("test run failed!", &proc_res);
82 }
83 }
84
85 fn run_bfail_test(&self) {
86 let pm = self.pass_mode();
87 let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
88 self.check_if_test_should_compile(Some(FailMode::Build), pm, &proc_res);
89 self.check_compiler_output_for_incr(&proc_res);
90 }
91
92 fn check_compiler_output_for_incr(&self, proc_res: &ProcRes) {
91 // Check compilation output.
9392 let output_to_check = self.get_output(proc_res);
9493 self.check_expected_errors(&proc_res);
9594 self.check_all_error_patterns(&output_to_check, proc_res);
9695 self.check_forbid_output(&output_to_check, proc_res);
96
97 // Run the binary and check its exit status, if appropriate.
98 match rev_kind {
99 IncrRevKind::CheckPass | IncrRevKind::BuildFail | IncrRevKind::BuildPass => {}
100 IncrRevKind::RunPass => {
101 if self.config.run_enabled() {
102 let run_proc_res = self.exec_compiled_test();
103 if !run_proc_res.status.success() {
104 self.fatal_proc_rec("test run failed!", &run_proc_res);
105 }
106 }
107 }
108 }
97109 }
98110}
tests/codegen-llvm/function-arguments.rs+1-1
......@@ -297,7 +297,7 @@ pub fn return_slice(x: &[u16]) -> &[u16] {
297297 x
298298}
299299
300// CHECK: { i16, i16 } @enum_id_1(i16 noundef{{( range\(i16 0, 3\))?}} %x.0, i16 %x.1)
300// CHECK: { i16, i16 } @enum_id_1(i16 noundef{{( range\(i16 -1, 2\))?}} %x.0, i16 %x.1)
301301#[no_mangle]
302302pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> {
303303 x
tests/run-make/naked-dead-code-elimination/rmake.rs+1
......@@ -1,5 +1,6 @@
11//@ ignore-cross-compile
22//@ needs-asm-support
3//@ needs-asm-mnemonic: RET
34
45use run_make_support::symbols::object_contains_any_symbol;
56use run_make_support::{bin_name, rustc};
tests/run-make/print-request-help-stable-unstable/help-diff.diff+1-1
......@@ -2,6 +2,6 @@
22 error: unknown print request: `xxx`
33 |
44- = help: valid print requests are: `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `tls-models`
5+ = help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
5+ = help: valid print requests are: `all-target-specs-json`, `backend-has-mnemonic`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
66 = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
77
tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err+1-1
......@@ -1,5 +1,5 @@
11error: unknown print request: `xxx`
22 |
3 = help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
3 = help: valid print requests are: `all-target-specs-json`, `backend-has-mnemonic`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
44 = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
55
tests/run-make/rustc-help/help-v.stdout+1-1
......@@ -43,7 +43,7 @@ Options:
4343 --print <INFO>[=<FILE>]
4444 Compiler information to print on stdout (or to a file)
4545 INFO may be one of
46 <all-target-specs-json|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
46 <all-target-specs-json|backend-has-mnemonic|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
4747 -g Equivalent to -C debuginfo=2
4848 -O Equivalent to -C opt-level=3
4949 -o <FILENAME> Write output to FILENAME
tests/run-make/rustc-help/help.stdout+1-1
......@@ -43,7 +43,7 @@ Options:
4343 --print <INFO>[=<FILE>]
4444 Compiler information to print on stdout (or to a file)
4545 INFO may be one of
46 <all-target-specs-json|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
46 <all-target-specs-json|backend-has-mnemonic|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
4747 -g Equivalent to -C debuginfo=2
4848 -O Equivalent to -C opt-level=3
4949 -o <FILENAME> Write output to FILENAME
tests/ui/compile-flags/invalid/print-without-arg.stderr+1-1
......@@ -3,5 +3,5 @@ error: Argument to option 'print' missing
33 --print <INFO>[=<FILE>]
44 Compiler information to print on stdout (or to a file)
55 INFO may be one of
6 <all-target-specs-json|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
6 <all-target-specs-json|backend-has-mnemonic|backend-has-zstd|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
77
tests/ui/compile-flags/invalid/print.stderr+1-1
......@@ -1,5 +1,5 @@
11error: unknown print request: `yyyy`
22 |
3 = help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
3 = help: valid print requests are: `all-target-specs-json`, `backend-has-mnemonic`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
44 = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
55
tests/ui/consts/const-closure-hkl.rs created+20
......@@ -0,0 +1,20 @@
1//! Regression test for hkl const closures not working in old solver
2
3//@ check-pass
4//@ revisions: current next
5//@ ignore-compare-mode-next-solver (explicit revisions)
6//@[next] compile-flags: -Znext-solver
7
8#![feature(const_trait_impl)]
9#![feature(const_closures)]
10const fn partial_compare() {
11 let len_chain = const move |_a: &_, _b: &_| {};
12
13 chaining_impl(len_chain);
14}
15
16const fn chaining_impl(x: impl for<'a> [const] FnOnce(&'a usize, &'a usize)) {
17 std::mem::forget(x);
18}
19
20fn main() {}
tests/ui/let-else/let-else-irrefutable-152938.rs+1-1
......@@ -6,7 +6,7 @@
66
77pub fn say_hello(name: Option<String>) {
88 let name_str = Some(name) else { return; };
9 //~^ WARN irrefutable `let...else` pattern
9 //~^ WARN unreachable `else` clause
1010 drop(name_str);
1111}
1212
tests/ui/let-else/let-else-irrefutable-152938.stderr+10-8
......@@ -1,16 +1,18 @@
1warning: irrefutable `let...else` pattern
2 --> $DIR/let-else-irrefutable-152938.rs:8:5
1warning: unreachable `else` clause
2 --> $DIR/let-else-irrefutable-152938.rs:8:31
33 |
44LL | let name_str = Some(name) else { return; };
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^
5 | ------------------------- ^^^^
6 | |
7 | assigning to binding pattern will always succeed
68 |
79 = note: this pattern always matches, so the else clause is unreachable
8help: remove this `else` block
9 --> $DIR/let-else-irrefutable-152938.rs:8:36
10 |
11LL | let name_str = Some(name) else { return; };
12 | ^^^^^^^^^^^
1310 = note: `#[warn(irrefutable_let_patterns)]` on by default
11help: consider using `let Some(name_str) = name` to match on a specific variant
12 |
13LL - let name_str = Some(name) else { return; };
14LL + let Some(name_str) = name else { return; };
15 |
1416
1517warning: 1 warning emitted
1618
tests/ui/let-else/let-else-irrefutable.rs+10-2
......@@ -1,10 +1,18 @@
11//@ check-pass
22
33fn main() {
4 let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
4 let x = 1 else { return }; //~ WARN unreachable `else` clause
55
66 // Multiline else blocks should not get printed
7 let x = 1 else { //~ WARN irrefutable `let...else` pattern
7 let x = 1 else { //~ WARN unreachable `else` clause
8 eprintln!("problem case encountered");
9 return
10 };
11
12 let case = Some("a");
13 let name = Some(case) else {
14 //~^ WARN unreachable `else` clause
15 //~| HELP consider using `let Some(name) = case` to match on a specific variant
816 eprintln!("problem case encountered");
917 return
1018 };
tests/ui/let-else/let-else-irrefutable.stderr+26-21
......@@ -1,33 +1,38 @@
1warning: irrefutable `let...else` pattern
2 --> $DIR/let-else-irrefutable.rs:4:5
1warning: unreachable `else` clause
2 --> $DIR/let-else-irrefutable.rs:4:15
33 |
44LL | let x = 1 else { return };
5 | ^^^^^^^^^
5 | --------- ^^^^
6 | |
7 | assigning to binding pattern will always succeed
68 |
79 = note: this pattern always matches, so the else clause is unreachable
8help: remove this `else` block
9 --> $DIR/let-else-irrefutable.rs:4:20
10 |
11LL | let x = 1 else { return };
12 | ^^^^^^^^^^
1310 = note: `#[warn(irrefutable_let_patterns)]` on by default
1411
15warning: irrefutable `let...else` pattern
16 --> $DIR/let-else-irrefutable.rs:7:5
12warning: unreachable `else` clause
13 --> $DIR/let-else-irrefutable.rs:7:15
1714 |
1815LL | let x = 1 else {
19 | ^^^^^^^^^
16 | --------- ^^^^
17 | |
18 | assigning to binding pattern will always succeed
19 |
20 = note: this pattern always matches, so the else clause is unreachable
21
22warning: unreachable `else` clause
23 --> $DIR/let-else-irrefutable.rs:13:27
24 |
25LL | let name = Some(case) else {
26 | --------------------- ^^^^
27 | |
28 | assigning to binding pattern will always succeed
2029 |
2130 = note: this pattern always matches, so the else clause is unreachable
22help: remove this `else` block
23 --> $DIR/let-else-irrefutable.rs:7:20
24 |
25LL | let x = 1 else {
26 | ____________________^
27LL | | eprintln!("problem case encountered");
28LL | | return
29LL | | };
30 | |_____^
31help: consider using `let Some(name) = case` to match on a specific variant
32 |
33LL - let name = Some(case) else {
34LL + let Some(name) = case else {
35 |
3136
32warning: 2 warnings emitted
37warning: 3 warnings emitted
3338
tests/ui/parser/bad-let-else-statement.rs+8-8
......@@ -93,10 +93,10 @@ fn i() {
9393fn j() {
9494 let mut bar = 0;
9595 let foo = bar = {
96 //~^ WARN irrefutable `let...else` pattern
9796 1
9897 } else {
99 //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
98 //~^ WARN unreachable `else` clause
99 //~| ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
100100 return;
101101 };
102102}
......@@ -158,21 +158,21 @@ fn o() -> Result<(), ()> {
158158
159159fn q() {
160160 let foo = |x: i32| {
161 //~^ WARN irrefutable `let...else` pattern
162161 x
163162 } else {
164 //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
163 //~^ WARN unreachable `else` clause
164 //~| ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
165165 return;
166166 };
167167}
168168
169169fn r() {
170170 let ok = format_args!("") else { return; };
171 //~^ WARN irrefutable `let...else` pattern
171 //~^ WARN unreachable `else` clause
172172
173173 let bad = format_args! {""} else { return; };
174174 //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
175 //~| WARN irrefutable `let...else` pattern
175 //~| WARN unreachable `else` clause
176176}
177177
178178fn s() {
......@@ -202,10 +202,10 @@ fn t() {
202202 }
203203
204204 let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! {
205 //~^ WARN irrefutable `let...else` pattern
206205 8
207206 } else {
208 //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
207 //~^ WARN unreachable `else` clause
208 //~| ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
209209 return;
210210 };
211211}
tests/ui/parser/bad-let-else-statement.stderr+28-61
......@@ -125,7 +125,7 @@ LL ~ }) else {
125125 |
126126
127127error: right curly brace `}` before `else` in a `let...else` statement not allowed
128 --> $DIR/bad-let-else-statement.rs:98:5
128 --> $DIR/bad-let-else-statement.rs:97:5
129129 |
130130LL | } else {
131131 | ^
......@@ -133,7 +133,6 @@ LL | } else {
133133help: wrap the expression in parentheses
134134 |
135135LL ~ let foo = bar = ({
136LL |
137136LL | 1
138137LL ~ }) else {
139138 |
......@@ -204,7 +203,7 @@ LL ~ }) else {
204203 |
205204
206205error: right curly brace `}` before `else` in a `let...else` statement not allowed
207 --> $DIR/bad-let-else-statement.rs:163:5
206 --> $DIR/bad-let-else-statement.rs:162:5
208207 |
209208LL | } else {
210209 | ^
......@@ -212,7 +211,6 @@ LL | } else {
212211help: wrap the expression in parentheses
213212 |
214213LL ~ let foo = |x: i32| ({
215LL |
216214LL | x
217215LL ~ }) else {
218216 |
......@@ -230,7 +228,7 @@ LL + let bad = format_args! ("") else { return; };
230228 |
231229
232230error: right curly brace `}` before `else` in a `let...else` statement not allowed
233 --> $DIR/bad-let-else-statement.rs:207:5
231 --> $DIR/bad-let-else-statement.rs:206:5
234232 |
235233LL | } else {
236234 | ^
......@@ -238,7 +236,6 @@ LL | } else {
238236help: use parentheses instead of braces for this macro
239237 |
240238LL ~ let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! (
241LL |
242239LL | 8
243240LL ~ ) else {
244241 |
......@@ -259,92 +256,62 @@ LL - let 0 = a! {} else { return; };
259256LL + let 0 = a! () else { return; };
260257 |
261258
262warning: irrefutable `let...else` pattern
263 --> $DIR/bad-let-else-statement.rs:95:5
259warning: unreachable `else` clause
260 --> $DIR/bad-let-else-statement.rs:97:7
264261 |
265262LL | / let foo = bar = {
266LL | |
267263LL | | 1
268264LL | | } else {
269 | |_____^
265 | | - ^^^^
266 | |_____|
267 | assigning to binding pattern will always succeed
270268 |
271269 = note: this pattern always matches, so the else clause is unreachable
272help: remove this `else` block
273 --> $DIR/bad-let-else-statement.rs:98:12
274 |
275LL | } else {
276 | ____________^
277LL | |
278LL | | return;
279LL | | };
280 | |_____^
281270 = note: `#[warn(irrefutable_let_patterns)]` on by default
282271
283warning: irrefutable `let...else` pattern
284 --> $DIR/bad-let-else-statement.rs:160:5
272warning: unreachable `else` clause
273 --> $DIR/bad-let-else-statement.rs:162:7
285274 |
286275LL | / let foo = |x: i32| {
287LL | |
288276LL | | x
289277LL | | } else {
290 | |_____^
278 | | - ^^^^
279 | |_____|
280 | assigning to binding pattern will always succeed
291281 |
292282 = note: this pattern always matches, so the else clause is unreachable
293help: remove this `else` block
294 --> $DIR/bad-let-else-statement.rs:163:12
295 |
296LL | } else {
297 | ____________^
298LL | |
299LL | | return;
300LL | | };
301 | |_____^
302283
303warning: irrefutable `let...else` pattern
304 --> $DIR/bad-let-else-statement.rs:170:5
284warning: unreachable `else` clause
285 --> $DIR/bad-let-else-statement.rs:170:31
305286 |
306287LL | let ok = format_args!("") else { return; };
307 | ^^^^^^^^^^^^^^^^^^^^^^^^^
288 | ------------------------- ^^^^
289 | |
290 | assigning to binding pattern will always succeed
308291 |
309292 = note: this pattern always matches, so the else clause is unreachable
310help: remove this `else` block
311 --> $DIR/bad-let-else-statement.rs:170:36
312 |
313LL | let ok = format_args!("") else { return; };
314 | ^^^^^^^^^^^
315293
316warning: irrefutable `let...else` pattern
317 --> $DIR/bad-let-else-statement.rs:173:5
294warning: unreachable `else` clause
295 --> $DIR/bad-let-else-statement.rs:173:33
318296 |
319297LL | let bad = format_args! {""} else { return; };
320 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
298 | --------------------------- ^^^^
299 | |
300 | assigning to binding pattern will always succeed
321301 |
322302 = note: this pattern always matches, so the else clause is unreachable
323help: remove this `else` block
324 --> $DIR/bad-let-else-statement.rs:173:38
325 |
326LL | let bad = format_args! {""} else { return; };
327 | ^^^^^^^^^^^
328303
329warning: irrefutable `let...else` pattern
330 --> $DIR/bad-let-else-statement.rs:204:5
304warning: unreachable `else` clause
305 --> $DIR/bad-let-else-statement.rs:206:7
331306 |
332307LL | / let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! {
333LL | |
334308LL | | 8
335309LL | | } else {
336 | |_____^
310 | | - ^^^^
311 | |_____|
312 | assigning to binding pattern will always succeed
337313 |
338314 = note: this pattern always matches, so the else clause is unreachable
339help: remove this `else` block
340 --> $DIR/bad-let-else-statement.rs:207:12
341 |
342LL | } else {
343 | ____________^
344LL | |
345LL | | return;
346LL | | };
347 | |_____^
348315
349316error: aborting due to 19 previous errors; 5 warnings emitted
350317
tests/ui/print-request/print-lints-help.stderr+1-1
......@@ -1,6 +1,6 @@
11error: unknown print request: `lints`
22 |
3 = help: valid print requests are: `all-target-specs-json`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
3 = help: valid print requests are: `all-target-specs-json`, `backend-has-mnemonic`, `backend-has-zstd`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
44 = help: use `-Whelp` to print a list of lints
55 = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
66
tests/ui/span/let-offset-of.rs+1-1
......@@ -15,5 +15,5 @@ fn init_to_offset_of() {
1515 //~^ WARN irrefutable `if let` pattern
1616
1717 let x = offset_of!(Foo, field) else { return; };
18 //~^ WARN irrefutable `let...else` pattern
18 //~^ WARN unreachable `else` clause
1919}
tests/ui/span/let-offset-of.stderr+5-8
......@@ -8,18 +8,15 @@ LL | if let x = offset_of!(Foo, field) {}
88 = help: consider replacing the `if let` with a `let`
99 = note: `#[warn(irrefutable_let_patterns)]` on by default
1010
11warning: irrefutable `let...else` pattern
12 --> $DIR/let-offset-of.rs:17:5
11warning: unreachable `else` clause
12 --> $DIR/let-offset-of.rs:17:36
1313 |
1414LL | let x = offset_of!(Foo, field) else { return; };
15 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15 | ------------------------------ ^^^^
16 | |
17 | assigning to binding pattern will always succeed
1618 |
1719 = note: this pattern always matches, so the else clause is unreachable
18help: remove this `else` block
19 --> $DIR/let-offset-of.rs:17:41
20 |
21LL | let x = offset_of!(Foo, field) else { return; };
22 | ^^^^^^^^^^^
2320
2421warning: 2 warnings emitted
2522
triagebot.toml-4
......@@ -940,10 +940,6 @@ Issue #{number} "{title}" has been added.
940940# Mentions
941941# ------------------------------------------------------------------------------
942942
943[mentions."triagebot.toml"]
944message = "`triagebot.toml` has been modified, there may have been changes to the review queue."
945cc = ["@davidtwco", "@wesleywiser"]
946
947943[mentions."compiler/rustc_codegen_cranelift"]
948944message = "The Cranelift subtree was changed"
949945cc = ["@bjorn3"]