| author | bors <bors@rust-lang.org> 2026-04-28 19:00:23 UTC |
| committer | bors <bors@rust-lang.org> 2026-04-28 19:00:23 UTC |
| log | 37d85e592f9ae5f20f7d9a9f99785246fa7298da |
| tree | ca150ed2ae434943dfad44c19c85385a8578d98f |
| parent | 03c609abb6638f9d7f49f34326d4137d07f5cd61 |
| parent | 4dd31caab6e9fc3b3e51245cab809428a9f3d7ca |
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 { |
| 2084 | 2084 | let distance_end_zero = max_value - v.end; |
| 2085 | 2085 | // FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation |
| 2086 | 2086 | // <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 { | |
| 2088 | 2089 | // We only need one, so just pick the one closest to zero. |
| 2089 | 2090 | // Not only does that obviously use zero if it's possible, but it also |
| 2090 | 2091 | // 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>( |
| 224 | 224 | |
| 225 | 225 | match cx.sess.psess.check_config.expecteds.get(&name) { |
| 226 | 226 | Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => cx |
| 227 | .emit_dyn_lint_with_sess( | |
| 227 | .emit_lint_with_sess( | |
| 228 | 228 | UNEXPECTED_CFGS, |
| 229 | 229 | move |dcx, level, sess| { |
| 230 | 230 | check_cfg::unexpected_cfg_value(sess, (name, name_span), value) |
| ... | ... | @@ -232,7 +232,7 @@ pub(crate) fn parse_name_value<S: Stage>( |
| 232 | 232 | }, |
| 233 | 233 | span, |
| 234 | 234 | ), |
| 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( | |
| 236 | 236 | UNEXPECTED_CFGS, |
| 237 | 237 | move |dcx, level, sess| { |
| 238 | 238 | 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 { |
| 67 | 67 | None, |
| 68 | 68 | ); |
| 69 | 69 | let span = n.value_span; |
| 70 | cx.emit_dyn_lint( | |
| 70 | cx.emit_lint( | |
| 71 | 71 | UNKNOWN_CRATE_TYPES, |
| 72 | 72 | move |dcx, level| { |
| 73 | 73 | 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 { |
| 24 | 24 | fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { |
| 25 | 25 | let attr_span = cx.attr_span; |
| 26 | 26 | if !matches!(args, ArgParser::NoArgs) { |
| 27 | cx.emit_dyn_lint( | |
| 27 | cx.emit_lint( | |
| 28 | 28 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 29 | 29 | |dcx, level| crate::errors::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level), |
| 30 | 30 | attr_span, |
| ... | ... | @@ -33,7 +33,7 @@ impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser { |
| 33 | 33 | |
| 34 | 34 | if !matches!(cx.target, Target::Impl { of_trait: true }) { |
| 35 | 35 | let target_span = cx.target_span; |
| 36 | cx.emit_dyn_lint( | |
| 36 | cx.emit_lint( | |
| 37 | 37 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, |
| 38 | 38 | move |dcx, level| { |
| 39 | 39 | 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>( |
| 140 | 140 | (Some(_) | None, None) => {} |
| 141 | 141 | (Some((first_span, _)), Some((later_span, _))) => { |
| 142 | 142 | let first_span = *first_span; |
| 143 | cx.emit_dyn_lint( | |
| 143 | cx.emit_lint( | |
| 144 | 144 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 145 | 145 | move |dcx, level| { |
| 146 | 146 | IgnoredDiagnosticOption { first_span, later_span, option_name } |
| ... | ... | @@ -167,14 +167,14 @@ fn parse_list<'p, S: Stage>( |
| 167 | 167 | // We're dealing with `#[diagnostic::attr()]`. |
| 168 | 168 | // This can be because that is what the user typed, but that's also what we'd see |
| 169 | 169 | // if the user used non-metaitem syntax. See `ArgParser::from_attr_args`. |
| 170 | cx.emit_dyn_lint( | |
| 170 | cx.emit_lint( | |
| 171 | 171 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 172 | 172 | move |dcx, level| NonMetaItemDiagnosticAttribute.into_diag(dcx, level), |
| 173 | 173 | list.span, |
| 174 | 174 | ); |
| 175 | 175 | } |
| 176 | 176 | ArgParser::NoArgs => { |
| 177 | cx.emit_dyn_lint( | |
| 177 | cx.emit_lint( | |
| 178 | 178 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 179 | 179 | move |dcx, level| { |
| 180 | 180 | MissingOptionsForDiagnosticAttribute { |
| ... | ... | @@ -187,7 +187,7 @@ fn parse_list<'p, S: Stage>( |
| 187 | 187 | ); |
| 188 | 188 | } |
| 189 | 189 | ArgParser::NameValue(_) => { |
| 190 | cx.emit_dyn_lint( | |
| 190 | cx.emit_lint( | |
| 191 | 191 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 192 | 192 | move |dcx, level| { |
| 193 | 193 | MalFormedDiagnosticAttributeLint { |
| ... | ... | @@ -221,7 +221,7 @@ fn parse_directive_items<'p, S: Stage>( |
| 221 | 221 | let span = item.span(); |
| 222 | 222 | |
| 223 | 223 | macro malformed() {{ |
| 224 | cx.emit_dyn_lint( | |
| 224 | cx.emit_lint( | |
| 225 | 225 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 226 | 226 | move |dcx, level| { |
| 227 | 227 | MalFormedDiagnosticAttributeLint { |
| ... | ... | @@ -249,7 +249,7 @@ fn parse_directive_items<'p, S: Stage>( |
| 249 | 249 | |
| 250 | 250 | macro duplicate($name: ident, $($first_span:tt)*) {{ |
| 251 | 251 | let first_span = $($first_span)*; |
| 252 | cx.emit_dyn_lint( | |
| 252 | cx.emit_lint( | |
| 253 | 253 | MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
| 254 | 254 | move |dcx, level| IgnoredDiagnosticOption { |
| 255 | 255 | first_span, |
| ... | ... | @@ -285,7 +285,7 @@ fn parse_directive_items<'p, S: Stage>( |
| 285 | 285 | | FormatWarning::PositionalArgument { span } |
| 286 | 286 | | FormatWarning::IndexedArgument { span } |
| 287 | 287 | | FormatWarning::DisallowedPlaceholder { span, .. }) = warning; |
| 288 | cx.emit_dyn_lint( | |
| 288 | cx.emit_lint( | |
| 289 | 289 | MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, |
| 290 | 290 | move |dcx, level| warning.into_diag(dcx, level), |
| 291 | 291 | span, |
| ... | ... | @@ -295,7 +295,7 @@ fn parse_directive_items<'p, S: Stage>( |
| 295 | 295 | f |
| 296 | 296 | } |
| 297 | 297 | Err(e) => { |
| 298 | cx.emit_dyn_lint( | |
| 298 | cx.emit_lint( | |
| 299 | 299 | MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, |
| 300 | 300 | move |dcx, level| { |
| 301 | 301 | WrappedParserError { |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs+1-1| ... | ... | @@ -28,7 +28,7 @@ impl<S: Stage> AttributeParser<S> for OnConstParser { |
| 28 | 28 | // so non-constness is still checked in check_attr.rs |
| 29 | 29 | if !matches!(cx.target, Target::Impl { of_trait: true }) { |
| 30 | 30 | let target_span = cx.target_span; |
| 31 | cx.emit_dyn_lint( | |
| 31 | cx.emit_lint( | |
| 32 | 32 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, |
| 33 | 33 | move |dcx, level| { |
| 34 | 34 | 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 { |
| 33 | 33 | self.span = Some(span); |
| 34 | 34 | |
| 35 | 35 | if !matches!(cx.target, Target::Enum | Target::Struct | Target::Union) { |
| 36 | cx.emit_dyn_lint( | |
| 36 | cx.emit_lint( | |
| 37 | 37 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, |
| 38 | 38 | move |dcx, level| DiagnosticOnMoveOnlyForAdt.into_diag(dcx, level), |
| 39 | 39 | span, |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs+1-1| ... | ... | @@ -23,7 +23,7 @@ impl OnUnimplementedParser { |
| 23 | 23 | self.span = Some(span); |
| 24 | 24 | |
| 25 | 25 | if !matches!(cx.target, Target::Trait) { |
| 26 | cx.emit_dyn_lint( | |
| 26 | cx.emit_lint( | |
| 27 | 27 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, |
| 28 | 28 | move |dcx, level| DiagnosticOnUnimplementedOnlyForTraits.into_diag(dcx, level), |
| 29 | 29 | span, |
compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs+1-1| ... | ... | @@ -35,7 +35,7 @@ impl OnUnknownParser { |
| 35 | 35 | |
| 36 | 36 | if !early && !matches!(cx.target, Target::Use) { |
| 37 | 37 | let target_span = cx.target_span; |
| 38 | cx.emit_dyn_lint( | |
| 38 | cx.emit_lint( | |
| 39 | 39 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, |
| 40 | 40 | move |dcx, level| { |
| 41 | 41 | 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 { |
| 25 | 25 | this.span = Some(span); |
| 26 | 26 | |
| 27 | 27 | if !matches!(cx.target, Target::MacroDef) { |
| 28 | cx.emit_dyn_lint( | |
| 28 | cx.emit_lint( | |
| 29 | 29 | MISPLACED_DIAGNOSTIC_ATTRIBUTES, |
| 30 | 30 | move |dcx, level| DiagnosticOnUnmatchArgsOnlyForMacros.into_diag(dcx, level), |
| 31 | 31 | span, |
compiler/rustc_attr_parsing/src/attributes/doc.rs+25-25| ... | ... | @@ -68,7 +68,7 @@ fn check_attr_not_crate_level<S: Stage>( |
| 68 | 68 | /// Checks that an attribute is used at the crate level. Returns `true` if valid. |
| 69 | 69 | fn check_attr_crate_level<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) -> bool { |
| 70 | 70 | if cx.shared.target != Target::Crate { |
| 71 | cx.emit_dyn_lint( | |
| 71 | cx.emit_lint( | |
| 72 | 72 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 73 | 73 | |dcx, level| AttrCrateLevelOnly.into_diag(dcx, level), |
| 74 | 74 | span, |
| ... | ... | @@ -84,7 +84,7 @@ fn expected_name_value<S: Stage>( |
| 84 | 84 | span: Span, |
| 85 | 85 | _name: Option<Symbol>, |
| 86 | 86 | ) { |
| 87 | cx.emit_dyn_lint( | |
| 87 | cx.emit_lint( | |
| 88 | 88 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 89 | 89 | |dcx, level| ExpectedNameValue.into_diag(dcx, level), |
| 90 | 90 | span, |
| ... | ... | @@ -93,7 +93,7 @@ fn expected_name_value<S: Stage>( |
| 93 | 93 | |
| 94 | 94 | // FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead. |
| 95 | 95 | fn expected_no_args<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) { |
| 96 | cx.emit_dyn_lint( | |
| 96 | cx.emit_lint( | |
| 97 | 97 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 98 | 98 | |dcx, level| ExpectedNoArgs.into_diag(dcx, level), |
| 99 | 99 | span, |
| ... | ... | @@ -107,7 +107,7 @@ fn expected_string_literal<S: Stage>( |
| 107 | 107 | span: Span, |
| 108 | 108 | _actual_literal: Option<&MetaItemLit>, |
| 109 | 109 | ) { |
| 110 | cx.emit_dyn_lint( | |
| 110 | cx.emit_lint( | |
| 111 | 111 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 112 | 112 | |dcx, level| MalformedDoc.into_diag(dcx, level), |
| 113 | 113 | span, |
| ... | ... | @@ -177,7 +177,7 @@ impl DocParser { |
| 177 | 177 | |
| 178 | 178 | if let Some(used_span) = self.attribute.no_crate_inject { |
| 179 | 179 | let unused_span = path.span(); |
| 180 | cx.emit_dyn_lint( | |
| 180 | cx.emit_lint( | |
| 181 | 181 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 182 | 182 | move |dcx, level| { |
| 183 | 183 | rustc_errors::lints::UnusedDuplicate { |
| ... | ... | @@ -203,7 +203,7 @@ impl DocParser { |
| 203 | 203 | // FIXME: remove this method once merged and uncomment the line below instead. |
| 204 | 204 | // cx.expected_list(cx.attr_span, args); |
| 205 | 205 | let span = cx.attr_span; |
| 206 | cx.emit_dyn_lint( | |
| 206 | cx.emit_lint( | |
| 207 | 207 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 208 | 208 | |dcx, level| MalformedDoc.into_diag(dcx, level), |
| 209 | 209 | span, |
| ... | ... | @@ -217,14 +217,14 @@ impl DocParser { |
| 217 | 217 | } |
| 218 | 218 | } |
| 219 | 219 | Some(name) => { |
| 220 | cx.emit_dyn_lint( | |
| 220 | cx.emit_lint( | |
| 221 | 221 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 222 | 222 | move |dcx, level| DocTestUnknown { name }.into_diag(dcx, level), |
| 223 | 223 | path.span(), |
| 224 | 224 | ); |
| 225 | 225 | } |
| 226 | 226 | None => { |
| 227 | cx.emit_dyn_lint( | |
| 227 | cx.emit_lint( | |
| 228 | 228 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 229 | 229 | |dcx, level| DocTestLiteral.into_diag(dcx, level), |
| 230 | 230 | path.span(), |
| ... | ... | @@ -261,7 +261,7 @@ impl DocParser { |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | 263 | if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() { |
| 264 | cx.emit_dyn_lint( | |
| 264 | cx.emit_lint( | |
| 265 | 265 | rustc_session::lint::builtin::UNUSED_ATTRIBUTES, |
| 266 | 266 | move |dcx, level| DocAliasDuplicated { first_definition }.into_diag(dcx, level), |
| 267 | 267 | span, |
| ... | ... | @@ -349,7 +349,7 @@ impl DocParser { |
| 349 | 349 | ArgParser::List(list) => { |
| 350 | 350 | for meta in list.mixed() { |
| 351 | 351 | let MetaItemOrLitParser::MetaItemParser(item) = meta else { |
| 352 | cx.emit_dyn_lint( | |
| 352 | cx.emit_lint( | |
| 353 | 353 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 354 | 354 | |dcx, level| DocAutoCfgExpectsHideOrShow.into_diag(dcx, level), |
| 355 | 355 | meta.span(), |
| ... | ... | @@ -360,7 +360,7 @@ impl DocParser { |
| 360 | 360 | Some(sym::hide) => (HideOrShow::Hide, sym::hide), |
| 361 | 361 | Some(sym::show) => (HideOrShow::Show, sym::show), |
| 362 | 362 | _ => { |
| 363 | cx.emit_dyn_lint( | |
| 363 | cx.emit_lint( | |
| 364 | 364 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 365 | 365 | |dcx, level| DocAutoCfgExpectsHideOrShow.into_diag(dcx, level), |
| 366 | 366 | item.span(), |
| ... | ... | @@ -369,7 +369,7 @@ impl DocParser { |
| 369 | 369 | } |
| 370 | 370 | }; |
| 371 | 371 | let ArgParser::List(list) = item.args() else { |
| 372 | cx.emit_dyn_lint( | |
| 372 | cx.emit_lint( | |
| 373 | 373 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 374 | 374 | move |dcx, level| { |
| 375 | 375 | DocAutoCfgHideShowExpectsList { attr_name }.into_diag(dcx, level) |
| ... | ... | @@ -383,7 +383,7 @@ impl DocParser { |
| 383 | 383 | |
| 384 | 384 | for item in list.mixed() { |
| 385 | 385 | let MetaItemOrLitParser::MetaItemParser(sub_item) = item else { |
| 386 | cx.emit_dyn_lint( | |
| 386 | cx.emit_lint( | |
| 387 | 387 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 388 | 388 | move |dcx, level| { |
| 389 | 389 | DocAutoCfgHideShowUnexpectedItem { attr_name } |
| ... | ... | @@ -399,7 +399,7 @@ impl DocParser { |
| 399 | 399 | // FIXME: remove this method once merged and uncomment the line |
| 400 | 400 | // below instead. |
| 401 | 401 | // cx.expected_identifier(sub_item.path().span()); |
| 402 | cx.emit_dyn_lint( | |
| 402 | cx.emit_lint( | |
| 403 | 403 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 404 | 404 | |dcx, level| MalformedDoc.into_diag(dcx, level), |
| 405 | 405 | sub_item.path().span(), |
| ... | ... | @@ -426,7 +426,7 @@ impl DocParser { |
| 426 | 426 | } |
| 427 | 427 | } |
| 428 | 428 | _ => { |
| 429 | cx.emit_dyn_lint( | |
| 429 | cx.emit_lint( | |
| 430 | 430 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 431 | 431 | move |dcx, level| { |
| 432 | 432 | DocAutoCfgHideShowUnexpectedItem { attr_name } |
| ... | ... | @@ -444,7 +444,7 @@ impl DocParser { |
| 444 | 444 | ArgParser::NameValue(nv) => { |
| 445 | 445 | let MetaItemLit { kind: LitKind::Bool(bool_value), span, .. } = nv.value_as_lit() |
| 446 | 446 | else { |
| 447 | cx.emit_dyn_lint( | |
| 447 | cx.emit_lint( | |
| 448 | 448 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 449 | 449 | move |dcx, level| DocAutoCfgWrongLiteral.into_diag(dcx, level), |
| 450 | 450 | nv.value_span, |
| ... | ... | @@ -588,7 +588,7 @@ impl DocParser { |
| 588 | 588 | Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args), |
| 589 | 589 | Some(sym::test) => { |
| 590 | 590 | let Some(list) = args.as_list() else { |
| 591 | cx.emit_dyn_lint( | |
| 591 | cx.emit_lint( | |
| 592 | 592 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 593 | 593 | |dcx, level| DocTestTakesList.into_diag(dcx, level), |
| 594 | 594 | args.span().unwrap_or(path.span()), |
| ... | ... | @@ -605,7 +605,7 @@ impl DocParser { |
| 605 | 605 | // FIXME: remove this method once merged and uncomment the line |
| 606 | 606 | // below instead. |
| 607 | 607 | // cx.unexpected_literal(lit.span); |
| 608 | cx.emit_dyn_lint( | |
| 608 | cx.emit_lint( | |
| 609 | 609 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 610 | 610 | |dcx, level| MalformedDoc.into_diag(dcx, level), |
| 611 | 611 | lit.span, |
| ... | ... | @@ -616,7 +616,7 @@ impl DocParser { |
| 616 | 616 | } |
| 617 | 617 | Some(sym::spotlight) => { |
| 618 | 618 | let span = path.span(); |
| 619 | cx.emit_dyn_lint( | |
| 619 | cx.emit_lint( | |
| 620 | 620 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 621 | 621 | move |dcx, level| DocUnknownSpotlight { sugg_span: span }.into_diag(dcx, level), |
| 622 | 622 | span, |
| ... | ... | @@ -629,7 +629,7 @@ impl DocParser { |
| 629 | 629 | }; |
| 630 | 630 | let value = nv.value_as_lit().symbol; |
| 631 | 631 | let span = path.span(); |
| 632 | cx.emit_dyn_lint( | |
| 632 | cx.emit_lint( | |
| 633 | 633 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 634 | 634 | move |dcx, level| { |
| 635 | 635 | DocUnknownInclude { |
| ... | ... | @@ -644,7 +644,7 @@ impl DocParser { |
| 644 | 644 | } |
| 645 | 645 | Some(name @ (sym::passes | sym::no_default_passes)) => { |
| 646 | 646 | let span = path.span(); |
| 647 | cx.emit_dyn_lint( | |
| 647 | cx.emit_lint( | |
| 648 | 648 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 649 | 649 | move |dcx, level| { |
| 650 | 650 | DocUnknownPasses { name, note_span: span }.into_diag(dcx, level) |
| ... | ... | @@ -654,14 +654,14 @@ impl DocParser { |
| 654 | 654 | } |
| 655 | 655 | Some(sym::plugins) => { |
| 656 | 656 | let span = path.span(); |
| 657 | cx.emit_dyn_lint( | |
| 657 | cx.emit_lint( | |
| 658 | 658 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 659 | 659 | move |dcx, level| DocUnknownPlugins { label_span: span }.into_diag(dcx, level), |
| 660 | 660 | span, |
| 661 | 661 | ); |
| 662 | 662 | } |
| 663 | 663 | Some(name) => { |
| 664 | cx.emit_dyn_lint( | |
| 664 | cx.emit_lint( | |
| 665 | 665 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 666 | 666 | move |dcx, level| DocUnknownAny { name }.into_diag(dcx, level), |
| 667 | 667 | path.span(), |
| ... | ... | @@ -671,7 +671,7 @@ impl DocParser { |
| 671 | 671 | let full_name = |
| 672 | 672 | path.segments().map(|s| s.as_str()).intersperse("::").collect::<String>(); |
| 673 | 673 | let name = Symbol::intern(&full_name); |
| 674 | cx.emit_dyn_lint( | |
| 674 | cx.emit_lint( | |
| 675 | 675 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 676 | 676 | move |dcx, level| DocUnknownAny { name }.into_diag(dcx, level), |
| 677 | 677 | path.span(), |
| ... | ... | @@ -689,7 +689,7 @@ impl DocParser { |
| 689 | 689 | ArgParser::NoArgs => { |
| 690 | 690 | let suggestions = cx.adcx().suggestions(); |
| 691 | 691 | let span = cx.attr_span; |
| 692 | cx.emit_dyn_lint( | |
| 692 | cx.emit_lint( | |
| 693 | 693 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 694 | 694 | move |dcx, level| { |
| 695 | 695 | 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>( |
| 122 | 122 | return None; |
| 123 | 123 | } |
| 124 | 124 | if rustc_feature::is_builtin_attr_name(ident.name) { |
| 125 | cx.emit_dyn_lint( | |
| 125 | cx.emit_lint( | |
| 126 | 126 | AMBIGUOUS_DERIVE_HELPERS, |
| 127 | 127 | |dcx, level| crate::errors::AmbiguousDeriveHelpers.into_diag(dcx, level), |
| 128 | 128 | 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> { |
| 462 | 462 | /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing |
| 463 | 463 | /// must be delayed until after HIR is built. This method will take care of the details of |
| 464 | 464 | /// that. |
| 465 | pub(crate) fn emit_dyn_lint< | |
| 465 | pub(crate) fn emit_lint< | |
| 466 | 466 | F: for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static, |
| 467 | 467 | >( |
| 468 | 468 | &mut self, |
| ... | ... | @@ -477,7 +477,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { |
| 477 | 477 | ); |
| 478 | 478 | } |
| 479 | 479 | |
| 480 | pub(crate) fn emit_dyn_lint_with_sess< | |
| 480 | pub(crate) fn emit_lint_with_sess< | |
| 481 | 481 | F: for<'a> Fn(DiagCtxtHandle<'a>, Level, &Session) -> Diag<'a, ()> |
| 482 | 482 | + DynSend |
| 483 | 483 | + DynSync |
| ... | ... | @@ -507,7 +507,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { |
| 507 | 507 | } |
| 508 | 508 | |
| 509 | 509 | pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) { |
| 510 | self.emit_dyn_lint( | |
| 510 | self.emit_lint( | |
| 511 | 511 | rustc_session::lint::builtin::UNUSED_ATTRIBUTES, |
| 512 | 512 | move |dcx, level| { |
| 513 | 513 | rustc_errors::lints::UnusedDuplicate { |
| ... | ... | @@ -526,7 +526,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { |
| 526 | 526 | used_span: Span, |
| 527 | 527 | unused_span: Span, |
| 528 | 528 | ) { |
| 529 | self.emit_dyn_lint( | |
| 529 | self.emit_lint( | |
| 530 | 530 | rustc_session::lint::builtin::UNUSED_ATTRIBUTES, |
| 531 | 531 | move |dcx, level| { |
| 532 | 532 | rustc_errors::lints::UnusedDuplicate { |
| ... | ... | @@ -951,7 +951,7 @@ where |
| 951 | 951 | pub(crate) fn warn_empty_attribute(&mut self, span: Span) { |
| 952 | 952 | let attr_path = self.attr_path.to_string(); |
| 953 | 953 | let valid_without_list = self.template.word; |
| 954 | self.emit_dyn_lint( | |
| 954 | self.emit_lint( | |
| 955 | 955 | rustc_session::lint::builtin::UNUSED_ATTRIBUTES, |
| 956 | 956 | move |dcx, level| { |
| 957 | 957 | crate::errors::EmptyAttributeList { |
| ... | ... | @@ -975,7 +975,7 @@ where |
| 975 | 975 | ) { |
| 976 | 976 | let suggestions = self.suggestions(); |
| 977 | 977 | let span = self.attr_span; |
| 978 | self.emit_dyn_lint( | |
| 978 | self.emit_lint( | |
| 979 | 979 | lint, |
| 980 | 980 | move |dcx, level| { |
| 981 | 981 | 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> { |
| 142 | 142 | }; |
| 143 | 143 | |
| 144 | 144 | let attr_span = cx.attr_span; |
| 145 | cx.emit_dyn_lint( | |
| 145 | cx.emit_lint( | |
| 146 | 146 | lint, |
| 147 | 147 | move |dcx, level| { |
| 148 | 148 | InvalidTargetLint { |
| ... | ... | @@ -186,7 +186,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { |
| 186 | 186 | let target_span = cx.target_span; |
| 187 | 187 | let attr_span = cx.attr_span; |
| 188 | 188 | |
| 189 | cx.emit_dyn_lint( | |
| 189 | cx.emit_lint( | |
| 190 | 190 | rustc_session::lint::builtin::UNUSED_ATTRIBUTES, |
| 191 | 191 | move |dcx, level| { |
| 192 | 192 | crate::errors::InvalidAttrStyle { |
compiler/rustc_borrowck/src/handle_placeholders.rs+8-10| ... | ... | @@ -35,18 +35,18 @@ pub(crate) struct LoweredConstraints<'tcx> { |
| 35 | 35 | pub(crate) placeholder_indices: PlaceholderIndices<'tcx>, |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | impl<'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 | ||
| 44 | 38 | /// A Visitor for SCC annotation construction. |
| 45 | 39 | pub(crate) struct SccAnnotations<'d, 'tcx, A: scc::Annotation> { |
| 46 | 40 | pub(crate) scc_to_annotation: IndexVec<ConstraintSccIndex, A>, |
| 47 | 41 | definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>, |
| 48 | 42 | } |
| 49 | 43 | |
| 44 | impl<'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 | ||
| 50 | 50 | impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> { |
| 51 | 51 | fn new(&self, element: RegionVid) -> RegionTracker { |
| 52 | 52 | RegionTracker::new(element, &self.definitions[element]) |
| ... | ... | @@ -118,7 +118,7 @@ impl RegionTracker { |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | 120 | /// 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 | |
| 122 | 122 | /// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)` |
| 123 | 123 | pub(crate) fn max_nameable_universe(self) -> UniverseIndex { |
| 124 | 124 | self.max_nameable_universe.0 |
| ... | ... | @@ -208,7 +208,7 @@ pub(super) fn region_definitions<'tcx>( |
| 208 | 208 | /// graph such that there is a series of constraints |
| 209 | 209 | /// A: B: C: ... : X where |
| 210 | 210 | /// 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 | |
| 212 | 212 | /// in the face of borrow checker/trait solver limitations that will |
| 213 | 213 | /// eventually go away. |
| 214 | 214 | /// |
| ... | ... | @@ -327,8 +327,6 @@ pub(crate) fn rewrite_placeholder_outlives<'tcx>( |
| 327 | 327 | |
| 328 | 328 | for scc in sccs.all_sccs() { |
| 329 | 329 | // No point in adding 'static: 'static! |
| 330 | // This micro-optimisation makes somewhat sense | |
| 331 | // because static outlives *everything*. | |
| 332 | 330 | if scc == sccs.scc(fr_static) { |
| 333 | 331 | continue; |
| 334 | 332 | } |
compiler/rustc_borrowck/src/region_infer/mod.rs+18-13| ... | ... | @@ -501,43 +501,48 @@ impl<'tcx> RegionInferenceContext<'tcx> { |
| 501 | 501 | |
| 502 | 502 | let mut errors_buffer = RegionErrors::new(infcx.tcx); |
| 503 | 503 | |
| 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); | |
| 510 | 509 | |
| 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); | |
| 512 | 511 | |
| 513 | 512 | debug!(?errors_buffer); |
| 514 | debug!(?outlives_requirements); | |
| 513 | debug!(?propagated_outlives_requirements); | |
| 515 | 514 | |
| 516 | 515 | // In Polonius mode, the errors about missing universal region relations are in the output |
| 517 | 516 | // and need to be emitted or propagated. Otherwise, we need to check whether the |
| 518 | 517 | // constraints were too strong, and if so, emit or propagate those errors. |
| 519 | 518 | if infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() { |
| 520 | 519 | self.check_polonius_subset_errors( |
| 521 | outlives_requirements.as_mut(), | |
| 520 | propagated_outlives_requirements.as_mut(), | |
| 522 | 521 | &mut errors_buffer, |
| 523 | 522 | polonius_output |
| 524 | 523 | .as_ref() |
| 525 | 524 | .expect("Polonius output is unavailable despite `-Z polonius`"), |
| 526 | 525 | ); |
| 527 | 526 | } 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 | ); | |
| 529 | 531 | } |
| 530 | 532 | |
| 531 | 533 | debug!(?errors_buffer); |
| 532 | 534 | |
| 533 | let outlives_requirements = outlives_requirements.unwrap_or_default(); | |
| 535 | let propagated_outlives_requirements = propagated_outlives_requirements.unwrap_or_default(); | |
| 534 | 536 | |
| 535 | if outlives_requirements.is_empty() { | |
| 537 | if propagated_outlives_requirements.is_empty() { | |
| 536 | 538 | (None, errors_buffer) |
| 537 | 539 | } else { |
| 538 | 540 | let num_external_vids = self.universal_regions().num_global_and_external_regions(); |
| 539 | 541 | ( |
| 540 | Some(ClosureRegionRequirements { num_external_vids, outlives_requirements }), | |
| 542 | Some(ClosureRegionRequirements { | |
| 543 | num_external_vids, | |
| 544 | outlives_requirements: propagated_outlives_requirements, | |
| 545 | }), | |
| 541 | 546 | errors_buffer, |
| 542 | 547 | ) |
| 543 | 548 | } |
compiler/rustc_codegen_cranelift/.github/workflows/main.yml+2-1| ... | ... | @@ -242,7 +242,8 @@ jobs: |
| 242 | 242 | runs-on: ubuntu-latest |
| 243 | 243 | timeout-minutes: 10 |
| 244 | 244 | 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] | |
| 246 | 247 | |
| 247 | 248 | permissions: |
| 248 | 249 | contents: write # for creating the dev tag and release |
compiler/rustc_codegen_cranelift/Cargo.lock+51-42| ... | ... | @@ -43,27 +43,27 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" |
| 43 | 43 | |
| 44 | 44 | [[package]] |
| 45 | 45 | name = "cranelift-assembler-x64" |
| 46 | version = "0.130.0" | |
| 46 | version = "0.131.0" | |
| 47 | 47 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 48 | checksum = "4f248321c6a7d4de5dcf2939368e96a397ad3f53b6a076e38d0104d1da326d37" | |
| 48 | checksum = "6edb5bdd1af46714e3224a017fabbbd57f70df4e840eb5ad6a7429dc456119d6" | |
| 49 | 49 | dependencies = [ |
| 50 | 50 | "cranelift-assembler-x64-meta", |
| 51 | 51 | ] |
| 52 | 52 | |
| 53 | 53 | [[package]] |
| 54 | 54 | name = "cranelift-assembler-x64-meta" |
| 55 | version = "0.130.0" | |
| 55 | version = "0.131.0" | |
| 56 | 56 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 57 | checksum = "ab6d78ff1f7d9bf8b7e1afbedbf78ba49e38e9da479d4c8a2db094e22f64e2bc" | |
| 57 | checksum = "a819599186e1b1a1f88d464e06045696afc7aa3e0cc018aa0b2999cb63d1d088" | |
| 58 | 58 | dependencies = [ |
| 59 | 59 | "cranelift-srcgen", |
| 60 | 60 | ] |
| 61 | 61 | |
| 62 | 62 | [[package]] |
| 63 | 63 | name = "cranelift-bforest" |
| 64 | version = "0.130.0" | |
| 64 | version = "0.131.0" | |
| 65 | 65 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 66 | checksum = "6b6005ba640213a5b95382aeaf6b82bf028309581c8d7349778d66f27dc1180b" | |
| 66 | checksum = "36e2c152d488e03c87b913bc2ed3414416eb1e0d66d61b49af60bf456a9665c7" | |
| 67 | 67 | dependencies = [ |
| 68 | 68 | "cranelift-entity", |
| 69 | 69 | "wasmtime-internal-core", |
| ... | ... | @@ -71,18 +71,18 @@ dependencies = [ |
| 71 | 71 | |
| 72 | 72 | [[package]] |
| 73 | 73 | name = "cranelift-bitset" |
| 74 | version = "0.130.0" | |
| 74 | version = "0.131.0" | |
| 75 | 75 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 76 | checksum = "81fb5b134a12b559ff0c0f5af0fcd755ad380723b5016c4e0d36f74d39485340" | |
| 76 | checksum = "b6559d4fbc253d1396e1f6beeae57fa88a244f02aaf0cde2a735afd3492d9b2e" | |
| 77 | 77 | dependencies = [ |
| 78 | 78 | "wasmtime-internal-core", |
| 79 | 79 | ] |
| 80 | 80 | |
| 81 | 81 | [[package]] |
| 82 | 82 | name = "cranelift-codegen" |
| 83 | version = "0.130.0" | |
| 83 | version = "0.131.0" | |
| 84 | 84 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 85 | checksum = "85837de8be7f17a4034a6b08816f05a3144345d2091937b39d415990daca28f4" | |
| 85 | checksum = "96d9315d98d6e0a64454d4c83be2ee0e8055c3f80c3b2d7bcad7079f281a06ff" | |
| 86 | 86 | dependencies = [ |
| 87 | 87 | "bumpalo", |
| 88 | 88 | "cranelift-assembler-x64", |
| ... | ... | @@ -107,9 +107,9 @@ dependencies = [ |
| 107 | 107 | |
| 108 | 108 | [[package]] |
| 109 | 109 | name = "cranelift-codegen-meta" |
| 110 | version = "0.130.0" | |
| 110 | version = "0.131.0" | |
| 111 | 111 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 112 | checksum = "e433faa87d38e5b8ff469e44a26fea4f93e58abd7a7c10bad9810056139700c9" | |
| 112 | checksum = "d89c00a88081c55e3087c45bebc77e0cc973de2d7b44ef6a943c7122647b89f5" | |
| 113 | 113 | dependencies = [ |
| 114 | 114 | "cranelift-assembler-x64-meta", |
| 115 | 115 | "cranelift-codegen-shared", |
| ... | ... | @@ -119,24 +119,24 @@ dependencies = [ |
| 119 | 119 | |
| 120 | 120 | [[package]] |
| 121 | 121 | name = "cranelift-codegen-shared" |
| 122 | version = "0.130.0" | |
| 122 | version = "0.131.0" | |
| 123 | 123 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 124 | checksum = "5397ba61976e13944ca71230775db13ee1cb62849701ed35b753f4761ed0a9b7" | |
| 124 | checksum = "879f77c497a1eb6273482aa1ac3b23cb8563ff04edb39ed5dfcfd28c8deff8f5" | |
| 125 | 125 | |
| 126 | 126 | [[package]] |
| 127 | 127 | name = "cranelift-control" |
| 128 | version = "0.130.0" | |
| 128 | version = "0.131.0" | |
| 129 | 129 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 130 | checksum = "cc81c88765580720eb30f4fc2c1bfdb75fcbf3094f87b3cd69cecca79d77a245" | |
| 130 | checksum = "498dc1f17a6910c88316d49c7176d8fa97cf10c30859c32a266040449317f963" | |
| 131 | 131 | dependencies = [ |
| 132 | 132 | "arbitrary", |
| 133 | 133 | ] |
| 134 | 134 | |
| 135 | 135 | [[package]] |
| 136 | 136 | name = "cranelift-entity" |
| 137 | version = "0.130.0" | |
| 137 | version = "0.131.0" | |
| 138 | 138 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 139 | checksum = "463feed5d46cf8763f3ba3045284cf706dd161496e20ec9c14afbb4ba09b9e66" | |
| 139 | checksum = "c2acba797f6a46042ce82aaf7680d0c3567fe2001e238db9df649fd104a2727f" | |
| 140 | 140 | dependencies = [ |
| 141 | 141 | "cranelift-bitset", |
| 142 | 142 | "wasmtime-internal-core", |
| ... | ... | @@ -144,9 +144,9 @@ dependencies = [ |
| 144 | 144 | |
| 145 | 145 | [[package]] |
| 146 | 146 | name = "cranelift-frontend" |
| 147 | version = "0.130.0" | |
| 147 | version = "0.131.0" | |
| 148 | 148 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 149 | checksum = "a4c5eca7696c1c04ab4c7ed8d18eadbb47d6cc9f14ec86fe0881bf1d7e97e261" | |
| 149 | checksum = "4dca3df1d107d98d88f159ad1d5eaa2d5cdb678b3d5bcfadc6fc83d8ebb448ea" | |
| 150 | 150 | dependencies = [ |
| 151 | 151 | "cranelift-codegen", |
| 152 | 152 | "log", |
| ... | ... | @@ -156,15 +156,15 @@ dependencies = [ |
| 156 | 156 | |
| 157 | 157 | [[package]] |
| 158 | 158 | name = "cranelift-isle" |
| 159 | version = "0.130.0" | |
| 159 | version = "0.131.0" | |
| 160 | 160 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 161 | checksum = "f1153844610cc9c6da8cf10ce205e45da1a585b7688ed558aa808bbe2e4e6d77" | |
| 161 | checksum = "f62dd18116d88bed649871feceda79dad7b59cc685ea8998c2b3e64d0e689602" | |
| 162 | 162 | |
| 163 | 163 | [[package]] |
| 164 | 164 | name = "cranelift-jit" |
| 165 | version = "0.130.0" | |
| 165 | version = "0.131.0" | |
| 166 | 166 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 167 | checksum = "41836de8321b303d3d4188e58cc09c30c7645337342acfcfb363732695cae098" | |
| 167 | checksum = "0a4942770ce6662b44d903493d7c5b00f9a986a713a61aae148306eaef21ebd4" | |
| 168 | 168 | dependencies = [ |
| 169 | 169 | "anyhow", |
| 170 | 170 | "cranelift-codegen", |
| ... | ... | @@ -182,9 +182,9 @@ dependencies = [ |
| 182 | 182 | |
| 183 | 183 | [[package]] |
| 184 | 184 | name = "cranelift-module" |
| 185 | version = "0.130.0" | |
| 185 | version = "0.131.0" | |
| 186 | 186 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 187 | checksum = "b731f66cb1b69b60a74216e632968ebdbb95c488d26aa1448ec226ae0ffec33e" | |
| 187 | checksum = "fb5ca0d214ecee44405ea9f0c65a5318b41ac469e8258fd9fe944e564c1c1b0b" | |
| 188 | 188 | dependencies = [ |
| 189 | 189 | "anyhow", |
| 190 | 190 | "cranelift-codegen", |
| ... | ... | @@ -193,9 +193,9 @@ dependencies = [ |
| 193 | 193 | |
| 194 | 194 | [[package]] |
| 195 | 195 | name = "cranelift-native" |
| 196 | version = "0.130.0" | |
| 196 | version = "0.131.0" | |
| 197 | 197 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 198 | checksum = "a97b583fe9a60f06b0464cee6be5a17f623fd91b217aaac99b51b339d19911af" | |
| 198 | checksum = "f843b80360d7fdf61a6124642af7597f6d55724cf521210c34af8a1c66daca6e" | |
| 199 | 199 | dependencies = [ |
| 200 | 200 | "cranelift-codegen", |
| 201 | 201 | "libc", |
| ... | ... | @@ -204,9 +204,9 @@ dependencies = [ |
| 204 | 204 | |
| 205 | 205 | [[package]] |
| 206 | 206 | name = "cranelift-object" |
| 207 | version = "0.130.0" | |
| 207 | version = "0.131.0" | |
| 208 | 208 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 209 | checksum = "9809d2d419cd18f17377f4ce64a7ad22eeda0d042c08833d3796657f1ddebc82" | |
| 209 | checksum = "b9d212d15015c374333b11b833111b7c7e686bfaec02385af53611050bce7e9d" | |
| 210 | 210 | dependencies = [ |
| 211 | 211 | "anyhow", |
| 212 | 212 | "cranelift-codegen", |
| ... | ... | @@ -219,9 +219,9 @@ dependencies = [ |
| 219 | 219 | |
| 220 | 220 | [[package]] |
| 221 | 221 | name = "cranelift-srcgen" |
| 222 | version = "0.130.0" | |
| 222 | version = "0.131.0" | |
| 223 | 223 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 224 | checksum = "8594dc6bb4860fa8292f1814c76459dbfb933e1978d8222de6380efce45c7cee" | |
| 224 | checksum = "090ee5de58c6f17eb5e3a5ae8cf1695c7efea04ec4dd0ecba6a5b996c9bad7dc" | |
| 225 | 225 | |
| 226 | 226 | [[package]] |
| 227 | 227 | name = "crc32fast" |
| ... | ... | @@ -277,6 +277,15 @@ dependencies = [ |
| 277 | 277 | "foldhash", |
| 278 | 278 | ] |
| 279 | 279 | |
| 280 | [[package]] | |
| 281 | name = "hashbrown" | |
| 282 | version = "0.17.0" | |
| 283 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 284 | checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" | |
| 285 | dependencies = [ | |
| 286 | "foldhash", | |
| 287 | ] | |
| 288 | ||
| 280 | 289 | [[package]] |
| 281 | 290 | name = "heck" |
| 282 | 291 | version = "0.5.0" |
| ... | ... | @@ -285,12 +294,12 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" |
| 285 | 294 | |
| 286 | 295 | [[package]] |
| 287 | 296 | name = "indexmap" |
| 288 | version = "2.13.0" | |
| 297 | version = "2.14.0" | |
| 289 | 298 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 290 | checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" | |
| 299 | checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" | |
| 291 | 300 | dependencies = [ |
| 292 | 301 | "equivalent", |
| 293 | "hashbrown 0.16.1", | |
| 302 | "hashbrown 0.17.0", | |
| 294 | 303 | ] |
| 295 | 304 | |
| 296 | 305 | [[package]] |
| ... | ... | @@ -338,12 +347,12 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" |
| 338 | 347 | |
| 339 | 348 | [[package]] |
| 340 | 349 | name = "object" |
| 341 | version = "0.38.1" | |
| 350 | version = "0.39.1" | |
| 342 | 351 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 343 | checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc" | |
| 352 | checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" | |
| 344 | 353 | dependencies = [ |
| 345 | 354 | "crc32fast", |
| 346 | "hashbrown 0.16.1", | |
| 355 | "hashbrown 0.17.0", | |
| 347 | 356 | "indexmap", |
| 348 | 357 | "memchr", |
| 349 | 358 | ] |
| ... | ... | @@ -482,9 +491,9 @@ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" |
| 482 | 491 | |
| 483 | 492 | [[package]] |
| 484 | 493 | name = "wasmtime-internal-core" |
| 485 | version = "43.0.0" | |
| 494 | version = "44.0.0" | |
| 486 | 495 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 487 | checksum = "e671917bb6856ae360cb59d7aaf26f1cfd042c7b924319dd06fd380739fc0b2e" | |
| 496 | checksum = "816a61a75275c6be435131fc625a4f5956daf24d9f9f59443e81cbef228929b3" | |
| 488 | 497 | dependencies = [ |
| 489 | 498 | "hashbrown 0.16.1", |
| 490 | 499 | "libm", |
| ... | ... | @@ -492,9 +501,9 @@ dependencies = [ |
| 492 | 501 | |
| 493 | 502 | [[package]] |
| 494 | 503 | name = "wasmtime-internal-jit-icache-coherence" |
| 495 | version = "43.0.0" | |
| 504 | version = "44.0.0" | |
| 496 | 505 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 497 | checksum = "9b3112806515fac8495883885eb8dbdde849988ae91fe6beb544c0d7c0f4c9aa" | |
| 506 | checksum = "2fd683a94490bf755d016a09697b0955602c50106b1ded97d16983ab2ded9fed" | |
| 498 | 507 | dependencies = [ |
| 499 | 508 | "cfg-if", |
| 500 | 509 | "libc", |
compiler/rustc_codegen_cranelift/Cargo.toml+13-13| ... | ... | @@ -8,15 +8,15 @@ crate-type = ["dylib"] |
| 8 | 8 | |
| 9 | 9 | [dependencies] |
| 10 | 10 | # These have to be in sync with each other |
| 11 | cranelift-codegen = { version = "0.130.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } | |
| 12 | cranelift-frontend = { version = "0.130.0" } | |
| 13 | cranelift-module = { version = "0.130.0" } | |
| 14 | cranelift-native = { version = "0.130.0" } | |
| 15 | cranelift-jit = { version = "0.130.0", optional = true } | |
| 16 | cranelift-object = { version = "0.130.0" } | |
| 11 | cranelift-codegen = { version = "0.131.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } | |
| 12 | cranelift-frontend = { version = "0.131.0" } | |
| 13 | cranelift-module = { version = "0.131.0" } | |
| 14 | cranelift-native = { version = "0.131.0" } | |
| 15 | cranelift-jit = { version = "0.131.0", optional = true } | |
| 16 | cranelift-object = { version = "0.131.0" } | |
| 17 | 17 | target-lexicon = "0.13" |
| 18 | 18 | gimli = { version = "0.33", default-features = false, features = ["write"] } |
| 19 | object = { version = "0.38.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } | |
| 19 | object = { version = "0.39.1", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } | |
| 20 | 20 | |
| 21 | 21 | indexmap = "2.0.0" |
| 22 | 22 | libloading = { version = "0.9.0", optional = true } |
| ... | ... | @@ -24,12 +24,12 @@ smallvec = "1.8.1" |
| 24 | 24 | |
| 25 | 25 | [patch.crates-io] |
| 26 | 26 | # 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" } | |
| 33 | 33 | |
| 34 | 34 | # Uncomment to use local checkout of cranelift |
| 35 | 35 | #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 { |
| 178 | 178 | && !file_name_str.contains("rustc_std_workspace_") |
| 179 | 179 | && !file_name_str.contains("rustc_demangle") |
| 180 | 180 | && !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") | |
| 184 | 182 | { |
| 185 | 183 | // These are large crates that are part of the rustc-dev component and are not |
| 186 | 184 | // necessary to run regular programs. |
| ... | ... | @@ -208,9 +206,9 @@ fn build_clif_sysroot_for_triple( |
| 208 | 206 | |
| 209 | 207 | apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs)); |
| 210 | 208 | |
| 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")); | |
| 214 | 212 | } |
| 215 | 213 | |
| 216 | 214 | // Build sysroot |
| ... | ... | @@ -243,6 +241,7 @@ fn build_clif_sysroot_for_triple( |
| 243 | 241 | build_cmd.arg("--features").arg("backtrace panic-unwind"); |
| 244 | 242 | build_cmd.arg(format!("-Zroot-dir={}", STDLIB_SRC.to_path(dirs).display())); |
| 245 | 243 | build_cmd.arg("-Zno-embed-metadata"); |
| 244 | build_cmd.arg("-Zbuild-dir-new-layout"); | |
| 246 | 245 | build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true"); |
| 247 | 246 | build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); |
| 248 | 247 | if compiler.triple.contains("apple") { |
| ... | ... | @@ -254,7 +253,13 @@ fn build_clif_sysroot_for_triple( |
| 254 | 253 | } |
| 255 | 254 | spawn_and_wait(build_cmd); |
| 256 | 255 | |
| 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 | { | |
| 258 | 263 | let entry = entry.unwrap(); |
| 259 | 264 | if let Some(ext) = entry.path().extension() { |
| 260 | 265 | 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 @@ |
| 1 | From 2aa88b261ffb51d3f18a4b9d3b79232d7445e5f3 Mon Sep 17 00:00:00 2001 | |
| 2 | From: bjorn3 <17426603+bjorn3@users.noreply.github.com> | |
| 3 | Date: Thu, 16 Apr 2026 17:29:02 +0200 | |
| 4 | Subject: [PATCH] Disable f16 usage in portable-simd | |
| 5 | ||
| 6 | It 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 | ||
| 26 | diff --git a/Cargo.toml b/Cargo.toml | |
| 27 | index 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"] | |
| 48 | diff --git a/crates/core_simd/src/alias.rs b/crates/core_simd/src/alias.rs | |
| 49 | index 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 | |
| 69 | diff --git a/crates/core_simd/src/cast.rs b/crates/core_simd/src/cast.rs | |
| 70 | index 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 | |
| 83 | diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs | |
| 84 | index 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, | |
| 95 | diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs | |
| 96 | index 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; | |
| 108 | diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs | |
| 109 | index 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> | |
| 121 | diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs | |
| 122 | index 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),* } => { | |
| 134 | diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs | |
| 135 | index 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),* } => { | |
| 147 | diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs | |
| 148 | index 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 } } | |
| 157 | diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs | |
| 158 | index 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 | |
| 175 | diff --git a/crates/core_simd/tests/f16_ops.rs b/crates/core_simd/tests/f16_ops.rs | |
| 176 | deleted file mode 100644 | |
| 177 | index 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 } | |
| 191 | diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs | |
| 192 | index 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 { | |
| 221 | diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs | |
| 222 | index 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 { | |
| 234 | diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs | |
| 235 | index 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 | ||
| 251 | diff --git a/crates/test_helpers/src/subnormals.rs b/crates/test_helpers/src/subnormals.rs | |
| 252 | index 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 | -- | |
| 265 | 2.53.0 | |
| 266 |
compiler/rustc_codegen_cranelift/rust-toolchain.toml+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | 1 | [toolchain] |
| 2 | channel = "nightly-2026-03-25" | |
| 2 | channel = "nightly-2026-04-28" | |
| 3 | 3 | components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] |
| 4 | 4 | profile = "minimal" |
compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh+3-3| ... | ... | @@ -67,9 +67,9 @@ index bc68bfe396..00143ef3ed 100644 |
| 67 | 67 | --- a/src/bootstrap/src/core/config/config.rs |
| 68 | 68 | +++ b/src/bootstrap/src/core/config/config.rs |
| 69 | 69 | @@ -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 } => { | |
| 73 | 73 | - if dwn_ctx.is_running_on_ci() { |
| 74 | 74 | + if false && dwn_ctx.is_running_on_ci() { |
| 75 | 75 | 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 |
| 50 | 50 | rm tests/ui/sanitizer/kcfi-c-variadic.rs # same |
| 51 | 51 | rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported |
| 52 | 52 | rm tests/ui/delegation/fn-header.rs |
| 53 | rm tests/ui/c-variadic/roundtrip.rs | |
| 53 | 54 | |
| 54 | 55 | # inline assembly features |
| 55 | 56 | rm 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 |
| 144 | 145 | rm tests/ui/consts/const-mut-refs-crate.rs # same |
| 145 | 146 | rm tests/ui/abi/large-byval-align.rs # exceeds implementation limit of Cranelift |
| 146 | 147 | rm -r tests/run-make/short-ice # ICE backtrace begin/end marker mismatch |
| 148 | rm -r tests/run-make/naked-dead-code-elimination # function not eliminated | |
| 147 | 149 | |
| 148 | 150 | # doesn't work due to the way the rustc test suite is invoked. |
| 149 | 151 | # 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 { |
| 51 | 51 | if ret_ty == types::I16 { fx.bcx.ins().bitcast(types::F16, MemFlags::new(), ret) } else { ret } |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | // FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have | |
| 55 | // been added to Cranelift. | |
| 56 | pub(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. | |
| 72 | pub(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 | ||
| 54 | 88 | pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs: Value) -> Value { |
| 55 | 89 | let ty = fx.bcx.func.dfg.value_type(lhs); |
| 56 | 90 | match ty { |
compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs+1-1| ... | ... | @@ -43,7 +43,7 @@ impl DebugContext { |
| 43 | 43 | let _: Result<()> = sections.for_each(|id, section| { |
| 44 | 44 | if let Some(section_id) = section_map.get(&id) { |
| 45 | 45 | 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); | |
| 47 | 47 | } |
| 48 | 48 | } |
| 49 | 49 | Ok(()) |
compiler/rustc_codegen_cranelift/src/debuginfo/object.rs+31-23| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | use cranelift_module::{DataId, FuncId}; |
| 2 | 2 | use cranelift_object::ObjectProduct; |
| 3 | 3 | use gimli::SectionId; |
| 4 | use object::write::{Relocation, StandardSegment}; | |
| 4 | use object::write::{Relocation, StandardSection, StandardSegment}; | |
| 5 | 5 | use object::{RelocationEncoding, RelocationFlags, SectionKind}; |
| 6 | 6 | use rustc_data_structures::fx::FxHashMap; |
| 7 | 7 | |
| ... | ... | @@ -16,6 +16,7 @@ pub(super) trait WriteDebugInfo { |
| 16 | 16 | section_map: &FxHashMap<SectionId, Self::SectionId>, |
| 17 | 17 | from: &Self::SectionId, |
| 18 | 18 | reloc: &DebugReloc, |
| 19 | use_section_symbol: bool, | |
| 19 | 20 | ); |
| 20 | 21 | } |
| 21 | 22 | |
| ... | ... | @@ -27,29 +28,31 @@ impl WriteDebugInfo for ObjectProduct { |
| 27 | 28 | id: SectionId, |
| 28 | 29 | data: Vec<u8>, |
| 29 | 30 | ) -> (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; | |
| 32 | 35 | } 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 | |
| 46 | 38 | } 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); | |
| 53 | 56 | let symbol_id = self.object.section_symbol(section_id); |
| 54 | 57 | (section_id, symbol_id) |
| 55 | 58 | } |
| ... | ... | @@ -59,6 +62,7 @@ impl WriteDebugInfo for ObjectProduct { |
| 59 | 62 | section_map: &FxHashMap<SectionId, Self::SectionId>, |
| 60 | 63 | from: &Self::SectionId, |
| 61 | 64 | reloc: &DebugReloc, |
| 65 | use_section_symbol: bool, | |
| 62 | 66 | ) { |
| 63 | 67 | let (symbol, symbol_offset) = match reloc.name { |
| 64 | 68 | DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0), |
| ... | ... | @@ -69,7 +73,11 @@ impl WriteDebugInfo for ObjectProduct { |
| 69 | 73 | } else { |
| 70 | 74 | self.data_symbol(DataId::from_u32(id & !(1 << 31))) |
| 71 | 75 | }; |
| 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 | } | |
| 73 | 81 | } |
| 74 | 82 | }; |
| 75 | 83 | self.object |
compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs+6-6| ... | ... | @@ -120,13 +120,12 @@ impl UnwindContext { |
| 120 | 120 | func_id: FuncId, |
| 121 | 121 | context: &Context, |
| 122 | 122 | ) { |
| 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 | |
| 125 | 126 | { |
| 126 | 127 | // 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. | |
| 130 | 129 | return; |
| 131 | 130 | } |
| 132 | 131 | |
| ... | ... | @@ -250,8 +249,9 @@ impl UnwindContext { |
| 250 | 249 | let mut section_map = FxHashMap::default(); |
| 251 | 250 | section_map.insert(id, section_id); |
| 252 | 251 | |
| 252 | let use_section_symbol = product.object.format() != object::BinaryFormat::MachO; | |
| 253 | 253 | 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); | |
| 255 | 255 | } |
| 256 | 256 | } |
| 257 | 257 | } |
compiler/rustc_codegen_cranelift/src/driver/jit.rs+1-1| ... | ... | @@ -7,7 +7,7 @@ use std::os::raw::{c_char, c_int}; |
| 7 | 7 | use cranelift_jit::{JITBuilder, JITModule}; |
| 8 | 8 | use rustc_codegen_ssa::CrateInfo; |
| 9 | 9 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; |
| 10 | use rustc_middle::mir::mono::MonoItem; | |
| 10 | use rustc_middle::mono::MonoItem; | |
| 11 | 11 | use rustc_session::Session; |
| 12 | 12 | use rustc_session::config::OutputFilenames; |
| 13 | 13 | use rustc_span::sym; |
compiler/rustc_codegen_cranelift/src/global_asm.rs+3| ... | ... | @@ -235,6 +235,9 @@ pub(crate) fn compile_global_asm( |
| 235 | 235 | .arg("-") |
| 236 | 236 | .arg("-Abad_asm_style") |
| 237 | 237 | .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") | |
| 238 | 241 | .stdin(Stdio::piped()) |
| 239 | 242 | .spawn() |
| 240 | 243 | .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>( |
| 1197 | 1197 | let a = a.load_scalar(fx); |
| 1198 | 1198 | let b = b.load_scalar(fx); |
| 1199 | 1199 | |
| 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 | }); | |
| 1206 | 1203 | let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16)); |
| 1207 | 1204 | ret.write_cvalue(fx, val); |
| 1208 | 1205 | } |
| ... | ... | @@ -1240,12 +1237,9 @@ fn codegen_regular_intrinsic_call<'tcx>( |
| 1240 | 1237 | let a = a.load_scalar(fx); |
| 1241 | 1238 | let b = b.load_scalar(fx); |
| 1242 | 1239 | |
| 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 | }); | |
| 1249 | 1243 | let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16)); |
| 1250 | 1244 | ret.write_cvalue(fx, val); |
| 1251 | 1245 | } |
compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs+89-57| ... | ... | @@ -91,23 +91,26 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 91 | 91 | fx.bcx.ins().icmp(IntCC::SignedGreaterThanOrEqual, x_lane, y_lane) |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | // FIXME(bytecodealliance/wasmtime#8312): Replace with Cranelift | |
| 95 | // `fcmp` once `f16`/`f128` backend lowerings have been added to | |
| 96 | // Cranelift. | |
| 94 | 97 | (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) | |
| 96 | 99 | } |
| 97 | 100 | (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) | |
| 99 | 102 | } |
| 100 | 103 | (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) | |
| 102 | 105 | } |
| 103 | 106 | (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) | |
| 105 | 108 | } |
| 106 | 109 | (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) | |
| 108 | 111 | } |
| 109 | 112 | (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) | |
| 111 | 114 | } |
| 112 | 115 | |
| 113 | 116 | _ => unreachable!(), |
| ... | ... | @@ -391,6 +394,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 391 | 394 | intrinsic, |
| 392 | 395 | ) { |
| 393 | 396 | (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), | |
| 394 | 398 | (ty::Float(_), sym::simd_neg) => fx.bcx.ins().fneg(lane), |
| 395 | 399 | |
| 396 | 400 | (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>( |
| 418 | 422 | |
| 419 | 423 | // FIXME use vector instructions when possible |
| 420 | 424 | 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 | ) | |
| 465 | 484 | }); |
| 466 | 485 | } |
| 467 | 486 | |
| ... | ... | @@ -486,7 +505,11 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 486 | 505 | let b_lane = b.value_lane(fx, lane).load_scalar(fx); |
| 487 | 506 | let c_lane = c.value_lane(fx, lane).load_scalar(fx); |
| 488 | 507 | |
| 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 | }; | |
| 490 | 513 | let res_lane = CValue::by_val(res_lane, res_lane_layout); |
| 491 | 514 | |
| 492 | 515 | ret.place_lane(fx, lane).write_cvalue(fx, res_lane); |
| ... | ... | @@ -584,14 +607,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 584 | 607 | ty::Float(_) => {} |
| 585 | 608 | _ => unreachable!("{:?}", lane_ty), |
| 586 | 609 | } |
| 587 | match intrinsic { | |
| 610 | ||
| 611 | codegen_f16_f128::maybe_with_f16_to_f32(fx, lane, |fx, lane| match intrinsic { | |
| 588 | 612 | sym::simd_fabs => fx.bcx.ins().fabs(lane), |
| 589 | 613 | sym::simd_fsqrt => fx.bcx.ins().sqrt(lane), |
| 590 | 614 | sym::simd_ceil => fx.bcx.ins().ceil(lane), |
| 591 | 615 | sym::simd_floor => fx.bcx.ins().floor(lane), |
| 592 | 616 | sym::simd_trunc => fx.bcx.ins().trunc(lane), |
| 593 | 617 | _ => unreachable!(), |
| 594 | } | |
| 618 | }) | |
| 595 | 619 | }); |
| 596 | 620 | } |
| 597 | 621 | |
| ... | ... | @@ -607,7 +631,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 607 | 631 | |
| 608 | 632 | simd_reduce(fx, v, Some(acc), ret, &|fx, lane_ty, a, b| { |
| 609 | 633 | 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 | }) | |
| 611 | 637 | } else { |
| 612 | 638 | fx.bcx.ins().iadd(a, b) |
| 613 | 639 | } |
| ... | ... | @@ -625,7 +651,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 625 | 651 | |
| 626 | 652 | simd_reduce(fx, v, None, ret, &|fx, lane_ty, a, b| { |
| 627 | 653 | 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 | }) | |
| 629 | 657 | } else { |
| 630 | 658 | fx.bcx.ins().iadd(a, b) |
| 631 | 659 | } |
| ... | ... | @@ -644,7 +672,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 644 | 672 | |
| 645 | 673 | simd_reduce(fx, v, Some(acc), ret, &|fx, lane_ty, a, b| { |
| 646 | 674 | 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 | }) | |
| 648 | 678 | } else { |
| 649 | 679 | fx.bcx.ins().imul(a, b) |
| 650 | 680 | } |
| ... | ... | @@ -662,7 +692,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( |
| 662 | 692 | |
| 663 | 693 | simd_reduce(fx, v, None, ret, &|fx, lane_ty, a, b| { |
| 664 | 694 | 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 | }) | |
| 666 | 698 | } else { |
| 667 | 699 | fx.bcx.ins().imul(a, b) |
| 668 | 700 | } |
compiler/rustc_codegen_cranelift/src/num.rs+6-17| ... | ... | @@ -358,7 +358,6 @@ pub(crate) fn codegen_float_binop<'tcx>( |
| 358 | 358 | } else { |
| 359 | 359 | (lhs, rhs) |
| 360 | 360 | }; |
| 361 | let b = fx.bcx.ins(); | |
| 362 | 361 | let res = match bin_op { |
| 363 | 362 | // FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings |
| 364 | 363 | // have been added to Cranelift. |
| ... | ... | @@ -367,10 +366,10 @@ pub(crate) fn codegen_float_binop<'tcx>( |
| 367 | 366 | { |
| 368 | 367 | codegen_f16_f128::codegen_f128_binop(fx, bin_op, lhs, rhs) |
| 369 | 368 | } |
| 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), | |
| 374 | 373 | BinOp::Rem => { |
| 375 | 374 | let (name, ty, lhs, rhs) = match in_lhs.layout().ty.kind() { |
| 376 | 375 | ty::Float(FloatTy::F16) => ( |
| ... | ... | @@ -389,22 +388,12 @@ pub(crate) fn codegen_float_binop<'tcx>( |
| 389 | 388 | _ => bug!(), |
| 390 | 389 | }; |
| 391 | 390 | |
| 392 | let ret_val = fx.lib_call( | |
| 391 | fx.lib_call( | |
| 393 | 392 | name, |
| 394 | 393 | vec![AbiParam::new(ty), AbiParam::new(ty)], |
| 395 | 394 | vec![AbiParam::new(ty)], |
| 396 | 395 | &[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] | |
| 408 | 397 | } |
| 409 | 398 | BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => { |
| 410 | 399 | let fltcc = match bin_op { |
compiler/rustc_codegen_cranelift/src/pretty_clif.rs+1-7| ... | ... | @@ -60,7 +60,6 @@ use std::fmt; |
| 60 | 60 | use std::io::Write; |
| 61 | 61 | |
| 62 | 62 | use cranelift_codegen::entity::SecondaryMap; |
| 63 | use cranelift_codegen::ir::Fact; | |
| 64 | 63 | use cranelift_codegen::ir::entities::AnyEntity; |
| 65 | 64 | use cranelift_codegen::write::{FuncWriter, PlainWriter}; |
| 66 | 65 | use rustc_middle::ty::print::with_no_trimmed_paths; |
| ... | ... | @@ -182,13 +181,8 @@ impl FuncWriter for &'_ CommentWriter { |
| 182 | 181 | _func: &Function, |
| 183 | 182 | entity: AnyEntity, |
| 184 | 183 | value: &dyn fmt::Display, |
| 185 | maybe_fact: Option<&Fact>, | |
| 186 | 184 | ) -> 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)?; | |
| 192 | 186 | |
| 193 | 187 | if let Some(comment) = self.entity_comments.get(&entity) { |
| 194 | 188 | 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> { |
| 204 | 204 | let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field); |
| 205 | 205 | CValue::by_ref(field_ptr, field_layout) |
| 206 | 206 | } |
| 207 | CValueInner::ByRef(_, Some(_)) => todo!(), | |
| 207 | CValueInner::ByRef(_, Some(_)) => { | |
| 208 | bug!("value_field for unsized by-ref value not supported") | |
| 209 | } | |
| 208 | 210 | } |
| 209 | 211 | } |
| 210 | 212 | |
| ... | ... | @@ -655,7 +657,13 @@ impl<'tcx> CPlace<'tcx> { |
| 655 | 657 | flags, |
| 656 | 658 | ); |
| 657 | 659 | } |
| 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 | } | |
| 659 | 667 | } |
| 660 | 668 | } |
| 661 | 669 | } |
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+1| ... | ... | @@ -2350,6 +2350,7 @@ unsafe extern "C" { |
| 2350 | 2350 | pub(crate) fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); |
| 2351 | 2351 | |
| 2352 | 2352 | pub(crate) fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; |
| 2353 | pub(crate) fn LLVMRustTargetHasMnemonic(T: &TargetMachine, s: *const c_char) -> bool; | |
| 2353 | 2354 | |
| 2354 | 2355 | pub(crate) fn LLVMRustPrintTargetCPUs(TM: &TargetMachine, OutStr: &RustString); |
| 2355 | 2356 | 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) { |
| 480 | 480 | match req.kind { |
| 481 | 481 | PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out), |
| 482 | 482 | 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 | } | |
| 483 | 487 | _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req), |
| 484 | 488 | } |
| 485 | 489 | } |
| ... | ... | @@ -738,3 +742,10 @@ pub(crate) fn tune_cpu(sess: &Session) -> Option<&str> { |
| 738 | 742 | let name = sess.opts.unstable_opts.tune_cpu.as_ref()?; |
| 739 | 743 | Some(handle_native(name)) |
| 740 | 744 | } |
| 745 | ||
| 746 | fn 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; |
| 27 | 27 | /// the max/min element of the SCC, or all of the above. |
| 28 | 28 | /// |
| 29 | 29 | /// 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)` | |
| 31 | 31 | /// |
| 32 | 32 | /// In general, what you want is probably always min/max according |
| 33 | 33 | /// 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( |
| 804 | 804 | let calling_conventions = rustc_abi::all_names(); |
| 805 | 805 | println_info!("{}", calling_conventions.join("\n")); |
| 806 | 806 | } |
| 807 | BackendHasMnemonic => { | |
| 808 | codegen_backend.print(req, &mut crate_info, sess); | |
| 809 | } | |
| 807 | 810 | BackendHasZstd => { |
| 808 | 811 | let has_zstd: bool = codegen_backend.has_zstd(); |
| 809 | 812 | println_info!("{has_zstd}"); |
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp+20| ... | ... | @@ -19,6 +19,7 @@ |
| 19 | 19 | #include "llvm/IR/Verifier.h" |
| 20 | 20 | #include "llvm/IRPrinter/IRPrintingPasses.h" |
| 21 | 21 | #include "llvm/LTO/LTO.h" |
| 22 | #include "llvm/MC/MCInstrInfo.h" | |
| 22 | 23 | #include "llvm/MC/MCSubtargetInfo.h" |
| 23 | 24 | #include "llvm/MC/TargetRegistry.h" |
| 24 | 25 | #include "llvm/Object/ObjectFile.h" |
| ... | ... | @@ -94,6 +95,25 @@ extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, |
| 94 | 95 | return MCInfo->checkFeatures(std::string("+") + Feature); |
| 95 | 96 | } |
| 96 | 97 | |
| 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. | |
| 102 | extern "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 | ||
| 97 | 117 | enum class LLVMRustCodeModel { |
| 98 | 118 | Tiny, |
| 99 | 119 | Small, |
compiler/rustc_middle/src/ty/context.rs+4-4| ... | ... | @@ -1416,12 +1416,12 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1416 | 1416 | self, |
| 1417 | 1417 | stable_crate_id: StableCrateId, |
| 1418 | 1418 | ) -> 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) { | |
| 1420 | 1421 | return Err(existing); |
| 1421 | 1422 | } |
| 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); | |
| 1425 | 1425 | Ok(TyCtxtFeed { key: num, tcx: self }) |
| 1426 | 1426 | } |
| 1427 | 1427 |
compiler/rustc_mir_build/src/errors.rs+17-15| ... | ... | @@ -924,22 +924,24 @@ pub(crate) struct IrrefutableLetPatternsIfLetGuard { |
| 924 | 924 | } |
| 925 | 925 | |
| 926 | 926 | #[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")] | |
| 939 | 929 | pub(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 | )] | |
| 940 | pub(crate) struct LetElseReplacementSuggestion { | |
| 941 | #[primary_span] | |
| 942 | pub(crate) span: Span, | |
| 943 | pub(crate) lhs: String, | |
| 944 | pub(crate) rhs: String, | |
| 943 | 945 | } |
| 944 | 946 | |
| 945 | 947 | #[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> { |
| 168 | 168 | let Ok(()) = self.visit_land(ex, &mut chain_refutabilities) else { return }; |
| 169 | 169 | // Lint only single irrefutable let binding. |
| 170 | 170 | if let [Some((_, Irrefutable))] = chain_refutabilities[..] { |
| 171 | self.lint_single_let(ex.span, None); | |
| 171 | self.lint_single_let(ex.span, None, None); | |
| 172 | 172 | } |
| 173 | 173 | return; |
| 174 | 174 | } |
| ... | ... | @@ -438,7 +438,45 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { |
| 438 | 438 | if let LetSource::PlainLet = self.let_source { |
| 439 | 439 | self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span)); |
| 440 | 440 | } 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 | |
| 442 | 480 | } |
| 443 | 481 | } |
| 444 | 482 | |
| ... | ... | @@ -559,14 +597,20 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { |
| 559 | 597 | } |
| 560 | 598 | |
| 561 | 599 | #[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 | ) { | |
| 563 | 606 | report_irrefutable_let_patterns( |
| 564 | 607 | self.tcx, |
| 565 | 608 | self.hir_source, |
| 566 | 609 | self.let_source, |
| 567 | 610 | 1, |
| 568 | 611 | let_span, |
| 569 | else_span, | |
| 612 | else_keyword_span, | |
| 613 | let_else_span, | |
| 570 | 614 | ); |
| 571 | 615 | } |
| 572 | 616 | |
| ... | ... | @@ -862,7 +906,8 @@ fn report_irrefutable_let_patterns( |
| 862 | 906 | source: LetSource, |
| 863 | 907 | count: usize, |
| 864 | 908 | span: Span, |
| 865 | else_span: Option<Span>, | |
| 909 | else_keyword_span: Option<Span>, | |
| 910 | let_else_span: Option<LetElseReplacementSuggestion>, | |
| 866 | 911 | ) { |
| 867 | 912 | macro_rules! emit_diag { |
| 868 | 913 | ($lint:tt) => {{ |
| ... | ... | @@ -875,11 +920,23 @@ fn report_irrefutable_let_patterns( |
| 875 | 920 | LetSource::IfLet | LetSource::ElseIfLet => emit_diag!(IrrefutableLetPatternsIfLet), |
| 876 | 921 | LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard), |
| 877 | 922 | 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 | ||
| 878 | 935 | tcx.emit_node_span_lint( |
| 879 | 936 | IRREFUTABLE_LET_PATTERNS, |
| 880 | 937 | id, |
| 881 | span, | |
| 882 | IrrefutableLetPatternsLetElse { count, else_span }, | |
| 938 | spans, | |
| 939 | IrrefutableLetPatternsLetElse { be_replaced: let_else_span }, | |
| 883 | 940 | ); |
| 884 | 941 | } |
| 885 | 942 | LetSource::WhileLet => emit_diag!(IrrefutableLetPatternsWhileLet), |
compiler/rustc_session/src/config.rs+1-5| ... | ... | @@ -1487,11 +1487,7 @@ impl Options { |
| 1487 | 1487 | } |
| 1488 | 1488 | |
| 1489 | 1489 | 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) | |
| 1495 | 1491 | } |
| 1496 | 1492 | |
| 1497 | 1493 | #[inline] |
compiler/rustc_session/src/config/print_request.rs+31-6| ... | ... | @@ -15,6 +15,7 @@ use crate::macros::AllVariants; |
| 15 | 15 | pub struct PrintRequest { |
| 16 | 16 | pub kind: PrintKind, |
| 17 | 17 | pub out: OutFileName, |
| 18 | pub arg: Option<String>, | |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | 21 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
| ... | ... | @@ -22,6 +23,7 @@ pub struct PrintRequest { |
| 22 | 23 | pub enum PrintKind { |
| 23 | 24 | // tidy-alphabetical-start |
| 24 | 25 | AllTargetSpecsJson, |
| 26 | BackendHasMnemonic, | |
| 25 | 27 | BackendHasZstd, |
| 26 | 28 | CallingConventions, |
| 27 | 29 | Cfg, |
| ... | ... | @@ -55,6 +57,7 @@ impl PrintKind { |
| 55 | 57 | match self { |
| 56 | 58 | // tidy-alphabetical-start |
| 57 | 59 | AllTargetSpecsJson => "all-target-specs-json", |
| 60 | BackendHasMnemonic => "backend-has-mnemonic", | |
| 58 | 61 | BackendHasZstd => "backend-has-zstd", |
| 59 | 62 | CallingConventions => "calling-conventions", |
| 60 | 63 | Cfg => "cfg", |
| ... | ... | @@ -108,7 +111,8 @@ impl PrintKind { |
| 108 | 111 | |
| 109 | 112 | // Unstable values: |
| 110 | 113 | 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) | |
| 112 | 116 | CheckCfg => false, |
| 113 | 117 | CrateRootLintLevels => false, |
| 114 | 118 | SupportedCrateTypes => false, |
| ... | ... | @@ -145,11 +149,19 @@ pub(crate) fn collect_print_requests( |
| 145 | 149 | ) -> Vec<PrintRequest> { |
| 146 | 150 | let mut prints = Vec::<PrintRequest>::new(); |
| 147 | 151 | 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 | }); | |
| 149 | 157 | cg.target_cpu = None; |
| 150 | 158 | }; |
| 151 | 159 | 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 | }); | |
| 153 | 165 | cg.target_feature = String::new(); |
| 154 | 166 | } |
| 155 | 167 | |
| ... | ... | @@ -162,9 +174,22 @@ pub(crate) fn collect_print_requests( |
| 162 | 174 | prints.extend(matches.opt_strs("print").into_iter().map(|req| { |
| 163 | 175 | let (req, out) = split_out_file_name(&req); |
| 164 | 176 | |
| 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) { | |
| 166 | 191 | check_print_request_stability(early_dcx, unstable_opts, print_kind); |
| 167 | print_kind | |
| 192 | (print_kind, None) | |
| 168 | 193 | } else { |
| 169 | 194 | let is_nightly = nightly_options::match_is_nightly_build(matches); |
| 170 | 195 | emit_unknown_print_request_help(early_dcx, req, is_nightly) |
| ... | ... | @@ -180,7 +205,7 @@ pub(crate) fn collect_print_requests( |
| 180 | 205 | } |
| 181 | 206 | } |
| 182 | 207 | |
| 183 | PrintRequest { kind, out } | |
| 208 | PrintRequest { kind, out, arg } | |
| 184 | 209 | })); |
| 185 | 210 | |
| 186 | 211 | prints |
compiler/rustc_session/src/options.rs+1-1| ... | ... | @@ -2166,7 +2166,7 @@ options! { |
| 2166 | 2166 | "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), |
| 2167 | 2167 | symbol_mangling_version: Option<SymbolManglingVersion> = (None, |
| 2168 | 2168 | 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')"), | |
| 2170 | 2170 | target_cpu: Option<String> = (None, parse_opt_string, [TRACKED], |
| 2171 | 2171 | "select target processor (`rustc --print target-cpus` for details)"), |
| 2172 | 2172 | 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>( |
| 554 | 554 | // but they don't really need to right now. |
| 555 | 555 | ty::CoroutineClosure(_, _) => return Err(EvaluationFailure::NoSolution), |
| 556 | 556 | |
| 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), | |
| 562 | 558 | |
| 563 | 559 | // Everything else needs explicit impls or cannot have an impl |
| 564 | 560 | _ => return Err(EvaluationFailure::NoSolution), |
library/core/src/option.rs-3| ... | ... | @@ -40,9 +40,6 @@ |
| 40 | 40 | //! } |
| 41 | 41 | //! ``` |
| 42 | 42 | //! |
| 43 | // | |
| 44 | // FIXME: Show how `Option` is used in practice, with lots of methods | |
| 45 | // | |
| 46 | 43 | //! # Options and pointers ("nullable" pointers) |
| 47 | 44 | //! |
| 48 | 45 | //! 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 {} |
| 1794 | 1794 | /// have different sizes. |
| 1795 | 1795 | /// |
| 1796 | 1796 | /// ### ABI compatibility |
| 1797 | /// [ABI compatibility]: #abi-compatibility | |
| 1797 | 1798 | /// |
| 1798 | 1799 | /// Generally, when a function is declared with one signature and called via a function pointer with |
| 1799 | 1800 | /// a different signature, the two signatures must be *ABI-compatible* or else calling the function |
| ... | ... | @@ -1831,7 +1832,7 @@ mod prim_ref {} |
| 1831 | 1832 | /// - `*const T`, `*mut T`, `&T`, `&mut T`, `Box<T>` (specifically, only `Box<T, Global>`), and |
| 1832 | 1833 | /// `NonNull<T>` are all ABI-compatible with each other for all `T`. They are also ABI-compatible |
| 1833 | 1834 | /// 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. | |
| 1835 | 1836 | /// - `usize` is ABI-compatible with the `uN` integer type of the same size, and likewise `isize` is |
| 1836 | 1837 | /// ABI-compatible with the `iN` integer type of the same size. |
| 1837 | 1838 | /// - `char` is ABI-compatible with `u32`. |
| ... | ... | @@ -1890,6 +1891,8 @@ mod prim_ref {} |
| 1890 | 1891 | /// Behavior since transmuting `None::<NonZero<i32>>` to `NonZero<i32>` violates the non-zero |
| 1891 | 1892 | /// requirement. |
| 1892 | 1893 | /// |
| 1894 | /// [cfi-docs]: https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#controlflowintegrity | |
| 1895 | /// | |
| 1893 | 1896 | /// ### Trait implementations |
| 1894 | 1897 | /// |
| 1895 | 1898 | /// 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 |
| 400 | 400 | if min_index.eq(T::TRUE) { |
| 401 | 401 | None |
| 402 | 402 | } 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) | |
| 404 | 412 | } |
| 405 | 413 | } |
| 406 | 414 | } |
library/portable-simd/crates/core_simd/src/simd/num/float.rs+4-4| ... | ... | @@ -430,14 +430,14 @@ macro_rules! impl_trait { |
| 430 | 430 | |
| 431 | 431 | #[inline] |
| 432 | 432 | 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) | |
| 435 | 436 | } |
| 436 | 437 | |
| 437 | 438 | #[inline] |
| 438 | 439 | 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) | |
| 441 | 441 | } |
| 442 | 442 | } |
| 443 | 443 | )* |
library/portable-simd/crates/core_simd/src/simd/prelude.rs+4| ... | ... | @@ -14,6 +14,10 @@ pub use super::{ |
| 14 | 14 | simd_swizzle, |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | #[rustfmt::skip] | |
| 18 | #[doc(no_inline)] | |
| 19 | pub use super::{f16x1, f16x2, f16x4, f16x8, f16x16, f16x32, f16x64}; | |
| 20 | ||
| 17 | 21 | #[rustfmt::skip] |
| 18 | 22 | #[doc(no_inline)] |
| 19 | 23 | pub 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 { |
| 33 | 33 | } |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | macro_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 | ||
| 53 | 36 | macro_rules! ternary_test { |
| 54 | 37 | { $scalar:tt, $($func:tt),+ } => { |
| 55 | 38 | test_helpers::test_lanes! { |
| ... | ... | @@ -76,7 +59,19 @@ macro_rules! impl_tests { |
| 76 | 59 | |
| 77 | 60 | // https://github.com/rust-lang/miri/issues/3555 |
| 78 | 61 | 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 | } | |
| 80 | 75 | |
| 81 | 76 | test_helpers::test_lanes! { |
| 82 | 77 | 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 { |
| 122 | 122 | proptest::test_runner::TestRunner::new(proptest::test_runner::Config::with_cases(4)) |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | #[track_caller] | |
| 126 | fn 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 | ||
| 125 | 136 | /// Test a function that takes a single value. |
| 126 | 137 | pub fn test_1<A: core::fmt::Debug + DefaultStrategy>( |
| 127 | 138 | f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult, |
| 128 | 139 | ) { |
| 129 | 140 | let mut runner = make_runner(); |
| 130 | runner.run(&A::default_strategy(), f).unwrap(); | |
| 141 | unwrap_test_error(runner.run(&A::default_strategy(), f)) | |
| 131 | 142 | } |
| 132 | 143 | |
| 133 | 144 | /// 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 |
| 135 | 146 | f: &dyn Fn(A, B) -> proptest::test_runner::TestCaseResult, |
| 136 | 147 | ) { |
| 137 | 148 | 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)| { | |
| 140 | 151 | f(a, b) |
| 141 | }) | |
| 142 | .unwrap(); | |
| 152 | }), | |
| 153 | ) | |
| 143 | 154 | } |
| 144 | 155 | |
| 145 | 156 | /// Test a function that takes two values. |
| ... | ... | @@ -151,16 +162,14 @@ pub fn test_3< |
| 151 | 162 | f: &dyn Fn(A, B, C) -> proptest::test_runner::TestCaseResult, |
| 152 | 163 | ) { |
| 153 | 164 | 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 | )); | |
| 164 | 173 | } |
| 165 | 174 | |
| 166 | 175 | /// Test a unary vector function against a unary scalar function, applied elementwise. |
library/portable-simd/rust-toolchain.toml+1-1| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | [toolchain] |
| 2 | channel = "nightly-2026-03-18" | |
| 2 | channel = "nightly-2026-04-28" | |
| 3 | 3 | components = ["rustfmt", "clippy", "miri", "rust-src"] |
src/bootstrap/src/core/builder/cargo.rs+2-11| ... | ... | @@ -687,16 +687,6 @@ impl Builder<'_> { |
| 687 | 687 | rustflags.arg(sysroot_str); |
| 688 | 688 | } |
| 689 | 689 | |
| 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 | ||
| 700 | 690 | // By default, windows-rs depends on a native library that doesn't get copied into the |
| 701 | 691 | // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native |
| 702 | 692 | // library unnecessary. This can be removed when windows-rs enables raw-dylib |
| ... | ... | @@ -706,7 +696,8 @@ impl Builder<'_> { |
| 706 | 696 | rustflags.arg("--cfg=windows_raw_dylib"); |
| 707 | 697 | } |
| 708 | 698 | |
| 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 { | |
| 710 | 701 | rustflags.arg(if usm { |
| 711 | 702 | "-Csymbol-mangling-version=v0" |
| 712 | 703 | } 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. |
| 346 | 346 | If you need to work with `#![no_std]` cross-compiling tests, consult the |
| 347 | 347 | [`minicore` test auxiliary](./minicore.md) chapter. |
| 348 | 348 | |
| 349 | #### Conditional assembly tests based on instruction support | |
| 350 | ||
| 351 | Tests that depend on specific assembly instructions being available can use the | |
| 352 | `//@ needs-asm-mnemonic: <MNEMONIC>` directive. This will skip the test if the | |
| 353 | target backend does not support the specified instruction mnemonic. | |
| 354 | ||
| 355 | For example, a test that requires the `RET` instruction: | |
| 356 | ```rust,ignore | |
| 357 | //@ needs-asm-mnemonic: RET | |
| 358 | ``` | |
| 359 | ||
| 349 | 360 | [`tests/assembly-llvm`]: https://github.com/rust-lang/rust/tree/HEAD/tests/assembly-llvm |
| 350 | 361 | |
| 351 | 362 |
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: |
| 163 | 163 | For tests that cross-compile to explicit targets |
| 164 | 164 | via `--target`, use `needs-llvm-components` instead to ensure the appropriate |
| 165 | 165 | 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. | |
| 166 | 169 | - `needs-profiler-runtime` — ignores the test if the profiler runtime was not |
| 167 | 170 | enabled for the target (`build.profiler = true` in `bootstrap.toml`) |
| 168 | 171 | - `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 |
| 15 | 15 | ## Requirements |
| 16 | 16 | |
| 17 | 17 | ### Compilation |
| 18 | This 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). | |
| 18 | This 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). | |
| 19 | 19 | |
| 20 | 20 | `wali` targets *minimally require* the following LLVM feature flags: |
| 21 | 21 | |
| ... | ... | @@ -31,7 +31,7 @@ This target is cross-compiled and requires an installation of the [WALI compiler |
| 31 | 31 | > **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. |
| 32 | 32 | |
| 33 | 33 | |
| 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. | |
| 35 | 35 | |
| 36 | 36 | ### Execution |
| 37 | 37 | Running 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 |
| 41 | 41 | ## Building the target |
| 42 | 42 | |
| 43 | 43 | You can build Rust with support for the target by adding it to the `target` |
| 44 | list 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): | |
| 44 | list 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): | |
| 45 | 45 | |
| 46 | 46 | ```toml |
| 47 | 47 | [build] |
| 48 | 48 | target = ["wasm32-wali-linux-musl"] |
| 49 | 49 | |
| 50 | 50 | [target.wasm32-wali-linux-musl] |
| 51 | musl-root = "<WALI>/wali-musl/sysroot" | |
| 52 | llvm-config = "<WALI>/llvm-project/build/bin/llvm-config" | |
| 53 | cc = "<WALI>/llvm-project/build/bin/clang-18" | |
| 54 | cxx = "<WALI>/llvm-project/build/bin/clang-18" | |
| 55 | ar = "<WALI>/llvm-project/build/bin/llvm-ar" | |
| 56 | ranlib = "<WALI>/llvm-project/build/bin/llvm-ranlib" | |
| 51 | musl-root = "<WALI>/build/sysroot" | |
| 52 | cc = "<WALI>/build/llvm/bin/clang" | |
| 53 | cxx = "<WALI>/build/llvm/bin/clang++" | |
| 54 | ar = "<WALI>/build/llvm/bin/llvm-ar" | |
| 55 | ranlib = "<WALI>/build/llvm/bin/llvm-ranlib" | |
| 57 | 56 | llvm-libunwind = "system" |
| 58 | 57 | crt-static = true |
| 59 | 58 | ``` |
| 60 | 59 | |
| 61 | > The `llvm-config` settings are only temporary, and the changes will eventually be upstreamed into LLVM | |
| 62 | ||
| 63 | 60 | ## Building Rust programs |
| 64 | 61 | |
| 65 | 62 | Rust does not yet ship pre-compiled artifacts for this target. To compile for |
| 66 | 63 | this target, you will either need to build Rust with the target enabled (see |
| 67 | 64 | "Building the target" above), or build your own copy of `core` by using |
| 68 | `build-std` or similar. | |
| 69 | ||
| 70 | Rust 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] | |
| 74 | linker = "<WALI>/llvm-project/build/bin/lld" | |
| 75 | ``` | |
| 65 | `build-std` or similar (with the appropriate sysroot links). | |
| 76 | 66 | |
| 77 | 67 | Note that the following `cfg` directives are set for `wasm32-wali-linux-*`: |
| 78 | 68 |
src/doc/rustc/src/symbol-mangling/index.md+3-4| ... | ... | @@ -46,7 +46,6 @@ foo::example_function |
| 46 | 46 | |
| 47 | 47 | ## Mangling versions |
| 48 | 48 | |
| 49 | `rustc` supports different mangling versions which encode the names in different ways. | |
| 50 | The legacy version (which is currently the default on beta/stable) is not described here. | |
| 51 | The "v0" mangling scheme addresses several limitations of the legacy format, | |
| 52 | and is described in the [v0 Symbol Format](v0.md) chapter. | |
| 49 | There is currently one stable mangling scheme version - `v0`. On nightly builds, rustc supports | |
| 50 | switching back to the `legacy` mangling scheme using [`-C symbol-mangling-version`]. The `v0` | |
| 51 | mangling 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. |
| 246 | 246 | |
| 247 | 247 | See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. |
| 248 | 248 | |
| 249 | ## Divergence from the Rust ABI | |
| 250 | ||
| 251 | There are some caveats to [the ABI-compatibility rules for Rust-to-Rust | |
| 252 | calls][rust-abi] due to how the CFI sanitizer is implemented. CFI is a tool | |
| 253 | that can be used to validate that dynamic function calls respect the ABI, but | |
| 254 | due to its C/C++ origins, it disagrees with the above documented guarantees in | |
| 255 | a few ways, see below. As CFI is unstable, the details may change in the | |
| 256 | future. | |
| 257 | ||
| 258 | When running the CFI sanitizer, pointer types are only ABI-compatible if the | |
| 259 | target type and mutability is the same. This means that `*mut String` and `*mut | |
| 260 | i32` are incompatible when using CFI. It also means that `*mut i32` is | |
| 261 | incompatible with `*const i32`. The `NonNull<_>` and `Box<_>` pointer types are | |
| 262 | currently considered immutable under CFI. For non-primitive target types, CFI | |
| 263 | uses the name of the type for its compatibility check. | |
| 264 | ||
| 265 | When not using the `-Zsanitizer-cfi-normalize-integers` flag, the CFI sanitizer | |
| 266 | further restricts the rules by considering `usize`/`isize` incompatible with | |
| 267 | the `uN`/`iN` integer type of the same size. | |
| 268 | ||
| 269 | Unlike other cases where the function ABI is violated, function calls that | |
| 270 | violate the CFI-specific ABI-compatibility rules are not undefined behavior. | |
| 271 | They are guaranteed to either function correctly, or to crash the program. | |
| 272 | ||
| 273 | This section only covers cases where CFI disagrees with the ABI-compatibility | |
| 274 | rules for Rust-to-Rust calls. It is not meant to be a complete explanation of | |
| 275 | how CFI works, and details important for C-to-Rust or Rust-to-C calls are | |
| 276 | omitted. | |
| 277 | ||
| 278 | [rust-abi]: https://doc.rust-lang.org/stable/std/primitive.fn.html#abi-compatibility | |
| 279 | ||
| 249 | 280 | ## Example 1: Redirecting control flow using an indirect branch/call to an invalid destination |
| 250 | 281 | |
| 251 | 282 | ```rust |
src/tools/compiletest/src/directives/directive_names.rs+1| ... | ... | @@ -156,6 +156,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ |
| 156 | 156 | "min-llvm-version", |
| 157 | 157 | "min-system-llvm-version", |
| 158 | 158 | "minicore-compile-flags", |
| 159 | "needs-asm-mnemonic", | |
| 159 | 160 | "needs-asm-support", |
| 160 | 161 | "needs-backends", |
| 161 | 162 | "needs-crate-type", |
src/tools/compiletest/src/directives/needs.rs+60| ... | ... | @@ -290,6 +290,37 @@ pub(super) fn handle_needs( |
| 290 | 290 | } |
| 291 | 291 | } |
| 292 | 292 | |
| 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 | ||
| 293 | 324 | if !name.starts_with("needs-") { |
| 294 | 325 | return IgnoreDecision::Continue; |
| 295 | 326 | } |
| ... | ... | @@ -352,6 +383,10 @@ pub(super) struct CachedNeedsConditions { |
| 352 | 383 | symlinks: bool, |
| 353 | 384 | /// Whether LLVM built with zstd, for the `needs-llvm-zstd` directive. |
| 354 | 385 | 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, | |
| 355 | 390 | } |
| 356 | 391 | |
| 357 | 392 | impl CachedNeedsConditions { |
| ... | ... | @@ -399,6 +434,8 @@ impl CachedNeedsConditions { |
| 399 | 434 | llvm_zstd: llvm_has_zstd(&config), |
| 400 | 435 | dlltool: find_dlltool(&config), |
| 401 | 436 | symlinks: has_symlinks(), |
| 437 | has_ret_mnemonic: has_mnemonic(config, "ret"), | |
| 438 | has_nop_mnemonic: has_mnemonic(config, "nop"), | |
| 402 | 439 | } |
| 403 | 440 | } |
| 404 | 441 | } |
| ... | ... | @@ -466,3 +503,26 @@ fn llvm_has_zstd(config: &Config) -> bool { |
| 466 | 503 | _ => panic!("unexpected output from `--print=backend-has-zstd`: {output:?}"), |
| 467 | 504 | } |
| 468 | 505 | } |
| 506 | ||
| 507 | fn 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() { |
| 1254 | 1254 | assert_edition_to_test(2018, range, Some(e2024)); |
| 1255 | 1255 | assert_edition_to_test(2018, range, Some(efuture)); |
| 1256 | 1256 | } |
| 1257 | ||
| 1258 | #[test] | |
| 1259 | fn 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> { |
| 319 | 319 | TestMode::RustdocJs => true, |
| 320 | 320 | TestMode::Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build), |
| 321 | 321 | 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 | } | |
| 336 | 322 | mode => panic!("unimplemented for mode {:?}", mode), |
| 337 | 323 | } |
| 338 | 324 | } |
src/tools/compiletest/src/runtest/incremental.rs+89-77| ... | ... | @@ -1,26 +1,43 @@ |
| 1 | use super::{Emit, FailMode, PassMode, ProcRes, TestCx, WillExecute}; | |
| 1 | use std::sync::LazyLock; | |
| 2 | ||
| 3 | use crate::runtest::{Emit, TestCx, WillExecute}; | |
| 4 | use crate::util::string_enum; | |
| 5 | ||
| 6 | string_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 | ||
| 19 | impl 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 | } | |
| 2 | 37 | |
| 3 | 38 | impl TestCx<'_> { |
| 39 | /// Runs a single revision of an incremental test. | |
| 4 | 40 | 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 | ||
| 24 | 41 | let revision = self.revision.expect("incremental tests require a list of revisions"); |
| 25 | 42 | |
| 26 | 43 | // Incremental workproduct directory should have already been created. |
| ... | ... | @@ -31,68 +48,63 @@ impl TestCx<'_> { |
| 31 | 48 | write!(self.stdout, "revision={:?} props={:#?}", revision, self.props); |
| 32 | 49 | } |
| 33 | 50 | |
| 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 | } | |
| 44 | 89 | } |
| 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); | |
| 68 | 90 | |
| 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. | |
| 93 | 92 | let output_to_check = self.get_output(proc_res); |
| 94 | 93 | self.check_expected_errors(&proc_res); |
| 95 | 94 | self.check_all_error_patterns(&output_to_check, proc_res); |
| 96 | 95 | 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 | } | |
| 97 | 109 | } |
| 98 | 110 | } |
tests/codegen-llvm/function-arguments.rs+1-1| ... | ... | @@ -297,7 +297,7 @@ pub fn return_slice(x: &[u16]) -> &[u16] { |
| 297 | 297 | x |
| 298 | 298 | } |
| 299 | 299 | |
| 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) | |
| 301 | 301 | #[no_mangle] |
| 302 | 302 | pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> { |
| 303 | 303 | x |
tests/run-make/naked-dead-code-elimination/rmake.rs+1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | //@ ignore-cross-compile |
| 2 | 2 | //@ needs-asm-support |
| 3 | //@ needs-asm-mnemonic: RET | |
| 3 | 4 | |
| 4 | 5 | use run_make_support::symbols::object_contains_any_symbol; |
| 5 | 6 | use run_make_support::{bin_name, rustc}; |
tests/run-make/print-request-help-stable-unstable/help-diff.diff+1-1| ... | ... | @@ -2,6 +2,6 @@ |
| 2 | 2 | error: unknown print request: `xxx` |
| 3 | 3 | | |
| 4 | 4 | - = 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` | |
| 6 | 6 | = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information |
| 7 | 7 |
tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error: unknown print request: `xxx` |
| 2 | 2 | | |
| 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` | |
| 4 | 4 | = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information |
| 5 | 5 |
tests/run-make/rustc-help/help-v.stdout+1-1| ... | ... | @@ -43,7 +43,7 @@ Options: |
| 43 | 43 | --print <INFO>[=<FILE>] |
| 44 | 44 | Compiler information to print on stdout (or to a file) |
| 45 | 45 | 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>. | |
| 47 | 47 | -g Equivalent to -C debuginfo=2 |
| 48 | 48 | -O Equivalent to -C opt-level=3 |
| 49 | 49 | -o <FILENAME> Write output to FILENAME |
tests/run-make/rustc-help/help.stdout+1-1| ... | ... | @@ -43,7 +43,7 @@ Options: |
| 43 | 43 | --print <INFO>[=<FILE>] |
| 44 | 44 | Compiler information to print on stdout (or to a file) |
| 45 | 45 | 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>. | |
| 47 | 47 | -g Equivalent to -C debuginfo=2 |
| 48 | 48 | -O Equivalent to -C opt-level=3 |
| 49 | 49 | -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 |
| 3 | 3 | --print <INFO>[=<FILE>] |
| 4 | 4 | Compiler information to print on stdout (or to a file) |
| 5 | 5 | 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>. | |
| 7 | 7 |
tests/ui/compile-flags/invalid/print.stderr+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | error: unknown print request: `yyyy` |
| 2 | 2 | | |
| 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` | |
| 4 | 4 | = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information |
| 5 | 5 |
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)] | |
| 10 | const fn partial_compare() { | |
| 11 | let len_chain = const move |_a: &_, _b: &_| {}; | |
| 12 | ||
| 13 | chaining_impl(len_chain); | |
| 14 | } | |
| 15 | ||
| 16 | const fn chaining_impl(x: impl for<'a> [const] FnOnce(&'a usize, &'a usize)) { | |
| 17 | std::mem::forget(x); | |
| 18 | } | |
| 19 | ||
| 20 | fn main() {} |
tests/ui/let-else/let-else-irrefutable-152938.rs+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | pub fn say_hello(name: Option<String>) { |
| 8 | 8 | let name_str = Some(name) else { return; }; |
| 9 | //~^ WARN irrefutable `let...else` pattern | |
| 9 | //~^ WARN unreachable `else` clause | |
| 10 | 10 | drop(name_str); |
| 11 | 11 | } |
| 12 | 12 |
tests/ui/let-else/let-else-irrefutable-152938.stderr+10-8| ... | ... | @@ -1,16 +1,18 @@ |
| 1 | warning: irrefutable `let...else` pattern | |
| 2 | --> $DIR/let-else-irrefutable-152938.rs:8:5 | |
| 1 | warning: unreachable `else` clause | |
| 2 | --> $DIR/let-else-irrefutable-152938.rs:8:31 | |
| 3 | 3 | | |
| 4 | 4 | LL | let name_str = Some(name) else { return; }; |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 5 | | ------------------------- ^^^^ | |
| 6 | | | | |
| 7 | | assigning to binding pattern will always succeed | |
| 6 | 8 | | |
| 7 | 9 | = note: this pattern always matches, so the else clause is unreachable |
| 8 | help: remove this `else` block | |
| 9 | --> $DIR/let-else-irrefutable-152938.rs:8:36 | |
| 10 | | | |
| 11 | LL | let name_str = Some(name) else { return; }; | |
| 12 | | ^^^^^^^^^^^ | |
| 13 | 10 | = note: `#[warn(irrefutable_let_patterns)]` on by default |
| 11 | help: consider using `let Some(name_str) = name` to match on a specific variant | |
| 12 | | | |
| 13 | LL - let name_str = Some(name) else { return; }; | |
| 14 | LL + let Some(name_str) = name else { return; }; | |
| 15 | | | |
| 14 | 16 | |
| 15 | 17 | warning: 1 warning emitted |
| 16 | 18 |
tests/ui/let-else/let-else-irrefutable.rs+10-2| ... | ... | @@ -1,10 +1,18 @@ |
| 1 | 1 | //@ check-pass |
| 2 | 2 | |
| 3 | 3 | fn main() { |
| 4 | let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern | |
| 4 | let x = 1 else { return }; //~ WARN unreachable `else` clause | |
| 5 | 5 | |
| 6 | 6 | // 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 | |
| 8 | 16 | eprintln!("problem case encountered"); |
| 9 | 17 | return |
| 10 | 18 | }; |
tests/ui/let-else/let-else-irrefutable.stderr+26-21| ... | ... | @@ -1,33 +1,38 @@ |
| 1 | warning: irrefutable `let...else` pattern | |
| 2 | --> $DIR/let-else-irrefutable.rs:4:5 | |
| 1 | warning: unreachable `else` clause | |
| 2 | --> $DIR/let-else-irrefutable.rs:4:15 | |
| 3 | 3 | | |
| 4 | 4 | LL | let x = 1 else { return }; |
| 5 | | ^^^^^^^^^ | |
| 5 | | --------- ^^^^ | |
| 6 | | | | |
| 7 | | assigning to binding pattern will always succeed | |
| 6 | 8 | | |
| 7 | 9 | = note: this pattern always matches, so the else clause is unreachable |
| 8 | help: remove this `else` block | |
| 9 | --> $DIR/let-else-irrefutable.rs:4:20 | |
| 10 | | | |
| 11 | LL | let x = 1 else { return }; | |
| 12 | | ^^^^^^^^^^ | |
| 13 | 10 | = note: `#[warn(irrefutable_let_patterns)]` on by default |
| 14 | 11 | |
| 15 | warning: irrefutable `let...else` pattern | |
| 16 | --> $DIR/let-else-irrefutable.rs:7:5 | |
| 12 | warning: unreachable `else` clause | |
| 13 | --> $DIR/let-else-irrefutable.rs:7:15 | |
| 17 | 14 | | |
| 18 | 15 | LL | 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 | ||
| 22 | warning: unreachable `else` clause | |
| 23 | --> $DIR/let-else-irrefutable.rs:13:27 | |
| 24 | | | |
| 25 | LL | let name = Some(case) else { | |
| 26 | | --------------------- ^^^^ | |
| 27 | | | | |
| 28 | | assigning to binding pattern will always succeed | |
| 20 | 29 | | |
| 21 | 30 | = note: this pattern always matches, so the else clause is unreachable |
| 22 | help: remove this `else` block | |
| 23 | --> $DIR/let-else-irrefutable.rs:7:20 | |
| 24 | | | |
| 25 | LL | let x = 1 else { | |
| 26 | | ____________________^ | |
| 27 | LL | | eprintln!("problem case encountered"); | |
| 28 | LL | | return | |
| 29 | LL | | }; | |
| 30 | | |_____^ | |
| 31 | help: consider using `let Some(name) = case` to match on a specific variant | |
| 32 | | | |
| 33 | LL - let name = Some(case) else { | |
| 34 | LL + let Some(name) = case else { | |
| 35 | | | |
| 31 | 36 | |
| 32 | warning: 2 warnings emitted | |
| 37 | warning: 3 warnings emitted | |
| 33 | 38 |
tests/ui/parser/bad-let-else-statement.rs+8-8| ... | ... | @@ -93,10 +93,10 @@ fn i() { |
| 93 | 93 | fn j() { |
| 94 | 94 | let mut bar = 0; |
| 95 | 95 | let foo = bar = { |
| 96 | //~^ WARN irrefutable `let...else` pattern | |
| 97 | 96 | 1 |
| 98 | 97 | } 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 | |
| 100 | 100 | return; |
| 101 | 101 | }; |
| 102 | 102 | } |
| ... | ... | @@ -158,21 +158,21 @@ fn o() -> Result<(), ()> { |
| 158 | 158 | |
| 159 | 159 | fn q() { |
| 160 | 160 | let foo = |x: i32| { |
| 161 | //~^ WARN irrefutable `let...else` pattern | |
| 162 | 161 | x |
| 163 | 162 | } 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 | |
| 165 | 165 | return; |
| 166 | 166 | }; |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | fn r() { |
| 170 | 170 | let ok = format_args!("") else { return; }; |
| 171 | //~^ WARN irrefutable `let...else` pattern | |
| 171 | //~^ WARN unreachable `else` clause | |
| 172 | 172 | |
| 173 | 173 | let bad = format_args! {""} else { return; }; |
| 174 | 174 | //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed |
| 175 | //~| WARN irrefutable `let...else` pattern | |
| 175 | //~| WARN unreachable `else` clause | |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | fn s() { |
| ... | ... | @@ -202,10 +202,10 @@ fn t() { |
| 202 | 202 | } |
| 203 | 203 | |
| 204 | 204 | let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! { |
| 205 | //~^ WARN irrefutable `let...else` pattern | |
| 206 | 205 | 8 |
| 207 | 206 | } 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 | |
| 209 | 209 | return; |
| 210 | 210 | }; |
| 211 | 211 | } |
tests/ui/parser/bad-let-else-statement.stderr+28-61| ... | ... | @@ -125,7 +125,7 @@ LL ~ }) else { |
| 125 | 125 | | |
| 126 | 126 | |
| 127 | 127 | error: 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 | |
| 129 | 129 | | |
| 130 | 130 | LL | } else { |
| 131 | 131 | | ^ |
| ... | ... | @@ -133,7 +133,6 @@ LL | } else { |
| 133 | 133 | help: wrap the expression in parentheses |
| 134 | 134 | | |
| 135 | 135 | LL ~ let foo = bar = ({ |
| 136 | LL | | |
| 137 | 136 | LL | 1 |
| 138 | 137 | LL ~ }) else { |
| 139 | 138 | | |
| ... | ... | @@ -204,7 +203,7 @@ LL ~ }) else { |
| 204 | 203 | | |
| 205 | 204 | |
| 206 | 205 | error: 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 | |
| 208 | 207 | | |
| 209 | 208 | LL | } else { |
| 210 | 209 | | ^ |
| ... | ... | @@ -212,7 +211,6 @@ LL | } else { |
| 212 | 211 | help: wrap the expression in parentheses |
| 213 | 212 | | |
| 214 | 213 | LL ~ let foo = |x: i32| ({ |
| 215 | LL | | |
| 216 | 214 | LL | x |
| 217 | 215 | LL ~ }) else { |
| 218 | 216 | | |
| ... | ... | @@ -230,7 +228,7 @@ LL + let bad = format_args! ("") else { return; }; |
| 230 | 228 | | |
| 231 | 229 | |
| 232 | 230 | error: 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 | |
| 234 | 232 | | |
| 235 | 233 | LL | } else { |
| 236 | 234 | | ^ |
| ... | ... | @@ -238,7 +236,6 @@ LL | } else { |
| 238 | 236 | help: use parentheses instead of braces for this macro |
| 239 | 237 | | |
| 240 | 238 | LL ~ let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! ( |
| 241 | LL | | |
| 242 | 239 | LL | 8 |
| 243 | 240 | LL ~ ) else { |
| 244 | 241 | | |
| ... | ... | @@ -259,92 +256,62 @@ LL - let 0 = a! {} else { return; }; |
| 259 | 256 | LL + let 0 = a! () else { return; }; |
| 260 | 257 | | |
| 261 | 258 | |
| 262 | warning: irrefutable `let...else` pattern | |
| 263 | --> $DIR/bad-let-else-statement.rs:95:5 | |
| 259 | warning: unreachable `else` clause | |
| 260 | --> $DIR/bad-let-else-statement.rs:97:7 | |
| 264 | 261 | | |
| 265 | 262 | LL | / let foo = bar = { |
| 266 | LL | | | |
| 267 | 263 | LL | | 1 |
| 268 | 264 | LL | | } else { |
| 269 | | |_____^ | |
| 265 | | | - ^^^^ | |
| 266 | | |_____| | |
| 267 | | assigning to binding pattern will always succeed | |
| 270 | 268 | | |
| 271 | 269 | = note: this pattern always matches, so the else clause is unreachable |
| 272 | help: remove this `else` block | |
| 273 | --> $DIR/bad-let-else-statement.rs:98:12 | |
| 274 | | | |
| 275 | LL | } else { | |
| 276 | | ____________^ | |
| 277 | LL | | | |
| 278 | LL | | return; | |
| 279 | LL | | }; | |
| 280 | | |_____^ | |
| 281 | 270 | = note: `#[warn(irrefutable_let_patterns)]` on by default |
| 282 | 271 | |
| 283 | warning: irrefutable `let...else` pattern | |
| 284 | --> $DIR/bad-let-else-statement.rs:160:5 | |
| 272 | warning: unreachable `else` clause | |
| 273 | --> $DIR/bad-let-else-statement.rs:162:7 | |
| 285 | 274 | | |
| 286 | 275 | LL | / let foo = |x: i32| { |
| 287 | LL | | | |
| 288 | 276 | LL | | x |
| 289 | 277 | LL | | } else { |
| 290 | | |_____^ | |
| 278 | | | - ^^^^ | |
| 279 | | |_____| | |
| 280 | | assigning to binding pattern will always succeed | |
| 291 | 281 | | |
| 292 | 282 | = note: this pattern always matches, so the else clause is unreachable |
| 293 | help: remove this `else` block | |
| 294 | --> $DIR/bad-let-else-statement.rs:163:12 | |
| 295 | | | |
| 296 | LL | } else { | |
| 297 | | ____________^ | |
| 298 | LL | | | |
| 299 | LL | | return; | |
| 300 | LL | | }; | |
| 301 | | |_____^ | |
| 302 | 283 | |
| 303 | warning: irrefutable `let...else` pattern | |
| 304 | --> $DIR/bad-let-else-statement.rs:170:5 | |
| 284 | warning: unreachable `else` clause | |
| 285 | --> $DIR/bad-let-else-statement.rs:170:31 | |
| 305 | 286 | | |
| 306 | 287 | LL | let ok = format_args!("") else { return; }; |
| 307 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 288 | | ------------------------- ^^^^ | |
| 289 | | | | |
| 290 | | assigning to binding pattern will always succeed | |
| 308 | 291 | | |
| 309 | 292 | = note: this pattern always matches, so the else clause is unreachable |
| 310 | help: remove this `else` block | |
| 311 | --> $DIR/bad-let-else-statement.rs:170:36 | |
| 312 | | | |
| 313 | LL | let ok = format_args!("") else { return; }; | |
| 314 | | ^^^^^^^^^^^ | |
| 315 | 293 | |
| 316 | warning: irrefutable `let...else` pattern | |
| 317 | --> $DIR/bad-let-else-statement.rs:173:5 | |
| 294 | warning: unreachable `else` clause | |
| 295 | --> $DIR/bad-let-else-statement.rs:173:33 | |
| 318 | 296 | | |
| 319 | 297 | LL | let bad = format_args! {""} else { return; }; |
| 320 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 298 | | --------------------------- ^^^^ | |
| 299 | | | | |
| 300 | | assigning to binding pattern will always succeed | |
| 321 | 301 | | |
| 322 | 302 | = note: this pattern always matches, so the else clause is unreachable |
| 323 | help: remove this `else` block | |
| 324 | --> $DIR/bad-let-else-statement.rs:173:38 | |
| 325 | | | |
| 326 | LL | let bad = format_args! {""} else { return; }; | |
| 327 | | ^^^^^^^^^^^ | |
| 328 | 303 | |
| 329 | warning: irrefutable `let...else` pattern | |
| 330 | --> $DIR/bad-let-else-statement.rs:204:5 | |
| 304 | warning: unreachable `else` clause | |
| 305 | --> $DIR/bad-let-else-statement.rs:206:7 | |
| 331 | 306 | | |
| 332 | 307 | LL | / let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! { |
| 333 | LL | | | |
| 334 | 308 | LL | | 8 |
| 335 | 309 | LL | | } else { |
| 336 | | |_____^ | |
| 310 | | | - ^^^^ | |
| 311 | | |_____| | |
| 312 | | assigning to binding pattern will always succeed | |
| 337 | 313 | | |
| 338 | 314 | = note: this pattern always matches, so the else clause is unreachable |
| 339 | help: remove this `else` block | |
| 340 | --> $DIR/bad-let-else-statement.rs:207:12 | |
| 341 | | | |
| 342 | LL | } else { | |
| 343 | | ____________^ | |
| 344 | LL | | | |
| 345 | LL | | return; | |
| 346 | LL | | }; | |
| 347 | | |_____^ | |
| 348 | 315 | |
| 349 | 316 | error: aborting due to 19 previous errors; 5 warnings emitted |
| 350 | 317 |
tests/ui/print-request/print-lints-help.stderr+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | error: unknown print request: `lints` |
| 2 | 2 | | |
| 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` | |
| 4 | 4 | = help: use `-Whelp` to print a list of lints |
| 5 | 5 | = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information |
| 6 | 6 |
tests/ui/span/let-offset-of.rs+1-1| ... | ... | @@ -15,5 +15,5 @@ fn init_to_offset_of() { |
| 15 | 15 | //~^ WARN irrefutable `if let` pattern |
| 16 | 16 | |
| 17 | 17 | let x = offset_of!(Foo, field) else { return; }; |
| 18 | //~^ WARN irrefutable `let...else` pattern | |
| 18 | //~^ WARN unreachable `else` clause | |
| 19 | 19 | } |
tests/ui/span/let-offset-of.stderr+5-8| ... | ... | @@ -8,18 +8,15 @@ LL | if let x = offset_of!(Foo, field) {} |
| 8 | 8 | = help: consider replacing the `if let` with a `let` |
| 9 | 9 | = note: `#[warn(irrefutable_let_patterns)]` on by default |
| 10 | 10 | |
| 11 | warning: irrefutable `let...else` pattern | |
| 12 | --> $DIR/let-offset-of.rs:17:5 | |
| 11 | warning: unreachable `else` clause | |
| 12 | --> $DIR/let-offset-of.rs:17:36 | |
| 13 | 13 | | |
| 14 | 14 | LL | let x = offset_of!(Foo, field) else { return; }; |
| 15 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 15 | | ------------------------------ ^^^^ | |
| 16 | | | | |
| 17 | | assigning to binding pattern will always succeed | |
| 16 | 18 | | |
| 17 | 19 | = note: this pattern always matches, so the else clause is unreachable |
| 18 | help: remove this `else` block | |
| 19 | --> $DIR/let-offset-of.rs:17:41 | |
| 20 | | | |
| 21 | LL | let x = offset_of!(Foo, field) else { return; }; | |
| 22 | | ^^^^^^^^^^^ | |
| 23 | 20 | |
| 24 | 21 | warning: 2 warnings emitted |
| 25 | 22 |
triagebot.toml-4| ... | ... | @@ -940,10 +940,6 @@ Issue #{number} "{title}" has been added. |
| 940 | 940 | # Mentions |
| 941 | 941 | # ------------------------------------------------------------------------------ |
| 942 | 942 | |
| 943 | [mentions."triagebot.toml"] | |
| 944 | message = "`triagebot.toml` has been modified, there may have been changes to the review queue." | |
| 945 | cc = ["@davidtwco", "@wesleywiser"] | |
| 946 | ||
| 947 | 943 | [mentions."compiler/rustc_codegen_cranelift"] |
| 948 | 944 | message = "The Cranelift subtree was changed" |
| 949 | 945 | cc = ["@bjorn3"] |