From f7ae9e11fc67f6bbbe06c095983c928225f39b88 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Feb 2025 12:19:21 +0100 Subject: [PATCH 01/11] adjust_abi: make fallback logic for ABIs a bit easier to read --- compiler/rustc_target/src/spec/mod.rs | 37 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 65736770efb8c..4c633bb9f5199 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2862,20 +2862,35 @@ impl Target { // On Windows, `extern "system"` behaves like msvc's `__stdcall`. // `__stdcall` only applies on x86 and on non-variadic functions: // https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170 - System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => { - Stdcall { unwind } + System { unwind } => { + if self.is_like_windows && self.arch == "x86" && !c_variadic { + Stdcall { unwind } + } else { + C { unwind } + } + } + + EfiApi => { + if self.arch == "arm" { + Aapcs { unwind: false } + } else if self.arch == "x86_64" { + Win64 { unwind: false } + } else { + C { unwind: false } + } } - System { unwind } => C { unwind }, - EfiApi if self.arch == "arm" => Aapcs { unwind: false }, - EfiApi if self.arch == "x86_64" => Win64 { unwind: false }, - EfiApi => C { unwind: false }, // See commentary in `is_abi_supported`. - Stdcall { .. } | Thiscall { .. } if self.arch == "x86" => abi, - Stdcall { unwind } | Thiscall { unwind } => C { unwind }, - Fastcall { .. } if self.arch == "x86" => abi, - Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => abi, - Fastcall { unwind } | Vectorcall { unwind } => C { unwind }, + Stdcall { unwind } | Thiscall { unwind } | Fastcall { unwind } => { + if self.arch == "x86" { abi } else { C { unwind } } + } + Vectorcall { unwind } => { + if ["x86", "x86_64"].contains(&&*self.arch) { + abi + } else { + C { unwind } + } + } // The Windows x64 calling convention we use for `extern "Rust"` // From 11959a8b6e75d2c55500a703070a248342d29549 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 23 Feb 2025 14:44:27 +0800 Subject: [PATCH 02/11] Fix invalid suggestion from type error for derive macro --- .../src/fn_ctxt/suggestions.rs | 14 +++++++++----- .../auxiliary/derive-demo-issue-136343.rs | 7 +++++++ ...alid-sugg-for-derive-macro-issue-136343.rs | 9 +++++++++ ...-sugg-for-derive-macro-issue-136343.stderr | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs create mode 100644 tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs create mode 100644 tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index f9fc121593637..35a3491f7c089 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{ExpnKind, Ident, MacroKind, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt; @@ -1365,6 +1365,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ty::TraitRef::new(self.tcx, into_def_id, [expr_ty, expected_ty]), )) + && !expr + .span + .macro_backtrace() + .any(|x| matches!(x.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, ..))) { let span = expr.span.find_oldest_ancestor_in_same_ctxt(); @@ -1380,10 +1384,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name))); } diag.multipart_suggestion( - format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"), - sugg, - Applicability::MaybeIncorrect - ); + format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"), + sugg, + Applicability::MaybeIncorrect + ); return true; } diff --git a/tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs b/tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs new file mode 100644 index 0000000000000..65be439b49a96 --- /dev/null +++ b/tests/ui/typeck/auxiliary/derive-demo-issue-136343.rs @@ -0,0 +1,7 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Sample)] +pub fn sample(_: TokenStream) -> TokenStream { + "fn bad, U>(a: T) -> U { a }".parse().unwrap() +} diff --git a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs new file mode 100644 index 0000000000000..c08030fc5c150 --- /dev/null +++ b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs @@ -0,0 +1,9 @@ +//@ proc-macro: derive-demo-issue-136343.rs + +#[macro_use] +extern crate derive_demo_issue_136343; + +#[derive(Sample)] //~ ERROR mismatched types +struct Test; + +fn main() {} diff --git a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr new file mode 100644 index 0000000000000..0b9c1d9123aab --- /dev/null +++ b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/invalid-sugg-for-derive-macro-issue-136343.rs:6:10 + | +LL | #[derive(Sample)] + | ^^^^^^ + | | + | expected type parameter `U`, found type parameter `T` + | expected `U` because of return type + | + = note: expected type parameter `U` + found type parameter `T` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + = note: the caller chooses a type for `U` which can be different from `T` + = note: this error originates in the derive macro `Sample` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 86b53db3e618fb89df012748180144c3c586b6e0 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Feb 2025 16:41:38 +0000 Subject: [PATCH 03/11] type_ir: remove redundant part of comment This refers to a `PredicatePolarity::Reserved` which no longer exists. --- compiler/rustc_type_ir/src/predicate.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 51790b13ec776..46385ca3a6fdb 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -131,8 +131,6 @@ pub struct TraitPredicate { /// If polarity is Negative: we are proving that a negative impl of this trait /// exists. (Note that coherence also checks whether negative impls of supertraits /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. pub polarity: PredicatePolarity, } From 1ee134f10dafe4374ff0de6d50bedcb01fee5296 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 13 Feb 2025 15:10:49 +0000 Subject: [PATCH 04/11] feature: fix typo in attribute description The force inlining attribute isn't is never used with `#![..]` attribute syntax, only `#[..]` syntax. --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- tests/ui/force-inlining/gate.rs | 4 ++-- tests/ui/force-inlining/gate.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6d16dc00ef4e4..306535bf7642e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1011,7 +1011,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), rustc_attr!( rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, - "#![rustc_force_inline] forces a free function to be inlined" + "#[rustc_force_inline] forces a free function to be inlined" ), // ========================================================================== diff --git a/tests/ui/force-inlining/gate.rs b/tests/ui/force-inlining/gate.rs index d6a01a74a44b5..cea094c14f2d6 100644 --- a/tests/ui/force-inlining/gate.rs +++ b/tests/ui/force-inlining/gate.rs @@ -2,11 +2,11 @@ #![allow(internal_features)] #[rustc_force_inline] -//~^ ERROR #![rustc_force_inline] forces a free function to be inlined +//~^ ERROR #[rustc_force_inline] forces a free function to be inlined pub fn bare() { } #[rustc_force_inline = "the test requires it"] -//~^ ERROR #![rustc_force_inline] forces a free function to be inlined +//~^ ERROR #[rustc_force_inline] forces a free function to be inlined pub fn justified() { } diff --git a/tests/ui/force-inlining/gate.stderr b/tests/ui/force-inlining/gate.stderr index e3973a08c232b..964d43fa18f6a 100644 --- a/tests/ui/force-inlining/gate.stderr +++ b/tests/ui/force-inlining/gate.stderr @@ -1,4 +1,4 @@ -error[E0658]: #![rustc_force_inline] forces a free function to be inlined +error[E0658]: #[rustc_force_inline] forces a free function to be inlined --> $DIR/gate.rs:4:1 | LL | #[rustc_force_inline] @@ -7,7 +7,7 @@ LL | #[rustc_force_inline] = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: #![rustc_force_inline] forces a free function to be inlined +error[E0658]: #[rustc_force_inline] forces a free function to be inlined --> $DIR/gate.rs:9:1 | LL | #[rustc_force_inline = "the test requires it"] From 6b2f5cf43ffd9a71883bd2ddd82e65ad7ef4bf86 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Feb 2025 11:52:33 +0100 Subject: [PATCH 05/11] Update browser-ui-test version to `0.20.3` --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index a158e5b6253cd..3428dd4826a73 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.20.2 \ No newline at end of file +0.20.3 \ No newline at end of file From 592028a2fc5f2f9af5aa7d802111b81393736ea0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Feb 2025 14:27:33 +0100 Subject: [PATCH 06/11] Add rustdoc-gui regression test for #137082 --- tests/rustdoc-gui/code-example-buttons.goml | 2 ++ tests/rustdoc-gui/copy-path.goml | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-gui/code-example-buttons.goml b/tests/rustdoc-gui/code-example-buttons.goml index c62683b45da9e..b96f6ddcc37aa 100644 --- a/tests/rustdoc-gui/code-example-buttons.goml +++ b/tests/rustdoc-gui/code-example-buttons.goml @@ -26,6 +26,8 @@ click: ".example-wrap .copy-button" move-cursor-to: ".search-input" assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0) assert-css: (".example-wrap .copy-button", { "visibility": "hidden" }) +// Since we clicked on the copy button, the clipboard content should have been updated. +assert-clipboard: 'println!("nothing fancy");\nprintln!("but with two lines!");' define-function: ( "check-buttons", diff --git a/tests/rustdoc-gui/copy-path.goml b/tests/rustdoc-gui/copy-path.goml index dc05b96f7aed1..e8766688f8d5e 100644 --- a/tests/rustdoc-gui/copy-path.goml +++ b/tests/rustdoc-gui/copy-path.goml @@ -1,12 +1,17 @@ // Checks that the "copy path" button is not triggering JS error and its display -// isn't broken. -go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" +// isn't broken and the copied path is as expected. +go-to: "file://" + |DOC_PATH| + "/test_docs/foreign_impl_order/trait.Foo.html" + +// We ensure that the clipboard is empty. +assert-clipboard: "" // First we store the size of the button before we click on it. store-size: ("#copy-path", {"width": width, "height": height}) click: "#copy-path" // We wait for the new text to appear. wait-for: "#copy-path.clicked" +// We check that the clipboard value is the expected one. +assert-clipboard: "test_docs::foreign_impl_order::Foo" // We check that the size didn't change. assert-size: ("#copy-path.clicked", {"width": |width|, "height": |height|}) // We wait for the button to turn back to its original state. From bab03bf1768fea8512ece42dea6d66f6f4743145 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Feb 2025 22:05:48 +0000 Subject: [PATCH 07/11] Improve behavior of IF_LET_RESCOPE around temporaries and place expressions --- compiler/rustc_lint/src/if_let_rescope.rs | 140 ++++++++---------- .../lint-if-let-rescope-false-positives.rs | 29 ++++ 2 files changed, 92 insertions(+), 77 deletions(-) create mode 100644 tests/ui/drop/lint-if-let-rescope-false-positives.rs diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index c1aa95667da68..7a6d656d00dc1 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -1,7 +1,7 @@ use std::iter::repeat; use std::ops::ControlFlow; -use hir::intravisit::Visitor; +use hir::intravisit::{self, Visitor}; use rustc_ast::Recovered; use rustc_errors::{ Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic, SuggestionStyle, @@ -9,6 +9,7 @@ use rustc_errors::{ use rustc_hir::{self as hir, HirIdSet}; use rustc_macros::LintDiagnostic; use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::adjustment::Adjust; use rustc_session::lint::{FutureIncompatibilityReason, LintId}; use rustc_session::{declare_lint, impl_lint_pass}; use rustc_span::Span; @@ -160,7 +161,7 @@ impl IfLetRescope { let lifetime_end = source_map.end_point(conseq.span); if let ControlFlow::Break(significant_dropper) = - (FindSignificantDropper { cx }).visit_expr(init) + (FindSignificantDropper { cx }).check_if_let_scrutinee(init) { first_if_to_lint = first_if_to_lint.or_else(|| Some((span, expr.hir_id))); significant_droppers.push(significant_dropper); @@ -363,96 +364,81 @@ enum SingleArmMatchBegin { WithoutOpenBracket(Span), } -struct FindSignificantDropper<'tcx, 'a> { +struct FindSignificantDropper<'a, 'tcx> { cx: &'a LateContext<'tcx>, } -impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> { - type Result = ControlFlow; +impl<'tcx> FindSignificantDropper<'_, 'tcx> { + fn check_if_let_scrutinee(&mut self, init: &'tcx hir::Expr<'tcx>) -> ControlFlow { + self.check_promoted_temp_with_drop(init)?; + self.visit_expr(init) + } - fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { - if self + // Check that an expression is not a promoted temporary with a significant + // drop impl. + // + // An expression is a promoted temporary if it has an addr taken (i.e. `&expr`) + // or is the scrutinee of the `if let`, *and* the expression is not a place + // expr, and it has a significant drop. + fn check_promoted_temp_with_drop(&self, expr: &'tcx hir::Expr<'tcx>) -> ControlFlow { + if !expr.is_place_expr(|base| { + self.cx + .typeck_results() + .adjustments() + .get(base.hir_id) + .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_)))) + }) && self .cx .typeck_results() .expr_ty(expr) .has_significant_drop(self.cx.tcx, self.cx.typing_env()) { - return ControlFlow::Break(expr.span); + ControlFlow::Break(expr.span) + } else { + ControlFlow::Continue(()) } - match expr.kind { - hir::ExprKind::ConstBlock(_) - | hir::ExprKind::Lit(_) - | hir::ExprKind::Path(_) - | hir::ExprKind::Assign(_, _, _) - | hir::ExprKind::AssignOp(_, _, _) - | hir::ExprKind::Break(_, _) - | hir::ExprKind::Continue(_) - | hir::ExprKind::Ret(_) - | hir::ExprKind::Become(_) - | hir::ExprKind::InlineAsm(_) - | hir::ExprKind::OffsetOf(_, _) - | hir::ExprKind::Repeat(_, _) - | hir::ExprKind::Err(_) - | hir::ExprKind::Struct(_, _, _) - | hir::ExprKind::Closure(_) - | hir::ExprKind::Block(_, _) - | hir::ExprKind::DropTemps(_) - | hir::ExprKind::Loop(_, _, _, _) => ControlFlow::Continue(()), + } +} - hir::ExprKind::Tup(exprs) | hir::ExprKind::Array(exprs) => { - for expr in exprs { - self.visit_expr(expr)?; - } - ControlFlow::Continue(()) - } - hir::ExprKind::Call(callee, args) => { - self.visit_expr(callee)?; - for expr in args { - self.visit_expr(expr)?; - } - ControlFlow::Continue(()) - } - hir::ExprKind::MethodCall(_, receiver, args, _) => { - self.visit_expr(receiver)?; - for expr in args { - self.visit_expr(expr)?; +impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { + type Result = ControlFlow; + + fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result { + // Blocks introduce temporary terminating scope for all of its + // statements, so just visit the tail expr. + if let Some(expr) = b.expr { self.visit_expr(expr) } else { ControlFlow::Continue(()) } + } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + // Check for promoted temporaries from autoref, e.g. + // `if let None = TypeWithDrop.as_ref() {} else {}` + // where `fn as_ref(&self) -> Option<...>`. + for adj in self.cx.typeck_results().expr_adjustments(expr) { + match adj.kind { + Adjust::Deref(_) => break, + Adjust::Borrow(_) => { + self.check_promoted_temp_with_drop(expr)?; } - ControlFlow::Continue(()) - } - hir::ExprKind::Index(left, right, _) | hir::ExprKind::Binary(_, left, right) => { - self.visit_expr(left)?; - self.visit_expr(right) + _ => {} } - hir::ExprKind::Unary(_, expr) - | hir::ExprKind::Cast(expr, _) - | hir::ExprKind::Type(expr, _) - | hir::ExprKind::UnsafeBinderCast(_, expr, _) - | hir::ExprKind::Yield(expr, _) - | hir::ExprKind::AddrOf(_, _, expr) - | hir::ExprKind::Match(expr, _, _) - | hir::ExprKind::Field(expr, _) - | hir::ExprKind::Let(&hir::LetExpr { - init: expr, - span: _, - pat: _, - ty: _, - recovered: Recovered::No, - }) => self.visit_expr(expr), - hir::ExprKind::Let(_) => ControlFlow::Continue(()), + } - hir::ExprKind::If(cond, _, _) => { - if let hir::ExprKind::Let(hir::LetExpr { - init, - span: _, - pat: _, - ty: _, - recovered: Recovered::No, - }) = cond.kind - { - self.visit_expr(init)?; - } - ControlFlow::Continue(()) + match expr.kind { + // Check for cases like `if let None = Some(&Drop) {} else {}`. + hir::ExprKind::AddrOf(_, _, expr) => { + self.check_promoted_temp_with_drop(expr)?; + intravisit::walk_expr(self, expr) } + // If always introduces a temporary terminating scope for its cond and arms, + // so don't visit them. + hir::ExprKind::If(..) => ControlFlow::Continue(()), + // Match introduces temporary terminating scopes for arms, so don't visit + // them, and only visit the scrutinee to account for cases like: + // `if let None = match &Drop { _ => Some(1) } {} else {}`. + hir::ExprKind::Match(scrut, _, _) => self.visit_expr(scrut), + // Self explanatory. + hir::ExprKind::DropTemps(_) => ControlFlow::Continue(()), + _ => intravisit::walk_expr(self, expr), } } } diff --git a/tests/ui/drop/lint-if-let-rescope-false-positives.rs b/tests/ui/drop/lint-if-let-rescope-false-positives.rs new file mode 100644 index 0000000000000..533d0f2f982b3 --- /dev/null +++ b/tests/ui/drop/lint-if-let-rescope-false-positives.rs @@ -0,0 +1,29 @@ +//@ edition: 2021 +//@ check-pass + +#![deny(if_let_rescope)] + +struct Drop; +impl std::ops::Drop for Drop { + fn drop(&mut self) { + println!("drop") + } +} + +impl Drop { + fn as_ref(&self) -> Option { + Some(1) + } +} + +fn consume(_: impl Sized) -> Option { Some(1) } + +fn main() { + let drop = Drop; + + // Make sure we don't drop if we don't actually make a temporary. + if let None = drop.as_ref() {} else {} + + // Make sure we don't lint if we consume the droppy value. + if let None = consume(Drop) {} else {} +} From 2797936f6dcd29777f236a5d966d487a7f4cbbb3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Feb 2025 22:13:23 +0000 Subject: [PATCH 08/11] More comments --- compiler/rustc_lint/src/if_let_rescope.rs | 24 +++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 7a6d656d00dc1..55d900e031990 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -369,17 +369,22 @@ struct FindSignificantDropper<'a, 'tcx> { } impl<'tcx> FindSignificantDropper<'_, 'tcx> { + /// Check the scrutinee of an `if let` to see if it promotes any temporary values + /// that would change drop order in edition 2024. Specifically, it checks the value + /// of the scrutinee itself, and also recurses into the expression to find any ref + /// exprs (or autoref) which would promote temporaries that would be scoped to the + /// end of this `if`. fn check_if_let_scrutinee(&mut self, init: &'tcx hir::Expr<'tcx>) -> ControlFlow { self.check_promoted_temp_with_drop(init)?; self.visit_expr(init) } - // Check that an expression is not a promoted temporary with a significant - // drop impl. - // - // An expression is a promoted temporary if it has an addr taken (i.e. `&expr`) - // or is the scrutinee of the `if let`, *and* the expression is not a place - // expr, and it has a significant drop. + /// Check that an expression is not a promoted temporary with a significant + /// drop impl. + /// + /// An expression is a promoted temporary if it has an addr taken (i.e. `&expr` or autoref) + /// or is the scrutinee of the `if let`, *and* the expression is not a place + /// expr, and it has a significant drop. fn check_promoted_temp_with_drop(&self, expr: &'tcx hir::Expr<'tcx>) -> ControlFlow { if !expr.is_place_expr(|base| { self.cx @@ -405,7 +410,8 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result { // Blocks introduce temporary terminating scope for all of its - // statements, so just visit the tail expr. + // statements, so just visit the tail expr, skipping over any + // statements. This prevents false positives like `{ let x = &Drop; }`. if let Some(expr) = b.expr { self.visit_expr(expr) } else { ControlFlow::Continue(()) } } @@ -415,6 +421,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { // where `fn as_ref(&self) -> Option<...>`. for adj in self.cx.typeck_results().expr_adjustments(expr) { match adj.kind { + // Skip when we hit the first deref expr. Adjust::Deref(_) => break, Adjust::Borrow(_) => { self.check_promoted_temp_with_drop(expr)?; @@ -424,7 +431,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { } match expr.kind { - // Check for cases like `if let None = Some(&Drop) {} else {}`. + // Account for cases like `if let None = Some(&Drop) {} else {}`. hir::ExprKind::AddrOf(_, _, expr) => { self.check_promoted_temp_with_drop(expr)?; intravisit::walk_expr(self, expr) @@ -438,6 +445,7 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { hir::ExprKind::Match(scrut, _, _) => self.visit_expr(scrut), // Self explanatory. hir::ExprKind::DropTemps(_) => ControlFlow::Continue(()), + // Otherwise, walk into the expr's parts. _ => intravisit::walk_expr(self, expr), } } From bad8e98c7d0ed217b58362e61ae4357e5344d995 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Feb 2025 01:09:51 +0000 Subject: [PATCH 09/11] Consider lvalues of field and index as possibly temporary places --- compiler/rustc_lint/src/if_let_rescope.rs | 8 +++++++ .../lint-if-let-rescope-false-positives.rs | 4 ++++ tests/ui/drop/lint-if-let-rescope.fixed | 6 +++++ tests/ui/drop/lint-if-let-rescope.rs | 6 +++++ tests/ui/drop/lint-if-let-rescope.stderr | 23 ++++++++++++++++++- 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 55d900e031990..23f037f3692ab 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -436,6 +436,14 @@ impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> { self.check_promoted_temp_with_drop(expr)?; intravisit::walk_expr(self, expr) } + // `(Drop, ()).1` introduces a temporary and then moves out of + // part of it, therefore we should check it for temporaries. + // FIXME: This may have false positives if we move the part + // that actually has drop, but oh well. + hir::ExprKind::Index(expr, _, _) | hir::ExprKind::Field(expr, _) => { + self.check_promoted_temp_with_drop(expr)?; + intravisit::walk_expr(self, expr) + } // If always introduces a temporary terminating scope for its cond and arms, // so don't visit them. hir::ExprKind::If(..) => ControlFlow::Continue(()), diff --git a/tests/ui/drop/lint-if-let-rescope-false-positives.rs b/tests/ui/drop/lint-if-let-rescope-false-positives.rs index 533d0f2f982b3..77b7df4bc3bab 100644 --- a/tests/ui/drop/lint-if-let-rescope-false-positives.rs +++ b/tests/ui/drop/lint-if-let-rescope-false-positives.rs @@ -26,4 +26,8 @@ fn main() { // Make sure we don't lint if we consume the droppy value. if let None = consume(Drop) {} else {} + + // Make sure we don't lint on field exprs of place exprs. + let tup_place = (Drop, ()); + if let None = consume(tup_place.1) {} else {} } diff --git a/tests/ui/drop/lint-if-let-rescope.fixed b/tests/ui/drop/lint-if-let-rescope.fixed index 182190aa323bc..79858e6f225aa 100644 --- a/tests/ui/drop/lint-if-let-rescope.fixed +++ b/tests/ui/drop/lint-if-let-rescope.fixed @@ -94,6 +94,12 @@ fn main() { //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } + match Some((droppy(), ()).1) { Some(_value) => {} _ => {}} + //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| HELP: the value is now dropped here in Edition 2024 + //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + // We want to keep the `if let`s below as direct descendents of match arms, // so the formatting is suppressed. #[rustfmt::skip] diff --git a/tests/ui/drop/lint-if-let-rescope.rs b/tests/ui/drop/lint-if-let-rescope.rs index e1b38be0a0f50..9d873c65426f6 100644 --- a/tests/ui/drop/lint-if-let-rescope.rs +++ b/tests/ui/drop/lint-if-let-rescope.rs @@ -94,6 +94,12 @@ fn main() { //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 } + if let Some(_value) = Some((droppy(), ()).1) {} else {} + //~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024 + //~| WARN: this changes meaning in Rust 2024 + //~| HELP: the value is now dropped here in Edition 2024 + //~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021 + // We want to keep the `if let`s below as direct descendents of match arms, // so the formatting is suppressed. #[rustfmt::skip] diff --git a/tests/ui/drop/lint-if-let-rescope.stderr b/tests/ui/drop/lint-if-let-rescope.stderr index 2b0fcb7a938a6..b17239976cc0d 100644 --- a/tests/ui/drop/lint-if-let-rescope.stderr +++ b/tests/ui/drop/lint-if-let-rescope.stderr @@ -175,5 +175,26 @@ LL - while (if let Some(_value) = droppy().get() { false } else { true }) { LL + while (match droppy().get() { Some(_value) => { false } _ => { true }}) { | -error: aborting due to 7 previous errors +error: `if let` assigns a shorter lifetime since Edition 2024 + --> $DIR/lint-if-let-rescope.rs:97:8 + | +LL | if let Some(_value) = Some((droppy(), ()).1) {} else {} + | ^^^^^^^^^^^^^^^^^^^^^^^^--------------^^^ + | | + | this value has a significant drop implementation which may observe a major change in drop order and requires your discretion + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +help: the value is now dropped here in Edition 2024 + --> $DIR/lint-if-let-rescope.rs:97:51 + | +LL | if let Some(_value) = Some((droppy(), ()).1) {} else {} + | ^ +help: a `match` with a single arm can preserve the drop order up to Edition 2021 + | +LL - if let Some(_value) = Some((droppy(), ()).1) {} else {} +LL + match Some((droppy(), ()).1) { Some(_value) => {} _ => {}} + | + +error: aborting due to 8 previous errors From 7a60c49c649a91e47ee3e093d3bff95847e5cf4c Mon Sep 17 00:00:00 2001 From: Geoffry Song Date: Mon, 24 Feb 2025 18:24:22 -0800 Subject: [PATCH 10/11] Don't doc-comment BTreeMap --- library/alloc/src/collections/btree/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 6d305386dbfa0..78b7da9d6b3ee 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -289,7 +289,7 @@ impl Clone for BTreeMap { } } -/// Internal functionality for `BTreeSet`. +// Internal functionality for `BTreeSet`. impl BTreeMap { pub(super) fn replace(&mut self, key: K) -> Option where From 60a268998c606440de092452a6380dde749f89c5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 25 Feb 2025 09:20:10 +0100 Subject: [PATCH 11/11] remove `simd_fpow` and `simd_fpowi` --- .../src/intrinsics/simd.rs | 58 ------------- .../rustc_codegen_gcc/src/intrinsic/simd.rs | 28 ++---- compiler/rustc_codegen_llvm/src/intrinsic.rs | 4 - .../rustc_hir_analysis/src/check/intrinsic.rs | 2 - compiler/rustc_span/src/symbol.rs | 2 - .../simd-intrinsic-float-pow.rs | 87 ------------------- .../simd-intrinsic-float-powi.rs | 87 ------------------- tests/ui/simd/intrinsic/float-math-pass.rs | 25 ++---- 8 files changed, 13 insertions(+), 280 deletions(-) delete mode 100644 tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs delete mode 100644 tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index fcccda62355c7..0c13fa91f7a73 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -460,64 +460,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } - sym::simd_fpow => { - intrinsic_args!(fx, args => (a, b); intrinsic); - - if !a.layout().ty.is_simd() { - report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty); - return; - } - - simd_pair_for_each_lane(fx, a, b, ret, &|fx, lane_ty, _ret_lane_ty, a_lane, b_lane| { - match lane_ty.kind() { - ty::Float(FloatTy::F32) => fx.lib_call( - "powf", - vec![AbiParam::new(types::F32), AbiParam::new(types::F32)], - vec![AbiParam::new(types::F32)], - &[a_lane, b_lane], - )[0], - ty::Float(FloatTy::F64) => fx.lib_call( - "pow", - vec![AbiParam::new(types::F64), AbiParam::new(types::F64)], - vec![AbiParam::new(types::F64)], - &[a_lane, b_lane], - )[0], - _ => unreachable!("{:?}", lane_ty), - } - }); - } - - sym::simd_fpowi => { - intrinsic_args!(fx, args => (a, exp); intrinsic); - let exp = exp.load_scalar(fx); - - if !a.layout().ty.is_simd() { - report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty); - return; - } - - simd_for_each_lane( - fx, - a, - ret, - &|fx, lane_ty, _ret_lane_ty, lane| match lane_ty.kind() { - ty::Float(FloatTy::F32) => fx.lib_call( - "__powisf2", // compiler-builtins - vec![AbiParam::new(types::F32), AbiParam::new(types::I32)], - vec![AbiParam::new(types::F32)], - &[lane, exp], - )[0], - ty::Float(FloatTy::F64) => fx.lib_call( - "__powidf2", // compiler-builtins - vec![AbiParam::new(types::F64), AbiParam::new(types::I32)], - vec![AbiParam::new(types::F64)], - &[lane, exp], - )[0], - _ => unreachable!("{:?}", lane_ty), - }, - ); - } - sym::simd_fsin | sym::simd_fcos | sym::simd_fexp diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 84cd5b002fbb6..8b454ab2a4241 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -772,8 +772,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( sym::simd_floor => "floor", sym::simd_fma => "fma", sym::simd_relaxed_fma => "fma", // FIXME: this should relax to non-fused multiply-add when necessary - sym::simd_fpowi => "__builtin_powi", - sym::simd_fpow => "pow", sym::simd_fsin => "sin", sym::simd_fsqrt => "sqrt", sym::simd_round => "round", @@ -788,24 +786,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let mut vector_elements = vec![]; for i in 0..in_len { let index = bx.context.new_rvalue_from_long(bx.ulong_type, i as i64); - // we have to treat fpowi specially, since fpowi's second argument is always an i32 let mut arguments = vec![]; - if name == sym::simd_fpowi { - arguments = vec![ - bx.extract_element(args[0].immediate(), index).to_rvalue(), - args[1].immediate(), - ]; - } else { - for arg in args { - let mut element = bx.extract_element(arg.immediate(), index).to_rvalue(); - // FIXME: it would probably be better to not have casts here and use the proper - // instructions. - if let Some(typ) = cast_type { - element = bx.context.new_cast(None, element, typ); - } - arguments.push(element); + for arg in args { + let mut element = bx.extract_element(arg.immediate(), index).to_rvalue(); + // FIXME: it would probably be better to not have casts here and use the proper + // instructions. + if let Some(typ) = cast_type { + element = bx.context.new_cast(None, element, typ); } - }; + arguments.push(element); + } let mut result = bx.context.new_call(None, function, &arguments); if cast_type.is_some() { result = bx.context.new_cast(None, result, elem_ty); @@ -829,8 +819,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( | sym::simd_floor | sym::simd_fma | sym::simd_relaxed_fma - | sym::simd_fpow - | sym::simd_fpowi | sym::simd_fsin | sym::simd_fsqrt | sym::simd_round diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7e1a9d361e6fb..2d8edb1cddd0c 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1587,8 +1587,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>( sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)), sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), sym::simd_relaxed_fma => ("fmuladd", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)), - sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)), - sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)), sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)), sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), @@ -1621,8 +1619,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>( | sym::simd_flog | sym::simd_floor | sym::simd_fma - | sym::simd_fpow - | sym::simd_fpowi | sym::simd_fsin | sym::simd_fsqrt | sym::simd_relaxed_fma diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 08e0e52a4925b..41822c14ba3a4 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -651,7 +651,6 @@ pub fn check_intrinsic_type( | sym::simd_xor | sym::simd_fmin | sym::simd_fmax - | sym::simd_fpow | sym::simd_saturating_add | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)), sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)), @@ -674,7 +673,6 @@ pub fn check_intrinsic_type( | sym::simd_floor | sym::simd_round | sym::simd_trunc => (1, 0, vec![param(0)], param(0)), - sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)), sym::simd_fma | sym::simd_relaxed_fma => { (1, 0, vec![param(0), param(0), param(0)], param(0)) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d4d435d9b7467..c2a8545de7851 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1886,8 +1886,6 @@ symbols! { simd_fma, simd_fmax, simd_fmin, - simd_fpow, - simd_fpowi, simd_fsin, simd_fsqrt, simd_gather, diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs deleted file mode 100644 index 3527f71c00b47..0000000000000 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs +++ /dev/null @@ -1,87 +0,0 @@ -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); - -extern "rust-intrinsic" { - fn simd_fpow(x: T, b: T) -> T; -} - -// CHECK-LABEL: @fpow_32x2 -#[no_mangle] -pub unsafe fn fpow_32x2(a: f32x2, b: f32x2) -> f32x2 { - // CHECK: call <2 x float> @llvm.pow.v2f32 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_32x4 -#[no_mangle] -pub unsafe fn fpow_32x4(a: f32x4, b: f32x4) -> f32x4 { - // CHECK: call <4 x float> @llvm.pow.v4f32 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_32x8 -#[no_mangle] -pub unsafe fn fpow_32x8(a: f32x8, b: f32x8) -> f32x8 { - // CHECK: call <8 x float> @llvm.pow.v8f32 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_32x16 -#[no_mangle] -pub unsafe fn fpow_32x16(a: f32x16, b: f32x16) -> f32x16 { - // CHECK: call <16 x float> @llvm.pow.v16f32 - simd_fpow(a, b) -} - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - -// CHECK-LABEL: @fpow_64x4 -#[no_mangle] -pub unsafe fn fpow_64x4(a: f64x4, b: f64x4) -> f64x4 { - // CHECK: call <4 x double> @llvm.pow.v4f64 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_64x2 -#[no_mangle] -pub unsafe fn fpow_64x2(a: f64x2, b: f64x2) -> f64x2 { - // CHECK: call <2 x double> @llvm.pow.v2f64 - simd_fpow(a, b) -} - -// CHECK-LABEL: @fpow_64x8 -#[no_mangle] -pub unsafe fn fpow_64x8(a: f64x8, b: f64x8) -> f64x8 { - // CHECK: call <8 x double> @llvm.pow.v8f64 - simd_fpow(a, b) -} diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs deleted file mode 100644 index 4f0b5e4e01a3e..0000000000000 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs +++ /dev/null @@ -1,87 +0,0 @@ -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -#![feature(repr_simd, intrinsics)] -#![allow(non_camel_case_types)] - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x2(pub [f32; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x4(pub [f32; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x8(pub [f32; 8]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f32x16(pub [f32; 16]); - -extern "rust-intrinsic" { - fn simd_fpowi(x: T, b: i32) -> T; -} - -// CHECK-LABEL: @fpowi_32x2 -#[no_mangle] -pub unsafe fn fpowi_32x2(a: f32x2, b: i32) -> f32x2 { - // CHECK: call <2 x float> @llvm.powi.v2f32 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_32x4 -#[no_mangle] -pub unsafe fn fpowi_32x4(a: f32x4, b: i32) -> f32x4 { - // CHECK: call <4 x float> @llvm.powi.v4f32 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_32x8 -#[no_mangle] -pub unsafe fn fpowi_32x8(a: f32x8, b: i32) -> f32x8 { - // CHECK: call <8 x float> @llvm.powi.v8f32 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_32x16 -#[no_mangle] -pub unsafe fn fpowi_32x16(a: f32x16, b: i32) -> f32x16 { - // CHECK: call <16 x float> @llvm.powi.v16f32 - simd_fpowi(a, b) -} - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x2(pub [f64; 2]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x4(pub [f64; 4]); - -#[repr(simd)] -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct f64x8(pub [f64; 8]); - -// CHECK-LABEL: @fpowi_64x4 -#[no_mangle] -pub unsafe fn fpowi_64x4(a: f64x4, b: i32) -> f64x4 { - // CHECK: call <4 x double> @llvm.powi.v4f64 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_64x2 -#[no_mangle] -pub unsafe fn fpowi_64x2(a: f64x2, b: i32) -> f64x2 { - // CHECK: call <2 x double> @llvm.powi.v2f64 - simd_fpowi(a, b) -} - -// CHECK-LABEL: @fpowi_64x8 -#[no_mangle] -pub unsafe fn fpowi_64x8(a: f64x8, b: i32) -> f64x8 { - // CHECK: call <8 x double> @llvm.powi.v8f64 - simd_fpowi(a, b) -} diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs index 74cb51a06068e..91059f353fd9a 100644 --- a/tests/ui/simd/intrinsic/float-math-pass.rs +++ b/tests/ui/simd/intrinsic/float-math-pass.rs @@ -48,13 +48,6 @@ unsafe fn simd_flog10(x: T) -> T; #[rustc_intrinsic] unsafe fn simd_flog2(x: T) -> T; -#[rustc_intrinsic] -unsafe fn simd_fpow(x: T, y: T) -> T; - -#[rustc_intrinsic] -unsafe fn simd_fpowi(x: T, y: i32) -> T; - - // rounding functions #[rustc_intrinsic] unsafe fn simd_ceil(x: T) -> T; @@ -68,23 +61,21 @@ unsafe fn simd_round(x: T) -> T; #[rustc_intrinsic] unsafe fn simd_trunc(x: T) -> T; - macro_rules! assert_approx_eq_f32 { - ($a:expr, $b:expr) => ({ + ($a:expr, $b:expr) => {{ let (a, b) = (&$a, &$b); - assert!((*a - *b).abs() < 1.0e-6, - "{} is not approximately equal to {}", *a, *b); - }) + assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); + }}; } macro_rules! assert_approx_eq { - ($a:expr, $b:expr) => ({ + ($a:expr, $b:expr) => {{ let a = $a; let b = $b; assert_approx_eq_f32!(a.0[0], b.0[0]); assert_approx_eq_f32!(a.0[1], b.0[1]); assert_approx_eq_f32!(a.0[2], b.0[2]); assert_approx_eq_f32!(a.0[3], b.0[3]); - }) + }}; } fn main() { @@ -125,12 +116,6 @@ fn main() { let r = simd_flog10(x); assert_approx_eq!(z, r); - let r = simd_fpow(h, x); - assert_approx_eq!(h, r); - - let r = simd_fpowi(h, 1); - assert_approx_eq!(h, r); - let r = simd_fsin(z); assert_approx_eq!(z, r);