From 1666f8684d7cd274c24ef5dc3f09a3e192a463ba Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 15 Aug 2024 13:01:43 +0100 Subject: [PATCH 001/183] proposal to expand (a subset of) linux specific socket capabilities. to stabilise the quickack part for now, tcp_deferaccept had been added at a later stage. --- library/std/src/os/android/net.rs | 2 +- library/std/src/os/linux/net.rs | 2 +- library/std/src/os/net/linux_ext/mod.rs | 2 +- library/std/src/os/net/linux_ext/tcp.rs | 12 +++++------- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/library/std/src/os/android/net.rs b/library/std/src/os/android/net.rs index 960a304fd0c8..3a459ed8aeea 100644 --- a/library/std/src/os/android/net.rs +++ b/library/std/src/os/android/net.rs @@ -6,5 +6,5 @@ pub use crate::os::net::linux_ext::addr::SocketAddrExt; #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub use crate::os::net::linux_ext::socket::UnixSocketExt; -#[unstable(feature = "tcp_quickack", issue = "96256")] +#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] pub use crate::os::net::linux_ext::tcp::TcpStreamExt; diff --git a/library/std/src/os/linux/net.rs b/library/std/src/os/linux/net.rs index 1de120c8fd36..c14aba13bd15 100644 --- a/library/std/src/os/linux/net.rs +++ b/library/std/src/os/linux/net.rs @@ -6,5 +6,5 @@ pub use crate::os::net::linux_ext::addr::SocketAddrExt; #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub use crate::os::net::linux_ext::socket::UnixSocketExt; -#[unstable(feature = "tcp_quickack", issue = "96256")] +#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] pub use crate::os::net::linux_ext::tcp::TcpStreamExt; diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs index d0979640c32e..bb9dfae2623e 100644 --- a/library/std/src/os/net/linux_ext/mod.rs +++ b/library/std/src/os/net/linux_ext/mod.rs @@ -8,7 +8,7 @@ pub(crate) mod addr; #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub(crate) mod socket; -#[unstable(feature = "tcp_quickack", issue = "96256")] +#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] pub(crate) mod tcp; #[cfg(test)] diff --git a/library/std/src/os/net/linux_ext/tcp.rs b/library/std/src/os/net/linux_ext/tcp.rs index c8d012962d45..7761b7a5b857 100644 --- a/library/std/src/os/net/linux_ext/tcp.rs +++ b/library/std/src/os/net/linux_ext/tcp.rs @@ -9,7 +9,7 @@ use crate::{io, net}; /// Os-specific extensions for [`TcpStream`] /// /// [`TcpStream`]: net::TcpStream -#[unstable(feature = "tcp_quickack", issue = "96256")] +#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] pub trait TcpStreamExt: Sealed { /// Enable or disable `TCP_QUICKACK`. /// @@ -23,7 +23,6 @@ pub trait TcpStreamExt: Sealed { /// # Examples /// /// ```no_run - /// #![feature(tcp_quickack)] /// use std::net::TcpStream; /// use std::os::linux::net::TcpStreamExt; /// @@ -31,7 +30,7 @@ pub trait TcpStreamExt: Sealed { /// .expect("Couldn't connect to the server..."); /// stream.set_quickack(true).expect("set_quickack call failed"); /// ``` - #[unstable(feature = "tcp_quickack", issue = "96256")] + #[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] fn set_quickack(&self, quickack: bool) -> io::Result<()>; /// Gets the value of the `TCP_QUICKACK` option on this socket. @@ -41,7 +40,6 @@ pub trait TcpStreamExt: Sealed { /// # Examples /// /// ```no_run - /// #![feature(tcp_quickack)] /// use std::net::TcpStream; /// use std::os::linux::net::TcpStreamExt; /// @@ -50,7 +48,7 @@ pub trait TcpStreamExt: Sealed { /// stream.set_quickack(true).expect("set_quickack call failed"); /// assert_eq!(stream.quickack().unwrap_or(false), true); /// ``` - #[unstable(feature = "tcp_quickack", issue = "96256")] + #[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] fn quickack(&self) -> io::Result; /// A socket listener will be awakened solely when data arrives. @@ -99,10 +97,10 @@ pub trait TcpStreamExt: Sealed { fn deferaccept(&self) -> io::Result; } -#[unstable(feature = "tcp_quickack", issue = "96256")] +#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] impl Sealed for net::TcpStream {} -#[unstable(feature = "tcp_quickack", issue = "96256")] +#[stable(feature = "tcp_quickack", since = "CURRENT_RUSTC_VERSION")] impl TcpStreamExt for net::TcpStream { fn set_quickack(&self, quickack: bool) -> io::Result<()> { self.as_inner().as_inner().set_quickack(quickack) From 145d2266d930d8d8b4119eb230590269d0626c05 Mon Sep 17 00:00:00 2001 From: dianqk Date: Thu, 22 May 2025 22:55:27 +0800 Subject: [PATCH 002/183] mir-opt: Create an indirect BB to add `StorageDead` --- .../src/early_otherwise_branch.rs | 20 ++++++++--- tests/mir-opt/early_otherwise_branch.rs | 31 ++++++++++++++++ ...anch.target_self.EarlyOtherwiseBranch.diff | 35 +++++++++++++++++++ 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index c7feb9e949b4..e7cd74a1f543 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -193,8 +193,20 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { let eq_bb = patch.new_block(eq_switch); // Jump to it on the basis of the inequality comparison - let true_case = opt_data.destination; - let false_case = eq_bb; + let mut true_case = opt_data.destination; + let mut false_case = eq_bb; + // Create an indirect BB to add `StorageDead` If the jump target is itself. + for bb in [&mut false_case, &mut true_case].into_iter() { + if *bb == parent { + *bb = patch.new_block(BasicBlockData::new( + Some(Terminator { + kind: TerminatorKind::Goto { target: parent }, + source_info: bbs[parent].terminator().source_info, + }), + bbs[parent].is_cleanup, + )); + } + } patch.patch_terminator( parent, TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case), @@ -210,9 +222,9 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { // Generate a StorageDead for comp_temp in each of the targets, since we moved it into // the switch - for bb in [false_case, true_case].iter() { + for bb in [false_case, true_case].into_iter() { patch.add_statement( - Location { block: *bb, statement_index: 0 }, + Location { block: bb, statement_index: 0 }, StatementKind::StorageDead(comp_temp), ); } diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs index 382c38ceb3ab..93a11b663df2 100644 --- a/tests/mir-opt/early_otherwise_branch.rs +++ b/tests/mir-opt/early_otherwise_branch.rs @@ -1,6 +1,10 @@ //@ test-mir-pass: EarlyOtherwiseBranch //@ compile-flags: -Zmir-enable-passes=+UnreachableEnumBranching +#![feature(custom_mir, core_intrinsics)] + +use std::intrinsics::mir::*; + enum Option2 { Some(T), None, @@ -124,6 +128,32 @@ fn opt5_failed_type(x: u32, y: u64) -> u32 { } } +// EMIT_MIR early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff +#[custom_mir(dialect = "runtime")] +fn target_self(val: i32) { + // CHECK-LABEL: fn target_self( + mir! { + { + Goto(bb1) + } + bb1 = { + match val { + 0 => bb2, + _ => bb1, + } + } + bb2 = { + match val { + 0 => bb3, + _ => bb1, + } + } + bb3 = { + Return() + } + } +} + fn main() { opt1(None, Some(0)); opt2(None, Some(0)); @@ -131,4 +161,5 @@ fn main() { opt4(Option2::None, Option2::Some(0)); opt5(0, 0); opt5_failed(0, 0); + target_self(1); } diff --git a/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff new file mode 100644 index 000000000000..fbef5df9a531 --- /dev/null +++ b/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff @@ -0,0 +1,35 @@ +- // MIR for `target_self` before EarlyOtherwiseBranch ++ // MIR for `target_self` after EarlyOtherwiseBranch + + fn target_self(_1: i32) -> () { + let mut _0: (); ++ let mut _2: bool; + + bb0: { + goto -> bb1; + } + + bb1: { +- switchInt(copy _1) -> [0: bb2, otherwise: bb1]; ++ StorageLive(_2); ++ _2 = Ne(copy _1, copy _1); ++ switchInt(move _2) -> [0: bb3, otherwise: bb4]; + } + + bb2: { +- switchInt(copy _1) -> [0: bb3, otherwise: bb1]; ++ return; + } + + bb3: { +- return; ++ StorageDead(_2); ++ switchInt(copy _1) -> [0: bb2, otherwise: bb1]; ++ } ++ ++ bb4: { ++ StorageDead(_2); ++ goto -> bb1; + } + } + From 8c7faa6ed154893fdbfcb128055b593102b4c6db Mon Sep 17 00:00:00 2001 From: dianqk Date: Sat, 24 May 2025 15:36:06 +0800 Subject: [PATCH 003/183] mir-opt: Do not create storage marks for temporary locals --- .../src/early_otherwise_branch.rs | 48 ++----------------- ...wise_branch.opt3.EarlyOtherwiseBranch.diff | 5 -- ...wise_branch.opt4.EarlyOtherwiseBranch.diff | 5 -- ...wise_branch.opt5.EarlyOtherwiseBranch.diff | 3 -- tests/mir-opt/early_otherwise_branch.rs | 2 + ...anch.target_self.EarlyOtherwiseBranch.diff | 9 +--- ...ement_tuple.opt2.EarlyOtherwiseBranch.diff | 5 -- 7 files changed, 8 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index e7cd74a1f543..da88e5c698bf 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -128,28 +128,20 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { let mut patch = MirPatch::new(body); - let (second_discriminant_temp, second_operand) = if opt_data.need_hoist_discriminant { + let second_operand = if opt_data.need_hoist_discriminant { // create temp to store second discriminant in, `_s` in example above let second_discriminant_temp = patch.new_temp(opt_data.child_ty, opt_data.child_source.span); - patch.add_statement( - parent_end, - StatementKind::StorageLive(second_discriminant_temp), - ); - // create assignment of discriminant patch.add_assign( parent_end, Place::from(second_discriminant_temp), Rvalue::Discriminant(opt_data.child_place), ); - ( - Some(second_discriminant_temp), - Operand::Move(Place::from(second_discriminant_temp)), - ) + Operand::Move(Place::from(second_discriminant_temp)) } else { - (None, Operand::Copy(opt_data.child_place)) + Operand::Copy(opt_data.child_place) }; // create temp to store inequality comparison between the two discriminants, `_t` in @@ -157,7 +149,6 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { let nequal = BinOp::Ne; let comp_res_type = nequal.ty(tcx, parent_ty, opt_data.child_ty); let comp_temp = patch.new_temp(comp_res_type, opt_data.child_source.span); - patch.add_statement(parent_end, StatementKind::StorageLive(comp_temp)); // create inequality comparison let comp_rvalue = @@ -193,42 +184,13 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { let eq_bb = patch.new_block(eq_switch); // Jump to it on the basis of the inequality comparison - let mut true_case = opt_data.destination; - let mut false_case = eq_bb; - // Create an indirect BB to add `StorageDead` If the jump target is itself. - for bb in [&mut false_case, &mut true_case].into_iter() { - if *bb == parent { - *bb = patch.new_block(BasicBlockData::new( - Some(Terminator { - kind: TerminatorKind::Goto { target: parent }, - source_info: bbs[parent].terminator().source_info, - }), - bbs[parent].is_cleanup, - )); - } - } + let true_case = opt_data.destination; + let false_case = eq_bb; patch.patch_terminator( parent, TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case), ); - if let Some(second_discriminant_temp) = second_discriminant_temp { - // generate StorageDead for the second_discriminant_temp not in use anymore - patch.add_statement( - parent_end, - StatementKind::StorageDead(second_discriminant_temp), - ); - } - - // Generate a StorageDead for comp_temp in each of the targets, since we moved it into - // the switch - for bb in [false_case, true_case].into_iter() { - patch.add_statement( - Location { block: bb, statement_index: 0 }, - StatementKind::StorageDead(comp_temp), - ); - } - patch.apply(body); } diff --git a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff index 7b94a4c2bf73..22ebe2f3f297 100644 --- a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff @@ -32,16 +32,12 @@ StorageDead(_4); _9 = discriminant((_3.0: Option2)); - switchInt(move _9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9]; -+ StorageLive(_12); + _12 = discriminant((_3.1: Option2)); -+ StorageLive(_13); + _13 = Ne(copy _9, move _12); -+ StorageDead(_12); + switchInt(move _13) -> [0: bb7, otherwise: bb1]; } bb1: { -+ StorageDead(_13); _0 = const 1_u32; - goto -> bb8; + goto -> bb5; @@ -100,7 +96,6 @@ + } + + bb7: { -+ StorageDead(_13); + switchInt(copy _9) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb6]; } } diff --git a/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff index f52795baef81..0da0eb3c53cb 100644 --- a/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch.opt4.EarlyOtherwiseBranch.diff @@ -32,16 +32,12 @@ StorageDead(_4); _9 = discriminant((_3.0: Option2)); - switchInt(move _9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9]; -+ StorageLive(_12); + _12 = discriminant((_3.1: Option2)); -+ StorageLive(_13); + _13 = Ne(copy _9, move _12); -+ StorageDead(_12); + switchInt(move _13) -> [0: bb7, otherwise: bb1]; } bb1: { -+ StorageDead(_13); _0 = const 1_u32; - goto -> bb8; + goto -> bb5; @@ -100,7 +96,6 @@ + } + + bb7: { -+ StorageDead(_13); + switchInt(copy _9) -> [0: bb4, 1: bb3, 2: bb2, otherwise: bb6]; } } diff --git a/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff index b7447ef0c469..b13d21e2d7ab 100644 --- a/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch.opt5.EarlyOtherwiseBranch.diff @@ -20,13 +20,11 @@ StorageDead(_5); StorageDead(_4); - switchInt(copy (_3.0: u32)) -> [1: bb2, 2: bb3, 3: bb4, otherwise: bb1]; -+ StorageLive(_6); + _6 = Ne(copy (_3.0: u32), copy (_3.1: u32)); + switchInt(move _6) -> [0: bb6, otherwise: bb1]; } bb1: { -+ StorageDead(_6); _0 = const 0_u32; - goto -> bb8; + goto -> bb5; @@ -70,7 +68,6 @@ - bb8: { - StorageDead(_3); - return; -+ StorageDead(_6); + switchInt(copy (_3.0: u32)) -> [1: bb4, 2: bb3, 3: bb2, otherwise: bb1]; } } diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs index 93a11b663df2..19a5d25de2df 100644 --- a/tests/mir-opt/early_otherwise_branch.rs +++ b/tests/mir-opt/early_otherwise_branch.rs @@ -132,6 +132,8 @@ fn opt5_failed_type(x: u32, y: u64) -> u32 { #[custom_mir(dialect = "runtime")] fn target_self(val: i32) { // CHECK-LABEL: fn target_self( + // CHECK: Ne( + // CHECK-NEXT: switchInt mir! { { Goto(bb1) diff --git a/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff index fbef5df9a531..4f70847bcdf8 100644 --- a/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch.target_self.EarlyOtherwiseBranch.diff @@ -11,9 +11,8 @@ bb1: { - switchInt(copy _1) -> [0: bb2, otherwise: bb1]; -+ StorageLive(_2); + _2 = Ne(copy _1, copy _1); -+ switchInt(move _2) -> [0: bb3, otherwise: bb4]; ++ switchInt(move _2) -> [0: bb3, otherwise: bb1]; } bb2: { @@ -23,13 +22,7 @@ bb3: { - return; -+ StorageDead(_2); + switchInt(copy _1) -> [0: bb2, otherwise: bb1]; -+ } -+ -+ bb4: { -+ StorageDead(_2); -+ goto -> bb1; } } diff --git a/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff index 831d8cbb4d60..e0878167e441 100644 --- a/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt2.EarlyOtherwiseBranch.diff @@ -42,16 +42,12 @@ StorageDead(_5); _14 = discriminant((_4.0: Option2)); - switchInt(move _14) -> [0: bb2, 1: bb4, 2: bb6, otherwise: bb12]; -+ StorageLive(_18); + _18 = discriminant((_4.1: Option2)); -+ StorageLive(_19); + _19 = Ne(copy _14, move _18); -+ StorageDead(_18); + switchInt(move _19) -> [0: bb10, otherwise: bb1]; } bb1: { -+ StorageDead(_19); _0 = const 1_u32; - goto -> bb11; + goto -> bb8; @@ -134,7 +130,6 @@ + } + + bb10: { -+ StorageDead(_19); + switchInt(copy _14) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9]; } } From 47d953487850898da0261c78083ee6c9e3aac61d Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 30 May 2025 22:38:31 +0200 Subject: [PATCH 004/183] Produce ClosureBinder node in atom.rs --- .../rust-analyzer/crates/parser/src/grammar/expressions/atom.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index 8cc332d4633d..68b0c8f5c73e 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs @@ -563,7 +563,9 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker { let m = p.start(); if p.at(T![for]) { + let b = p.start(); types::for_binder(p); + b.complete(p, CLOSURE_BINDER); } // test const_closure // fn main() { let cl = const || _ = 0; } From d3a7d1c447b0d3fadc8114f52a77169304d1b814 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 30 May 2025 22:58:13 +0200 Subject: [PATCH 005/183] Add test for closure_binder Co-authored-by: Lukas Wirth --- .../rust-analyzer/crates/parser/src/grammar/expressions/atom.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index 68b0c8f5c73e..8ed0fc6729fc 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs @@ -562,6 +562,8 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker { let m = p.start(); + // test closure_binder + // fn main() { for<'a> || (); } if p.at(T![for]) { let b = p.start(); types::for_binder(p); From bd71e6c2e9cfca85f434433b3bdfc14baed9ab83 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 30 May 2025 21:04:19 +0000 Subject: [PATCH 006/183] Run 'cargo codegen' to update tests --- .../rust-analyzer/crates/parser/test_data/generated/runner.rs | 4 ++++ .../parser/test_data/parser/inline/ok/closure_binder.rs | 1 + 2 files changed, 5 insertions(+) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 030d8e0f04dd..537f6df05b9f 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -83,6 +83,10 @@ mod ok { #[test] fn cast_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/cast_expr.rs"); } #[test] + fn closure_binder() { + run_and_expect_no_errors("test_data/parser/inline/ok/closure_binder.rs"); + } + #[test] fn closure_body_underscore_assignment() { run_and_expect_no_errors( "test_data/parser/inline/ok/closure_body_underscore_assignment.rs", diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs new file mode 100644 index 000000000000..a6d8aafb08a4 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rs @@ -0,0 +1 @@ +fn main() { for<'a> || (); } From ca4811241caa91a5a9da62b4bddb9be937b3b8f5 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 30 May 2025 21:16:38 +0000 Subject: [PATCH 007/183] Update expected test output --- .../parser/err/0024_many_type_parens.rast | 15 ++++---- .../parser/inline/ok/closure_binder.rast | 36 +++++++++++++++++++ .../parser/inline/ok/lambda_expr.rast | 30 ++++++++-------- 3 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast index f0dbc9b1027f..025c12e4c2a0 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0024_many_type_parens.rast @@ -186,13 +186,14 @@ SOURCE_FILE TUPLE_EXPR L_PAREN "(" CLOSURE_EXPR - FOR_KW "for" - GENERIC_PARAM_LIST - L_ANGLE "<" - LIFETIME_PARAM - LIFETIME - LIFETIME_IDENT "'a" - R_ANGLE ">" + CLOSURE_BINDER + FOR_KW "for" + GENERIC_PARAM_LIST + L_ANGLE "<" + LIFETIME_PARAM + LIFETIME + LIFETIME_IDENT "'a" + R_ANGLE ">" WHITESPACE " " BIN_EXPR BIN_EXPR diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast new file mode 100644 index 000000000000..c04dbe1ea0a4 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/closure_binder.rast @@ -0,0 +1,36 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "main" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE " " + EXPR_STMT + CLOSURE_EXPR + CLOSURE_BINDER + FOR_KW "for" + GENERIC_PARAM_LIST + L_ANGLE "<" + LIFETIME_PARAM + LIFETIME + LIFETIME_IDENT "'a" + R_ANGLE ">" + WHITESPACE " " + PARAM_LIST + PIPE "|" + PIPE "|" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE " " + R_CURLY "}" + WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast index c25ad8430d0d..ea401d224e69 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/lambda_expr.rast @@ -202,13 +202,14 @@ SOURCE_FILE WHITESPACE "\n " EXPR_STMT CLOSURE_EXPR - FOR_KW "for" - GENERIC_PARAM_LIST - L_ANGLE "<" - LIFETIME_PARAM - LIFETIME - LIFETIME_IDENT "'a" - R_ANGLE ">" + CLOSURE_BINDER + FOR_KW "for" + GENERIC_PARAM_LIST + L_ANGLE "<" + LIFETIME_PARAM + LIFETIME + LIFETIME_IDENT "'a" + R_ANGLE ">" WHITESPACE " " PARAM_LIST PIPE "|" @@ -222,13 +223,14 @@ SOURCE_FILE WHITESPACE "\n " EXPR_STMT CLOSURE_EXPR - FOR_KW "for" - GENERIC_PARAM_LIST - L_ANGLE "<" - LIFETIME_PARAM - LIFETIME - LIFETIME_IDENT "'a" - R_ANGLE ">" + CLOSURE_BINDER + FOR_KW "for" + GENERIC_PARAM_LIST + L_ANGLE "<" + LIFETIME_PARAM + LIFETIME + LIFETIME_IDENT "'a" + R_ANGLE ">" WHITESPACE " " MOVE_KW "move" WHITESPACE " " From 8976a6ee07fd983cda1463fd299a4e2adc16ec4d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 30 May 2025 09:50:06 +0800 Subject: [PATCH 008/183] bootstrap: remap compiler vs non-compiler sources differently - Map compiler sources (corresponding to `rustc-dev` dist component) with `/rustc-dev/{hash}`. - Map non-compiler sources (corresponding to `rust-src` dist component or other non-compiler sources) with `/rustc/{hash}`. This allows the compiler to have the possibility of opportunistically reverse the mapping. This is because - `rust-src` unpacks sources to a path like `$sysroot/lib/rustlib/src/rust`, whereas - `rustc-dev` unpacks sources to a path like `$sysroot/lib/rustlib/rustc-src/rust` (Notice the `src` vs `rustc-src` difference.) --- src/bootstrap/src/core/builder/cargo.rs | 47 +++++++++++++++++++++---- src/bootstrap/src/lib.rs | 33 +++++++++++++++-- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index e41f6f16b023..27b3a5b97c3d 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -11,7 +11,7 @@ use crate::utils::build_stamp; use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags}; use crate::{ BootstrapCommand, CLang, Compiler, Config, DocTests, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode, - TargetSelection, command, prepare_behaviour_dump_dir, t, + RemapScheme, TargetSelection, command, prepare_behaviour_dump_dir, t, }; /// Represents flag values in `String` form with whitespace delimiter to pass it to the compiler @@ -920,13 +920,46 @@ impl Builder<'_> { hostflags.arg(format!("-Ctarget-feature={sign}crt-static")); } - if let Some(map_to) = self.build.debuginfo_map_to(GitRepo::Rustc) { - let map = format!("{}={}", self.build.src.display(), map_to); - cargo.env("RUSTC_DEBUGINFO_MAP", map); + // `rustc` needs to know the remapping scheme, in order to know how to reverse it (unremap) + // later. Two env vars are set and made available to the compiler + // + // - `CFG_VIRTUAL_RUST_SOURCE_BASE_DIR`: `rust-src` remap scheme (`NonCompiler`) + // - `CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR`: `rustc-dev` remap scheme (`Compiler`) + // + // Keep this scheme in sync with `rustc_metadata::rmeta::decoder`'s + // `try_to_translate_virtual_to_real`. + // + // `RUSTC_DEBUGINFO_MAP` is used to pass through to the underlying rustc + // `--remap-path-prefix`. + match mode { + Mode::Rustc | Mode::Codegen => { + if let Some(ref map_to) = + self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) + { + cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to); + } - // `rustc` needs to know the virtual `/rustc/$hash` we're mapping to, - // in order to opportunistically reverse it later. - cargo.env("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR", map_to); + if let Some(ref map_to) = + self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::Compiler) + { + // When building compiler sources, we want to apply the compiler remap scheme. + cargo.env( + "RUSTC_DEBUGINFO_MAP", + format!("{}={}", self.build.src.display(), map_to), + ); + cargo.env("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR", map_to); + } + } + Mode::Std | Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd => { + if let Some(ref map_to) = + self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler) + { + cargo.env( + "RUSTC_DEBUGINFO_MAP", + format!("{}={}", self.build.src.display(), map_to), + ); + } + } } if self.config.rust_remap_debuginfo { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 7cce14841eb3..2fbe72fa8620 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -272,6 +272,16 @@ impl Mode { } } +/// When `rust.rust_remap_debuginfo` is requested, the compiler needs to know how to +/// opportunistically unremap compiler vs non-compiler sources. We use two schemes, +/// [`RemapScheme::Compiler`] and [`RemapScheme::NonCompiler`]. +pub enum RemapScheme { + /// The [`RemapScheme::Compiler`] scheme will remap to `/rustc-dev/{hash}`. + Compiler, + /// The [`RemapScheme::NonCompiler`] scheme will remap to `/rustc/{hash}`. + NonCompiler, +} + #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum CLang { C, @@ -1210,7 +1220,7 @@ Executed at: {executed_at}"#, }) } - fn debuginfo_map_to(&self, which: GitRepo) -> Option { + fn debuginfo_map_to(&self, which: GitRepo, remap_scheme: RemapScheme) -> Option { if !self.config.rust_remap_debuginfo { return None; } @@ -1218,7 +1228,24 @@ Executed at: {executed_at}"#, match which { GitRepo::Rustc => { let sha = self.rust_sha().unwrap_or(&self.version); - Some(format!("/rustc/{sha}")) + + match remap_scheme { + RemapScheme::Compiler => { + // For compiler sources, remap via `/rustc-dev/{sha}` to allow + // distinguishing between compiler sources vs library sources, since + // `rustc-dev` dist component places them under + // `$sysroot/lib/rustlib/rustc-src/rust` as opposed to `rust-src`'s + // `$sysroot/lib/rustlib/src/rust`. + // + // Keep this scheme in sync with `rustc_metadata::rmeta::decoder`'s + // `try_to_translate_virtual_to_real`. + Some(format!("/rustc-dev/{sha}")) + } + RemapScheme::NonCompiler => { + // For non-compiler sources, use `/rustc/{sha}` remapping scheme. + Some(format!("/rustc/{sha}")) + } + } } GitRepo::Llvm => Some(String::from("/rustc/llvm")), } @@ -1285,7 +1312,7 @@ Executed at: {executed_at}"#, base.push("-fno-omit-frame-pointer".into()); } - if let Some(map_to) = self.debuginfo_map_to(which) { + if let Some(map_to) = self.debuginfo_map_to(which, RemapScheme::NonCompiler) { let map = format!("{}={}", self.src.display(), map_to); let cc = self.cc(target); if cc.ends_with("clang") || cc.ends_with("gcc") { From e3d26cdbb6b02aa2524044d7e2db202a940ce891 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Sun, 1 Jun 2025 00:44:33 +0200 Subject: [PATCH 009/183] Allow assist edit for converting structs to appear also on struct keyword and on visibility --- .../convert_named_struct_to_tuple_struct.rs | 88 ++++++++++++++++++- .../convert_tuple_struct_to_named_struct.rs | 87 +++++++++++++++++- .../crates/ide-assists/src/utils.rs | 23 +++++ 3 files changed, 192 insertions(+), 6 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 5d75e445861e..fa9fab7d78b6 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -7,7 +7,7 @@ use syntax::{ match_ast, ted, }; -use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder}; +use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, utils::find_struct_definition_from_cursor}; // Assist: convert_named_struct_to_tuple_struct // @@ -56,8 +56,7 @@ pub(crate) fn convert_named_struct_to_tuple_struct( // XXX: We don't currently provide this assist for struct definitions inside macros, but if we // are to lift this limitation, don't forget to make `edit_struct_def()` consider macro files // too. - let name = ctx.find_node_at_offset::()?; - let strukt = name.syntax().parent().and_then(>::cast)?; + let strukt = find_struct_definition_from_cursor(ctx)?; let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?; let record_fields = match field_list { ast::FieldList::RecordFieldList(it) => it, @@ -293,6 +292,89 @@ impl A { ); } + #[test] + fn convert_simple_struct_cursor_on_struct_keyword() { + check_assist( + convert_named_struct_to_tuple_struct, + r#" +struct Inner; +struct$0 A { inner: Inner } + +impl A { + fn new(inner: Inner) -> A { + A { inner } + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.inner + } +}"#, + r#" +struct Inner; +struct A(Inner); + +impl A { + fn new(inner: Inner) -> A { + A(inner) + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.0 + } +}"#, + ); + } + + #[test] + fn convert_simple_struct_cursor_on_visibility_keyword() { + check_assist( + convert_named_struct_to_tuple_struct, + r#" +struct Inner; +pub$0 struct A { inner: Inner } + +impl A { + fn new(inner: Inner) -> A { + A { inner } + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.inner + } +}"#, + r#" +struct Inner; +struct A(Inner); + +impl A { + fn new(inner: Inner) -> A { + A(inner) + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.0 + } +}"#, + ); + } + + #[test] fn convert_struct_referenced_via_self_kw() { check_assist( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 0c0b93bcfbc1..5c2a3cdc3051 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -6,7 +6,7 @@ use syntax::{ match_ast, ted, }; -use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder}; +use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, utils::find_struct_definition_from_cursor}; // Assist: convert_tuple_struct_to_named_struct // @@ -51,8 +51,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct( acc: &mut Assists, ctx: &AssistContext<'_>, ) -> Option<()> { - let name = ctx.find_node_at_offset::()?; - let strukt = name.syntax().parent().and_then(>::cast)?; + let strukt = find_struct_definition_from_cursor(ctx)?; let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?; let tuple_fields = match field_list { ast::FieldList::TupleFieldList(it) => it, @@ -300,6 +299,88 @@ impl A { struct Inner; struct A { field1: Inner } +impl A { + fn new(inner: Inner) -> A { + A { field1: inner } + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.field1 + } +}"#, + ); + } + + #[test] + fn convert_simple_struct_cursor_on_struct_keyword() { + check_assist( + convert_tuple_struct_to_named_struct, + r#" +struct Inner; +struct$0 A(Inner); + +impl A { + fn new(inner: Inner) -> A { + A(inner) + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.0 + } +}"#, + r#" +struct Inner; +struct A { field1: Inner } + +impl A { + fn new(inner: Inner) -> A { + A { field1: inner } + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.field1 + } +}"#, + ); + } + + #[test] + fn convert_simple_struct_cursor_on_visibility_keyword() { + check_assist( + convert_tuple_struct_to_named_struct, + r#" +struct Inner; +pub$0 struct A(Inner); + +impl A { + fn new(inner: Inner) -> A { + A(inner) + } + + fn new_with_default() -> A { + A::new(Inner) + } + + fn into_inner(self) -> Inner { + self.0 + } +}"#, + r#" +struct Inner; +pub struct A { field1: Inner } + impl A { fn new(inner: Inner) -> A { A { field1: inner } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index ef6914fda1d5..1c0e022d01e0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -1,5 +1,7 @@ //! Assorted functions shared by several assists. +use either::Either; + pub(crate) use gen_trait_fn_body::gen_trait_fn_body; use hir::{ DisplayTarget, HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, @@ -1146,3 +1148,24 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo }); is_const } + +/// Gets the struct definition from a context +pub(crate) fn find_struct_definition_from_cursor(ctx: &AssistContext<'_>) +-> Option> +{ + ctx.find_node_at_offset::().and_then(|name| name.syntax().parent()) + .or(find_struct_keyword(ctx).and_then(|kw| kw.parent())) + .or(ctx.find_node_at_offset::().and_then(|visibility| visibility.syntax().parent())) + .and_then(>::cast) +} + +fn find_struct_keyword(ctx: &AssistContext<'_>) -> Option { + // Attempt to find the token at the current cursor offset + ctx + .token_at_offset() + .find(|leaf| match leaf.kind() { + STRUCT_KW => true, + _ => false, + }) +} + From a241d8ebd1402116272503f2aaf9610fddc48441 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Sun, 1 Jun 2025 00:47:43 +0200 Subject: [PATCH 010/183] add missing public keyword --- .../src/handlers/convert_named_struct_to_tuple_struct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index fa9fab7d78b6..1d6450a9754c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -356,7 +356,7 @@ impl A { }"#, r#" struct Inner; -struct A(Inner); +pub struct A(Inner); impl A { fn new(inner: Inner) -> A { From 01837bc0c489d56bc0c22e46edea08937e3128f7 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Sun, 1 Jun 2025 01:09:23 +0200 Subject: [PATCH 011/183] Formatting issues resolved --- .../convert_named_struct_to_tuple_struct.rs | 6 ++++-- .../convert_tuple_struct_to_named_struct.rs | 7 +++++-- .../crates/ide-assists/src/utils.rs | 18 +++++++++--------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 1d6450a9754c..0a23bd6d7177 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -7,7 +7,10 @@ use syntax::{ match_ast, ted, }; -use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, utils::find_struct_definition_from_cursor}; +use crate::{ + AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, + utils::find_struct_definition_from_cursor, +}; // Assist: convert_named_struct_to_tuple_struct // @@ -374,7 +377,6 @@ impl A { ); } - #[test] fn convert_struct_referenced_via_self_kw() { check_assist( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 5c2a3cdc3051..464309dadb45 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -6,7 +6,10 @@ use syntax::{ match_ast, ted, }; -use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, utils::find_struct_definition_from_cursor}; +use crate::{ + AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, + utils::find_struct_definition_from_cursor, +}; // Assist: convert_tuple_struct_to_named_struct // @@ -356,7 +359,7 @@ impl A { ); } - #[test] + #[test] fn convert_simple_struct_cursor_on_visibility_keyword() { check_assist( convert_tuple_struct_to_named_struct, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 1c0e022d01e0..5741b15fdce9 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -1150,22 +1150,22 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo } /// Gets the struct definition from a context -pub(crate) fn find_struct_definition_from_cursor(ctx: &AssistContext<'_>) --> Option> -{ - ctx.find_node_at_offset::().and_then(|name| name.syntax().parent()) +pub(crate) fn find_struct_definition_from_cursor( + ctx: &AssistContext<'_>, +) -> Option> { + ctx.find_node_at_offset::() + .and_then(|name| name.syntax().parent()) .or(find_struct_keyword(ctx).and_then(|kw| kw.parent())) - .or(ctx.find_node_at_offset::().and_then(|visibility| visibility.syntax().parent())) + .or(ctx + .find_node_at_offset::() + .and_then(|visibility| visibility.syntax().parent())) .and_then(>::cast) } fn find_struct_keyword(ctx: &AssistContext<'_>) -> Option { // Attempt to find the token at the current cursor offset - ctx - .token_at_offset() - .find(|leaf| match leaf.kind() { + ctx.token_at_offset().find(|leaf| match leaf.kind() { STRUCT_KW => true, _ => false, }) } - From b34e36bc8b0ba4c27e4d9a7e0b5677a2b2294699 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Sun, 1 Jun 2025 01:16:37 +0200 Subject: [PATCH 012/183] rename function so it makes more sense --- .../src/handlers/convert_named_struct_to_tuple_struct.rs | 4 ++-- .../src/handlers/convert_tuple_struct_to_named_struct.rs | 4 ++-- src/tools/rust-analyzer/crates/ide-assists/src/utils.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 0a23bd6d7177..6435cb25f287 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -9,7 +9,7 @@ use syntax::{ use crate::{ AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, - utils::find_struct_definition_from_cursor, + utils::get_struct_definition_from_context, }; // Assist: convert_named_struct_to_tuple_struct @@ -59,7 +59,7 @@ pub(crate) fn convert_named_struct_to_tuple_struct( // XXX: We don't currently provide this assist for struct definitions inside macros, but if we // are to lift this limitation, don't forget to make `edit_struct_def()` consider macro files // too. - let strukt = find_struct_definition_from_cursor(ctx)?; + let strukt = get_struct_definition_from_context(ctx)?; let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?; let record_fields = match field_list { ast::FieldList::RecordFieldList(it) => it, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 464309dadb45..2f7b1ec8db74 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -8,7 +8,7 @@ use syntax::{ use crate::{ AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, - utils::find_struct_definition_from_cursor, + utils::get_struct_definition_from_context, }; // Assist: convert_tuple_struct_to_named_struct @@ -54,7 +54,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct( acc: &mut Assists, ctx: &AssistContext<'_>, ) -> Option<()> { - let strukt = find_struct_definition_from_cursor(ctx)?; + let strukt = get_struct_definition_from_context(ctx)?; let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?; let tuple_fields = match field_list { ast::FieldList::TupleFieldList(it) => it, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 5741b15fdce9..676937c8168d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -1150,7 +1150,7 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo } /// Gets the struct definition from a context -pub(crate) fn find_struct_definition_from_cursor( +pub(crate) fn get_struct_definition_from_context( ctx: &AssistContext<'_>, ) -> Option> { ctx.find_node_at_offset::() From 4f018d84a994e05ad8dd6f2a9445bba2126ca059 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Sun, 1 Jun 2025 01:20:45 +0200 Subject: [PATCH 013/183] clippy and more formatting --- .../rust-analyzer/crates/ide-assists/src/utils.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 676937c8168d..c7a6c2d5326b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -1155,17 +1155,12 @@ pub(crate) fn get_struct_definition_from_context( ) -> Option> { ctx.find_node_at_offset::() .and_then(|name| name.syntax().parent()) - .or(find_struct_keyword(ctx).and_then(|kw| kw.parent())) + .or(ctx + .token_at_offset() + .find(|leaf| matches!(leaf.kind(), STRUCT_KW)) + .and_then(|kw| kw.parent())) .or(ctx .find_node_at_offset::() .and_then(|visibility| visibility.syntax().parent())) .and_then(>::cast) } - -fn find_struct_keyword(ctx: &AssistContext<'_>) -> Option { - // Attempt to find the token at the current cursor offset - ctx.token_at_offset().find(|leaf| match leaf.kind() { - STRUCT_KW => true, - _ => false, - }) -} From d964f5dec26d1c898e522bad29eaae7d762b73dc Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Mon, 2 Jun 2025 11:21:46 +0100 Subject: [PATCH 014/183] internal: Use 'ProjectJson' consistently The Rust source code previously mised ProjectJson and JsonProject, and the TypeScript definition didn't match either. Use 'ProjectJson' everywhere. This is purely an internal change. --- src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs | 4 ++-- src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs | 4 ++-- .../rust-analyzer/docs/book/src/non_cargo_based_projects.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index d1ca8c1a91a3..96be6726ccb1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1192,7 +1192,7 @@ impl ConfigChange { #[derive(Debug, Clone, Eq, PartialEq)] pub enum LinkedProject { ProjectManifest(ProjectManifest), - InlineJsonProject(ProjectJson), + InlineProjectJson(ProjectJson), } impl From for LinkedProject { @@ -1203,7 +1203,7 @@ impl From for LinkedProject { impl From for LinkedProject { fn from(v: ProjectJson) -> Self { - LinkedProject::InlineJsonProject(v) + LinkedProject::InlineProjectJson(v) } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index ae9e3e998746..4677880daaf9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -292,7 +292,7 @@ impl GlobalState { if let (Some(_command), Some(path)) = (&discover_command, &path) { let build = linked_projects.iter().find_map(|project| match project { - LinkedProject::InlineJsonProject(it) => it.crate_by_buildfile(path), + LinkedProject::InlineProjectJson(it) => it.crate_by_buildfile(path), _ => None, }); @@ -318,7 +318,7 @@ impl GlobalState { &progress, ) } - LinkedProject::InlineJsonProject(it) => { + LinkedProject::InlineProjectJson(it) => { let workspace = project_model::ProjectWorkspace::load_inline( it.clone(), &cargo_config, diff --git a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md index 151f8758a176..bbdb48bbbc9e 100644 --- a/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md +++ b/src/tools/rust-analyzer/docs/book/src/non_cargo_based_projects.md @@ -5,7 +5,7 @@ build system, you’ll have to describe the structure of your project for rust-analyzer in the `rust-project.json` format: ```typescript -interface JsonProject { +interface ProjectJson { /// Path to the sysroot directory. /// /// The sysroot is where rustc looks for the From 4d7b1a44dba285c9c6e3506b1d1ec76dc66a2c34 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 30 May 2025 10:41:08 +0200 Subject: [PATCH 015/183] Enhance renaming to include identifiers that are generated from the original symbol Co-authored-by: Jake Goulding --- .../rust-analyzer/crates/hir/src/semantics.rs | 15 ++ .../src/handlers/remove_underscore.rs | 3 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 28 ++- .../src/handlers/incorrect_case.rs | 4 +- .../rust-analyzer/crates/ide/src/rename.rs | 176 +++++++++++++++--- .../crates/test-fixture/src/lib.rs | 69 +++++++ 6 files changed, 251 insertions(+), 44 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index e01774650b1f..09377df61567 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -222,6 +222,21 @@ impl Semantics<'_, DB> { self.imp.descend_node_at_offset(node, offset).filter_map(|mut it| it.find_map(N::cast)) } + // FIXME: Rethink this API + pub fn find_namelike_at_offset_with_descend<'slf>( + &'slf self, + node: &SyntaxNode, + offset: TextSize, + ) -> impl Iterator + 'slf { + node.token_at_offset(offset) + .map(move |token| self.descend_into_macros_no_opaque(token)) + .map(|descendants| descendants.into_iter().filter_map(move |it| it.value.parent())) + // re-order the tokens from token_at_offset by returning the ancestors with the smaller first nodes first + // See algo::ancestors_at_offset, which uses the same approach + .kmerge_by(|left, right| left.text_range().len().lt(&right.text_range().len())) + .filter_map(ast::NameLike::cast) + } + pub fn resolve_range_pat(&self, range_pat: &ast::RangePat) -> Option { self.imp.resolve_range_pat(range_pat).map(Struct::from) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs index 912e1936b593..a8e27416d5ce 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_underscore.rs @@ -1,6 +1,7 @@ use ide_db::{ assists::AssistId, defs::{Definition, NameClass, NameRefClass}, + rename::RenameDefinition, }; use syntax::{AstNode, ast}; @@ -61,7 +62,7 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_>) -> O "Remove underscore from a used variable", text_range, |builder| { - let changes = def.rename(&ctx.sema, new_name).unwrap(); + let changes = def.rename(&ctx.sema, new_name, RenameDefinition::Yes).unwrap(); builder.source_change = changes; }, ) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index fa2a46a0f7c2..e4d42146caeb 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -70,15 +70,19 @@ macro_rules! _bail { } pub use _bail as bail; +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum RenameDefinition { + Yes, + No, +} + impl Definition { pub fn rename( &self, sema: &Semantics<'_, RootDatabase>, new_name: &str, + rename_definition: RenameDefinition, ) -> Result { - // We append `r#` if needed. - let new_name = new_name.trim_start_matches("r#"); - // self.krate() returns None if // self is a built-in attr, built-in type or tool module. // it is not allowed for these defs to be renamed. @@ -103,8 +107,10 @@ impl Definition { bail!("Cannot rename a builtin attr.") } Definition::SelfType(_) => bail!("Cannot rename `Self`"), - Definition::Macro(mac) => rename_reference(sema, Definition::Macro(mac), new_name), - def => rename_reference(sema, def, new_name), + Definition::Macro(mac) => { + rename_reference(sema, Definition::Macro(mac), new_name, rename_definition) + } + def => rename_reference(sema, def, new_name, rename_definition), } } @@ -328,6 +334,7 @@ fn rename_reference( sema: &Semantics<'_, RootDatabase>, def: Definition, new_name: &str, + rename_definition: RenameDefinition, ) -> Result { let ident_kind = IdentifierKind::classify(new_name)?; @@ -366,11 +373,12 @@ fn rename_reference( source_edit_from_references(references, def, new_name, file_id.edition(sema.db)), ) })); - - // This needs to come after the references edits, because we change the annotation of existing edits - // if a conflict is detected. - let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; - source_change.insert_source_edit(file_id, edit); + if rename_definition == RenameDefinition::Yes { + // This needs to come after the references edits, because we change the annotation of existing edits + // if a conflict is detected. + let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; + source_change.insert_source_edit(file_id, edit); + } Ok(source_change) } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs index 38f10c778d69..519ff192799d 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_case.rs @@ -1,5 +1,5 @@ use hir::{CaseType, InFile, db::ExpandDatabase}; -use ide_db::{assists::Assist, defs::NameClass}; +use ide_db::{assists::Assist, defs::NameClass, rename::RenameDefinition}; use syntax::AstNode; use crate::{ @@ -44,7 +44,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option> = match alias_fallback { Some(_) => defs // FIXME: This can use the `ide_db::rename_reference` (or def.rename) method once we can // properly find "direct" usages/references. - .map(|(.., def)| { - match IdentifierKind::classify(new_name)? { + .map(|(.., def, new_name, _)| { + match IdentifierKind::classify(&new_name)? { IdentifierKind::Ident => (), IdentifierKind::Lifetime => { bail!("Cannot alias reference to a lifetime identifier") @@ -120,7 +120,7 @@ pub(crate) fn rename( source_change.extend(usages.references.get_mut(&file_id).iter().map(|refs| { ( position.file_id, - source_edit_from_references(refs, def, new_name, file_id.edition(db)), + source_edit_from_references(refs, def, &new_name, file_id.edition(db)), ) })); @@ -128,18 +128,18 @@ pub(crate) fn rename( }) .collect(), None => defs - .map(|(.., def)| { + .map(|(.., def, new_name, rename_def)| { if let Definition::Local(local) = def { if let Some(self_param) = local.as_self_param(sema.db) { cov_mark::hit!(rename_self_to_param); - return rename_self_to_param(&sema, local, self_param, new_name); + return rename_self_to_param(&sema, local, self_param, &new_name); } if new_name == "self" { cov_mark::hit!(rename_to_self); return rename_to_self(&sema, local); } } - def.rename(&sema, new_name) + def.rename(&sema, &new_name, rename_def) }) .collect(), }; @@ -159,7 +159,7 @@ pub(crate) fn will_rename_file( let sema = Semantics::new(db); let module = sema.file_to_module_def(file_id)?; let def = Definition::Module(module); - let mut change = def.rename(&sema, new_name_stem).ok()?; + let mut change = def.rename(&sema, new_name_stem, RenameDefinition::Yes).ok()?; change.file_system_edits.clear(); Some(change) } @@ -200,22 +200,34 @@ fn find_definitions( sema: &Semantics<'_, RootDatabase>, syntax: &SyntaxNode, FilePosition { file_id, offset }: FilePosition, -) -> RenameResult> { - let token = syntax.token_at_offset(offset).find(|t| matches!(t.kind(), SyntaxKind::STRING)); + new_name: &str, +) -> RenameResult> +{ + let maybe_format_args = + syntax.token_at_offset(offset).find(|t| matches!(t.kind(), SyntaxKind::STRING)); if let Some((range, _, _, Some(resolution))) = - token.and_then(|token| sema.check_for_format_args_template(token, offset)) + maybe_format_args.and_then(|token| sema.check_for_format_args_template(token, offset)) { return Ok(vec![( FileRange { file_id, range }, SyntaxKind::STRING, Definition::from(resolution), + new_name.to_owned(), + RenameDefinition::Yes, )] .into_iter()); } + let original_ident = syntax + .token_at_offset(offset) + .max_by_key(|t| { + t.kind().is_any_identifier() || matches!(t.kind(), SyntaxKind::LIFETIME_IDENT) + }) + .map(|t| Name::new_root(t.text())) + .ok_or_else(|| format_err!("No references found at position"))?; let symbols = - sema.find_nodes_at_offset_with_descend::(syntax, offset).map(|name_like| { + sema.find_namelike_at_offset_with_descend(syntax, offset).map(|name_like| { let kind = name_like.syntax().kind(); let range = sema .original_range_opt(name_like.syntax()) @@ -284,23 +296,29 @@ fn find_definitions( .ok_or_else(|| format_err!("No references found at position")) } }; - res.map(|def| (range, kind, def)) + res.map(|def| { + let n = def.name(sema.db)?; + if n == original_ident { + Some((range, kind, def, new_name.to_owned(), RenameDefinition::Yes)) + } else if let Some(suffix) = n.as_str().strip_prefix(original_ident.as_str()) { + Some((range, kind, def, format!("{new_name}{suffix}"), RenameDefinition::No)) + } else if let Some(prefix) = n.as_str().strip_suffix(original_ident.as_str()) { + Some((range, kind, def, format!("{prefix}{new_name}"), RenameDefinition::No)) + } else { + None + } + }) }); - let res: RenameResult> = symbols.collect(); + let res: RenameResult> = symbols.filter_map(Result::transpose).collect(); match res { Ok(v) => { - if v.is_empty() { - // FIXME: some semantic duplication between "empty vec" and "Err()" - Err(format_err!("No references found at position")) - } else { - // remove duplicates, comparing `Definition`s - Ok(v.into_iter() - .unique_by(|&(.., def)| def) - .map(|(a, b, c)| (a.into_file_id(sema.db), b, c)) - .collect::>() - .into_iter()) - } + // remove duplicates, comparing `Definition`s + Ok(v.into_iter() + .unique_by(|&(.., def, _, _)| def) + .map(|(a, b, c, d, e)| (a.into_file_id(sema.db), b, c, d, e)) + .collect::>() + .into_iter()) } Err(e) => Err(e), } @@ -2536,7 +2554,7 @@ fn baz() { x.0$0 = 5; } "#, - "error: No identifier available to rename", + "error: No references found at position", ); } @@ -2566,7 +2584,7 @@ impl Foo { } } "#, - "error: Cannot rename `Self`", + "error: No references found at position", ); } @@ -3259,6 +3277,102 @@ trait Trait { trait Trait { fn foo() -> impl use Trait {} } +"#, + ); + } + + #[test] + fn rename_macro_generated_type_from_type_with_a_suffix() { + check( + "Bar", + r#" +//- proc_macros: generate_suffixed_type +#[proc_macros::generate_suffixed_type] +struct Foo$0; +fn usage(_: FooSuffix) {} +usage(FooSuffix); +"#, + r#" +#[proc_macros::generate_suffixed_type] +struct Bar; +fn usage(_: BarSuffix) {} +usage(BarSuffix); +"#, + ); + } + + #[test] + // FIXME + #[should_panic] + fn rename_macro_generated_type_from_type_usage_with_a_suffix() { + check( + "Bar", + r#" +//- proc_macros: generate_suffixed_type +#[proc_macros::generate_suffixed_type] +struct Foo; +fn usage(_: FooSuffix) {} +usage(FooSuffix); +fn other_place() { Foo$0; } +"#, + r#" +#[proc_macros::generate_suffixed_type] +struct Bar; +fn usage(_: BarSuffix) {} +usage(BarSuffix); +fn other_place() { Bar; } +"#, + ); + } + + #[test] + fn rename_macro_generated_type_from_variant_with_a_suffix() { + check( + "Bar", + r#" +//- proc_macros: generate_suffixed_type +#[proc_macros::generate_suffixed_type] +enum Quux { + Foo$0, +} +fn usage(_: FooSuffix) {} +usage(FooSuffix); +"#, + r#" +#[proc_macros::generate_suffixed_type] +enum Quux { + Bar, +} +fn usage(_: BarSuffix) {} +usage(BarSuffix); +"#, + ); + } + + #[test] + // FIXME + #[should_panic] + fn rename_macro_generated_type_from_variant_usage_with_a_suffix() { + check( + "Bar", + r#" +//- proc_macros: generate_suffixed_type +#[proc_macros::generate_suffixed_type] +enum Quux { + Foo, +} +fn usage(_: FooSuffix) {} +usage(FooSuffix); +fn other_place() { Quux::Foo$0; } +"#, + r#" +#[proc_macros::generate_suffixed_type] +enum Quux { + Bar, +} +fn usage(_: BarSuffix) {} +usage(BartSuffix); +fn other_place() { Quux::Bar$0; } "#, ); } diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 96e1301f227e..8eb48f8d93e7 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -538,6 +538,21 @@ pub fn disallow_cfg(_attr: TokenStream, input: TokenStream) -> TokenStream { disabled: false, }, ), + ( + r#" +#[proc_macro_attribute] +pub fn generate_suffixed_type(_attr: TokenStream, input: TokenStream) -> TokenStream { + input +} +"# + .into(), + ProcMacro { + name: Symbol::intern("generate_suffixed_type"), + kind: ProcMacroKind::Attr, + expander: sync::Arc::new(GenerateSuffixedTypeProcMacroExpander), + disabled: false, + }, + ), ]) } @@ -919,3 +934,57 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander { Ok(subtree.clone()) } } + +// Generates a new type by adding a suffix to the original name +#[derive(Debug)] +struct GenerateSuffixedTypeProcMacroExpander; +impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander { + fn expand( + &self, + subtree: &TopSubtree, + _attrs: Option<&TopSubtree>, + _env: &Env, + _def_site: Span, + call_site: Span, + _mixed_site: Span, + _current_dir: String, + ) -> Result { + let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[1] else { + return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); + }; + + let ident = match ident.sym.as_str() { + "struct" => { + let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[2] else { + return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); + }; + ident + } + + "enum" => { + let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[4] else { + return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); + }; + ident + } + + _ => { + return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); + } + }; + + let generated_ident = tt::Ident { + sym: Symbol::intern(&format!("{}Suffix", ident.sym)), + span: ident.span, + is_raw: tt::IdentIsRaw::No, + }; + + let ret = quote! { call_site => + #subtree + + struct #generated_ident; + }; + + Ok(ret) + } +} From 4c1f3c63d78544ba204766b92b70a60ee126d410 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 30 May 2025 11:35:17 +0200 Subject: [PATCH 016/183] fix: Fix edition handling for names in rename logic --- .../rust-analyzer/crates/hir/src/semantics.rs | 4 +- .../rust-analyzer/crates/ide-db/src/rename.rs | 178 ++++++++++-------- .../rust-analyzer/crates/ide/src/rename.rs | 94 +++++---- 3 files changed, 161 insertions(+), 115 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 09377df61567..a75c56aa8fc6 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -659,7 +659,7 @@ impl<'db> SemanticsImpl<'db> { /// Checks if renaming `renamed` to `new_name` may introduce conflicts with other locals, /// and returns the conflicting locals. - pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &str) -> Vec { + pub fn rename_conflicts(&self, to_be_renamed: &Local, new_name: &Name) -> Vec { let body = self.db.body(to_be_renamed.parent); let resolver = to_be_renamed.parent.resolver(self.db); let starting_expr = @@ -668,7 +668,7 @@ impl<'db> SemanticsImpl<'db> { body: &body, conflicts: FxHashSet::default(), db: self.db, - new_name: Symbol::intern(new_name), + new_name: new_name.symbol().clone(), old_name: to_be_renamed.name(self.db).symbol().clone(), owner: to_be_renamed.parent, to_be_renamed: to_be_renamed.binding_id, diff --git a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs index e4d42146caeb..4e737e27f050 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/rename.rs @@ -20,7 +20,7 @@ //! //! The correct behavior in such cases is probably to show a dialog to the user. //! Our current behavior is ¯\_(ツ)_/¯. -use std::fmt; +use std::fmt::{self, Display}; use crate::{ source_change::ChangeAnnotation, @@ -28,13 +28,12 @@ use crate::{ }; use base_db::AnchoredPathBuf; use either::Either; -use hir::{EditionedFileId, FieldSource, FileRange, InFile, ModuleSource, Semantics}; +use hir::{FieldSource, FileRange, InFile, ModuleSource, Name, Semantics, sym}; use span::{Edition, FileId, SyntaxContext}; use stdx::{TupleExt, never}; use syntax::{ AstNode, SyntaxKind, T, TextRange, ast::{self, HasName}, - utils::is_raw_identifier, }; use crate::{ @@ -87,13 +86,16 @@ impl Definition { // self is a built-in attr, built-in type or tool module. // it is not allowed for these defs to be renamed. // cases where self.krate() is None is handled below. - if let Some(krate) = self.krate(sema.db) { + let edition = if let Some(krate) = self.krate(sema.db) { // Can we not rename non-local items? // Then bail if non-local if !krate.origin(sema.db).is_local() { bail!("Cannot rename a non-local definition") } - } + krate.edition(sema.db) + } else { + Edition::LATEST + }; match *self { Definition::Module(module) => rename_mod(sema, module, new_name), @@ -108,9 +110,9 @@ impl Definition { } Definition::SelfType(_) => bail!("Cannot rename `Self`"), Definition::Macro(mac) => { - rename_reference(sema, Definition::Macro(mac), new_name, rename_definition) + rename_reference(sema, Definition::Macro(mac), new_name, rename_definition, edition) } - def => rename_reference(sema, def, new_name, rename_definition), + def => rename_reference(sema, def, new_name, rename_definition, edition), } } @@ -243,10 +245,6 @@ fn rename_mod( module: hir::Module, new_name: &str, ) -> Result { - if IdentifierKind::classify(new_name)? != IdentifierKind::Ident { - bail!("Invalid name `{0}`: cannot rename module to {0}", new_name); - } - let mut source_change = SourceChange::default(); if module.is_crate_root() { @@ -254,6 +252,14 @@ fn rename_mod( } let InFile { file_id, value: def_source } = module.definition_source(sema.db); + let edition = file_id.edition(sema.db); + let (new_name, kind) = IdentifierKind::classify(edition, new_name)?; + if kind != IdentifierKind::Ident { + bail!( + "Invalid name `{0}`: cannot rename module to {0}", + new_name.display(sema.db, edition) + ); + } if let ModuleSource::SourceFile(..) = def_source { let anchor = file_id.original_file(sema.db).file_id(sema.db); @@ -262,7 +268,7 @@ fn rename_mod( // Module exists in a named file if !is_mod_rs { - let path = format!("{new_name}.rs"); + let path = format!("{}.rs", new_name.as_str()); let dst = AnchoredPathBuf { anchor, path }; source_change.push_file_system_edit(FileSystemEdit::MoveFile { src: anchor, dst }) } @@ -273,11 +279,11 @@ fn rename_mod( let dir_paths = match (is_mod_rs, has_detached_child, module.name(sema.db)) { // Go up one level since the anchor is inside the dir we're trying to rename (true, _, Some(mod_name)) => { - Some((format!("../{}", mod_name.as_str()), format!("../{new_name}"))) + Some((format!("../{}", mod_name.as_str()), format!("../{}", new_name.as_str()))) } // The anchor is on the same level as target dir (false, true, Some(mod_name)) => { - Some((mod_name.as_str().to_owned(), new_name.to_owned())) + Some((mod_name.as_str().to_owned(), new_name.as_str().to_owned())) } _ => None, }; @@ -302,11 +308,7 @@ fn rename_mod( .original_file_range_opt(sema.db) .map(TupleExt::head) { - let new_name = if is_raw_identifier(new_name, file_id.edition(sema.db)) { - format!("r#{new_name}") - } else { - new_name.to_owned() - }; + let new_name = new_name.display(sema.db, edition).to_string(); source_change.insert_source_edit( file_id.file_id(sema.db), TextEdit::replace(file_range.range, new_name), @@ -320,9 +322,10 @@ fn rename_mod( let def = Definition::Module(module); let usages = def.usages(sema).all(); let ref_edits = usages.iter().map(|(file_id, references)| { + let edition = file_id.edition(sema.db); ( file_id.file_id(sema.db), - source_edit_from_references(references, def, new_name, file_id.edition(sema.db)), + source_edit_from_references(sema.db, references, def, &new_name, edition), ) }); source_change.extend(ref_edits); @@ -335,8 +338,9 @@ fn rename_reference( def: Definition, new_name: &str, rename_definition: RenameDefinition, + edition: Edition, ) -> Result { - let ident_kind = IdentifierKind::classify(new_name)?; + let (mut new_name, ident_kind) = IdentifierKind::classify(edition, new_name)?; if matches!( def, @@ -344,18 +348,34 @@ fn rename_reference( ) { match ident_kind { IdentifierKind::Underscore => { - bail!("Invalid name `{}`: not a lifetime identifier", new_name); + bail!( + "Invalid name `{}`: not a lifetime identifier", + new_name.display(sema.db, edition) + ); } - _ => cov_mark::hit!(rename_lifetime), + IdentifierKind::Ident => { + new_name = Name::new_lifetime(&format!("'{}", new_name.as_str())) + } + IdentifierKind::Lifetime => (), + IdentifierKind::LowercaseSelf => bail!( + "Invalid name `{}`: not a lifetime identifier", + new_name.display(sema.db, edition) + ), } } else { match ident_kind { IdentifierKind::Lifetime => { cov_mark::hit!(rename_not_an_ident_ref); - bail!("Invalid name `{}`: not an identifier", new_name); + bail!("Invalid name `{}`: not an identifier", new_name.display(sema.db, edition)); } IdentifierKind::Ident => cov_mark::hit!(rename_non_local), IdentifierKind::Underscore => (), + IdentifierKind::LowercaseSelf => { + bail!( + "Invalid name `{}`: cannot rename to `self`", + new_name.display(sema.db, edition) + ); + } } } @@ -368,31 +388,29 @@ fn rename_reference( } let mut source_change = SourceChange::default(); source_change.extend(usages.iter().map(|(file_id, references)| { + let edition = file_id.edition(sema.db); ( file_id.file_id(sema.db), - source_edit_from_references(references, def, new_name, file_id.edition(sema.db)), + source_edit_from_references(sema.db, references, def, &new_name, edition), ) })); if rename_definition == RenameDefinition::Yes { // This needs to come after the references edits, because we change the annotation of existing edits // if a conflict is detected. - let (file_id, edit) = source_edit_from_def(sema, def, new_name, &mut source_change)?; + let (file_id, edit) = source_edit_from_def(sema, def, &new_name, &mut source_change)?; source_change.insert_source_edit(file_id, edit); } Ok(source_change) } pub fn source_edit_from_references( + db: &RootDatabase, references: &[FileReference], def: Definition, - new_name: &str, + new_name: &Name, edition: Edition, ) -> TextEdit { - let new_name = if is_raw_identifier(new_name, edition) { - format!("r#{new_name}") - } else { - new_name.to_owned() - }; + let name_display = new_name.display(db, edition); let mut edit = TextEdit::builder(); // macros can cause multiple refs to occur for the same text range, so keep track of what we have edited so far let mut edited_ranges = Vec::new(); @@ -403,23 +421,15 @@ pub fn source_edit_from_references( // to make special rewrites like shorthand syntax and such, so just rename the node in // the macro input FileReferenceNode::NameRef(name_ref) if name_range == range => { - source_edit_from_name_ref(&mut edit, name_ref, &new_name, def) + source_edit_from_name_ref(&mut edit, name_ref, &name_display, def) } FileReferenceNode::Name(name) if name_range == range => { - source_edit_from_name(&mut edit, name, &new_name) + source_edit_from_name(&mut edit, name, &name_display) } _ => false, }; if !has_emitted_edit && !edited_ranges.contains(&range.start()) { - let (range, new_name) = match name { - FileReferenceNode::Lifetime(_) => ( - TextRange::new(range.start() + syntax::TextSize::from(1), range.end()), - new_name.strip_prefix('\'').unwrap_or(&new_name).to_owned(), - ), - _ => (range, new_name.to_owned()), - }; - - edit.replace(range, new_name); + edit.replace(range, name_display.to_string()); edited_ranges.push(range.start()); } } @@ -427,7 +437,11 @@ pub fn source_edit_from_references( edit.finish() } -fn source_edit_from_name(edit: &mut TextEditBuilder, name: &ast::Name, new_name: &str) -> bool { +fn source_edit_from_name( + edit: &mut TextEditBuilder, + name: &ast::Name, + new_name: &dyn Display, +) -> bool { if ast::RecordPatField::for_field_name(name).is_some() { if let Some(ident_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) { cov_mark::hit!(rename_record_pat_field_name_split); @@ -447,7 +461,7 @@ fn source_edit_from_name(edit: &mut TextEditBuilder, name: &ast::Name, new_name: fn source_edit_from_name_ref( edit: &mut TextEditBuilder, name_ref: &ast::NameRef, - new_name: &str, + new_name: &dyn Display, def: Definition, ) -> bool { if name_ref.super_token().is_some() { @@ -460,6 +474,7 @@ fn source_edit_from_name_ref( match &(rcf_name_ref, rcf_expr.and_then(|it| expr_as_name_ref(&it))) { // field: init-expr, check if we can use a field init shorthand (Some(field_name), Some(init)) => { + let new_name = new_name.to_string(); if field_name == name_ref { if init.text() == new_name { cov_mark::hit!(test_rename_field_put_init_shorthand); @@ -515,6 +530,7 @@ fn source_edit_from_name_ref( { // field name is being renamed if let Some(name) = pat.name() { + let new_name = new_name.to_string(); if name.text() == new_name { cov_mark::hit!(test_rename_field_put_init_shorthand_pat); // Foo { field: ref mut local } -> Foo { ref mut field } @@ -526,7 +542,7 @@ fn source_edit_from_name_ref( let s = field_name.syntax().text_range().start(); let e = pat.syntax().text_range().start(); edit.delete(TextRange::new(s, e)); - edit.replace(name.syntax().text_range(), new_name.to_owned()); + edit.replace(name.syntax().text_range(), new_name); return true; } } @@ -540,16 +556,9 @@ fn source_edit_from_name_ref( fn source_edit_from_def( sema: &Semantics<'_, RootDatabase>, def: Definition, - new_name: &str, + new_name: &Name, source_change: &mut SourceChange, ) -> Result<(FileId, TextEdit)> { - let new_name_edition_aware = |new_name: &str, file_id: EditionedFileId| { - if is_raw_identifier(new_name, file_id.edition(sema.db)) { - format!("r#{new_name}") - } else { - new_name.to_owned() - } - }; let mut edit = TextEdit::builder(); if let Definition::Local(local) = def { let mut file_id = None; @@ -581,7 +590,10 @@ fn source_edit_from_def( { Some(FileRange { file_id: file_id2, range }) => { file_id = Some(file_id2); - edit.replace(range, new_name_edition_aware(new_name, file_id2)); + edit.replace( + range, + new_name.display(sema.db, file_id2.edition(sema.db)).to_string(), + ); continue; } None => { @@ -595,7 +607,7 @@ fn source_edit_from_def( // special cases required for renaming fields/locals in Record patterns if let Some(pat_field) = pat.syntax().parent().and_then(ast::RecordPatField::cast) { if let Some(name_ref) = pat_field.name_ref() { - if new_name == name_ref.text().as_str().trim_start_matches("r#") + if new_name.as_str() == name_ref.text().as_str().trim_start_matches("r#") && pat.at_token().is_none() { // Foo { field: ref mut local } -> Foo { ref mut field } @@ -615,7 +627,9 @@ fn source_edit_from_def( // ^^^^^ replace this with `new_name` edit.replace( name_range, - new_name_edition_aware(new_name, source.file_id), + new_name + .display(sema.db, source.file_id.edition(sema.db)) + .to_string(), ); } } else { @@ -626,10 +640,16 @@ fn source_edit_from_def( pat.syntax().text_range().start(), format!("{}: ", pat_field.field_name().unwrap()), ); - edit.replace(name_range, new_name_edition_aware(new_name, source.file_id)); + edit.replace( + name_range, + new_name.display(sema.db, source.file_id.edition(sema.db)).to_string(), + ); } } else { - edit.replace(name_range, new_name_edition_aware(new_name, source.file_id)); + edit.replace( + name_range, + new_name.display(sema.db, source.file_id.edition(sema.db)).to_string(), + ); } } } @@ -647,16 +667,13 @@ fn source_edit_from_def( .range_for_rename(sema) .ok_or_else(|| format_err!("No identifier available to rename"))?; let (range, new_name) = match def { - Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) => ( - TextRange::new(range.start() + syntax::TextSize::from(1), range.end()), - new_name.strip_prefix('\'').unwrap_or(new_name).to_owned(), + Definition::ExternCrateDecl(decl) if decl.alias(sema.db).is_none() => ( + TextRange::empty(range.end()), + format!(" as {}", new_name.display(sema.db, file_id.edition(sema.db)),), ), - Definition::ExternCrateDecl(decl) if decl.alias(sema.db).is_none() => { - (TextRange::empty(range.end()), format!(" as {new_name}")) - } - _ => (range, new_name.to_owned()), + _ => (range, new_name.display(sema.db, file_id.edition(sema.db)).to_string()), }; - edit.replace(range, new_name_edition_aware(&new_name, file_id)); + edit.replace(range, new_name); Ok((file_id.file_id(sema.db), edit.finish())) } @@ -665,26 +682,27 @@ pub enum IdentifierKind { Ident, Lifetime, Underscore, + LowercaseSelf, } impl IdentifierKind { - pub fn classify(new_name: &str) -> Result { - let new_name = new_name.trim_start_matches("r#"); - match parser::LexedStr::single_token(Edition::LATEST, new_name) { + pub fn classify(edition: Edition, new_name: &str) -> Result<(Name, IdentifierKind)> { + match parser::LexedStr::single_token(edition, new_name) { Some(res) => match res { - (SyntaxKind::IDENT, _) => { - if let Some(inner) = new_name.strip_prefix("r#") { - if matches!(inner, "self" | "crate" | "super" | "Self") { - bail!("Invalid name: `{}` cannot be a raw identifier", inner); - } - } - Ok(IdentifierKind::Ident) + (SyntaxKind::IDENT, _) => Ok((Name::new_root(new_name), IdentifierKind::Ident)), + (T![_], _) => { + Ok((Name::new_symbol_root(sym::underscore), IdentifierKind::Underscore)) } - (T![_], _) => Ok(IdentifierKind::Underscore), (SyntaxKind::LIFETIME_IDENT, _) if new_name != "'static" && new_name != "'_" => { - Ok(IdentifierKind::Lifetime) + Ok((Name::new_lifetime(new_name), IdentifierKind::Lifetime)) } - _ if is_raw_identifier(new_name, Edition::LATEST) => Ok(IdentifierKind::Ident), + _ if SyntaxKind::from_keyword(new_name, edition).is_some() => match new_name { + "self" => Ok((Name::new_root(new_name), IdentifierKind::LowercaseSelf)), + "crate" | "super" | "Self" => { + bail!("Invalid name `{}`: cannot rename to a keyword", new_name) + } + _ => Ok((Name::new_root(new_name), IdentifierKind::Ident)), + }, (_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error), (_, None) => bail!("Invalid name `{}`: not an identifier", new_name), }, diff --git a/src/tools/rust-analyzer/crates/ide/src/rename.rs b/src/tools/rust-analyzer/crates/ide/src/rename.rs index e959a9bd76f2..fb84e8e6b474 100644 --- a/src/tools/rust-analyzer/crates/ide/src/rename.rs +++ b/src/tools/rust-analyzer/crates/ide/src/rename.rs @@ -4,7 +4,7 @@ //! tests. This module also implements a couple of magic tricks, like renaming //! `self` and to `self` (to switch between associated function and method). -use hir::{AsAssocItem, InFile, Name, Semantics}; +use hir::{AsAssocItem, InFile, Name, Semantics, sym}; use ide_db::{ FileId, FileRange, RootDatabase, defs::{Definition, NameClass, NameRefClass}, @@ -33,7 +33,7 @@ pub(crate) fn prepare_rename( let source_file = sema.parse_guess_edition(position.file_id); let syntax = source_file.syntax(); - let res = find_definitions(&sema, syntax, position, "?")? + let res = find_definitions(&sema, syntax, position, &Name::new_symbol_root(sym::underscore))? .map(|(frange, kind, def, _, _)| { // ensure all ranges are valid @@ -88,22 +88,28 @@ pub(crate) fn rename( let source_file = sema.parse(file_id); let syntax = source_file.syntax(); - let defs = find_definitions(&sema, syntax, position, new_name)?; - let alias_fallback = alias_fallback(syntax, position, new_name); + let edition = file_id.edition(db); + let (new_name, kind) = IdentifierKind::classify(edition, new_name)?; + + let defs = find_definitions(&sema, syntax, position, &new_name)?; + let alias_fallback = + alias_fallback(syntax, position, &new_name.display(db, edition).to_string()); let ops: RenameResult> = match alias_fallback { Some(_) => defs // FIXME: This can use the `ide_db::rename_reference` (or def.rename) method once we can // properly find "direct" usages/references. .map(|(.., def, new_name, _)| { - match IdentifierKind::classify(&new_name)? { + match kind { IdentifierKind::Ident => (), IdentifierKind::Lifetime => { bail!("Cannot alias reference to a lifetime identifier") } IdentifierKind::Underscore => bail!("Cannot alias reference to `_`"), + IdentifierKind::LowercaseSelf => { + bail!("Cannot rename alias reference to `self`") + } }; - let mut usages = def.usages(&sema).all(); // FIXME: hack - removes the usage that triggered this rename operation. @@ -120,7 +126,7 @@ pub(crate) fn rename( source_change.extend(usages.references.get_mut(&file_id).iter().map(|refs| { ( position.file_id, - source_edit_from_references(refs, def, &new_name, file_id.edition(db)), + source_edit_from_references(db, refs, def, &new_name, edition), ) })); @@ -132,14 +138,14 @@ pub(crate) fn rename( if let Definition::Local(local) = def { if let Some(self_param) = local.as_self_param(sema.db) { cov_mark::hit!(rename_self_to_param); - return rename_self_to_param(&sema, local, self_param, &new_name); + return rename_self_to_param(&sema, local, self_param, &new_name, kind); } - if new_name == "self" { + if kind == IdentifierKind::LowercaseSelf { cov_mark::hit!(rename_to_self); return rename_to_self(&sema, local); } } - def.rename(&sema, &new_name, rename_def) + def.rename(&sema, new_name.as_str(), rename_def) }) .collect(), }; @@ -200,8 +206,8 @@ fn find_definitions( sema: &Semantics<'_, RootDatabase>, syntax: &SyntaxNode, FilePosition { file_id, offset }: FilePosition, - new_name: &str, -) -> RenameResult> + new_name: &Name, +) -> RenameResult> { let maybe_format_args = syntax.token_at_offset(offset).find(|t| matches!(t.kind(), SyntaxKind::STRING)); @@ -213,7 +219,7 @@ fn find_definitions( FileRange { file_id, range }, SyntaxKind::STRING, Definition::from(resolution), - new_name.to_owned(), + new_name.clone(), RenameDefinition::Yes, )] .into_iter()); @@ -224,7 +230,13 @@ fn find_definitions( .max_by_key(|t| { t.kind().is_any_identifier() || matches!(t.kind(), SyntaxKind::LIFETIME_IDENT) }) - .map(|t| Name::new_root(t.text())) + .map(|t| { + if t.kind() == SyntaxKind::LIFETIME_IDENT { + Name::new_lifetime(t.text()) + } else { + Name::new_root(t.text()) + } + }) .ok_or_else(|| format_err!("No references found at position"))?; let symbols = sema.find_namelike_at_offset_with_descend(syntax, offset).map(|name_like| { @@ -299,13 +311,12 @@ fn find_definitions( res.map(|def| { let n = def.name(sema.db)?; if n == original_ident { - Some((range, kind, def, new_name.to_owned(), RenameDefinition::Yes)) + Some((range, kind, def, new_name.clone(), RenameDefinition::Yes)) } else if let Some(suffix) = n.as_str().strip_prefix(original_ident.as_str()) { - Some((range, kind, def, format!("{new_name}{suffix}"), RenameDefinition::No)) - } else if let Some(prefix) = n.as_str().strip_suffix(original_ident.as_str()) { - Some((range, kind, def, format!("{prefix}{new_name}"), RenameDefinition::No)) + Some((range, kind, def, Name::new_root(&format!("{}{suffix}", new_name.as_str())), RenameDefinition::No)) } else { - None + n.as_str().strip_suffix(original_ident.as_str().trim_start_matches('\'')) + .map(|prefix| (range, kind, def, Name::new_root(&format!("{prefix}{}", new_name.as_str())), RenameDefinition::No)) } }) }); @@ -388,7 +399,13 @@ fn rename_to_self( source_change.extend(usages.iter().map(|(file_id, references)| { ( file_id.file_id(sema.db), - source_edit_from_references(references, def, "self", file_id.edition(sema.db)), + source_edit_from_references( + sema.db, + references, + def, + &Name::new_symbol_root(sym::self_), + file_id.edition(sema.db), + ), ) })); source_change.insert_source_edit( @@ -402,23 +419,25 @@ fn rename_self_to_param( sema: &Semantics<'_, RootDatabase>, local: hir::Local, self_param: hir::SelfParam, - new_name: &str, + new_name: &Name, + identifier_kind: IdentifierKind, ) -> RenameResult { - if new_name == "self" { + if identifier_kind == IdentifierKind::LowercaseSelf { // Let's do nothing rather than complain. cov_mark::hit!(rename_self_to_self); return Ok(SourceChange::default()); } - let identifier_kind = IdentifierKind::classify(new_name)?; - let InFile { file_id, value: self_param } = sema.source(self_param).ok_or_else(|| format_err!("cannot find function source"))?; let def = Definition::Local(local); let usages = def.usages(sema).all(); - let edit = text_edit_from_self_param(&self_param, new_name) - .ok_or_else(|| format_err!("No target type found"))?; + let edit = text_edit_from_self_param( + &self_param, + new_name.display(sema.db, file_id.edition(sema.db)).to_string(), + ) + .ok_or_else(|| format_err!("No target type found"))?; if usages.len() > 1 && identifier_kind == IdentifierKind::Underscore { bail!("Cannot rename reference to `_` as it is being referenced multiple times"); } @@ -427,13 +446,19 @@ fn rename_self_to_param( source_change.extend(usages.iter().map(|(file_id, references)| { ( file_id.file_id(sema.db), - source_edit_from_references(references, def, new_name, file_id.edition(sema.db)), + source_edit_from_references( + sema.db, + references, + def, + new_name, + file_id.edition(sema.db), + ), ) })); Ok(source_change) } -fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Option { +fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: String) -> Option { fn target_type_name(impl_def: &ast::Impl) -> Option { if let Some(ast::Type::PathType(p)) = impl_def.self_ty() { return Some(p.path()?.segment()?.name_ref()?.text().to_string()); @@ -445,7 +470,7 @@ fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Opt Some(impl_def) => { let type_name = target_type_name(&impl_def)?; - let mut replacement_text = String::from(new_name); + let mut replacement_text = new_name; replacement_text.push_str(": "); match (self_param.amp_token(), self_param.mut_token()) { (Some(_), None) => replacement_text.push('&'), @@ -458,7 +483,7 @@ fn text_edit_from_self_param(self_param: &ast::SelfParam, new_name: &str) -> Opt } None => { cov_mark::hit!(rename_self_outside_of_methods); - let mut replacement_text = String::from(new_name); + let mut replacement_text = new_name; replacement_text.push_str(": _"); Some(TextEdit::replace(self_param.syntax().text_range(), replacement_text)) } @@ -728,7 +753,7 @@ impl Foo { check( "super", r#"fn main() { let i$0 = 1; }"#, - "error: Invalid name `super`: not an identifier", + "error: Invalid name `super`: cannot rename to a keyword", ); } @@ -777,7 +802,11 @@ impl Foo { #[test] fn test_rename_mod_invalid_raw_ident() { - check("r#self", r#"mod foo$0 {}"#, "error: Invalid name `self`: not an identifier"); + check( + "r#self", + r#"mod foo$0 {}"#, + "error: Invalid name `self`: cannot rename module to self", + ); } #[test] @@ -2377,7 +2406,6 @@ fn foo(foo: Foo) { #[test] fn test_rename_lifetimes() { - cov_mark::check!(rename_lifetime); check( "'yeeee", r#" From a18f23210c018a2cb43d5eb467bfb484a03cdb27 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 2 Jun 2025 15:22:03 +0200 Subject: [PATCH 017/183] Support derive-macros for rename prefix magic --- src/tools/rust-analyzer/Cargo.toml | 2 + .../crates/hir-def/src/dyn_map.rs | 10 +- .../rust-analyzer/crates/hir/src/semantics.rs | 298 +++++++++++------- .../crates/hir/src/semantics/source_to_def.rs | 18 +- 4 files changed, 211 insertions(+), 117 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 8c5071898466..975fe277b220 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -21,6 +21,8 @@ smol_str.opt-level = 3 text-size.opt-level = 3 serde.opt-level = 3 salsa.opt-level = 3 +dissimilar.opt-level = 3 + # This speeds up `cargo xtask dist`. miniz_oxide.opt-level = 3 diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs index eed1490a7af6..20018b61e5cc 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs @@ -67,8 +67,14 @@ pub mod keys { pub const PROC_MACRO: Key = Key::new(); pub const MACRO_CALL: Key = Key::new(); pub const ATTR_MACRO_CALL: Key = Key::new(); - pub const DERIVE_MACRO_CALL: Key]>)> = - Key::new(); + pub const DERIVE_MACRO_CALL: Key< + ast::Attr, + ( + AttrId, + /* derive() */ MacroCallId, + /* actual derive macros */ Box<[Option]>, + ), + > = Key::new(); /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are /// equal if they point to exactly the same object. diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index a75c56aa8fc6..587e1013b9ee 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -550,7 +550,7 @@ impl<'db> SemanticsImpl<'db> { } pub fn is_derive_annotated(&self, adt: InFile<&ast::Adt>) -> bool { - self.with_ctx(|ctx| ctx.has_derives(adt)) + self.with_ctx(|ctx| ctx.file_of_adt_has_derives(adt)) } pub fn derive_helpers_in_scope(&self, adt: &ast::Adt) -> Option> { @@ -894,6 +894,7 @@ impl<'db> SemanticsImpl<'db> { // node is just the token, so descend the token self.descend_into_macros_impl( InFile::new(file.file_id, first), + false, &mut |InFile { value, .. }, _ctx| { if let Some(node) = value .parent_ancestors() @@ -908,14 +909,19 @@ impl<'db> SemanticsImpl<'db> { } else { // Descend first and last token, then zip them to look for the node they belong to let mut scratch: SmallVec<[_; 1]> = smallvec![]; - self.descend_into_macros_impl(InFile::new(file.file_id, first), &mut |token, _ctx| { - scratch.push(token); - CONTINUE_NO_BREAKS - }); + self.descend_into_macros_impl( + InFile::new(file.file_id, first), + false, + &mut |token, _ctx| { + scratch.push(token); + CONTINUE_NO_BREAKS + }, + ); let mut scratch = scratch.into_iter(); self.descend_into_macros_impl( InFile::new(file.file_id, last), + false, &mut |InFile { value: last, file_id: last_fid }, _ctx| { if let Some(InFile { value: first, file_id: first_fid }) = scratch.next() { if first_fid == last_fid { @@ -967,7 +973,7 @@ impl<'db> SemanticsImpl<'db> { ast::Item::Union(it) => it.into(), _ => return false, }; - ctx.has_derives(token.with_value(&adt)) + ctx.file_of_adt_has_derives(token.with_value(&adt)) }) }) } @@ -977,7 +983,7 @@ impl<'db> SemanticsImpl<'db> { token: SyntaxToken, mut cb: impl FnMut(InFile, SyntaxContext), ) { - self.descend_into_macros_impl(self.wrap_token_infile(token), &mut |t, ctx| { + self.descend_into_macros_impl(self.wrap_token_infile(token), false, &mut |t, ctx| { cb(t, ctx); CONTINUE_NO_BREAKS }); @@ -985,10 +991,14 @@ impl<'db> SemanticsImpl<'db> { pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> { let mut res = smallvec![]; - self.descend_into_macros_impl(self.wrap_token_infile(token.clone()), &mut |t, _ctx| { - res.push(t.value); - CONTINUE_NO_BREAKS - }); + self.descend_into_macros_impl( + self.wrap_token_infile(token.clone()), + false, + &mut |t, _ctx| { + res.push(t.value); + CONTINUE_NO_BREAKS + }, + ); if res.is_empty() { res.push(token); } @@ -1001,7 +1011,7 @@ impl<'db> SemanticsImpl<'db> { ) -> SmallVec<[InFile; 1]> { let mut res = smallvec![]; let token = self.wrap_token_infile(token); - self.descend_into_macros_impl(token.clone(), &mut |t, ctx| { + self.descend_into_macros_impl(token.clone(), true, &mut |t, ctx| { if !ctx.is_opaque(self.db) { // Don't descend into opaque contexts res.push(t); @@ -1019,7 +1029,7 @@ impl<'db> SemanticsImpl<'db> { token: InFile, mut cb: impl FnMut(InFile, SyntaxContext) -> ControlFlow, ) -> Option { - self.descend_into_macros_impl(token, &mut cb) + self.descend_into_macros_impl(token, false, &mut cb) } /// Descends the token into expansions, returning the tokens that matches the input @@ -1092,41 +1102,41 @@ impl<'db> SemanticsImpl<'db> { fn descend_into_macros_impl( &self, InFile { value: token, file_id }: InFile, + always_descend_into_derives: bool, f: &mut dyn FnMut(InFile, SyntaxContext) -> ControlFlow, ) -> Option { let _p = tracing::info_span!("descend_into_macros_impl").entered(); - let span = self.db.span_map(file_id).span_for_range(token.text_range()); + let db = self.db; + let span = db.span_map(file_id).span_for_range(token.text_range()); // Process the expansion of a call, pushing all tokens with our span in the expansion back onto our stack - let process_expansion_for_token = |stack: &mut Vec<_>, macro_file| { - let InMacroFile { file_id, value: mapped_tokens } = self.with_ctx(|ctx| { - Some( - ctx.cache - .get_or_insert_expansion(ctx.db, macro_file) - .map_range_down(span)? - .map(SmallVec::<[_; 2]>::from_iter), - ) - })?; - // we have found a mapping for the token if the vec is non-empty - let res = mapped_tokens.is_empty().not().then_some(()); - // requeue the tokens we got from mapping our current token down - stack.push((HirFileId::from(file_id), mapped_tokens)); - res - }; + let process_expansion_for_token = + |ctx: &mut SourceToDefCtx<'_, '_>, stack: &mut Vec<_>, macro_file| { + let InMacroFile { file_id, value: mapped_tokens } = ctx + .cache + .get_or_insert_expansion(ctx.db, macro_file) + .map_range_down(span)? + .map(SmallVec::<[_; 2]>::from_iter); + // we have found a mapping for the token if the vec is non-empty + let res = mapped_tokens.is_empty().not().then_some(()); + // requeue the tokens we got from mapping our current token down + stack.push((HirFileId::from(file_id), mapped_tokens)); + res + }; // A stack of tokens to process, along with the file they came from // These are tracked to know which macro calls we still have to look into // the tokens themselves aren't that interesting as the span that is being used to map // things down never changes. let mut stack: Vec<(_, SmallVec<[_; 2]>)> = vec![]; - let include = file_id.file_id().and_then(|file_id| { - self.s2d_cache.borrow_mut().get_or_insert_include_for(self.db, file_id) - }); + let include = file_id + .file_id() + .and_then(|file_id| self.s2d_cache.borrow_mut().get_or_insert_include_for(db, file_id)); match include { Some(include) => { // include! inputs are always from real files, so they only need to be handled once upfront - process_expansion_for_token(&mut stack, include)?; + self.with_ctx(|ctx| process_expansion_for_token(ctx, &mut stack, include))?; } None => { stack.push((file_id, smallvec![(token, span.ctx)])); @@ -1148,62 +1158,120 @@ impl<'db> SemanticsImpl<'db> { tokens.reverse(); while let Some((token, ctx)) = tokens.pop() { let was_not_remapped = (|| { - // First expand into attribute invocations - let containing_attribute_macro_call = self.with_ctx(|ctx| { - token.parent_ancestors().filter_map(ast::Item::cast).find_map(|item| { - // Don't force populate the dyn cache for items that don't have an attribute anyways - item.attrs().next()?; - Some((ctx.item_to_macro_call(InFile::new(expansion, &item))?, item)) - }) - }); - if let Some((call_id, item)) = containing_attribute_macro_call { - let attr_id = match self.db.lookup_intern_macro_call(call_id).kind { - hir_expand::MacroCallKind::Attr { invoc_attr_index, .. } => { - invoc_attr_index.ast_index() - } - _ => 0, - }; - // FIXME: here, the attribute's text range is used to strip away all - // entries from the start of the attribute "list" up the invoking - // attribute. But in - // ``` - // mod foo { - // #![inner] - // } - // ``` - // we don't wanna strip away stuff in the `mod foo {` range, that is - // here if the id corresponds to an inner attribute we got strip all - // text ranges of the outer ones, and then all of the inner ones up - // to the invoking attribute so that the inbetween is ignored. - let text_range = item.syntax().text_range(); - let start = collect_attrs(&item) - .nth(attr_id) - .map(|attr| match attr.1 { - Either::Left(it) => it.syntax().text_range().start(), - Either::Right(it) => it.syntax().text_range().start(), + // First expand into attribute invocations, this is required to be handled + // upfront as any other macro call within will not semantically resolve unless + // also descended. + let res = self.with_ctx(|ctx| { + token + .parent_ancestors() + .filter_map(ast::Item::cast) + // FIXME: This might work incorrectly when we have a derive, followed by + // an attribute on an item, like: + // ``` + // #[derive(Debug$0)] + // #[my_attr] + // struct MyStruct; + // ``` + // here we should not consider the attribute at all, as our cursor + // technically lies outside of its expansion + .find_map(|item| { + // Don't force populate the dyn cache for items that don't have an attribute anyways + item.attrs().next()?; + ctx.item_to_macro_call(InFile::new(expansion, &item)) + .zip(Some(item)) }) - .unwrap_or_else(|| text_range.start()); - let text_range = TextRange::new(start, text_range.end()); - filter_duplicates(tokens, text_range); - return process_expansion_for_token(&mut stack, call_id); + .map(|(call_id, item)| { + let attr_id = match db.lookup_intern_macro_call(call_id).kind { + hir_expand::MacroCallKind::Attr { + invoc_attr_index, .. + } => invoc_attr_index.ast_index(), + _ => 0, + }; + // FIXME: here, the attribute's text range is used to strip away all + // entries from the start of the attribute "list" up the invoking + // attribute. But in + // ``` + // mod foo { + // #![inner] + // } + // ``` + // we don't wanna strip away stuff in the `mod foo {` range, that is + // here if the id corresponds to an inner attribute we got strip all + // text ranges of the outer ones, and then all of the inner ones up + // to the invoking attribute so that the inbetween is ignored. + let text_range = item.syntax().text_range(); + let start = collect_attrs(&item) + .nth(attr_id) + .map(|attr| match attr.1 { + Either::Left(it) => it.syntax().text_range().start(), + Either::Right(it) => it.syntax().text_range().start(), + }) + .unwrap_or_else(|| text_range.start()); + let text_range = TextRange::new(start, text_range.end()); + filter_duplicates(tokens, text_range); + process_expansion_for_token(ctx, &mut stack, call_id) + }) + }); + + if let Some(res) = res { + return res; } + if always_descend_into_derives { + let res = self.with_ctx(|ctx| { + let (derives, adt) = token + .parent_ancestors() + .filter_map(ast::Adt::cast) + .find_map(|adt| { + Some(( + ctx.derive_macro_calls(InFile::new(expansion, &adt))? + .map(|(a, b, c)| (a, b, c.to_owned())) + .collect::>(), + adt, + )) + })?; + let mut res = None; + for (_, derive_attr, derives) in derives { + // as there may be multiple derives registering the same helper + // name, we gotta make sure to call this for all of them! + // FIXME: We need to call `f` for all of them as well though! + res = res.or(process_expansion_for_token( + ctx, + &mut stack, + derive_attr, + )); + for derive in derives.into_iter().flatten() { + res = res + .or(process_expansion_for_token(ctx, &mut stack, derive)); + } + } + // remove all tokens that are within the derives expansion + filter_duplicates(tokens, adt.syntax().text_range()); + Some(res) + }); + // if we found derives, we can early exit. There is no way we can be in any + // macro call at this point given we are not in a token tree + if let Some(res) = res { + return res; + } + } // Then check for token trees, that means we are either in a function-like macro or // secondary attribute inputs let tt = token .parent_ancestors() .map_while(Either::::cast) .last()?; + match tt { // function-like macro call Either::Left(tt) => { + let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?; if tt.left_delimiter_token().map_or(false, |it| it == token) { return None; } if tt.right_delimiter_token().map_or(false, |it| it == token) { return None; } - let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?; let mcall = InFile::new(expansion, macro_call); let file_id = match m_cache.get(&mcall) { Some(&it) => it, @@ -1216,13 +1284,16 @@ impl<'db> SemanticsImpl<'db> { let text_range = tt.syntax().text_range(); filter_duplicates(tokens, text_range); - process_expansion_for_token(&mut stack, file_id).or(file_id - .eager_arg(self.db) - .and_then(|arg| { - // also descend into eager expansions - process_expansion_for_token(&mut stack, arg) - })) + self.with_ctx(|ctx| { + process_expansion_for_token(ctx, &mut stack, file_id).or(file_id + .eager_arg(db) + .and_then(|arg| { + // also descend into eager expansions + process_expansion_for_token(ctx, &mut stack, arg) + })) + }) } + Either::Right(_) if always_descend_into_derives => None, // derive or derive helper Either::Right(meta) => { // attribute we failed expansion for earlier, this might be a derive invocation @@ -1231,31 +1302,33 @@ impl<'db> SemanticsImpl<'db> { let adt = match attr.syntax().parent().and_then(ast::Adt::cast) { Some(adt) => { // this might be a derive on an ADT - let derive_call = self.with_ctx(|ctx| { + let res = self.with_ctx(|ctx| { // so try downmapping the token into the pseudo derive expansion // see [hir_expand::builtin_attr_macro] for how the pseudo derive expansion works - ctx.attr_to_derive_macro_call( - InFile::new(expansion, &adt), - InFile::new(expansion, attr.clone()), - ) - .map(|(_, call_id, _)| call_id) - }); + let derive_call = ctx + .attr_to_derive_macro_call( + InFile::new(expansion, &adt), + InFile::new(expansion, attr.clone()), + )? + .1; - match derive_call { - Some(call_id) => { - // resolved to a derive - let text_range = attr.syntax().text_range(); - // remove any other token in this macro input, all their mappings are the - // same as this - tokens.retain(|(t, _)| { - !text_range.contains_range(t.text_range()) - }); - return process_expansion_for_token( - &mut stack, call_id, - ); - } - None => Some(adt), + // resolved to a derive + let text_range = attr.syntax().text_range(); + // remove any other token in this macro input, all their mappings are the + // same as this + tokens.retain(|(t, _)| { + !text_range.contains_range(t.text_range()) + }); + Some(process_expansion_for_token( + ctx, + &mut stack, + derive_call, + )) + }); + if let Some(res) = res { + return res; } + Some(adt) } None => { // Otherwise this could be a derive helper on a variant or field @@ -1269,12 +1342,9 @@ impl<'db> SemanticsImpl<'db> { ) } }?; - if !self.with_ctx(|ctx| ctx.has_derives(InFile::new(expansion, &adt))) { - return None; - } let attr_name = attr.path().and_then(|it| it.as_single_name_ref())?.as_name(); - // Not an attribute, nor a derive, so it's either an intert attribute or a derive helper + // Not an attribute, nor a derive, so it's either an inert attribute or a derive helper // Try to resolve to a derive helper and downmap let resolver = &token .parent() @@ -1282,7 +1352,7 @@ impl<'db> SemanticsImpl<'db> { self.analyze_impl(InFile::new(expansion, &parent), None, false) })? .resolver; - let id = self.db.ast_id_map(expansion).ast_id(&adt); + let id = db.ast_id_map(expansion).ast_id(&adt); let helpers = resolver .def_map() .derive_helpers_in_scope(InFile::new(expansion, id))?; @@ -1293,20 +1363,22 @@ impl<'db> SemanticsImpl<'db> { } let mut res = None; - for (.., derive) in - helpers.iter().filter(|(helper, ..)| *helper == attr_name) - { - // as there may be multiple derives registering the same helper - // name, we gotta make sure to call this for all of them! - // FIXME: We need to call `f` for all of them as well though! - res = res.or(process_expansion_for_token(&mut stack, *derive)); - } - res + self.with_ctx(|ctx| { + for (.., derive) in + helpers.iter().filter(|(helper, ..)| *helper == attr_name) + { + // as there may be multiple derives registering the same helper + // name, we gotta make sure to call this for all of them! + // FIXME: We need to call `f` for all of them as well though! + res = res + .or(process_expansion_for_token(ctx, &mut stack, *derive)); + } + res + }) } } })() .is_none(); - if was_not_remapped { if let ControlFlow::Break(b) = f(InFile::new(expansion, token), ctx) { return Some(b); diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 7f6c9af47400..7dac01a26890 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -108,7 +108,7 @@ use span::FileId; use stdx::impl_from; use syntax::{ AstNode, AstPtr, SyntaxNode, - ast::{self, HasName}, + ast::{self, HasAttrs, HasName}, }; use tt::TextRange; @@ -411,10 +411,24 @@ impl SourceToDefCtx<'_, '_> { .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids)) } - pub(super) fn has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool { + pub(super) fn file_of_adt_has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool { self.dyn_map(adt).as_ref().is_some_and(|map| !map[keys::DERIVE_MACRO_CALL].is_empty()) } + pub(super) fn derive_macro_calls<'slf>( + &'slf mut self, + adt: InFile<&ast::Adt>, + ) -> Option])> + use<'slf>> + { + self.dyn_map(adt).as_ref().map(|&map| { + let dyn_map = &map[keys::DERIVE_MACRO_CALL]; + adt.value + .attrs() + .filter_map(move |attr| dyn_map.get(&AstPtr::new(&attr))) + .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids)) + }) + } + fn to_def( &mut self, src: InFile<&Ast>, From 3f0df08a9a9433e3ab093ab88555a6537a8c4548 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Mon, 2 Jun 2025 15:35:13 -0400 Subject: [PATCH 018/183] fix: don't duplicate must_use for functions and traits --- .../crates/ide-completion/src/completions/attribute.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs index 3c195f80fea4..352e4444b721 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs @@ -264,13 +264,13 @@ static KIND_TO_ATTRIBUTES: LazyLock> = LazyLock:: FN, attrs!( item, linkable, - "cold", "ignore", "inline", "must_use", "panic_handler", "proc_macro", + "cold", "ignore", "inline", "panic_handler", "proc_macro", "proc_macro_derive", "proc_macro_attribute", "should_panic", "target_feature", "test", "track_caller" ), ), (STATIC, attrs!(item, linkable, "global_allocator", "used")), - (TRAIT, attrs!(item, "must_use")), + (TRAIT, attrs!(item)), (IMPL, attrs!(item, "automatically_derived")), (ASSOC_ITEM_LIST, attrs!(item)), (EXTERN_BLOCK, attrs!(item, "link")), From d122bd43da8aca656c8024ed62920207d368ba45 Mon Sep 17 00:00:00 2001 From: BazookaMusic Date: Mon, 2 Jun 2025 23:28:26 +0200 Subject: [PATCH 019/183] simplify expression that checks the offset --- .../convert_named_struct_to_tuple_struct.rs | 24 ++++++++++++------- .../convert_tuple_struct_to_named_struct.rs | 24 ++++++++++++------- .../crates/ide-assists/src/utils.rs | 18 -------------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 6435cb25f287..32c4ae2e869e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -7,10 +7,7 @@ use syntax::{ match_ast, ted, }; -use crate::{ - AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, - utils::get_struct_definition_from_context, -}; +use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder}; // Assist: convert_named_struct_to_tuple_struct // @@ -59,13 +56,22 @@ pub(crate) fn convert_named_struct_to_tuple_struct( // XXX: We don't currently provide this assist for struct definitions inside macros, but if we // are to lift this limitation, don't forget to make `edit_struct_def()` consider macro files // too. - let strukt = get_struct_definition_from_context(ctx)?; - let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?; + let strukt_or_variant = ctx + .find_node_at_offset::() + .map(Either::Left) + .or_else(|| ctx.find_node_at_offset::().map(Either::Right))?; + let field_list = strukt_or_variant.as_ref().either(|s| s.field_list(), |v| v.field_list())?; + + if ctx.offset() > field_list.syntax().text_range().start() { + // Assist could be distracting after the braces + return None; + } + let record_fields = match field_list { ast::FieldList::RecordFieldList(it) => it, ast::FieldList::TupleFieldList(_) => return None, }; - let strukt_def = match &strukt { + let strukt_def = match &strukt_or_variant { Either::Left(s) => Either::Left(ctx.sema.to_def(s)?), Either::Right(v) => Either::Right(ctx.sema.to_def(v)?), }; @@ -73,11 +79,11 @@ pub(crate) fn convert_named_struct_to_tuple_struct( acc.add( AssistId::refactor_rewrite("convert_named_struct_to_tuple_struct"), "Convert to tuple struct", - strukt.syntax().text_range(), + strukt_or_variant.syntax().text_range(), |edit| { edit_field_references(ctx, edit, record_fields.fields()); edit_struct_references(ctx, edit, strukt_def); - edit_struct_def(ctx, edit, &strukt, record_fields); + edit_struct_def(ctx, edit, &strukt_or_variant, record_fields); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 2f7b1ec8db74..80756197fb70 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -6,10 +6,7 @@ use syntax::{ match_ast, ted, }; -use crate::{ - AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder, - utils::get_struct_definition_from_context, -}; +use crate::{AssistContext, AssistId, Assists, assist_context::SourceChangeBuilder}; // Assist: convert_tuple_struct_to_named_struct // @@ -54,17 +51,26 @@ pub(crate) fn convert_tuple_struct_to_named_struct( acc: &mut Assists, ctx: &AssistContext<'_>, ) -> Option<()> { - let strukt = get_struct_definition_from_context(ctx)?; - let field_list = strukt.as_ref().either(|s| s.field_list(), |v| v.field_list())?; + let strukt_or_variant = ctx + .find_node_at_offset::() + .map(Either::Left) + .or_else(|| ctx.find_node_at_offset::().map(Either::Right))?; + let field_list = strukt_or_variant.as_ref().either(|s| s.field_list(), |v| v.field_list())?; + + if ctx.offset() > field_list.syntax().text_range().start() { + // Assist could be distracting after the braces + return None; + } + let tuple_fields = match field_list { ast::FieldList::TupleFieldList(it) => it, ast::FieldList::RecordFieldList(_) => return None, }; - let strukt_def = match &strukt { + let strukt_def = match &strukt_or_variant { Either::Left(s) => Either::Left(ctx.sema.to_def(s)?), Either::Right(v) => Either::Right(ctx.sema.to_def(v)?), }; - let target = strukt.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range(); + let target = strukt_or_variant.as_ref().either(|s| s.syntax(), |v| v.syntax()).text_range(); acc.add( AssistId::refactor_rewrite("convert_tuple_struct_to_named_struct"), @@ -74,7 +80,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct( let names = generate_names(tuple_fields.fields()); edit_field_references(ctx, edit, tuple_fields.fields(), &names); edit_struct_references(ctx, edit, strukt_def, &names); - edit_struct_def(ctx, edit, &strukt, tuple_fields, names); + edit_struct_def(ctx, edit, &strukt_or_variant, tuple_fields, names); }, ) } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index c7a6c2d5326b..ef6914fda1d5 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs @@ -1,7 +1,5 @@ //! Assorted functions shared by several assists. -use either::Either; - pub(crate) use gen_trait_fn_body::gen_trait_fn_body; use hir::{ DisplayTarget, HasAttrs as HirHasAttrs, HirDisplay, InFile, ModuleDef, PathResolution, @@ -1148,19 +1146,3 @@ pub fn is_body_const(sema: &Semantics<'_, RootDatabase>, expr: &ast::Expr) -> bo }); is_const } - -/// Gets the struct definition from a context -pub(crate) fn get_struct_definition_from_context( - ctx: &AssistContext<'_>, -) -> Option> { - ctx.find_node_at_offset::() - .and_then(|name| name.syntax().parent()) - .or(ctx - .token_at_offset() - .find(|leaf| matches!(leaf.kind(), STRUCT_KW)) - .and_then(|kw| kw.parent())) - .or(ctx - .find_node_at_offset::() - .and_then(|visibility| visibility.syntax().parent())) - .and_then(>::cast) -} From 59fe3995c837b42826cdb4ee8a376f2bcd70ee95 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Mon, 2 Jun 2025 17:17:27 -0400 Subject: [PATCH 020/183] feat: implement completion for diagnostic module --- .../src/completions/attribute.rs | 54 +++++++++---- .../src/completions/attribute/diagnostic.rs | 60 ++++++++++++++ .../ide-completion/src/tests/attribute.rs | 78 ++++++++++++++++++- 3 files changed, 175 insertions(+), 17 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs index 352e4444b721..f696f0c0b951 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs @@ -25,6 +25,7 @@ use crate::{ mod cfg; mod derive; +mod diagnostic; mod lint; mod macro_use; mod repr; @@ -40,14 +41,23 @@ pub(crate) fn complete_known_attribute_input( extern_crate: Option<&ast::ExternCrate>, ) -> Option<()> { let attribute = fake_attribute_under_caret; - let name_ref = match attribute.path() { - Some(p) => Some(p.as_single_name_ref()?), - None => None, - }; - let (path, tt) = name_ref.zip(attribute.token_tree())?; + let path = attribute.path()?; + let name_ref = path.segment()?.name_ref(); + let (name_ref, tt) = name_ref.zip(attribute.token_tree())?; tt.l_paren_token()?; - match path.text().as_str() { + if let Some(qualifier) = path.qualifier() { + let qualifier_name_ref = qualifier.as_single_name_ref()?; + match (qualifier_name_ref.text().as_str(), name_ref.text().as_str()) { + ("diagnostic", "on_unimplemented") => { + diagnostic::complete_on_unimplemented(acc, ctx, tt) + } + _ => (), + } + return Some(()); + } + + match name_ref.text().as_str() { "repr" => repr::complete_repr(acc, ctx, tt), "feature" => lint::complete_lint( acc, @@ -139,6 +149,8 @@ pub(crate) fn complete_attribute_path( } Qualified::TypeAnchor { .. } | Qualified::With { .. } => {} } + let qualifier_path = + if let Qualified::With { path, .. } = qualified { Some(path) } else { None }; let attributes = annotated_item_kind.and_then(|kind| { if ast::Expr::can_cast(kind) { @@ -149,18 +161,28 @@ pub(crate) fn complete_attribute_path( }); let add_completion = |attr_completion: &AttrCompletion| { - let mut item = CompletionItem::new( - SymbolKind::Attribute, - ctx.source_range(), - attr_completion.label, - ctx.edition, - ); + // if we already have the qualifier of the completion, then trim it from the label and the snippet + let mut label = attr_completion.label; + let mut snippet = attr_completion.snippet; + if let Some(name_ref) = qualifier_path.and_then(|q| q.as_single_name_ref()) { + if let Some((label_qual, label_seg)) = attr_completion.label.split_once("::") { + if name_ref.text() == label_qual { + label = label_seg; + snippet = snippet.map(|snippet| { + snippet.trim_start_matches(label_qual).trim_start_matches("::") + }); + } + } + } + + let mut item = + CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), label, ctx.edition); if let Some(lookup) = attr_completion.lookup { item.lookup_by(lookup); } - if let Some((snippet, cap)) = attr_completion.snippet.zip(ctx.config.snippet_cap) { + if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) { item.insert_snippet(cap, snippet); } @@ -270,8 +292,8 @@ static KIND_TO_ATTRIBUTES: LazyLock> = LazyLock:: ), ), (STATIC, attrs!(item, linkable, "global_allocator", "used")), - (TRAIT, attrs!(item)), - (IMPL, attrs!(item, "automatically_derived")), + (TRAIT, attrs!(item, "diagnostic::on_unimplemented")), + (IMPL, attrs!(item, "automatically_derived", "diagnostic::do_not_recommend")), (ASSOC_ITEM_LIST, attrs!(item)), (EXTERN_BLOCK, attrs!(item, "link")), (EXTERN_ITEM_LIST, attrs!(item, "link")), @@ -311,6 +333,8 @@ const ATTRIBUTES: &[AttrCompletion] = &[ attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), attr(r#"deprecated"#, Some("deprecated"), Some(r#"deprecated"#)), attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), + attr("diagnostic::do_not_recommend", None, None), + attr("diagnostic::on_unimplemented", None, Some(r#"diagnostic::on_unimplemented(${0:keys})"#)), attr(r#"doc = "…""#, Some("doc"), Some(r#"doc = "${0:docs}""#)), attr(r#"doc(alias = "…")"#, Some("docalias"), Some(r#"doc(alias = "${0:docs}")"#)), attr(r#"doc(hidden)"#, Some("dochidden"), Some(r#"doc(hidden)"#)), diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs new file mode 100644 index 000000000000..10c5135b4b57 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs @@ -0,0 +1,60 @@ +//! Completion for diagnostic attributes. + +use ide_db::SymbolKind; +use syntax::ast::{self}; + +use crate::{CompletionItem, Completions, context::CompletionContext}; + +use super::AttrCompletion; + +pub(super) fn complete_on_unimplemented( + acc: &mut Completions, + ctx: &CompletionContext<'_>, + input: ast::TokenTree, +) { + if let Some(existing_keys) = super::parse_comma_sep_expr(input) { + for attr in ATTRIBUTES { + let already_annotated = existing_keys + .iter() + .filter_map(|expr| match expr { + ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(), + ast::Expr::BinExpr(bin) + if bin.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) => + { + match bin.lhs()? { + ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(), + _ => None, + } + } + _ => None, + }) + .any(|it| { + let text = it.text(); + attr.key() == text && text != "note" + }); + if already_annotated { + continue; + } + + let mut item = CompletionItem::new( + SymbolKind::BuiltinAttr, + ctx.source_range(), + attr.label, + ctx.edition, + ); + if let Some(lookup) = attr.lookup { + item.lookup_by(lookup); + } + if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) { + item.insert_snippet(cap, snippet); + } + item.add_to(acc, ctx.db); + } + } +} + +const ATTRIBUTES: &[AttrCompletion] = &[ + super::attr(r#"label = "…""#, Some("label"), Some(r#"label = "${0:label}""#)), + super::attr(r#"message = "…""#, Some("message"), Some(r#"message = "${0:message}""#)), + super::attr(r#"note = "…""#, Some("note"), Some(r#"note = "${0:note}""#)), +]; diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs index 32d3b50f237e..411902f1117a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs @@ -30,6 +30,8 @@ pub struct Foo(#[m$0] i32); at deprecated at derive macro derive at derive(…) + at diagnostic::do_not_recommend + at diagnostic::on_unimplemented at doc = "…" at doc(alias = "…") at doc(hidden) @@ -472,13 +474,13 @@ fn attr_on_trait() { at cfg_attr(…) at deny(…) at deprecated + at diagnostic::on_unimplemented at doc = "…" at doc(alias = "…") at doc(hidden) at expect(…) at forbid(…) at must_use - at must_use at no_mangle at warn(…) kw crate:: @@ -498,6 +500,7 @@ fn attr_on_impl() { at cfg_attr(…) at deny(…) at deprecated + at diagnostic::do_not_recommend at doc = "…" at doc(alias = "…") at doc(hidden) @@ -532,6 +535,76 @@ fn attr_on_impl() { ); } +#[test] +fn attr_with_qualifier() { + check( + r#"#[diagnostic::$0] impl () {}"#, + expect![[r#" + at allow(…) + at automatically_derived + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at do_not_recommend + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at expect(…) + at forbid(…) + at must_use + at no_mangle + at warn(…) + "#]], + ); + check( + r#"#[diagnostic::$0] trait Foo {}"#, + expect![[r#" + at allow(…) + at cfg(…) + at cfg_attr(…) + at deny(…) + at deprecated + at doc = "…" + at doc(alias = "…") + at doc(hidden) + at expect(…) + at forbid(…) + at must_use + at no_mangle + at on_unimplemented + at warn(…) + "#]], + ); +} + +#[test] +fn attr_diagnostic_on_unimplemented() { + check( + r#"#[diagnostic::on_unimplemented($0)] trait Foo {}"#, + expect![[r#" + ba label = "…" + ba message = "…" + ba note = "…" + "#]], + ); + check( + r#"#[diagnostic::on_unimplemented(message = "foo", $0)] trait Foo {}"#, + expect![[r#" + ba label = "…" + ba note = "…" + "#]], + ); + check( + r#"#[diagnostic::on_unimplemented(note = "foo", $0)] trait Foo {}"#, + expect![[r#" + ba label = "…" + ba message = "…" + ba note = "…" + "#]], + ); +} + #[test] fn attr_on_extern_block() { check( @@ -619,7 +692,6 @@ fn attr_on_fn() { at link_name = "…" at link_section = "…" at must_use - at must_use at no_mangle at panic_handler at proc_macro @@ -649,6 +721,8 @@ fn attr_in_source_file_end() { at deny(…) at deprecated at derive(…) + at diagnostic::do_not_recommend + at diagnostic::on_unimplemented at doc = "…" at doc(alias = "…") at doc(hidden) From ddcc1afd4de546ec4c6b2cc7d3027c6a37f23caf Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Fri, 30 May 2025 23:53:30 +0900 Subject: [PATCH 021/183] fix: Cycle handlers for `HirDatabase::infer, const_param_ty_with_diagnostics --- .../rust-analyzer/crates/hir-ty/src/db.rs | 2 + .../rust-analyzer/crates/hir-ty/src/infer.rs | 7 +++ .../rust-analyzer/crates/hir-ty/src/lower.rs | 20 +++++--- .../crates/hir-ty/src/mir/lower.rs | 2 +- .../crates/hir-ty/src/tests/regression.rs | 48 +++++++++++++++++++ 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 980ee264b027..1e985dc604ee 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs @@ -31,6 +31,7 @@ use crate::{ #[query_group::query_group] pub trait HirDatabase: DefDatabase + std::fmt::Debug { #[salsa::invoke(crate::infer::infer_query)] + #[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)] fn infer(&self, def: DefWithBodyId) -> Arc; // region:mir @@ -132,6 +133,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { // FIXME: Make this a non-interned query. #[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)] + #[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)] fn const_param_ty_with_diagnostics(&self, def: ConstParamId) -> (Ty, Diagnostics); #[salsa::invoke(crate::lower::const_param_ty_query)] diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index e698fb201cb8..840a916c24ad 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -135,6 +135,10 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc Arc { + Arc::new(InferenceResult { has_errors: true, ..Default::default() }) +} + /// Fully normalize all the types found within `ty` in context of `owner` body definition. /// /// This is appropriate to use only after type-check: it assumes @@ -558,6 +562,9 @@ impl InferenceResult { ExprOrPatId::PatId(id) => self.type_of_pat.get(id), } } + pub fn is_erroneous(&self) -> bool { + self.has_errors && self.type_of_expr.iter().count() == 0 + } } impl Index for InferenceResult { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index ea8e7cc2be90..0a546768dab4 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -1604,6 +1604,14 @@ pub(crate) fn impl_self_ty_with_diagnostics_query( ) } +pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( + db: &dyn HirDatabase, + impl_id: ImplId, +) -> (Binders, Diagnostics) { + let generics = generics(db, impl_id.into()); + (make_binders(db, &generics, TyKind::Error.intern(Interner)), None) +} + pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { db.const_param_ty_with_diagnostics(def).0 } @@ -1633,12 +1641,12 @@ pub(crate) fn const_param_ty_with_diagnostics_query( (ty, create_diagnostics(ctx.diagnostics)) } -pub(crate) fn impl_self_ty_with_diagnostics_cycle_result( - db: &dyn HirDatabase, - impl_id: ImplId, -) -> (Binders, Diagnostics) { - let generics = generics(db, impl_id.into()); - (make_binders(db, &generics, TyKind::Error.intern(Interner)), None) +pub(crate) fn const_param_ty_with_diagnostics_cycle_result( + _: &dyn HirDatabase, + _: crate::db::HirDatabaseData, + _: ConstParamId, +) -> (Ty, Diagnostics) { + (TyKind::Error.intern(Interner), None) } pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option> { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index e6caf2d8d97a..99d935153037 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs @@ -2182,7 +2182,7 @@ pub fn lower_to_mir( // need to take this input explicitly. root_expr: ExprId, ) -> Result { - if infer.type_mismatches().next().is_some() { + if infer.type_mismatches().next().is_some() || infer.is_erroneous() { return Err(MirLowerError::HasErrors); } let mut ctx = MirLowerCtx::new(db, owner, body, infer); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 47c695c69748..ff8adeef1dbe 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -2301,3 +2301,51 @@ trait Foo { "#]], ); } + +#[test] +fn no_panic_on_recursive_const() { + check_infer( + r#" +struct Foo {} +impl> Foo { + fn foo(self) {} +} + +fn test() { + let _ = N; +} +"#, + expect![[r#" + 72..76 'self': Foo + 78..80 '{}': () + 94..112 '{ ...= N; }': () + 104..105 '_': {unknown} + 108..109 'N': {unknown} + "#]], + ); + + check_infer( + r#" +struct Foo; +const N: Foo = Foo; + +impl Foo { + fn foo(self) -> usize { + N + } +} + +fn test() { + let _ = N; +} +"#, + expect![[r#" + 93..97 'self': Foo + 108..125 '{ ... }': usize + 118..119 'N': usize + 139..157 '{ ...= N; }': () + 149..150 '_': Foo<_> + 153..154 'N': Foo<_> + "#]], + ); +} From 1a1d180effb3fc78b98d1a02979df80d96db6bca Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 3 Jun 2025 04:54:36 +0000 Subject: [PATCH 022/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 553d410b2bc7..15f06b60d0f9 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -337c11e5932275e7d450c1f2e26f289f0ddfa717 +99426c570eebec8dcba2eaa8f5057265346aaedc From e323eae5590588d75445e2a53104b654a2dca124 Mon Sep 17 00:00:00 2001 From: Tyler Breisacher Date: Mon, 26 May 2025 12:23:29 -0700 Subject: [PATCH 023/183] Add a quickfix for accessing a private field of a struct --- .../rust-analyzer/crates/hir-ty/src/infer.rs | 5 +- .../crates/hir-ty/src/infer/expr.rs | 4 +- .../crates/hir-ty/src/infer/pat.rs | 4 +- .../crates/hir/src/diagnostics.rs | 3 +- .../src/handlers/fix_visibility.rs | 147 +--------------- .../src/handlers/no_such_field.rs | 157 ++++++++++++++---- 6 files changed, 138 insertions(+), 182 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index e698fb201cb8..7d8e0f7dd23d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -35,7 +35,8 @@ use chalk_ir::{ use either::Either; use hir_def::{ AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, - ImplId, ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId, + ImplId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, + VariantId, builtin_type::{BuiltinInt, BuiltinType, BuiltinUint}, expr_store::{Body, ExpressionStore, HygieneId, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, @@ -203,7 +204,7 @@ pub(crate) type InferResult = Result, TypeError>; pub enum InferenceDiagnostic { NoSuchField { field: ExprOrPatId, - private: bool, + private: Option, variant: VariantId, }, PrivateField { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 87b7f3406ff7..640312792963 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -554,7 +554,7 @@ impl InferenceContext<'_> { self.push_diagnostic( InferenceDiagnostic::NoSuchField { field: field.expr.into(), - private: true, + private: Some(local_id), variant: def, }, ); @@ -564,7 +564,7 @@ impl InferenceContext<'_> { None => { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: field.expr.into(), - private: false, + private: None, variant: def, }); None diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs index a9a3265858e4..4bc3e167ebf7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/pat.rs @@ -143,7 +143,7 @@ impl InferenceContext<'_> { { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: inner.into(), - private: true, + private: Some(local_id), variant: def, }); } @@ -157,7 +157,7 @@ impl InferenceContext<'_> { None => { self.push_diagnostic(InferenceDiagnostic::NoSuchField { field: inner.into(), - private: false, + private: None, variant: def, }); self.err_ty() diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs index b6e3002ed5d4..f7b140e03d43 100644 --- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs @@ -224,7 +224,7 @@ pub struct MalformedDerive { #[derive(Debug)] pub struct NoSuchField { pub field: InFile>>, - pub private: bool, + pub private: Option, pub variant: VariantId, } @@ -648,6 +648,7 @@ impl AnyDiagnostic { } ExprOrPatId::PatId(pat) => source_map.pat_field_syntax(pat), }; + let private = private.map(|id| Field { id, parent: variant.into() }); NoSuchField { field: expr_or_pat, private, variant }.into() } &InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs index 19e0a73f3335..3badc17d01af 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/fix_visibility.rs @@ -7,10 +7,10 @@ use syntax::{ use crate::{AssistContext, AssistId, Assists}; -// FIXME: this really should be a fix for diagnostic, rather than an assist. - // Assist: fix_visibility // +// Note that there is some duplication between this and the no_such_field diagnostic. +// // Makes inaccessible item public. // // ``` @@ -32,7 +32,6 @@ use crate::{AssistContext, AssistId, Assists}; // ``` pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { add_vis_to_referenced_module_def(acc, ctx) - .or_else(|| add_vis_to_referenced_record_field(acc, ctx)) } fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { @@ -88,59 +87,6 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) }) } -fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let record_field: ast::RecordExprField = ctx.find_node_at_offset()?; - let (record_field_def, _, _) = ctx.sema.resolve_record_field(&record_field)?; - - let current_module = ctx.sema.scope(record_field.syntax())?.module(); - let current_edition = current_module.krate().edition(ctx.db()); - let visibility = record_field_def.visibility(ctx.db()); - if visibility.is_visible_from(ctx.db(), current_module.into()) { - return None; - } - - let parent = record_field_def.parent_def(ctx.db()); - let parent_name = parent.name(ctx.db()); - let target_module = parent.module(ctx.db()); - - let in_file_source = record_field_def.source(ctx.db())?; - let (vis_owner, target) = match in_file_source.value { - hir::FieldSource::Named(it) => { - let range = it.syntax().text_range(); - (ast::AnyHasVisibility::new(it), range) - } - hir::FieldSource::Pos(it) => { - let range = it.syntax().text_range(); - (ast::AnyHasVisibility::new(it), range) - } - }; - - let missing_visibility = if current_module.krate() == target_module.krate() { - make::visibility_pub_crate() - } else { - make::visibility_pub() - }; - let target_file = in_file_source.file_id.original_file(ctx.db()); - - let target_name = record_field_def.name(ctx.db()); - let assist_label = format!( - "Change visibility of {}.{} to {missing_visibility}", - parent_name.display(ctx.db(), current_edition), - target_name.display(ctx.db(), current_edition) - ); - - acc.add(AssistId::quick_fix("fix_visibility"), assist_label, target, |edit| { - edit.edit_file(target_file.file_id(ctx.db())); - - let vis_owner = edit.make_mut(vis_owner); - vis_owner.set_visibility(Some(missing_visibility.clone_for_update())); - - if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) { - edit.add_tabstop_before(cap, vis); - } - }) -} - fn target_data_for_def( db: &dyn HirDatabase, def: hir::ModuleDef, @@ -293,44 +239,6 @@ struct Foo; ); } - #[test] - fn fix_visibility_of_struct_field() { - check_assist( - fix_visibility, - r"mod foo { pub struct Foo { bar: (), } } - fn main() { foo::Foo { $0bar: () }; } ", - r"mod foo { pub struct Foo { $0pub(crate) bar: (), } } - fn main() { foo::Foo { bar: () }; } ", - ); - check_assist( - fix_visibility, - r" -//- /lib.rs -mod foo; -fn main() { foo::Foo { $0bar: () }; } -//- /foo.rs -pub struct Foo { bar: () } -", - r"pub struct Foo { $0pub(crate) bar: () } -", - ); - check_assist_not_applicable( - fix_visibility, - r"mod foo { pub struct Foo { pub bar: (), } } - fn main() { foo::Foo { $0bar: () }; } ", - ); - check_assist_not_applicable( - fix_visibility, - r" -//- /lib.rs -mod foo; -fn main() { foo::Foo { $0bar: () }; } -//- /foo.rs -pub struct Foo { pub bar: () } -", - ); - } - #[test] fn fix_visibility_of_enum_variant_field() { // Enum variants, as well as their fields, always get the enum's visibility. In fact, rustc @@ -367,44 +275,6 @@ pub struct Foo { pub bar: () } ); } - #[test] - fn fix_visibility_of_union_field() { - check_assist( - fix_visibility, - r"mod foo { pub union Foo { bar: (), } } - fn main() { foo::Foo { $0bar: () }; } ", - r"mod foo { pub union Foo { $0pub(crate) bar: (), } } - fn main() { foo::Foo { bar: () }; } ", - ); - check_assist( - fix_visibility, - r" -//- /lib.rs -mod foo; -fn main() { foo::Foo { $0bar: () }; } -//- /foo.rs -pub union Foo { bar: () } -", - r"pub union Foo { $0pub(crate) bar: () } -", - ); - check_assist_not_applicable( - fix_visibility, - r"mod foo { pub union Foo { pub bar: (), } } - fn main() { foo::Foo { $0bar: () }; } ", - ); - check_assist_not_applicable( - fix_visibility, - r" -//- /lib.rs -mod foo; -fn main() { foo::Foo { $0bar: () }; } -//- /foo.rs -pub union Foo { pub bar: () } -", - ); - } - #[test] fn fix_visibility_of_const() { check_assist( @@ -570,19 +440,6 @@ foo::Bar$0 pub(crate) struct Bar; ", r"$0pub struct Bar; -", - ); - check_assist( - fix_visibility, - r" -//- /main.rs crate:a deps:foo -fn main() { - foo::Foo { $0bar: () }; -} -//- /lib.rs crate:foo -pub struct Foo { pub(crate) bar: () } -", - r"pub struct Foo { $0pub bar: () } ", ); } diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs index 84fb467a5ce1..ef42f2dc7448 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/no_such_field.rs @@ -1,4 +1,5 @@ use either::Either; +use hir::{Field, HasCrate}; use hir::{HasSource, HirDisplay, Semantics, VariantId, db::ExpandDatabase}; use ide_db::text_edit::TextEdit; use ide_db::{EditionedFileId, RootDatabase, source_change::SourceChange}; @@ -13,44 +14,69 @@ use crate::{Assist, Diagnostic, DiagnosticCode, DiagnosticsContext, fix}; // // This diagnostic is triggered if created structure does not have field provided in record. pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Diagnostic { - let node = d.field.map(Into::into); - if d.private { - // FIXME: quickfix to add required visibility - Diagnostic::new_with_syntax_node_ptr( - ctx, - DiagnosticCode::RustcHardError("E0451"), - "field is private", - node, - ) - .stable() + let (code, message) = if d.private.is_some() { + ("E0451", "field is private") + } else if let VariantId::EnumVariantId(_) = d.variant { + ("E0559", "no such field") } else { - Diagnostic::new_with_syntax_node_ptr( - ctx, - match d.variant { - VariantId::EnumVariantId(_) => DiagnosticCode::RustcHardError("E0559"), - _ => DiagnosticCode::RustcHardError("E0560"), - }, - "no such field", - node, - ) + ("E0560", "no such field") + }; + + let node = d.field.map(Into::into); + Diagnostic::new_with_syntax_node_ptr(ctx, DiagnosticCode::RustcHardError(code), message, node) .stable() .with_fixes(fixes(ctx, d)) - } } fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Option> { // FIXME: quickfix for pattern let root = ctx.sema.db.parse_or_expand(d.field.file_id); match &d.field.value.to_node(&root) { - Either::Left(node) => missing_record_expr_field_fixes( - &ctx.sema, - d.field.file_id.original_file(ctx.sema.db), - node, - ), + Either::Left(node) => { + if let Some(private_field) = d.private { + field_is_private_fixes( + &ctx.sema, + d.field.file_id.original_file(ctx.sema.db), + node, + private_field, + ) + } else { + missing_record_expr_field_fixes( + &ctx.sema, + d.field.file_id.original_file(ctx.sema.db), + node, + ) + } + } _ => None, } } +fn field_is_private_fixes( + sema: &Semantics<'_, RootDatabase>, + usage_file_id: EditionedFileId, + record_expr_field: &ast::RecordExprField, + private_field: Field, +) -> Option> { + let def_crate = private_field.krate(sema.db); + let usage_crate = sema.file_to_module_def(usage_file_id.file_id(sema.db))?.krate(); + let visibility = if usage_crate == def_crate { "pub(crate) " } else { "pub " }; + + let source = private_field.source(sema.db)?; + let (range, _) = source.syntax().original_file_range_opt(sema.db)?; + let source_change = SourceChange::from_text_edit( + range.file_id.file_id(sema.db), + TextEdit::insert(range.range.start(), visibility.into()), + ); + + Some(vec![fix( + "increase_field_visibility", + "Increase field visibility", + source_change, + sema.original_range(record_expr_field.syntax()).range, + )]) +} + fn missing_record_expr_field_fixes( sema: &Semantics<'_, RootDatabase>, usage_file_id: EditionedFileId, @@ -118,7 +144,7 @@ fn missing_record_expr_field_fixes( "create_field", "Create field", source_change, - record_expr_field.syntax().text_range(), + sema.original_range(record_expr_field.syntax()).range, )]); fn record_field_list(field_def_list: ast::FieldList) -> Option { @@ -387,21 +413,92 @@ fn f(s@m::Struct { // assignee expression m::Struct { field: 0, - //^^^^^^^^ error: field is private + //^^^^^^^^ 💡 error: field is private field2 - //^^^^^^ error: field is private + //^^^^^^ 💡 error: field is private } = s; m::Struct { field: 0, - //^^^^^^^^ error: field is private + //^^^^^^^^ 💡 error: field is private field2 - //^^^^^^ error: field is private + //^^^^^^ 💡 error: field is private }; } "#, ) } + #[test] + fn test_struct_field_private_same_crate_fix() { + check_diagnostics( + r#" +mod m { + pub struct Struct { + field: u32, + } +} +fn f() { + let _ = m::Struct { + field: 0, + //^^^^^^^^ 💡 error: field is private + }; +} +"#, + ); + + check_fix( + r#" +mod m { + pub struct Struct { + field: u32, + } +} +fn f() { + let _ = m::Struct { + field$0: 0, + }; +} +"#, + r#" +mod m { + pub struct Struct { + pub(crate) field: u32, + } +} +fn f() { + let _ = m::Struct { + field: 0, + }; +} +"#, + ); + } + + #[test] + fn test_struct_field_private_other_crate_fix() { + check_fix( + r#" +//- /lib.rs crate:another_crate +pub struct Struct { + field: u32, +} +//- /lib.rs crate:this_crate deps:another_crate +use another_crate; + +fn f() { + let _ = another_crate::Struct { + field$0: 0, + }; +} +"#, + r#" +pub struct Struct { + pub field: u32, +} +"#, + ); + } + #[test] fn editions_between_macros() { check_diagnostics( From 1cefc216c72f6201525317407e472cd0ca21d3f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:11:14 +0000 Subject: [PATCH 024/183] chore(deps): bump tar-fs from 2.1.2 to 2.1.3 in /editors/code Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 2.1.2 to 2.1.3. - [Commits](https://github.com/mafintosh/tar-fs/commits) --- updated-dependencies: - dependency-name: tar-fs dependency-version: 2.1.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- src/tools/rust-analyzer/editors/code/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json index 18fb097aad7f..ab431140c10d 100644 --- a/src/tools/rust-analyzer/editors/code/package-lock.json +++ b/src/tools/rust-analyzer/editors/code/package-lock.json @@ -5500,9 +5500,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", "dev": true, "license": "MIT", "optional": true, From 7dac755be8d09234afa0ac6c3626c8d5f733ef31 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 30 May 2025 11:21:34 +0000 Subject: [PATCH 025/183] `FIXME(-Znext-solver)` triage Co-authored-by: Michael Goulet --- .../src/type_check/constraint_conversion.rs | 5 ++++- compiler/rustc_hir_analysis/src/autoderef.rs | 16 ++++++++-------- .../src/hir_ty_lowering/mod.rs | 6 +++++- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/demand.rs | 6 +++++- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +--- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 7 ++++--- compiler/rustc_hir_typeck/src/method/probe.rs | 15 +++++++-------- .../src/infer/outlives/obligations.rs | 5 ++++- compiler/rustc_middle/src/ty/context.rs | 4 ++++ compiler/rustc_mir_transform/src/inline/cycle.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 4 ++-- .../src/solve/normalizes_to/inherent.rs | 3 +++ .../src/solve/trait_goals.rs | 6 +++++- .../src/traits/normalize.rs | 2 +- compiler/rustc_traits/src/codegen.rs | 1 - compiler/rustc_type_ir/src/fast_reject.rs | 11 ++++++++--- compiler/rustc_type_ir/src/interner.rs | 4 ++++ .../recursive-coroutine-boxed.next.stderr | 2 +- tests/ui/impl-trait/recursive-coroutine-boxed.rs | 3 --- 20 files changed, 68 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index a1c74672157b..0a114467f432 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -141,8 +141,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } if !tcx.recursion_limit().value_within_limit(iteration) { + // This may actually be reachable. If so, we should convert + // this to a proper error/consider whether we should detect + // this somewhere else. bug!( - "FIXME(-Znext-solver): Overflowed when processing region obligations: {outlives_predicates:#?}" + "unexpected overflowed when processing region obligations: {outlives_predicates:#?}" ); } diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 99e495d92669..c88c534e1354 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -160,7 +160,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.param_env, ty::Binder::dummy(trait_ref), ); - if !self.infcx.predicate_may_hold(&obligation) { + if !self.infcx.next_trait_solver() && !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); return None; } @@ -184,17 +184,17 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.param_env, ty, ) else { - // We shouldn't have errors here, except for evaluate/fulfill mismatches, - // but that's not a reason for an ICE (`predicate_may_hold` is conservative - // by design). - // FIXME(-Znext-solver): This *actually* shouldn't happen then. + // We shouldn't have errors here in the old solver, except for + // evaluate/fulfill mismatches, but that's not a reason for an ICE. return None; }; let errors = ocx.select_where_possible(); if !errors.is_empty() { - // This shouldn't happen, except for evaluate/fulfill mismatches, - // but that's not a reason for an ICE (`predicate_may_hold` is conservative - // by design). + if self.infcx.next_trait_solver() { + unreachable!(); + } + // We shouldn't have errors here in the old solver, except for + // evaluate/fulfill mismatches, but that's not a reason for an ICE. debug!(?errors, "encountered errors while fulfilling"); return None; } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2a37a8bdbd47..b22590e0a912 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -805,7 +805,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) }); let bound = (bound.upcast(tcx), span); - // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. + // FIXME(-Znext-solver): We can likely remove this hack once the + // new trait solver lands. This fixed an overflow in the old solver. + // This may have performance implications, so please check perf when + // removing it. + // This was added in . if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) { bounds.insert(0, bound); } else { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 61dd8c573073..4ac260cb15f4 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -600,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (def_id, args) = match *expected_ty.kind() { // FIXME: Could also check that the RPIT is not defined ty::Alias(ty::Opaque, alias_ty) => (alias_ty.def_id.as_local()?, alias_ty.args), - // FIXME(-Znext-solver): Remove this branch once `replace_opaque_types_with_infer` is gone. + // FIXME(-Znext-solver=no): Remove this branch once `replace_opaque_types_with_infer` is gone. ty::Infer(ty::TyVar(_)) => self .inner .borrow_mut() diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 152c88ad92a5..5b55fbe91500 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -260,7 +260,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, ) -> Result, Diag<'a>> { - let expected = self.resolve_vars_with_obligations(expected); + let expected = if self.next_trait_solver() { + expected + } else { + self.resolve_vars_with_obligations(expected) + }; let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { Ok(ty) => return Ok(ty), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 362c7d8efac0..c84e1113d65f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1436,8 +1436,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// in this case. #[instrument(level = "debug", skip(self, sp), ret)] pub(crate) fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { - let ty = self.resolve_vars_with_obligations(ty); - if self.next_trait_solver() && let ty::Alias(..) = ty.kind() { @@ -1455,7 +1453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } else { - ty + self.resolve_vars_with_obligations(ty) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index a5c0829b8d9e..393556928af8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -412,9 +412,10 @@ pub(crate) struct LoweredTy<'tcx> { impl<'tcx> LoweredTy<'tcx> { fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx> { - // FIXME(-Znext-solver): We're still figuring out how to best handle - // normalization and this doesn't feel too great. We should look at this - // code again before stabilizing it. + // FIXME(-Znext-solver=no): This is easier than requiring all uses of `LoweredTy` + // to call `try_structurally_resolve_type` instead. This seems like a lot of + // effort, especially as we're still supporting the old solver. We may revisit + // this in the future. let normalized = if fcx.next_trait_solver() { fcx.try_structurally_resolve_type(span, raw) } else { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 725240b480ba..a3fdf200c8ea 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1913,8 +1913,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ty::Binder::dummy(trait_ref), ); - // FIXME(-Znext-solver): We only need this hack to deal with fatal - // overflow in the old solver. + // We only need this hack to deal with fatal overflow in the old solver. if self.infcx.next_trait_solver() || self.infcx.predicate_may_hold(&obligation) { ocx.register_obligation(obligation); @@ -1955,17 +1954,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - // FIXME(-Znext-solver): See the linked issue below. - // + // See . // // In the new solver, check the well-formedness of the return type. // This emulates, in a way, the predicates that fall out of // normalizing the return type in the old solver. // - // We alternatively could check the predicates of the method itself hold, - // but we intentionally do not do this in the old solver b/c of cycles, - // and doing it in the new solver would be stronger. This should be fixed - // in the future, since it likely leads to much better method winnowing. + // FIXME(-Znext-solver): We alternatively could check the predicates of + // the method itself hold, but we intentionally do not do this in the old + // solver b/c of cycles, and doing it in the new solver would be stronger. + // This should be fixed in the future, since it likely leads to much better + // method winnowing. if let Some(xform_ret_ty) = xform_ret_ty && self.infcx.next_trait_solver() { diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 10827c9fd037..db937b3e83eb 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -198,8 +198,11 @@ impl<'tcx> InferCtxt<'tcx> { } if !self.tcx.recursion_limit().value_within_limit(iteration) { + // This may actually be reachable. If so, we should convert + // this to a proper error/consider whether we should detect + // this somewhere else. bug!( - "FIXME(-Znext-solver): Overflowed when processing region obligations: {my_region_obligations:#?}" + "unexpected overflowed when processing region obligations: {my_region_obligations:#?}" ); } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 57b20a1bba60..2bf37f69bf19 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -86,6 +86,10 @@ use crate::ty::{ #[allow(rustc::usage_of_ty_tykind)] impl<'tcx> Interner for TyCtxt<'tcx> { + fn next_trait_solver_globally(self) -> bool { + self.next_trait_solver_globally() + } + type DefId = DefId; type LocalDefId = LocalDefId; type Span = Span; diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 292278800f8a..a944960ce4ab 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -138,7 +138,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( } false } - // FIXME(-Znext-solver): Remove this hack when trait solver overflow can return an error. + // FIXME(-Znext-solver=no): Remove this hack when trait solver overflow can return an error. // In code like that pointed out in #128887, the type complexity we ask the solver to deal with // grows as we recurse into the call graph. If we use the same recursion limit here and in the // solver, the solver hits the limit first and emits a fatal error. But if we use a reduced diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index a7a984181d7f..e4e0aba7b502 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -237,8 +237,8 @@ where return None; } - // FIXME(-Znext-solver): We should instead try to find a `Certainty::Yes` response with - // a subset of the constraints that all the other responses have. + // FIXME(-Znext-solver): Add support to merge region constraints in + // responses to deal with trait-system-refactor-initiative#27. let one = responses[0]; if responses[1..].iter().all(|&resp| resp == one) { return Some(one); diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 2640238f5a90..26443c54e184 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -41,6 +41,9 @@ where // and we tag the impl bounds with `GoalSource::ImplWhereBound`? // Right now this includes both the impl and the assoc item where bounds, // and I don't think the assoc item where-bounds are allowed to be coinductive. + // + // Projecting to the IAT also "steps out the impl contructor", so we would have + // to be very careful when changing the impl where-clauses to be productive. self.add_goals( GoalSource::Misc, cx.predicates_of(inherent.def_id) diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 7c4e1dc2c12e..110c67a8e215 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -235,7 +235,11 @@ where .predicates_of(goal.predicate.def_id()) .iter_instantiated(cx, goal.predicate.trait_ref.args) .map(|p| goal.with(cx, p)); - // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? + // While you could think of trait aliases to have a single builtin impl + // which uses its implied trait bounds as where-clauses, using + // `GoalSource::ImplWhereClause` here would be incorrect, as we also + // impl them, which means we're "stepping out of the impl constructor" + // again. To handle this, we treat these cycles as ambiguous for now. ecx.add_goals(GoalSource::Misc, nested_obligations); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index eb6d5c8a60a2..35a43b294ee0 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -47,7 +47,7 @@ impl<'tcx> At<'_, 'tcx> { /// same goals in both a temporary and the shared context which negatively impacts /// performance as these don't share caching. /// - /// FIXME(-Znext-solver): For performance reasons, we currently reuse an existing + /// FIXME(-Znext-solver=no): For performance reasons, we currently reuse an existing /// fulfillment context in the old solver. Once we have removed the old solver, we /// can remove the `fulfill_cx` parameter on this function. fn deeply_normalize( diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 88f02d16c7d5..a0a1d4545564 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -58,7 +58,6 @@ pub(crate) fn codegen_select_candidate<'tcx>( // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. - // FIXME(-Znext-solver): Doesn't need diagnostics if new solver. let ocx = ObligationCtxt::new(&infcx); let impl_source = selection.map(|obligation| { ocx.register_obligation(obligation); diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 34502f495500..615d07707b9d 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -84,6 +84,9 @@ pub enum TreatParams { /// /// This also treats projections with inference variables as infer vars /// since they could be further normalized. + // FIXME(@lcnr): This treats aliases as rigid. This is only correct if the + // type has been structurally normalized. We should reflect this requirement + // in the variant name. It is currently incorrectly used in diagnostics. AsRigid, } @@ -151,9 +154,11 @@ pub fn simplify_type( ty::Alias(..) => match treat_params { // When treating `ty::Param` as a placeholder, projections also // don't unify with anything else as long as they are fully normalized. - // FIXME(-Znext-solver): Can remove this `if` and always simplify to `Placeholder` - // when the new solver is enabled by default. - TreatParams::AsRigid if !ty.has_non_region_infer() => Some(SimplifiedType::Placeholder), + TreatParams::AsRigid + if !ty.has_non_region_infer() || cx.next_trait_solver_globally() => + { + Some(SimplifiedType::Placeholder) + } TreatParams::AsRigid | TreatParams::InstantiateWithInfer => None, }, ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)), diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index a9917192144f..a131c7148687 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -33,6 +33,10 @@ pub trait Interner: + IrPrint> + IrPrint> { + fn next_trait_solver_globally(self) -> bool { + true + } + type DefId: DefId; type LocalDefId: Copy + Debug + Hash + Eq + Into + TypeFoldable; type Span: Span; diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index 132f7de4ef23..5ce6eb0fc398 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:14:23 + --> $DIR/recursive-coroutine-boxed.rs:11:23 | LL | let mut gen = Box::pin(foo()); | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 8d38e6aed124..306edc3591e9 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -7,9 +7,6 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine { - // FIXME(-Znext-solver): this fails with a mismatched types as the - // hidden type of the opaque ends up as {type error}. We should not - // emit errors for such goals. #[coroutine] || { let mut gen = Box::pin(foo()); //[next]~^ ERROR type annotations needed From 840142b7f7f7e53d65cca9630d55702949ec8a4c Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 4 Jun 2025 00:14:00 +0900 Subject: [PATCH 026/183] ci: Pin `cargo-workspaces` to `0.3.6` --- src/tools/rust-analyzer/.github/workflows/publish-libs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml index 93ae5675a71a..f2c8b6365b66 100644 --- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml +++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml @@ -22,7 +22,7 @@ jobs: run: rustup update --no-self-update stable - name: Install cargo-workspaces - run: cargo install cargo-workspaces + run: cargo install cargo-workspaces --version "0.3.6" - name: Publish Crates env: From 5bafe9d8fcad72b97f8b00f40ce8115f54d80504 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Wed, 5 Mar 2025 15:00:24 +0100 Subject: [PATCH 027/183] Enable Float non-determinism in miri. Update and add tests and change change tests in std, core and coretests. --- library/coretests/tests/floats/f64.rs | 2 +- library/coretests/tests/num/dec2flt/float.rs | 6 +- library/std/src/num/f32.rs | 32 +-- library/std/src/num/f64.rs | 4 +- library/std/tests/floats/f32.rs | 73 +++++- library/std/tests/floats/f64.rs | 8 +- src/tools/miri/src/intrinsics/mod.rs | 262 ++++++++++++++----- src/tools/miri/src/math.rs | 14 + src/tools/miri/tests/pass/float.rs | 113 +++++++- 9 files changed, 413 insertions(+), 101 deletions(-) diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs index 74202a374091..dd5b67c251dc 100644 --- a/library/coretests/tests/floats/f64.rs +++ b/library/coretests/tests/floats/f64.rs @@ -422,7 +422,7 @@ fn test_powi() { let nan: f64 = f64::NAN; let inf: f64 = f64::INFINITY; let neg_inf: f64 = f64::NEG_INFINITY; - assert_biteq!(1.0f64.powi(1), 1.0); + assert_approx_eq!(1.0f64.powi(1), 1.0); assert_approx_eq!((-3.1f64).powi(2), 9.61); assert_approx_eq!(5.9f64.powi(-2), 0.028727); assert_biteq!(8.3f64.powi(0), 1.0); diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs index 264de061be98..2407ba50ca31 100644 --- a/library/coretests/tests/num/dec2flt/float.rs +++ b/library/coretests/tests/num/dec2flt/float.rs @@ -23,7 +23,8 @@ fn test_f16_integer_decode() { fn test_f32_integer_decode() { assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1)); assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1)); - assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1)); + // Set 2^100 directly instead of using powf, because it doesn't guarentee precision + assert_eq!(1.2676506e30_f32.integer_decode(), (8388608, 77, 1)); assert_eq!(0f32.integer_decode(), (0, -150, 1)); assert_eq!((-0f32).integer_decode(), (0, -150, -1)); assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1)); @@ -39,7 +40,8 @@ fn test_f32_integer_decode() { fn test_f64_integer_decode() { assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1)); assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1)); - assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1)); + // Set 2^100 directly instead of using powf, because it doesn't guarentee precision + assert_eq!(1.2676506002282294e30_f64.integer_decode(), (4503599627370496, 48, 1)); assert_eq!(0f64.integer_decode(), (0, -1075, 1)); assert_eq!((-0f64).integer_decode(), (0, -1075, -1)); assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1)); diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index b7f6529ac402..d7396a96b836 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -304,7 +304,7 @@ impl f32 { /// ``` /// let x = 2.0_f32; /// let abs_difference = (x.powi(2) - (x * x)).abs(); - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 8.0 * f32::EPSILON); /// /// assert_eq!(f32::powi(f32::NAN, 0), 1.0); /// ``` @@ -328,7 +328,7 @@ impl f32 { /// ``` /// let x = 2.0_f32; /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 8.0 * f32::EPSILON); /// /// assert_eq!(f32::powf(1.0, f32::NAN), 1.0); /// assert_eq!(f32::powf(f32::NAN, 0.0), 1.0); @@ -388,7 +388,7 @@ impl f32 { /// // ln(e) - 1 == 0 /// let abs_difference = (e.ln() - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -413,7 +413,7 @@ impl f32 { /// // 2^2 - 4 == 0 /// let abs_difference = (f.exp2() - 4.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 8.0 * f32::EPSILON); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -442,7 +442,7 @@ impl f32 { /// // ln(e) - 1 == 0 /// let abs_difference = (e.ln() - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` /// /// Non-positive values: @@ -479,7 +479,7 @@ impl f32 { /// // log5(5) - 1 == 0 /// let abs_difference = (five.log(5.0) - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` /// /// Non-positive values: @@ -512,7 +512,7 @@ impl f32 { /// // log2(2) - 1 == 0 /// let abs_difference = (two.log2() - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` /// /// Non-positive values: @@ -545,7 +545,7 @@ impl f32 { /// // log10(10) - 1 == 0 /// let abs_difference = (ten.log10() - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` /// /// Non-positive values: @@ -652,7 +652,7 @@ impl f32 { /// // sqrt(x^2 + y^2) /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -676,7 +676,7 @@ impl f32 { /// /// let abs_difference = (x.sin() - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -700,7 +700,7 @@ impl f32 { /// /// let abs_difference = (x.cos() - 1.0).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -784,7 +784,7 @@ impl f32 { /// // acos(cos(pi/4)) /// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[doc(alias = "arccos")] #[rustc_allow_incoherent_impl] @@ -884,8 +884,8 @@ impl f32 { /// let abs_difference_0 = (f.0 - x.sin()).abs(); /// let abs_difference_1 = (f.1 - x.cos()).abs(); /// - /// assert!(abs_difference_0 <= f32::EPSILON); - /// assert!(abs_difference_1 <= f32::EPSILON); + /// assert!(abs_difference_0 <= 4.0 * f32::EPSILON); + /// assert!(abs_difference_1 <= 4.0 * f32::EPSILON); /// ``` #[doc(alias = "sincos")] #[rustc_allow_incoherent_impl] @@ -1067,7 +1067,7 @@ impl f32 { /// /// let abs_difference = (f - x).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[doc(alias = "arcsinh")] #[rustc_allow_incoherent_impl] @@ -1095,7 +1095,7 @@ impl f32 { /// /// let abs_difference = (f - x).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 4.0 * f32::EPSILON); /// ``` #[doc(alias = "arccosh")] #[rustc_allow_incoherent_impl] diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index 75e35a8db335..d1d62f9275cb 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -304,7 +304,7 @@ impl f64 { /// ``` /// let x = 2.0_f64; /// let abs_difference = (x.powi(2) - (x * x)).abs(); - /// assert!(abs_difference <= f64::EPSILON); + /// assert!(abs_difference <= 8.0 * f64::EPSILON); /// /// assert_eq!(f64::powi(f64::NAN, 0), 1.0); /// ``` @@ -328,7 +328,7 @@ impl f64 { /// ``` /// let x = 2.0_f64; /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); - /// assert!(abs_difference <= f64::EPSILON); + /// assert!(abs_difference <= 8.0 * f64::EPSILON); /// /// assert_eq!(f64::powf(1.0, f64::NAN), 1.0); /// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0); diff --git a/library/std/tests/floats/f32.rs b/library/std/tests/floats/f32.rs index e54f227bb774..7144a27345b2 100644 --- a/library/std/tests/floats/f32.rs +++ b/library/std/tests/floats/f32.rs @@ -1,5 +1,10 @@ use std::f32::consts; +/// Miri adds some extra errors to float functions; make sure the tests still pass. +/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides. +/// They serve as a way to get an idea of the real precision of floating point operations on different platforms. +const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 }; + #[allow(unused_macros)] macro_rules! assert_f32_biteq { ($left : expr, $right : expr) => { @@ -17,9 +22,17 @@ fn test_powf() { let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; assert_eq!(1.0f32.powf(1.0), 1.0); - assert_approx_eq!(3.4f32.powf(4.5), 246.408218); + assert_approx_eq!( + 3.4f32.powf(4.5), + 246.408218, + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); assert_approx_eq!(2.7f32.powf(-3.2), 0.041652); - assert_approx_eq!((-3.1f32).powf(2.0), 9.61); + assert_approx_eq!( + (-3.1f32).powf(2.0), + 9.61, + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); assert_approx_eq!(5.9f32.powf(-2.0), 0.028727); assert_eq!(8.3f32.powf(0.0), 1.0); assert!(nan.powf(2.0).is_nan()); @@ -30,8 +43,12 @@ fn test_powf() { #[test] fn test_exp() { assert_eq!(1.0, 0.0f32.exp()); - assert_approx_eq!(2.718282, 1.0f32.exp()); - assert_approx_eq!(148.413162, 5.0f32.exp()); + assert_approx_eq!(2.718282, 1.0f32.exp(), APPROX_DELTA); + assert_approx_eq!( + 148.413162, + 5.0f32.exp(), + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; @@ -43,7 +60,11 @@ fn test_exp() { #[test] fn test_exp2() { - assert_eq!(32.0, 5.0f32.exp2()); + assert_approx_eq!( + 32.0, + 5.0f32.exp2(), + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); assert_eq!(1.0, 0.0f32.exp2()); let inf: f32 = f32::INFINITY; @@ -66,7 +87,11 @@ fn test_ln() { assert!((-2.3f32).ln().is_nan()); assert_eq!((-0.0f32).ln(), neg_inf); assert_eq!(0.0f32.ln(), neg_inf); - assert_approx_eq!(4.0f32.ln(), 1.386294); + assert_approx_eq!( + 4.0f32.ln(), + 1.386294, + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); } #[test] @@ -74,9 +99,9 @@ fn test_log() { let nan: f32 = f32::NAN; let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(10.0f32.log(10.0), 1.0); + assert_approx_eq!(10.0f32.log(10.0), 1.0); assert_approx_eq!(2.3f32.log(3.5), 0.664858); - assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0); + assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0); assert!(1.0f32.log(1.0).is_nan()); assert!(1.0f32.log(-13.9).is_nan()); assert!(nan.log(2.3).is_nan()); @@ -92,9 +117,17 @@ fn test_log2() { let nan: f32 = f32::NAN; let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!(10.0f32.log2(), 3.321928); + assert_approx_eq!( + 10.0f32.log2(), + 3.321928, + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); assert_approx_eq!(2.3f32.log2(), 1.201634); - assert_approx_eq!(1.0f32.exp().log2(), 1.442695); + assert_approx_eq!( + 1.0f32.exp().log2(), + 1.442695, + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); assert!(nan.log2().is_nan()); assert_eq!(inf.log2(), inf); assert!(neg_inf.log2().is_nan()); @@ -108,7 +141,7 @@ fn test_log10() { let nan: f32 = f32::NAN; let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; - assert_eq!(10.0f32.log10(), 1.0); + assert_approx_eq!(10.0f32.log10(), 1.0); assert_approx_eq!(2.3f32.log10(), 0.361728); assert_approx_eq!(1.0f32.exp().log10(), 0.434294); assert_eq!(1.0f32.log10(), 0.0); @@ -158,7 +191,11 @@ fn test_acosh() { assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32); // test for low accuracy from issue 104548 - assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh()); + assert_approx_eq!( + 60.0f32, + 60.0f32.cosh().acosh(), + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); } #[test] @@ -237,7 +274,11 @@ fn test_real_consts() { let ln_10: f32 = consts::LN_10; assert_approx_eq!(frac_pi_2, pi / 2f32); - assert_approx_eq!(frac_pi_3, pi / 3f32); + assert_approx_eq!( + frac_pi_3, + pi / 3f32, + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); assert_approx_eq!(frac_pi_4, pi / 4f32); assert_approx_eq!(frac_pi_6, pi / 6f32); assert_approx_eq!(frac_pi_8, pi / 8f32); @@ -249,5 +290,9 @@ fn test_real_consts() { assert_approx_eq!(log2_e, e.log2()); assert_approx_eq!(log10_e, e.log10()); assert_approx_eq!(ln_2, 2f32.ln()); - assert_approx_eq!(ln_10, 10f32.ln()); + assert_approx_eq!( + ln_10, + 10f32.ln(), + APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ + ); } diff --git a/library/std/tests/floats/f64.rs b/library/std/tests/floats/f64.rs index 2d8dd1cf0915..fccf20097278 100644 --- a/library/std/tests/floats/f64.rs +++ b/library/std/tests/floats/f64.rs @@ -43,7 +43,7 @@ fn test_exp() { #[test] fn test_exp2() { - assert_eq!(32.0, 5.0f64.exp2()); + assert_approx_eq!(32.0, 5.0f64.exp2()); assert_eq!(1.0, 0.0f64.exp2()); let inf: f64 = f64::INFINITY; @@ -74,9 +74,9 @@ fn test_log() { let nan: f64 = f64::NAN; let inf: f64 = f64::INFINITY; let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(10.0f64.log(10.0), 1.0); + assert_approx_eq!(10.0f64.log(10.0), 1.0); assert_approx_eq!(2.3f64.log(3.5), 0.664858); - assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0); + assert_approx_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0); assert!(1.0f64.log(1.0).is_nan()); assert!(1.0f64.log(-13.9).is_nan()); assert!(nan.log(2.3).is_nan()); @@ -108,7 +108,7 @@ fn test_log10() { let nan: f64 = f64::NAN; let inf: f64 = f64::INFINITY; let neg_inf: f64 = f64::NEG_INFINITY; - assert_eq!(10.0f64.log10(), 1.0); + assert_approx_eq!(10.0f64.log10(), 1.0); assert_approx_eq!(2.3f64.log10(), 0.361728); assert_approx_eq!(1.0f64.exp().log10(), 0.434294); assert_eq!(1.0f64.log10(), 0.0); diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index a4882a201481..9957e351ff10 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -3,17 +3,20 @@ mod atomic; mod simd; +use std::ops::Neg; + use rand::Rng; use rustc_abi::Size; -use rustc_apfloat::{Float, Round}; +use rustc_apfloat::ieee::{IeeeFloat, Semantics}; +use rustc_apfloat::{self, Float, Round}; use rustc_middle::mir; -use rustc_middle::ty::{self, FloatTy}; +use rustc_middle::ty::{self, FloatTy, ScalarInt}; use rustc_span::{Symbol, sym}; use self::atomic::EvalContextExt as _; use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count}; use self::simd::EvalContextExt as _; -use crate::math::apply_random_float_error_to_imm; +use crate::math::{IeeeExt, apply_random_float_error_ulp}; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -187,31 +190,39 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; - // Using host floats (but it's fine, these operations do not have - // guaranteed precision). - let host = f.to_host(); - let res = match intrinsic_name { - "sinf32" => host.sin(), - "cosf32" => host.cos(), - "expf32" => host.exp(), - "exp2f32" => host.exp2(), - "logf32" => host.ln(), - "log10f32" => host.log10(), - "log2f32" => host.log2(), - _ => bug!(), - }; - let res = res.to_soft(); - // Apply a relative error of 16ULP to introduce some non-determinism - // simulating imprecise implementations and optimizations. - // FIXME: temporarily disabled as it breaks std tests. - // let res = apply_random_float_error_ulp( - // this, - // res, - // 4, // log2(16) - // ); + + let res = fixed_float_value(intrinsic_name, &[f]).unwrap_or_else(||{ + // Using host floats (but it's fine, these operations do not have + // guaranteed precision). + let host = f.to_host(); + let res = match intrinsic_name { + "sinf32" => host.sin(), + "cosf32" => host.cos(), + "expf32" => host.exp(), + "exp2f32" => host.exp2(), + "logf32" => host.ln(), + "log10f32" => host.log10(), + "log2f32" => host.log2(), + _ => bug!(), + }; + let res = res.to_soft(); + + // Apply a relative error of 4ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = apply_random_float_error_ulp( + this, + res, + 2, // log2(4) + ); + + // Clamp the result to the guaranteed range of this function according to the C standard, + // if any. + clamp_float_value(intrinsic_name, res) + }); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } + #[rustfmt::skip] | "sinf64" | "cosf64" @@ -223,28 +234,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { => { let [f] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; - // Using host floats (but it's fine, these operations do not have - // guaranteed precision). - let host = f.to_host(); - let res = match intrinsic_name { - "sinf64" => host.sin(), - "cosf64" => host.cos(), - "expf64" => host.exp(), - "exp2f64" => host.exp2(), - "logf64" => host.ln(), - "log10f64" => host.log10(), - "log2f64" => host.log2(), - _ => bug!(), - }; - let res = res.to_soft(); - // Apply a relative error of 16ULP to introduce some non-determinism - // simulating imprecise implementations and optimizations. - // FIXME: temporarily disabled as it breaks std tests. - // let res = apply_random_float_error_ulp( - // this, - // res, - // 4, // log2(16) - // ); + + let res = fixed_float_value(intrinsic_name, &[f]).unwrap_or_else(||{ + // Using host floats (but it's fine, these operations do not have + // guaranteed precision). + let host = f.to_host(); + let res = match intrinsic_name { + "sinf64" => host.sin(), + "cosf64" => host.cos(), + "expf64" => host.exp(), + "exp2f64" => host.exp2(), + "logf64" => host.ln(), + "log10f64" => host.log10(), + "log2f64" => host.log2(), + _ => bug!(), + }; + let res = res.to_soft(); + + // Apply a relative error of 4ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + let res = apply_random_float_error_ulp( + this, + res, + 2, // log2(4) + ); + + // Clamp the result to the guaranteed range of this function according to the C standard, + // if any. + clamp_float_value(intrinsic_name, res) + }); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -302,43 +320,75 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "powf32" => { - // FIXME: apply random relative error but without altering behaviour of powf let [f1, f2] = check_intrinsic_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; - // Using host floats (but it's fine, this operation does not have guaranteed precision). - let res = f1.to_host().powf(f2.to_host()).to_soft(); + + let res = fixed_float_value(intrinsic_name, &[f1, f2]).unwrap_or_else(|| { + // Using host floats (but it's fine, this operation does not have guaranteed precision). + let res = f1.to_host().powf(f2.to_host()).to_soft(); + + // Apply a relative error of 4ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + apply_random_float_error_ulp( + this, res, 2, // log2(4) + ) + }); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; } "powf64" => { - // FIXME: apply random relative error but without altering behaviour of powf let [f1, f2] = check_intrinsic_arg_count(args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; - // Using host floats (but it's fine, this operation does not have guaranteed precision). - let res = f1.to_host().powf(f2.to_host()).to_soft(); + + let res = fixed_float_value(intrinsic_name, &[f1, f2]).unwrap_or_else(|| { + // Using host floats (but it's fine, this operation does not have guaranteed precision). + let res = f1.to_host().powf(f2.to_host()).to_soft(); + + // Apply a relative error of 4ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + apply_random_float_error_ulp( + this, res, 2, // log2(4) + ) + }); let res = this.adjust_nan(res, &[f1, f2]); this.write_scalar(res, dest)?; } "powif32" => { - // FIXME: apply random relative error but without altering behaviour of powi let [f, i] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let i = this.read_scalar(i)?.to_i32()?; - // Using host floats (but it's fine, this operation does not have guaranteed precision). - let res = f.to_host().powi(i).to_soft(); + + let res = fixed_powi_float_value(f, i).unwrap_or_else(|| { + // Using host floats (but it's fine, this operation does not have guaranteed precision). + let res = f.to_host().powi(i).to_soft(); + + // Apply a relative error of 4ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + apply_random_float_error_ulp( + this, res, 2, // log2(4) + ) + }); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } "powif64" => { - // FIXME: apply random relative error but without altering behaviour of powi let [f, i] = check_intrinsic_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let i = this.read_scalar(i)?.to_i32()?; - // Using host floats (but it's fine, this operation does not have guaranteed precision). - let res = f.to_host().powi(i).to_soft(); + + let res = fixed_powi_float_value(f, i).unwrap_or_else(|| { + // Using host floats (but it's fine, this operation does not have guaranteed precision). + let res = f.to_host().powi(i).to_soft(); + + // Apply a relative error of 4ULP to introduce some non-determinism + // simulating imprecise implementations and optimizations. + apply_random_float_error_ulp( + this, res, 2, // log2(4) + ) + }); let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } @@ -425,3 +475,97 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { interp_ok(EmulateItemResult::NeedsReturn) } } + +/// Applies a random ULP floating point error to `val` and returns the new value. +/// So if you want an X ULP error, `ulp_exponent` should be log2(X). +/// +/// Will fail if `val` is not a floating point number. +fn apply_random_float_error_to_imm<'tcx>( + ecx: &mut MiriInterpCx<'tcx>, + val: ImmTy<'tcx>, + ulp_exponent: u32, +) -> InterpResult<'tcx, ImmTy<'tcx>> { + let scalar = val.to_scalar_int()?; + let res: ScalarInt = match val.layout.ty.kind() { + ty::Float(FloatTy::F16) => + apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(), + ty::Float(FloatTy::F32) => + apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(), + ty::Float(FloatTy::F64) => + apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(), + ty::Float(FloatTy::F128) => + apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(), + _ => bug!("intrinsic called with non-float input type"), + }; + + interp_ok(ImmTy::from_scalar_int(res, val.layout)) +} + +/// For the intrinsics: +/// - sinf32, sinf64 +/// - cosf32, cosf64 +/// - expf32, expf64, exp2f32, exp2f64 +/// - logf32, logf64, log2f32, log2f64, log10f32, log10f64 +/// - powf32, powf64 +/// +/// Returns `Some(output)` if the `intrinsic` results in a defined fixed `output` specified in the C standard +/// (specifically, C23 annex F.10) when given `args` as arguments. Outputs that are unaffected by a relative error +/// (such as INF and zero) are not handled here, they are assumed to be handled by the underlying +/// implementation. Returns `None` if no specific value is guaranteed. +fn fixed_float_value( + intrinsic_name: &str, + args: &[IeeeFloat], +) -> Option> { + let one = IeeeFloat::::one(); + match (intrinsic_name, args) { + // cos(+- 0) = 1 + ("cosf32" | "cosf64", [input]) if input.is_zero() => Some(one), + + // e^0 = 1 + ("expf32" | "expf64" | "exp2f32" | "exp2f64", [input]) if input.is_zero() => Some(one), + + // 1^y = 1 for any y, even a NaN. + ("powf32" | "powf64", [base, _]) if *base == one => Some(one), + + // (-1)^(±INF) = 1 + ("powf32" | "powf64", [base, exp]) if *base == -one && exp.is_infinite() => Some(one), + + // FIXME(#4286): The C ecosystem is inconsistent with handling sNaN's, some return 1 others propogate + // the NaN. We should return either 1 or the NaN non-deterministically here. + // But for now, just handle them all the same. + // x^(±0) = 1 for any x, even a NaN + ("powf32" | "powf64", [_, exp]) if exp.is_zero() => Some(one), + + // There are a lot of cases for fixed outputs according to the C Standard, but these are mainly INF or zero + // which are not affected by the applied error. + _ => None, + } +} + +/// Returns `Some(output)` if `powi` (called `pown` in C) results in a fixed value specified in the C standard +/// (specifically, C23 annex F.10.4.6) when doing `base^exp`. Otherwise, returns `None`. +fn fixed_powi_float_value(base: IeeeFloat, exp: i32) -> Option> { + match (base.category(), exp) { + // x^0 = 1, if x is not a Signaling NaN + // FIXME(#4286): The C ecosystem is inconsistent with handling sNaN's, some return 1 others propogate + // the NaN. We should return either 1 or the NaN non-deterministically here. + // But for now, just handle them all the same. + (_, 0) => Some(IeeeFloat::::one()), + + _ => None, + } +} + +/// Given an floating-point operation and a floating-point value, clamps the result to the output +/// range of the given operation. +fn clamp_float_value(intrinsic_name: &str, val: IeeeFloat) -> IeeeFloat { + match intrinsic_name { + // sin and cos: [-1, 1] + "sinf32" | "cosf32" | "sinf64" | "cosf64" => + val.clamp(IeeeFloat::::one().neg(), IeeeFloat::::one()), + // exp: [0, +INF] + "expf32" | "exp2f32" | "expf64" | "exp2f64" => + IeeeFloat::::maximum(val, IeeeFloat::::ZERO), + _ => val, + } +} diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs index 2ff29c7ac1aa..d1355a216847 100644 --- a/src/tools/miri/src/math.rs +++ b/src/tools/miri/src/math.rs @@ -151,6 +151,20 @@ pub(crate) fn sqrt(x: IeeeFloat) -> IeeeFl } } +/// Extend functionality of rustc_apfloat softfloats +pub trait IeeeExt: rustc_apfloat::Float { + #[inline] + fn one() -> Self { + Self::from_u128(1).value + } + + #[inline] + fn clamp(self, min: Self, max: Self) -> Self { + self.maximum(min).minimum(max) + } +} +impl IeeeExt for IeeeFloat {} + #[cfg(test)] mod tests { use rustc_apfloat::ieee::{DoubleS, HalfS, IeeeFloat, QuadS, SingleS}; diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 98a88cfd62dc..586a52a4f81d 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -45,6 +45,31 @@ macro_rules! assert_approx_eq { }; } + +/// From IEEE 754 a Signaling NaN for single precision has the following representation: +/// ``` +/// s | 1111 1111 | 0x..x +/// ```` +/// Were at least one `x` is a 1. +/// +/// This sNaN has the following representation and is used for testing purposes.: +/// ``` +/// 0 | 1111111 | 01..0 +/// ``` +const SNAN_F32: f32 = f32::from_bits(0x7fa00000); + +/// From IEEE 754 a Signaling NaN for double precision has the following representation: +/// ``` +/// s | 1111 1111 111 | 0x..x +/// ```` +/// Were at least one `x` is a 1. +/// +/// This sNaN has the following representation and is used for testing purposes.: +/// ``` +/// 0 | 1111 1111 111 | 01..0 +/// ``` +const SNAN_F64: f64 = f64::from_bits(0x7ff4000000000000); + fn main() { basic(); casts(); @@ -1008,17 +1033,82 @@ pub fn libm() { assert_approx_eq!(25f32.powf(-2f32), 0.0016f32); assert_approx_eq!(400f64.powf(0.5f64), 20f64); + // Some inputs to powf and powi result in fixed outputs + // and thus must be exactly equal to that value + // C standard says: + // 1^y = 1 for any y, even a NaN. + assert_eq!(1f32.powf(10.0), 1.0); + assert_eq!(1f64.powf(100.0), 1.0); + assert_eq!(1f32.powf(f32::INFINITY), 1.0); + assert_eq!(1f64.powf(f64::INFINITY), 1.0); + assert_eq!(1f32.powf(f32::NAN), 1.0); + assert_eq!(1f64.powf(f64::NAN), 1.0); + + // f*::NAN is a quiet NAN and should return 1 as well. + assert_eq!(f32::NAN.powf(0.0), 1.0); + assert_eq!(f64::NAN.powf(0.0), 1.0); + + assert_eq!(42f32.powf(0.0), 1.0); + assert_eq!(42f64.powf(0.0), 1.0); + assert_eq!(f32::INFINITY.powf(0.0), 1.0); + assert_eq!(f64::INFINITY.powf(0.0), 1.0); + + // f*::NAN is a quiet NAN and should return 1 as well. + assert_eq!(f32::NAN.powi(0), 1.0); + assert_eq!(f64::NAN.powi(0), 1.0); + + assert_eq!(10.0f32.powi(0), 1.0); + assert_eq!(10.0f64.powi(0), 1.0); + assert_eq!(f32::INFINITY.powi(0), 1.0); + assert_eq!(f64::INFINITY.powi(0), 1.0); + + assert_eq!((-1f32).powf(f32::INFINITY), 1.0); + assert_eq!((-1f64).powf(f64::INFINITY), 1.0); + assert_eq!((-1f32).powf(f32::NEG_INFINITY), 1.0); + assert_eq!((-1f64).powf(f64::NEG_INFINITY), 1.0); + + // For pow (powf in rust) the C standard says: + // x^0 = 1 for all x even a sNaN + assert_eq!(SNAN_F32.powf(0.0), 1.0); + assert_eq!(SNAN_F64.powf(0.0), 1.0); + + // For pown (powi in rust) the C standard says: + // x^0 = 1 for all x even a sNaN + assert_eq!(SNAN_F32.powi(0), 1.0); + assert_eq!(SNAN_F64.powi(0), 1.0); + + assert_eq!(0f32.powi(10), 0.0); + assert_eq!(0f64.powi(100), 0.0); + assert_eq!(0f32.powi(9), 0.0); + assert_eq!(0f64.powi(99), 0.0); + + assert_biteq((-0f32).powf(10.0), 0.0, "-0^x = +0 where x is positive"); + assert_biteq((-0f64).powf(100.0), 0.0, "-0^x = +0 where x is positive"); + assert_biteq((-0f32).powf(9.0), -0.0, "-0^x = -0 where x is negative"); + assert_biteq((-0f64).powf(99.0), -0.0, "-0^x = -0 where x is negative"); + + assert_biteq((-0f32).powi(10), 0.0, "-0^x = +0 where x is positive"); + assert_biteq((-0f64).powi(100), 0.0, "-0^x = +0 where x is positive"); + assert_biteq((-0f32).powi(9), -0.0, "-0^x = -0 where x is negative"); + assert_biteq((-0f64).powi(99), -0.0, "-0^x = -0 where x is negative"); + assert_approx_eq!(1f32.exp(), f32::consts::E); assert_approx_eq!(1f64.exp(), f64::consts::E); + assert_eq!(0f32.exp(), 1.0); + assert_eq!(0f64.exp(), 1.0); assert_approx_eq!(1f32.exp_m1(), f32::consts::E - 1.0); assert_approx_eq!(1f64.exp_m1(), f64::consts::E - 1.0); assert_approx_eq!(10f32.exp2(), 1024f32); assert_approx_eq!(50f64.exp2(), 1125899906842624f64); + assert_eq!(0f32.exp2(), 1.0); + assert_eq!(0f64.exp2(), 1.0); assert_approx_eq!(f32::consts::E.ln(), 1f32); - assert_approx_eq!(1f64.ln(), 0f64); + assert_approx_eq!(f64::consts::E.ln(), 1f64); + assert_eq!(1f32.ln(), 0.0); + assert_eq!(1f64.ln(), 0.0); assert_approx_eq!(0f32.ln_1p(), 0f32); assert_approx_eq!(0f64.ln_1p(), 0f64); @@ -1047,7 +1137,8 @@ pub fn libm() { // Trigonometric functions. - assert_approx_eq!(0f32.sin(), 0f32); + assert_eq!(0f32.sin(), 0f32); + assert_eq!(0f64.sin(), 0f64); assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64); assert_approx_eq!(f32::consts::FRAC_PI_6.sin(), 0.5); assert_approx_eq!(f64::consts::FRAC_PI_6.sin(), 0.5); @@ -1059,7 +1150,23 @@ pub fn libm() { assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32); assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64); - assert_approx_eq!(0f32.cos(), 1f32); + // Ensure `sin` always returns something that is a valid input for `asin`, and same for + // `cos` and `acos`. + let halve_pi_f32 = std::f32::consts::FRAC_PI_2; + let halve_pi_f64 = std::f64::consts::FRAC_PI_2; + let pi_f32 = std::f32::consts::PI; + let pi_f64 = std::f64::consts::PI; + for _ in 0..64 { + // sin() should be clamped to [-1, 1] so asin() can never return NaN + assert!(!halve_pi_f32.sin().asin().is_nan()); + assert!(!halve_pi_f64.sin().asin().is_nan()); + // cos() should be clamped to [-1, 1] so acos() can never return NaN + assert!(!pi_f32.cos().acos().is_nan()); + assert!(!pi_f64.cos().acos().is_nan()); + } + + assert_eq!(0f32.cos(), 1f32); + assert_eq!(0f64.cos(), 1f64); assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64); assert_approx_eq!(f32::consts::FRAC_PI_3.cos(), 0.5); assert_approx_eq!(f64::consts::FRAC_PI_3.cos(), 0.5); From 32297bdf8c1c3114d6a51ca865f4b8163e580c5b Mon Sep 17 00:00:00 2001 From: David Barsky Date: Tue, 3 Jun 2025 08:11:49 -0400 Subject: [PATCH 028/183] hir-ty: add incremental tests checking for `infer` invalidation --- .../crates/hir-ty/src/tests/incremental.rs | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 48474d2d26de..e8e3812c69d3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs @@ -106,3 +106,256 @@ fn baz() -> i32 { assert_eq!(format!("{events:?}").matches("infer_shim").count(), 1, "{events:#?}") } } + +#[test] +fn adding_struct_invalidates_infer() { + let (mut db, pos) = TestDB::with_position( + " +//- /lib.rs +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} +$0", + ); + { + let events = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) + } + + let new_text = " +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} + +pub struct NewStruct { + field: i32, +} +"; + + db.set_file_text(pos.file_id.file_id(&db), new_text); + + { + let actual = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + + let expected = vec![ + "parse_shim".to_owned(), + "ast_id_map_shim".to_owned(), + "file_item_tree_shim".to_owned(), + "real_span_map_shim".to_owned(), + "crate_local_def_map".to_owned(), + "trait_impls_in_crate_shim".to_owned(), + ]; + + assert_eq!(expected, actual); + } +} + +#[test] +fn adding_enum_query_log() { + let (mut db, pos) = TestDB::with_position( + " +//- /lib.rs +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} +$0", + ); + { + let events = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) + } + + let new_text = " +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} + +pub enum SomeEnum { + A, + B +} +"; + + db.set_file_text(pos.file_id.file_id(&db), new_text); + + { + let actual = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + + let expected = vec![ + "parse_shim".to_owned(), + "ast_id_map_shim".to_owned(), + "file_item_tree_shim".to_owned(), + "real_span_map_shim".to_owned(), + "crate_local_def_map".to_owned(), + "trait_impls_in_crate_shim".to_owned(), + ]; + + assert_eq!(expected, actual); + } +} + +#[test] +fn adding_use_query_log() { + let (mut db, pos) = TestDB::with_position( + " +//- /lib.rs +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} +$0", + ); + { + let events = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) + } + + let new_text = " +use std::collections::HashMap; + +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} +"; + + db.set_file_text(pos.file_id.file_id(&db), new_text); + + { + let actual = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + + let expected = vec![ + "parse_shim".to_owned(), + "ast_id_map_shim".to_owned(), + "file_item_tree_shim".to_owned(), + "real_span_map_shim".to_owned(), + "crate_local_def_map".to_owned(), + "trait_impls_in_crate_shim".to_owned(), + ]; + + assert_eq!(expected, actual); + } +} + +#[test] +fn adding_impl_query_log() { + let (mut db, pos) = TestDB::with_position( + " +//- /lib.rs +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} + +pub struct SomeStruct { + field: i32, +} +$0", + ); + { + let events = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + assert!(format!("{events:?}").contains("trait_impls_in_crate_shim")) + } + + let new_text = " +fn foo() -> i32 { + 1 + 1 +} + +fn bar() -> f32 { + 2.0 * 3.0 +} + +pub struct SomeStruct { + field: i32, +} + +impl SomeStruct { + pub fn new(value: i32) -> Self { + Self { field: value } + } +} +"; + + db.set_file_text(pos.file_id.file_id(&db), new_text); + + { + let actual = db.log_executed(|| { + let module = db.module_for_file(pos.file_id.file_id(&db)); + let _crate_def_map = module.def_map(&db); + db.trait_impls_in_crate(module.krate()); + }); + + let expected = vec![ + "parse_shim".to_owned(), + "ast_id_map_shim".to_owned(), + "file_item_tree_shim".to_owned(), + "real_span_map_shim".to_owned(), + "crate_local_def_map".to_owned(), + "trait_impls_in_crate_shim".to_owned(), + "attrs_shim".to_owned(), + "impl_trait_with_diagnostics_shim".to_owned(), + "impl_signature_shim".to_owned(), + "impl_signature_with_source_map_shim".to_owned(), + "impl_self_ty_with_diagnostics_shim".to_owned(), + "struct_signature_shim".to_owned(), + "struct_signature_with_source_map_shim".to_owned(), + "type_for_adt_tracked".to_owned(), + ]; + + assert_eq!(expected, actual); + } +} From 80a95b745e0d156fd9fce7cb66de0377a4df2781 Mon Sep 17 00:00:00 2001 From: Nia Espera Date: Mon, 2 Jun 2025 21:49:13 +0200 Subject: [PATCH 029/183] native-lib: allow multiple libraries and/or dirs --- src/tools/miri/README.md | 6 +- src/tools/miri/src/alloc_addresses/mod.rs | 4 +- src/tools/miri/src/bin/miri.rs | 19 ++++-- src/tools/miri/src/eval.rs | 7 +-- src/tools/miri/src/machine.rs | 14 ++--- src/tools/miri/src/shims/foreign_items.rs | 2 +- src/tools/miri/src/shims/native_lib.rs | 75 ++++++++++++----------- 7 files changed, 70 insertions(+), 57 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index de521393cd0a..126a8dc47362 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -398,9 +398,11 @@ to Miri failing to detect cases of undefined behavior in a program. **unsound** since the fallback body might not be checking for all UB. * `-Zmiri-native-lib=` is an experimental flag for providing support for calling native functions from inside the interpreter via FFI. The flag is supported only on - Unix systems. Functions not provided by that file are still executed via the usual Miri shims. + Unix systems. Functions not provided by that file are still executed via the usual Miri shims. If + a path to a directory is specified, all files in that directory are included nonrecursively. This + flag can be passed multiple times to specify multiple files and/or directories. **WARNING**: If an invalid/incorrect `.so` file is specified, this can cause Undefined Behavior in - Miri itself! And of course, Miri cannot do any checks on the actions taken by the native code. + Miri itself! And of course, Miri often cannot do any checks on the actions taken by the native code. Note that Miri has its own handling of file descriptors, so if you want to replace *some* functions working on file descriptors, you will have to replace *all* of them, or the two kinds of file descriptors will be mixed up. This is **work in progress**; currently, only integer and diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 12a320b96767..4a038fe64873 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -132,7 +132,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { assert!(!matches!(info.kind, AllocKind::Dead)); // This allocation does not have a base address yet, pick or reuse one. - if this.machine.native_lib.is_some() { + if !this.machine.native_lib.is_empty() { // In native lib mode, we use the "real" address of the bytes for this allocation. // This ensures the interpreted program and native code have the same view of memory. let params = this.machine.get_default_alloc_params(); @@ -413,7 +413,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, MiriAllocBytes> { let this = self.eval_context_ref(); assert!(this.tcx.try_get_global_alloc(id).is_some()); - if this.machine.native_lib.is_some() { + if !this.machine.native_lib.is_empty() { // In native lib mode, MiriAllocBytes for global allocations are handled via `prepared_alloc_bytes`. // This additional call ensures that some `MiriAllocBytes` are always prepared, just in case // this function gets called before the first time `addr_from_alloc_id` gets called. diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 0121472d330f..f8168853d3aa 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -692,11 +692,18 @@ fn main() { }; } else if let Some(param) = arg.strip_prefix("-Zmiri-native-lib=") { let filename = param.to_string(); - if std::path::Path::new(&filename).exists() { - if let Some(other_filename) = miri_config.native_lib { - show_error!("-Zmiri-native-lib is already set to {}", other_filename.display()); + let file_path = std::path::Path::new(&filename); + if file_path.exists() { + // For directories, nonrecursively add all normal files inside + if let Ok(dir) = file_path.read_dir() { + for lib in dir.filter_map(|res| res.ok()) { + if lib.file_type().unwrap().is_file() { + miri_config.native_lib.push(lib.path().to_owned()); + } + } + } else { + miri_config.native_lib.push(filename.into()); } - miri_config.native_lib = Some(filename.into()); } else { show_error!("-Zmiri-native-lib `{}` does not exist", filename); } @@ -731,12 +738,12 @@ fn main() { "Tree Borrows does not support integer-to-pointer casts, and hence requires strict provenance" ); } - if miri_config.native_lib.is_some() { + if !miri_config.native_lib.is_empty() { show_error!("Tree Borrows is not compatible with calling native functions"); } } // Native calls and strict provenance are not compatible. - if miri_config.native_lib.is_some() && miri_config.provenance_mode == ProvenanceMode::Strict { + if !miri_config.native_lib.is_empty() && miri_config.provenance_mode == ProvenanceMode::Strict { show_error!("strict provenance is not compatible with calling native functions"); } // You can set either one seed or many. diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 8fe034d25829..1477f103ca5e 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -148,9 +148,8 @@ pub struct MiriConfig { pub report_progress: Option, /// Whether Stacked Borrows and Tree Borrows retagging should recurse into fields of datatypes. pub retag_fields: RetagFields, - /// The location of a shared object file to load when calling external functions - /// FIXME! consider allowing users to specify paths to multiple files, or to a directory - pub native_lib: Option, + /// The location of the shared object files to load when calling external functions + pub native_lib: Vec, /// Run a garbage collector for BorTags every N basic blocks. pub gc_interval: u32, /// The number of CPUs to be reported by miri. @@ -197,7 +196,7 @@ impl Default for MiriConfig { preemption_rate: 0.01, // 1% report_progress: None, retag_fields: RetagFields::Yes, - native_lib: None, + native_lib: vec![], gc_interval: 10_000, num_cpus: 1, page_size: None, diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 15b3653d7aef..b221dd850925 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -558,9 +558,9 @@ pub struct MiriMachine<'tcx> { /// Handle of the optional shared object file for native functions. #[cfg(unix)] - pub native_lib: Option<(libloading::Library, std::path::PathBuf)>, + pub native_lib: Vec<(libloading::Library, std::path::PathBuf)>, #[cfg(not(unix))] - pub native_lib: Option, + pub native_lib: Vec, /// Run a garbage collector for BorTags every N basic blocks. pub(crate) gc_interval: u32, @@ -720,7 +720,7 @@ impl<'tcx> MiriMachine<'tcx> { extern_statics: FxHashMap::default(), rng: RefCell::new(rng), #[cfg(target_os = "linux")] - allocator: if config.native_lib.is_some() { + allocator: if !config.native_lib.is_empty() { Some(Rc::new(RefCell::new(crate::alloc::isolated_alloc::IsolatedAlloc::new()))) } else { None }, tracked_alloc_ids: config.tracked_alloc_ids.clone(), @@ -732,7 +732,7 @@ impl<'tcx> MiriMachine<'tcx> { basic_block_count: 0, monotonic_clock: MonotonicClock::new(config.isolated_op == IsolatedOp::Allow), #[cfg(unix)] - native_lib: config.native_lib.as_ref().map(|lib_file_path| { + native_lib: config.native_lib.iter().map(|lib_file_path| { let host_triple = rustc_session::config::host_tuple(); let target_triple = tcx.sess.opts.target_triple.tuple(); // Check if host target == the session target. @@ -752,11 +752,11 @@ impl<'tcx> MiriMachine<'tcx> { }, lib_file_path.clone(), ) - }), + }).collect(), #[cfg(not(unix))] - native_lib: config.native_lib.as_ref().map(|_| { + native_lib: config.native_lib.iter().map(|_| { panic!("calling functions from native libraries via FFI is only supported on Unix") - }), + }).collect(), gc_interval: config.gc_interval, since_gc: 0, num_cpus: config.num_cpus, diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index b08b522d279a..81a5046b2260 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -238,7 +238,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // First deal with any external C functions in linked .so file. #[cfg(unix)] - if this.machine.native_lib.as_ref().is_some() { + if !this.machine.native_lib.is_empty() { use crate::shims::native_lib::EvalContextExt as _; // An Ok(false) here means that the function being called was not exported // by the specified `.so` file; we should continue and check if it corresponds to diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index 1e6c93333c15..40440bf6da41 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -87,47 +87,52 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Get the pointer to the function of the specified name in the shared object file, - /// if it exists. The function must be in the shared object file specified: we do *not* - /// return pointers to functions in dependencies of the library. + /// if it exists. The function must be in one of the shared object files specified: + /// we do *not* return pointers to functions in dependencies of libraries. fn get_func_ptr_explicitly_from_lib(&mut self, link_name: Symbol) -> Option { let this = self.eval_context_mut(); - // Try getting the function from the shared library. - let (lib, lib_path) = this.machine.native_lib.as_ref().unwrap(); - let func: libloading::Symbol<'_, unsafe extern "C" fn()> = - unsafe { lib.get(link_name.as_str().as_bytes()).ok()? }; - #[expect(clippy::as_conversions)] // fn-ptr to raw-ptr cast needs `as`. - let fn_ptr = *func.deref() as *mut std::ffi::c_void; + // Try getting the function from one of the shared libraries. + for (lib, lib_path) in &this.machine.native_lib { + let Ok(func): Result, _> = + (unsafe { lib.get(link_name.as_str().as_bytes()) }) + else { + continue; + }; + #[expect(clippy::as_conversions)] // fn-ptr to raw-ptr cast needs `as`. + let fn_ptr = *func.deref() as *mut std::ffi::c_void; - // FIXME: this is a hack! - // The `libloading` crate will automatically load system libraries like `libc`. - // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202 - // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the - // library if it can't find the symbol in the library itself. - // So, in order to check if the function was actually found in the specified - // `machine.external_so_lib` we need to check its `dli_fname` and compare it to - // the specified SO file path. - // This code is a reimplementation of the mechanism for getting `dli_fname` in `libloading`, - // from: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#411 - // using the `libc` crate where this interface is public. - let mut info = std::mem::MaybeUninit::::zeroed(); - unsafe { - if libc::dladdr(fn_ptr, info.as_mut_ptr()) != 0 { - let info = info.assume_init(); - #[cfg(target_os = "cygwin")] - let fname_ptr = info.dli_fname.as_ptr(); - #[cfg(not(target_os = "cygwin"))] - let fname_ptr = info.dli_fname; - assert!(!fname_ptr.is_null()); - if std::ffi::CStr::from_ptr(fname_ptr).to_str().unwrap() - != lib_path.to_str().unwrap() - { - return None; + // FIXME: this is a hack! + // The `libloading` crate will automatically load system libraries like `libc`. + // On linux `libloading` is based on `dlsym`: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#202 + // and `dlsym`(https://linux.die.net/man/3/dlsym) looks through the dependency tree of the + // library if it can't find the symbol in the library itself. + // So, in order to check if the function was actually found in the specified + // `machine.external_so_lib` we need to check its `dli_fname` and compare it to + // the specified SO file path. + // This code is a reimplementation of the mechanism for getting `dli_fname` in `libloading`, + // from: https://docs.rs/libloading/0.7.3/src/libloading/os/unix/mod.rs.html#411 + // using the `libc` crate where this interface is public. + let mut info = std::mem::MaybeUninit::::zeroed(); + unsafe { + if libc::dladdr(fn_ptr, info.as_mut_ptr()) != 0 { + let info = info.assume_init(); + #[cfg(target_os = "cygwin")] + let fname_ptr = info.dli_fname.as_ptr(); + #[cfg(not(target_os = "cygwin"))] + let fname_ptr = info.dli_fname; + assert!(!fname_ptr.is_null()); + if std::ffi::CStr::from_ptr(fname_ptr).to_str().unwrap() + != lib_path.to_str().unwrap() + { + return None; + } } } - } - // Return a pointer to the function. - Some(CodePtr(fn_ptr)) + // Return a pointer to the function. + return Some(CodePtr(fn_ptr)); + } + None } } From beff63bb98effefbc9204ff52a66a92545120786 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 4 Jun 2025 04:54:56 +0000 Subject: [PATCH 030/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 15f06b60d0f9..2bc38eebfc29 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -99426c570eebec8dcba2eaa8f5057265346aaedc +792fc2b033aea7ea7b766e38bdc40f7d6bdce8c3 From cd38deb3ca2d472ec2f174c8f1202463b37e7da8 Mon Sep 17 00:00:00 2001 From: "Shoyu Vanilla (Flint)" Date: Wed, 4 Jun 2025 13:53:27 +0900 Subject: [PATCH 031/183] ci: When autopublishing, remove `xtask` from workspace Revert `cargo-workspaces` version fix --- src/tools/rust-analyzer/.github/workflows/autopublish.yaml | 4 ++-- src/tools/rust-analyzer/.github/workflows/publish-libs.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml index d3f0499e4342..13b6078a3ed1 100644 --- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml +++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml @@ -54,8 +54,8 @@ jobs: cargo workspaces rename --from project-model project_model cargo workspaces rename --from test-fixture test_fixture cargo workspaces rename --from test-utils test_utils - # Remove library crates from the workspaces so we don't auto-publish them as well - sed -i 's/ "lib\/\*",//' ./Cargo.toml + # Remove library crates and xtask from the workspaces so we don't auto-publish them as well + sed -i 's/"xtask\\/",//; s/ "lib\/\*",//' ./Cargo.toml cargo workspaces rename ra_ap_%n find crates/rust-analyzer -type f -name '*.rs' -exec sed -i 's/rust_analyzer/ra_ap_rust_analyzer/g' {} + cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$(($RUN_NUMBER + 133)) diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml index f2c8b6365b66..93ae5675a71a 100644 --- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml +++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml @@ -22,7 +22,7 @@ jobs: run: rustup update --no-self-update stable - name: Install cargo-workspaces - run: cargo install cargo-workspaces --version "0.3.6" + run: cargo install cargo-workspaces - name: Publish Crates env: From d61d0f7977c74442ae57881db6c04ce3931d4926 Mon Sep 17 00:00:00 2001 From: "Shoyu Vanilla (Flint)" Date: Wed, 4 Jun 2025 15:07:01 +0900 Subject: [PATCH 032/183] fix: Typo mistake in autopublish workflow --- src/tools/rust-analyzer/.github/workflows/autopublish.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml index 13b6078a3ed1..788b3a3a005c 100644 --- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml +++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml @@ -55,7 +55,7 @@ jobs: cargo workspaces rename --from test-fixture test_fixture cargo workspaces rename --from test-utils test_utils # Remove library crates and xtask from the workspaces so we don't auto-publish them as well - sed -i 's/"xtask\\/",//; s/ "lib\/\*",//' ./Cargo.toml + sed -i 's|^members = .*$|members = ["crates/*"]|' Cargo.toml cargo workspaces rename ra_ap_%n find crates/rust-analyzer -type f -name '*.rs' -exec sed -i 's/rust_analyzer/ra_ap_rust_analyzer/g' {} + cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$(($RUN_NUMBER + 133)) From 4e85d77393ba1991583179563220ba9817dfc436 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Wed, 4 Jun 2025 16:03:00 +0900 Subject: [PATCH 033/183] ci: Pin `cargo-workspaces` version to `0.3.6`, again --- src/tools/rust-analyzer/.github/workflows/autopublish.yaml | 2 +- src/tools/rust-analyzer/.github/workflows/publish-libs.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml index 788b3a3a005c..6e2be7fd3da5 100644 --- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml +++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml @@ -28,7 +28,7 @@ jobs: run: rustup update --no-self-update stable - name: Install cargo-workspaces - run: cargo install cargo-workspaces + run: cargo install cargo-workspaces --version "0.3.6" - name: Publish Crates env: diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml index 93ae5675a71a..f2c8b6365b66 100644 --- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml +++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml @@ -22,7 +22,7 @@ jobs: run: rustup update --no-self-update stable - name: Install cargo-workspaces - run: cargo install cargo-workspaces + run: cargo install cargo-workspaces --version "0.3.6" - name: Publish Crates env: From c1e3da315a003e6e7ee57b73289de4201176743f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 3 Jun 2025 12:03:01 +0200 Subject: [PATCH 034/183] Remove unnecessary parameters in inlay-hint computation --- .../crates/ide/src/inlay_hints.rs | 57 +++++++++++-------- .../ide/src/inlay_hints/binding_mode.rs | 2 - .../crates/ide/src/inlay_hints/bounds.rs | 2 - .../ide/src/inlay_hints/closing_brace.rs | 15 +++-- .../ide/src/inlay_hints/discriminant.rs | 2 - .../ide/src/inlay_hints/extern_block.rs | 4 -- .../ide/src/inlay_hints/implicit_drop.rs | 5 +- .../ide/src/inlay_hints/implicit_static.rs | 2 - .../crates/ide/src/inlay_hints/lifetime.rs | 8 --- .../ide/src/inlay_hints/range_exclusive.rs | 2 - 10 files changed, 41 insertions(+), 58 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index 82704af647db..d05a36c5f4b3 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -6,7 +6,7 @@ use std::{ use either::Either; use hir::{ ClosureStyle, DisplayTarget, EditionedFileId, HasVisibility, HirDisplay, HirDisplayError, - HirWrite, ModuleDef, ModuleDefId, Semantics, sym, + HirWrite, InRealFile, ModuleDef, ModuleDefId, Semantics, sym, }; use ide_db::{FileRange, RootDatabase, famous_defs::FamousDefs, text_edit::TextEditBuilder}; use ide_db::{FxHashSet, text_edit::TextEdit}; @@ -95,16 +95,16 @@ pub(crate) fn inlay_hints( return acc; }; let famous_defs = FamousDefs(&sema, scope.krate()); + let display_target = famous_defs.1.to_display_target(sema.db); let ctx = &mut InlayHintCtx::default(); let mut hints = |event| { if let Some(node) = handle_event(ctx, event) { - hints(&mut acc, ctx, &famous_defs, config, file_id, node); + hints(&mut acc, ctx, &famous_defs, config, file_id, display_target, node); } }; let mut preorder = file.preorder(); while let Some(event) = preorder.next() { - // FIXME: This can miss some hints that require the parent of the range to calculate if matches!((&event, range_limit), (WalkEvent::Enter(node), Some(range)) if range.intersect(node.text_range()).is_none()) { preorder.skip_subtree(); @@ -144,10 +144,12 @@ pub(crate) fn inlay_hints_resolve( let famous_defs = FamousDefs(&sema, scope.krate()); let mut acc = Vec::new(); + let display_target = famous_defs.1.to_display_target(sema.db); + let ctx = &mut InlayHintCtx::default(); let mut hints = |event| { if let Some(node) = handle_event(ctx, event) { - hints(&mut acc, ctx, &famous_defs, config, file_id, node); + hints(&mut acc, ctx, &famous_defs, config, file_id, display_target, node); } }; @@ -202,17 +204,19 @@ fn handle_event(ctx: &mut InlayHintCtx, node: WalkEvent) -> Option, ctx: &mut InlayHintCtx, - famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, + famous_defs @ FamousDefs(sema, _krate): &FamousDefs<'_, '_>, config: &InlayHintsConfig, file_id: EditionedFileId, + display_target: DisplayTarget, node: SyntaxNode, ) { - let file_id = file_id.editioned_file_id(sema.db); - let Some(krate) = sema.first_crate(file_id.file_id()) else { - return; - }; - let display_target = krate.to_display_target(sema.db); - closing_brace::hints(hints, sema, config, file_id, display_target, node.clone()); + closing_brace::hints( + hints, + sema, + config, + display_target, + InRealFile { file_id, value: node.clone() }, + ); if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) { generic_param::hints(hints, famous_defs, config, any_has_generic_args); } @@ -231,18 +235,18 @@ fn hints( closure_captures::hints(hints, famous_defs, config, it.clone()); closure_ret::hints(hints, famous_defs, config, display_target, it) }, - ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, file_id, it), + ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, it), _ => Some(()), } }, ast::Pat(it) => { - binding_mode::hints(hints, famous_defs, config, file_id, &it); + binding_mode::hints(hints, famous_defs, config, &it); match it { ast::Pat::IdentPat(it) => { bind_pat::hints(hints, famous_defs, config, display_target, &it); } ast::Pat::RangePat(it) => { - range_exclusive::hints(hints, famous_defs, config, file_id, it); + range_exclusive::hints(hints, famous_defs, config, it); } _ => {} } @@ -250,30 +254,33 @@ fn hints( }, ast::Item(it) => match it { ast::Item::Fn(it) => { - implicit_drop::hints(hints, famous_defs, config, file_id, &it); + implicit_drop::hints(hints, famous_defs, config, display_target, &it); if let Some(extern_block) = &ctx.extern_block_parent { - extern_block::fn_hints(hints, famous_defs, config, file_id, &it, extern_block); + extern_block::fn_hints(hints, famous_defs, config, &it, extern_block); } - lifetime::fn_hints(hints, ctx, famous_defs, config, file_id, it) + lifetime::fn_hints(hints, ctx, famous_defs, config, it) }, ast::Item::Static(it) => { if let Some(extern_block) = &ctx.extern_block_parent { - extern_block::static_hints(hints, famous_defs, config, file_id, &it, extern_block); + extern_block::static_hints(hints, famous_defs, config, &it, extern_block); } - implicit_static::hints(hints, famous_defs, config, file_id, Either::Left(it)) + implicit_static::hints(hints, famous_defs, config, Either::Left(it)) }, - ast::Item::Const(it) => implicit_static::hints(hints, famous_defs, config, file_id, Either::Right(it)), - ast::Item::Enum(it) => discriminant::enum_hints(hints, famous_defs, config, file_id, it), - ast::Item::ExternBlock(it) => extern_block::extern_block_hints(hints, famous_defs, config, file_id, it), + ast::Item::Const(it) => implicit_static::hints(hints, famous_defs, config, Either::Right(it)), + ast::Item::Enum(it) => discriminant::enum_hints(hints, famous_defs, config, it), + ast::Item::ExternBlock(it) => extern_block::extern_block_hints(hints, famous_defs, config, it), _ => None, }, // FIXME: trait object type elisions ast::Type(ty) => match ty { - ast::Type::FnPtrType(ptr) => lifetime::fn_ptr_hints(hints, ctx, famous_defs, config, file_id, ptr), - ast::Type::PathType(path) => lifetime::fn_path_hints(hints, ctx, famous_defs, config, file_id, path), + ast::Type::FnPtrType(ptr) => lifetime::fn_ptr_hints(hints, ctx, famous_defs, config, ptr), + ast::Type::PathType(path) => { + lifetime::fn_path_hints(hints, ctx, famous_defs, config, path); + Some(()) + }, _ => Some(()), }, - ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config, file_id, it), + ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config, it), _ => Some(()), } }; diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs index d29173206889..169ab92342ba 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs @@ -8,7 +8,6 @@ use hir::Mutability; use ide_db::famous_defs::FamousDefs; use ide_db::text_edit::TextEditBuilder; -use span::EditionedFileId; use syntax::ast::{self, AstNode}; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -17,7 +16,6 @@ pub(super) fn hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, pat: &ast::Pat, ) -> Option<()> { if !config.binding_mode_hints { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs index 8ddbfaeffe87..b9a98f88be76 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bounds.rs @@ -3,7 +3,6 @@ //! Currently this renders the implied `Sized` bound. use ide_db::{FileRange, famous_defs::FamousDefs}; -use span::EditionedFileId; use syntax::ast::{self, AstNode, HasTypeBounds}; use crate::{ @@ -15,7 +14,6 @@ pub(super) fn hints( acc: &mut Vec, famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, params: ast::GenericParamList, ) -> Option<()> { if !config.sized_bound { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs index 2ec85da4a429..ca3a982760f1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/closing_brace.rs @@ -3,9 +3,8 @@ //! fn g() { //! } /* fn g */ //! ``` -use hir::{DisplayTarget, HirDisplay, Semantics}; +use hir::{DisplayTarget, HirDisplay, InRealFile, Semantics}; use ide_db::{FileRange, RootDatabase}; -use span::EditionedFileId; use syntax::{ SyntaxKind, SyntaxNode, T, ast::{self, AstNode, HasLoopBody, HasName}, @@ -21,15 +20,14 @@ pub(super) fn hints( acc: &mut Vec, sema: &Semantics<'_, RootDatabase>, config: &InlayHintsConfig, - file_id: EditionedFileId, display_target: DisplayTarget, - original_node: SyntaxNode, + InRealFile { file_id, value: node }: InRealFile, ) -> Option<()> { let min_lines = config.closing_brace_hints_min_lines?; let name = |it: ast::Name| it.syntax().text_range(); - let mut node = original_node.clone(); + let mut node = node.clone(); let mut closing_token; let (label, name_range) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) { closing_token = item_list.r_curly_token()?; @@ -44,7 +42,7 @@ pub(super) fn hints( let hint_text = match trait_ { Some(tr) => format!( "impl {} for {}", - tr.name(sema.db).display(sema.db, file_id.edition()), + tr.name(sema.db).display(sema.db, display_target.edition), ty.display_truncated(sema.db, config.max_length, display_target, )), None => format!("impl {}", ty.display_truncated(sema.db, config.max_length, display_target)), @@ -142,7 +140,8 @@ pub(super) fn hints( return None; } - let linked_location = name_range.map(|range| FileRange { file_id: file_id.into(), range }); + let linked_location = + name_range.map(|range| FileRange { file_id: file_id.file_id(sema.db), range }); acc.push(InlayHint { range: closing_token.text_range(), kind: InlayKind::ClosingBrace, @@ -151,7 +150,7 @@ pub(super) fn hints( position: InlayHintPosition::After, pad_left: true, pad_right: false, - resolve_parent: Some(original_node.text_range()), + resolve_parent: Some(node.text_range()), }); None diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs index 827a0438dd02..a2a702835a79 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/discriminant.rs @@ -7,7 +7,6 @@ use hir::Semantics; use ide_db::text_edit::TextEdit; use ide_db::{RootDatabase, famous_defs::FamousDefs}; -use span::EditionedFileId; use syntax::ast::{self, AstNode, HasName}; use crate::{ @@ -19,7 +18,6 @@ pub(super) fn enum_hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _: EditionedFileId, enum_: ast::Enum, ) -> Option<()> { if let DiscriminantHints::Never = config.discriminant_hints { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs index 20f54b2cd19d..88152bf3e388 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs @@ -1,6 +1,5 @@ //! Extern block hints use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit}; -use span::EditionedFileId; use syntax::{AstNode, SyntaxToken, ast}; use crate::{InlayHint, InlayHintsConfig}; @@ -9,7 +8,6 @@ pub(super) fn extern_block_hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, extern_block: ast::ExternBlock, ) -> Option<()> { if extern_block.unsafe_token().is_some() { @@ -36,7 +34,6 @@ pub(super) fn fn_hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, fn_: &ast::Fn, extern_block: &ast::ExternBlock, ) -> Option<()> { @@ -55,7 +52,6 @@ pub(super) fn static_hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, static_: &ast::Static, extern_block: &ast::ExternBlock, ) -> Option<()> { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs index f52e27946fff..bf4688e9d82b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implicit_drop.rs @@ -12,7 +12,6 @@ use hir::{ }; use ide_db::{FileRange, famous_defs::FamousDefs}; -use span::EditionedFileId; use syntax::{ ToSmolStr, ast::{self, AstNode}, @@ -25,7 +24,7 @@ pub(super) fn hints( acc: &mut Vec, FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, + display_target: hir::DisplayTarget, node: &ast::Fn, ) -> Option<()> { if !config.implicit_drop_hints { @@ -94,7 +93,7 @@ pub(super) fn hints( MirSpan::Unknown => continue, }; let binding = &hir.bindings[binding_idx]; - let name = binding.name.display_no_db(file_id.edition()).to_smolstr(); + let name = binding.name.display_no_db(display_target.edition).to_smolstr(); if name.starts_with(", FamousDefs(_sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, statik_or_const: Either, ) -> Option<()> { if config.lifetime_elision_hints != LifetimeElisionHints::Always { diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs index baba49a427d1..939fe0269192 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs @@ -6,7 +6,6 @@ use std::iter; use ide_db::{FxHashMap, famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty}; use itertools::Itertools; -use span::EditionedFileId; use syntax::{SmolStr, format_smolstr}; use syntax::{ SyntaxKind, SyntaxToken, @@ -23,7 +22,6 @@ pub(super) fn fn_hints( ctx: &mut InlayHintCtx, fd: &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, func: ast::Fn, ) -> Option<()> { if config.lifetime_elision_hints == LifetimeElisionHints::Never { @@ -40,7 +38,6 @@ pub(super) fn fn_hints( ctx, fd, config, - file_id, param_list.params().filter_map(|it| { Some(( it.pat().and_then(|it| match it { @@ -74,7 +71,6 @@ pub(super) fn fn_ptr_hints( ctx: &mut InlayHintCtx, fd: &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, func: ast::FnPtrType, ) -> Option<()> { if config.lifetime_elision_hints == LifetimeElisionHints::Never { @@ -97,7 +93,6 @@ pub(super) fn fn_ptr_hints( ctx, fd, config, - file_id, param_list.params().filter_map(|it| { Some(( it.pat().and_then(|it| match it { @@ -140,7 +135,6 @@ pub(super) fn fn_path_hints( ctx: &mut InlayHintCtx, fd: &FamousDefs<'_, '_>, config: &InlayHintsConfig, - file_id: EditionedFileId, func: ast::PathType, ) -> Option<()> { if config.lifetime_elision_hints == LifetimeElisionHints::Never { @@ -163,7 +157,6 @@ pub(super) fn fn_path_hints( ctx, fd, config, - file_id, param_list.type_args().filter_map(|it| Some((None, it.ty()?))), generic_param_list, ret_type, @@ -202,7 +195,6 @@ fn hints_( ctx: &mut InlayHintCtx, FamousDefs(_, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, params: impl Iterator, ast::Type)>, generic_param_list: Option, ret_type: Option, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs index d67d84588402..47bd6d737f82 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/range_exclusive.rs @@ -4,7 +4,6 @@ //! if let ../* < */100 = 50 {} //! ``` use ide_db::famous_defs::FamousDefs; -use span::EditionedFileId; use syntax::{SyntaxToken, T, ast}; use crate::{InlayHint, InlayHintsConfig}; @@ -13,7 +12,6 @@ pub(super) fn hints( acc: &mut Vec, FamousDefs(_sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - _file_id: EditionedFileId, range: impl ast::RangeItem, ) -> Option<()> { (config.range_exclusive_hints && range.end().is_some()) From 25cef03fdfe7b1943ca1b992954d3c32accc7769 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 4 Jun 2025 11:30:43 +0200 Subject: [PATCH 035/183] Give path segment type anchors their own grammar rule --- .../macro_expansion_tests/mbe/regression.rs | 11 ++-- .../crates/parser/src/grammar/paths.rs | 5 +- .../parser/src/syntax_kind/generated.rs | 2 + .../inline/err/angled_path_without_qual.rast | 42 ++++++------ .../test_data/parser/inline/ok/call_expr.rast | 46 ++++++------- .../parser/inline/ok/qual_paths.rast | 62 ++++++++--------- .../inline/ok/type_path_in_pattern.rast | 9 +-- .../parser/inline/ok/where_clause.rast | 31 ++++----- .../parser/ok/0036_fully_qualified.rast | 31 ++++----- .../parser/ok/0042_ufcs_call_list.rast | 15 +++-- .../parser/ok/0067_where_for_pred.rast | 31 ++++----- .../rust-analyzer/crates/syntax/rust.ungram | 7 +- .../crates/syntax/src/ast/generated/nodes.rs | 66 ++++++++++++++++--- .../crates/syntax/src/ast/node_ext.rs | 23 +++---- 14 files changed, 223 insertions(+), 158 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs index cb4fcd887d8a..2cc3ca8c7523 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs @@ -931,11 +931,12 @@ pub fn new() { // PATH_TYPE@23..26 // PATH@23..26 // PATH_SEGMENT@23..26 -// L_ANGLE@23..24 "<" -// PAREN_TYPE@24..26 -// L_PAREN@24..25 "(" -// ERROR@25..26 -// INT_NUMBER@25..26 "8" +// TYPE_ANCHOR@23..26 +// L_ANGLE@23..24 "<" +// PAREN_TYPE@24..26 +// L_PAREN@24..25 "(" +// ERROR@25..26 +// INT_NUMBER@25..26 "8" // PLUS@26..27 "+" // CONST_ARG@27..28 // LITERAL@27..28 diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs index 770827c6b0d4..e628bcc05679 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs @@ -89,7 +89,9 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option::Output; // fn foo() { ::default(); } - if first && p.eat(T![<]) { + if first && p.at(T![<]) { + let m = p.start(); + p.bump(T![<]); // test_err angled_path_without_qual // type X = <()>; // type Y = ; @@ -102,6 +104,7 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option]); + m.complete(p, TYPE_ANCHOR); if !p.at(T![::]) { p.error("expected `::`"); } diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index b1727509b137..f534546ea07e 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -291,6 +291,7 @@ pub enum SyntaxKind { TUPLE_STRUCT_PAT, TUPLE_TYPE, TYPE_ALIAS, + TYPE_ANCHOR, TYPE_ARG, TYPE_BOUND, TYPE_BOUND_LIST, @@ -463,6 +464,7 @@ impl SyntaxKind { | TUPLE_STRUCT_PAT | TUPLE_TYPE | TYPE_ALIAS + | TYPE_ANCHOR | TYPE_ARG | TYPE_BOUND | TYPE_BOUND_LIST diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast index 0529e9750e7f..53fbe0b615e0 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/angled_path_without_qual.rast @@ -10,11 +10,12 @@ SOURCE_FILE PATH_TYPE PATH PATH_SEGMENT - L_ANGLE "<" - TUPLE_TYPE - L_PAREN "(" - R_PAREN ")" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + TUPLE_TYPE + L_PAREN "(" + R_PAREN ")" + R_ANGLE ">" SEMICOLON ";" WHITESPACE "\n" TYPE_ALIAS @@ -28,21 +29,22 @@ SOURCE_FILE PATH_TYPE PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "A" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "B" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "A" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "B" + R_ANGLE ">" SEMICOLON ";" WHITESPACE "\n" error 13: expected `::` diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast index 19cc8d5ac7cf..7c1d894f7e4c 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/call_expr.rast @@ -88,13 +88,14 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Foo" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Foo" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF @@ -119,21 +120,22 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Foo" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Trait" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Foo" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Trait" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast index 8c66cfe599f2..10f8a6a75165 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/qual_paths.rast @@ -11,21 +11,22 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "A" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "B" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "A" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "B" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF @@ -51,21 +52,22 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "usize" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Default" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "usize" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Default" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast index 297f7575ca6e..3d27afa5ecd7 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_path_in_pattern.rast @@ -19,10 +19,11 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - INFER_TYPE - UNDERSCORE "_" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + INFER_TYPE + UNDERSCORE "_" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast index a3cbe457e1ac..9adfe2caa732 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/where_clause.rast @@ -84,21 +84,22 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "T" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Iterator" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Iterator" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast index 9382020e2f60..2fecb1cc47d8 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0036_fully_qualified.rast @@ -45,21 +45,22 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "S" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Iterator" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "S" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Iterator" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast index a536b0e881f0..d1d1ffacf0d3 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast @@ -107,13 +107,14 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Foo" - R_ANGLE ">" + TYPE_ANCHOR + L_ANGLE "<" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Foo" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast index cd3b21ae94fd..8bf1090f9cfc 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0067_where_for_pred.rast @@ -288,26 +288,27 @@ SOURCE_FILE PATH PATH PATH_SEGMENT - L_ANGLE "<" - REF_TYPE - AMP "&" - LIFETIME - LIFETIME_IDENT "'a" + TYPE_ANCHOR + L_ANGLE "<" + REF_TYPE + AMP "&" + LIFETIME + LIFETIME_IDENT "'a" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + WHITESPACE " " + AS_KW "as" WHITESPACE " " PATH_TYPE PATH PATH_SEGMENT NAME_REF - IDENT "T" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Baz" - R_ANGLE ">" + IDENT "Baz" + R_ANGLE ">" COLON2 "::" PATH_SEGMENT NAME_REF diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 10abca7d35d9..c81da06682ee 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -39,7 +39,10 @@ PathSegment = | NameRef GenericArgList? | NameRef ParenthesizedArgList RetType? | NameRef ReturnTypeSyntax -| '<' Type ('as' PathType)? '>' +| TypeAnchor + +TypeAnchor = + '<' Type ('as' PathType)? '>' ReturnTypeSyntax = '(' '..' ')' @@ -98,7 +101,7 @@ WhereClause = 'where' predicates:(WherePred (',' WherePred)* ','?) WherePred = - ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList? + ('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList? //*************************// diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index cd9f4dba8908..04c7e8a578c5 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -1232,21 +1232,13 @@ impl PathSegment { support::child(&self.syntax) } #[inline] - pub fn path_type(&self) -> Option { support::child(&self.syntax) } - #[inline] pub fn ret_type(&self) -> Option { support::child(&self.syntax) } #[inline] pub fn return_type_syntax(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn ty(&self) -> Option { support::child(&self.syntax) } + pub fn type_anchor(&self) -> Option { support::child(&self.syntax) } #[inline] pub fn coloncolon_token(&self) -> Option { support::token(&self.syntax, T![::]) } - #[inline] - pub fn l_angle_token(&self) -> Option { support::token(&self.syntax, T![<]) } - #[inline] - pub fn r_angle_token(&self) -> Option { support::token(&self.syntax, T![>]) } - #[inline] - pub fn as_token(&self) -> Option { support::token(&self.syntax, T![as]) } } pub struct PathType { pub(crate) syntax: SyntaxNode, @@ -1739,6 +1731,21 @@ impl TypeAlias { #[inline] pub fn type_token(&self) -> Option { support::token(&self.syntax, T![type]) } } +pub struct TypeAnchor { + pub(crate) syntax: SyntaxNode, +} +impl TypeAnchor { + #[inline] + pub fn path_type(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn ty(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn l_angle_token(&self) -> Option { support::token(&self.syntax, T![<]) } + #[inline] + pub fn r_angle_token(&self) -> Option { support::token(&self.syntax, T![>]) } + #[inline] + pub fn as_token(&self) -> Option { support::token(&self.syntax, T![as]) } +} pub struct TypeArg { pub(crate) syntax: SyntaxNode, } @@ -7108,6 +7115,42 @@ impl fmt::Debug for TypeAlias { f.debug_struct("TypeAlias").field("syntax", &self.syntax).finish() } } +impl AstNode for TypeAnchor { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TYPE_ANCHOR + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ANCHOR } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for TypeAnchor { + fn hash(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for TypeAnchor {} +impl PartialEq for TypeAnchor { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for TypeAnchor { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for TypeAnchor { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TypeAnchor").field("syntax", &self.syntax).finish() + } +} impl AstNode for TypeArg { #[inline] fn kind() -> SyntaxKind @@ -10624,6 +10667,11 @@ impl std::fmt::Display for TypeAlias { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for TypeAnchor { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for TypeArg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index b9ccd34cff06..dcf853427e53 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -276,18 +276,15 @@ impl ast::PathSegment { _ => PathSegmentKind::Name(name_ref), } } else { - match self.syntax().first_child_or_token()?.kind() { - T![<] => { - // or - // T is any TypeRef, Trait has to be a PathType - let mut type_refs = - self.syntax().children().filter(|node| ast::Type::can_cast(node.kind())); - let type_ref = type_refs.next().and_then(ast::Type::cast); - let trait_ref = type_refs.next().and_then(ast::PathType::cast); - PathSegmentKind::Type { type_ref, trait_ref } - } - _ => return None, - } + let anchor = self.type_anchor()?; + // FIXME: Move this over to `ast::TypeAnchor` + // or + // T is any TypeRef, Trait has to be a PathType + let mut type_refs = + anchor.syntax().children().filter(|node| ast::Type::can_cast(node.kind())); + let type_ref = type_refs.next().and_then(ast::Type::cast); + let trait_ref = type_refs.next().and_then(ast::PathType::cast); + PathSegmentKind::Type { type_ref, trait_ref } }; Some(res) } @@ -473,7 +470,7 @@ impl ast::Impl { // [#15778](https://github.com/rust-lang/rust-analyzer/issues/15778) impl ast::PathSegment { pub fn qualifying_trait(&self) -> Option { - let mut path_types = support::children(self.syntax()); + let mut path_types = support::children(self.type_anchor()?.syntax()); let first = path_types.next()?; path_types.next().or(Some(first)) } From efa88e52506264c3744a08c841b7a0d8f85b5a11 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 4 Jun 2025 11:30:43 +0200 Subject: [PATCH 036/183] feat: Add `dyn` keyword inlay hints --- .../crates/ide/src/inlay_hints.rs | 9 +- .../ide/src/inlay_hints/implied_dyn_trait.rs | 133 ++++++++++++++++++ .../crates/ide/src/inlay_hints/lifetime.rs | 2 +- 3 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs index d05a36c5f4b3..b094b098462f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs @@ -34,6 +34,7 @@ mod extern_block; mod generic_param; mod implicit_drop; mod implicit_static; +mod implied_dyn_trait; mod lifetime; mod param_name; mod range_exclusive; @@ -275,7 +276,12 @@ fn hints( ast::Type(ty) => match ty { ast::Type::FnPtrType(ptr) => lifetime::fn_ptr_hints(hints, ctx, famous_defs, config, ptr), ast::Type::PathType(path) => { - lifetime::fn_path_hints(hints, ctx, famous_defs, config, path); + lifetime::fn_path_hints(hints, ctx, famous_defs, config, &path); + implied_dyn_trait::hints(hints, famous_defs, config, Either::Left(path)); + Some(()) + }, + ast::Type::DynTraitType(dyn_) => { + implied_dyn_trait::hints(hints, famous_defs, config, Either::Right(dyn_)); Some(()) }, _ => Some(()), @@ -445,6 +451,7 @@ pub enum InlayKind { Parameter, GenericParameter, Type, + Dyn, Drop, RangeExclusive, ExternUnsafety, diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs new file mode 100644 index 000000000000..32d130503a47 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/implied_dyn_trait.rs @@ -0,0 +1,133 @@ +//! Implementation of trait bound hints. +//! +//! Currently this renders the implied `Sized` bound. +use either::Either; +use ide_db::{famous_defs::FamousDefs, text_edit::TextEdit}; + +use syntax::ast::{self, AstNode}; + +use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; + +pub(super) fn hints( + acc: &mut Vec, + FamousDefs(sema, _): &FamousDefs<'_, '_>, + config: &InlayHintsConfig, + path: Either, +) -> Option<()> { + let parent = path.syntax().parent()?; + let range = match path { + Either::Left(path) => { + let paren = + parent.ancestors().take_while(|it| ast::ParenType::can_cast(it.kind())).last(); + let parent = paren.as_ref().and_then(|it| it.parent()).unwrap_or(parent); + if ast::TypeBound::can_cast(parent.kind()) + || ast::TypeAnchor::can_cast(parent.kind()) + || ast::Impl::cast(parent) + .and_then(|it| it.trait_()) + .is_some_and(|it| it.syntax() == path.syntax()) + { + return None; + } + sema.resolve_trait(&path.path()?)?; + paren.map_or_else(|| path.syntax().text_range(), |it| it.text_range()) + } + Either::Right(dyn_) => { + if dyn_.dyn_token().is_some() { + return None; + } + + dyn_.syntax().text_range() + } + }; + + acc.push(InlayHint { + range, + kind: InlayKind::Dyn, + label: InlayHintLabel::simple("dyn", None, None), + text_edit: Some( + config.lazy_text_edit(|| TextEdit::insert(range.start(), "dyn ".to_owned())), + ), + position: InlayHintPosition::Before, + pad_left: false, + pad_right: true, + resolve_parent: Some(range), + }); + + Some(()) +} + +#[cfg(test)] +mod tests { + + use expect_test::expect; + + use crate::inlay_hints::InlayHintsConfig; + + use crate::inlay_hints::tests::{DISABLED_CONFIG, check_edit, check_with_config}; + + #[track_caller] + fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) { + check_with_config(InlayHintsConfig { sized_bound: true, ..DISABLED_CONFIG }, ra_fixture); + } + + #[test] + fn path_works() { + check( + r#" +struct S {} +trait T {} +fn foo(_: T, _: dyn T, _: S) {} + // ^ dyn +fn foo(_: &T, _: for<'a> T) {} + // ^ dyn + // ^ dyn +impl T {} + // ^ dyn +impl T for (T) {} + // ^^^ dyn +"#, + ); + } + + #[test] + fn missing_dyn_bounds() { + check( + r#" +trait T {} +fn foo( + _: T + T, + // ^^^^^ dyn + _: T + 'a, + // ^^^^^^ dyn + _: 'a + T, + // ^^^^^^ dyn + _: &(T + T) + // ^^^^^ dyn + _: &mut (T + T) + // ^^^^^ dyn + _: *mut (T), + // ^^^ dyn +) {} +"#, + ); + } + + #[test] + fn edit() { + check_edit( + DISABLED_CONFIG, + r#" +trait T {} +fn foo( + _: &mut T +) {} +"#, + expect![[r#" + trait T {} + fn foo( + _: &mut dyn T + ) {} + "#]], + ); + } +} diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs index 939fe0269192..0069452e7b90 100644 --- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs +++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs @@ -135,7 +135,7 @@ pub(super) fn fn_path_hints( ctx: &mut InlayHintCtx, fd: &FamousDefs<'_, '_>, config: &InlayHintsConfig, - func: ast::PathType, + func: &ast::PathType, ) -> Option<()> { if config.lifetime_elision_hints == LifetimeElisionHints::Never { return None; From 13d71f7e05c46e4c4321d0e8c946759595f7d4de Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 2 Jun 2025 15:55:08 +0200 Subject: [PATCH 037/183] refactor: Cleanup descension stuff --- .../rust-analyzer/crates/hir/src/semantics.rs | 78 +++++++++++-------- .../crates/hir/src/semantics/source_to_def.rs | 1 + 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 587e1013b9ee..ee83d10c0e9b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -892,7 +892,7 @@ impl<'db> SemanticsImpl<'db> { if first == last { // node is just the token, so descend the token - self.descend_into_macros_impl( + self.descend_into_macros_all( InFile::new(file.file_id, first), false, &mut |InFile { value, .. }, _ctx| { @@ -903,23 +903,19 @@ impl<'db> SemanticsImpl<'db> { { res.push(node) } - CONTINUE_NO_BREAKS }, ); } else { // Descend first and last token, then zip them to look for the node they belong to let mut scratch: SmallVec<[_; 1]> = smallvec![]; - self.descend_into_macros_impl( + self.descend_into_macros_all( InFile::new(file.file_id, first), false, - &mut |token, _ctx| { - scratch.push(token); - CONTINUE_NO_BREAKS - }, + &mut |token, _ctx| scratch.push(token), ); let mut scratch = scratch.into_iter(); - self.descend_into_macros_impl( + self.descend_into_macros_all( InFile::new(file.file_id, last), false, &mut |InFile { value: last, file_id: last_fid }, _ctx| { @@ -938,17 +934,18 @@ impl<'db> SemanticsImpl<'db> { } } } - CONTINUE_NO_BREAKS }, ); } res } - pub fn is_inside_macro_call(&self, token: InFile<&SyntaxToken>) -> bool { - // FIXME: Maybe `ancestors_with_macros()` is more suitable here? Currently - // this is only used on real (not macro) files so this is not a problem. - token.value.parent_ancestors().any(|ancestor| { + /// Returns true if the given input is within a macro call. + /// + /// Note that if this token itself is within the context of a macro expansion does not matter. + /// That is, we strictly check if it lies inside the input of a macro call. + pub fn is_inside_macro_call(&self, token @ InFile { value, .. }: InFile<&SyntaxToken>) -> bool { + value.parent_ancestors().any(|ancestor| { if ast::MacroCall::can_cast(ancestor.kind()) { return true; } @@ -983,21 +980,17 @@ impl<'db> SemanticsImpl<'db> { token: SyntaxToken, mut cb: impl FnMut(InFile, SyntaxContext), ) { - self.descend_into_macros_impl(self.wrap_token_infile(token), false, &mut |t, ctx| { - cb(t, ctx); - CONTINUE_NO_BREAKS + self.descend_into_macros_all(self.wrap_token_infile(token), false, &mut |t, ctx| { + cb(t, ctx) }); } pub fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> { let mut res = smallvec![]; - self.descend_into_macros_impl( + self.descend_into_macros_all( self.wrap_token_infile(token.clone()), false, - &mut |t, _ctx| { - res.push(t.value); - CONTINUE_NO_BREAKS - }, + &mut |t, _ctx| res.push(t.value), ); if res.is_empty() { res.push(token); @@ -1011,12 +1004,11 @@ impl<'db> SemanticsImpl<'db> { ) -> SmallVec<[InFile; 1]> { let mut res = smallvec![]; let token = self.wrap_token_infile(token); - self.descend_into_macros_impl(token.clone(), true, &mut |t, ctx| { + self.descend_into_macros_all(token.clone(), true, &mut |t, ctx| { if !ctx.is_opaque(self.db) { // Don't descend into opaque contexts res.push(t); } - CONTINUE_NO_BREAKS }); if res.is_empty() { res.push(token); @@ -1099,6 +1091,18 @@ impl<'db> SemanticsImpl<'db> { .unwrap_or(token) } + fn descend_into_macros_all( + &self, + token: InFile, + always_descend_into_derives: bool, + f: &mut dyn FnMut(InFile, SyntaxContext), + ) { + self.descend_into_macros_impl(token, always_descend_into_derives, &mut |tok, ctx| { + f(tok, ctx); + CONTINUE_NO_BREAKS + }); + } + fn descend_into_macros_impl( &self, InFile { value: token, file_id }: InFile, @@ -1467,25 +1471,31 @@ impl<'db> SemanticsImpl<'db> { } /// Iterates the ancestors of the given node, climbing up macro expansions while doing so. + // FIXME: Replace with `ancestors_with_macros_file` when all usages are updated. pub fn ancestors_with_macros( &self, node: SyntaxNode, ) -> impl Iterator + Clone + '_ { let node = self.find_file(&node); - iter::successors(Some(node.cloned()), move |&InFile { file_id, ref value }| { - match value.parent() { - Some(parent) => Some(InFile::new(file_id, parent)), - None => { - let macro_file = file_id.macro_file()?; + self.ancestors_with_macros_file(node.cloned()).map(|it| it.value) + } - self.with_ctx(|ctx| { - let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file); - expansion_info.arg().map(|node| node?.parent()).transpose() - }) - } + /// Iterates the ancestors of the given node, climbing up macro expansions while doing so. + pub fn ancestors_with_macros_file( + &self, + node: InFile, + ) -> impl Iterator> + Clone + '_ { + iter::successors(Some(node), move |&InFile { file_id, ref value }| match value.parent() { + Some(parent) => Some(InFile::new(file_id, parent)), + None => { + let macro_file = file_id.macro_file()?; + + self.with_ctx(|ctx| { + let expansion_info = ctx.cache.get_or_insert_expansion(ctx.db, macro_file); + expansion_info.arg().map(|node| node?.parent()).transpose() + }) } }) - .map(|it| it.value) } pub fn ancestors_at_offset_with_macros( diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 7dac01a26890..b5537d0bff05 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -411,6 +411,7 @@ impl SourceToDefCtx<'_, '_> { .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids)) } + // FIXME: Make this more fine grained! This should be a `adt_has_derives`! pub(super) fn file_of_adt_has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool { self.dyn_map(adt).as_ref().is_some_and(|map| !map[keys::DERIVE_MACRO_CALL].is_empty()) } From c5355a19bd40a24533755da057046877bb2e3236 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Wed, 4 Jun 2025 08:30:27 -0400 Subject: [PATCH 038/183] match on segments of path and some small cleanup --- .../src/completions/attribute.rs | 31 +++++++------------ .../src/completions/attribute/diagnostic.rs | 6 ++-- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs index f696f0c0b951..0ca90fae4ed4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs @@ -42,31 +42,21 @@ pub(crate) fn complete_known_attribute_input( ) -> Option<()> { let attribute = fake_attribute_under_caret; let path = attribute.path()?; - let name_ref = path.segment()?.name_ref(); - let (name_ref, tt) = name_ref.zip(attribute.token_tree())?; - tt.l_paren_token()?; + let segments = path.segments().map(|s| s.name_ref()).collect::>>()?; + let segments = segments.iter().map(|n| n.text()).collect::>(); + let segments = segments.iter().map(|t| t.as_str()).collect::>(); + let tt = attribute.token_tree()?; - if let Some(qualifier) = path.qualifier() { - let qualifier_name_ref = qualifier.as_single_name_ref()?; - match (qualifier_name_ref.text().as_str(), name_ref.text().as_str()) { - ("diagnostic", "on_unimplemented") => { - diagnostic::complete_on_unimplemented(acc, ctx, tt) - } - _ => (), - } - return Some(()); - } - - match name_ref.text().as_str() { - "repr" => repr::complete_repr(acc, ctx, tt), - "feature" => lint::complete_lint( + match segments.as_slice() { + ["repr"] => repr::complete_repr(acc, ctx, tt), + ["feature"] => lint::complete_lint( acc, ctx, colon_prefix, &parse_tt_as_comma_sep_paths(tt, ctx.edition)?, FEATURES, ), - "allow" | "expect" | "deny" | "forbid" | "warn" => { + ["allow"] | ["expect"] | ["deny"] | ["forbid"] | ["warn"] => { let existing_lints = parse_tt_as_comma_sep_paths(tt, ctx.edition)?; let lints: Vec = CLIPPY_LINT_GROUPS @@ -80,13 +70,14 @@ pub(crate) fn complete_known_attribute_input( lint::complete_lint(acc, ctx, colon_prefix, &existing_lints, &lints); } - "cfg" => cfg::complete_cfg(acc, ctx), - "macro_use" => macro_use::complete_macro_use( + ["cfg"] => cfg::complete_cfg(acc, ctx), + ["macro_use"] => macro_use::complete_macro_use( acc, ctx, extern_crate, &parse_tt_as_comma_sep_paths(tt, ctx.edition)?, ), + ["diagnostic", "on_unimplemented"] => diagnostic::complete_on_unimplemented(acc, ctx, tt), _ => (), } Some(()) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs index 10c5135b4b57..8adc97423909 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/diagnostic.rs @@ -1,7 +1,7 @@ //! Completion for diagnostic attributes. use ide_db::SymbolKind; -use syntax::ast::{self}; +use syntax::ast; use crate::{CompletionItem, Completions, context::CompletionContext}; @@ -13,7 +13,7 @@ pub(super) fn complete_on_unimplemented( input: ast::TokenTree, ) { if let Some(existing_keys) = super::parse_comma_sep_expr(input) { - for attr in ATTRIBUTES { + for attr in ATTRIBUTE_ARGS { let already_annotated = existing_keys .iter() .filter_map(|expr| match expr { @@ -53,7 +53,7 @@ pub(super) fn complete_on_unimplemented( } } -const ATTRIBUTES: &[AttrCompletion] = &[ +const ATTRIBUTE_ARGS: &[AttrCompletion] = &[ super::attr(r#"label = "…""#, Some("label"), Some(r#"label = "${0:label}""#)), super::attr(r#"message = "…""#, Some("message"), Some(r#"message = "${0:message}""#)), super::attr(r#"note = "…""#, Some("note"), Some(r#"note = "${0:note}""#)), From 53ef69e3eb9565aeb5134815e83beab8e044e424 Mon Sep 17 00:00:00 2001 From: Ryan Mehri Date: Wed, 4 Jun 2025 11:02:48 -0400 Subject: [PATCH 039/183] add qualifiers to attribute completions --- .../src/completions/attribute.rs | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs index 0ca90fae4ed4..705402c785a2 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs @@ -152,17 +152,22 @@ pub(crate) fn complete_attribute_path( }); let add_completion = |attr_completion: &AttrCompletion| { - // if we already have the qualifier of the completion, then trim it from the label and the snippet - let mut label = attr_completion.label; - let mut snippet = attr_completion.snippet; - if let Some(name_ref) = qualifier_path.and_then(|q| q.as_single_name_ref()) { - if let Some((label_qual, label_seg)) = attr_completion.label.split_once("::") { - if name_ref.text() == label_qual { - label = label_seg; - snippet = snippet.map(|snippet| { - snippet.trim_start_matches(label_qual).trim_start_matches("::") - }); - } + // if we don't already have the qualifiers of the completion, then + // add the missing parts to the label and snippet + let mut label = attr_completion.label.to_owned(); + let mut snippet = attr_completion.snippet.map(|s| s.to_owned()); + let segments = qualifier_path.iter().flat_map(|q| q.segments()).collect::>(); + let qualifiers = attr_completion.qualifiers; + let matching_qualifiers = segments + .iter() + .zip(qualifiers) + .take_while(|(s, q)| s.name_ref().is_some_and(|t| t.text() == **q)) + .count(); + if matching_qualifiers != qualifiers.len() { + let prefix = qualifiers[matching_qualifiers..].join("::"); + label = format!("{prefix}::{label}"); + if let Some(s) = snippet.as_mut() { + *s = format!("{prefix}::{s}"); } } @@ -197,6 +202,7 @@ struct AttrCompletion { label: &'static str, lookup: Option<&'static str>, snippet: Option<&'static str>, + qualifiers: &'static [&'static str], prefer_inner: bool, } @@ -205,6 +211,10 @@ impl AttrCompletion { self.lookup.unwrap_or(self.label) } + const fn qualifiers(self, qualifiers: &'static [&'static str]) -> AttrCompletion { + AttrCompletion { qualifiers, ..self } + } + const fn prefer_inner(self) -> AttrCompletion { AttrCompletion { prefer_inner: true, ..self } } @@ -215,7 +225,7 @@ const fn attr( lookup: Option<&'static str>, snippet: Option<&'static str>, ) -> AttrCompletion { - AttrCompletion { label, lookup, snippet, prefer_inner: false } + AttrCompletion { label, lookup, snippet, qualifiers: &[], prefer_inner: false } } macro_rules! attrs { @@ -324,8 +334,14 @@ const ATTRIBUTES: &[AttrCompletion] = &[ attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), attr(r#"deprecated"#, Some("deprecated"), Some(r#"deprecated"#)), attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), - attr("diagnostic::do_not_recommend", None, None), - attr("diagnostic::on_unimplemented", None, Some(r#"diagnostic::on_unimplemented(${0:keys})"#)), + attr("do_not_recommend", Some("diagnostic::do_not_recommend"), None) + .qualifiers(&["diagnostic"]), + attr( + "on_unimplemented", + Some("diagnostic::on_unimplemented"), + Some(r#"on_unimplemented(${0:keys})"#), + ) + .qualifiers(&["diagnostic"]), attr(r#"doc = "…""#, Some("doc"), Some(r#"doc = "${0:docs}""#)), attr(r#"doc(alias = "…")"#, Some("docalias"), Some(r#"doc(alias = "${0:docs}")"#)), attr(r#"doc(hidden)"#, Some("dochidden"), Some(r#"doc(hidden)"#)), From 27f8efbae2bf906ea6f967dd3fe1eb0e7faf3a2e Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Wed, 4 Jun 2025 20:10:50 +0800 Subject: [PATCH 040/183] Bump object --- Cargo.lock | 46 ++++++++++++++++---------- compiler/rustc_codegen_llvm/Cargo.toml | 2 +- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_target/Cargo.toml | 2 +- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43f5f40925b6..d59c7b9cc895 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,7 +162,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4" dependencies = [ - "object", + "object 0.36.7", ] [[package]] @@ -235,7 +235,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.36.7", "rustc-demangle", "windows-targets 0.52.6", ] @@ -2509,7 +2509,19 @@ dependencies = [ "indexmap", "memchr", "ruzstd", - "wasmparser 0.222.1", +] + +[[package]] +name = "object" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6273adb7096cf9ab4335f258e627d8230e69d40d45567d678f552dcec6245215" +dependencies = [ + "crc32fast", + "hashbrown", + "indexmap", + "memchr", + "wasmparser 0.232.0", ] [[package]] @@ -3109,7 +3121,7 @@ dependencies = [ "build_helper", "gimli", "libc", - "object", + "object 0.36.7", "regex", "serde_json", "similar", @@ -3422,7 +3434,7 @@ dependencies = [ "itertools", "libc", "measureme", - "object", + "object 0.37.0", "rustc-demangle", "rustc_abi", "rustc_ast", @@ -3463,7 +3475,7 @@ dependencies = [ "either", "itertools", "libc", - "object", + "object 0.37.0", "pathdiff", "regex", "rustc_abi", @@ -4495,7 +4507,7 @@ name = "rustc_target" version = "0.0.0" dependencies = [ "bitflags", - "object", + "object 0.37.0", "rustc_abi", "rustc_data_structures", "rustc_fs_util", @@ -5246,7 +5258,7 @@ checksum = "9e9c1e705f82a260173f3eec93f2ff6d7807f23ad5a8cc2e7316a891733ea7a1" dependencies = [ "gimli", "hashbrown", - "object", + "object 0.36.7", "tracing", ] @@ -5907,15 +5919,6 @@ dependencies = [ "indexmap", ] -[[package]] -name = "wasmparser" -version = "0.222.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa210fd1788e6b37a1d1930f3389c48e1d6ebd1a013d34fa4b7f9e3e3bf03146" -dependencies = [ - "bitflags", -] - [[package]] name = "wasmparser" version = "0.229.0" @@ -5940,6 +5943,15 @@ dependencies = [ "semver", ] +[[package]] +name = "wasmparser" +version = "0.232.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917739b33bb1eb0e9a49bcd2637a351931be4578d0cc4d37b908d7a797784fbb" +dependencies = [ + "bitflags", +] + [[package]] name = "wast" version = "230.0.0" diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index bf8ec8c3b915..88efc8ac96b5 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -15,7 +15,7 @@ gimli = "0.31" itertools = "0.12" libc = "0.2" measureme = "12.0.1" -object = { version = "0.36.3", default-features = false, features = ["std", "read"] } +object = { version = "0.37.0", default-features = false, features = ["std", "read"] } rustc-demangle = "0.1.21" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 337c69441779..e9c4c255bce0 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -54,7 +54,7 @@ libc = "0.2.50" # tidy-alphabetical-end [dependencies.object] -version = "0.36.2" +version = "0.37.0" default-features = false features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write", "wasm"] diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 189b19b02861..0121c752dbdd 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -20,5 +20,5 @@ tracing = "0.1" # tidy-alphabetical-start default-features = false features = ["elf", "macho"] -version = "0.36.2" +version = "0.37.0" # tidy-alphabetical-end From 869baeaf9207e86fa9a8e8a3319d7ae080e4a07c Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 5 Jun 2025 04:55:14 +0000 Subject: [PATCH 041/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 2bc38eebfc29..437d4218cfad 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -792fc2b033aea7ea7b766e38bdc40f7d6bdce8c3 +81a964c23ea4fe9ab52b4449bb166bf280035797 From 77b0d3e106b97e3e53783502c896d16876eefd0f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 5 Jun 2025 07:25:14 +0200 Subject: [PATCH 042/183] Deduplicate code in proc-macro-srv --- .../crates/proc-macro-srv/src/server_impl.rs | 133 ++++++++++++++ .../src/server_impl/rust_analyzer_span.rs | 137 +------------- .../src/server_impl/token_id.rs | 168 ++---------------- .../project-model/src/cargo_workspace.rs | 6 - .../crates/rust-analyzer/src/lsp/utils.rs | 3 +- .../rust-analyzer/tests/slow-tests/main.rs | 10 +- 6 files changed, 160 insertions(+), 297 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs index 11dbd9200915..ad2859903348 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl.rs @@ -10,6 +10,7 @@ use std::fmt; +use intern::Symbol; use proc_macro::bridge; mod token_stream; @@ -112,3 +113,135 @@ fn literal_kind_to_internal(kind: bridge::LitKind) -> tt::LitKind { bridge::LitKind::ErrWithGuar => tt::LitKind::Err(()), } } + +pub(super) fn literal_from_str( + s: &str, + span: Span, +) -> Result, ()> { + use proc_macro::bridge::LitKind; + use rustc_lexer::{LiteralKind, Token, TokenKind}; + + let mut tokens = rustc_lexer::tokenize(s); + let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); + + let lit = if minus_or_lit.kind == TokenKind::Minus { + let lit = tokens.next().ok_or(())?; + if !matches!( + lit.kind, + TokenKind::Literal { kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, .. } + ) { + return Err(()); + } + lit + } else { + minus_or_lit + }; + + if tokens.next().is_some() { + return Err(()); + } + + let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) }; + let (kind, start_offset, end_offset) = match kind { + LiteralKind::Int { .. } => (LitKind::Integer, 0, 0), + LiteralKind::Float { .. } => (LitKind::Float, 0, 0), + LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize), + LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize), + LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize), + LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize), + LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize), + LiteralKind::RawStr { n_hashes } => ( + LitKind::StrRaw(n_hashes.unwrap_or_default()), + 2 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + LiteralKind::RawByteStr { n_hashes } => ( + LitKind::ByteStrRaw(n_hashes.unwrap_or_default()), + 3 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + LiteralKind::RawCStr { n_hashes } => ( + LitKind::CStrRaw(n_hashes.unwrap_or_default()), + 3 + n_hashes.unwrap_or_default() as usize, + 1 + n_hashes.unwrap_or_default() as usize, + ), + }; + + let (lit, suffix) = s.split_at(suffix_start as usize); + let lit = &lit[start_offset..lit.len() - end_offset]; + let suffix = match suffix { + "" | "_" => None, + suffix => Some(Symbol::intern(suffix)), + }; + + Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span }) +} + +pub(super) fn from_token_tree( + tree: bridge::TokenTree, Span, Symbol>, +) -> TokenStream { + match tree { + bridge::TokenTree::Group(group) => { + let group = TopSubtree::from_bridge(group); + TokenStream { token_trees: group.0 } + } + + bridge::TokenTree::Ident(ident) => { + let text = ident.sym; + let ident: tt::Ident = tt::Ident { + sym: text, + span: ident.span, + is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, + }; + let leaf = tt::Leaf::from(ident); + let tree = tt::TokenTree::from(leaf); + TokenStream { token_trees: vec![tree] } + } + + bridge::TokenTree::Literal(literal) => { + let token_trees = + if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') { + let punct = tt::Punct { + spacing: tt::Spacing::Alone, + span: literal.span, + char: '-' as char, + }; + let leaf: tt::Leaf = tt::Leaf::from(punct); + let minus_tree = tt::TokenTree::from(leaf); + + let literal = tt::Literal { + symbol: Symbol::intern(symbol), + suffix: literal.suffix, + span: literal.span, + kind: literal_kind_to_internal(literal.kind), + }; + let leaf: tt::Leaf = tt::Leaf::from(literal); + let tree = tt::TokenTree::from(leaf); + vec![minus_tree, tree] + } else { + let literal = tt::Literal { + symbol: literal.symbol, + suffix: literal.suffix, + span: literal.span, + kind: literal_kind_to_internal(literal.kind), + }; + + let leaf: tt::Leaf = tt::Leaf::from(literal); + let tree = tt::TokenTree::from(leaf); + vec![tree] + }; + TokenStream { token_trees } + } + + bridge::TokenTree::Punct(p) => { + let punct = tt::Punct { + char: p.ch as char, + spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone }, + span: p.span, + }; + let leaf = tt::Leaf::from(punct); + let tree = tt::TokenTree::from(leaf); + TokenStream { token_trees: vec![tree] } + } + } +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index e0c6e68f8037..5d1271ba81e1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -14,16 +14,7 @@ use proc_macro::bridge::{self, server}; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span}; use tt::{TextRange, TextSize}; -use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder}; -mod tt { - pub use tt::*; - - pub type TokenTree = ::tt::TokenTree; - pub type Leaf = ::tt::Leaf; - pub type Literal = ::tt::Literal; - pub type Punct = ::tt::Punct; - pub type Ident = ::tt::Ident; -} +use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder}; type TokenStream = crate::server_impl::TokenStream; @@ -62,66 +53,7 @@ impl server::FreeFunctions for RaSpanServer { &mut self, s: &str, ) -> Result, ()> { - use proc_macro::bridge::LitKind; - use rustc_lexer::{LiteralKind, Token, TokenKind}; - - let mut tokens = rustc_lexer::tokenize(s); - let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); - - let lit = if minus_or_lit.kind == TokenKind::Minus { - let lit = tokens.next().ok_or(())?; - if !matches!( - lit.kind, - TokenKind::Literal { - kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, - .. - } - ) { - return Err(()); - } - lit - } else { - minus_or_lit - }; - - if tokens.next().is_some() { - return Err(()); - } - - let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) }; - let (kind, start_offset, end_offset) = match kind { - LiteralKind::Int { .. } => (LitKind::Integer, 0, 0), - LiteralKind::Float { .. } => (LitKind::Float, 0, 0), - LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize), - LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize), - LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize), - LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize), - LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize), - LiteralKind::RawStr { n_hashes } => ( - LitKind::StrRaw(n_hashes.unwrap_or_default()), - 2 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - LiteralKind::RawByteStr { n_hashes } => ( - LitKind::ByteStrRaw(n_hashes.unwrap_or_default()), - 3 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - LiteralKind::RawCStr { n_hashes } => ( - LitKind::CStrRaw(n_hashes.unwrap_or_default()), - 3 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - }; - - let (lit, suffix) = s.split_at(suffix_start as usize); - let lit = &lit[start_offset..lit.len() - end_offset]; - let suffix = match suffix { - "" | "_" => None, - suffix => Some(Symbol::intern(suffix)), - }; - - Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site }) + literal_from_str(s, self.call_site) } fn emit_diagnostic(&mut self, _: bridge::Diagnostic) { @@ -149,70 +81,7 @@ impl server::TokenStream for RaSpanServer { &mut self, tree: bridge::TokenTree, ) -> Self::TokenStream { - match tree { - bridge::TokenTree::Group(group) => { - let group = TopSubtree::from_bridge(group); - TokenStream { token_trees: group.0 } - } - - bridge::TokenTree::Ident(ident) => { - let text = ident.sym; - let ident: tt::Ident = tt::Ident { - sym: text, - span: ident.span, - is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, - }; - let leaf = tt::Leaf::from(ident); - let tree = tt::TokenTree::from(leaf); - TokenStream { token_trees: vec![tree] } - } - - bridge::TokenTree::Literal(literal) => { - let token_trees = - if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') { - let punct = tt::Punct { - spacing: tt::Spacing::Alone, - span: literal.span, - char: '-' as char, - }; - let leaf: tt::Leaf = tt::Leaf::from(punct); - let minus_tree = tt::TokenTree::from(leaf); - - let literal = tt::Literal { - symbol: Symbol::intern(symbol), - suffix: literal.suffix, - span: literal.span, - kind: literal_kind_to_internal(literal.kind), - }; - let leaf: tt::Leaf = tt::Leaf::from(literal); - let tree = tt::TokenTree::from(leaf); - vec![minus_tree, tree] - } else { - let literal = tt::Literal { - symbol: literal.symbol, - suffix: literal.suffix, - span: literal.span, - kind: literal_kind_to_internal(literal.kind), - }; - - let leaf: tt::Leaf = tt::Leaf::from(literal); - let tree = tt::TokenTree::from(leaf); - vec![tree] - }; - TokenStream { token_trees } - } - - bridge::TokenTree::Punct(p) => { - let punct = tt::Punct { - char: p.ch as char, - spacing: if p.joint { tt::Spacing::Joint } else { tt::Spacing::Alone }, - span: p.span, - }; - let leaf = tt::Leaf::from(punct); - let tree = tt::TokenTree::from(leaf); - TokenStream { token_trees: vec![tree] } - } - } + from_token_tree(tree) } fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index d55b269f868d..b493b325e830 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -5,23 +5,9 @@ use std::ops::{Bound, Range}; use intern::Symbol; use proc_macro::bridge::{self, server}; -use crate::server_impl::{TopSubtree, literal_kind_to_internal, token_stream::TokenStreamBuilder}; -mod tt { - pub use span::TokenId; +use crate::server_impl::{from_token_tree, literal_from_str, token_stream::TokenStreamBuilder}; - pub use tt::*; - - pub type TokenTree = ::tt::TokenTree; - pub type Leaf = ::tt::Leaf; - pub type Literal = ::tt::Literal; - pub type Punct = ::tt::Punct; - pub type Ident = ::tt::Ident; -} -type TokenTree = tt::TokenTree; -type Punct = tt::Punct; -type Spacing = tt::Spacing; -type Literal = tt::Literal; -type Span = tt::TokenId; +type Span = span::TokenId; type TokenStream = crate::server_impl::TokenStream; pub struct FreeFunctions; @@ -49,67 +35,7 @@ impl server::FreeFunctions for TokenIdServer { &mut self, s: &str, ) -> Result, ()> { - use proc_macro::bridge::LitKind; - use rustc_lexer::{LiteralKind, Token, TokenKind}; - - let mut tokens = rustc_lexer::tokenize(s); - let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); - - let lit = if minus_or_lit.kind == TokenKind::Minus { - let lit = tokens.next().ok_or(())?; - if !matches!( - lit.kind, - TokenKind::Literal { - kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, - .. - } - ) { - return Err(()); - } - lit - } else { - minus_or_lit - }; - - if tokens.next().is_some() { - return Err(()); - } - - let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) }; - - let (kind, start_offset, end_offset) = match kind { - LiteralKind::Int { .. } => (LitKind::Integer, 0, 0), - LiteralKind::Float { .. } => (LitKind::Float, 0, 0), - LiteralKind::Char { terminated } => (LitKind::Char, 1, terminated as usize), - LiteralKind::Byte { terminated } => (LitKind::Byte, 2, terminated as usize), - LiteralKind::Str { terminated } => (LitKind::Str, 1, terminated as usize), - LiteralKind::ByteStr { terminated } => (LitKind::ByteStr, 2, terminated as usize), - LiteralKind::CStr { terminated } => (LitKind::CStr, 2, terminated as usize), - LiteralKind::RawStr { n_hashes } => ( - LitKind::StrRaw(n_hashes.unwrap_or_default()), - 2 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - LiteralKind::RawByteStr { n_hashes } => ( - LitKind::ByteStrRaw(n_hashes.unwrap_or_default()), - 3 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - LiteralKind::RawCStr { n_hashes } => ( - LitKind::CStrRaw(n_hashes.unwrap_or_default()), - 3 + n_hashes.unwrap_or_default() as usize, - 1 + n_hashes.unwrap_or_default() as usize, - ), - }; - - let (lit, suffix) = s.split_at(suffix_start as usize); - let lit = &lit[start_offset..lit.len() - end_offset]; - let suffix = match suffix { - "" | "_" => None, - suffix => Some(Symbol::intern(suffix)), - }; - - Ok(bridge::Literal { kind, symbol: Symbol::intern(lit), suffix, span: self.call_site }) + literal_from_str(s, self.call_site) } fn emit_diagnostic(&mut self, _: bridge::Diagnostic) {} @@ -135,69 +61,7 @@ impl server::TokenStream for TokenIdServer { &mut self, tree: bridge::TokenTree, ) -> Self::TokenStream { - match tree { - bridge::TokenTree::Group(group) => { - let group = TopSubtree::from_bridge(group); - TokenStream { token_trees: group.0 } - } - - bridge::TokenTree::Ident(ident) => { - let ident: tt::Ident = tt::Ident { - sym: ident.sym, - span: ident.span, - is_raw: if ident.is_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No }, - }; - let leaf = tt::Leaf::from(ident); - let tree = TokenTree::from(leaf); - TokenStream { token_trees: vec![tree] } - } - - bridge::TokenTree::Literal(literal) => { - let token_trees = - if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') { - let punct = tt::Punct { - spacing: tt::Spacing::Alone, - span: literal.span, - char: '-' as char, - }; - let leaf: tt::Leaf = tt::Leaf::from(punct); - let minus_tree = tt::TokenTree::from(leaf); - - let literal = Literal { - symbol: Symbol::intern(symbol), - suffix: literal.suffix, - span: literal.span, - kind: literal_kind_to_internal(literal.kind), - }; - let leaf: tt::Leaf = tt::Leaf::from(literal); - let tree = tt::TokenTree::from(leaf); - vec![minus_tree, tree] - } else { - let literal = Literal { - symbol: literal.symbol, - suffix: literal.suffix, - span: literal.span, - kind: literal_kind_to_internal(literal.kind), - }; - - let leaf: tt::Leaf = tt::Leaf::from(literal); - let tree = tt::TokenTree::from(leaf); - vec![tree] - }; - TokenStream { token_trees } - } - - bridge::TokenTree::Punct(p) => { - let punct = Punct { - char: p.ch as char, - spacing: if p.joint { Spacing::Joint } else { Spacing::Alone }, - span: p.span, - }; - let leaf = tt::Leaf::from(punct); - let tree = TokenTree::from(leaf); - TokenStream { token_trees: vec![tree] } - } - } + from_token_tree(tree) } fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result { @@ -337,6 +201,8 @@ impl server::Server for TokenIdServer { #[cfg(test)] mod tests { + use span::TokenId; + use super::*; #[test] @@ -345,18 +211,18 @@ mod tests { token_trees: vec![ tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym: Symbol::intern("struct"), - span: tt::TokenId(0), + span: TokenId(0), is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym: Symbol::intern("T"), - span: tt::TokenId(0), + span: TokenId(0), is_raw: tt::IdentIsRaw::No, })), tt::TokenTree::Subtree(tt::Subtree { delimiter: tt::Delimiter { - open: tt::TokenId(0), - close: tt::TokenId(0), + open: TokenId(0), + close: TokenId(0), kind: tt::DelimiterKind::Brace, }, len: 0, @@ -372,8 +238,8 @@ mod tests { let subtree_paren_a = vec![ tt::TokenTree::Subtree(tt::Subtree { delimiter: tt::Delimiter { - open: tt::TokenId(0), - close: tt::TokenId(0), + open: TokenId(0), + close: TokenId(0), kind: tt::DelimiterKind::Parenthesis, }, len: 1, @@ -381,24 +247,24 @@ mod tests { tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { is_raw: tt::IdentIsRaw::No, sym: Symbol::intern("a"), - span: tt::TokenId(0), + span: TokenId(0), })), ]; - let t1 = TokenStream::from_str("(a)", tt::TokenId(0)).unwrap(); + let t1 = TokenStream::from_str("(a)", TokenId(0)).unwrap(); assert_eq!(t1.token_trees.len(), 2); assert!(t1.token_trees[0..2] == subtree_paren_a); - let t2 = TokenStream::from_str("(a);", tt::TokenId(0)).unwrap(); + let t2 = TokenStream::from_str("(a);", TokenId(0)).unwrap(); assert_eq!(t2.token_trees.len(), 3); assert!(t2.token_trees[0..2] == subtree_paren_a); - let underscore = TokenStream::from_str("_", tt::TokenId(0)).unwrap(); + let underscore = TokenStream::from_str("_", TokenId(0)).unwrap(); assert!( underscore.token_trees[0] == tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym: Symbol::intern("_"), - span: tt::TokenId(0), + span: TokenId(0), is_raw: tt::IdentIsRaw::No, })) ); diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 6e730b1aea26..bb02284a5130 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -431,12 +431,6 @@ impl CargoWorkspace { .ok_or(cargo_metadata::Error::NoJson)?; Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None)) })() - .map(|(metadata, error)| { - ( - metadata, - error.map(|e| e.context(format!("Failed to run `{:?}`", meta.cargo_command()))), - ) - }) .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command())) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs index 673eaa5952f0..5bea7084fdb5 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/utils.rs @@ -108,8 +108,7 @@ impl GlobalState { /// edge users from being upset! pub(crate) fn poke_rust_analyzer_developer(&mut self, message: String) { let from_source_build = option_env!("POKE_RA_DEVS").is_some(); - let profiling_enabled = std::env::var("RA_PROFILE").is_ok(); - if from_source_build || profiling_enabled { + if from_source_build { self.show_and_log_error(message, None); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index f6bcb5642c3b..59073af983b7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -975,10 +975,6 @@ version = \"0.0.0\" } fn out_dirs_check_impl(root_contains_symlink: bool) { - if skip_slow_tests() { - return; - } - let mut server = Project::with_fixture( r###" //- /Cargo.toml @@ -1130,12 +1126,18 @@ fn main() { #[test] fn out_dirs_check() { + if skip_slow_tests() { + return; + } out_dirs_check_impl(false); } #[test] #[cfg(not(windows))] // windows requires elevated permissions to create symlinks fn root_contains_symlink_out_dirs_check() { + if skip_slow_tests() { + return; + } out_dirs_check_impl(true); } From 129d568e6de140606ee37fd945c8e001167a3f4b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 5 Jun 2025 15:04:50 +0200 Subject: [PATCH 043/183] fix: Record macro calls in signatures in `ChildBySource` impls --- .../rust-analyzer/crates/hir/src/semantics.rs | 6 --- .../hir/src/semantics/child_by_source.rs | 28 +++++++++++- .../crates/hir/src/semantics/source_to_def.rs | 18 +++----- .../crates/ide/src/expand_macro.rs | 44 +++++++++++++++++++ 4 files changed, 77 insertions(+), 19 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index ee83d10c0e9b..4a2e8e379fb8 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs @@ -1948,18 +1948,12 @@ impl<'db> SemanticsImpl<'db> { ChildContainer::TraitId(it) => { return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); } - ChildContainer::TraitAliasId(it) => { - return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); - } ChildContainer::ImplId(it) => { return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); } ChildContainer::EnumId(it) => { return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); } - ChildContainer::TypeAliasId(it) => { - return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset)); - } ChildContainer::GenericDefId(it) => { return Some(SourceAnalyzer::new_generic_def(self.db, it, node, offset)); } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index 6accf9b2e9c2..a150df70502b 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -17,6 +17,7 @@ use hir_def::{ DynMap, keys::{self, Key}, }, + hir::generics::GenericParams, item_scope::ItemScope, item_tree::ItemTreeNode, nameres::DefMap, @@ -49,6 +50,12 @@ impl ChildBySource for TraitId { data.items.iter().for_each(|&(_, item)| { add_assoc_item(db, res, file_id, item); }); + let (_, source_map) = db.trait_signature_with_source_map(*self); + source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( + |(ast, &exp_id)| { + res[keys::MACRO_CALL].insert(ast.value, exp_id); + }, + ); } } @@ -68,6 +75,12 @@ impl ChildBySource for ImplId { data.items.iter().for_each(|&(_, item)| { add_assoc_item(db, res, file_id, item); }); + let (_, source_map) = db.impl_signature_with_source_map(*self); + source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( + |(ast, &exp_id)| { + res[keys::MACRO_CALL].insert(ast.value, exp_id); + }, + ); } } @@ -195,6 +208,12 @@ impl ChildBySource for EnumId { res[keys::ENUM_VARIANT] .insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant); }); + let (_, source_map) = db.enum_signature_with_source_map(*self); + source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( + |(ast, &exp_id)| { + res[keys::MACRO_CALL].insert(ast.value, exp_id); + }, + ); } } @@ -225,7 +244,8 @@ impl ChildBySource for GenericDefId { return; } - let generic_params = db.generic_params(*self); + let (generic_params, _, source_map) = + GenericParams::generic_params_and_store_and_source_map(db, *self); let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx); let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx); @@ -253,6 +273,12 @@ impl ChildBySource for GenericDefId { res[keys::LIFETIME_PARAM].insert(AstPtr::new(&ast_param), id); } } + + source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( + |(ast, &exp_id)| { + res[keys::MACRO_CALL].insert(ast.value, exp_id); + }, + ); } } diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index b5537d0bff05..71ee0f693896 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs @@ -631,14 +631,14 @@ impl SourceToDefCtx<'_, '_> { match &item { ast::Item::Module(it) => self.module_to_def(container.with_value(it))?.into(), ast::Item::Trait(it) => self.trait_to_def(container.with_value(it))?.into(), - ast::Item::TraitAlias(it) => { - self.trait_alias_to_def(container.with_value(it))?.into() - } ast::Item::Impl(it) => self.impl_to_def(container.with_value(it))?.into(), ast::Item::Enum(it) => self.enum_to_def(container.with_value(it))?.into(), - ast::Item::TypeAlias(it) => { - self.type_alias_to_def(container.with_value(it))?.into() - } + ast::Item::TypeAlias(it) => ChildContainer::GenericDefId( + self.type_alias_to_def(container.with_value(it))?.into(), + ), + ast::Item::TraitAlias(it) => ChildContainer::GenericDefId( + self.trait_alias_to_def(container.with_value(it))?.into(), + ), ast::Item::Struct(it) => { let def = self.struct_to_def(container.with_value(it))?; let is_in_body = it.field_list().is_some_and(|it| { @@ -738,11 +738,9 @@ pub(crate) enum ChildContainer { DefWithBodyId(DefWithBodyId), ModuleId(ModuleId), TraitId(TraitId), - TraitAliasId(TraitAliasId), ImplId(ImplId), EnumId(EnumId), VariantId(VariantId), - TypeAliasId(TypeAliasId), /// XXX: this might be the same def as, for example an `EnumId`. However, /// here the children are generic parameters, and not, eg enum variants. GenericDefId(GenericDefId), @@ -751,11 +749,9 @@ impl_from! { DefWithBodyId, ModuleId, TraitId, - TraitAliasId, ImplId, EnumId, VariantId, - TypeAliasId, GenericDefId for ChildContainer } @@ -767,11 +763,9 @@ impl ChildContainer { ChildContainer::DefWithBodyId(it) => it.child_by_source(db, file_id), ChildContainer::ModuleId(it) => it.child_by_source(db, file_id), ChildContainer::TraitId(it) => it.child_by_source(db, file_id), - ChildContainer::TraitAliasId(_) => DynMap::default(), ChildContainer::ImplId(it) => it.child_by_source(db, file_id), ChildContainer::EnumId(it) => it.child_by_source(db, file_id), ChildContainer::VariantId(it) => it.child_by_source(db, file_id), - ChildContainer::TypeAliasId(_) => DynMap::default(), ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id), } } diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 7c396339c145..1c09bd5d0c0a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -800,4 +800,48 @@ foo(); foo();"#]], ); } + + #[test] + fn works_in_sig() { + check( + r#" +macro_rules! foo { + () => { u32 }; +} +fn foo() -> foo$0!() { + 42 +} +"#, + expect![[r#" + foo! + u32"#]], + ); + check( + r#" +macro_rules! foo { + () => { u32 }; +} +fn foo(_: foo$0!() ) {} +"#, + expect![[r#" + foo! + u32"#]], + ); + } + + #[test] + fn works_in_generics() { + check( + r#" +trait Trait {} +macro_rules! foo { + () => { Trait }; +} +impl Trait for () {} +"#, + expect![[r#" + foo! + Trait"#]], + ); + } } From 1de497207d02c4f66a71c4a16fa94e061e404280 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 5 Jun 2025 16:11:30 +0200 Subject: [PATCH 044/183] Better parser recovery for macro calls in type bound position --- .../parser/src/grammar/generic_params.rs | 11 ++ .../crates/parser/src/grammar/paths.rs | 2 +- .../crates/parser/src/grammar/types.rs | 14 +-- .../parser/test_data/generated/runner.rs | 4 + .../err/type_bounds_macro_call_recovery.rast | 112 ++++++++++++++++++ .../err/type_bounds_macro_call_recovery.rs | 1 + 6 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs index 9d4fdbfaf2ef..ea5a3bc8593f 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs @@ -201,6 +201,17 @@ fn type_bound(p: &mut Parser<'_>) -> bool { } if paths::is_use_path_start(p) { types::path_type_bounds(p, false); + // test_err type_bounds_macro_call_recovery + // fn foo() -> Box {} + if p.at(T![!]) { + let m = p.start(); + p.bump(T![!]); + p.error("unexpected `!` in type path, macro calls are not allowed here"); + if p.at_ts(TokenSet::new(&[T!['{'], T!['['], T!['(']])) { + items::token_tree(p); + } + m.complete(p, ERROR); + } } else { m.abandon(p); return false; diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs index e628bcc05679..dfe7cb57d24b 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/paths.rs @@ -98,7 +98,7 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option) { m.complete(p, DYN_TRAIT_TYPE); } -// test path_type -// type A = Foo; -// type B = ::Foo; -// type C = self::Foo; -// type D = super::Foo; -pub(super) fn path_type(p: &mut Parser<'_>) { - path_type_bounds(p, true); -} - // test macro_call_type // type A = foo!(); // type B = crate::foo!(); @@ -365,6 +356,11 @@ fn path_or_macro_type(p: &mut Parser<'_>, allow_bounds: bool) { } } +// test path_type +// type A = Foo; +// type B = ::Foo; +// type C = self::Foo; +// type D = super::Foo; pub(super) fn path_type_bounds(p: &mut Parser<'_>, allow_bounds: bool) { assert!(paths::is_path_start(p)); let m = p.start(); diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 537f6df05b9f..6ec4192830bc 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -876,6 +876,10 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs"); } #[test] + fn type_bounds_macro_call_recovery() { + run_and_expect_errors("test_data/parser/inline/err/type_bounds_macro_call_recovery.rs"); + } + #[test] fn type_in_array_recover() { run_and_expect_errors("test_data/parser/inline/err/type_in_array_recover.rs"); } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast new file mode 100644 index 000000000000..4722beb61928 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast @@ -0,0 +1,112 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "foo" + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME + IDENT "T" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + ERROR + BANG "!" + TOKEN_TREE + L_BRACK "[" + R_BRACK "]" + COMMA "," + WHITESPACE " " + TYPE_PARAM + NAME + IDENT "T" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + ERROR + BANG "!" + COMMA "," + WHITESPACE " " + TYPE_PARAM + NAME + IDENT "T" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + ERROR + BANG "!" + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" + R_ANGLE ">" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + RET_TYPE + THIN_ARROW "->" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Box" + GENERIC_ARG_LIST + L_ANGLE "<" + TYPE_ARG + DYN_TRAIT_TYPE + TYPE_BOUND_LIST + TYPE_BOUND + MACRO_TYPE + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + BANG "!" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + ERROR + BANG "!" + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" + R_ANGLE ">" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + R_CURLY "}" + WHITESPACE "\n" +error 12: unexpected `!` in type path, macro calls are not allowed here +error 21: unexpected `!` in type path, macro calls are not allowed here +error 28: unexpected `!` in type path, macro calls are not allowed here +error 43: expected `{`, `[`, `(` +error 48: unexpected `!` in type path, macro calls are not allowed here diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs new file mode 100644 index 000000000000..517404fdb0e5 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rs @@ -0,0 +1 @@ +fn foo() -> Box {} From 00452bd783a2c91b85cfb37e650628674c64b006 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Fri, 30 May 2025 12:38:28 +0200 Subject: [PATCH 045/183] change tests to use fixed constants to let them pass with miri --- library/core/src/num/f32.rs | 2 +- library/core/src/num/f64.rs | 2 +- library/coretests/tests/floats/f32.rs | 9 +++- library/std/src/num/f32.rs | 34 +++++++------- library/std/src/num/f64.rs | 6 +-- library/std/tests/floats/f32.rs | 64 +++++---------------------- src/tools/miri/tests/pass/float.rs | 4 +- 7 files changed, 44 insertions(+), 77 deletions(-) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index bf923d4070ad..b460c7d0205b 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1879,7 +1879,7 @@ pub mod math { /// /// let x = 2.0_f32; /// let abs_difference = (f32::math::powi(x, 2) - (x * x)).abs(); - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 1e-5); /// /// assert_eq!(f32::math::powi(f32::NAN, 0), 1.0); /// ``` diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 0a63ed828aed..3cd079b84eb4 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1877,7 +1877,7 @@ pub mod math { /// /// let x = 2.0_f64; /// let abs_difference = (f64::math::powi(x, 2) - (x * x)).abs(); - /// assert!(abs_difference <= f64::EPSILON); + /// assert!(abs_difference <= 1e-6); /// /// assert_eq!(f64::math::powi(f64::NAN, 0), 1.0); /// ``` diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs index 4e6509ead2ba..98e9695d0903 100644 --- a/library/coretests/tests/floats/f32.rs +++ b/library/coretests/tests/floats/f32.rs @@ -23,6 +23,11 @@ const NAN_MASK1: u32 = 0x002a_aaaa; /// Second pattern over the mantissa const NAN_MASK2: u32 = 0x0055_5555; +/// Miri adds some extra errors to float functions; make sure the tests still pass. +/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides. +/// They serve as a way to get an idea of the real precision of floating point operations on different platforms. +const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 }; + #[test] fn test_num_f32() { super::test_num(10f32, 2f32); @@ -437,8 +442,8 @@ fn test_powi() { let nan: f32 = f32::NAN; let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; - assert_biteq!(1.0f32.powi(1), 1.0); - assert_approx_eq!((-3.1f32).powi(2), 9.61); + assert_approx_eq!(1.0f32.powi(1), 1.0); + assert_approx_eq!((-3.1f32).powi(2), 9.61, APPROX_DELTA); assert_approx_eq!(5.9f32.powi(-2), 0.028727); assert_biteq!(8.3f32.powi(0), 1.0); assert!(nan.powi(2).is_nan()); diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index d7396a96b836..e79ec2ae966f 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -304,7 +304,7 @@ impl f32 { /// ``` /// let x = 2.0_f32; /// let abs_difference = (x.powi(2) - (x * x)).abs(); - /// assert!(abs_difference <= 8.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-5); /// /// assert_eq!(f32::powi(f32::NAN, 0), 1.0); /// ``` @@ -328,7 +328,7 @@ impl f32 { /// ``` /// let x = 2.0_f32; /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); - /// assert!(abs_difference <= 8.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-5); /// /// assert_eq!(f32::powf(1.0, f32::NAN), 1.0); /// assert_eq!(f32::powf(f32::NAN, 0.0), 1.0); @@ -388,7 +388,7 @@ impl f32 { /// // ln(e) - 1 == 0 /// let abs_difference = (e.ln() - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -413,7 +413,7 @@ impl f32 { /// // 2^2 - 4 == 0 /// let abs_difference = (f.exp2() - 4.0).abs(); /// - /// assert!(abs_difference <= 8.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-5); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -442,7 +442,7 @@ impl f32 { /// // ln(e) - 1 == 0 /// let abs_difference = (e.ln() - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` /// /// Non-positive values: @@ -479,7 +479,7 @@ impl f32 { /// // log5(5) - 1 == 0 /// let abs_difference = (five.log(5.0) - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` /// /// Non-positive values: @@ -512,7 +512,7 @@ impl f32 { /// // log2(2) - 1 == 0 /// let abs_difference = (two.log2() - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` /// /// Non-positive values: @@ -545,7 +545,7 @@ impl f32 { /// // log10(10) - 1 == 0 /// let abs_difference = (ten.log10() - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` /// /// Non-positive values: @@ -652,7 +652,7 @@ impl f32 { /// // sqrt(x^2 + y^2) /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -676,7 +676,7 @@ impl f32 { /// /// let abs_difference = (x.sin() - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -700,7 +700,7 @@ impl f32 { /// /// let abs_difference = (x.cos() - 1.0).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -754,7 +754,7 @@ impl f32 { /// // asin(sin(pi/2)) /// let abs_difference = (f.sin().asin() - std::f32::consts::FRAC_PI_2).abs(); /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert!(abs_difference <= 1e-3); /// ``` #[doc(alias = "arcsin")] #[rustc_allow_incoherent_impl] @@ -784,7 +784,7 @@ impl f32 { /// // acos(cos(pi/4)) /// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` #[doc(alias = "arccos")] #[rustc_allow_incoherent_impl] @@ -884,8 +884,8 @@ impl f32 { /// let abs_difference_0 = (f.0 - x.sin()).abs(); /// let abs_difference_1 = (f.1 - x.cos()).abs(); /// - /// assert!(abs_difference_0 <= 4.0 * f32::EPSILON); - /// assert!(abs_difference_1 <= 4.0 * f32::EPSILON); + /// assert!(abs_difference_0 <= 1e-6); + /// assert!(abs_difference_1 <= 1e-6); /// ``` #[doc(alias = "sincos")] #[rustc_allow_incoherent_impl] @@ -1067,7 +1067,7 @@ impl f32 { /// /// let abs_difference = (f - x).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-7); /// ``` #[doc(alias = "arcsinh")] #[rustc_allow_incoherent_impl] @@ -1095,7 +1095,7 @@ impl f32 { /// /// let abs_difference = (f - x).abs(); /// - /// assert!(abs_difference <= 4.0 * f32::EPSILON); + /// assert!(abs_difference <= 1e-6); /// ``` #[doc(alias = "arccosh")] #[rustc_allow_incoherent_impl] diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index d1d62f9275cb..853417825f97 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -304,7 +304,7 @@ impl f64 { /// ``` /// let x = 2.0_f64; /// let abs_difference = (x.powi(2) - (x * x)).abs(); - /// assert!(abs_difference <= 8.0 * f64::EPSILON); + /// assert!(abs_difference <= 1e-14); /// /// assert_eq!(f64::powi(f64::NAN, 0), 1.0); /// ``` @@ -328,7 +328,7 @@ impl f64 { /// ``` /// let x = 2.0_f64; /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); - /// assert!(abs_difference <= 8.0 * f64::EPSILON); + /// assert!(abs_difference <= 1e-14); /// /// assert_eq!(f64::powf(1.0, f64::NAN), 1.0); /// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0); @@ -754,7 +754,7 @@ impl f64 { /// // asin(sin(pi/2)) /// let abs_difference = (f.sin().asin() - std::f64::consts::FRAC_PI_2).abs(); /// - /// assert!(abs_difference < 1e-10); + /// assert!(abs_difference < 1e-7); /// ``` #[doc(alias = "arcsin")] #[rustc_allow_incoherent_impl] diff --git a/library/std/tests/floats/f32.rs b/library/std/tests/floats/f32.rs index 7144a27345b2..38c906c1d877 100644 --- a/library/std/tests/floats/f32.rs +++ b/library/std/tests/floats/f32.rs @@ -3,7 +3,7 @@ use std::f32::consts; /// Miri adds some extra errors to float functions; make sure the tests still pass. /// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides. /// They serve as a way to get an idea of the real precision of floating point operations on different platforms. -const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 }; +const APPROX_DELTA: f32 = if cfg!(miri) { 1e-3 } else { 1e-6 }; #[allow(unused_macros)] macro_rules! assert_f32_biteq { @@ -22,17 +22,9 @@ fn test_powf() { let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; assert_eq!(1.0f32.powf(1.0), 1.0); - assert_approx_eq!( - 3.4f32.powf(4.5), - 246.408218, - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(3.4f32.powf(4.5), 246.408218, APPROX_DELTA); assert_approx_eq!(2.7f32.powf(-3.2), 0.041652); - assert_approx_eq!( - (-3.1f32).powf(2.0), - 9.61, - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!((-3.1f32).powf(2.0), 9.61, APPROX_DELTA); assert_approx_eq!(5.9f32.powf(-2.0), 0.028727); assert_eq!(8.3f32.powf(0.0), 1.0); assert!(nan.powf(2.0).is_nan()); @@ -44,11 +36,7 @@ fn test_powf() { fn test_exp() { assert_eq!(1.0, 0.0f32.exp()); assert_approx_eq!(2.718282, 1.0f32.exp(), APPROX_DELTA); - assert_approx_eq!( - 148.413162, - 5.0f32.exp(), - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(148.413162, 5.0f32.exp(), APPROX_DELTA); let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; @@ -60,11 +48,7 @@ fn test_exp() { #[test] fn test_exp2() { - assert_approx_eq!( - 32.0, - 5.0f32.exp2(), - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(32.0, 5.0f32.exp2(), APPROX_DELTA); assert_eq!(1.0, 0.0f32.exp2()); let inf: f32 = f32::INFINITY; @@ -87,11 +71,7 @@ fn test_ln() { assert!((-2.3f32).ln().is_nan()); assert_eq!((-0.0f32).ln(), neg_inf); assert_eq!(0.0f32.ln(), neg_inf); - assert_approx_eq!( - 4.0f32.ln(), - 1.386294, - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(4.0f32.ln(), 1.386294, APPROX_DELTA); } #[test] @@ -101,7 +81,7 @@ fn test_log() { let neg_inf: f32 = f32::NEG_INFINITY; assert_approx_eq!(10.0f32.log(10.0), 1.0); assert_approx_eq!(2.3f32.log(3.5), 0.664858); - assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0); + assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0, APPROX_DELTA); assert!(1.0f32.log(1.0).is_nan()); assert!(1.0f32.log(-13.9).is_nan()); assert!(nan.log(2.3).is_nan()); @@ -117,17 +97,9 @@ fn test_log2() { let nan: f32 = f32::NAN; let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; - assert_approx_eq!( - 10.0f32.log2(), - 3.321928, - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(10.0f32.log2(), 3.321928, APPROX_DELTA); assert_approx_eq!(2.3f32.log2(), 1.201634); - assert_approx_eq!( - 1.0f32.exp().log2(), - 1.442695, - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(1.0f32.exp().log2(), 1.442695, APPROX_DELTA); assert!(nan.log2().is_nan()); assert_eq!(inf.log2(), inf); assert!(neg_inf.log2().is_nan()); @@ -191,11 +163,7 @@ fn test_acosh() { assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32); // test for low accuracy from issue 104548 - assert_approx_eq!( - 60.0f32, - 60.0f32.cosh().acosh(), - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh(), APPROX_DELTA); } #[test] @@ -274,11 +242,7 @@ fn test_real_consts() { let ln_10: f32 = consts::LN_10; assert_approx_eq!(frac_pi_2, pi / 2f32); - assert_approx_eq!( - frac_pi_3, - pi / 3f32, - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(frac_pi_3, pi / 3f32, APPROX_DELTA); assert_approx_eq!(frac_pi_4, pi / 4f32); assert_approx_eq!(frac_pi_6, pi / 6f32); assert_approx_eq!(frac_pi_8, pi / 8f32); @@ -290,9 +254,5 @@ fn test_real_consts() { assert_approx_eq!(log2_e, e.log2()); assert_approx_eq!(log10_e, e.log10()); assert_approx_eq!(ln_2, 2f32.ln()); - assert_approx_eq!( - ln_10, - 10f32.ln(), - APPROX_DELTA /* Miri float-non-det: Make tests pass for now */ - ); + assert_approx_eq!(ln_10, 10f32.ln(), APPROX_DELTA); } diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 586a52a4f81d..7ce0bc88517e 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1034,7 +1034,7 @@ pub fn libm() { assert_approx_eq!(400f64.powf(0.5f64), 20f64); // Some inputs to powf and powi result in fixed outputs - // and thus must be exactly equal to that value + // and thus must be exactly equal to that value. // C standard says: // 1^y = 1 for any y, even a NaN. assert_eq!(1f32.powf(10.0), 1.0); @@ -1069,11 +1069,13 @@ pub fn libm() { // For pow (powf in rust) the C standard says: // x^0 = 1 for all x even a sNaN + // FIXME(#4286): this does not match the behavior of all implementations. assert_eq!(SNAN_F32.powf(0.0), 1.0); assert_eq!(SNAN_F64.powf(0.0), 1.0); // For pown (powi in rust) the C standard says: // x^0 = 1 for all x even a sNaN + // FIXME(#4286): this does not match the behavior of all implementations. assert_eq!(SNAN_F32.powi(0), 1.0); assert_eq!(SNAN_F64.powi(0), 1.0); From 387dae9092414888e9291efd9317068458250a49 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 5 Jun 2025 14:47:00 +0000 Subject: [PATCH 046/183] Move canonicalization into current_dll_path And consistently use try_canonicalize rather than canonicalize. --- compiler/rustc_session/src/filesearch.rs | 30 ++++++++++-------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 0e711890e076..1fd74c914b29 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use std::{env, fs}; -use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; +use rustc_fs_util::try_canonicalize; use rustc_target::spec::Target; use smallvec::{SmallVec, smallvec}; @@ -87,7 +87,7 @@ fn current_dll_path() -> Result { }; let bytes = CStr::from_ptr(fname_ptr).to_bytes(); let os = OsStr::from_bytes(bytes); - Ok(PathBuf::from(os)) + try_canonicalize(Path::new(os)).map_err(|e| e.to_string()) } #[cfg(target_os = "aix")] @@ -122,7 +122,7 @@ fn current_dll_path() -> Result { if (data_base..data_end).contains(&addr) { let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); let os = OsStr::from_bytes(bytes); - return Ok(PathBuf::from(os)); + return try_canonicalize(Path::new(os)).map_err(|e| e.to_string()); } if (*current).ldinfo_next == 0 { break; @@ -169,7 +169,12 @@ fn current_dll_path() -> Result { filename.truncate(n); - Ok(OsString::from_wide(&filename).into()) + let path = try_canonicalize(OsString::from_wide(&filename)).map_err(|e| e.to_string())?; + + // See comments on this target function, but the gist is that + // gcc chokes on verbatim paths which fs::canonicalize generates + // so we try to avoid those kinds of paths. + Ok(rustc_fs_util::fix_windows_verbatim_for_gcc(&path)) } #[cfg(target_os = "wasi")] @@ -178,10 +183,8 @@ fn current_dll_path() -> Result { } pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { - let target = crate::config::host_tuple(); let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()]; - let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string())); - if let Ok(dll) = path { + if let Ok(dll) = current_dll_path() { // use `parent` twice to chop off the file name and then also the // directory containing the dll which should be either `lib` or `bin`. if let Some(path) = dll.parent().and_then(|p| p.parent()) { @@ -196,7 +199,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { // assume that we may be in the main libdir. sysroot_candidates.push(path.to_owned()); - if path.ends_with(target) { + if path.ends_with(crate::config::host_tuple()) { sysroot_candidates.extend( path.parent() // chop off `$target` .and_then(|p| p.parent()) // chop off `rustlib` @@ -219,17 +222,8 @@ pub fn materialize_sysroot(maybe_sysroot: Option) -> PathBuf { /// This function checks if sysroot is found using env::args().next(), and if it /// is not found, finds sysroot from current rustc_driver dll. pub fn get_or_default_sysroot() -> PathBuf { - // Follow symlinks. If the resolved path is relative, make it absolute. - fn canonicalize(path: PathBuf) -> PathBuf { - let path = try_canonicalize(&path).unwrap_or(path); - // See comments on this target function, but the gist is that - // gcc chokes on verbatim paths which fs::canonicalize generates - // so we try to avoid those kinds of paths. - fix_windows_verbatim_for_gcc(&path) - } - fn default_from_rustc_driver_dll() -> Result { - let dll = current_dll_path().map(|s| canonicalize(s))?; + let dll = current_dll_path()?; // `dll` will be in one of the following two: // - compiler's libdir: $sysroot/lib/*.dll From dff8ee5b01b7251937860da41afd55958c13456a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 5 Jun 2025 16:53:12 +0000 Subject: [PATCH 047/183] Replace all uses of sysroot_candidates with get_or_default_sysroot Before this change we had two different ways to attempt to locate the sysroot which are inconsistently used: * get_or_default_sysroot which tries to locate based on the 0th cli argument and if that doesn't work falls back to locating it using the librustc_driver.so location and returns a single path., * sysroot_candidates which takes the former and additionally does another attempt at locating using librustc_driver.so except without linux multiarch handling and then returns both paths., The latter was originally introduced to be able to locate the codegen backend back when cg_llvm was dynamically linked even for a custom driver when the --sysroot passed in does not contain a copy of cg_llvm. Back then get_or_default_sysroot did not attempt to locate the sysroot based on the location of librustc_driver.so yet. Because that is now done, the only case where removing sysroot_candidates can break things is if you have a custom driver inside what looks like a sysroot including the lib/rustlib directory, but which is missing some parts of the full sysroot like eg rust-lld. --- compiler/rustc_error_messages/src/lib.rs | 4 +-- compiler/rustc_interface/src/interface.rs | 4 +-- compiler/rustc_interface/src/util.rs | 11 ++++--- compiler/rustc_session/src/filesearch.rs | 36 +++++------------------ compiler/rustc_session/src/session.rs | 6 +--- 5 files changed, 17 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 3c6df147b1ba..a1f787b00d98 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -107,7 +107,7 @@ impl From> for TranslationBundleError { #[instrument(level = "trace")] pub fn fluent_bundle( sysroot: PathBuf, - sysroot_candidates: Vec, + default_sysroot: PathBuf, requested_locale: Option, additional_ftl_path: Option<&Path>, with_directionality_markers: bool, @@ -141,7 +141,7 @@ pub fn fluent_bundle( // If the user requests the default locale then don't try to load anything. if let Some(requested_locale) = requested_locale { let mut found_resources = false; - for mut sysroot in Some(sysroot).into_iter().chain(sysroot_candidates.into_iter()) { + for mut sysroot in [sysroot, default_sysroot] { sysroot.push("share"); sysroot.push("locale"); sysroot.push(requested_locale.to_string()); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index cf494f8d686e..068b8c6d0445 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -18,7 +18,7 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; -use rustc_session::filesearch::sysroot_candidates; +use rustc_session::filesearch::get_or_default_sysroot; use rustc_session::parse::ParseSess; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint}; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; @@ -443,7 +443,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let bundle = match rustc_errors::fluent_bundle( config.opts.sysroot.clone(), - sysroot_candidates().to_vec(), + get_or_default_sysroot(), config.opts.unstable_opts.translate_lang.clone(), config.opts.unstable_opts.translate_additional_ftl.as_deref(), config.opts.unstable_opts.translate_directionality_markers, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 087b11fdf9d9..f769c6156aeb 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -2,7 +2,7 @@ use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, OnceLock}; -use std::{env, iter, thread}; +use std::{env, thread}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; @@ -12,7 +12,6 @@ use rustc_metadata::{DylibError, load_symbol_from_dylib}; use rustc_middle::ty::CurrentGcx; use rustc_parse::validate_attr; use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_tuple}; -use rustc_session::filesearch::sysroot_candidates; use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer}; use rustc_session::output::{CRATE_TYPES, categorize_crate_type}; use rustc_session::{EarlyDiagCtxt, Session, filesearch}; @@ -346,7 +345,7 @@ pub fn rustc_path<'a>() -> Option<&'a Path> { } fn get_rustc_path_inner(bin_path: &str) -> Option { - sysroot_candidates().iter().find_map(|sysroot| { + Some(filesearch::get_or_default_sysroot()).iter().find_map(|sysroot| { let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") { "rustc.exe" } else { @@ -374,10 +373,10 @@ fn get_codegen_sysroot( ); let target = host_tuple(); - let sysroot_candidates = sysroot_candidates(); + let sysroot_candidates = filesearch::sysroot_with_fallback(&sysroot); - let sysroot = iter::once(sysroot) - .chain(sysroot_candidates.iter().map(<_>::as_ref)) + let sysroot = sysroot_candidates + .iter() .map(|sysroot| { filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends") }) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 1fd74c914b29..def2cc97f061 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -182,35 +182,13 @@ fn current_dll_path() -> Result { Err("current_dll_path is not supported on WASI".to_string()) } -pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { - let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()]; - if let Ok(dll) = current_dll_path() { - // use `parent` twice to chop off the file name and then also the - // directory containing the dll which should be either `lib` or `bin`. - if let Some(path) = dll.parent().and_then(|p| p.parent()) { - // The original `path` pointed at the `rustc_driver` crate's dll. - // Now that dll should only be in one of two locations. The first is - // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The - // other is the target's libdir, for example - // `$sysroot/lib/rustlib/$target/lib/*.dll`. - // - // We don't know which, so let's assume that if our `path` above - // ends in `$target` we *could* be in the target libdir, and always - // assume that we may be in the main libdir. - sysroot_candidates.push(path.to_owned()); - - if path.ends_with(crate::config::host_tuple()) { - sysroot_candidates.extend( - path.parent() // chop off `$target` - .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| p.parent()) // chop off `lib` - .map(|s| s.to_owned()), - ); - } - } +pub fn sysroot_with_fallback(sysroot: &Path) -> SmallVec<[PathBuf; 2]> { + let mut candidates = smallvec![sysroot.to_owned()]; + let default_sysroot = get_or_default_sysroot(); + if default_sysroot != sysroot { + candidates.push(default_sysroot); } - - sysroot_candidates + candidates } /// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none. @@ -236,7 +214,7 @@ pub fn get_or_default_sysroot() -> PathBuf { dll.display() ))?; - // if `dir` points target's dir, move up to the sysroot + // if `dir` points to target's dir, move up to the sysroot let mut sysroot_dir = if dir.ends_with(crate::config::host_tuple()) { dir.parent() // chop off `$target` .and_then(|p| p.parent()) // chop off `rustlib` diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 010ae42c2802..6b85e0abc868 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -458,13 +458,9 @@ impl Session { /// directories are also returned, for example if `--sysroot` is used but tools are missing /// (#125246): we also add the bin directories to the sysroot where rustc is located. pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec { - let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_tuple()); - let fallback_sysroot_paths = filesearch::sysroot_candidates() + let search_paths = filesearch::sysroot_with_fallback(&self.sysroot) .into_iter() - // Ignore sysroot candidate if it was the same as the sysroot path we just used. - .filter(|sysroot| *sysroot != self.sysroot) .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_tuple())); - let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths); if self_contained { // The self-contained tools are expected to be e.g. in `bin/self-contained` in the From e1567dff243135a84f8e348528da782bee1d13e9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 5 Jun 2025 17:02:49 +0000 Subject: [PATCH 048/183] Make root vars more stable --- compiler/rustc_infer/src/infer/type_variable.rs | 3 +++ compiler/rustc_infer/src/infer/unify_key.rs | 3 +++ compiler/rustc_type_ir/src/ty_kind.rs | 17 ----------------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 2086483b94a7..6f6791804d32 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -238,6 +238,9 @@ impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> { fn tag() -> &'static str { "TyVidEqKey" } + fn order_roots(a: Self, _: &Self::Value, b: Self, _: &Self::Value) -> Option<(Self, Self)> { + if a.vid.as_u32() < b.vid.as_u32() { Some((a, b)) } else { Some((b, a)) } + } } impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { diff --git a/compiler/rustc_infer/src/infer/unify_key.rs b/compiler/rustc_infer/src/infer/unify_key.rs index 3ba8aea1d3a0..5e5d0e063a0d 100644 --- a/compiler/rustc_infer/src/infer/unify_key.rs +++ b/compiler/rustc_infer/src/infer/unify_key.rs @@ -137,6 +137,9 @@ impl<'tcx> UnifyKey for ConstVidKey<'tcx> { fn tag() -> &'static str { "ConstVidKey" } + fn order_roots(a: Self, _: &Self::Value, b: Self, _: &Self::Value) -> Option<(Self, Self)> { + if a.vid.as_u32() < b.vid.as_u32() { Some((a, b)) } else { Some((b, a)) } + } } impl<'tcx> UnifyValue for ConstVariableValue<'tcx> { diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 0cd98b5aa53b..9669772d1a68 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -771,23 +771,6 @@ pub enum InferTy { FreshFloatTy(u32), } -/// Raw `TyVid` are used as the unification key for `sub_relations`; -/// they carry no values. -impl UnifyKey for TyVid { - type Value = (); - #[inline] - fn index(&self) -> u32 { - self.as_u32() - } - #[inline] - fn from_index(i: u32) -> TyVid { - TyVid::from_u32(i) - } - fn tag() -> &'static str { - "TyVid" - } -} - impl UnifyValue for IntVarValue { type Error = NoError; From 38d69c3f571b668c82cfb90e5bea8bc86530530c Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 9 Jan 2025 20:35:49 +0800 Subject: [PATCH 049/183] Add new Tier-3 targets: `loongarch32-unknown-none*` MCP: https://github.com/rust-lang/compiler-team/issues/865 --- .../rustc_codegen_gcc/example/alloc_system.rs | 1 + compiler/rustc_codegen_llvm/src/asm.rs | 2 +- .../src/back/link/raw_dylib.rs | 1 + .../rustc_codegen_ssa/src/back/metadata.rs | 2 +- compiler/rustc_target/src/asm/mod.rs | 14 ++++-- compiler/rustc_target/src/callconv/mod.rs | 4 +- compiler/rustc_target/src/spec/mod.rs | 3 ++ .../spec/targets/loongarch32_unknown_none.rs | 29 +++++++++++++ .../loongarch32_unknown_none_softfloat.rs | 30 +++++++++++++ compiler/rustc_target/src/target_features.rs | 6 +-- library/core/Cargo.toml | 2 + library/core/src/sync/atomic.rs | 10 +++-- library/std/Cargo.toml | 2 + library/std/src/env.rs | 1 + library/std/src/os/linux/raw.rs | 1 + library/std/src/sys/alloc/mod.rs | 1 + library/std/src/sys/personality/gcc.rs | 2 +- library/unwind/Cargo.toml | 2 +- library/unwind/src/libunwind.rs | 2 +- src/bootstrap/bootstrap.py | 1 + src/bootstrap/src/core/sanity.rs | 2 + src/doc/rustc/src/platform-support.md | 2 + .../src/platform-support/loongarch-none.md | 43 +++++++++++++------ src/librustdoc/clean/cfg.rs | 1 + src/tools/build-manifest/src/main.rs | 2 + src/tools/compiletest/src/common.rs | 1 + src/tools/compiletest/src/directive-list.rs | 2 + src/tools/miri/src/shims/alloc.rs | 5 ++- tests/assembly/targets/targets-elf.rs | 6 +++ tests/ui/check-cfg/well-known-values.stderr | 2 +- 30 files changed, 149 insertions(+), 33 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs create mode 100644 compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 945d34063a63..4d70122496b7 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -8,6 +8,7 @@ // add fast paths for low alignment values. #[cfg(any(target_arch = "x86", target_arch = "arm", + target_arch = "loongarch32", target_arch = "m68k", target_arch = "mips", target_arch = "mips32r6", diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 9e3893d5314a..4185aef8b31c 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -251,7 +251,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { InlineAsmArch::Nvptx64 => {} InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {} InlineAsmArch::Hexagon => {} - InlineAsmArch::LoongArch64 => { + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { constraints.extend_from_slice(&[ "~{$fcc0}".to_string(), "~{$fcc1}".to_string(), diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 2c24378afe13..74f39022afb7 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -287,6 +287,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] (Architecture::X86_64, None) => elf::EM_X86_64, (Architecture::X86_64_X32, None) => elf::EM_X86_64, (Architecture::Hexagon, None) => elf::EM_HEXAGON, + (Architecture::LoongArch32, None) => elf::EM_LOONGARCH, (Architecture::LoongArch64, None) => elf::EM_LOONGARCH, (Architecture::M68k, None) => elf::EM_68K, (Architecture::Mips, None) => elf::EM_MIPS, diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index ec46c71b0e40..a16862c41ee5 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -348,7 +348,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { e_flags } - Architecture::LoongArch64 => { + Architecture::LoongArch32 | Architecture::LoongArch64 => { // Source: https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#e_flags-identifies-abi-type-and-version let mut e_flags: u32 = elf::EF_LARCH_OBJABI_V1; diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 9f791603c723..e06f881e4b1c 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -226,6 +226,7 @@ pub enum InlineAsmArch { RiscV64, Nvptx64, Hexagon, + LoongArch32, LoongArch64, Mips, Mips64, @@ -260,6 +261,7 @@ impl FromStr for InlineAsmArch { "powerpc" => Ok(Self::PowerPC), "powerpc64" => Ok(Self::PowerPC64), "hexagon" => Ok(Self::Hexagon), + "loongarch32" => Ok(Self::LoongArch32), "loongarch64" => Ok(Self::LoongArch64), "mips" | "mips32r6" => Ok(Self::Mips), "mips64" | "mips64r6" => Ok(Self::Mips64), @@ -365,7 +367,9 @@ impl InlineAsmReg { Self::PowerPC(PowerPCInlineAsmReg::parse(name)?) } InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?), - InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?), + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { + Self::LoongArch(LoongArchInlineAsmReg::parse(name)?) + } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmReg::parse(name)?) } @@ -652,7 +656,9 @@ impl InlineAsmRegClass { Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?) } InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?), - InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?), + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { + Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?) + } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmRegClass::parse(name)?) } @@ -860,7 +866,7 @@ pub fn allocatable_registers( hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } - InlineAsmArch::LoongArch64 => { + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => { let mut map = loongarch::regclass_map(); loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map @@ -992,7 +998,7 @@ impl InlineAsmClobberAbi { "C" | "system" => Ok(InlineAsmClobberAbi::Avr), _ => Err(&["C", "system"]), }, - InlineAsmArch::LoongArch64 => match name { + InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name { "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch), _ => Err(&["C", "system"]), }, diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index d2e49cea647b..d595fa45fb65 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -648,7 +648,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), "avr" => avr::compute_abi_info(self), - "loongarch64" => loongarch::compute_abi_info(cx, self), + "loongarch32" | "loongarch64" => loongarch::compute_abi_info(cx, self), "m68k" => m68k::compute_abi_info(self), "csky" => csky::compute_abi_info(self), "mips" | "mips32r6" => mips::compute_abi_info(cx, self), @@ -691,7 +691,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { match &*spec.arch { "x86" => x86::compute_rust_abi_info(cx, self), "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self), - "loongarch64" => loongarch::compute_rust_abi_info(cx, self), + "loongarch32" | "loongarch64" => loongarch::compute_rust_abi_info(cx, self), "aarch64" => aarch64::compute_rust_abi_info(cx, self), _ => {} }; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 6529c2d72c82..b7916df77c8c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1981,6 +1981,8 @@ supported_targets! { ("sparc-unknown-none-elf", sparc_unknown_none_elf), + ("loongarch32-unknown-none", loongarch32_unknown_none), + ("loongarch32-unknown-none-softfloat", loongarch32_unknown_none_softfloat), ("loongarch64-unknown-none", loongarch64_unknown_none), ("loongarch64-unknown-none-softfloat", loongarch64_unknown_none_softfloat), @@ -3502,6 +3504,7 @@ impl Target { "msp430" => (Architecture::Msp430, None), "hexagon" => (Architecture::Hexagon, None), "bpf" => (Architecture::Bpf, None), + "loongarch32" => (Architecture::LoongArch32, None), "loongarch64" => (Architecture::LoongArch64, None), "csky" => (Architecture::Csky, None), "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)), diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs new file mode 100644 index 000000000000..fb4963b88b0f --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none.rs @@ -0,0 +1,29 @@ +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, +}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "loongarch32-unknown-none".into(), + metadata: TargetMetadata { + description: Some("Freestanding/bare-metal LoongArch32".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), + arch: "loongarch32".into(), + options: TargetOptions { + cpu: "generic".into(), + features: "+f,+d".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + llvm_abiname: "ilp32d".into(), + max_atomic_width: Some(32), + relocation_model: RelocModel::Static, + panic_strategy: PanicStrategy::Abort, + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs new file mode 100644 index 000000000000..0e65f83a71cf --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/loongarch32_unknown_none_softfloat.rs @@ -0,0 +1,30 @@ +use crate::spec::{ + Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, TargetOptions, +}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "loongarch32-unknown-none".into(), + metadata: TargetMetadata { + description: Some("Freestanding/bare-metal LoongArch32 softfloat".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(), + arch: "loongarch32".into(), + options: TargetOptions { + cpu: "generic".into(), + features: "-f,-d".into(), + abi: "softfloat".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), + llvm_abiname: "ilp32s".into(), + max_atomic_width: Some(32), + relocation_model: RelocModel::Static, + panic_strategy: PanicStrategy::Abort, + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 682c4c5068f9..c1f128fdc87a 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -846,7 +846,7 @@ impl Target { "wasm32" | "wasm64" => WASM_FEATURES, "bpf" => BPF_FEATURES, "csky" => CSKY_FEATURES, - "loongarch64" => LOONGARCH_FEATURES, + "loongarch32" | "loongarch64" => LOONGARCH_FEATURES, "s390x" => IBMZ_FEATURES, "sparc" | "sparc64" => SPARC_FEATURES, "m68k" => M68K_FEATURES, @@ -860,7 +860,7 @@ impl Target { "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI, "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI, "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI, - "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, + "loongarch32" | "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI, "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI, "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI, "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI, @@ -1034,7 +1034,7 @@ impl Target { _ => unreachable!(), } } - "loongarch64" => { + "loongarch32" | "loongarch64" => { // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname` // about what the intended ABI is. match &*self.llvm_abiname { diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index f88661ee0015..5d65b55bcdab 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -29,6 +29,8 @@ debug_typeid = [] [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ + # #[cfg(bootstrap)] loongarch32 + 'cfg(target_arch, values("loongarch32"))', 'cfg(no_fp_fmt_parse)', # core use #[path] imports to portable-simd `core_simd` crate # and to stdarch `core_arch` crate which messes-up with Cargo list diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index ea459f6d92d8..e07a372943c5 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -178,7 +178,7 @@ //! //! | `target_arch` | Size limit | //! |---------------|---------| -//! | `x86`, `arm`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes | +//! | `x86`, `arm`, `loongarch32`, `mips`, `mips32r6`, `powerpc`, `riscv32`, `sparc`, `hexagon` | 4 bytes | //! | `x86_64`, `aarch64`, `loongarch64`, `mips64`, `mips64r6`, `powerpc64`, `riscv64`, `sparc64`, `s390x` | 8 bytes | //! //! Atomics loads that are larger than this limit as well as atomic loads with ordering other @@ -349,8 +349,12 @@ pub type Atomic = ::AtomicInner; // This list should only contain architectures which have word-sized atomic-or/ // atomic-and instructions but don't natively support byte-sized atomics. #[cfg(target_has_atomic = "8")] -const EMULATE_ATOMIC_BOOL: bool = - cfg!(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "loongarch64")); +const EMULATE_ATOMIC_BOOL: bool = cfg!(any( + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "loongarch32", + target_arch = "loongarch64" +)); /// A boolean type which can be safely shared between threads. /// diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 196b904d56a1..0419336e13a2 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -157,6 +157,8 @@ test = true [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ + # #[cfg(bootstrap)] loongarch32 + 'cfg(target_arch, values("loongarch32"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/std/src/env.rs b/library/std/src/env.rs index ce2dc7952207..6d7d576b32a1 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -1046,6 +1046,7 @@ pub mod consts { /// * `"sparc"` /// * `"sparc64"` /// * `"hexagon"` + /// * `"loongarch32"` /// * `"loongarch64"` /// /// diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index d53674d3c5f2..6483f0861139 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -231,6 +231,7 @@ mod arch { } #[cfg(any( + target_arch = "loongarch32", target_arch = "loongarch64", target_arch = "mips64", target_arch = "mips64r6", diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 8489e17c971d..f3af1f7f5991 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -17,6 +17,7 @@ const MIN_ALIGN: usize = if cfg!(any( target_arch = "arm", target_arch = "m68k", target_arch = "csky", + target_arch = "loongarch32", target_arch = "mips", target_arch = "mips32r6", target_arch = "powerpc", diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index b012e47f9aa2..75e793f18b83 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -86,7 +86,7 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 #[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))] const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11 -#[cfg(target_arch = "loongarch64")] +#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1 // The following code is based on GCC's C and C++ personality routines. For reference, see: diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index df43e6ae80fb..0db3f7450f17 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -37,4 +37,4 @@ system-llvm-libunwind = [] [lints.rust.unexpected_cfgs] level = "warn" -check-cfg = ['cfg(emscripten_wasm_eh)'] +check-cfg = ['cfg(emscripten_wasm_eh)', 'cfg(target_arch, values("loongarch32"))'] diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 12582569a573..b350003cbb19 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -81,7 +81,7 @@ pub const unwinder_private_data_size: usize = 2; #[cfg(all(target_arch = "hexagon", target_os = "linux"))] pub const unwinder_private_data_size: usize = 35; -#[cfg(target_arch = "loongarch64")] +#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] pub const unwinder_private_data_size: usize = 2; #[repr(C)] diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index c60c6b8db640..d8c6be782477 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -394,6 +394,7 @@ def default_build_triple(verbose): "i686": "i686", "i686-AT386": "i686", "i786": "i686", + "loongarch32": "loongarch32", "loongarch64": "loongarch64", "m68k": "m68k", "csky": "csky", diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index af4ec679d080..59ae303e21e8 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,6 +34,8 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e7dfaaf4fd5d..e2e2ad9ac3b5 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -324,6 +324,8 @@ target | std | host | notes [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] [^win32-msvc-alignment] [`i686-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [^x86_32-floats-return-ABI] [`loongarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | LoongArch64 OpenHarmony +[`loongarch32-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch32 Bare-metal (ILP32D ABI) +[`loongarch32-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch32 Bare-metal (ILP32S ABI) [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux [`m68k-unknown-none-elf`](platform-support/m68k-unknown-none-elf.md) | | | Motorola 680x0 `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index a2bd6e5734cd..fd90b0a27638 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -1,18 +1,18 @@ # `loongarch*-unknown-none*` -**Tier: 2** +Freestanding/bare-metal LoongArch binaries in ELF format: firmware, kernels, etc. -Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc. - -| Target | Description | -|--------|-------------| -| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | -| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | +| Target | Description | Tier | +|--------|-------------|------| +| `loongarch32-unknown-none` | LoongArch 32-bit, ILP32D ABI (freestanding, hard-float) | Tier 3 | +| `loongarch32-unknown-none-softfloat` | LoongArch 32-bit, ILP32S ABI (freestanding, soft-float) | Tier 3 | +| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | Tier 2 | +| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | Tier 2 | ## Target maintainers -[@heiher](https://github.com/heiher) -[@xen0n](https://github.com/xen0n) +- [@heiher](https://github.com/heiher) +- [@xen0n](https://github.com/xen0n) ## Requirements @@ -29,13 +29,13 @@ additional CPU features via the `-C target-feature=` codegen options to rustc, o via the `#[target_feature]` mechanism within Rust code. By default, code generated with the soft-float target should run on any -LoongArch64 hardware, with the hard-float target additionally requiring an FPU; +LoongArch hardware, with the hard-float target additionally requiring an FPU; enabling additional target features may raise this baseline. Code generated with the targets will use the `medium` code model by default. You can change this using the `-C code-model=` option to rustc. -On `loongarch64-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. +On `loongarch*-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. [lapcs]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc @@ -52,6 +52,8 @@ list in `bootstrap.toml`: [build] build-stage = 1 target = [ + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", "loongarch64-unknown-none", "loongarch64-unknown-none-softfloat", ] @@ -64,13 +66,28 @@ As the targets support a variety of different environments and do not support ## Building Rust programs +### loongarch32-unknown-none* + +The `loongarch32-unknown-none*` targets are Tier 3, so you must build the Rust +compiler from source to use them. + +```sh +# target flag may be used with any cargo or rustc command +cargo build --target loongarch32-unknown-none +cargo build --target loongarch32-unknown-none-softfloat +``` + +### loongarch64-unknown-none* + Starting with Rust 1.74, precompiled artifacts are provided via `rustup`: ```sh # install cross-compile toolchain rustup target add loongarch64-unknown-none +rustup target add loongarch64-unknown-none-softfloat # target flag may be used with any cargo or rustc command cargo build --target loongarch64-unknown-none +cargo build --target loongarch64-unknown-none-softfloat ``` ## Cross-compilation toolchains and C code @@ -79,10 +96,10 @@ For cross builds, you will need an appropriate LoongArch C/C++ toolchain for linking, or if you want to compile C code along with Rust (such as for Rust crates with C dependencies). -Rust *may* be able to use an `loongarch64-unknown-linux-gnu-` toolchain with +Rust *may* be able to use an `loongarch{32,64}-unknown-linux-{gnu,musl}-` toolchain with appropriate standalone flags to build for this toolchain (depending on the assumptions of that toolchain, see below), or you may wish to use a separate -`loongarch64-unknown-none` toolchain. +`loongarch{32,64}-unknown-none` toolchain. On some LoongArch hosts that use ELF binaries, you *may* be able to use the host C toolchain, if it does not introduce assumptions about the host environment diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index ebc276b38fbf..a3762e4117d1 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -508,6 +508,7 @@ impl fmt::Display for Display<'_> { (sym::target_arch, Some(arch)) => match arch.as_str() { "aarch64" => "AArch64", "arm" => "ARM", + "loongarch32" => "LoongArch LA32", "loongarch64" => "LoongArch LA64", "m68k" => "M68k", "csky" => "CSKY", diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 741d7e3fa16c..c85f2c9442bd 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -111,6 +111,8 @@ static TARGETS: &[&str] = &[ "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", "loongarch64-unknown-linux-musl", + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", "loongarch64-unknown-none", "loongarch64-unknown-none-softfloat", "m68k-unknown-linux-gnu", diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 4f93b4987413..9b9d94bbead0 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -495,6 +495,7 @@ impl Config { "arm64ec", "riscv32", "riscv64", + "loongarch32", "loongarch64", "s390x", // These targets require an additional asm_experimental_arch feature. diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 5757e422ae21..1406553c9ea7 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -73,6 +73,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-linux", "ignore-lldb", "ignore-llvm-version", + "ignore-loongarch32", "ignore-loongarch64", "ignore-macabi", "ignore-macos", @@ -196,6 +197,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-i686-unknown-linux-gnu", "only-ios", "only-linux", + "only-loongarch32", "only-loongarch64", "only-loongarch64-unknown-linux-gnu", "only-macos", diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 323b95d5f5f2..d7bb16f0858d 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -13,10 +13,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // alignment requirement and size less than or equal to the size requested." // So first we need to figure out what the limits are for "fundamental alignment". // This is given by `alignof(max_align_t)`. The following list is taken from - // `library/std/src/sys/pal/common/alloc.rs` (where this is called `MIN_ALIGN`) and should + // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should // be kept in sync. let max_fundamental_align = match this.tcx.sess.target.arch.as_ref() { - "x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "wasm32" => 8, + "x86" | "arm" | "loongarch32" | "mips" | "mips32r6" | "powerpc" | "powerpc64" + | "wasm32" => 8, "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" => 16, arch => bug!("unsupported target architecture for malloc: `{}`", arch), diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 325559111949..edf16548e7de 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -259,6 +259,12 @@ //@ revisions: i686_wrs_vxworks //@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks //@ [i686_wrs_vxworks] needs-llvm-components: x86 +//@ revisions: loongarch32_unknown_none +//@ [loongarch32_unknown_none] compile-flags: --target loongarch32-unknown-none +//@ [loongarch32_unknown_none] needs-llvm-components: loongarch +//@ revisions: loongarch32_unknown_none_softfloat +//@ [loongarch32_unknown_none_softfloat] compile-flags: --target loongarch32-unknown-none-softfloat +//@ [loongarch32_unknown_none_softfloat] needs-llvm-components: loongarch //@ revisions: loongarch64_unknown_linux_gnu //@ [loongarch64_unknown_linux_gnu] compile-flags: --target loongarch64-unknown-linux-gnu //@ [loongarch64_unknown_linux_gnu] needs-llvm-components: loongarch diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 7cda6c2eaa52..532c1ab13d11 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -138,7 +138,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa` + = note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch32`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From 0713466a2e7ce9a162de32f920700d81f2882eae Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 6 Jun 2025 03:52:32 +0300 Subject: [PATCH 050/183] Always include quickfixes for diagnostics, even when diagnostics are disabled --- .../rust-analyzer/crates/rust-analyzer/src/config.rs | 10 ++++++++++ .../crates/rust-analyzer/src/handlers/request.rs | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 96be6726ccb1..5cbea9c2b3d9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -1597,6 +1597,16 @@ impl Config { term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(), } } + + pub fn diagnostic_fixes(&self, source_root: Option) -> DiagnosticsConfig { + // We always want to show quickfixes for diagnostics, even when diagnostics/experimental diagnostics are disabled. + DiagnosticsConfig { + enabled: true, + disable_experimental: false, + ..self.diagnostics(source_root) + } + } + pub fn expand_proc_attr_macros(&self) -> bool { self.procMacro_enable().to_owned() && self.procMacro_attributes_enable().to_owned() } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 69983a676261..6d46ce68ed47 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -1439,7 +1439,7 @@ pub(crate) fn handle_code_action( }; let assists = snap.analysis.assists_with_fixes( &assists_config, - &snap.config.diagnostics(Some(source_root)), + &snap.config.diagnostic_fixes(Some(source_root)), resolve, frange, )?; @@ -1530,7 +1530,7 @@ pub(crate) fn handle_code_action_resolve( let assists = snap.analysis.assists_with_fixes( &assists_config, - &snap.config.diagnostics(Some(source_root)), + &snap.config.diagnostic_fixes(Some(source_root)), AssistResolveStrategy::Single(assist_resolve), frange, )?; From 903a0db6f33b072ba37f7512fe732a8e12e158d4 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 6 Jun 2025 03:55:57 +0300 Subject: [PATCH 051/183] Stabilize unlinked file diagnostic --- .../crates/ide-diagnostics/src/handlers/unlinked_file.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs index af9126c89331..d96c658d7b04 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -69,6 +69,7 @@ pub(crate) fn unlinked_file( FileRange { file_id, range }, ) .with_unused(unused) + .stable() .with_fixes(fixes), ); } From 8c410ca291a68bf23ca3694b1bbda631323b12cd Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 6 Jun 2025 04:55:10 +0000 Subject: [PATCH 052/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 437d4218cfad..1e97cdf5bde9 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -81a964c23ea4fe9ab52b4449bb166bf280035797 +cf423712b9e95e9f6ec84b1ecb3d125e55ac8d56 From e90b3fb51f2e5c5c7e65480b1a456b71249a24da Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Jun 2025 06:13:15 +0200 Subject: [PATCH 053/183] fix: Record macro calls for fields in `ChildBySource` impls --- .../hir/src/semantics/child_by_source.rs | 20 +++++++++---------- .../crates/ide/src/expand_macro.rs | 17 ++++++++++++++++ .../rust-analyzer/tests/slow-tests/ratoml.rs | 1 + 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index a150df70502b..1a6d63c88c62 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -191,6 +191,8 @@ impl ChildBySource for VariantId { Either::Right(source) => res[keys::RECORD_FIELD].insert(AstPtr::new(&source), id), } } + let (_, sm) = db.variant_fields_with_source_map(*self); + sm.expansions().for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id)); } } @@ -209,11 +211,10 @@ impl ChildBySource for EnumId { .insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant); }); let (_, source_map) = db.enum_signature_with_source_map(*self); - source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( - |(ast, &exp_id)| { - res[keys::MACRO_CALL].insert(ast.value, exp_id); - }, - ); + source_map + .expansions() + .filter(|(ast, _)| ast.file_id == file_id) + .for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id)); } } @@ -274,11 +275,10 @@ impl ChildBySource for GenericDefId { } } - source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each( - |(ast, &exp_id)| { - res[keys::MACRO_CALL].insert(ast.value, exp_id); - }, - ); + source_map + .expansions() + .filter(|(ast, _)| ast.file_id == file_id) + .for_each(|(ast, &exp_id)| res[keys::MACRO_CALL].insert(ast.value, exp_id)); } } diff --git a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 1c09bd5d0c0a..f31886b96976 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs @@ -844,4 +844,21 @@ impl Trait for () {} Trait"#]], ); } + + #[test] + fn works_in_fields() { + check( + r#" +macro_rules! foo { + () => { u32 }; +} +struct S { + field: foo$0!(), +} +"#, + expect![[r#" + foo! + u32"#]], + ); + } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs index 485f32281dde..cac7efd84aaf 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/ratoml.rs @@ -439,6 +439,7 @@ assist.emitMustUse = true"#, } #[test] +#[ignore = "flaky test that tends to hang"] fn ratoml_inherit_config_from_ws_root() { if skip_slow_tests() { return; From d945c8562b49df98af25ed43b41bdbc59b8385cc Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 5 Jun 2025 23:09:28 -0700 Subject: [PATCH 054/183] compiler: Add track_caller to AbiMapping::unwrap Same reason as it is on Option's. --- compiler/rustc_target/src/spec/abi_map.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index d9101f79f046..be94e18dc397 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -29,6 +29,7 @@ impl AbiMapping { } } + #[track_caller] pub fn unwrap(self) -> CanonAbi { self.into_option().unwrap() } From 338216927a4566679752513d4d19b8ae54d099c4 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 6 Jun 2025 14:51:35 +0800 Subject: [PATCH 055/183] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 64a12460708c..fc1518ef02b7 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 64a12460708cf146e16cc61f28aba5dc2463bbb4 +Subproject commit fc1518ef02b77327d70d4026b95ea719dd9b8c51 From b1652dc7d53e24196d3745f6196411c61ccd53fa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 5 Jun 2025 18:52:26 +0200 Subject: [PATCH 056/183] use File::lock to implement flock, and add a test for File::lock --- src/tools/miri/Cargo.lock | 1 - src/tools/miri/Cargo.toml | 7 -- src/tools/miri/src/lib.rs | 1 + src/tools/miri/src/shims/unix/fs.rs | 113 +++++--------------------- src/tools/miri/tests/pass/shims/fs.rs | 33 +++++++- 5 files changed, 50 insertions(+), 105 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 6f4bd3eab51a..192d4f444c2f 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -555,7 +555,6 @@ dependencies = [ "tempfile", "tikv-jemalloc-sys", "ui_test", - "windows-sys", ] [[package]] diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index e4d7abdb0f73..a314488bb253 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -40,13 +40,6 @@ libc = "0.2" libffi = "4.0.0" libloading = "0.8" -[target.'cfg(target_family = "windows")'.dependencies] -windows-sys = { version = "0.59", features = [ - "Win32_Foundation", - "Win32_System_IO", - "Win32_Storage_FileSystem", -] } - [dev-dependencies] ui_test = "0.29.1" colored = "2" diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 51ec19af52a0..dfefe2f4b052 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -16,6 +16,7 @@ #![feature(unqualified_local_imports)] #![feature(derive_coerce_pointee)] #![feature(arbitrary_self_types)] +#![feature(file_lock)] // Configure clippy and other lints #![allow( clippy::collapsible_else_if, diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 31cb269059c1..0f7d453b296c 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -2,7 +2,8 @@ use std::borrow::Cow; use std::fs::{ - DirBuilder, File, FileType, OpenOptions, ReadDir, read_dir, remove_dir, remove_file, rename, + DirBuilder, File, FileType, OpenOptions, ReadDir, TryLockError, read_dir, remove_dir, + remove_file, rename, }; use std::io::{self, ErrorKind, Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; @@ -89,103 +90,27 @@ impl UnixFileDescription for FileHandle { communicate_allowed: bool, op: FlockOp, ) -> InterpResult<'tcx, io::Result<()>> { - // cfg(bootstrap) - macro_rules! cfg_select_dispatch { - ($($tokens:tt)*) => { - #[cfg(bootstrap)] - cfg_match! { $($tokens)* } - - #[cfg(not(bootstrap))] - cfg_select! { $($tokens)* } - }; - } - assert!(communicate_allowed, "isolation should have prevented even opening a file"); - cfg_select_dispatch! { - all(target_family = "unix", not(target_os = "solaris")) => { - use std::os::fd::AsRawFd; - use FlockOp::*; - // We always use non-blocking call to prevent interpreter from being blocked - let (host_op, lock_nb) = match op { - SharedLock { nonblocking } => (libc::LOCK_SH | libc::LOCK_NB, nonblocking), - ExclusiveLock { nonblocking } => (libc::LOCK_EX | libc::LOCK_NB, nonblocking), - Unlock => (libc::LOCK_UN, false), - }; - - let fd = self.file.as_raw_fd(); - let ret = unsafe { libc::flock(fd, host_op) }; - let res = match ret { - 0 => Ok(()), - -1 => { - let err = io::Error::last_os_error(); - if !lock_nb && err.kind() == io::ErrorKind::WouldBlock { - throw_unsup_format!("blocking `flock` is not currently supported"); - } - Err(err) - } - ret => panic!("Unexpected return value from flock: {ret}"), - }; - interp_ok(res) + use FlockOp::*; + // We must not block the interpreter loop, so we always `try_lock`. + let (res, nonblocking) = match op { + SharedLock { nonblocking } => (self.file.try_lock_shared(), nonblocking), + ExclusiveLock { nonblocking } => (self.file.try_lock(), nonblocking), + Unlock => { + return interp_ok(self.file.unlock()); } - target_family = "windows" => { - use std::os::windows::io::AsRawHandle; + }; - use windows_sys::Win32::Foundation::{ - ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, TRUE, - }; - use windows_sys::Win32::Storage::FileSystem::{ - LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, LockFileEx, UnlockFile, - }; - - let fh = self.file.as_raw_handle(); - - use FlockOp::*; - let (ret, lock_nb) = match op { - SharedLock { nonblocking } | ExclusiveLock { nonblocking } => { - // We always use non-blocking call to prevent interpreter from being blocked - let mut flags = LOCKFILE_FAIL_IMMEDIATELY; - if matches!(op, ExclusiveLock { .. }) { - flags |= LOCKFILE_EXCLUSIVE_LOCK; - } - let ret = unsafe { LockFileEx(fh, flags, 0, !0, !0, &mut std::mem::zeroed()) }; - (ret, nonblocking) - } - Unlock => { - let ret = unsafe { UnlockFile(fh, 0, 0, !0, !0) }; - (ret, false) - } - }; - - let res = match ret { - TRUE => Ok(()), - FALSE => { - let mut err = io::Error::last_os_error(); - // This only runs on Windows hosts so we can use `raw_os_error`. - // We have to be careful not to forward that error code to target code. - let code: u32 = err.raw_os_error().unwrap().try_into().unwrap(); - if matches!(code, ERROR_IO_PENDING | ERROR_LOCK_VIOLATION) { - if lock_nb { - // The io error mapping does not know about these error codes, - // so we translate it to `WouldBlock` manually. - let desc = format!("LockFileEx wouldblock error: {err}"); - err = io::Error::new(io::ErrorKind::WouldBlock, desc); - } else { - throw_unsup_format!("blocking `flock` is not currently supported"); - } - } - Err(err) - } - _ => panic!("Unexpected return value: {ret}"), - }; - interp_ok(res) - } - _ => { - let _ = op; - throw_unsup_format!( - "flock is supported only on UNIX (except Solaris) and Windows hosts" - ); - } + match res { + Ok(()) => interp_ok(Ok(())), + Err(TryLockError::Error(err)) => interp_ok(Err(err)), + Err(TryLockError::WouldBlock) => + if nonblocking { + interp_ok(Err(ErrorKind::WouldBlock.into())) + } else { + throw_unsup_format!("blocking `flock` is not currently supported"); + }, } } } diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 87df43ca7e57..2f30827c9336 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -2,12 +2,12 @@ #![feature(io_error_more)] #![feature(io_error_uncategorized)] +#![feature(file_lock)] use std::collections::BTreeMap; use std::ffi::OsString; use std::fs::{ - File, OpenOptions, canonicalize, create_dir, read_dir, remove_dir, remove_dir_all, remove_file, - rename, + self, File, OpenOptions, create_dir, read_dir, remove_dir, remove_dir_all, remove_file, rename, }; use std::io::{Error, ErrorKind, IsTerminal, Read, Result, Seek, SeekFrom, Write}; use std::path::Path; @@ -33,6 +33,8 @@ fn main() { test_canonicalize(); #[cfg(unix)] test_pread_pwrite(); + #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] + test_flock(); } } @@ -240,7 +242,7 @@ fn test_canonicalize() { let path = dir_path.join("test_file"); drop(File::create(&path).unwrap()); - let p = canonicalize(format!("{}/./test_file", dir_path.to_string_lossy())).unwrap(); + let p = fs::canonicalize(format!("{}/./test_file", dir_path.to_string_lossy())).unwrap(); assert_eq!(p.to_string_lossy().find("/./"), None); remove_dir_all(&dir_path).unwrap(); @@ -351,3 +353,28 @@ fn test_pread_pwrite() { f.read_exact(&mut buf1).unwrap(); assert_eq!(&buf1, b" m"); } + +// This function does seem to exist on Illumos but std does not expose it there. +#[cfg(not(any(target_os = "solaris", target_os = "illumos")))] +fn test_flock() { + let bytes = b"Hello, World!\n"; + let path = utils::prepare_with_content("miri_test_fs_flock.txt", bytes); + let file1 = OpenOptions::new().read(true).write(true).open(&path).unwrap(); + let file2 = OpenOptions::new().read(true).write(true).open(&path).unwrap(); + + // Test that we can apply many shared locks + file1.lock_shared().unwrap(); + file2.lock_shared().unwrap(); + // Test that shared lock prevents exclusive lock + assert!(matches!(file1.try_lock().unwrap_err(), fs::TryLockError::WouldBlock)); + // Unlock shared lock + file1.unlock().unwrap(); + file2.unlock().unwrap(); + // Take exclusive lock + file1.lock().unwrap(); + // Test that shared lock prevents exclusive and shared locks + assert!(matches!(file2.try_lock().unwrap_err(), fs::TryLockError::WouldBlock)); + assert!(matches!(file2.try_lock_shared().unwrap_err(), fs::TryLockError::WouldBlock)); + // Unlock exclusive lock + file1.unlock().unwrap(); +} From dc14e732326df21d4889cc2bef8318f77f1092a7 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sun, 27 Apr 2025 21:20:38 +0200 Subject: [PATCH 057/183] Delete unused variant and document AttributeKind --- .../src/attributes.rs | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index d2d1285b0756..845e4d5e5d0f 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -57,14 +57,6 @@ impl OptimizeAttr { } } -#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic, PrintAttribute)] -pub enum DiagnosticAttribute { - // tidy-alphabetical-start - DoNotRecommend, - OnUnimplemented, - // tidy-alphabetical-end -} - #[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)] pub enum ReprAttr { ReprInt(IntType), @@ -160,40 +152,52 @@ impl Deprecation { #[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] pub enum AttributeKind { // tidy-alphabetical-start + /// Represents `#[rustc_allow_const_fn_unstable]`. AllowConstFnUnstable(ThinVec), + + /// Represents `#[allow_internal_unstable]`. AllowInternalUnstable(ThinVec<(Symbol, Span)>), + + /// Represents `#[rustc_default_body_unstable]`. BodyStability { stability: DefaultBodyStability, /// Span of the `#[rustc_default_body_unstable(...)]` attribute span: Span, }, + + /// Represents `#[rustc_confusables]`. Confusables { symbols: ThinVec, // FIXME(jdonszelmann): remove when target validation code is moved first_span: Span, }, + + /// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`. ConstStability { stability: PartialConstStability, /// Span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` attribute span: Span, }, + + /// Represents `#[rustc_const_stable_indirect]`. ConstStabilityIndirect, - Deprecation { - deprecation: Deprecation, - span: Span, - }, - Diagnostic(DiagnosticAttribute), - DocComment { - style: AttrStyle, - kind: CommentKind, - span: Span, - comment: Symbol, - }, + + /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). + Deprecation { deprecation: Deprecation, span: Span }, + + /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). + DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, + + /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), + + /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr(ThinVec<(ReprAttr, Span)>), + + /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. Stability { stability: Stability, - /// Span of the `#[stable(...)]` or `#[unstable(...)]` attribute + /// Span of the attribute. span: Span, }, // tidy-alphabetical-end From 5fdacfe1b7a99ddd5b850cc9a1cdc006da0c62b4 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sun, 27 Apr 2025 21:59:09 +0200 Subject: [PATCH 058/183] Force exhaustive handling of every parsed attribute --- compiler/rustc_passes/src/check_attr.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0777d442b594..467f70990681 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -132,7 +132,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target, attrs, ), - _ => { + Attribute::Parsed(AttributeKind::AllowConstFnUnstable { .. }) => { + self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target) + } + Attribute::Parsed(AttributeKind::Deprecation { .. }) => { + self.check_deprecated(hir_id, attr, span, target) + } + Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/ + } + Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ + } + Attribute::Parsed( + AttributeKind::BodyStability { .. } + | AttributeKind::ConstStabilityIndirect + | AttributeKind::MacroTransparency(_), + ) => { /* do nothing */ } + Attribute::Unparsed(_) => { match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { self.check_do_not_recommend(attr.span(), hir_id, target, attr, item) @@ -169,9 +184,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_rustc_layout_scalar_valid_range(attr, span, target) } [sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target), - [sym::rustc_allow_const_fn_unstable, ..] => { - self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target) - } [sym::rustc_std_internal_symbol, ..] => { self.check_rustc_std_internal_symbol(attr, span, target) } @@ -229,7 +241,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target), [sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target), [sym::no_mangle, ..] => self.check_no_mangle(hir_id, attr, span, target), - [sym::deprecated, ..] => self.check_deprecated(hir_id, attr, span, target), [sym::macro_use, ..] | [sym::macro_escape, ..] => { self.check_macro_use(hir_id, attr, target) } @@ -283,7 +294,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::pointee // FIXME(derive_coerce_pointee) | sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section) | sym::used // handled elsewhere to restrict to static items - | sym::repr // handled elsewhere to restrict to type decls items | sym::instruction_set // broken on stable!!! | sym::windows_subsystem // broken on stable!!! | sym::patchable_function_entry // FIXME(patchable_function_entry) From e4c4c4c677f00a35aef0cfbe5e5ab3b30eafda4c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 6 Jun 2025 14:20:48 +0000 Subject: [PATCH 059/183] Fix review comments --- Cargo.lock | 1 + compiler/rustc_error_messages/Cargo.toml | 1 + compiler/rustc_error_messages/src/lib.rs | 6 +++--- compiler/rustc_interface/src/interface.rs | 5 ++--- compiler/rustc_interface/src/util.rs | 12 ++++-------- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43f5f40925b6..b9258fb18557 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3640,6 +3640,7 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "smallvec", "tracing", "unic-langid", ] diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 0951859fa531..5dc582b9c3a5 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -16,6 +16,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } +smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" unic-langid = { version = "0.9.0", features = ["macros"] } # tidy-alphabetical-end diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index a1f787b00d98..1d3b5b20751a 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -21,6 +21,7 @@ use intl_memoizer::concurrent::IntlLangMemoizer; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; +use smallvec::SmallVec; use tracing::{instrument, trace}; pub use unic_langid::{LanguageIdentifier, langid}; @@ -106,8 +107,7 @@ impl From> for TranslationBundleError { /// (overriding any conflicting messages). #[instrument(level = "trace")] pub fn fluent_bundle( - sysroot: PathBuf, - default_sysroot: PathBuf, + sysroot_candidates: SmallVec<[PathBuf; 2]>, requested_locale: Option, additional_ftl_path: Option<&Path>, with_directionality_markers: bool, @@ -141,7 +141,7 @@ pub fn fluent_bundle( // If the user requests the default locale then don't try to load anything. if let Some(requested_locale) = requested_locale { let mut found_resources = false; - for mut sysroot in [sysroot, default_sysroot] { + for mut sysroot in sysroot_candidates { sysroot.push("share"); sysroot.push("locale"); sysroot.push(requested_locale.to_string()); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 068b8c6d0445..e824e9d4aa91 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -18,7 +18,7 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; -use rustc_session::filesearch::get_or_default_sysroot; +use rustc_session::filesearch::sysroot_with_fallback; use rustc_session::parse::ParseSess; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint}; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; @@ -442,8 +442,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); let bundle = match rustc_errors::fluent_bundle( - config.opts.sysroot.clone(), - get_or_default_sysroot(), + sysroot_with_fallback(&config.opts.sysroot), config.opts.unstable_opts.translate_lang.clone(), config.opts.unstable_opts.translate_additional_ftl.as_deref(), config.opts.unstable_opts.translate_directionality_markers, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index f769c6156aeb..8bdc24d47d98 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -345,14 +345,10 @@ pub fn rustc_path<'a>() -> Option<&'a Path> { } fn get_rustc_path_inner(bin_path: &str) -> Option { - Some(filesearch::get_or_default_sysroot()).iter().find_map(|sysroot| { - let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") { - "rustc.exe" - } else { - "rustc" - }); - candidate.exists().then_some(candidate) - }) + let candidate = filesearch::get_or_default_sysroot() + .join(bin_path) + .join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" }); + candidate.exists().then_some(candidate) } #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable From c677dc26b4d9d5e742ff860ace924a270a2266b6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Jun 2025 16:15:02 +0000 Subject: [PATCH 060/183] Allow transmute casts in pre-runtime-MIR --- compiler/rustc_middle/src/mir/syntax.rs | 2 - compiler/rustc_mir_transform/src/validate.rs | 46 ++++++++------------ tests/ui/type/pattern_types/matching.rs | 1 + 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index bb068f3821db..f2f975a69683 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1531,8 +1531,6 @@ pub enum CastKind { /// /// MIR is well-formed if the input and output types have different sizes, /// but running a transmute between differently-sized types is UB. - /// - /// Allowed only in [`MirPhase::Runtime`]; Earlier it's a [`TerminatorKind::Call`]. Transmute, } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index fd91508cc114..7dcdd7999f28 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -1308,37 +1308,27 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } CastKind::Transmute => { - if let MirPhase::Runtime(..) = self.body.phase { - // Unlike `mem::transmute`, a MIR `Transmute` is well-formed - // for any two `Sized` types, just potentially UB to run. + // Unlike `mem::transmute`, a MIR `Transmute` is well-formed + // for any two `Sized` types, just potentially UB to run. - if !self - .tcx - .normalize_erasing_regions(self.typing_env, op_ty) - .is_sized(self.tcx, self.typing_env) - { - self.fail( - location, - format!("Cannot transmute from non-`Sized` type {op_ty}"), - ); - } - if !self - .tcx - .normalize_erasing_regions(self.typing_env, *target_type) - .is_sized(self.tcx, self.typing_env) - { - self.fail( - location, - format!("Cannot transmute to non-`Sized` type {target_type:?}"), - ); - } - } else { + if !self + .tcx + .normalize_erasing_regions(self.typing_env, op_ty) + .is_sized(self.tcx, self.typing_env) + { self.fail( location, - format!( - "Transmute is not supported in non-runtime phase {:?}.", - self.body.phase - ), + format!("Cannot transmute from non-`Sized` type {op_ty}"), + ); + } + if !self + .tcx + .normalize_erasing_regions(self.typing_env, *target_type) + .is_sized(self.tcx, self.typing_env) + { + self.fail( + location, + format!("Cannot transmute to non-`Sized` type {target_type:?}"), ); } } diff --git a/tests/ui/type/pattern_types/matching.rs b/tests/ui/type/pattern_types/matching.rs index b8463a8e8229..21f89b3b673b 100644 --- a/tests/ui/type/pattern_types/matching.rs +++ b/tests/ui/type/pattern_types/matching.rs @@ -1,6 +1,7 @@ #![feature(pattern_types, pattern_type_macro, structural_match)] //@ check-pass +//@ compile-flags: -Zvalidate-mir use std::marker::StructuralPartialEq; use std::pat::pattern_type; From cf5aea57cc741ad10a80841a3ec2fde52a939279 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 7 Jun 2025 04:53:58 +0000 Subject: [PATCH 061/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 1e97cdf5bde9..84a353bfbcf3 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -cf423712b9e95e9f6ec84b1ecb3d125e55ac8d56 +775e0c8aeb8f63192854b27156f8b05a06b51814 From 4007b1937bdc6994da0847a27db9bbe97a9f69c2 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 7 Jun 2025 05:02:30 +0000 Subject: [PATCH 062/183] fmt --- src/tools/miri/src/shims/backtrace.rs | 10 ++++++++-- src/tools/miri/src/shims/unix/linux_like/epoll.rs | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index 8606735c913e..feb83ca8829a 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -169,8 +169,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { _ => throw_unsup_format!("unknown `miri_resolve_frame` flags {}", flags), } - this.write_scalar(Scalar::from_u32(lineno), &this.project_field(dest, FieldIdx::from_u32(2))?)?; - this.write_scalar(Scalar::from_u32(colno), &this.project_field(dest, FieldIdx::from_u32(3))?)?; + this.write_scalar( + Scalar::from_u32(lineno), + &this.project_field(dest, FieldIdx::from_u32(2))?, + )?; + this.write_scalar( + Scalar::from_u32(colno), + &this.project_field(dest, FieldIdx::from_u32(3))?, + )?; // Support a 4-field struct for now - this is deprecated // and slated for removal. diff --git a/src/tools/miri/src/shims/unix/linux_like/epoll.rs b/src/tools/miri/src/shims/unix/linux_like/epoll.rs index f971fb10b199..d460abc783dd 100644 --- a/src/tools/miri/src/shims/unix/linux_like/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux_like/epoll.rs @@ -286,7 +286,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if op == epoll_ctl_add || op == epoll_ctl_mod { // Read event bitmask and data from epoll_event passed by caller. - let mut events = this.read_scalar(&this.project_field(&event, FieldIdx::ZERO)?)?.to_u32()?; + let mut events = + this.read_scalar(&this.project_field(&event, FieldIdx::ZERO)?)?.to_u32()?; let data = this.read_scalar(&this.project_field(&event, FieldIdx::ONE)?)?.to_u64()?; // Unset the flag we support to discover if any unsupported flags are used. From b620d0791d9176232d72b2743e93e054a7849a32 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 7 Jun 2025 08:27:34 +0200 Subject: [PATCH 063/183] test_dup: ensure the FDs remain in sync even after dup'ing --- src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index 129b18d8e598..0ff48c389e85 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -88,16 +88,17 @@ fn test_dup() { let name_ptr = name.as_bytes().as_ptr().cast::(); unsafe { let fd = libc::open(name_ptr, libc::O_RDONLY); + let new_fd = libc::dup(fd); + let new_fd2 = libc::dup2(fd, 8); + let mut first_buf = [0u8; 4]; libc::read(fd, first_buf.as_mut_ptr() as *mut libc::c_void, 4); assert_eq!(&first_buf, b"dup "); - let new_fd = libc::dup(fd); let mut second_buf = [0u8; 4]; libc::read(new_fd, second_buf.as_mut_ptr() as *mut libc::c_void, 4); assert_eq!(&second_buf, b"and "); - let new_fd2 = libc::dup2(fd, 8); let mut third_buf = [0u8; 4]; libc::read(new_fd2, third_buf.as_mut_ptr() as *mut libc::c_void, 4); assert_eq!(&third_buf, b"dup2"); From a87cd55f8e808425266e31aba658d77bc7b59939 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Wed, 14 May 2025 11:40:20 +0000 Subject: [PATCH 064/183] Make NonZero possible --- library/core/src/num/niche_types.rs | 2 ++ library/core/src/num/nonzero.rs | 1 + library/coretests/tests/num/mod.rs | 9 ++++----- library/coretests/tests/num/niche_types.rs | 12 ++++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 library/coretests/tests/num/niche_types.rs diff --git a/library/core/src/num/niche_types.rs b/library/core/src/num/niche_types.rs index 47ff4254e533..b92561c9e356 100644 --- a/library/core/src/num/niche_types.rs +++ b/library/core/src/num/niche_types.rs @@ -131,6 +131,8 @@ define_valid_range_type! { pub struct NonZeroI32Inner(i32 as u32 in 1..=0xffff_ffff); pub struct NonZeroI64Inner(i64 as u64 in 1..=0xffffffff_ffffffff); pub struct NonZeroI128Inner(i128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff); + + pub struct NonZeroCharInner(char as u32 in 1..=0x10ffff); } #[cfg(target_pointer_width = "16")] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 511807b409f7..0fa066c8f7e3 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -79,6 +79,7 @@ impl_zeroable_primitive!( NonZeroI64Inner(i64), NonZeroI128Inner(i128), NonZeroIsizeInner(isize), + NonZeroCharInner(char), ); /// A value that is known not to equal zero. diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index 6611aa57866f..f340926292c8 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -22,20 +22,19 @@ mod u64; mod u8; mod bignum; - mod const_from; mod dec2flt; +mod float_iter_sum_identity; mod flt2dec; +mod ieee754; mod int_log; mod int_sqrt; mod midpoint; +mod nan; +mod niche_types; mod ops; mod wrapping; -mod float_iter_sum_identity; -mod ieee754; -mod nan; - /// Adds the attribute to all items in the block. macro_rules! cfg_block { ($(#[$attr:meta]{$($it:item)*})*) => {$($( diff --git a/library/coretests/tests/num/niche_types.rs b/library/coretests/tests/num/niche_types.rs new file mode 100644 index 000000000000..171a7f35d53e --- /dev/null +++ b/library/coretests/tests/num/niche_types.rs @@ -0,0 +1,12 @@ +use core::num::NonZero; + +#[test] +fn test_new_from_zero_is_none() { + assert_eq!(NonZero::::new(0 as char), None); +} + +#[test] +fn test_new_from_extreme_is_some() { + assert!(NonZero::::new(1 as char).is_some()); + assert!(NonZero::::new(char::MAX).is_some()); +} From bafe406711a4e7e9e2683d9245fcc13f306e1d83 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 7 Jun 2025 15:42:19 +0200 Subject: [PATCH 065/183] UnsafePinned: update get() docs and signature to allow shared mutation --- library/core/src/cell.rs | 2 +- library/core/src/pin/unsafe_pinned.rs | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index ed523920e42b..0656ab98ee3c 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2170,7 +2170,7 @@ impl UnsafeCell { /// This can be cast to a pointer of any kind. /// Ensure that the access is unique (no active references, mutable or not) /// when casting to `&mut T`, and ensure that there are no mutations - /// or mutable aliases going on when casting to `&T` + /// or mutable aliases going on when casting to `&T`. /// /// # Examples /// diff --git a/library/core/src/pin/unsafe_pinned.rs b/library/core/src/pin/unsafe_pinned.rs index dbcceb807aba..f3d5e0798382 100644 --- a/library/core/src/pin/unsafe_pinned.rs +++ b/library/core/src/pin/unsafe_pinned.rs @@ -86,11 +86,14 @@ impl UnsafePinned { ptr::from_mut(self) as *mut T } - /// Get read-only access to the contents of a shared `UnsafePinned`. + /// Get mutable access to the contents of a shared `UnsafePinned`. /// - /// Note that `&UnsafePinned` is read-only if `&T` is read-only. This means that if there is - /// mutation of the `T`, future reads from the `*const T` returned here are UB! Use - /// [`UnsafeCell`] if you also need interior mutability. + /// This can be cast to a pointer of any kind. + /// Ensure that the access is unique (no active references, mutable or not) + /// when casting to `&mut T`, and ensure that there are no mutations + /// or mutable aliases going on when casting to `&T`. + /// + /// All the usual caveats around mutation shared state apply, see [`UnsafeCell`]. /// /// [`UnsafeCell`]: crate::cell::UnsafeCell /// @@ -100,16 +103,16 @@ impl UnsafePinned { /// /// unsafe { /// let mut x = UnsafePinned::new(0); - /// let ptr = x.get(); // read-only pointer, assumes immutability + /// let ptr = x.get(); /// x.get_mut_unchecked().write(1); - /// ptr.read(); // UB! + /// assert_eq!(ptr.read(), 1); /// } /// ``` #[inline(always)] #[must_use] #[unstable(feature = "unsafe_pinned", issue = "125735")] - pub const fn get(&self) -> *const T { - ptr::from_ref(self) as *const T + pub const fn get(&self) -> *mut T { + self.value.get() } /// Gets an immutable pointer to the wrapped value. From b283394db14a47d44a4b5ace33705cfa3873b0b5 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 7 Jun 2025 14:45:10 +0200 Subject: [PATCH 066/183] Only allow `bootstrap` cfg in rustc, related and tool-std --- src/bootstrap/src/core/builder/cargo.rs | 16 +++++++++------- src/bootstrap/src/lib.rs | 5 ++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 1e9af68a92df..a21bee7c6110 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -636,6 +636,15 @@ impl Builder<'_> { for (restricted_mode, name, values) in EXTRA_CHECK_CFGS { if restricted_mode.is_none() || *restricted_mode == Some(mode) { rustflags.arg(&check_cfg_arg(name, *values)); + + if *name == "bootstrap" { + // Cargo doesn't pass RUSTFLAGS to proc_macros: + // https://github.com/rust-lang/cargo/issues/4423 + // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`. + // We also declare that the flag is expected, which we need to do to not + // get warnings about it being unexpected. + hostflags.arg(check_cfg_arg(name, *values)); + } } } @@ -645,13 +654,6 @@ impl Builder<'_> { if stage == 0 { hostflags.arg("--cfg=bootstrap"); } - // Cargo doesn't pass RUSTFLAGS to proc_macros: - // https://github.com/rust-lang/cargo/issues/4423 - // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`. - // We also declare that the flag is expected, which we need to do to not - // get warnings about it being unexpected. - hostflags.arg("-Zunstable-options"); - hostflags.arg("--check-cfg=cfg(bootstrap)"); // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`, // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 07772b8932d9..8e657b99f17e 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -81,7 +81,10 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; /// (Mode restriction, config name, config values (if any)) #[expect(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above. const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ - (None, "bootstrap", None), + (Some(Mode::Rustc), "bootstrap", None), + (Some(Mode::Codegen), "bootstrap", None), + (Some(Mode::ToolRustc), "bootstrap", None), + (Some(Mode::ToolStd), "bootstrap", None), (Some(Mode::Rustc), "llvm_enzyme", None), (Some(Mode::Codegen), "llvm_enzyme", None), (Some(Mode::ToolRustc), "llvm_enzyme", None), From 9b1cd722ca7490ae28db77b44eefb4700ef6bb19 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 7 Jun 2025 14:45:25 +0200 Subject: [PATCH 067/183] Fix usage of `bootstrap` in core --- library/core/src/iter/sources/generator.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/core/src/iter/sources/generator.rs b/library/core/src/iter/sources/generator.rs index c94232e09eb8..0846974d526a 100644 --- a/library/core/src/iter/sources/generator.rs +++ b/library/core/src/iter/sources/generator.rs @@ -9,8 +9,6 @@ /// /// ``` /// #![feature(iter_macro, coroutines)] -/// # #[cfg(not(bootstrap))] -/// # { /// /// let it = std::iter::iter!{|| { /// yield 1; @@ -19,11 +17,10 @@ /// } }(); /// let v: Vec<_> = it.collect(); /// assert_eq!(v, [1, 2, 3]); -/// # } /// ``` #[unstable(feature = "iter_macro", issue = "none", reason = "generators are unstable")] #[allow_internal_unstable(coroutines, iter_from_coroutine)] -#[cfg_attr(not(bootstrap), rustc_builtin_macro)] +#[rustc_builtin_macro] pub macro iter($($t:tt)*) { /* compiler-builtin */ } From cd7533ab44cbc7b1b50b582d45a574af6eec12b7 Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 8 May 2025 01:06:23 +0530 Subject: [PATCH 068/183] Stabilize the `keylocker_x86` flag, and the `kl` and `widekl` target features --- compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_feature/src/unstable.rs | 2 -- compiler/rustc_target/src/target_features.rs | 4 ++-- library/core/src/lib.rs | 1 - .../ui/feature-gates/feature-gate-keylocker_x86.rs | 6 ------ .../feature-gates/feature-gate-keylocker_x86.stderr | 13 ------------- 6 files changed, 4 insertions(+), 24 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-keylocker_x86.rs delete mode 100644 tests/ui/feature-gates/feature-gate-keylocker_x86.stderr diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index ffa6ffb40b61..21e957427040 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -259,6 +259,8 @@ declare_features! ( /// Allows some increased flexibility in the name resolution rules, /// especially around globs and shadowing (RFC 1560). (accepted, item_like_imports, "1.15.0", Some(35120)), + // Allows using the `kl` and `widekl` target features and the associated intrinsics + (accepted, keylocker_x86, "CURRENT_RUSTC_VERSION", Some(134813)), /// Allows `'a: { break 'a; }`. (accepted, label_break_value, "1.65.0", Some(48594)), /// Allows `let...else` statements. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index b46eac6d8a60..44413b756e1b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -546,8 +546,6 @@ declare_features! ( (incomplete, inherent_associated_types, "1.52.0", Some(8995)), /// Allows using `pointer` and `reference` in intra-doc links (unstable, intra_doc_pointers, "1.51.0", Some(80896)), - // Allows using the `kl` and `widekl` target features and the associated intrinsics - (unstable, keylocker_x86, "1.86.0", Some(134813)), // Allows setting the threshold for the `large_assignments` lint. (unstable, large_assignments, "1.52.0", Some(83518)), /// Allow to have type alias types for inter-crate use. diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 682c4c5068f9..ecf6fba26301 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -443,7 +443,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("fma", Stable, &["avx"]), ("fxsr", Stable, &[]), ("gfni", Stable, &["sse2"]), - ("kl", Unstable(sym::keylocker_x86), &["sse2"]), + ("kl", Stable, &["sse2"]), ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]), ("lzcnt", Stable, &[]), ("movbe", Stable, &[]), @@ -471,7 +471,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("tbm", Unstable(sym::tbm_target_feature), &[]), ("vaes", Stable, &["avx2", "aes"]), ("vpclmulqdq", Stable, &["avx", "pclmulqdq"]), - ("widekl", Unstable(sym::keylocker_x86), &["kl"]), + ("widekl", Stable, &["kl"]), ("x87", Unstable(sym::x87_target_feature), &[]), ("xop", Unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]), ("xsave", Stable, &[]), diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f2a5c40bada0..b7bd2f837c10 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -190,7 +190,6 @@ #![feature(aarch64_unstable_target_feature)] #![feature(arm_target_feature)] #![feature(hexagon_target_feature)] -#![feature(keylocker_x86)] #![feature(loongarch_target_feature)] #![feature(mips_target_feature)] #![feature(powerpc_target_feature)] diff --git a/tests/ui/feature-gates/feature-gate-keylocker_x86.rs b/tests/ui/feature-gates/feature-gate-keylocker_x86.rs deleted file mode 100644 index cef80ad41a89..000000000000 --- a/tests/ui/feature-gates/feature-gate-keylocker_x86.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ only-x86_64 -#[target_feature(enable = "kl")] -//~^ ERROR: currently unstable -unsafe fn foo() {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr b/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr deleted file mode 100644 index ed814d3a3ce2..000000000000 --- a/tests/ui/feature-gates/feature-gate-keylocker_x86.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: the target feature `kl` is currently unstable - --> $DIR/feature-gate-keylocker_x86.rs:2:18 - | -LL | #[target_feature(enable = "kl")] - | ^^^^^^^^^^^^^ - | - = note: see issue #134813 for more information - = help: add `#![feature(keylocker_x86)]` 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: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. From 632396ea01e7556d9af24ad1a22f9a74ccb63d60 Mon Sep 17 00:00:00 2001 From: sayantn Date: Thu, 8 May 2025 01:13:59 +0530 Subject: [PATCH 069/183] Stabilize `sha512_sm_x86`, and the `sha512`, `sm3` and `sm4` target features --- compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_feature/src/unstable.rs | 2 -- compiler/rustc_target/src/target_features.rs | 6 +++--- library/core/src/lib.rs | 1 - .../ui/feature-gates/feature-gate-sha512_sm_x86.rs | 6 ------ .../feature-gates/feature-gate-sha512_sm_x86.stderr | 13 ------------- 6 files changed, 5 insertions(+), 25 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-sha512_sm_x86.rs delete mode 100644 tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index ffa6ffb40b61..10c5cb194f40 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -382,6 +382,8 @@ declare_features! ( (accepted, self_in_typedefs, "1.32.0", Some(49303)), /// Allows `Self` struct constructor (RFC 2302). (accepted, self_struct_ctor, "1.32.0", Some(51994)), + /// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics + (accepted, sha512_sm_x86, "CURRENT_RUSTC_VERSION", Some(126624)), /// Shortern the tail expression lifetime (accepted, shorter_tail_lifetimes, "1.84.0", Some(123739)), /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index b46eac6d8a60..9447deeecbbc 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -627,8 +627,6 @@ declare_features! ( (unstable, return_type_notation, "1.70.0", Some(109417)), /// Allows `extern "rust-cold"`. (unstable, rust_cold_cc, "1.63.0", Some(97544)), - /// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics - (unstable, sha512_sm_x86, "1.82.0", Some(126624)), /// Allows the use of SIMD types in functions declared in `extern` blocks. (unstable, simd_ffi, "1.0.0", Some(27731)), /// Allows specialization of implementations (RFC 1210). diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 682c4c5068f9..b93f623a7396 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -455,9 +455,9 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("rdseed", Stable, &[]), ("rtm", Unstable(sym::rtm_target_feature), &[]), ("sha", Stable, &["sse2"]), - ("sha512", Unstable(sym::sha512_sm_x86), &["avx2"]), - ("sm3", Unstable(sym::sha512_sm_x86), &["avx"]), - ("sm4", Unstable(sym::sha512_sm_x86), &["avx2"]), + ("sha512", Stable, &["avx2"]), + ("sm3", Stable, &["avx"]), + ("sm4", Stable, &["avx2"]), // This cannot actually be toggled, the ABI always fixes it, so it'd make little sense to // stabilize. It must be in this list for the ABI check to be able to use it. ("soft-float", Stability::Unstable(sym::x87_target_feature), &[]), diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f2a5c40bada0..fc98ae9ff3f7 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -197,7 +197,6 @@ #![feature(riscv_target_feature)] #![feature(rtm_target_feature)] #![feature(s390x_target_feature)] -#![feature(sha512_sm_x86)] #![feature(sse4a_target_feature)] #![feature(tbm_target_feature)] #![feature(wasm_target_feature)] diff --git a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.rs b/tests/ui/feature-gates/feature-gate-sha512_sm_x86.rs deleted file mode 100644 index 176a40ecf537..000000000000 --- a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ only-x86_64 -#[target_feature(enable = "sha512")] -//~^ ERROR: currently unstable -unsafe fn foo() {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr b/tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr deleted file mode 100644 index da9eea095a33..000000000000 --- a/tests/ui/feature-gates/feature-gate-sha512_sm_x86.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: the target feature `sha512` is currently unstable - --> $DIR/feature-gate-sha512_sm_x86.rs:2:18 - | -LL | #[target_feature(enable = "sha512")] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #126624 for more information - = help: add `#![feature(sha512_sm_x86)]` 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: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. From bd0a81ee82bbc9e7e163bab648c86170cf816c5e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 7 Jun 2025 21:57:45 +0200 Subject: [PATCH 070/183] centralize aliasing rules discussion in UnsafeCell docs --- library/core/src/cell.rs | 16 ++++++++-------- library/core/src/pin/unsafe_pinned.rs | 10 +++------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 0656ab98ee3c..a4b6efe35fc1 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1914,6 +1914,8 @@ impl fmt::Display for RefMut<'_, T> { /// [`.get()`]: `UnsafeCell::get` /// [concurrent memory model]: ../sync/atomic/index.html#memory-model-for-atomic-accesses /// +/// # Aliasing rules +/// /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious: /// /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference), then @@ -2167,10 +2169,9 @@ impl UnsafeCell { /// Gets a mutable pointer to the wrapped value. /// - /// This can be cast to a pointer of any kind. - /// Ensure that the access is unique (no active references, mutable or not) - /// when casting to `&mut T`, and ensure that there are no mutations - /// or mutable aliases going on when casting to `&T`. + /// This can be cast to a pointer of any kind. When creating references, you must uphold the + /// aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for more discussion and + /// caveats. /// /// # Examples /// @@ -2219,10 +2220,9 @@ impl UnsafeCell { /// The difference from [`get`] is that this function accepts a raw pointer, /// which is useful to avoid the creation of temporary references. /// - /// The result can be cast to a pointer of any kind. - /// Ensure that the access is unique (no active references, mutable or not) - /// when casting to `&mut T`, and ensure that there are no mutations - /// or mutable aliases going on when casting to `&T`. + /// This can be cast to a pointer of any kind. When creating references, you must uphold the + /// aliasing rules; see [the type-level docs][UnsafeCell#aliasing-rules] for more discussion and + /// caveats. /// /// [`get`]: UnsafeCell::get() /// diff --git a/library/core/src/pin/unsafe_pinned.rs b/library/core/src/pin/unsafe_pinned.rs index f3d5e0798382..17f7bcd306b0 100644 --- a/library/core/src/pin/unsafe_pinned.rs +++ b/library/core/src/pin/unsafe_pinned.rs @@ -88,14 +88,10 @@ impl UnsafePinned { /// Get mutable access to the contents of a shared `UnsafePinned`. /// - /// This can be cast to a pointer of any kind. - /// Ensure that the access is unique (no active references, mutable or not) - /// when casting to `&mut T`, and ensure that there are no mutations - /// or mutable aliases going on when casting to `&T`. + /// This can be cast to a pointer of any kind. When creating references, you must uphold the + /// aliasing rules; see [`UnsafeCell`] for more discussion and caveats. /// - /// All the usual caveats around mutation shared state apply, see [`UnsafeCell`]. - /// - /// [`UnsafeCell`]: crate::cell::UnsafeCell + /// [`UnsafeCell`]: crate::cell::UnsafeCell#aliasing-rules /// /// ```rust,no_run /// #![feature(unsafe_pinned)] From a50bd7ca24aa752fee840e83f7090bbd23f3a158 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 7 Jun 2025 21:31:21 +0200 Subject: [PATCH 071/183] store `target.min_global_align` as an `Align` --- compiler/rustc_codegen_gcc/messages.ftl | 3 --- compiler/rustc_codegen_gcc/src/consts.rs | 10 ++----- compiler/rustc_codegen_gcc/src/errors.rs | 6 ----- compiler/rustc_codegen_llvm/messages.ftl | 6 ----- compiler/rustc_codegen_llvm/src/consts.rs | 26 ++++--------------- compiler/rustc_codegen_llvm/src/errors.rs | 12 --------- compiler/rustc_target/src/spec/json.rs | 21 +++++++++++++-- compiler/rustc_target/src/spec/mod.rs | 8 +++++- .../spec/targets/s390x_unknown_linux_gnu.rs | 4 +-- .../spec/targets/s390x_unknown_linux_musl.rs | 4 +-- 10 files changed, 37 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl index 882fff8673a1..546bfc87b689 100644 --- a/compiler/rustc_codegen_gcc/messages.ftl +++ b/compiler/rustc_codegen_gcc/messages.ftl @@ -2,9 +2,6 @@ codegen_gcc_unknown_ctarget_feature_prefix = unknown feature specified for `-Ctarget-feature`: `{$feature}` .note = features must begin with a `+` to enable or `-` to disable it -codegen_gcc_invalid_minimum_alignment = - invalid minimum global alignment: {$err} - codegen_gcc_forbidden_ctarget_feature = target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason} diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index deb13ddf7558..1690641a5bc0 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -18,7 +18,6 @@ use rustc_span::def_id::DefId; use crate::base; use crate::context::CodegenCx; -use crate::errors::InvalidMinimumAlignment; use crate::type_of::LayoutGccExt; fn set_global_alignment<'gcc, 'tcx>( @@ -29,13 +28,8 @@ fn set_global_alignment<'gcc, 'tcx>( // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. - if let Some(min) = cx.sess().target.min_global_align { - match Align::from_bits(min) { - Ok(min) => align = align.max(min), - Err(err) => { - cx.sess().dcx().emit_err(InvalidMinimumAlignment { err: err.to_string() }); - } - } + if let Some(min_global) = cx.sess().target.min_global_align { + align = Ord::max(align, min_global); } gv.set_alignment(align.bytes() as i32); } diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs index 1b59b9ac169a..ccd9abe38049 100644 --- a/compiler/rustc_codegen_gcc/src/errors.rs +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -47,12 +47,6 @@ pub(crate) struct UnwindingInlineAsm { pub span: Span, } -#[derive(Diagnostic)] -#[diag(codegen_gcc_invalid_minimum_alignment)] -pub(crate) struct InvalidMinimumAlignment { - pub err: String, -} - #[derive(Diagnostic)] #[diag(codegen_gcc_copy_bitcode)] pub(crate) struct CopyBitcode { diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 41391b096cca..bda121c67fb6 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -19,12 +19,6 @@ codegen_llvm_from_llvm_diag = {$message} codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message} -codegen_llvm_invalid_minimum_alignment_not_power_of_two = - invalid minimum global alignment: {$align} is not power of 2 - -codegen_llvm_invalid_minimum_alignment_too_large = - invalid minimum global alignment: {$align} is too large - codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}" codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err} diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 73def2711dc6..a4492d76c3c5 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -1,8 +1,6 @@ use std::ops::Range; -use rustc_abi::{ - Align, AlignFromBytesError, HasDataLayout, Primitive, Scalar, Size, WrappingRange, -}; +use rustc_abi::{Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange}; use rustc_codegen_ssa::common; use rustc_codegen_ssa::traits::*; use rustc_hir::LangItem; @@ -20,9 +18,7 @@ use rustc_middle::{bug, span_bug}; use tracing::{debug, instrument, trace}; use crate::common::{AsCCharPtr, CodegenCx}; -use crate::errors::{ - InvalidMinimumAlignmentNotPowerOfTwo, InvalidMinimumAlignmentTooLarge, SymbolAlreadyDefined, -}; +use crate::errors::SymbolAlreadyDefined; use crate::llvm::{self, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; @@ -149,22 +145,10 @@ fn set_global_alignment<'ll>(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, mut align: // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. - if let Some(min) = cx.sess().target.min_global_align { - match Align::from_bits(min) { - Ok(min) => align = align.max(min), - Err(err) => match err { - AlignFromBytesError::NotPowerOfTwo(align) => { - cx.sess().dcx().emit_err(InvalidMinimumAlignmentNotPowerOfTwo { align }); - } - AlignFromBytesError::TooLarge(align) => { - cx.sess().dcx().emit_err(InvalidMinimumAlignmentTooLarge { align }); - } - }, - } - } - unsafe { - llvm::LLVMSetAlignment(gv, align.bytes() as u32); + if let Some(min_global) = cx.sess().target.min_global_align { + align = Ord::max(align, min_global); } + llvm::set_alignment(gv, align); } fn check_and_apply_linkage<'ll, 'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index ecf108f988f0..eaafc6807129 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -57,18 +57,6 @@ pub(crate) struct SymbolAlreadyDefined<'a> { pub symbol_name: &'a str, } -#[derive(Diagnostic)] -#[diag(codegen_llvm_invalid_minimum_alignment_not_power_of_two)] -pub(crate) struct InvalidMinimumAlignmentNotPowerOfTwo { - pub align: u64, -} - -#[derive(Diagnostic)] -#[diag(codegen_llvm_invalid_minimum_alignment_too_large)] -pub(crate) struct InvalidMinimumAlignmentTooLarge { - pub align: u64, -} - #[derive(Diagnostic)] #[diag(codegen_llvm_sanitizer_memtag_requires_mte)] pub(crate) struct SanitizerMemtagRequiresMte; diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index 54b06d9f9b47..039056a5a25a 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::str::FromStr; -use rustc_abi::ExternAbi; +use rustc_abi::{Align, AlignFromBytesError, ExternAbi}; use serde_json::Value; use super::{Target, TargetKind, TargetOptions, TargetWarnings}; @@ -57,6 +57,14 @@ impl Target { base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool()); } + let alignment_error = |field_name: &str, error: AlignFromBytesError| -> String { + let msg = match error { + AlignFromBytesError::NotPowerOfTwo(_) => "not a power of 2 number of bytes", + AlignFromBytesError::TooLarge(_) => "too large", + }; + format!("`{}` bits is not a valid value for {field_name}: {msg}", error.align() * 8) + }; + let mut incorrect_type = vec![]; macro_rules! key { @@ -111,6 +119,15 @@ impl Target { base.$key_name = Some(s.into()); } } ); + ($key_name:ident, Option) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(b) = obj.remove(&name).and_then(|b| b.as_u64()) { + match Align::from_bits(b) { + Ok(align) => base.$key_name = Some(align), + Err(e) => return Err(alignment_error(&name, e)), + } + } + } ); ($key_name:ident, BinaryFormat) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.remove(&name).and_then(|f| f.as_str().and_then(|s| { @@ -617,7 +634,7 @@ impl Target { key!(crt_static_default, bool); key!(crt_static_respected, bool); key!(stack_probes, StackProbeType)?; - key!(min_global_align, Option); + key!(min_global_align, Option); key!(default_codegen_units, Option); key!(default_codegen_backend, Option>); key!(trap_unreachable, bool); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 6529c2d72c82..48da1f2fb06c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1697,6 +1697,12 @@ impl ToJson for BinaryFormat { } } +impl ToJson for Align { + fn to_json(&self) -> Json { + self.bits().to_json() + } +} + macro_rules! supported_targets { ( $(($tuple:literal, $module:ident),)+ ) => { mod targets { @@ -2513,7 +2519,7 @@ pub struct TargetOptions { pub stack_probes: StackProbeType, /// The minimum alignment for global symbols. - pub min_global_align: Option, + pub min_global_align: Option, /// Default number of codegen units to use in debug mode pub default_codegen_units: Option, diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs index e0d16a7bfa55..cdcf7d62a3e2 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs @@ -1,4 +1,4 @@ -use rustc_abi::Endian; +use rustc_abi::{Align, Endian}; use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base}; @@ -8,7 +8,7 @@ pub(crate) fn target() -> Target { // z10 is the oldest CPU supported by LLVM base.cpu = "z10".into(); base.max_atomic_width = Some(128); - base.min_global_align = Some(16); + base.min_global_align = Some(Align::from_bits(16).unwrap()); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs index 47050c1f769e..e9522ac760e1 100644 --- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use rustc_abi::Endian; +use rustc_abi::{Align, Endian}; use crate::spec::{SanitizerSet, StackProbeType, Target, TargetMetadata, base}; @@ -8,7 +8,7 @@ pub(crate) fn target() -> Target { // z10 is the oldest CPU supported by LLVM base.cpu = "z10".into(); base.max_atomic_width = Some(128); - base.min_global_align = Some(16); + base.min_global_align = Some(Align::from_bits(16).unwrap()); base.static_position_independent_executables = true; base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = From 3380a91f5baccd551fffd8a1f5dc1fa3d23e5b5e Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Fri, 6 Jun 2025 23:29:49 +0500 Subject: [PATCH 072/183] cleaned up some tests --- .../crate-name-attr-validation.rs} | 2 + tests/ui/complex.rs | 38 ------------------- tests/ui/constructor-lifetime-args.rs | 26 ------------- .../auxiliary/method_reexport_aux.rs} | 4 +- .../cross-crate-method-reexport.rs} | 8 ++-- .../impl-trait-invalid-iterator-error.rs} | 2 +- .../impl-trait-invalid-iterator-error.stderr} | 2 +- .../global-path-resolution-drop.rs} | 2 + ...onstructor-lifetime-early-binding-error.rs | 22 +++++++++++ ...uctor-lifetime-early-binding-error.stderr} | 16 ++++---- .../crate-type-invalid-flag-error.rs} | 2 + .../crate-type-invalid-flag-error.stderr} | 0 12 files changed, 45 insertions(+), 79 deletions(-) rename tests/ui/{crate-name-attr-used.rs => attributes/crate-name-attr-validation.rs} (68%) delete mode 100644 tests/ui/complex.rs delete mode 100644 tests/ui/constructor-lifetime-args.rs rename tests/ui/{auxiliary/crate-method-reexport-grrrrrrr2.rs => cross-crate/auxiliary/method_reexport_aux.rs} (79%) rename tests/ui/{crate-method-reexport-grrrrrrr.rs => cross-crate/cross-crate-method-reexport.rs} (56%) rename tests/ui/{conservative_impl_trait.rs => diagnostic-width/impl-trait-invalid-iterator-error.rs} (79%) rename tests/ui/{conservative_impl_trait.stderr => diagnostic-width/impl-trait-invalid-iterator-error.stderr} (87%) rename tests/ui/{crate-leading-sep.rs => imports/global-path-resolution-drop.rs} (59%) create mode 100644 tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs rename tests/ui/{constructor-lifetime-args.stderr => lifetimes/constructor-lifetime-early-binding-error.stderr} (79%) rename tests/ui/{crate_type_flag.rs => linking/crate-type-invalid-flag-error.rs} (59%) rename tests/ui/{crate_type_flag.stderr => linking/crate-type-invalid-flag-error.stderr} (100%) diff --git a/tests/ui/crate-name-attr-used.rs b/tests/ui/attributes/crate-name-attr-validation.rs similarity index 68% rename from tests/ui/crate-name-attr-used.rs rename to tests/ui/attributes/crate-name-attr-validation.rs index 5d5a58c32c79..e27893c3d25b 100644 --- a/tests/ui/crate-name-attr-used.rs +++ b/tests/ui/attributes/crate-name-attr-validation.rs @@ -1,3 +1,5 @@ +//! Checks proper validation of the `#![crate_name]` attribute. + //@ run-pass //@ compile-flags:--crate-name crate_name_attr_used -F unused-attributes diff --git a/tests/ui/complex.rs b/tests/ui/complex.rs deleted file mode 100644 index d1da9d189ca1..000000000000 --- a/tests/ui/complex.rs +++ /dev/null @@ -1,38 +0,0 @@ -//@ run-pass - -#![allow(unconditional_recursion)] -#![allow(non_camel_case_types)] -#![allow(dead_code)] -#![allow(unused_mut)] - - - -type t = isize; - -fn nothing() { } - -fn putstr(_s: String) { } - -fn putint(_i: isize) { - let mut i: isize = 33; - while i < 36 { putstr("hi".to_string()); i = i + 1; } -} - -fn zerg(i: isize) -> isize { return i; } - -fn foo(x: isize) -> isize { - let mut y: t = x + 2; - putstr("hello".to_string()); - while y < 10 { putint(y); if y * 3 == 4 { y = y + 2; nothing(); } } - let mut z: t; - z = 0x55; - foo(z); - return 0; -} - -pub fn main() { - let x: isize = 2 + 2; - println!("{}", x); - println!("hello, world"); - println!("{}", 10); -} diff --git a/tests/ui/constructor-lifetime-args.rs b/tests/ui/constructor-lifetime-args.rs deleted file mode 100644 index f5802e7d8b11..000000000000 --- a/tests/ui/constructor-lifetime-args.rs +++ /dev/null @@ -1,26 +0,0 @@ -// All lifetime parameters in struct constructors are currently considered early bound, -// i.e., `S::` is interpreted kinda like an associated item `S::::ctor`. -// This behavior is a bit weird, because if equivalent constructor were written manually -// it would get late bound lifetime parameters. -// Variant constructors behave in the same way, lifetime parameters are considered -// belonging to the enum and being early bound. -// https://github.com/rust-lang/rust/issues/30904 - -struct S<'a, 'b>(&'a u8, &'b u8); -enum E<'a, 'b> { - V(&'a u8), - U(&'b u8), -} - -fn main() { - S(&0, &0); // OK - S::<'static>(&0, &0); - //~^ ERROR struct takes 2 lifetime arguments - S::<'static, 'static, 'static>(&0, &0); - //~^ ERROR struct takes 2 lifetime arguments - E::V(&0); // OK - E::V::<'static>(&0); - //~^ ERROR enum takes 2 lifetime arguments - E::V::<'static, 'static, 'static>(&0); - //~^ ERROR enum takes 2 lifetime arguments -} diff --git a/tests/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs b/tests/ui/cross-crate/auxiliary/method_reexport_aux.rs similarity index 79% rename from tests/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs rename to tests/ui/cross-crate/auxiliary/method_reexport_aux.rs index 06413e13526e..7579f033dc6d 100644 --- a/tests/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs +++ b/tests/ui/cross-crate/auxiliary/method_reexport_aux.rs @@ -1,4 +1,6 @@ -#![crate_name="crate_method_reexport_grrrrrrr2"] +//! Used by `tests/ui/cross-crate/cross-crate-method-reexport.rs` + +#![crate_name="method_reexport_aux"] pub use name_pool::add; diff --git a/tests/ui/crate-method-reexport-grrrrrrr.rs b/tests/ui/cross-crate/cross-crate-method-reexport.rs similarity index 56% rename from tests/ui/crate-method-reexport-grrrrrrr.rs rename to tests/ui/cross-crate/cross-crate-method-reexport.rs index aca399f4e209..e9eab99e2145 100644 --- a/tests/ui/crate-method-reexport-grrrrrrr.rs +++ b/tests/ui/cross-crate/cross-crate-method-reexport.rs @@ -4,13 +4,13 @@ // name_pool::methods impl in the other crate is reachable from this // crate. -//@ aux-build:crate-method-reexport-grrrrrrr2.rs +//@ aux-build:method_reexport_aux.rs -extern crate crate_method_reexport_grrrrrrr2; +extern crate method_reexport_aux; pub fn main() { - use crate_method_reexport_grrrrrrr2::rust::add; - use crate_method_reexport_grrrrrrr2::rust::cx; + use method_reexport_aux::rust::add; + use method_reexport_aux::rust::cx; let x: Box<_> = Box::new(()); x.cx(); let y = (); diff --git a/tests/ui/conservative_impl_trait.rs b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.rs similarity index 79% rename from tests/ui/conservative_impl_trait.rs rename to tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.rs index b7f795eadb76..055889323952 100644 --- a/tests/ui/conservative_impl_trait.rs +++ b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.rs @@ -1,4 +1,4 @@ -// #39872, #39553 +//! Test for #39872 and #39553 fn will_ice(something: &u32) -> impl Iterator { //~^ ERROR `()` is not an iterator diff --git a/tests/ui/conservative_impl_trait.stderr b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.stderr similarity index 87% rename from tests/ui/conservative_impl_trait.stderr rename to tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.stderr index eecdb6f92667..0146fa7a28b4 100644 --- a/tests/ui/conservative_impl_trait.stderr +++ b/tests/ui/diagnostic-width/impl-trait-invalid-iterator-error.stderr @@ -1,5 +1,5 @@ error[E0277]: `()` is not an iterator - --> $DIR/conservative_impl_trait.rs:3:33 + --> $DIR/impl-trait-invalid-iterator-error.rs:3:33 | LL | fn will_ice(something: &u32) -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/imports/global-path-resolution-drop.rs similarity index 59% rename from tests/ui/crate-leading-sep.rs rename to tests/ui/imports/global-path-resolution-drop.rs index 6f4dd0bcfd7f..29a6afa10c96 100644 --- a/tests/ui/crate-leading-sep.rs +++ b/tests/ui/imports/global-path-resolution-drop.rs @@ -1,3 +1,5 @@ +//! Checks global path resolution of `mem::drop` using a leading `::`. + //@ run-pass #![allow(dropping_copy_types)] diff --git a/tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs new file mode 100644 index 000000000000..2d5a444a942d --- /dev/null +++ b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.rs @@ -0,0 +1,22 @@ +//! Tests that all lifetime parameters in struct (`S`) and enum (`E`) constructors are +//! treated as early bound, similar to associated items, rather than late bound as in manual +//! constructors. + +struct S<'a, 'b>(&'a u8, &'b u8); +enum E<'a, 'b> { + V(&'a u8), + U(&'b u8), +} + +fn main() { + S(&0, &0); // OK + S::<'static>(&0, &0); + //~^ ERROR struct takes 2 lifetime arguments + S::<'static, 'static, 'static>(&0, &0); + //~^ ERROR struct takes 2 lifetime arguments + E::V(&0); // OK + E::V::<'static>(&0); + //~^ ERROR enum takes 2 lifetime arguments + E::V::<'static, 'static, 'static>(&0); + //~^ ERROR enum takes 2 lifetime arguments +} diff --git a/tests/ui/constructor-lifetime-args.stderr b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.stderr similarity index 79% rename from tests/ui/constructor-lifetime-args.stderr rename to tests/ui/lifetimes/constructor-lifetime-early-binding-error.stderr index d3759f4b3658..94699a3509b5 100644 --- a/tests/ui/constructor-lifetime-args.stderr +++ b/tests/ui/lifetimes/constructor-lifetime-early-binding-error.stderr @@ -1,5 +1,5 @@ error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/constructor-lifetime-args.rs:17:5 + --> $DIR/constructor-lifetime-early-binding-error.rs:13:5 | LL | S::<'static>(&0, &0); | ^ ------- supplied 1 lifetime argument @@ -7,7 +7,7 @@ LL | S::<'static>(&0, &0); | expected 2 lifetime arguments | note: struct defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/constructor-lifetime-args.rs:9:8 + --> $DIR/constructor-lifetime-early-binding-error.rs:5:8 | LL | struct S<'a, 'b>(&'a u8, &'b u8); | ^ -- -- @@ -17,7 +17,7 @@ LL | S::<'static, 'static>(&0, &0); | +++++++++ error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied - --> $DIR/constructor-lifetime-args.rs:19:5 + --> $DIR/constructor-lifetime-early-binding-error.rs:15:5 | LL | S::<'static, 'static, 'static>(&0, &0); | ^ --------- help: remove the lifetime argument @@ -25,13 +25,13 @@ LL | S::<'static, 'static, 'static>(&0, &0); | expected 2 lifetime arguments | note: struct defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/constructor-lifetime-args.rs:9:8 + --> $DIR/constructor-lifetime-early-binding-error.rs:5:8 | LL | struct S<'a, 'b>(&'a u8, &'b u8); | ^ -- -- error[E0107]: enum takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/constructor-lifetime-args.rs:22:8 + --> $DIR/constructor-lifetime-early-binding-error.rs:18:8 | LL | E::V::<'static>(&0); | ^ ------- supplied 1 lifetime argument @@ -39,7 +39,7 @@ LL | E::V::<'static>(&0); | expected 2 lifetime arguments | note: enum defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/constructor-lifetime-args.rs:10:6 + --> $DIR/constructor-lifetime-early-binding-error.rs:6:6 | LL | enum E<'a, 'b> { | ^ -- -- @@ -49,7 +49,7 @@ LL | E::V::<'static, 'static>(&0); | +++++++++ error[E0107]: enum takes 2 lifetime arguments but 3 lifetime arguments were supplied - --> $DIR/constructor-lifetime-args.rs:24:8 + --> $DIR/constructor-lifetime-early-binding-error.rs:20:8 | LL | E::V::<'static, 'static, 'static>(&0); | ^ --------- help: remove the lifetime argument @@ -57,7 +57,7 @@ LL | E::V::<'static, 'static, 'static>(&0); | expected 2 lifetime arguments | note: enum defined here, with 2 lifetime parameters: `'a`, `'b` - --> $DIR/constructor-lifetime-args.rs:10:6 + --> $DIR/constructor-lifetime-early-binding-error.rs:6:6 | LL | enum E<'a, 'b> { | ^ -- -- diff --git a/tests/ui/crate_type_flag.rs b/tests/ui/linking/crate-type-invalid-flag-error.rs similarity index 59% rename from tests/ui/crate_type_flag.rs rename to tests/ui/linking/crate-type-invalid-flag-error.rs index 03bea3638e1a..3f84184c989a 100644 --- a/tests/ui/crate_type_flag.rs +++ b/tests/ui/linking/crate-type-invalid-flag-error.rs @@ -1,3 +1,5 @@ +// Test for #70183 that --crate-type flag display valid value. + //@ compile-flags: --crate-type dynlib fn main() {} diff --git a/tests/ui/crate_type_flag.stderr b/tests/ui/linking/crate-type-invalid-flag-error.stderr similarity index 100% rename from tests/ui/crate_type_flag.stderr rename to tests/ui/linking/crate-type-invalid-flag-error.stderr From 143354c52b1dd8ba7c665c123fd7ed0f2396d7b4 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sun, 8 Jun 2025 03:44:44 +0500 Subject: [PATCH 073/183] added test for 30904 --- .../fn-traits-hrtb-coercion.rs | 39 +++++++++++++++++++ .../fn-traits-hrtb-coercion.stderr | 14 +++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs create mode 100644 tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr diff --git a/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs new file mode 100644 index 000000000000..4a08bf28bf3c --- /dev/null +++ b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.rs @@ -0,0 +1,39 @@ +//! Test for issue +//! Related to higher-ranked lifetime inference with unboxed closures and FnOnce. + +#![feature(fn_traits, unboxed_closures)] + +fn test FnOnce<(&'x str,)>>(_: F) {} + +struct Compose(F, G); + +impl FnOnce<(T,)> for Compose +where + F: FnOnce<(T,)>, + G: FnOnce<(F::Output,)>, +{ + type Output = G::Output; + extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { + (self.1)((self.0)(x)) + } +} + +struct Str<'a>(&'a str); + +fn mk_str<'a>(s: &'a str) -> Str<'a> { + Str(s) +} + +fn main() { + let _: for<'a> fn(&'a str) -> Str<'a> = mk_str; + let _: for<'a> fn(&'a str) -> Str<'a> = Str; + //~^ ERROR: mismatched types + + test(|_: &str| {}); + test(mk_str); + test(Str); + + test(Compose(|_: &str| {}, |_| {})); + test(Compose(mk_str, |_| {})); + test(Compose(Str, |_| {})); +} diff --git a/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr new file mode 100644 index 000000000000..a31d99f45d59 --- /dev/null +++ b/tests/ui/unboxed-closures/fn-traits-hrtb-coercion.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/fn-traits-hrtb-coercion.rs:29:45 + | +LL | let _: for<'a> fn(&'a str) -> Str<'a> = Str; + | ------------------------------ ^^^ one type is more general than the other + | | + | expected due to this + | + = note: expected fn pointer `for<'a> fn(&'a _) -> Str<'a>` + found struct constructor `fn(&_) -> Str<'_> {Str::<'_>}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From cc3e57147e7cf5933a2bfa4b92b5a3a5eb424997 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 4 Jun 2025 20:56:35 +0000 Subject: [PATCH 074/183] Use the in-tree `compiler-builtins` Many of `std`'s dependency have a dependency on the crates.io `compiler-builtins` when used with the feature `rustc-std-workspace-core`. Use a Cargo patch to select the in-tree version instead. `compiler-builtins` is also added as a dependency of `rustc-std-workspace-core` so these crates can remove their crates.io dependency in the future. --- Cargo.lock | 5 ++- .../build_system/build_sysroot/Cargo.toml | 2 +- library/Cargo.lock | 5 +-- library/Cargo.toml | 1 + library/alloc/Cargo.toml | 2 +- .../compiler-builtins/Cargo.toml | 4 +- library/panic_abort/Cargo.toml | 2 +- library/panic_unwind/Cargo.toml | 2 +- library/rustc-std-workspace-core/Cargo.toml | 1 + library/rustc-std-workspace-core/lib.rs | 4 ++ library/std/Cargo.toml | 2 +- library/unwind/Cargo.toml | 2 +- src/tools/miri/cargo-miri/Cargo.lock | 45 +++++++++++++++++-- src/tools/miri/cargo-miri/Cargo.toml | 2 +- tests/run-make/linker-warning/short-error.txt | 2 +- 15 files changed, 62 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 164617c909fe..ecdc93daa98c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3118,11 +3118,12 @@ dependencies = [ [[package]] name = "rustc-build-sysroot" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0" +checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc" dependencies = [ "anyhow", + "regex", "rustc_version", "tempfile", "walkdir", diff --git a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml index 24152070e645..931f6097abc2 100644 --- a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml +++ b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml @@ -6,7 +6,6 @@ resolver = "2" [dependencies] core = { path = "./sysroot_src/library/core" } -compiler_builtins = "0.1" alloc = { path = "./sysroot_src/library/alloc" } std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] } test = { path = "./sysroot_src/library/test" } @@ -16,6 +15,7 @@ proc_macro = { path = "./sysroot_src/library/proc_macro" } rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" } rustc-std-workspace-alloc = { path = "./sysroot_src/library/rustc-std-workspace-alloc" } rustc-std-workspace-std = { path = "./sysroot_src/library/rustc-std-workspace-std" } +compiler_builtins = { path = "./sysroot_src/library/compiler-builtins/compiler-builtins" } # For compiler-builtins we always use a high number of codegen units. # The goal here is to place every single intrinsic into its own object diff --git a/library/Cargo.lock b/library/Cargo.lock index 0c75977ee798..966ae72dc2ad 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -62,11 +62,9 @@ dependencies = [ [[package]] name = "compiler_builtins" version = "0.1.160" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6376049cfa92c0aa8b9ac95fae22184b981c658208d4ed8a1dc553cd83612895" dependencies = [ "cc", - "rustc-std-workspace-core", + "core", ] [[package]] @@ -304,6 +302,7 @@ dependencies = [ name = "rustc-std-workspace-core" version = "1.99.0" dependencies = [ + "compiler_builtins", "core", ] diff --git a/library/Cargo.toml b/library/Cargo.toml index 026ba1470081..35480b9319d7 100644 --- a/library/Cargo.toml +++ b/library/Cargo.toml @@ -50,3 +50,4 @@ rustc-demangle.opt-level = "s" rustc-std-workspace-core = { path = 'rustc-std-workspace-core' } rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' } rustc-std-workspace-std = { path = 'rustc-std-workspace-std' } +compiler_builtins = { path = "compiler-builtins/compiler-builtins" } diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 31b6014af7c1..017c790ecac3 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -16,7 +16,7 @@ bench = false [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.160", features = ['rustc-dep-of-std'] } +compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["rustc-dep-of-std"] } [features] compiler-builtins-mem = ['compiler_builtins/mem'] diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index 11ee91954384..df8e964825b3 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -17,9 +17,7 @@ doctest = false test = false [dependencies] -# For more information on this dependency see -# https://github.com/rust-lang/rust/tree/master/library/rustc-std-workspace-core -core = { version = "1.0.1", optional = true, package = "rustc-std-workspace-core" } +core = { path = "../../core", optional = true } [build-dependencies] cc = { optional = true, version = "1.2" } diff --git a/library/panic_abort/Cargo.toml b/library/panic_abort/Cargo.toml index d7d169671f01..e8c66f1a4dd3 100644 --- a/library/panic_abort/Cargo.toml +++ b/library/panic_abort/Cargo.toml @@ -13,7 +13,7 @@ doc = false [dependencies] core = { path = "../core" } -compiler_builtins = "0.1.0" +compiler_builtins = { path = "../compiler-builtins/compiler-builtins" } [target.'cfg(target_os = "android")'.dependencies] libc = { version = "0.2", default-features = false } diff --git a/library/panic_unwind/Cargo.toml b/library/panic_unwind/Cargo.toml index d176434e06ba..47914b9cd3c6 100644 --- a/library/panic_unwind/Cargo.toml +++ b/library/panic_unwind/Cargo.toml @@ -15,7 +15,7 @@ doc = false alloc = { path = "../alloc" } core = { path = "../core" } unwind = { path = "../unwind" } -compiler_builtins = "0.1.0" +compiler_builtins = { path = "../compiler-builtins/compiler-builtins" } cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] diff --git a/library/rustc-std-workspace-core/Cargo.toml b/library/rustc-std-workspace-core/Cargo.toml index 9315c08a4d19..bd318fc2f9e9 100644 --- a/library/rustc-std-workspace-core/Cargo.toml +++ b/library/rustc-std-workspace-core/Cargo.toml @@ -12,3 +12,4 @@ path = "lib.rs" [dependencies] core = { path = "../core" } +compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["compiler-builtins"] } diff --git a/library/rustc-std-workspace-core/lib.rs b/library/rustc-std-workspace-core/lib.rs index 143278525616..21c047dd36ed 100644 --- a/library/rustc-std-workspace-core/lib.rs +++ b/library/rustc-std-workspace-core/lib.rs @@ -2,3 +2,7 @@ #![no_core] pub use core::*; + +// Crate must be brought into scope so it appears in the crate graph for anything that +// depends on `rustc-std-workspace-core`. +use compiler_builtins as _; diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 196b904d56a1..8ad81959bfbf 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.160" } +compiler_builtins = { path = "../compiler-builtins/compiler-builtins" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index df43e6ae80fb..3472b61fbfbe 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -15,7 +15,7 @@ doc = false [dependencies] core = { path = "../core" } -compiler_builtins = "0.1.0" +compiler_builtins = { path = "../compiler-builtins/compiler-builtins" } cfg-if = "1.0" [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock index c1915ae617e8..d37f8750bde4 100644 --- a/src/tools/miri/cargo-miri/Cargo.lock +++ b/src/tools/miri/cargo-miri/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.97" @@ -207,12 +216,42 @@ dependencies = [ ] [[package]] -name = "rustc-build-sysroot" -version = "0.5.7" +name = "regex" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-build-sysroot" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc" dependencies = [ "anyhow", + "regex", "rustc_version", "tempfile", "walkdir", diff --git a/src/tools/miri/cargo-miri/Cargo.toml b/src/tools/miri/cargo-miri/Cargo.toml index 5c579b2a77d6..e08733959ccc 100644 --- a/src/tools/miri/cargo-miri/Cargo.toml +++ b/src/tools/miri/cargo-miri/Cargo.toml @@ -18,7 +18,7 @@ directories = "6" rustc_version = "0.4" serde_json = "1.0.40" cargo_metadata = "0.19" -rustc-build-sysroot = "0.5.7" +rustc-build-sysroot = "0.5.8" # Enable some feature flags that dev-dependencies need but dependencies # do not. This makes `./miri install` after `./miri build` faster. diff --git a/tests/run-make/linker-warning/short-error.txt b/tests/run-make/linker-warning/short-error.txt index a7f48af885a0..33d03832b7e7 100644 --- a/tests/run-make/linker-warning/short-error.txt +++ b/tests/run-make/linker-warning/short-error.txt @@ -1,6 +1,6 @@ error: linking with `./fake-linker` failed: exit status: 1 | - = note: "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" + = note: "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error" = note: some arguments are omitted. use `--verbose` to show all linker arguments = note: error: baz From f43bb2ac994e356d6e3abbee6f4eb1609a7bd0bd Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 5 Jun 2025 06:00:54 +0000 Subject: [PATCH 075/183] compiler-builtins: Fix a `rustdoc::bare-urls` error --- .../compiler-builtins/compiler-builtins/src/aarch64_linux.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs b/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs index e238d0237eb3..226121237e87 100644 --- a/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs +++ b/library/compiler-builtins/compiler-builtins/src/aarch64_linux.rs @@ -4,7 +4,7 @@ //! To avoid breaking backwards compat, C toolchains introduced a concept of "outlined atomics", //! where atomic operations call into the compiler runtime to dispatch between two depending on //! which is supported on the current CPU. -//! See https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10#:~:text=out%20of%20line%20atomics for more discussion. +//! See for more discussion. //! //! Currently we only support LL/SC, because LSE requires `getauxval` from libc in order to do runtime detection. //! Use the `compiler-rt` intrinsics if you want LSE support. From f413f157675f585eb3a7cae9a808d54d4ba32a29 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 8 Jun 2025 04:56:16 +0000 Subject: [PATCH 076/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 84a353bfbcf3..d1a5ef7b7fce 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -775e0c8aeb8f63192854b27156f8b05a06b51814 +a5584a8fe16037dc01782064fa41424a6dbe9987 From 873122c006315e541c30809210089606877122c5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 23 May 2025 12:24:55 +0200 Subject: [PATCH 077/183] add (back) unsupported_calling_conventions lint to reject more invalid calling conventions --- Cargo.lock | 1 + compiler/rustc_hir_analysis/Cargo.toml | 1 + .../rustc_hir_analysis/src/check/check.rs | 49 ++- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_lint/src/lib.rs | 1 - compiler/rustc_lint_defs/src/builtin.rs | 48 +++ compiler/rustc_target/src/spec/abi_map.rs | 3 - compiler/rustc_target/src/spec/mod.rs | 2 +- tests/ui/abi/unsupported.aarch64.stderr | 173 ++++++-- tests/ui/abi/unsupported.arm.stderr | 165 ++++++-- tests/ui/abi/unsupported.i686.stderr | 54 +-- tests/ui/abi/unsupported.riscv32.stderr | 165 ++++++-- tests/ui/abi/unsupported.riscv64.stderr | 165 ++++++-- tests/ui/abi/unsupported.rs | 87 +++- tests/ui/abi/unsupported.x64.stderr | 133 +++++-- tests/ui/abi/unsupported.x64_win.stderr | 375 ++++++++++++++++++ tests/ui/suggestions/abi-typo.fixed | 4 +- tests/ui/suggestions/abi-typo.rs | 4 +- tests/ui/suggestions/abi-typo.stderr | 12 +- 19 files changed, 1199 insertions(+), 245 deletions(-) create mode 100644 tests/ui/abi/unsupported.x64_win.stderr diff --git a/Cargo.lock b/Cargo.lock index 164617c909fe..8296e225c5f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3786,6 +3786,7 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", + "rustc_target", "rustc_trait_selection", "smallvec", "tracing", diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index f2b82c679b93..899370b34e49 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -26,6 +26,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 102fc2a63be8..26a6d67f230b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -11,7 +11,8 @@ use rustc_hir::{LangItem, Node, intravisit}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, ObligationCauseCode}; use rustc_lint_defs::builtin::{ - REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, + REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS, + UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, }; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; @@ -24,6 +25,7 @@ use rustc_middle::ty::{ TypeVisitable, TypeVisitableExt, fold_regions, }; use rustc_session::lint::builtin::UNINHABITED_STATIC; +use rustc_target::spec::{AbiMap, AbiMapping}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits; @@ -35,25 +37,38 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; -pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) { - if !tcx.sess.target.is_abi_supported(abi) { - struct_span_code_err!( - tcx.dcx(), - span, - E0570, - "`{abi}` is not a supported ABI for the current target", - ) - .emit(); +pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) { + match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { + AbiMapping::Direct(..) => (), + AbiMapping::Invalid => { + struct_span_code_err!( + tcx.dcx(), + span, + E0570, + "`{abi}` is not a supported ABI for the current target", + ) + .emit(); + } + AbiMapping::Deprecated(..) => { + tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { + lint.primary_message("use of calling convention not supported on this target"); + }); + } } } pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) { - if !tcx.sess.target.is_abi_supported(abi) { - tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.primary_message(format!( - "the calling convention {abi} is not supported on this target" - )); - }); + // This is always an FCW, even for `AbiMapping::Invalid`, since we started linting later than + // in `check_abi` above. + match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { + AbiMapping::Direct(..) => (), + AbiMapping::Deprecated(..) | AbiMapping::Invalid => { + tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { + lint.primary_message(format!( + "the calling convention {abi} is not supported on this target" + )); + }); + } } } @@ -779,7 +794,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { let hir::ItemKind::ForeignMod { abi, items } = it.kind else { return; }; - check_abi(tcx, it.span, abi); + check_abi(tcx, it.hir_id(), it.span, abi); for item in items { let def_id = item.id.owner_id.def_id; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b0346f8d32eb..ca8b1c95ff3e 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -150,7 +150,7 @@ fn typeck_with_inspect<'tcx>( tcx.fn_sig(def_id).instantiate_identity() }; - check_abi(tcx, span, fn_sig.abi()); + check_abi(tcx, id, span, fn_sig.abi()); // Compute the function signature from point of view of inside the fn. let mut fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c86f66cc9b09..72bfeaddbf1a 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -599,7 +599,6 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see PR #125380 \ for more information", ); - store.register_removed("unsupported_calling_conventions", "converted into hard error"); store.register_removed( "cenum_impl_drop_cast", "converted into hard error, \ diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 843d57784213..777118e69fb1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3621,6 +3621,54 @@ declare_lint! { crate_level_only } +declare_lint! { + /// The `unsupported_calling_conventions` lint is output whenever there is a use of the + /// `stdcall`, `fastcall`, and `cdecl` calling conventions (or their unwind + /// variants) on targets that cannot meaningfully be supported for the requested target. + /// + /// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc + /// code, because this calling convention was never specified for those targets. + /// + /// Historically MSVC toolchains have fallen back to the regular C calling convention for + /// targets other than x86, but Rust doesn't really see a similar need to introduce a similar + /// hack across many more targets. + /// + /// ### Example + /// + /// ```rust,ignore (needs specific targets) + /// extern "stdcall" fn stdcall() {} + /// ``` + /// + /// This will produce: + /// + /// ```text + /// warning: use of calling convention not supported on this target + /// --> $DIR/unsupported.rs:39:1 + /// | + /// LL | extern "stdcall" fn stdcall() {} + /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// | + /// = note: `#[warn(unsupported_calling_conventions)]` on by default + /// = warning: this was previously accepted by the compiler but is being phased out; + /// it will become a hard error in a future release! + /// = note: for more information, see issue ... + /// ``` + /// + /// ### Explanation + /// + /// On most of the targets the behaviour of `stdcall` and similar calling conventions is not + /// defined at all, but was previously accepted due to a bug in the implementation of the + /// compiler. + pub UNSUPPORTED_CALLING_CONVENTIONS, + Warn, + "use of unsupported calling convention", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseError, + report_in_deps: true, + reference: "issue #137018 ", + }; +} + declare_lint! { /// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of /// a target dependent calling convention on a target that does not support this calling diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index d9101f79f046..4ce0a97892c0 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -115,9 +115,6 @@ impl AbiMap { (ExternAbi::Vectorcall { .. }, Arch::X86 | Arch::X86_64) => { CanonAbi::X86(X86Call::Vectorcall) } - (ExternAbi::Vectorcall { .. }, _) if os == OsKind::Windows => { - return AbiMapping::Deprecated(CanonAbi::C); - } (ExternAbi::Vectorcall { .. }, _) => return AbiMapping::Invalid, (ExternAbi::SysV64 { .. }, Arch::X86_64) => CanonAbi::X86(X86Call::SysV64), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 6529c2d72c82..7c82d6bef3ad 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -62,7 +62,7 @@ mod abi_map; mod base; mod json; -pub use abi_map::AbiMap; +pub use abi_map::{AbiMap, AbiMapping}; pub use base::apple; pub use base::avr::ef_avr_arch; diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index c11cc4e2d52e..930552eef618 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:40:1 + --> $DIR/unsupported.rs:43:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:64:1 + --> $DIR/unsupported.rs:70:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:129:1 + --> $DIR/unsupported.rs:140:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:154:1 + --> $DIR/unsupported.rs:168:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -114,13 +114,47 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:180:1 + --> $DIR/unsupported.rs:199:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:266:1 + | +LL | extern "vectorcall" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +163,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -138,77 +172,92 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:200:1 + --> $DIR/unsupported.rs:285:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:33:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:1 + --> $DIR/unsupported.rs:48:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:1 + --> $DIR/unsupported.rs:124:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:135:1 + --> $DIR/unsupported.rs:146:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:161:1 + --> $DIR/unsupported.rs:176:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:250:1 + | +LL | extern "vectorcall" fn vectorcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:193:1 + --> $DIR/unsupported.rs:278:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 19 previous errors; 10 warnings emitted +error: aborting due to 21 previous errors; 14 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +268,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -230,7 +279,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +290,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -252,7 +301,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +312,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -274,7 +323,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -285,7 +334,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -294,9 +343,42 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -307,7 +389,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -316,3 +398,14 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index b2f24381336a..f7562f0d5742 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:40:1 + --> $DIR/unsupported.rs:43:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:129:1 + --> $DIR/unsupported.rs:140:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:154:1 + --> $DIR/unsupported.rs:168:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,47 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:180:1 + --> $DIR/unsupported.rs:199:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:266:1 + | +LL | extern "vectorcall" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +148,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,71 +157,86 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:200:1 + --> $DIR/unsupported.rs:285:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:33:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:1 + --> $DIR/unsupported.rs:124:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:135:1 + --> $DIR/unsupported.rs:146:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:161:1 + --> $DIR/unsupported.rs:176:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:250:1 + | +LL | extern "vectorcall" fn vectorcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:193:1 + --> $DIR/unsupported.rs:278:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors; 9 warnings emitted +error: aborting due to 19 previous errors; 13 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +247,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +258,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +269,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +280,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +291,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +302,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -262,9 +311,42 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +357,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -284,3 +366,14 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 94bd9b8af90d..4e8a43a84f90 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:40:1 + --> $DIR/unsupported.rs:43:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:64:1 + --> $DIR/unsupported.rs:70:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,49 +93,49 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:200:1 + --> $DIR/unsupported.rs:285:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:33:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:1 + --> $DIR/unsupported.rs:48:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:193:1 + --> $DIR/unsupported.rs:278:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ error: aborting due to 13 previous errors; 7 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +178,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index c6ff47283c6e..bba7875dcb19 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:40:1 + --> $DIR/unsupported.rs:43:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:64:1 + --> $DIR/unsupported.rs:70:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:129:1 + --> $DIR/unsupported.rs:140:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:154:1 + --> $DIR/unsupported.rs:168:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,47 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:180:1 + --> $DIR/unsupported.rs:199:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:266:1 + | +LL | extern "vectorcall" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +148,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,71 +157,86 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:200:1 + --> $DIR/unsupported.rs:285:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:33:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:1 + --> $DIR/unsupported.rs:48:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:1 + --> $DIR/unsupported.rs:124:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:135:1 + --> $DIR/unsupported.rs:146:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:161:1 + --> $DIR/unsupported.rs:176:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:250:1 + | +LL | extern "vectorcall" fn vectorcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:193:1 + --> $DIR/unsupported.rs:278:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors; 9 warnings emitted +error: aborting due to 19 previous errors; 13 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +247,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -209,7 +258,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +269,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +280,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +291,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +302,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -262,9 +311,42 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +357,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -284,3 +366,14 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index c6ff47283c6e..bba7875dcb19 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:40:1 + --> $DIR/unsupported.rs:43:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:64:1 + --> $DIR/unsupported.rs:70:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:129:1 + --> $DIR/unsupported.rs:140:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:154:1 + --> $DIR/unsupported.rs:168:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,47 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:180:1 + --> $DIR/unsupported.rs:199:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:266:1 + | +LL | extern "vectorcall" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +148,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,71 +157,86 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:200:1 + --> $DIR/unsupported.rs:285:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:33:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:1 + --> $DIR/unsupported.rs:48:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:1 + --> $DIR/unsupported.rs:124:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:135:1 + --> $DIR/unsupported.rs:146:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:161:1 + --> $DIR/unsupported.rs:176:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error[E0570]: `"vectorcall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:250:1 + | +LL | extern "vectorcall" fn vectorcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:193:1 + --> $DIR/unsupported.rs:278:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors; 9 warnings emitted +error: aborting due to 19 previous errors; 13 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +247,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -209,7 +258,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +269,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +280,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:118:15 + --> $DIR/unsupported.rs:129:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +291,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +302,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -262,9 +311,42 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "vectorcall" is not supported on this target + --> $DIR/unsupported.rs:255:22 + | +LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +357,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -284,3 +366,14 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 84646502f6fd..01a9ded257e3 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -1,8 +1,10 @@ //@ add-core-stubs -//@ revisions: x64 i686 aarch64 arm riscv32 riscv64 +//@ revisions: x64 x64_win i686 aarch64 arm riscv32 riscv64 // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib +//@ [x64_win] needs-llvm-components: x86 +//@ [x64_win] compile-flags: --target=x86_64-pc-windows-msvc --crate-type=rlib //@ [i686] needs-llvm-components: x86 //@ [i686] compile-flags: --target=i686-unknown-linux-gnu --crate-type=rlib //@ [aarch64] needs-llvm-components: aarch64 @@ -24,6 +26,7 @@ abi_x86_interrupt, abi_riscv_interrupt, abi_c_cmse_nonsecure_call, + abi_vectorcall, cmse_nonsecure_entry )] @@ -48,6 +51,7 @@ extern "aapcs" fn aapcs() {} //[aarch64]~^^^ ERROR is not a supported ABI //[riscv32]~^^^^ ERROR is not a supported ABI //[riscv64]~^^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^^ ERROR is not a supported ABI fn aapcs_ptr(f: extern "aapcs" fn()) { //[x64]~^ WARN unsupported_fn_ptr_calling_conventions //[x64]~^^ WARN this was previously accepted @@ -59,6 +63,8 @@ fn aapcs_ptr(f: extern "aapcs" fn()) { //[riscv32]~^^^^^^^^ WARN this was previously accepted //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions //[riscv64]~^^^^^^^^^^ WARN this was previously accepted + //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted f() } extern "aapcs" {} @@ -67,6 +73,7 @@ extern "aapcs" {} //[aarch64]~^^^ ERROR is not a supported ABI //[riscv32]~^^^^ ERROR is not a supported ABI //[riscv64]~^^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^^ ERROR is not a supported ABI extern "msp430-interrupt" fn msp430() {} //~^ ERROR is not a supported ABI @@ -93,6 +100,7 @@ extern "riscv-interrupt-m" fn riscv() {} //[x64]~^^ ERROR is not a supported ABI //[i686]~^^^ ERROR is not a supported ABI //[aarch64]~^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^ ERROR is not a supported ABI fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { //[arm]~^ WARN unsupported_fn_ptr_calling_conventions //[arm]~^^ WARN this was previously accepted @@ -102,6 +110,8 @@ fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { //[i686]~^^^^^^ WARN this was previously accepted //[aarch64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions //[aarch64]~^^^^^^^^ WARN this was previously accepted + //[x64_win]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[x64_win]~^^^^^^^^^^ WARN this was previously accepted f() } extern "riscv-interrupt-m" {} @@ -109,6 +119,7 @@ extern "riscv-interrupt-m" {} //[x64]~^^ ERROR is not a supported ABI //[i686]~^^^ ERROR is not a supported ABI //[aarch64]~^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^ ERROR is not a supported ABI extern "x86-interrupt" fn x86() {} //[aarch64]~^ ERROR is not a supported ABI @@ -138,6 +149,7 @@ extern "thiscall" fn thiscall() {} //[aarch64]~^^^ ERROR is not a supported ABI //[riscv32]~^^^^ ERROR is not a supported ABI //[riscv64]~^^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^^ ERROR is not a supported ABI fn thiscall_ptr(f: extern "thiscall" fn()) { //[x64]~^ WARN unsupported_fn_ptr_calling_conventions //[x64]~^^ WARN this was previously accepted @@ -149,6 +161,8 @@ fn thiscall_ptr(f: extern "thiscall" fn()) { //[riscv32]~^^^^^^^^ WARN this was previously accepted //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions //[riscv64]~^^^^^^^^^^ WARN this was previously accepted + //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted f() } extern "thiscall" {} @@ -157,6 +171,7 @@ extern "thiscall" {} //[aarch64]~^^^ ERROR is not a supported ABI //[riscv32]~^^^^ ERROR is not a supported ABI //[riscv64]~^^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^^ ERROR is not a supported ABI extern "stdcall" fn stdcall() {} //[x64]~^ ERROR is not a supported ABI @@ -164,6 +179,8 @@ extern "stdcall" fn stdcall() {} //[aarch64]~^^^ ERROR is not a supported ABI //[riscv32]~^^^^ ERROR is not a supported ABI //[riscv64]~^^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^^ WARN unsupported_calling_conventions +//[x64_win]~^^^^^^^ WARN this was previously accepted fn stdcall_ptr(f: extern "stdcall" fn()) { //[x64]~^ WARN unsupported_fn_ptr_calling_conventions //[x64]~^^ WARN this was previously accepted @@ -175,6 +192,8 @@ fn stdcall_ptr(f: extern "stdcall" fn()) { //[riscv32]~^^^^^^^^ WARN this was previously accepted //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions //[riscv64]~^^^^^^^^^^ WARN this was previously accepted + //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted f() } extern "stdcall" {} @@ -183,6 +202,72 @@ extern "stdcall" {} //[aarch64]~^^^ ERROR is not a supported ABI //[riscv32]~^^^^ ERROR is not a supported ABI //[riscv64]~^^^^^ ERROR is not a supported ABI +//[x64_win]~^^^^^^ WARN unsupported_calling_conventions +//[x64_win]~^^^^^^^ WARN this was previously accepted + +extern "cdecl" fn cdecl() {} +//[x64]~^ WARN unsupported_calling_conventions +//[x64]~^^ WARN this was previously accepted +//[arm]~^^^ WARN unsupported_calling_conventions +//[arm]~^^^^ WARN this was previously accepted +//[aarch64]~^^^^^ WARN unsupported_calling_conventions +//[aarch64]~^^^^^^ WARN this was previously accepted +//[riscv32]~^^^^^^^ WARN unsupported_calling_conventions +//[riscv32]~^^^^^^^^ WARN this was previously accepted +//[riscv64]~^^^^^^^^^ WARN unsupported_calling_conventions +//[riscv64]~^^^^^^^^^^ WARN this was previously accepted +//[x64_win]~^^^^^^^^^^^ WARN unsupported_calling_conventions +//[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted +fn cdecl_ptr(f: extern "cdecl" fn()) { + //[x64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64]~^^ WARN this was previously accepted + //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions + //[arm]~^^^^ WARN this was previously accepted + //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[aarch64]~^^^^^^ WARN this was previously accepted + //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[riscv32]~^^^^^^^^ WARN this was previously accepted + //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[riscv64]~^^^^^^^^^^ WARN this was previously accepted + //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted + f() +} +extern "cdecl" {} +//[x64]~^ WARN unsupported_calling_conventions +//[x64]~^^ WARN this was previously accepted +//[arm]~^^^ WARN unsupported_calling_conventions +//[arm]~^^^^ WARN this was previously accepted +//[aarch64]~^^^^^ WARN unsupported_calling_conventions +//[aarch64]~^^^^^^ WARN this was previously accepted +//[riscv32]~^^^^^^^ WARN unsupported_calling_conventions +//[riscv32]~^^^^^^^^ WARN this was previously accepted +//[riscv64]~^^^^^^^^^ WARN unsupported_calling_conventions +//[riscv64]~^^^^^^^^^^ WARN this was previously accepted +//[x64_win]~^^^^^^^^^^^ WARN unsupported_calling_conventions +//[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted + +extern "vectorcall" fn vectorcall() {} +//[arm]~^ ERROR is not a supported ABI +//[aarch64]~^^ ERROR is not a supported ABI +//[riscv32]~^^^ ERROR is not a supported ABI +//[riscv64]~^^^^ ERROR is not a supported ABI +fn vectorcall_ptr(f: extern "vectorcall" fn()) { + //[arm]~^ WARN unsupported_fn_ptr_calling_conventions + //[arm]~^^ WARN this was previously accepted + //[aarch64]~^^^ WARN unsupported_fn_ptr_calling_conventions + //[aarch64]~^^^^ WARN this was previously accepted + //[riscv32]~^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[riscv32]~^^^^^^ WARN this was previously accepted + //[riscv64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions + //[riscv64]~^^^^^^^^ WARN this was previously accepted + f() +} +extern "vectorcall" {} +//[arm]~^ ERROR is not a supported ABI +//[aarch64]~^^ ERROR is not a supported ABI +//[riscv32]~^^^ ERROR is not a supported ABI +//[riscv64]~^^^^ ERROR is not a supported ABI fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { //~^ WARN unsupported_fn_ptr_calling_conventions diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 0a9f9a69123c..35276b9281ce 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,5 +1,5 @@ warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,13 +9,13 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:40:1 + --> $DIR/unsupported.rs:43:1 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:64:1 + --> $DIR/unsupported.rs:70:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:154:1 + --> $DIR/unsupported.rs:168:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,32 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:180:1 + --> $DIR/unsupported.rs:199:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +133,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,71 +142,80 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:200:1 + --> $DIR/unsupported.rs:285:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:33:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:45:1 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:45:1 + --> $DIR/unsupported.rs:48:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:71:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:135:1 + --> $DIR/unsupported.rs:146:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:161:1 + --> $DIR/unsupported.rs:176:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:193:1 + --> $DIR/unsupported.rs:278:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors; 9 warnings emitted +error: aborting due to 17 previous errors; 12 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: warning: the calling convention "ptx-kernel" is not supported on this target - --> $DIR/unsupported.rs:35:15 + --> $DIR/unsupported.rs:38:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +226,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:51:17 + --> $DIR/unsupported.rs:55:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -209,7 +237,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:73:18 + --> $DIR/unsupported.rs:80:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +248,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:83:15 + --> $DIR/unsupported.rs:90:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +259,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:96:17 + --> $DIR/unsupported.rs:104:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -242,7 +270,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:141:20 + --> $DIR/unsupported.rs:153:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +281,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:167:19 + --> $DIR/unsupported.rs:184:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -262,9 +290,31 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:187:21 + --> $DIR/unsupported.rs:272:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,7 +325,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:195:22 + --> $DIR/unsupported.rs:280:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -284,3 +334,14 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr new file mode 100644 index 000000000000..3e6f8c268fd3 --- /dev/null +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -0,0 +1,375 @@ +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:38:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:43:1 + | +LL | extern "ptx-kernel" {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:55:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"aapcs"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:70:1 + | +LL | extern "aapcs" {} + | ^^^^^^^^^^^^^^^^^ + +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:80:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:85:1 + | +LL | extern "msp430-interrupt" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:90:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:95:1 + | +LL | extern "avr-interrupt" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: the calling convention "riscv-interrupt-m" is not supported on this target + --> $DIR/unsupported.rs:104:17 + | +LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:117:1 + | +LL | extern "riscv-interrupt-m" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:153:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"thiscall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:168:1 + | +LL | extern "thiscall" {} + | ^^^^^^^^^^^^^^^^^^^^ + +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:184:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:199:1 + | +LL | extern "stdcall" {} + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:272:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:280:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + +error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:285:1 + | +LL | extern "C-cmse-nonsecure-entry" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:36:1 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"gpu-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:45:1 + | +LL | extern "gpu-kernel" fn gpu() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"aapcs"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:48:1 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:78:1 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:88:1 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:98:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"thiscall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:146:1 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:176:1 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + +error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:278:1 + | +LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 15 previous errors; 14 warnings emitted + +For more information about this error, try `rustc --explain E0570`. +Future incompatibility report: Future breakage diagnostic: +warning: the calling convention "ptx-kernel" is not supported on this target + --> $DIR/unsupported.rs:38:15 + | +LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "aapcs" is not supported on this target + --> $DIR/unsupported.rs:55:17 + | +LL | fn aapcs_ptr(f: extern "aapcs" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "msp430-interrupt" is not supported on this target + --> $DIR/unsupported.rs:80:18 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "avr-interrupt" is not supported on this target + --> $DIR/unsupported.rs:90:15 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "riscv-interrupt-m" is not supported on this target + --> $DIR/unsupported.rs:104:17 + | +LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "thiscall" is not supported on this target + --> $DIR/unsupported.rs:153:20 + | +LL | fn thiscall_ptr(f: extern "thiscall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "stdcall" is not supported on this target + --> $DIR/unsupported.rs:184:19 + | +LL | fn stdcall_ptr(f: extern "stdcall" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:199:1 + | +LL | extern "stdcall" {} + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "cdecl" is not supported on this target + --> $DIR/unsupported.rs:221:17 + | +LL | fn cdecl_ptr(f: extern "cdecl" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:236:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target + --> $DIR/unsupported.rs:272:21 + | +LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target + --> $DIR/unsupported.rs:280:22 + | +LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #130260 + = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:176:1 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:208:1 + | +LL | extern "cdecl" fn cdecl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + diff --git a/tests/ui/suggestions/abi-typo.fixed b/tests/ui/suggestions/abi-typo.fixed index 44fa80f63389..ae507c3e48fb 100644 --- a/tests/ui/suggestions/abi-typo.fixed +++ b/tests/ui/suggestions/abi-typo.fixed @@ -1,6 +1,6 @@ //@ run-rustfix -extern "cdecl" fn cdedl() {} //~ ERROR invalid ABI +extern "system" fn systen() {} //~ ERROR invalid ABI fn main() { - cdedl(); + systen(); } diff --git a/tests/ui/suggestions/abi-typo.rs b/tests/ui/suggestions/abi-typo.rs index 3d5c23e0f23a..c40bd803e530 100644 --- a/tests/ui/suggestions/abi-typo.rs +++ b/tests/ui/suggestions/abi-typo.rs @@ -1,6 +1,6 @@ //@ run-rustfix -extern "cdedl" fn cdedl() {} //~ ERROR invalid ABI +extern "systen" fn systen() {} //~ ERROR invalid ABI fn main() { - cdedl(); + systen(); } diff --git a/tests/ui/suggestions/abi-typo.stderr b/tests/ui/suggestions/abi-typo.stderr index 4d89ac16570e..a8b4d3667052 100644 --- a/tests/ui/suggestions/abi-typo.stderr +++ b/tests/ui/suggestions/abi-typo.stderr @@ -1,14 +1,14 @@ -error[E0703]: invalid ABI: found `cdedl` +error[E0703]: invalid ABI: found `systen` --> $DIR/abi-typo.rs:2:8 | -LL | extern "cdedl" fn cdedl() {} - | ^^^^^^^ invalid ABI +LL | extern "systen" fn systen() {} + | ^^^^^^^^ invalid ABI | = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions -help: there's a similarly named valid ABI `cdecl` +help: there's a similarly named valid ABI `system` | -LL - extern "cdedl" fn cdedl() {} -LL + extern "cdecl" fn cdedl() {} +LL - extern "systen" fn systen() {} +LL + extern "system" fn systen() {} | error: aborting due to 1 previous error From b616e1197482f31c0a403d2dac41bb7425cd70f4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 23 May 2025 12:44:15 +0200 Subject: [PATCH 078/183] raw dylib: ensure that we have applied standard ABI checks also unify error messages that do not seem to have a good reason to be different --- compiler/rustc_metadata/messages.ftl | 9 +++------ compiler/rustc_metadata/src/errors.rs | 11 ++--------- compiler/rustc_metadata/src/native_libs.rs | 12 +++++++++--- tests/ui/abi/unsupported.rs | 6 ++++++ tests/ui/abi/unsupported.x64_win.stderr | 22 +++++++++++++++++++++- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index bccffe392437..3bef5ca114b8 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -272,6 +272,9 @@ metadata_raw_dylib_no_nul = metadata_raw_dylib_only_windows = link kind `raw-dylib` is only supported on Windows targets +metadata_raw_dylib_unsupported_abi = + ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture + metadata_renaming_no_link = renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library @@ -319,12 +322,6 @@ metadata_unknown_link_modifier = metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}` -metadata_unsupported_abi = - ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture - -metadata_unsupported_abi_i686 = - ABI not supported by `#[link(kind = "raw-dylib")]` on i686 - metadata_wasm_c_abi = older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88 diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 16f59793e632..71da42901741 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -300,15 +300,8 @@ pub struct NoLinkModOverride { } #[derive(Diagnostic)] -#[diag(metadata_unsupported_abi_i686)] -pub struct UnsupportedAbiI686 { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_unsupported_abi)] -pub struct UnsupportedAbi { +#[diag(metadata_raw_dylib_unsupported_abi)] +pub struct RawDylibUnsupportedAbi { #[primary_span] pub span: Span, } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index cee9cff07750..5cdeb8935f70 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -652,7 +652,13 @@ impl<'tcx> Collector<'tcx> { ) -> DllImport { let span = self.tcx.def_span(item); - // this logic is similar to `Target::adjust_abi` (in rustc_target/src/spec/mod.rs) but errors on unsupported inputs + // This `extern` block should have been checked for general ABI support before, but let's + // double-check that. + assert!(self.tcx.sess.target.is_abi_supported(abi)); + + // This logic is similar to `AbiMap::canonize_abi` (in rustc_target/src/spec/abi_map.rs) but + // we need more detail than those adjustments, and we can't support all ABIs that are + // generally supported. let calling_convention = if self.tcx.sess.target.arch == "x86" { match abi { ExternAbi::C { .. } | ExternAbi::Cdecl { .. } => DllCallingConvention::C, @@ -679,7 +685,7 @@ impl<'tcx> Collector<'tcx> { DllCallingConvention::Vectorcall(self.i686_arg_list_size(item)) } _ => { - self.tcx.dcx().emit_fatal(errors::UnsupportedAbiI686 { span }); + self.tcx.dcx().emit_fatal(errors::RawDylibUnsupportedAbi { span }); } } } else { @@ -688,7 +694,7 @@ impl<'tcx> Collector<'tcx> { DllCallingConvention::C } _ => { - self.tcx.dcx().emit_fatal(errors::UnsupportedAbi { span }); + self.tcx.dcx().emit_fatal(errors::RawDylibUnsupportedAbi { span }); } } }; diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 01a9ded257e3..b7f718993ef1 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -284,3 +284,9 @@ fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { } extern "C-cmse-nonsecure-entry" {} //~^ ERROR is not a supported ABI + +#[cfg(windows)] +#[link(name = "foo", kind = "raw-dylib")] +extern "cdecl" {} +//[x64_win]~^ WARN use of calling convention not supported on this target +//[x64_win]~^^ WARN this was previously accepted diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr index 3e6f8c268fd3..4e61a6ab2057 100644 --- a/tests/ui/abi/unsupported.x64_win.stderr +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -150,6 +150,15 @@ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:290:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target --> $DIR/unsupported.rs:36:1 | @@ -216,7 +225,7 @@ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 15 previous errors; 14 warnings emitted +error: aborting due to 15 previous errors; 15 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -351,6 +360,17 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:290:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = note: `#[warn(unsupported_calling_conventions)]` on by default + Future breakage diagnostic: warning: use of calling convention not supported on this target --> $DIR/unsupported.rs:176:1 From 1fc6be419adaf4e6573632e283b85b610135a013 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 23 May 2025 14:22:55 +0200 Subject: [PATCH 079/183] avoid repeating error annotations in test file --- tests/ui/abi/unsupported.aarch64.stderr | 86 +++++------ tests/ui/abi/unsupported.arm.stderr | 80 +++++----- tests/ui/abi/unsupported.i686.stderr | 42 ++--- tests/ui/abi/unsupported.riscv32.stderr | 78 +++++----- tests/ui/abi/unsupported.riscv64.stderr | 78 +++++----- tests/ui/abi/unsupported.rs | 196 ++++-------------------- tests/ui/abi/unsupported.x64.stderr | 70 ++++----- tests/ui/abi/unsupported.x64_win.stderr | 78 +++++----- 8 files changed, 290 insertions(+), 418 deletions(-) diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 930552eef618..335ded4b769c 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:1 + --> $DIR/unsupported.rs:55:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:140:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:168:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -114,13 +114,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | extern "cdecl" {} = note: `#[warn(unsupported_calling_conventions)]` on by default warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,13 +148,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:266:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -196,43 +196,43 @@ LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:98:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:124:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:146:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +241,13 @@ LL | extern "cdecl" fn cdecl() {} = note: for more information, see issue #137018 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:250:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -268,7 +268,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -290,7 +290,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -301,7 +301,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -312,7 +312,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -323,7 +323,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -334,7 +334,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -345,7 +345,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -356,7 +356,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -367,7 +367,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -378,7 +378,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -389,7 +389,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -400,7 +400,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index f7562f0d5742..fed529e65bc8 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:140:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:168:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | extern "cdecl" {} = note: `#[warn(unsupported_calling_conventions)]` on by default warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:266:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -175,43 +175,43 @@ LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:98:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:124:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:146:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,13 +220,13 @@ LL | extern "cdecl" fn cdecl() {} = note: for more information, see issue #137018 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:250:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -258,7 +258,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -269,7 +269,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +302,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -324,7 +324,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +346,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,7 +368,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 4e8a43a84f90..d4eabed382aa 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:1 + --> $DIR/unsupported.rs:55:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,25 +117,25 @@ LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:98:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +178,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index bba7875dcb19..8286563bef02 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:1 + --> $DIR/unsupported.rs:55:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:140:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:168:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | extern "cdecl" {} = note: `#[warn(unsupported_calling_conventions)]` on by default warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:266:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,37 +181,37 @@ LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:124:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:146:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,13 +220,13 @@ LL | extern "cdecl" fn cdecl() {} = note: for more information, see issue #137018 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:250:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -258,7 +258,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -269,7 +269,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +302,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -324,7 +324,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +346,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,7 +368,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index bba7875dcb19..8286563bef02 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:1 + --> $DIR/unsupported.rs:55:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:140:1 + --> $DIR/unsupported.rs:95:1 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:168:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | extern "cdecl" {} = note: `#[warn(unsupported_calling_conventions)]` on by default warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:266:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,37 +181,37 @@ LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:124:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:146:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,13 +220,13 @@ LL | extern "cdecl" fn cdecl() {} = note: for more information, see issue #137018 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:250:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -247,7 +247,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -258,7 +258,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -269,7 +269,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "x86-interrupt" is not supported on this target - --> $DIR/unsupported.rs:129:15 + --> $DIR/unsupported.rs:90:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -302,7 +302,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -324,7 +324,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:255:22 + --> $DIR/unsupported.rs:136:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +346,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,7 +368,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index b7f718993ef1..82d72ecad702 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -46,34 +46,14 @@ extern "gpu-kernel" fn gpu() {} //~^ ERROR is not a supported ABI extern "aapcs" fn aapcs() {} -//[x64]~^ ERROR is not a supported ABI -//[i686]~^^ ERROR is not a supported ABI -//[aarch64]~^^^ ERROR is not a supported ABI -//[riscv32]~^^^^ ERROR is not a supported ABI -//[riscv64]~^^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^^ ERROR is not a supported ABI +//[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI fn aapcs_ptr(f: extern "aapcs" fn()) { - //[x64]~^ WARN unsupported_fn_ptr_calling_conventions - //[x64]~^^ WARN this was previously accepted - //[i686]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[i686]~^^^^ WARN this was previously accepted - //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^^^^^ WARN this was previously accepted - //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv32]~^^^^^^^^ WARN this was previously accepted - //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv64]~^^^^^^^^^^ WARN this was previously accepted - //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted + //[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64,x64_win,i686,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted f() } extern "aapcs" {} -//[x64]~^ ERROR is not a supported ABI -//[i686]~^^ ERROR is not a supported ABI -//[aarch64]~^^^ ERROR is not a supported ABI -//[riscv32]~^^^^ ERROR is not a supported ABI -//[riscv64]~^^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^^ ERROR is not a supported ABI +//[x64,x64_win,i686,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI extern "msp430-interrupt" fn msp430() {} //~^ ERROR is not a supported ABI @@ -96,178 +76,70 @@ extern "avr-interrupt" {} //~^ ERROR is not a supported ABI extern "riscv-interrupt-m" fn riscv() {} -//[arm]~^ ERROR is not a supported ABI -//[x64]~^^ ERROR is not a supported ABI -//[i686]~^^^ ERROR is not a supported ABI -//[aarch64]~^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^ ERROR is not a supported ABI +//[x64,x64_win,i686,arm,aarch64]~^ ERROR is not a supported ABI fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { - //[arm]~^ WARN unsupported_fn_ptr_calling_conventions - //[arm]~^^ WARN this was previously accepted - //[x64]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[x64]~^^^^ WARN this was previously accepted - //[i686]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[i686]~^^^^^^ WARN this was previously accepted - //[aarch64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^^^^^^^ WARN this was previously accepted - //[x64_win]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[x64_win]~^^^^^^^^^^ WARN this was previously accepted + //[x64,x64_win,i686,arm,aarch64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64,x64_win,i686,arm,aarch64]~^^ WARN this was previously accepted f() } extern "riscv-interrupt-m" {} -//[arm]~^ ERROR is not a supported ABI -//[x64]~^^ ERROR is not a supported ABI -//[i686]~^^^ ERROR is not a supported ABI -//[aarch64]~^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^ ERROR is not a supported ABI +//[x64,x64_win,i686,arm,aarch64]~^ ERROR is not a supported ABI extern "x86-interrupt" fn x86() {} -//[aarch64]~^ ERROR is not a supported ABI -//[arm]~^^ ERROR is not a supported ABI -//[riscv32]~^^^ ERROR is not a supported ABI -//[riscv64]~^^^^ ERROR is not a supported ABI +//[aarch64,arm,riscv32,riscv64]~^ ERROR is not a supported ABI fn x86_ptr(f: extern "x86-interrupt" fn()) { - //[aarch64]~^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^ WARN this was previously accepted - //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[arm]~^^^^ WARN this was previously accepted - //[riscv32]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv32]~^^^^^^ WARN this was previously accepted - //[riscv64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv64]~^^^^^^^^ WARN this was previously accepted + //[aarch64,arm,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[aarch64,arm,riscv32,riscv64]~^^ WARN this was previously accepted f() } extern "x86-interrupt" {} -//[aarch64]~^ ERROR is not a supported ABI -//[arm]~^^ ERROR is not a supported ABI -//[riscv32]~^^^ ERROR is not a supported ABI -//[riscv64]~^^^^ ERROR is not a supported ABI +//[aarch64,arm,riscv32,riscv64]~^ ERROR is not a supported ABI extern "thiscall" fn thiscall() {} -//[x64]~^ ERROR is not a supported ABI -//[arm]~^^ ERROR is not a supported ABI -//[aarch64]~^^^ ERROR is not a supported ABI -//[riscv32]~^^^^ ERROR is not a supported ABI -//[riscv64]~^^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^^ ERROR is not a supported ABI +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI fn thiscall_ptr(f: extern "thiscall" fn()) { - //[x64]~^ WARN unsupported_fn_ptr_calling_conventions - //[x64]~^^ WARN this was previously accepted - //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[arm]~^^^^ WARN this was previously accepted - //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^^^^^ WARN this was previously accepted - //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv32]~^^^^^^^^ WARN this was previously accepted - //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv64]~^^^^^^^^^^ WARN this was previously accepted - //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted f() } extern "thiscall" {} -//[x64]~^ ERROR is not a supported ABI -//[arm]~^^ ERROR is not a supported ABI -//[aarch64]~^^^ ERROR is not a supported ABI -//[riscv32]~^^^^ ERROR is not a supported ABI -//[riscv64]~^^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^^ ERROR is not a supported ABI +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI extern "stdcall" fn stdcall() {} -//[x64]~^ ERROR is not a supported ABI -//[arm]~^^ ERROR is not a supported ABI -//[aarch64]~^^^ ERROR is not a supported ABI -//[riscv32]~^^^^ ERROR is not a supported ABI -//[riscv64]~^^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^^ WARN unsupported_calling_conventions -//[x64_win]~^^^^^^^ WARN this was previously accepted +//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64_win]~^^ WARN unsupported_calling_conventions +//[x64_win]~^^^ WARN this was previously accepted fn stdcall_ptr(f: extern "stdcall" fn()) { - //[x64]~^ WARN unsupported_fn_ptr_calling_conventions - //[x64]~^^ WARN this was previously accepted - //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[arm]~^^^^ WARN this was previously accepted - //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^^^^^ WARN this was previously accepted - //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv32]~^^^^^^^^ WARN this was previously accepted - //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv64]~^^^^^^^^^^ WARN this was previously accepted - //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted f() } extern "stdcall" {} -//[x64]~^ ERROR is not a supported ABI -//[arm]~^^ ERROR is not a supported ABI -//[aarch64]~^^^ ERROR is not a supported ABI -//[riscv32]~^^^^ ERROR is not a supported ABI -//[riscv64]~^^^^^ ERROR is not a supported ABI -//[x64_win]~^^^^^^ WARN unsupported_calling_conventions -//[x64_win]~^^^^^^^ WARN this was previously accepted +//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64_win]~^^ WARN unsupported_calling_conventions +//[x64_win]~^^^ WARN this was previously accepted extern "cdecl" fn cdecl() {} -//[x64]~^ WARN unsupported_calling_conventions -//[x64]~^^ WARN this was previously accepted -//[arm]~^^^ WARN unsupported_calling_conventions -//[arm]~^^^^ WARN this was previously accepted -//[aarch64]~^^^^^ WARN unsupported_calling_conventions -//[aarch64]~^^^^^^ WARN this was previously accepted -//[riscv32]~^^^^^^^ WARN unsupported_calling_conventions -//[riscv32]~^^^^^^^^ WARN this was previously accepted -//[riscv64]~^^^^^^^^^ WARN unsupported_calling_conventions -//[riscv64]~^^^^^^^^^^ WARN this was previously accepted -//[x64_win]~^^^^^^^^^^^ WARN unsupported_calling_conventions -//[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted fn cdecl_ptr(f: extern "cdecl" fn()) { - //[x64]~^ WARN unsupported_fn_ptr_calling_conventions - //[x64]~^^ WARN this was previously accepted - //[arm]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[arm]~^^^^ WARN this was previously accepted - //[aarch64]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^^^^^ WARN this was previously accepted - //[riscv32]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv32]~^^^^^^^^ WARN this was previously accepted - //[riscv64]~^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv64]~^^^^^^^^^^ WARN this was previously accepted - //[x64_win]~^^^^^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted f() } extern "cdecl" {} -//[x64]~^ WARN unsupported_calling_conventions -//[x64]~^^ WARN this was previously accepted -//[arm]~^^^ WARN unsupported_calling_conventions -//[arm]~^^^^ WARN this was previously accepted -//[aarch64]~^^^^^ WARN unsupported_calling_conventions -//[aarch64]~^^^^^^ WARN this was previously accepted -//[riscv32]~^^^^^^^ WARN unsupported_calling_conventions -//[riscv32]~^^^^^^^^ WARN this was previously accepted -//[riscv64]~^^^^^^^^^ WARN unsupported_calling_conventions -//[riscv64]~^^^^^^^^^^ WARN this was previously accepted -//[x64_win]~^^^^^^^^^^^ WARN unsupported_calling_conventions -//[x64_win]~^^^^^^^^^^^^ WARN this was previously accepted +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted extern "vectorcall" fn vectorcall() {} -//[arm]~^ ERROR is not a supported ABI -//[aarch64]~^^ ERROR is not a supported ABI -//[riscv32]~^^^ ERROR is not a supported ABI -//[riscv64]~^^^^ ERROR is not a supported ABI +//[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI fn vectorcall_ptr(f: extern "vectorcall" fn()) { - //[arm]~^ WARN unsupported_fn_ptr_calling_conventions - //[arm]~^^ WARN this was previously accepted - //[aarch64]~^^^ WARN unsupported_fn_ptr_calling_conventions - //[aarch64]~^^^^ WARN this was previously accepted - //[riscv32]~^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv32]~^^^^^^ WARN this was previously accepted - //[riscv64]~^^^^^^^ WARN unsupported_fn_ptr_calling_conventions - //[riscv64]~^^^^^^^^ WARN this was previously accepted + //[arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted f() } extern "vectorcall" {} -//[arm]~^ ERROR is not a supported ABI -//[aarch64]~^^ ERROR is not a supported ABI -//[riscv32]~^^^ ERROR is not a supported ABI -//[riscv64]~^^^^ ERROR is not a supported ABI +//[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { //~^ WARN unsupported_fn_ptr_calling_conventions diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 35276b9281ce..29ce40441afc 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:1 + --> $DIR/unsupported.rs:55:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:168:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,13 +99,13 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | extern "cdecl" {} = note: `#[warn(unsupported_calling_conventions)]` on by default warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,37 +166,37 @@ LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:98:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:146:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL | extern "cdecl" fn cdecl() {} = note: for more information, see issue #137018 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -226,7 +226,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -237,7 +237,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -248,7 +248,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -259,7 +259,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -270,7 +270,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -281,7 +281,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -292,7 +292,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -303,7 +303,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -314,7 +314,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,7 +336,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr index 4e61a6ab2057..a5468b0e4324 100644 --- a/tests/ui/abi/unsupported.x64_win.stderr +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -15,7 +15,7 @@ LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -24,13 +24,13 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { = note: for more information, see issue #130260 error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:1 + --> $DIR/unsupported.rs:55:1 | LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,13 +39,13 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:85:1 + --> $DIR/unsupported.rs:65:1 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { = note: for more information, see issue #130260 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:95:1 + --> $DIR/unsupported.rs:75:1 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,13 +69,13 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { = note: for more information, see issue #130260 error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:85:1 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -84,13 +84,13 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:168:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | extern "stdcall" {} = note: `#[warn(unsupported_calling_conventions)]` on by default warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | extern "cdecl" {} = note: for more information, see issue #137018 warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,13 +145,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:285:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:290:1 + --> $DIR/unsupported.rs:162:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -178,31 +178,31 @@ LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:78:1 + --> $DIR/unsupported.rs:58:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:88:1 + --> $DIR/unsupported.rs:68:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:98:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:146:1 + --> $DIR/unsupported.rs:98:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #137018 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | extern "cdecl" fn cdecl() {} = note: for more information, see issue #137018 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:278:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { Future breakage diagnostic: warning: the calling convention "aapcs" is not supported on this target - --> $DIR/unsupported.rs:55:17 + --> $DIR/unsupported.rs:50:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -252,7 +252,7 @@ LL | fn aapcs_ptr(f: extern "aapcs" fn()) { Future breakage diagnostic: warning: the calling convention "msp430-interrupt" is not supported on this target - --> $DIR/unsupported.rs:80:18 + --> $DIR/unsupported.rs:60:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "avr-interrupt" is not supported on this target - --> $DIR/unsupported.rs:90:15 + --> $DIR/unsupported.rs:70:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -274,7 +274,7 @@ LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { Future breakage diagnostic: warning: the calling convention "riscv-interrupt-m" is not supported on this target - --> $DIR/unsupported.rs:104:17 + --> $DIR/unsupported.rs:80:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -285,7 +285,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "thiscall" is not supported on this target - --> $DIR/unsupported.rs:153:20 + --> $DIR/unsupported.rs:100:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -296,7 +296,7 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { Future breakage diagnostic: warning: the calling convention "stdcall" is not supported on this target - --> $DIR/unsupported.rs:184:19 + --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -307,7 +307,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:199:1 + --> $DIR/unsupported.rs:117:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -318,7 +318,7 @@ LL | extern "stdcall" {} Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:221:17 + --> $DIR/unsupported.rs:125:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -329,7 +329,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:236:1 + --> $DIR/unsupported.rs:130:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -340,7 +340,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:272:21 + --> $DIR/unsupported.rs:144:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -351,7 +351,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:280:22 + --> $DIR/unsupported.rs:152:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -362,7 +362,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:290:1 + --> $DIR/unsupported.rs:162:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -373,7 +373,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:176:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -384,7 +384,7 @@ LL | extern "stdcall" fn stdcall() {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:208:1 + --> $DIR/unsupported.rs:122:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ From fab11f619dbab4a6b37d8f99d945a459a158ee5b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 29 May 2025 12:10:14 +0200 Subject: [PATCH 080/183] add specific help messages for stdcall and cdecl --- .../rustc_hir_analysis/src/check/check.rs | 26 +++++- tests/ui/abi/unsupported.aarch64.stderr | 72 ++++++++++++---- tests/ui/abi/unsupported.arm.stderr | 72 ++++++++++++---- tests/ui/abi/unsupported.i686.stderr | 12 +-- tests/ui/abi/unsupported.riscv32.stderr | 72 ++++++++++++---- tests/ui/abi/unsupported.riscv64.stderr | 72 ++++++++++++---- tests/ui/abi/unsupported.rs | 7 ++ tests/ui/abi/unsupported.x64.stderr | 64 +++++++++++--- tests/ui/abi/unsupported.x64_win.stderr | 84 +++++++++++++++---- 9 files changed, 375 insertions(+), 106 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 26a6d67f230b..8519ab8d0218 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -4,8 +4,8 @@ use std::ops::ControlFlow; use rustc_abi::FieldIdx; use rustc_attr_data_structures::ReprAttr::ReprPacked; use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_errors::MultiSpan; use rustc_errors::codes::*; +use rustc_errors::{EmissionGuarantee, MultiSpan}; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::{LangItem, Node, intravisit}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; @@ -38,20 +38,38 @@ use super::compare_impl_item::check_type_bounds; use super::*; pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) { + // FIXME: this should be checked earlier, e.g. in `rustc_ast_lowering`, to fix + // things like #86232. + fn add_help(abi: ExternAbi, diag: &mut Diag<'_, T>) { + if let ExternAbi::Cdecl { unwind } = abi { + let c_abi = ExternAbi::C { unwind }; + diag.help(format!("use `extern {c_abi}` instead",)); + } else if let ExternAbi::Stdcall { unwind } = abi { + let c_abi = ExternAbi::C { unwind }; + let system_abi = ExternAbi::System { unwind }; + diag.help(format!( + "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \ + use `extern {system_abi}`" + )); + } + } + match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { AbiMapping::Direct(..) => (), AbiMapping::Invalid => { - struct_span_code_err!( + let mut err = struct_span_code_err!( tcx.dcx(), span, E0570, "`{abi}` is not a supported ABI for the current target", - ) - .emit(); + ); + add_help(abi, &mut err); + err.emit(); } AbiMapping::Deprecated(..) => { tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { lint.primary_message("use of calling convention not supported on this target"); + add_help(abi, lint); }); } } diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 335ded4b769c..ea645780b0d7 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -118,9 +118,19 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -129,17 +139,28 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead + warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,13 +169,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:148:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +184,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -172,7 +193,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,29 +251,32 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 21 previous errors; 14 warnings emitted +error: aborting due to 22 previous errors; 15 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -345,7 +369,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -356,18 +380,31 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -378,7 +415,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -389,7 +426,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -400,12 +437,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index fed529e65bc8..2c82e2951e22 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -103,9 +103,19 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,17 +124,28 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead + warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,13 +154,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:148:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +169,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +178,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,29 +230,32 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 19 previous errors; 13 warnings emitted +error: aborting due to 20 previous errors; 14 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -313,7 +337,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -324,18 +348,31 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +383,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +394,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,12 +405,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index d4eabed382aa..d552f9a132cf 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -75,7 +75,7 @@ LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index 8286563bef02..a0e2901c759f 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -103,9 +103,19 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,17 +124,28 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead + warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,13 +154,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:148:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +169,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +178,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,29 +230,32 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 19 previous errors; 13 warnings emitted +error: aborting due to 20 previous errors; 14 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -313,7 +337,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -324,18 +348,31 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +383,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +394,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,12 +405,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index 8286563bef02..a0e2901c759f 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -103,9 +103,19 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,17 +124,28 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead + warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,13 +154,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:148:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -148,7 +169,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +178,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,29 +230,32 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:141:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 19 previous errors; 13 warnings emitted +error: aborting due to 20 previous errors; 14 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -313,7 +337,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -324,18 +348,31 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:136:22 + --> $DIR/unsupported.rs:143:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -346,7 +383,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +394,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,12 +405,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 82d72ecad702..9ea22ca516b4 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -118,6 +118,10 @@ extern "stdcall" {} //[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI //[x64_win]~^^ WARN unsupported_calling_conventions //[x64_win]~^^^ WARN this was previously accepted +extern "stdcall-unwind" {} +//[x64,arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI +//[x64_win]~^^ WARN unsupported_calling_conventions +//[x64_win]~^^^ WARN this was previously accepted extern "cdecl" fn cdecl() {} //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions @@ -130,6 +134,9 @@ fn cdecl_ptr(f: extern "cdecl" fn()) { extern "cdecl" {} //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted +extern "cdecl-unwind" {} +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions +//[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted extern "vectorcall" fn vectorcall() {} //[arm,aarch64,riscv32,riscv64]~^ ERROR is not a supported ABI diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 29ce40441afc..732a5f84f50e 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -103,9 +103,19 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -114,17 +124,28 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead + warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +154,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +163,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,23 +215,26 @@ error[E0570]: `"stdcall"` is not a supported ABI for the current target | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 17 previous errors; 12 warnings emitted +error: aborting due to 18 previous errors; 13 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -292,7 +316,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -303,18 +327,31 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +362,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,12 +373,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr index a5468b0e4324..5597440d5d91 100644 --- a/tests/ui/abi/unsupported.x64_win.stderr +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -106,10 +106,21 @@ LL | extern "stdcall" {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` = note: `#[warn(unsupported_calling_conventions)]` on by default +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` + warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -118,16 +129,27 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: for more information, see issue #130260 warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +158,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,19 +167,20 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:164:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:169:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target --> $DIR/unsupported.rs:36:1 @@ -209,23 +232,25 @@ LL | extern "stdcall" fn stdcall() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:150:1 + --> $DIR/unsupported.rs:157:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 15 previous errors; 15 warnings emitted +error: aborting due to 15 previous errors; 17 warnings emitted For more information about this error, try `rustc --explain E0570`. Future incompatibility report: Future breakage diagnostic: @@ -314,11 +339,24 @@ LL | extern "stdcall" {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:121:1 + | +LL | extern "stdcall-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:125:17 + --> $DIR/unsupported.rs:129:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -329,18 +367,31 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:130:1 + --> $DIR/unsupported.rs:134:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default + +Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:137:1 + | +LL | extern "cdecl-unwind" {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C-unwind"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:144:21 + --> $DIR/unsupported.rs:151:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -351,7 +402,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:152:22 + --> $DIR/unsupported.rs:159:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -362,13 +413,14 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:162:1 + --> $DIR/unsupported.rs:169:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: @@ -380,16 +432,18 @@ LL | extern "stdcall" fn stdcall() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:122:1 + --> $DIR/unsupported.rs:126:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 + = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default From 85ce9ee481a56bcabaa9480cfc0e2b420e4f1807 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sat, 7 Jun 2025 16:17:21 +0500 Subject: [PATCH 081/183] cleaned up some tests --- .../attr_unknown_custom_attr.rs} | 2 ++ .../attr_unknown_custom_attr.stderr} | 6 +++--- tests/ui/{ => attributes}/crate-name-mismatch.rs | 2 ++ tests/ui/{ => attributes}/crate-name-mismatch.stderr | 2 +- .../custom_attr_multisegment_error.rs} | 2 +- .../custom_attr_multisegment_error.stderr} | 2 +- tests/ui/default-method-parsing.rs | 7 ------- tests/ui/{deep.rs => runtime/deep_recursion.rs} | 2 ++ .../custom_test_frameworks_simple.rs} | 2 ++ .../default_method_simple.rs} | 10 ++++------ 10 files changed, 18 insertions(+), 19 deletions(-) rename tests/ui/{custom_attribute.rs => attributes/attr_unknown_custom_attr.rs} (81%) rename tests/ui/{custom_attribute.stderr => attributes/attr_unknown_custom_attr.stderr} (69%) rename tests/ui/{ => attributes}/crate-name-mismatch.rs (65%) rename tests/ui/{ => attributes}/crate-name-mismatch.stderr (83%) rename tests/ui/{custom-attribute-multisegment.rs => attributes/custom_attr_multisegment_error.rs} (65%) rename tests/ui/{custom-attribute-multisegment.stderr => attributes/custom_attr_multisegment_error.stderr} (85%) delete mode 100644 tests/ui/default-method-parsing.rs rename tests/ui/{deep.rs => runtime/deep_recursion.rs} (85%) rename tests/ui/{custom-test-frameworks-simple.rs => test-attrs/custom_test_frameworks_simple.rs} (83%) rename tests/ui/{default-method-simple.rs => traits/default_method_simple.rs} (75%) diff --git a/tests/ui/custom_attribute.rs b/tests/ui/attributes/attr_unknown_custom_attr.rs similarity index 81% rename from tests/ui/custom_attribute.rs rename to tests/ui/attributes/attr_unknown_custom_attr.rs index 4957184229da..cdbe48a636fc 100644 --- a/tests/ui/custom_attribute.rs +++ b/tests/ui/attributes/attr_unknown_custom_attr.rs @@ -1,3 +1,5 @@ +//! Checks error handling for undefined custom attributes. + #![feature(stmt_expr_attributes)] #[foo] //~ ERROR cannot find attribute `foo` in this scope diff --git a/tests/ui/custom_attribute.stderr b/tests/ui/attributes/attr_unknown_custom_attr.stderr similarity index 69% rename from tests/ui/custom_attribute.stderr rename to tests/ui/attributes/attr_unknown_custom_attr.stderr index 4023892d2946..76c3b884a5d4 100644 --- a/tests/ui/custom_attribute.stderr +++ b/tests/ui/attributes/attr_unknown_custom_attr.stderr @@ -1,17 +1,17 @@ error: cannot find attribute `foo` in this scope - --> $DIR/custom_attribute.rs:3:3 + --> $DIR/attr_unknown_custom_attr.rs:5:3 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/custom_attribute.rs:5:7 + --> $DIR/attr_unknown_custom_attr.rs:7:7 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/custom_attribute.rs:7:7 + --> $DIR/attr_unknown_custom_attr.rs:9:7 | LL | #[foo] | ^^^ diff --git a/tests/ui/crate-name-mismatch.rs b/tests/ui/attributes/crate-name-mismatch.rs similarity index 65% rename from tests/ui/crate-name-mismatch.rs rename to tests/ui/attributes/crate-name-mismatch.rs index 7651e0f97ebe..0c343d70b9cf 100644 --- a/tests/ui/crate-name-mismatch.rs +++ b/tests/ui/attributes/crate-name-mismatch.rs @@ -1,3 +1,5 @@ +//! Checks error handling for mismatched `--crate-name` and `#![crate_name]` values. + //@ compile-flags: --crate-name foo #![crate_name = "bar"] diff --git a/tests/ui/crate-name-mismatch.stderr b/tests/ui/attributes/crate-name-mismatch.stderr similarity index 83% rename from tests/ui/crate-name-mismatch.stderr rename to tests/ui/attributes/crate-name-mismatch.stderr index 511562618d56..4021fbe7c181 100644 --- a/tests/ui/crate-name-mismatch.stderr +++ b/tests/ui/attributes/crate-name-mismatch.stderr @@ -1,5 +1,5 @@ error: `--crate-name` and `#[crate_name]` are required to match, but `foo` != `bar` - --> $DIR/crate-name-mismatch.rs:3:1 + --> $DIR/crate-name-mismatch.rs:5:1 | LL | #![crate_name = "bar"] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/custom-attribute-multisegment.rs b/tests/ui/attributes/custom_attr_multisegment_error.rs similarity index 65% rename from tests/ui/custom-attribute-multisegment.rs rename to tests/ui/attributes/custom_attr_multisegment_error.rs index 243492139024..1045282c3a33 100644 --- a/tests/ui/custom-attribute-multisegment.rs +++ b/tests/ui/attributes/custom_attr_multisegment_error.rs @@ -1,4 +1,4 @@ -// Unresolved multi-segment attributes are not treated as custom. +//! Unresolved multi-segment attributes are not treated as custom. mod existent {} diff --git a/tests/ui/custom-attribute-multisegment.stderr b/tests/ui/attributes/custom_attr_multisegment_error.stderr similarity index 85% rename from tests/ui/custom-attribute-multisegment.stderr rename to tests/ui/attributes/custom_attr_multisegment_error.stderr index 90ebe2779391..02bed225d53e 100644 --- a/tests/ui/custom-attribute-multisegment.stderr +++ b/tests/ui/attributes/custom_attr_multisegment_error.stderr @@ -1,5 +1,5 @@ error[E0433]: failed to resolve: could not find `nonexistent` in `existent` - --> $DIR/custom-attribute-multisegment.rs:5:13 + --> $DIR/custom_attr_multisegment_error.rs:5:13 | LL | #[existent::nonexistent] | ^^^^^^^^^^^ could not find `nonexistent` in `existent` diff --git a/tests/ui/default-method-parsing.rs b/tests/ui/default-method-parsing.rs deleted file mode 100644 index 84c3ab747c8e..000000000000 --- a/tests/ui/default-method-parsing.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ check-pass - -trait Foo { - fn m(&self, _:isize) { } -} - -pub fn main() { } diff --git a/tests/ui/deep.rs b/tests/ui/runtime/deep_recursion.rs similarity index 85% rename from tests/ui/deep.rs rename to tests/ui/runtime/deep_recursion.rs index 5a631d068b1a..bf220f174a1b 100644 --- a/tests/ui/deep.rs +++ b/tests/ui/runtime/deep_recursion.rs @@ -1,3 +1,5 @@ +//! Checks deep recursion behavior. + //@ run-pass //@ ignore-emscripten apparently blows the stack diff --git a/tests/ui/custom-test-frameworks-simple.rs b/tests/ui/test-attrs/custom_test_frameworks_simple.rs similarity index 83% rename from tests/ui/custom-test-frameworks-simple.rs rename to tests/ui/test-attrs/custom_test_frameworks_simple.rs index 3fb7de6b26bd..54a4e4095a77 100644 --- a/tests/ui/custom-test-frameworks-simple.rs +++ b/tests/ui/test-attrs/custom_test_frameworks_simple.rs @@ -1,3 +1,5 @@ +//! Checks run with a custom test framework and indexed test functions. + //@ compile-flags: --test //@ run-pass diff --git a/tests/ui/default-method-simple.rs b/tests/ui/traits/default_method_simple.rs similarity index 75% rename from tests/ui/default-method-simple.rs rename to tests/ui/traits/default_method_simple.rs index e5fbedfaece1..96fad94f57ae 100644 --- a/tests/ui/default-method-simple.rs +++ b/tests/ui/traits/default_method_simple.rs @@ -1,6 +1,6 @@ -//@ run-pass +//! Checks basic default method functionality. -#![allow(dead_code)] +//@ run-pass trait Foo { fn f(&self) { @@ -10,9 +10,7 @@ trait Foo { fn g(&self); } -struct A { - x: isize -} +struct A; impl Foo for A { fn g(&self) { @@ -21,6 +19,6 @@ impl Foo for A { } pub fn main() { - let a = A { x: 1 }; + let a = A; a.f(); } From 3ab5e60d18a7f6ed016974cced19e9f372517976 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 8 Jun 2025 11:58:19 +0530 Subject: [PATCH 082/183] Add execution context --- src/bootstrap/src/utils/exec.rs | 26 ++- src/bootstrap/src/utils/execution_context.rs | 198 +++++++++++++++++++ 2 files changed, 222 insertions(+), 2 deletions(-) create mode 100644 src/bootstrap/src/utils/execution_context.rs diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 64e46f105638..c03fd2772ad8 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -11,6 +11,7 @@ use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio} use build_helper::ci::CiEnv; use build_helper::drop_bomb::DropBomb; +use super::execution_context::ExecutionContext; use crate::Build; /// What should be done when the command fails. @@ -125,7 +126,6 @@ impl BootstrapCommand { Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self } } - #[expect(dead_code)] pub fn fail_fast(self) -> Self { Self { failure_behavior: BehaviorOnFailure::Exit, ..self } } @@ -140,6 +140,29 @@ impl BootstrapCommand { self } + #[track_caller] + pub fn run_exec_ctx(&mut self, exec_ctx: impl AsRef) -> bool { + exec_ctx.as_ref().run(self, OutputMode::Print, OutputMode::Print).is_success() + } + + /// Run the command, while capturing and returning all its output. + #[track_caller] + pub fn run_capture_exec_ctx( + &mut self, + exec_ctx: impl AsRef, + ) -> CommandOutput { + exec_ctx.as_ref().run(self, OutputMode::Capture, OutputMode::Capture) + } + + /// Run the command, while capturing and returning stdout, and printing stderr. + #[track_caller] + pub fn run_capture_stdout_exec_ctx( + &mut self, + exec_ctx: impl AsRef, + ) -> CommandOutput { + exec_ctx.as_ref().run(self, OutputMode::Capture, OutputMode::Print) + } + /// Run the command, while printing stdout and stderr. /// Returns true if the command has succeeded. #[track_caller] @@ -280,7 +303,6 @@ impl CommandOutput { !self.is_success() } - #[expect(dead_code)] pub fn status(&self) -> Option { match self.status { CommandStatus::Finished(status) => Some(status), diff --git a/src/bootstrap/src/utils/execution_context.rs b/src/bootstrap/src/utils/execution_context.rs new file mode 100644 index 000000000000..17af98babb49 --- /dev/null +++ b/src/bootstrap/src/utils/execution_context.rs @@ -0,0 +1,198 @@ +//! Shared execution context for running bootstrap commands. +//! +//! This module provides the [`ExecutionContext`] type, which holds global configuration +//! relevant during the execution of commands in bootstrap. This includes dry-run +//! mode, verbosity level, and behavior on failure. +use std::sync::{Arc, Mutex}; + +use crate::core::config::DryRun; +use crate::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode, exit}; + +#[derive(Clone, Default)] +pub struct ExecutionContext { + dry_run: DryRun, + verbose: u8, + pub fail_fast: bool, + delayed_failures: Arc>>, +} + +impl ExecutionContext { + pub fn new() -> Self { + ExecutionContext::default() + } + + pub fn dry_run(&self) -> bool { + match self.dry_run { + DryRun::Disabled => false, + DryRun::SelfCheck | DryRun::UserSelected => true, + } + } + + pub fn verbose(&self, f: impl Fn()) { + if self.is_verbose() { + f() + } + } + + pub fn is_verbose(&self) -> bool { + self.verbose > 0 + } + + pub fn fail_fast(&self) -> bool { + self.fail_fast + } + + pub fn set_dry_run(&mut self, value: DryRun) { + self.dry_run = value; + } + + pub fn set_verbose(&mut self, value: u8) { + self.verbose = value; + } + + pub fn set_fail_fast(&mut self, value: bool) { + self.fail_fast = value; + } + + pub fn add_to_delay_failure(&self, message: String) { + self.delayed_failures.lock().unwrap().push(message); + } + + pub fn report_failures_and_exit(&self) { + let failures = self.delayed_failures.lock().unwrap(); + if failures.is_empty() { + return; + } + eprintln!("\n{} command(s) did not execute successfully:\n", failures.len()); + for failure in &*failures { + eprintln!(" - {failure}"); + } + exit!(1); + } + + /// Execute a command and return its output. + /// Note: Ideally, you should use one of the BootstrapCommand::run* functions to + /// execute commands. They internally call this method. + #[track_caller] + pub fn run( + &self, + command: &mut BootstrapCommand, + stdout: OutputMode, + stderr: OutputMode, + ) -> CommandOutput { + command.mark_as_executed(); + if self.dry_run() && !command.run_always { + return CommandOutput::default(); + } + + #[cfg(feature = "tracing")] + let _run_span = trace_cmd!(command); + + let created_at = command.get_created_location(); + let executed_at = std::panic::Location::caller(); + + self.verbose(|| { + println!("running: {command:?} (created at {created_at}, executed at {executed_at})") + }); + + let cmd = command.as_command_mut(); + cmd.stdout(stdout.stdio()); + cmd.stderr(stderr.stdio()); + + let output = cmd.output(); + + use std::fmt::Write; + + let mut message = String::new(); + let output: CommandOutput = match output { + // Command has succeeded + Ok(output) if output.status.success() => { + CommandOutput::from_output(output, stdout, stderr) + } + // Command has started, but then it failed + Ok(output) => { + writeln!( + message, + r#" +Command {command:?} did not execute successfully. +Expected success, got {} +Created at: {created_at} +Executed at: {executed_at}"#, + output.status, + ) + .unwrap(); + + let output: CommandOutput = CommandOutput::from_output(output, stdout, stderr); + + // If the output mode is OutputMode::Capture, we can now print the output. + // If it is OutputMode::Print, then the output has already been printed to + // stdout/stderr, and we thus don't have anything captured to print anyway. + if stdout.captures() { + writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); + } + if stderr.captures() { + writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); + } + output + } + // The command did not even start + Err(e) => { + writeln!( + message, + "\n\nCommand {command:?} did not execute successfully.\ + \nIt was not possible to execute the command: {e:?}" + ) + .unwrap(); + CommandOutput::did_not_start(stdout, stderr) + } + }; + + let fail = |message: &str, output: CommandOutput| -> ! { + if self.is_verbose() { + println!("{message}"); + } else { + let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); + // If the command captures output, the user would not see any indication that + // it has failed. In this case, print a more verbose error, since to provide more + // context. + if stdout.is_some() || stderr.is_some() { + if let Some(stdout) = + output.stdout_if_present().take_if(|s| !s.trim().is_empty()) + { + println!("STDOUT:\n{stdout}\n"); + } + if let Some(stderr) = + output.stderr_if_present().take_if(|s| !s.trim().is_empty()) + { + println!("STDERR:\n{stderr}\n"); + } + println!("Command {command:?} has failed. Rerun with -v to see more details."); + } else { + println!("Command has failed. Rerun with -v to see more details."); + } + } + exit!(1); + }; + + if !output.is_success() { + match command.failure_behavior { + BehaviorOnFailure::DelayFail => { + if self.fail_fast { + fail(&message, output); + } + + self.add_to_delay_failure(message); + } + BehaviorOnFailure::Exit => { + fail(&message, output); + } + BehaviorOnFailure::Ignore => { + // If failures are allowed, either the error has been printed already + // (OutputMode::Print) or the user used a capture output mode and wants to + // handle the error output on their own. + } + } + } + output + } +} From 81ee86b23b356aca3d131fa6271b19d55f9751c3 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 8 Jun 2025 12:02:58 +0530 Subject: [PATCH 083/183] add execution context to bootstrap workflow --- src/bootstrap/src/bin/main.rs | 4 ++-- src/bootstrap/src/core/builder/mod.rs | 11 +++++++++++ src/bootstrap/src/core/config/config.rs | 23 +++++++++++++++++++++-- src/bootstrap/src/core/config/flags.rs | 15 +++++++++++---- src/bootstrap/src/utils/mod.rs | 1 + 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 833f80279517..9f1fde74359c 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -29,9 +29,9 @@ fn main() { } debug!("parsing flags"); - let flags = Flags::parse(&args); + let (flags, exec_ctx) = Flags::parse(&args); debug!("parsing config based on flags"); - let config = Config::parse(flags); + let config = Config::parse(flags, exec_ctx); let mut build_lock; let _build_lock_guard; diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 19b79bfe818c..e8686c75e02f 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -22,6 +22,7 @@ use crate::core::config::flags::Subcommand; use crate::core::config::{DryRun, TargetSelection}; use crate::utils::cache::Cache; use crate::utils::exec::{BootstrapCommand, command}; +use crate::utils::execution_context::ExecutionContext; use crate::utils::helpers::{self, LldThreads, add_dylib_path, exe, libdir, linker_args, t}; use crate::{Build, Crate, trace}; @@ -1633,4 +1634,14 @@ impl<'a> Builder<'a> { self.info(&format!("{err}\n")); } } + + pub fn exec_ctx(&self) -> &ExecutionContext { + &self.config.exec_ctx + } +} + +impl<'a> AsRef for Builder<'a> { + fn as_ref(&self) -> &ExecutionContext { + self.exec_ctx() + } } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a92d58ef9e87..d7e6107defaa 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -47,6 +47,7 @@ use crate::core::config::{ }; use crate::core::download::is_download_ci_available; use crate::utils::channel; +use crate::utils::execution_context::ExecutionContext; use crate::utils::helpers::exe; use crate::{Command, GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, output, t}; @@ -304,6 +305,8 @@ pub struct Config { /// This is mostly for RA as building the stage1 compiler to check the library tree /// on each code change might be too much for some computers. pub skip_std_check_if_no_download_rustc: bool, + + pub exec_ctx: ExecutionContext, } impl Config { @@ -364,8 +367,8 @@ impl Config { feature = "tracing", instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::parse", skip_all) )] - pub fn parse(flags: Flags) -> Config { - Self::parse_inner(flags, Self::get_toml) + pub fn parse(flags: Flags, exec_ctx: ExecutionContext) -> Config { + Self::parse_inner(flags, Self::get_toml, exec_ctx) } #[cfg_attr( @@ -380,8 +383,10 @@ impl Config { pub(crate) fn parse_inner( mut flags: Flags, get_toml: impl Fn(&Path) -> Result, + exec_ctx: ExecutionContext, ) -> Config { let mut config = Config::default_opts(); + config.exec_ctx = exec_ctx; // Set flags. config.paths = std::mem::take(&mut flags.paths); @@ -1741,4 +1746,18 @@ impl Config { _ => !self.is_system_llvm(target), } } + + pub fn exec_ctx(&self) -> &ExecutionContext { + &self.exec_ctx + } + + pub fn git_info(&self, omit_git_hash: bool, dir: &Path) -> GitInfo { + GitInfo::new(omit_git_hash, dir, self) + } +} + +impl AsRef for Config { + fn as_ref(&self) -> &ExecutionContext { + &self.exec_ctx + } } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 30617f58d430..a50ff4caaf46 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -14,7 +14,8 @@ use crate::core::build_steps::setup::Profile; use crate::core::builder::{Builder, Kind}; use crate::core::config::Config; use crate::core::config::target_selection::{TargetSelectionList, target_selection_list}; -use crate::{Build, DocTests}; +use crate::utils::execution_context::ExecutionContext; +use crate::{Build, DocTests, DryRun}; #[derive(Copy, Clone, Default, Debug, ValueEnum)] pub enum Color { @@ -209,7 +210,8 @@ impl Flags { HelpVerboseOnly::try_parse_from(normalize_args(args)) { println!("NOTE: updating submodules before printing available paths"); - let config = Config::parse(Self::parse(&[String::from("build")])); + let (flags, exec_ctx) = Self::parse(&[String::from("build")]); + let config = Config::parse(flags, exec_ctx); let build = Build::new(config); let paths = Builder::get_help(&build, subcommand); if let Some(s) = paths { @@ -227,8 +229,13 @@ impl Flags { feature = "tracing", instrument(level = "trace", name = "Flags::parse", skip_all, fields(args = ?args)) )] - pub fn parse(args: &[String]) -> Self { - Flags::parse_from(normalize_args(args)) + pub fn parse(args: &[String]) -> (Self, ExecutionContext) { + let mut exec_ctx = ExecutionContext::new(); + let flags = Flags::parse_from(normalize_args(args)); + exec_ctx.set_dry_run(if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }); + exec_ctx.set_verbose(flags.verbose); + exec_ctx.set_fail_fast(flags.cmd.fail_fast()); + (flags, exec_ctx) } } diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index 169fcec303e9..5a0b90801e73 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod cc_detect; pub(crate) mod change_tracker; pub(crate) mod channel; pub(crate) mod exec; +pub(crate) mod execution_context; pub(crate) mod helpers; pub(crate) mod job; pub(crate) mod render_tests; From def44885ee91b059d60834dfd9afe667da888575 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 8 Jun 2025 12:03:45 +0530 Subject: [PATCH 084/183] move git command to new execution context --- src/bootstrap/src/core/build_steps/tool.rs | 3 +-- src/bootstrap/src/core/config/config.rs | 24 ++++++++++++---------- src/bootstrap/src/lib.rs | 13 +++++++++++- src/bootstrap/src/utils/channel.rs | 18 +++++++++++----- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 9861637d8c82..717accb399ad 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -23,7 +23,6 @@ use crate::core::builder::{ Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step, cargo_profile_var, }; use crate::core::config::{DebuginfoLevel, RustcLto, TargetSelection}; -use crate::utils::channel::GitInfo; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{add_dylib_path, exe, t}; use crate::{Compiler, FileType, Kind, Mode, gha}; @@ -278,7 +277,7 @@ pub fn prepare_tool_cargo( cargo.env("CFG_VER_DESCRIPTION", description); } - let info = GitInfo::new(builder.config.omit_git_hash, &dir); + let info = builder.config.git_info(builder.config.omit_git_hash, &dir); if let Some(sha) = info.sha() { cargo.env("CFG_COMMIT_HASH", sha); } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index d7e6107defaa..ee068f2bf52f 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -547,7 +547,7 @@ impl Config { build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); } - if GitInfo::new(false, &config.src).is_from_tarball() && toml.profile.is_none() { + if config.git_info(false, &config.src).is_from_tarball() && toml.profile.is_none() { toml.profile = Some("dist".into()); } @@ -850,19 +850,21 @@ impl Config { let default = config.channel == "dev"; config.omit_git_hash = toml.rust.as_ref().and_then(|r| r.omit_git_hash).unwrap_or(default); - config.rust_info = GitInfo::new(config.omit_git_hash, &config.src); - config.cargo_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/cargo")); + config.rust_info = config.git_info(config.omit_git_hash, &config.src); + config.cargo_info = + config.git_info(config.omit_git_hash, &config.src.join("src/tools/cargo")); config.rust_analyzer_info = - GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer")); + config.git_info(config.omit_git_hash, &config.src.join("src/tools/rust-analyzer")); config.clippy_info = - GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/clippy")); - config.miri_info = GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/miri")); + config.git_info(config.omit_git_hash, &config.src.join("src/tools/clippy")); + config.miri_info = + config.git_info(config.omit_git_hash, &config.src.join("src/tools/miri")); config.rustfmt_info = - GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/rustfmt")); + config.git_info(config.omit_git_hash, &config.src.join("src/tools/rustfmt")); config.enzyme_info = - GitInfo::new(config.omit_git_hash, &config.src.join("src/tools/enzyme")); - config.in_tree_llvm_info = GitInfo::new(false, &config.src.join("src/llvm-project")); - config.in_tree_gcc_info = GitInfo::new(false, &config.src.join("src/gcc")); + config.git_info(config.omit_git_hash, &config.src.join("src/tools/enzyme")); + config.in_tree_llvm_info = config.git_info(false, &config.src.join("src/llvm-project")); + config.in_tree_gcc_info = config.git_info(false, &config.src.join("src/gcc")); config.vendor = vendor.unwrap_or( config.rust_info.is_from_tarball() @@ -1329,7 +1331,7 @@ impl Config { // NOTE: The check for the empty directory is here because when running x.py the first time, // the submodule won't be checked out. Check it out now so we can build it. - if !GitInfo::new(false, &absolute_path).is_managed_git_subrepository() + if !self.git_info(false, &absolute_path).is_managed_git_subrepository() && !helpers::dir_is_empty(&absolute_path) { return; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 07772b8932d9..9bace4eb77ce 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -32,6 +32,7 @@ use cc::Tool; use termcolor::{ColorChoice, StandardStream, WriteColor}; use utils::build_stamp::BuildStamp; use utils::channel::GitInfo; +use utils::execution_context::ExecutionContext; use crate::core::builder; use crate::core::builder::Kind; @@ -616,7 +617,7 @@ impl Build { return; } - if GitInfo::new(false, Path::new(submodule)).is_managed_git_subrepository() { + if config.git_info(false, Path::new(submodule)).is_managed_git_subrepository() { config.update_submodule(submodule); } } @@ -2015,6 +2016,16 @@ to download LLVM rather than building it. stream.reset().unwrap(); result } + + pub fn exec_ctx(&self) -> &ExecutionContext { + &self.config.exec_ctx + } +} + +impl AsRef for Build { + fn as_ref(&self) -> &ExecutionContext { + &self.config.exec_ctx + } } #[cfg(unix)] diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs index 4a9ecc7a4f8a..333c04c3c264 100644 --- a/src/bootstrap/src/utils/channel.rs +++ b/src/bootstrap/src/utils/channel.rs @@ -8,6 +8,7 @@ use std::fs; use std::path::Path; +use super::execution_context::ExecutionContext; use super::helpers; use crate::Build; use crate::utils::helpers::{start_process, t}; @@ -34,7 +35,7 @@ pub struct Info { } impl GitInfo { - pub fn new(omit_git_hash: bool, dir: &Path) -> GitInfo { + pub fn new(omit_git_hash: bool, dir: &Path, exec_ctx: impl AsRef) -> GitInfo { // See if this even begins to look like a git dir if !dir.join(".git").exists() { match read_commit_info_file(dir) { @@ -43,11 +44,18 @@ impl GitInfo { } } - // Make sure git commands work - match helpers::git(Some(dir)).arg("rev-parse").as_command_mut().output() { - Ok(ref out) if out.status.success() => {} - _ => return GitInfo::Absent, + let mut git_command = helpers::git(Some(dir)); + git_command.arg("rev-parse"); + let output = git_command.allow_failure().run_capture_stdout_exec_ctx(exec_ctx); + + if output.is_failure() { + return GitInfo::Absent; } + // Make sure git commands work + // match helpers::git(Some(dir)).arg("rev-parse").as_command_mut().output() { + // Ok(ref out) if out.status.success() => {} + // _ => return GitInfo::Absent, + // } // If we're ignoring the git info, we don't actually need to collect it, just make sure this // was a git repo in the first place. From 8bd81699d977657e9571758e413e7cf1595626d4 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 6 Jun 2025 21:16:47 +0530 Subject: [PATCH 085/183] moved render_tests in utils to new execution context --- src/bootstrap/src/utils/render_tests.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 418f3ff975d9..77e645a9e3cb 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -43,8 +43,7 @@ pub(crate) fn try_run_tests( if builder.fail_fast { crate::exit!(1); } else { - let mut failures = builder.delayed_failures.borrow_mut(); - failures.push(format!("{cmd:?}")); + builder.config.exec_ctx().add_to_delay_failure(format!("{cmd:?}")); false } } else { From fdae3448ba96ed4b02791aaff72a9738e46a855e Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 8 Jun 2025 14:51:13 +0200 Subject: [PATCH 086/183] De-duplicate f16 & f128 doctest attributes --- library/core/src/num/f128.rs | 23 +----------- library/core/src/num/f16.rs | 25 +------------ library/std/src/num/f128.rs | 69 +----------------------------------- library/std/src/num/f16.rs | 67 +--------------------------------- 4 files changed, 4 insertions(+), 180 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 58de62a8be8d..4c09c930c796 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1422,6 +1422,7 @@ impl f128 { // due to https://github.com/llvm/llvm-project/issues/44744. aarch64 linux matches this. // #[unstable(feature = "core_float_math", issue = "137578")] #[cfg(not(test))] +#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))] impl f128 { /// Returns the largest integer less than or equal to `self`. /// @@ -1431,8 +1432,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1464,8 +1463,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1497,8 +1494,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1535,8 +1530,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1570,8 +1563,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1604,8 +1595,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1646,8 +1635,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1694,8 +1681,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1739,8 +1724,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1779,8 +1762,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1814,8 +1795,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 45f402d49671..1d98a485c4f7 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1398,6 +1398,7 @@ impl f16 { // Functions in this module fall into `core_float_math` // #[unstable(feature = "core_float_math", issue = "137578")] #[cfg(not(test))] +#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))] impl f16 { /// Returns the largest integer less than or equal to `self`. /// @@ -1407,8 +1408,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1440,8 +1439,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1473,8 +1470,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1511,8 +1506,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1546,8 +1539,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1580,8 +1571,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1622,8 +1611,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1670,8 +1657,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1715,8 +1700,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1755,8 +1738,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1790,8 +1771,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1828,8 +1807,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs index c0190de089f4..64e604e35f75 100644 --- a/library/std/src/num/f128.rs +++ b/library/std/src/num/f128.rs @@ -5,6 +5,7 @@ //! Mathematically significant numbers are provided in the `consts` sub-module. #![unstable(feature = "f128", issue = "116909")] +#![doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))] #[unstable(feature = "f128", issue = "116909")] pub use core::f128::consts; @@ -27,8 +28,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -59,8 +58,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -93,8 +90,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -127,8 +122,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -146,8 +139,6 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -180,8 +171,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -197,8 +186,6 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -227,8 +214,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -244,8 +229,6 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -274,8 +257,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -291,8 +272,6 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -323,8 +302,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -362,8 +339,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -395,8 +370,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -426,8 +399,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -460,8 +431,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -495,8 +464,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -533,8 +500,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -570,8 +535,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -611,8 +574,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -656,8 +617,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -694,8 +653,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -733,8 +690,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -751,8 +706,6 @@ impl f128 { /// Out-of-range values: /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -783,8 +736,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -821,8 +772,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -859,8 +808,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -894,8 +841,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -929,8 +874,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -966,8 +909,6 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1003,8 +944,6 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_gamma)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1041,8 +980,6 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_gamma)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// @@ -1079,8 +1016,6 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_erf)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// /// The error function relates what percent of a normal distribution lies @@ -1121,8 +1056,6 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_erf)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f128_math)] { /// let x: f128 = 0.123; diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs index 4a4a8fd839a9..7bdefb05858e 100644 --- a/library/std/src/num/f16.rs +++ b/library/std/src/num/f16.rs @@ -5,6 +5,7 @@ //! Mathematically significant numbers are provided in the `consts` sub-module. #![unstable(feature = "f16", issue = "116909")] +#![doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))] #[unstable(feature = "f16", issue = "116909")] pub use core::f16::consts; @@ -27,8 +28,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -59,8 +58,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -93,8 +90,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -127,8 +122,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -146,8 +139,6 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -180,8 +171,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -197,8 +186,6 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -227,8 +214,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -244,8 +229,6 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -274,8 +257,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -291,8 +272,6 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -325,8 +304,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -358,8 +335,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -389,8 +364,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -423,8 +396,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -458,8 +429,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -496,8 +465,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -533,8 +500,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -574,8 +539,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -619,8 +582,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -657,8 +618,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -696,8 +655,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -714,8 +671,6 @@ impl f16 { /// Out-of-range values: /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -746,8 +701,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -784,8 +737,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -822,8 +773,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -857,8 +806,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -892,8 +839,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -929,8 +874,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -966,8 +909,6 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_gamma)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1004,8 +945,6 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_gamma)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -1042,8 +981,6 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_erf)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// /// The error function relates what percent of a normal distribution lies @@ -1084,8 +1021,6 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_erf)] - /// # #![feature(cfg_target_has_reliable_f16_f128)] - /// # #![expect(internal_features)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// let x: f16 = 0.123; From 53d339b2d096662953200fc57e8b7967ede29855 Mon Sep 17 00:00:00 2001 From: dianne Date: Sat, 7 Jun 2025 00:21:30 -0700 Subject: [PATCH 087/183] add tests for pattern binding drop order edge cases I couldn't find existing tests that for this behavior, so this should make sure it doesn't accidentally change. --- tests/ui/drop/or-pattern-drop-order.rs | 109 ++++++++++++++++++ .../dropck/eager-by-ref-binding-for-guards.rs | 31 +++++ .../eager-by-ref-binding-for-guards.stderr | 28 +++++ tests/ui/dropck/let-else-more-permissive.rs | 30 +++++ .../ui/dropck/let-else-more-permissive.stderr | 35 ++++++ 5 files changed, 233 insertions(+) create mode 100644 tests/ui/drop/or-pattern-drop-order.rs create mode 100644 tests/ui/dropck/eager-by-ref-binding-for-guards.rs create mode 100644 tests/ui/dropck/eager-by-ref-binding-for-guards.stderr create mode 100644 tests/ui/dropck/let-else-more-permissive.rs create mode 100644 tests/ui/dropck/let-else-more-permissive.stderr diff --git a/tests/ui/drop/or-pattern-drop-order.rs b/tests/ui/drop/or-pattern-drop-order.rs new file mode 100644 index 000000000000..fdc28225c359 --- /dev/null +++ b/tests/ui/drop/or-pattern-drop-order.rs @@ -0,0 +1,109 @@ +//@ run-pass +//! Test drop order for different ways of declaring pattern bindings involving or-patterns. +//! Currently, it's inconsistent between language constructs (#142163). + +use std::cell::RefCell; +use std::ops::Drop; + +// For more informative failures, we collect drops in a `Vec` before checking their order. +struct DropOrder(RefCell>); +struct LogDrop<'o>(&'o DropOrder, u32); + +impl<'o> Drop for LogDrop<'o> { + fn drop(&mut self) { + self.0.0.borrow_mut().push(self.1); + } +} + +#[track_caller] +fn assert_drop_order(expected_drops: impl IntoIterator, f: impl Fn(&DropOrder)) { + let order = DropOrder(RefCell::new(Vec::new())); + f(&order); + let order = order.0.into_inner(); + let correct_order: Vec = expected_drops.into_iter().collect(); + assert_eq!(order, correct_order); +} + +#[expect(unused_variables, unused_assignments, irrefutable_let_patterns)] +fn main() { + // When bindings are declared with `let pat;`, they're visited in left-to-right order, using the + // order given by the first occurrence of each variable. They're later dropped in reverse. + assert_drop_order(1..=3, |o| { + // Drops are right-to-left: `z`, `y`, `x`. + let (x, Ok(y) | Err(y), z); + // Assignment order doesn't matter. + z = LogDrop(o, 1); + y = LogDrop(o, 2); + x = LogDrop(o, 3); + }); + assert_drop_order(1..=2, |o| { + // The first or-pattern alternative determines the bindings' drop order: `y`, `x`. + let ((true, x, y) | (false, y, x)); + x = LogDrop(o, 2); + y = LogDrop(o, 1); + }); + + // When bindings are declared with `let pat = expr;`, bindings within or-patterns are seen last, + // thus they're dropped first. + assert_drop_order(1..=3, |o| { + // Drops are right-to-left, treating `y` as rightmost: `y`, `z`, `x`. + let (x, Ok(y) | Err(y), z) = (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)); + }); + assert_drop_order(1..=2, |o| { + // The first or-pattern alternative determines the bindings' drop order: `y`, `x`. + let ((true, x, y) | (false, y, x)) = (true, LogDrop(o, 2), LogDrop(o, 1)); + }); + assert_drop_order(1..=2, |o| { + // That drop order is used regardless of which or-pattern alternative matches: `y`, `x`. + let ((true, x, y) | (false, y, x)) = (false, LogDrop(o, 1), LogDrop(o, 2)); + }); + + // `match` treats or-patterns as last like `let pat = expr;`, but also determines drop order + // using the order of the bindings in the *last* or-pattern alternative. + assert_drop_order(1..=3, |o| { + // Drops are right-to-left, treating `y` as rightmost: `y`, `z`, `x`. + match (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) { (x, Ok(y) | Err(y), z) => {} } + }); + assert_drop_order(1..=2, |o| { + // The last or-pattern alternative determines the bindings' drop order: `x`, `y`. + match (true, LogDrop(o, 1), LogDrop(o, 2)) { (true, x, y) | (false, y, x) => {} } + }); + assert_drop_order(1..=2, |o| { + // That drop order is used regardless of which or-pattern alternative matches: `x`, `y`. + match (false, LogDrop(o, 2), LogDrop(o, 1)) { (true, x, y) | (false, y, x) => {} } + }); + + // Function params are visited one-by-one, and the order of bindings within a param's pattern is + // the same as `let pat = expr`; + assert_drop_order(1..=3, |o| { + // Among separate params, the drop order is right-to-left: `z`, `y`, `x`. + (|x, (Ok(y) | Err(y)), z| {})(LogDrop(o, 3), Ok(LogDrop(o, 2)), LogDrop(o, 1)); + }); + assert_drop_order(1..=3, |o| { + // Within a param's pattern, or-patterns are treated as rightmost: `y`, `z`, `x`. + (|(x, Ok(y) | Err(y), z)| {})((LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2))); + }); + assert_drop_order(1..=2, |o| { + // The first or-pattern alternative determines the bindings' drop order: `y`, `x`. + (|((true, x, y) | (false, y, x))| {})((true, LogDrop(o, 2), LogDrop(o, 1))); + }); + + // `if let` and `let`-`else` see bindings in the same order as `let pat = expr;`. + // Vars in or-patterns are seen last (dropped first), and the first alternative's order is used. + assert_drop_order(1..=3, |o| { + if let (x, Ok(y) | Err(y), z) = (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) {} + }); + assert_drop_order(1..=3, |o| { + let (x, Ok(y) | Err(y), z) = (LogDrop(o, 3), Ok(LogDrop(o, 1)), LogDrop(o, 2)) else { + unreachable!(); + }; + }); + assert_drop_order(1..=2, |o| { + if let (true, x, y) | (false, y, x) = (true, LogDrop(o, 2), LogDrop(o, 1)) {} + }); + assert_drop_order(1..=2, |o| { + let ((true, x, y) | (false, y, x)) = (true, LogDrop(o, 2), LogDrop(o, 1)) else { + unreachable!(); + }; + }); +} diff --git a/tests/ui/dropck/eager-by-ref-binding-for-guards.rs b/tests/ui/dropck/eager-by-ref-binding-for-guards.rs new file mode 100644 index 000000000000..3f4758391717 --- /dev/null +++ b/tests/ui/dropck/eager-by-ref-binding-for-guards.rs @@ -0,0 +1,31 @@ +//! The drop check is currently more permissive when match arms have guards, due to eagerly creating +//! by-ref bindings for the guard (#142057). + +struct Struct(T); +impl Drop for Struct { + fn drop(&mut self) {} +} + +fn main() { + // This is an error: `short1` is dead before `long1` is dropped. + match (Struct(&&0), 1) { + (mut long1, ref short1) => long1.0 = &short1, + //~^ ERROR `short1` does not live long enough + } + // This is OK: `short2`'s storage is live until after `long2`'s drop runs. + match (Struct(&&0), 1) { + (mut long2, ref short2) if true => long2.0 = &short2, + _ => unreachable!(), + } + // This depends on the binding modes of the final or-pattern alternatives (see #142163): + let res: &Result = &Ok(1); + match (Struct(&&0), res) { + (mut long3, Ok(short3) | &Err(short3)) if true => long3.0 = &short3, + //~^ ERROR `short3` does not live long enough + _ => unreachable!(), + } + match (Struct(&&0), res) { + (mut long4, &Err(short4) | Ok(short4)) if true => long4.0 = &short4, + _ => unreachable!(), + } +} diff --git a/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr b/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr new file mode 100644 index 000000000000..cb1a04cd4447 --- /dev/null +++ b/tests/ui/dropck/eager-by-ref-binding-for-guards.stderr @@ -0,0 +1,28 @@ +error[E0597]: `short1` does not live long enough + --> $DIR/eager-by-ref-binding-for-guards.rs:12:46 + | +LL | (mut long1, ref short1) => long1.0 = &short1, + | ---------- ^^^^^^- + | | | | + | | | `short1` dropped here while still borrowed + | | | borrow might be used here, when `long1` is dropped and runs the `Drop` code for type `Struct` + | | borrowed value does not live long enough + | binding `short1` declared here + | + = note: values in a scope are dropped in the opposite order they are defined + +error[E0597]: `short3` does not live long enough + --> $DIR/eager-by-ref-binding-for-guards.rs:23:69 + | +LL | (mut long3, Ok(short3) | &Err(short3)) if true => long3.0 = &short3, + | ------ ^^^^^^- + | | | | + | | | `short3` dropped here while still borrowed + | | | borrow might be used here, when `long3` is dropped and runs the `Drop` code for type `Struct` + | binding `short3` declared here borrowed value does not live long enough + | + = note: values in a scope are dropped in the opposite order they are defined + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/dropck/let-else-more-permissive.rs b/tests/ui/dropck/let-else-more-permissive.rs new file mode 100644 index 000000000000..0020814aa81f --- /dev/null +++ b/tests/ui/dropck/let-else-more-permissive.rs @@ -0,0 +1,30 @@ +//! The drop check is currently more permissive when `let` statements have an `else` block, due to +//! scheduling drops for bindings' storage before pattern-matching (#142056). + +struct Struct(T); +impl Drop for Struct { + fn drop(&mut self) {} +} + +fn main() { + { + // This is an error: `short1` is dead before `long1` is dropped. + let (mut long1, short1) = (Struct(&0), 1); + long1.0 = &short1; + //~^ ERROR `short1` does not live long enough + } + { + // This is OK: `short2`'s storage is live until after `long2`'s drop runs. + #[expect(irrefutable_let_patterns)] + let (mut long2, short2) = (Struct(&0), 1) else { unreachable!() }; + long2.0 = &short2; + } + { + // Sanity check: `short3`'s drop is significant; it's dropped before `long3`: + let tmp = Box::new(0); + #[expect(irrefutable_let_patterns)] + let (mut long3, short3) = (Struct(&tmp), Box::new(1)) else { unreachable!() }; + long3.0 = &short3; + //~^ ERROR `short3` does not live long enough + } +} diff --git a/tests/ui/dropck/let-else-more-permissive.stderr b/tests/ui/dropck/let-else-more-permissive.stderr new file mode 100644 index 000000000000..7c37e170afaf --- /dev/null +++ b/tests/ui/dropck/let-else-more-permissive.stderr @@ -0,0 +1,35 @@ +error[E0597]: `short1` does not live long enough + --> $DIR/let-else-more-permissive.rs:13:19 + | +LL | let (mut long1, short1) = (Struct(&0), 1); + | ------ binding `short1` declared here +LL | long1.0 = &short1; + | ^^^^^^^ borrowed value does not live long enough +LL | +LL | } + | - + | | + | `short1` dropped here while still borrowed + | borrow might be used here, when `long1` is dropped and runs the `Drop` code for type `Struct` + | + = note: values in a scope are dropped in the opposite order they are defined + +error[E0597]: `short3` does not live long enough + --> $DIR/let-else-more-permissive.rs:27:19 + | +LL | let (mut long3, short3) = (Struct(&tmp), Box::new(1)) else { unreachable!() }; + | ------ binding `short3` declared here +LL | long3.0 = &short3; + | ^^^^^^^ borrowed value does not live long enough +LL | +LL | } + | - + | | + | `short3` dropped here while still borrowed + | borrow might be used here, when `long3` is dropped and runs the `Drop` code for type `Struct` + | + = note: values in a scope are dropped in the opposite order they are defined + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. From 9223704f4b92ded13090659f60afb98e52eabf1b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 8 Jun 2025 14:47:28 +0000 Subject: [PATCH 088/183] Remove all unused feature gates from the compiler --- compiler/rustc_ast_lowering/src/lib.rs | 2 -- compiler/rustc_builtin_macros/src/lib.rs | 1 - compiler/rustc_codegen_gcc/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_data_structures/src/lib.rs | 1 - compiler/rustc_errors/src/lib.rs | 2 -- compiler/rustc_expand/src/lib.rs | 1 - compiler/rustc_fluent_macro/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_typeck/src/lib.rs | 2 -- compiler/rustc_infer/src/lib.rs | 1 - compiler/rustc_macros/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 3 --- compiler/rustc_parse/src/lib.rs | 1 - compiler/rustc_passes/src/lib.rs | 2 -- compiler/rustc_query_system/src/lib.rs | 1 - compiler/rustc_span/src/lib.rs | 1 - compiler/rustc_target/src/lib.rs | 2 -- compiler/rustc_trait_selection/src/lib.rs | 2 -- 20 files changed, 1 insertion(+), 28 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3004be403343..b99df8bd7e55 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -33,9 +33,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![doc(rust_logo)] -#![feature(assert_matches)] #![feature(box_patterns)] -#![feature(exact_size_is_empty)] #![feature(if_let_guard)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index aa52c3bd2815..9e7d0ec9e814 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -15,7 +15,6 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![feature(rustdoc_internals)] -#![feature(string_from_utf8_lossy_owned)] #![feature(try_blocks)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index f79ba2dcfc7e..0591ffa42e4a 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -16,7 +16,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature(rustc_private, decl_macro, never_type, trusted_len)] +#![feature(rustc_private)] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index fd376ea8d804..6890923a5946 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -9,7 +9,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] -#![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(file_buffered)] #![feature(if_let_guard)] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b7447e24731b..eb3817a80a72 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -25,7 +25,6 @@ #![feature(dropck_eyepatch)] #![feature(extend_one)] #![feature(file_buffered)] -#![feature(macro_metavar_expr)] #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(negative_impls)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6f0090a0bd65..133bd361ee77 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -15,12 +15,10 @@ #![feature(box_patterns)] #![feature(default_field_values)] #![feature(error_reporter)] -#![feature(if_let_guard)] #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 35b38d99c703..515d82296caf 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -6,7 +6,6 @@ #![feature(associated_type_defaults)] #![feature(if_let_guard)] #![feature(macro_metavar_expr)] -#![feature(map_try_insert)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_internals)] #![feature(rustdoc_internals)] diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index c6e0484b9210..6f85e05f29aa 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -4,7 +4,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(proc_macro_diagnostic)] -#![feature(proc_macro_span)] #![feature(rustdoc_internals)] #![feature(track_path)] // tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 7a5ff8906896..c6fe475b4609 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -5,7 +5,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![feature(associated_type_defaults)] -#![feature(box_patterns)] #![feature(closure_track_caller)] #![feature(debug_closure_helpers)] #![feature(exhaustive_patterns)] diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b0346f8d32eb..fe3a23289fe6 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,13 +1,11 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![feature(array_windows)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(never_type)] -#![feature(try_blocks)] // tidy-alphabetical-end mod _match; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index ab7b7060c092..550707ed4bc6 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -20,7 +20,6 @@ #![doc(rust_logo)] #![feature(assert_matches)] #![feature(extend_one)] -#![feature(iterator_try_collect)] #![feature(rustdoc_internals)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 81817018cb14..42d006ef301c 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -3,7 +3,6 @@ #![feature(if_let_guard)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] -#![feature(proc_macro_span)] #![feature(proc_macro_tracked_env)] // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 7135b8f04a2e..667361b3ca0b 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -54,7 +54,6 @@ #![feature(round_char_boundary)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] -#![feature(trusted_len)] #![feature(try_blocks)] #![feature(try_trait_v2)] #![feature(try_trait_v2_yeet)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index d26e44687157..572ad585c8c8 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -7,10 +7,7 @@ #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] -#![feature(map_try_insert)] -#![feature(never_type)] #![feature(try_blocks)] -#![feature(vec_deque_pop_if)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 3ab726d9d9d6..8ea535599c94 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -9,7 +9,6 @@ #![feature(debug_closure_helpers)] #![feature(if_let_guard)] #![feature(iter_intersperse)] -#![feature(string_from_utf8_lossy_owned)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 639ca683cf60..1831f45a9ecc 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -8,10 +8,8 @@ #![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(box_patterns)] #![feature(map_try_insert)] #![feature(rustdoc_internals)] -#![feature(try_blocks)] // tidy-alphabetical-end use rustc_middle::util::Providers; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index d36cb6f0e5b1..7fa643d91aa3 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -2,7 +2,6 @@ #![allow(internal_features)] #![feature(assert_matches)] #![feature(core_intrinsics)] -#![feature(dropck_eyepatch)] #![feature(min_specialization)] // tidy-alphabetical-end diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index e950493f1355..ed74dea5f1e6 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -23,7 +23,6 @@ #![doc(rust_logo)] #![feature(array_windows)] #![feature(core_io_borrowed_buf)] -#![feature(hash_set_entry)] #![feature(if_let_guard)] #![feature(map_try_insert)] #![feature(negative_impls)] diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index 566bee75c7f3..91657fef8032 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -11,10 +11,8 @@ #![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(assert_matches)] #![feature(debug_closure_helpers)] #![feature(iter_intersperse)] -#![feature(rustc_attrs)] #![feature(rustdoc_internals)] // tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 67328defe36b..e2b22f7bab74 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -19,14 +19,12 @@ #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] -#![feature(cfg_version)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(iterator_try_reduce)] #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(try_blocks)] -#![feature(type_alias_impl_trait)] #![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc From 7c1c56646b62762b3b88b2b34930b11d1921443a Mon Sep 17 00:00:00 2001 From: bohan Date: Sun, 8 Jun 2025 20:28:35 +0800 Subject: [PATCH 089/183] early return in trait detection for non-trait item --- .../rustc_hir_typeck/src/method/suggest.rs | 20 +++++++++++-------- tests/crashes/135863.rs | 10 ---------- .../double-reference-ty-in-self-ty.rs | 12 +++++++++++ .../double-reference-ty-in-self-ty.stderr | 19 ++++++++++++++++++ 4 files changed, 43 insertions(+), 18 deletions(-) delete mode 100644 tests/crashes/135863.rs create mode 100644 tests/ui/suggestions/double-reference-ty-in-self-ty.rs create mode 100644 tests/ui/suggestions/double-reference-ty-in-self-ty.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3eae95d5b738..2fac13b72019 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3494,7 +3494,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } trait_in_other_version_found = self - .detect_and_explain_multiple_crate_versions( + .detect_and_explain_multiple_crate_versions_of_trait_item( err, pick.item.def_id, rcvr.hir_id, @@ -3701,12 +3701,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // same crate. let rcvr_ty = self.node_ty_opt(ty.hir_id); - trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions( - err, - assoc.def_id, - ty.hir_id, - rcvr_ty, - ); + trait_in_other_version_found = self + .detect_and_explain_multiple_crate_versions_of_trait_item( + err, + assoc.def_id, + ty.hir_id, + rcvr_ty, + ); } if !trait_in_other_version_found && self.suggest_valid_traits(err, item_name, valid_out_of_scope_traits, true) @@ -4098,7 +4099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn detect_and_explain_multiple_crate_versions( + fn detect_and_explain_multiple_crate_versions_of_trait_item( &self, err: &mut Diag<'_>, item_def_id: DefId, @@ -4111,6 +4112,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } let trait_def_id = self.tcx.parent(item_def_id); + if !self.tcx.is_trait(trait_def_id) { + return false; + } let krate = self.tcx.crate_name(trait_def_id.krate); let name = self.tcx.item_name(trait_def_id); let candidates: Vec<_> = traits diff --git a/tests/crashes/135863.rs b/tests/crashes/135863.rs deleted file mode 100644 index a0ff5988a0db..000000000000 --- a/tests/crashes/135863.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #135863 -struct A; - -impl A { - fn len(self: &&B) {} -} - -fn main() { - A.len() -} diff --git a/tests/ui/suggestions/double-reference-ty-in-self-ty.rs b/tests/ui/suggestions/double-reference-ty-in-self-ty.rs new file mode 100644 index 000000000000..4ac13f0f635d --- /dev/null +++ b/tests/ui/suggestions/double-reference-ty-in-self-ty.rs @@ -0,0 +1,12 @@ +// issue#135863 + +struct A; + +impl A { + fn len(self: &&A) {} +} + +fn main() { + A.len(); + //~^ ERROR: no method named `len` found for struct `A` in the current scope +} diff --git a/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr b/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr new file mode 100644 index 000000000000..a71823424109 --- /dev/null +++ b/tests/ui/suggestions/double-reference-ty-in-self-ty.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `len` found for struct `A` in the current scope + --> $DIR/double-reference-ty-in-self-ty.rs:10:7 + | +LL | struct A; + | -------- method `len` not found for this struct +... +LL | fn len(self: &&A) {} + | --- the method is available for `&A` here +... +LL | A.len(); + | ^^^ method not found in `A` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `len`, perhaps you need to implement it: + candidate #1: `ExactSizeIterator` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. From b189d29b924ab03728d0738ed6463e61f5362f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Jun 2025 19:44:33 +0200 Subject: [PATCH 090/183] Do not free disk space in the `mingw-check-tidy` job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not needed an it slows down the job considerably. Signed-off-by: Jakub Beránek --- src/ci/github-actions/jobs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index b6b2792d0ec2..e45bf891cf5a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -128,6 +128,7 @@ pr: <<: *job-linux-4c - name: mingw-check-tidy continue_on_error: true + free_disk: false <<: *job-linux-4c - name: x86_64-gnu-llvm-19 env: From b154e03726ee58029382e1a80ae719e4202bc296 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 8 Jun 2025 07:34:20 +0200 Subject: [PATCH 091/183] try to manually bless windows test output --- .../raw-dylib/windows/unsupported-abi.rs | 2 + .../raw-dylib/windows/unsupported-abi.stderr | 37 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs index 48af6b009d3f..df69782e154d 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs @@ -3,6 +3,8 @@ //@ compile-flags: --crate-type lib --emit link #[link(name = "foo", kind = "raw-dylib")] extern "stdcall" { +//~^ WARN: calling convention not supported on this target +//~| WARN: previously accepted fn f(x: i32); //~^ ERROR ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture } diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr index ef022404e7f6..e7a32f4c84b5 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr @@ -1,8 +1,41 @@ +warning: use of calling convention not supported on this target + --> $DIR/unsupported-abi.rs:5:1 + | +LL | / extern "stdcall" { +LL | | +LL | | +LL | | fn f(x: i32); +LL | | +LL | | } + | |_^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + = note: `#[warn(unsupported_calling_conventions)]` on by default + error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture - --> $DIR/unsupported-abi.rs:6:5 + --> $DIR/unsupported-abi.rs:8:5 | LL | fn f(x: i32); | ^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: use of calling convention not supported on this target + --> $DIR/unsupported-abi.rs:5:1 + | +LL | / extern "stdcall" { +LL | | +LL | | +LL | | fn f(x: i32); +LL | | +LL | | } + | |_^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + = note: `#[warn(unsupported_calling_conventions)]` on by default From e82630c4528f80db9ef0d32c4389d43df74379be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Jun 2025 20:49:08 +0200 Subject: [PATCH 092/183] Run `mingw-check-tidy` on auto builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub Beránek --- src/ci/github-actions/jobs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index b6b2792d0ec2..b98653ac6bb9 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -305,6 +305,10 @@ auto: - name: mingw-check-2 <<: *job-linux-4c + - name: mingw-check-tidy + free_disk: false + <<: *job-linux-4c + - name: test-various <<: *job-linux-4c From f4ba1746cc1b13eb73f3739a5ff5e64cde56f078 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sun, 8 Jun 2025 21:37:25 +0200 Subject: [PATCH 093/183] CI: rfl: move job forward to Linux v6.16-rc1 Remove the comment on top as well, since that issue is now fixed in this new tag. Signed-off-by: Miguel Ojeda --- src/ci/docker/scripts/rfl-build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index fa18f67583ff..c59928913989 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,8 +2,7 @@ set -euo pipefail -# https://github.com/Rust-for-Linux/linux/issues/1163 -LINUX_VERSION=3ca02fc80cc4fdac63aaa6796642f1e07be591d6 +LINUX_VERSION=v6.16-rc1 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt From 814b9a11721872ef26b71bc2972c5645b4b2114b Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 9 Jun 2025 00:35:40 +0300 Subject: [PATCH 094/183] Stabilize the "JSON is not Rust" diagnostic --- .../crates/ide-diagnostics/src/handlers/json_is_not_rust.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs index 87c9397fb771..bf7dddacd8c5 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs @@ -135,6 +135,7 @@ pub(crate) fn json_in_items( "JSON syntax is not valid as a Rust item", FileRange { file_id: vfs_file_id, range }, ) + .stable() .with_fixes(Some(vec![{ let mut scb = SourceChangeBuilder::new(vfs_file_id); let scope = scb.make_import_scope_mut(import_scope); From 2e1965831526407bada7abec631d7b7e9f6cbc7d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 11 Feb 2025 22:09:16 -0800 Subject: [PATCH 095/183] Remove rustc's notion of "preferred" alignment AKA `__alignof` In PR 90877 T-lang decided not to remove `intrinsics::pref_align_of`. However, the intrinsic and its supporting code 1. is a nightly feature, so can be removed at compiler/libs discretion 2. requires considerable effort in the compiler to support, as it necessarily complicates every single site reasoning about alignment 3. has been justified based on relevance to codegen, but it is only a requirement for C++ (not C, not Rust) stack frame layout for AIX, in ways Rust would not consider even with increased C++ interop 4. is only used by rustc to overalign some globals, not correctness 5. can be adequately replaced by other rules for globals, as it mostly affects alignments for a few types under 16 bytes of alignment 6. has only one clear benefactor: automating C -> Rust translation for GNU extensions like `__alignof` 7. such code was likely intended to be `alignof` or `_Alignof`, because the GNU extension is a "false friend" of the C keyword, which makes the choice to support such a mapping very questionable 8. makes it easy to do incorrect codegen in the compiler by its mere presence as usual Rust rules of alignment (e.g. `size == align * N`) do not hold with preferred alignment The implementation is clearly damaging the code quality of the compiler. Thus it is within the compiler team's purview to simply rip it out. If T-lang wishes to have this intrinsic restored for c2rust's benefit, it would have to use a radically different implementation that somehow does not cause internal incorrectness. Until then, remove the intrinsic and its supporting code, as one tool and an ill-considered GCC extension cannot justify risking correctness. Because we touch a fair amount of the compiler to change this at all, and unfortunately the duplication of AbiAndPrefAlign is deep-rooted, we keep an "AbiAlign" type which we can wean code off later. --- compiler/rustc_abi/src/layout.rs | 20 ++--- compiler/rustc_abi/src/layout/ty.rs | 4 +- compiler/rustc_abi/src/lib.rs | 90 +++++++++---------- .../src/intrinsics/mod.rs | 6 +- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 6 +- .../src/interpret/intrinsics.rs | 15 +--- compiler/rustc_feature/src/removed.rs | 2 + library/core/src/intrinsics/mod.rs | 9 -- tests/ui/abi/c-zst.aarch64-darwin.stderr | 6 +- tests/ui/abi/c-zst.powerpc-linux.stderr | 6 +- tests/ui/abi/c-zst.s390x-linux.stderr | 6 +- tests/ui/abi/c-zst.sparc64-linux.stderr | 6 +- tests/ui/abi/c-zst.x86_64-linux.stderr | 6 +- .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 6 +- tests/ui/abi/debug.stderr | 72 +++++---------- tests/ui/abi/sysv64-zst.stderr | 6 +- tests/ui/intrinsics/intrinsic-alignment.rs | 25 ++---- tests/ui/layout/debug.stderr | 54 ++++------- tests/ui/layout/enum.stderr | 2 +- tests/ui/layout/hexagon-enum.stderr | 30 +++---- ...-scalarpair-payload-might-be-uninit.stderr | 51 ++++------- .../issue-96185-overaligned-enum.stderr | 18 ++-- tests/ui/layout/thumb-enum.stderr | 30 +++---- .../layout/zero-sized-array-enum-niche.stderr | 39 +++----- ...-variants.aarch64-unknown-linux-gnu.stderr | 24 ++--- ...-c-dead-variants.armebv7r-none-eabi.stderr | 24 ++--- ...-dead-variants.i686-pc-windows-msvc.stderr | 24 ++--- ...d-variants.x86_64-unknown-linux-gnu.stderr | 24 ++--- tests/ui/repr/repr-c-int-dead-variants.stderr | 24 ++--- .../ui/type/pattern_types/or_patterns.stderr | 6 +- .../type/pattern_types/range_patterns.stderr | 33 +++---- 31 files changed, 230 insertions(+), 444 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 21fd6be39fa4..58a7fcae9f64 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -8,7 +8,7 @@ use rustc_index::bit_set::BitMatrix; use tracing::debug; use crate::{ - AbiAndPrefAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, + AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, Variants, WrappingRange, }; @@ -173,13 +173,7 @@ impl LayoutCalculator { // Non-power-of-two vectors have padding up to the next power-of-two. // If we're a packed repr, remove the padding while keeping the alignment as close // to a vector as possible. - ( - BackendRepr::Memory { sized: true }, - AbiAndPrefAlign { - abi: Align::max_aligned_factor(size), - pref: dl.llvmlike_vector_align(size).pref, - }, - ) + (BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) }) } else { (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size)) }; @@ -435,13 +429,13 @@ impl LayoutCalculator { } if let Some(pack) = repr.pack { - align = align.min(AbiAndPrefAlign::new(pack)); + align = align.min(AbiAlign::new(pack)); } // The unadjusted ABI alignment does not include repr(align), but does include repr(pack). // See documentation on `LayoutS::unadjusted_abi_align`. let unadjusted_abi_align = align.abi; if let Some(repr_align) = repr.align { - align = align.max(AbiAndPrefAlign::new(repr_align)); + align = align.max(AbiAlign::new(repr_align)); } // `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate. let align = align; @@ -1289,7 +1283,7 @@ impl LayoutCalculator { if let StructKind::Prefixed(prefix_size, prefix_align) = kind { let prefix_align = if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align }; - align = align.max(AbiAndPrefAlign::new(prefix_align)); + align = align.max(AbiAlign::new(prefix_align)); offset = prefix_size.align_to(prefix_align); } for &i in &inverse_memory_index { @@ -1308,7 +1302,7 @@ impl LayoutCalculator { // Invariant: offset < dl.obj_size_bound() <= 1<<61 let field_align = if let Some(pack) = pack { - field.align.min(AbiAndPrefAlign::new(pack)) + field.align.min(AbiAlign::new(pack)) } else { field.align }; @@ -1342,7 +1336,7 @@ impl LayoutCalculator { // See documentation on `LayoutS::unadjusted_abi_align`. let unadjusted_abi_align = align.abi; if let Some(repr_align) = repr.align { - align = align.max(AbiAndPrefAlign::new(repr_align)); + align = align.max(AbiAlign::new(repr_align)); } // `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate. let align = align; diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index b5f93351d686..bb880a58e527 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -5,7 +5,7 @@ use rustc_data_structures::intern::Interned; use rustc_macros::HashStable_Generic; use crate::{ - AbiAndPrefAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche, + AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche, PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants, }; @@ -100,7 +100,7 @@ impl<'a> Layout<'a> { self.0.0.largest_niche } - pub fn align(self) -> AbiAndPrefAlign { + pub fn align(self) -> AbiAlign { self.0.0.align } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 46b7a0c1e77f..29e36c021edf 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -226,22 +226,22 @@ pub const MAX_SIMD_LANES: u64 = 1 << 0xF; #[derive(Debug, PartialEq, Eq)] pub struct TargetDataLayout { pub endian: Endian, - pub i1_align: AbiAndPrefAlign, - pub i8_align: AbiAndPrefAlign, - pub i16_align: AbiAndPrefAlign, - pub i32_align: AbiAndPrefAlign, - pub i64_align: AbiAndPrefAlign, - pub i128_align: AbiAndPrefAlign, - pub f16_align: AbiAndPrefAlign, - pub f32_align: AbiAndPrefAlign, - pub f64_align: AbiAndPrefAlign, - pub f128_align: AbiAndPrefAlign, + pub i1_align: AbiAlign, + pub i8_align: AbiAlign, + pub i16_align: AbiAlign, + pub i32_align: AbiAlign, + pub i64_align: AbiAlign, + pub i128_align: AbiAlign, + pub f16_align: AbiAlign, + pub f32_align: AbiAlign, + pub f64_align: AbiAlign, + pub f128_align: AbiAlign, pub pointer_size: Size, - pub pointer_align: AbiAndPrefAlign, - pub aggregate_align: AbiAndPrefAlign, + pub pointer_align: AbiAlign, + pub aggregate_align: AbiAlign, /// Alignments for vector types. - pub vector_align: Vec<(Size, AbiAndPrefAlign)>, + pub vector_align: Vec<(Size, AbiAlign)>, pub instruction_address_space: AddressSpace, @@ -257,22 +257,22 @@ impl Default for TargetDataLayout { let align = |bits| Align::from_bits(bits).unwrap(); TargetDataLayout { endian: Endian::Big, - i1_align: AbiAndPrefAlign::new(align(8)), - i8_align: AbiAndPrefAlign::new(align(8)), - i16_align: AbiAndPrefAlign::new(align(16)), - i32_align: AbiAndPrefAlign::new(align(32)), - i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, - i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, - f16_align: AbiAndPrefAlign::new(align(16)), - f32_align: AbiAndPrefAlign::new(align(32)), - f64_align: AbiAndPrefAlign::new(align(64)), - f128_align: AbiAndPrefAlign::new(align(128)), + i1_align: AbiAlign::new(align(8)), + i8_align: AbiAlign::new(align(8)), + i16_align: AbiAlign::new(align(16)), + i32_align: AbiAlign::new(align(32)), + i64_align: AbiAlign::new(align(32)), + i128_align: AbiAlign::new(align(32)), + f16_align: AbiAlign::new(align(16)), + f32_align: AbiAlign::new(align(32)), + f64_align: AbiAlign::new(align(64)), + f128_align: AbiAlign::new(align(128)), pointer_size: Size::from_bits(64), - pointer_align: AbiAndPrefAlign::new(align(64)), - aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) }, + pointer_align: AbiAlign::new(align(64)), + aggregate_align: AbiAlign { abi: align(8) }, vector_align: vec![ - (Size::from_bits(64), AbiAndPrefAlign::new(align(64))), - (Size::from_bits(128), AbiAndPrefAlign::new(align(128))), + (Size::from_bits(64), AbiAlign::new(align(64))), + (Size::from_bits(128), AbiAlign::new(align(128))), ], instruction_address_space: AddressSpace::DATA, c_enum_min_size: Integer::I32, @@ -330,8 +330,7 @@ impl TargetDataLayout { .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err }) }; let abi = parse_bits(s[0], "alignment", cause)?; - let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?; - Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? }) + Ok(AbiAlign::new(align_from_bits(abi)?)) }; let mut dl = TargetDataLayout::default(); @@ -426,7 +425,7 @@ impl TargetDataLayout { /// psABI-mandated alignment for a vector type, if any #[inline] - fn cabi_vector_align(&self, vec_size: Size) -> Option { + fn cabi_vector_align(&self, vec_size: Size) -> Option { self.vector_align .iter() .find(|(size, _align)| *size == vec_size) @@ -435,8 +434,8 @@ impl TargetDataLayout { /// an alignment resembling the one LLVM would pick for a vector #[inline] - pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { - self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new( + pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign { + self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new( Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(), )) } @@ -864,25 +863,24 @@ impl Align { /// It is of effectively no consequence for layout in structs and on the stack. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub struct AbiAndPrefAlign { +pub struct AbiAlign { pub abi: Align, - pub pref: Align, } -impl AbiAndPrefAlign { +impl AbiAlign { #[inline] - pub fn new(align: Align) -> AbiAndPrefAlign { - AbiAndPrefAlign { abi: align, pref: align } + pub fn new(align: Align) -> AbiAlign { + AbiAlign { abi: align } } #[inline] - pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { - AbiAndPrefAlign { abi: self.abi.min(other.abi), pref: self.pref.min(other.pref) } + pub fn min(self, other: AbiAlign) -> AbiAlign { + AbiAlign { abi: self.abi.min(other.abi) } } #[inline] - pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { - AbiAndPrefAlign { abi: self.abi.max(other.abi), pref: self.pref.max(other.pref) } + pub fn max(self, other: AbiAlign) -> AbiAlign { + AbiAlign { abi: self.abi.max(other.abi) } } } @@ -945,7 +943,7 @@ impl Integer { } } - pub fn align(self, cx: &C) -> AbiAndPrefAlign { + pub fn align(self, cx: &C) -> AbiAlign { use Integer::*; let dl = cx.data_layout(); @@ -1058,7 +1056,7 @@ impl Float { } } - pub fn align(self, cx: &C) -> AbiAndPrefAlign { + pub fn align(self, cx: &C) -> AbiAlign { use Float::*; let dl = cx.data_layout(); @@ -1102,7 +1100,7 @@ impl Primitive { } } - pub fn align(self, cx: &C) -> AbiAndPrefAlign { + pub fn align(self, cx: &C) -> AbiAlign { use Primitive::*; let dl = cx.data_layout(); @@ -1225,7 +1223,7 @@ impl Scalar { } } - pub fn align(self, cx: &impl HasDataLayout) -> AbiAndPrefAlign { + pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign { self.primitive().align(cx) } @@ -1731,7 +1729,7 @@ pub struct LayoutData { /// especially in the case of by-pointer struct returns, which allocate stack even when unused. pub uninhabited: bool, - pub align: AbiAndPrefAlign, + pub align: AbiAlign, pub size: Size, /// The largest alignment explicitly requested with `repr(align)` on this type or any field. diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index a0f96d85dc3c..1d1cf884e48b 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -812,11 +812,7 @@ fn codegen_regular_intrinsic_call<'tcx>( dest.write_cvalue(fx, val); } - sym::pref_align_of - | sym::needs_drop - | sym::type_id - | sym::type_name - | sym::variant_count => { + sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { intrinsic_args!(fx, args => (); intrinsic); let const_val = fx diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index a3f09f64a3ee..e217c09939ea 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -150,11 +150,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } value } - sym::pref_align_of - | sym::needs_drop - | sym::type_id - | sym::type_name - | sym::variant_count => { + sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap(); OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 64467a901369..ab27182c211a 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -50,13 +50,6 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env)) } - sym::pref_align_of => { - // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - let layout = tcx - .layout_of(typing_env.as_query_input(tp_ty)) - .map_err(|e| err_inval!(Layout(*e)))?; - ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) - } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128()) @@ -144,14 +137,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(result, self), dest)?; } - sym::pref_align_of - | sym::needs_drop - | sym::type_id - | sym::type_name - | sym::variant_count => { + sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => { let gid = GlobalId { instance, promoted: None }; let ty = match intrinsic_name { - sym::pref_align_of | sym::variant_count => self.tcx.types.usize, + sym::variant_count => self.tcx.types.usize, sym::needs_drop => self.tcx.types.bool, sym::type_id => self.tcx.types.u128, sym::type_name => Ty::new_static_str(self.tcx.tcx), diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 687d859df535..013e1d5d0fa7 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -207,6 +207,8 @@ declare_features! ( /// Allows exhaustive integer pattern matching with `usize::MAX`/`isize::MIN`/`isize::MAX`. (removed, precise_pointer_size_matching, "1.32.0", Some(56354), Some("removed in favor of half-open ranges")), + (removed, pref_align_of, "CURRENT_RUSTC_VERSION", Some(91971), + Some("removed due to marginal use and inducing compiler complications")), (removed, proc_macro_expr, "1.27.0", Some(54727), Some("subsumed by `#![feature(proc_macro_hygiene)]`")), (removed, proc_macro_gen, "1.27.0", Some(54727), diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 954c37540843..4434ceb49bca 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2651,15 +2651,6 @@ pub const fn size_of() -> usize; #[rustc_intrinsic] pub const fn min_align_of() -> usize; -/// The preferred alignment of a type. -/// -/// This intrinsic does not have a stable counterpart. -/// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971). -#[rustc_nounwind] -#[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_intrinsic] -pub const unsafe fn pref_align_of() -> usize; - /// Returns the number of variants of the type `T` cast to a `usize`; /// if `T` has no variants, returns `0`. Uninhabited variants will be counted. /// diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 48fa2bf29bc4..5e09145a2712 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index bfdf94c99007..b8d6c632b978 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index bfdf94c99007..b8d6c632b978 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index bfdf94c99007..b8d6c632b978 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index 48fa2bf29bc4..5e09145a2712 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index bfdf94c99007..b8d6c632b978 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 480f3f04215e..8ed6dedf4d5a 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(test) = FnAbi { ty: u8, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -44,9 +43,8 @@ error: fn_abi_of(test) = FnAbi { ty: bool, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -103,9 +101,8 @@ error: fn_abi_of(TestFnPtr) = FnAbi { ty: bool, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -151,9 +148,8 @@ error: fn_abi_of(TestFnPtr) = FnAbi { ty: u8, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -201,9 +197,8 @@ error: fn_abi_of(test_generic) = FnAbi { ty: *const T, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -241,9 +236,8 @@ error: fn_abi_of(test_generic) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -288,9 +282,8 @@ error: ABIs are not compatible ty: u8, layout: Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -327,9 +320,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -362,9 +354,8 @@ error: ABIs are not compatible ty: u32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -401,9 +392,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -442,9 +432,8 @@ error: ABIs are not compatible ty: [u8; 32], layout: Layout { size: Size(32 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -482,9 +471,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -517,9 +505,8 @@ error: ABIs are not compatible ty: [u32; 32], layout: Layout { size: Size(128 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -557,9 +544,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -598,9 +584,8 @@ error: ABIs are not compatible ty: f32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -636,9 +621,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -671,9 +655,8 @@ error: ABIs are not compatible ty: u32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -710,9 +693,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -751,9 +733,8 @@ error: ABIs are not compatible ty: i32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -790,9 +771,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -825,9 +805,8 @@ error: ABIs are not compatible ty: u32, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -864,9 +843,8 @@ error: ABIs are not compatible ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -925,9 +903,8 @@ error: fn_abi_of(assoc_test) = FnAbi { ty: &S, layout: Layout { size: $SOME_SIZE, - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -977,9 +954,8 @@ error: fn_abi_of(assoc_test) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index f91d1b5fa63c..2233e8e4f623 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi { ty: (), layout: Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: $SOME_ALIGN, - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs index a467c445d616..30a523f364c7 100644 --- a/tests/ui/intrinsics/intrinsic-alignment.rs +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -23,18 +23,12 @@ use std::intrinsics as rusti; mod m { #[cfg(target_arch = "x86")] pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 4); - } + assert_eq!(crate::rusti::min_align_of::(), 4); } #[cfg(not(target_arch = "x86"))] pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } @@ -42,30 +36,21 @@ mod m { mod m { #[cfg(target_arch = "x86_64")] pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } #[cfg(target_os = "windows")] mod m { pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } #[cfg(target_family = "wasm")] mod m { pub fn main() { - unsafe { - assert_eq!(crate::rusti::pref_align_of::(), 8); - assert_eq!(crate::rusti::min_align_of::(), 8); - } + assert_eq!(crate::rusti::min_align_of::(), 8); } } diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index abaa16cdefac..b2ce6385ab65 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -6,9 +6,8 @@ LL | union EmptyUnion {} error: layout_of(E) = Layout { size: Size(12 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -45,9 +44,8 @@ error: layout_of(E) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -67,9 +65,8 @@ error: layout_of(E) = Layout { }, Layout { size: Size(12 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -108,9 +105,8 @@ LL | enum E { Foo, Bar(!, i32, i32) } error: layout_of(S) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -156,9 +152,8 @@ LL | struct S { f1: i32, f2: (), f3: i32 } error: layout_of(U) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -182,9 +177,8 @@ LL | union U { f1: (i32, i32), f3: i32 } error: layout_of(Result) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -234,9 +228,8 @@ error: layout_of(Result) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -273,9 +266,8 @@ error: layout_of(Result) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -323,9 +315,8 @@ LL | type Test = Result; error: layout_of(i32) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -353,9 +344,8 @@ LL | type T = impl std::fmt::Debug; error: layout_of(V) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -379,9 +369,8 @@ LL | pub union V { error: layout_of(W) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -405,9 +394,8 @@ LL | pub union W { error: layout_of(Y) = Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -431,9 +419,8 @@ LL | pub union Y { error: layout_of(P1) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -457,9 +444,8 @@ LL | union P1 { x: u32 } error: layout_of(P2) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -483,9 +469,8 @@ LL | union P2 { x: (u32, u32) } error: layout_of(P3) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -509,9 +494,8 @@ LL | union P3 { x: F32x4 } error: layout_of(P4) = Layout { size: Size(12 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -535,9 +519,8 @@ LL | union P4 { x: E } error: layout_of(P5) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Union { @@ -566,9 +549,8 @@ LL | union P5 { zst: [u16; 0], byte: u8 } error: layout_of(MaybeUninit) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Union { diff --git a/tests/ui/layout/enum.stderr b/tests/ui/layout/enum.stderr index 7f0b38d0a07c..f95b577bfc9d 100644 --- a/tests/ui/layout/enum.stderr +++ b/tests/ui/layout/enum.stderr @@ -1,4 +1,4 @@ -error: align: AbiAndPrefAlign { abi: Align(2 bytes), pref: $PREF_ALIGN } +error: align: AbiAlign { abi: Align(2 bytes) } --> $DIR/enum.rs:9:1 | LL | enum UninhabitedVariantAlign { diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 9c3a8662d4f0..d910456c0e6d 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -1,8 +1,7 @@ error: layout_of(A) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(A) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Memory { sized: true, @@ -78,9 +76,8 @@ LL | enum A { Apple } error: layout_of(B) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Scalar( Initialized { @@ -123,9 +120,8 @@ error: layout_of(B) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(1 bytes), }, backend_repr: Memory { sized: true, @@ -156,9 +152,8 @@ LL | enum B { Banana = 255, } error: layout_of(C) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(2 bytes), }, backend_repr: Scalar( Initialized { @@ -201,9 +196,8 @@ error: layout_of(C) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(2 bytes), }, backend_repr: Memory { sized: true, @@ -234,9 +228,8 @@ LL | enum C { Chaenomeles = 256, } error: layout_of(P) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -279,9 +272,8 @@ error: layout_of(P) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -312,9 +304,8 @@ LL | enum P { Peach = 0x1000_0000isize, } error: layout_of(T) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -357,9 +348,8 @@ error: layout_of(T) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index ef7f0cd2d1c3..2087fedeb19b 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -1,8 +1,7 @@ error: layout_of(MissingPayloadField) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -51,9 +50,8 @@ error: layout_of(MissingPayloadField) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -89,9 +87,8 @@ error: layout_of(MissingPayloadField) = Layout { }, Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -122,9 +119,8 @@ LL | pub enum MissingPayloadField { error: layout_of(CommonPayloadField) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -174,9 +170,8 @@ error: layout_of(CommonPayloadField) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -213,9 +208,8 @@ error: layout_of(CommonPayloadField) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -263,9 +257,8 @@ LL | pub enum CommonPayloadField { error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -314,9 +307,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -352,9 +344,8 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -401,9 +392,8 @@ LL | pub enum CommonPayloadFieldIsMaybeUninit { error: layout_of(NicheFirst) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -456,9 +446,8 @@ error: layout_of(NicheFirst) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -506,9 +495,8 @@ error: layout_of(NicheFirst) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -528,9 +516,8 @@ error: layout_of(NicheFirst) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -561,9 +548,8 @@ LL | pub enum NicheFirst { error: layout_of(NicheSecond) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -616,9 +602,8 @@ error: layout_of(NicheSecond) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -666,9 +651,8 @@ error: layout_of(NicheSecond) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -688,9 +672,8 @@ error: layout_of(NicheSecond) = Layout { }, Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index a9081afc5094..6bcc5b4906b5 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -1,8 +1,7 @@ error: layout_of(Aligned1) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -39,9 +38,8 @@ error: layout_of(Aligned1) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -63,9 +61,8 @@ error: layout_of(Aligned1) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -100,9 +97,8 @@ LL | pub enum Aligned1 { error: layout_of(Aligned2) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Scalar( Initialized { @@ -145,9 +141,8 @@ error: layout_of(Aligned2) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -169,9 +164,8 @@ error: layout_of(Aligned2) = Layout { }, Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index b635d1a45bb7..9bd8ced0c02d 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -1,8 +1,7 @@ error: layout_of(A) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(A) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -78,9 +76,8 @@ LL | enum A { Apple } error: layout_of(B) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -123,9 +120,8 @@ error: layout_of(B) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -156,9 +152,8 @@ LL | enum B { Banana = 255, } error: layout_of(C) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -201,9 +196,8 @@ error: layout_of(C) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -234,9 +228,8 @@ LL | enum C { Chaenomeles = 256, } error: layout_of(P) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -279,9 +272,8 @@ error: layout_of(P) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, @@ -312,9 +304,8 @@ LL | enum P { Peach = 0x1000_0000isize, } error: layout_of(T) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Scalar( Initialized { @@ -357,9 +348,8 @@ error: layout_of(T) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: Align(4 bytes), }, backend_repr: Memory { sized: true, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 1ba184bdacef..1707b8aff81c 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -1,8 +1,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -39,9 +38,8 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -65,9 +63,8 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -111,9 +108,8 @@ LL | type AlignedResult = Result<[u32; 0], bool>; error: layout_of(MultipleAlignments) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -150,9 +146,8 @@ error: layout_of(MultipleAlignments) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(2 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -176,9 +171,8 @@ error: layout_of(MultipleAlignments) = Layout { }, Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -202,9 +196,8 @@ error: layout_of(MultipleAlignments) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -248,9 +241,8 @@ LL | enum MultipleAlignments { error: layout_of(Result<[u32; 0], Packed>>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -287,9 +279,8 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -313,9 +304,8 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, Layout { size: Size(3 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -359,9 +349,8 @@ LL | type NicheLosesToTagged = Result<[u32; 0], Packed>>; error: layout_of(Result<[u32; 0], Packed>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -402,9 +391,8 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { variants: [ Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, @@ -428,9 +416,8 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $PREF_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index c11acc98637d..63d685951d98 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index a7888155deaf..555471be0271 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index c11acc98637d..63d685951d98 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index c11acc98637d..63d685951d98 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -1,8 +1,7 @@ error: layout_of(Univariant) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(Univariant) = Layout { variants: [ Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum Univariant { error: layout_of(TwoVariants) = Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariants) = Layout { variants: [ Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariants) = Layout { }, Layout { size: Size(8 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariants { error: layout_of(DeadBranchHasOtherField) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index f63574182c25..d88a842f8848 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -1,8 +1,7 @@ error: layout_of(UnivariantU8) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -45,9 +44,8 @@ error: layout_of(UnivariantU8) = Layout { variants: [ Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -88,9 +86,8 @@ LL | enum UnivariantU8 { error: layout_of(TwoVariantsU8) = Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -139,9 +136,8 @@ error: layout_of(TwoVariantsU8) = Layout { variants: [ Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -177,9 +173,8 @@ error: layout_of(TwoVariantsU8) = Layout { }, Layout { size: Size(2 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: ScalarPair( Initialized { @@ -226,9 +221,8 @@ LL | enum TwoVariantsU8 { error: layout_of(DeadBranchHasOtherFieldU8) = Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -265,9 +259,8 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { variants: [ Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -295,9 +288,8 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { }, Layout { size: Size(16 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(8 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index 58ca585f4a9a..a417e502e356 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -41,9 +41,8 @@ LL | let _: NonNegOneI8 = -128; error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -80,9 +79,8 @@ LL | type NonNullI8 = pattern_type!(i8 is ..0 | 1..); error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index bcb602a70dd6..a9c674632cb2 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -1,8 +1,7 @@ error: layout_of(NonZero) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -46,9 +45,8 @@ LL | type X = std::num::NonZeroU32; error: layout_of((u32) is 1..) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -85,9 +83,8 @@ LL | type Y = pattern_type!(u32 is 1..); error: layout_of(Option<(u32) is 1..>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -125,9 +122,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout { variants: [ Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -147,9 +143,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -199,9 +194,8 @@ LL | type Z = Option; error: layout_of(Option>) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -239,9 +233,8 @@ error: layout_of(Option>) = Layout { variants: [ Layout { size: Size(0 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Memory { sized: true, @@ -261,9 +254,8 @@ error: layout_of(Option>) = Layout { }, Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -313,9 +305,8 @@ LL | type A = Option; error: layout_of(NonZeroU32New) = Layout { size: Size(4 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(4 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -387,9 +378,8 @@ LL | type WRAP2 = pattern_type!(u32 is 5..2); error: layout_of((i8) is -10..=10) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { @@ -426,9 +416,8 @@ LL | type SIGN = pattern_type!(i8 is -10..=10); error: layout_of((i8) is i8::MIN..=0) = Layout { size: Size(1 bytes), - align: AbiAndPrefAlign { + align: AbiAlign { abi: Align(1 bytes), - pref: $SOME_ALIGN, }, backend_repr: Scalar( Initialized { From ec13ae6475275d82ec48e2ae32e27eaecdfa19cd Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 4 Jun 2025 14:02:09 -0700 Subject: [PATCH 096/183] compiler: add Deref to AbiAlign to ease transition We will want to remove many cases of `.abi`, including `.abi.thing`, so this may simplify future PRs and certainly doesn't hurt. We omit DerefMut because mutation is much rarer and localized. --- compiler/rustc_abi/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 29e36c021edf..4268e68b2e42 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -43,7 +43,7 @@ use std::fmt; #[cfg(feature = "nightly")] use std::iter::Step; use std::num::{NonZeroUsize, ParseIntError}; -use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub}; +use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub}; use std::str::FromStr; use bitflags::bitflags; @@ -884,6 +884,14 @@ impl AbiAlign { } } +impl Deref for AbiAlign { + type Target = Align; + + fn deref(&self) -> &Self::Target { + &self.abi + } +} + /// Integers, also used for enum discriminants. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr( From d2afab4d60d393bcaead85b051a33b8fddeaf5a6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jun 2025 22:40:40 -0400 Subject: [PATCH 097/183] Dont make ObligationCtxts with diagnostics unnecessarily --- compiler/rustc_const_eval/src/check_consts/check.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 6167f8cd4b51..9719d4052590 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -395,7 +395,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { } let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx)); - let ocx = ObligationCtxt::new_with_diagnostics(&infcx); + let ocx = ObligationCtxt::new(&infcx); let body_id = self.body.source.def_id().expect_local(); let host_polarity = match self.const_kind() { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index e39fd6b947b4..4dc27622d235 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -319,7 +319,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) let infcx = tcx.infer_ctxt().ignoring_regions().build(ty::TypingMode::non_body_analysis()); - let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); + let ocx = traits::ObligationCtxt::new(&infcx); let cause = traits::ObligationCause::dummy(); let param_env = tcx.param_env(impl_def_id); From 87141e37f32b31de0cc1e9559319ea408c794fb1 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 23 May 2025 12:41:18 +0000 Subject: [PATCH 098/183] move `canonicalize_param_env` into sub-fn --- .../src/canonicalizer.rs | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index a87ae5284b1a..4b48ae7c4175 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -100,6 +100,31 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { Canonical { max_universe, variables, value } } + fn canonicalize_param_env( + delegate: &'a D, + variables: &'a mut Vec, + param_env: I::ParamEnv, + ) -> (I::ParamEnv, HashMap, Vec>) { + if !param_env.has_type_flags(NEEDS_CANONICAL) { + return (param_env, Default::default(), Vec::new()); + } + + let mut env_canonicalizer = Canonicalizer { + delegate, + canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, + + variables, + variable_lookup_table: Default::default(), + var_kinds: Vec::new(), + binder_index: ty::INNERMOST, + + cache: Default::default(), + }; + let param_env = param_env.fold_with(&mut env_canonicalizer); + debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST); + (param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds) + } + /// When canonicalizing query inputs, we keep `'static` in the `param_env` /// but erase it everywhere else. We generally don't want to depend on region /// identity, so while it should not matter whether `'static` is kept in the @@ -114,37 +139,17 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { input: QueryInput, ) -> ty::Canonical> { // First canonicalize the `param_env` while keeping `'static` - let mut env_canonicalizer = Canonicalizer { - delegate, - canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, - - variables, - variable_lookup_table: Default::default(), - var_kinds: Vec::new(), - binder_index: ty::INNERMOST, - - cache: Default::default(), - }; - - let param_env = input.goal.param_env; - let param_env = if param_env.has_type_flags(NEEDS_CANONICAL) { - param_env.fold_with(&mut env_canonicalizer) - } else { - param_env - }; - - debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST); + let (param_env, variable_lookup_table, var_kinds) = + Canonicalizer::canonicalize_param_env(delegate, variables, input.goal.param_env); // Then canonicalize the rest of the input without keeping `'static` // while *mostly* reusing the canonicalizer from above. let mut rest_canonicalizer = Canonicalizer { delegate, canonicalize_mode: CanonicalizeMode::Input { keep_static: false }, - variables: env_canonicalizer.variables, - // We're able to reuse the `variable_lookup_table` as whether or not - // it already contains an entry for `'static` does not matter. - variable_lookup_table: env_canonicalizer.variable_lookup_table, - var_kinds: env_canonicalizer.var_kinds, + variables, + variable_lookup_table, + var_kinds, binder_index: ty::INNERMOST, // We do not reuse the cache as it may contain entries whose canonicalized From 758f4c94989a324b9d17722233bfc6df1a3ef2c6 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 23 May 2025 14:02:08 +0000 Subject: [PATCH 099/183] add `param_env` cache to canonicalization --- compiler/rustc_middle/src/ty/context.rs | 14 ++++ .../src/canonicalizer.rs | 74 +++++++++++++++---- compiler/rustc_type_ir/src/canonical.rs | 9 +++ compiler/rustc_type_ir/src/interner.rs | 9 ++- 4 files changed, 91 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0b1e9852d2a9..5e14516c7122 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -179,6 +179,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> { f(&mut *self.new_solver_evaluation_cache.lock()) } + fn canonical_param_env_cache_get_or_insert( + self, + param_env: ty::ParamEnv<'tcx>, + f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry, + from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry) -> R, + ) -> R { + let mut cache = self.new_solver_canonical_param_env_cache.lock(); + let entry = cache.entry(param_env).or_insert_with(f); + from_entry(entry) + } + fn evaluation_is_concurrent(&self) -> bool { self.sess.threads() > 1 } @@ -1444,6 +1455,8 @@ pub struct GlobalCtxt<'tcx> { /// Caches the results of goal evaluation in the new solver. pub new_solver_evaluation_cache: Lock>>, + pub new_solver_canonical_param_env_cache: + Lock, ty::CanonicalParamEnvCacheEntry>>>, pub canonical_param_env_cache: CanonicalParamEnvCache<'tcx>, @@ -1692,6 +1705,7 @@ impl<'tcx> TyCtxt<'tcx> { selection_cache: Default::default(), evaluation_cache: Default::default(), new_solver_evaluation_cache: Default::default(), + new_solver_canonical_param_env_cache: Default::default(), canonical_param_env_cache: Default::default(), data_layout, alloc_map: interpret::AllocMap::new(), diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 4b48ae7c4175..cea775331786 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -4,8 +4,9 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack}; use rustc_type_ir::inherent::*; use rustc_type_ir::solve::{Goal, QueryInput}; use rustc_type_ir::{ - self as ty, Canonical, CanonicalTyVarKind, CanonicalVarKind, Flags, InferCtxtLike, Interner, - TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalTyVarKind, CanonicalVarKind, + Flags, InferCtxtLike, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, }; use crate::delegate::SolverDelegate; @@ -109,20 +110,65 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { return (param_env, Default::default(), Vec::new()); } - let mut env_canonicalizer = Canonicalizer { - delegate, - canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, + // Check whether we can use the global cache for this param_env. As we only use + // the `param_env` itself as the cache key, considering any additional information + // durnig its canonicalization would be incorrect. We always canonicalize region + // inference variables in a separate universe, so these are fine. However, we do + // track the universe of type and const inference variables so these must not be + // globally cached. We don't rely on any additional information when canonicalizing + // placeholders. + if !param_env.has_non_region_infer() { + delegate.cx().canonical_param_env_cache_get_or_insert( + param_env, + || { + let mut variables = Vec::new(); + let mut env_canonicalizer = Canonicalizer { + delegate, + canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, - variables, - variable_lookup_table: Default::default(), - var_kinds: Vec::new(), - binder_index: ty::INNERMOST, + variables: &mut variables, + variable_lookup_table: Default::default(), + var_kinds: Vec::new(), + binder_index: ty::INNERMOST, - cache: Default::default(), - }; - let param_env = param_env.fold_with(&mut env_canonicalizer); - debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST); - (param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds) + cache: Default::default(), + }; + let param_env = param_env.fold_with(&mut env_canonicalizer); + debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST); + CanonicalParamEnvCacheEntry { + param_env, + variable_lookup_table: env_canonicalizer.variable_lookup_table, + var_kinds: env_canonicalizer.var_kinds, + variables, + } + }, + |&CanonicalParamEnvCacheEntry { + param_env, + variables: ref cache_variables, + ref variable_lookup_table, + ref var_kinds, + }| { + debug_assert!(variables.is_empty()); + variables.extend(cache_variables.iter().copied()); + (param_env, variable_lookup_table.clone(), var_kinds.clone()) + }, + ) + } else { + let mut env_canonicalizer = Canonicalizer { + delegate, + canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, + + variables, + variable_lookup_table: Default::default(), + var_kinds: Vec::new(), + binder_index: ty::INNERMOST, + + cache: Default::default(), + }; + let param_env = param_env.fold_with(&mut env_canonicalizer); + debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST); + (param_env, env_canonicalizer.variable_lookup_table, env_canonicalizer.var_kinds) + } } /// When canonicalizing query inputs, we keep `'static` in the `param_env` diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 2b1b0617cef6..c66a83662d76 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -7,6 +7,7 @@ use derive_where::derive_where; use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use crate::data_structures::HashMap; use crate::inherent::*; use crate::{self as ty, Interner, TypingMode, UniverseIndex}; @@ -333,3 +334,11 @@ impl Index for CanonicalVarValues { &self.var_values.as_slice()[value.as_usize()] } } + +#[derive_where(Clone, Debug; I: Interner)] +pub struct CanonicalParamEnvCacheEntry { + pub param_env: I::ParamEnv, + pub variables: Vec, + pub variable_lookup_table: HashMap, + pub var_kinds: Vec>, +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 05ca6f103233..9cbbb74f63e4 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -12,7 +12,7 @@ use crate::lang_items::TraitSolverLangItem; use crate::relate::Relate; use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult}; use crate::visit::{Flags, TypeVisitable}; -use crate::{self as ty, search_graph}; +use crate::{self as ty, CanonicalParamEnvCacheEntry, search_graph}; #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_interner")] pub trait Interner: @@ -149,6 +149,13 @@ pub trait Interner: fn with_global_cache(self, f: impl FnOnce(&mut search_graph::GlobalCache) -> R) -> R; + fn canonical_param_env_cache_get_or_insert( + self, + param_env: Self::ParamEnv, + f: impl FnOnce() -> CanonicalParamEnvCacheEntry, + from_entry: impl FnOnce(&CanonicalParamEnvCacheEntry) -> R, + ) -> R; + fn evaluation_is_concurrent(&self) -> bool; fn expand_abstract_consts>(self, t: T) -> T; From 889f7cbffa5b7e89fe006c1d35dad42ef6ecc525 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 8 Jun 2025 20:11:19 -0700 Subject: [PATCH 100/183] Avoid a gratuitous 10s wait in a stress test `stress_recv_timeout_two_threads`, in the mpmc and mpsc testsuites, is a stress test of the `recv_timeout` function. This test processes and ignores timeouts, and just ensures that every sent value gets received. As such, the exact length of the timeouts is not critical, only that the timeout and sleep durations ensure that at least one timeout occurred. The current tests have 100 iterations, half of which sleep for 200ms, causing the test to take 10s. This represents around 2/3rds of the *total* runtime of the `library/std` testsuite. Reduce this to 50 iterations where half of them sleep for 10ms, causing the test to take 0.25s. Add a check that at least one timeout occurred. --- library/std/tests/sync/mpmc.rs | 11 ++++++++--- library/std/tests/sync/mpsc.rs | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/library/std/tests/sync/mpmc.rs b/library/std/tests/sync/mpmc.rs index 78abcb3bcbe1..594fc2180d83 100644 --- a/library/std/tests/sync/mpmc.rs +++ b/library/std/tests/sync/mpmc.rs @@ -462,8 +462,8 @@ fn oneshot_single_thread_recv_timeout() { #[test] fn stress_recv_timeout_two_threads() { let (tx, rx) = channel(); - let stress = stress_factor() + 100; - let timeout = Duration::from_millis(100); + let stress = stress_factor() + 50; + let timeout = Duration::from_millis(5); thread::spawn(move || { for i in 0..stress { @@ -475,18 +475,23 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; + let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { assert_eq!(n, 1usize); recv_count += 1; } - Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Timeout) => { + got_timeout = true; + continue; + } Err(RecvTimeoutError::Disconnected) => break, } } assert_eq!(recv_count, stress); + assert!(got_timeout); } #[test] diff --git a/library/std/tests/sync/mpsc.rs b/library/std/tests/sync/mpsc.rs index 1d8edfde44be..9de4a71987b8 100644 --- a/library/std/tests/sync/mpsc.rs +++ b/library/std/tests/sync/mpsc.rs @@ -425,8 +425,8 @@ fn oneshot_single_thread_recv_timeout() { #[test] fn stress_recv_timeout_two_threads() { let (tx, rx) = channel(); - let stress = stress_factor() + 100; - let timeout = Duration::from_millis(100); + let stress = stress_factor() + 50; + let timeout = Duration::from_millis(5); thread::spawn(move || { for i in 0..stress { @@ -438,18 +438,23 @@ fn stress_recv_timeout_two_threads() { }); let mut recv_count = 0; + let mut got_timeout = false; loop { match rx.recv_timeout(timeout) { Ok(n) => { assert_eq!(n, 1usize); recv_count += 1; } - Err(RecvTimeoutError::Timeout) => continue, + Err(RecvTimeoutError::Timeout) => { + got_timeout = true; + continue; + } Err(RecvTimeoutError::Disconnected) => break, } } assert_eq!(recv_count, stress); + assert!(got_timeout); } #[test] From 58bef69b81fb78a4edf2e289d4e7d74effb9aebf Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 8 Jun 2025 10:21:57 +0000 Subject: [PATCH 101/183] compiler-builtins: Resolve `unsafe_op_in_unsafe_fn` on Arm32 Android There are a few places that violate this lint, which showed up in rust-lang/rust CI (the relevent module is gated behind `kernel_user_helpers` which is only set for `armv4t`, `armv5te`, and `arm-linux-androideabi`; none of these are tested in compiler-builtins CI). Add new `unsafe { /* ... */ }` blocks where needed to address this. Some blocks should get a more thorough review of their preconditions, so their safety comments are left as `FIXME`s. --- .../compiler-builtins/src/arm_linux.rs | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/arm_linux.rs b/library/compiler-builtins/compiler-builtins/src/arm_linux.rs index 6ce67ba719c9..ab9f86807390 100644 --- a/library/compiler-builtins/compiler-builtins/src/arm_linux.rs +++ b/library/compiler-builtins/compiler-builtins/src/arm_linux.rs @@ -4,12 +4,17 @@ use core::{arch, mem}; // Kernel-provided user-mode helper functions: // https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt unsafe fn __kuser_cmpxchg(oldval: u32, newval: u32, ptr: *mut u32) -> bool { - let f: extern "C" fn(u32, u32, *mut u32) -> u32 = mem::transmute(0xffff0fc0usize as *const ()); + // FIXME(volatile): the third parameter is a volatile pointer + // SAFETY: kernel docs specify a known address with the given signature + let f = unsafe { + mem::transmute::<_, extern "C" fn(u32, u32, *mut u32) -> u32>(0xffff0fc0usize as *const ()) + }; f(oldval, newval, ptr) == 0 } unsafe fn __kuser_memory_barrier() { - let f: extern "C" fn() = mem::transmute(0xffff0fa0usize as *const ()); + // SAFETY: kernel docs specify a known address with the given signature + let f = unsafe { mem::transmute::<_, extern "C" fn()>(0xffff0fa0usize as *const ()) }; f(); } @@ -67,8 +72,10 @@ fn insert_aligned(aligned: u32, val: u32, shift: u32, mask: u32) -> u32 { /// - if `size_of::() == 2`, `ptr` or `ptr` offset by 2 bytes must be valid for a relaxed atomic /// read of 2 bytes. /// - if `size_of::() == 4`, `ptr` must be valid for a relaxed atomic read of 4 bytes. +// FIXME: assert some of the preconditions in debug mode unsafe fn atomic_load_aligned(ptr: *mut u32) -> u32 { - if mem::size_of::() == 4 { + const { assert!(size_of::() <= 4) }; + if size_of::() == 4 { // SAFETY: As `T` has a size of 4, the caller garantees this is sound. unsafe { AtomicU32::from_ptr(ptr).load(Ordering::Relaxed) } } else { @@ -100,11 +107,13 @@ unsafe fn atomic_rmw u32, G: Fn(u32, u32) -> u32>(ptr: *mut T, let (shift, mask) = get_shift_mask(ptr); loop { - let curval_aligned = atomic_load_aligned::(aligned_ptr); + // FIXME(safety): preconditions review needed + let curval_aligned = unsafe { atomic_load_aligned::(aligned_ptr) }; let curval = extract_aligned(curval_aligned, shift, mask); let newval = f(curval); let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask); - if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) { + // FIXME(safety): preconditions review needed + if unsafe { __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) } { return g(curval, newval); } } @@ -116,13 +125,15 @@ unsafe fn atomic_cmpxchg(ptr: *mut T, oldval: u32, newval: u32) -> u32 { let (shift, mask) = get_shift_mask(ptr); loop { - let curval_aligned = atomic_load_aligned::(aligned_ptr); + // FIXME(safety): preconditions review needed + let curval_aligned = unsafe { atomic_load_aligned::(aligned_ptr) }; let curval = extract_aligned(curval_aligned, shift, mask); if curval != oldval { return curval; } let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask); - if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) { + // FIXME(safety): preconditions review needed + if unsafe { __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) } { return oldval; } } @@ -132,7 +143,14 @@ macro_rules! atomic_rmw { ($name:ident, $ty:ty, $op:expr, $fetch:expr) => { intrinsics! { pub unsafe extern "C" fn $name(ptr: *mut $ty, val: $ty) -> $ty { - atomic_rmw(ptr, |x| $op(x as $ty, val) as u32, |old, new| $fetch(old, new)) as $ty + // FIXME(safety): preconditions review needed + unsafe { + atomic_rmw( + ptr, + |x| $op(x as $ty, val) as u32, + |old, new| $fetch(old, new) + ) as $ty + } } } }; @@ -149,7 +167,8 @@ macro_rules! atomic_cmpxchg { ($name:ident, $ty:ty) => { intrinsics! { pub unsafe extern "C" fn $name(ptr: *mut $ty, oldval: $ty, newval: $ty) -> $ty { - atomic_cmpxchg(ptr, oldval as u32, newval as u32) as $ty + // FIXME(safety): preconditions review needed + unsafe { atomic_cmpxchg(ptr, oldval as u32, newval as u32) as $ty } } } }; @@ -285,6 +304,7 @@ atomic_cmpxchg!(__sync_val_compare_and_swap_4, u32); intrinsics! { pub unsafe extern "C" fn __sync_synchronize() { - __kuser_memory_barrier(); + // SAFETY: preconditions are the same as the calling function. + unsafe { __kuser_memory_barrier() }; } } From f131c2fa47a743e3822d28b24ba7709f60b0cbc5 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 8 Jun 2025 17:13:18 +0000 Subject: [PATCH 102/183] compiler-builtins: Specify `:r` registers for `usize` On the ILP32 `x86_64-unknown-linux-gnux32` target, `usize` is 32 bits so there is a sub-register alignment warning. Specify the 64-bit `r` registers, which matches the current default as well as the size of the other operands in the routines. --- .../compiler-builtins/compiler-builtins/src/mem/x86_64.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs index 5cbe83ab1e21..fb29eb11b231 100644 --- a/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs +++ b/library/compiler-builtins/compiler-builtins/src/mem/x86_64.rs @@ -69,7 +69,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) { "rep movsb", "sub $7, %rsi", "sub $7, %rdi", - "mov {qword_count}, %rcx", + "mov {qword_count:r}, %rcx", "rep movsq", "test {pre_byte_count:e}, {pre_byte_count:e}", "add $7, %rsi", @@ -212,7 +212,7 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize { let x = { let r; asm!( - "movdqa ({addr}), {dest}", + "movdqa ({addr:r}), {dest}", addr = in(reg) s, dest = out(xmm_reg) r, options(att_syntax, nostack), @@ -232,7 +232,7 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize { let x = { let r; asm!( - "movdqa ({addr}), {dest}", + "movdqa ({addr:r}), {dest}", addr = in(reg) s, dest = out(xmm_reg) r, options(att_syntax, nostack), From fc715449326ce5dc193bc717c854c8d35c07508e Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 9 Jun 2025 04:10:24 +0000 Subject: [PATCH 103/183] compiler-builtins: Emit `rustc-check-cfg` earlier The `build.rs` entrypoint returns early for some targets, so emscripten and OpenBSD were not getting check-cfg set. Emit these earlier to avoid the `unexpected_cfgs` lint. --- library/compiler-builtins/compiler-builtins/build.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/build.rs b/library/compiler-builtins/compiler-builtins/build.rs index d37fdc5df507..7c8da02fd287 100644 --- a/library/compiler-builtins/compiler-builtins/build.rs +++ b/library/compiler-builtins/compiler-builtins/build.rs @@ -22,6 +22,9 @@ fn main() { println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display()); + println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)"); + println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))"); + // Emscripten's runtime includes all the builtins if target.os == "emscripten" { return; @@ -47,7 +50,6 @@ fn main() { } // These targets have hardware unaligned access support. - println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))"); if target.arch.contains("x86_64") || target.arch.contains("x86") || target.arch.contains("aarch64") @@ -78,7 +80,6 @@ fn main() { // Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. This // includes the old androideabi. It is deprecated but it is available as a // rustc target (arm-linux-androideabi). - println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)"); if llvm_target[0] == "armv4t" || llvm_target[0] == "armv5te" || target.triple == "arm-linux-androideabi" From ee00d0f0514c74fdd09de3e6cbb01009257f2a23 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 9 Jun 2025 04:56:52 +0000 Subject: [PATCH 104/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index d1a5ef7b7fce..c8721bb36001 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -a5584a8fe16037dc01782064fa41424a6dbe9987 +c31cccb7b5cc098b1a8c1794ed38d7fdbec0ccb0 From 7614592107065b37657de008638f9f5bc19362c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 9 Jun 2025 08:06:05 +0200 Subject: [PATCH 105/183] Do not inherit environment variables in citool tests So that we can make sure that they are reproducible locally. --- src/ci/citool/tests/jobs.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index fcdca899e068..2374eaa13af9 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -46,16 +46,21 @@ fn pr_jobs() { } fn get_matrix(event_name: &str, commit_msg: &str, branch_ref: &str) -> String { - let output = Command::new("cargo") - .args(["run", "-q", "calculate-job-matrix", "--jobs-file", TEST_JOBS_YML_PATH]) + let path = std::env::var("PATH"); + let mut cmd = Command::new("cargo"); + cmd.args(["run", "-q", "calculate-job-matrix", "--jobs-file", TEST_JOBS_YML_PATH]) + .env_clear() .env("GITHUB_EVENT_NAME", event_name) .env("COMMIT_MESSAGE", commit_msg) .env("GITHUB_REF", branch_ref) .env("GITHUB_RUN_ID", "123") .env("GITHUB_RUN_ATTEMPT", "1") - .stdout(Stdio::piped()) - .output() - .expect("Failed to execute command"); + .stdout(Stdio::piped()); + if let Ok(path) = path { + cmd.env("PATH", path); + } + + let output = cmd.output().expect("Failed to execute command"); let stdout = String::from_utf8(output.stdout).unwrap(); let stderr = String::from_utf8(output.stderr).unwrap(); From 54ed1b966fc0b4b46140bd4a3798d739acfe3249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 9 Jun 2025 08:10:55 +0200 Subject: [PATCH 106/183] Run `calculate_matrix` job on the `master` branch This allows us to reuse its cache on PR CI jobs. --- .github/workflows/ci.yml | 4 ++++ src/ci/citool/src/jobs.rs | 6 +++++- src/ci/citool/src/main.rs | 1 + src/ci/citool/tests/jobs.rs | 9 +++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81fb39cdc569..e5054a075676 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ name: CI on: push: branches: + # CI on master only serves for caching citool builds for the `calculate_matrix` job. + # In order to use GHA cache on PR CI (and auto/try) jobs, we need to write to it + # from the default branch. + - master - auto - try - try-perf diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 2884ae08ea88..81e002edb156 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -161,6 +161,8 @@ pub enum RunType { TryJob { job_patterns: Option> }, /// Merge attempt workflow AutoJob, + /// Fake job only used for sharing Github Actions cache. + MasterJob, } /// Maximum number of custom try jobs that can be requested in a single @@ -210,6 +212,7 @@ fn calculate_jobs( (jobs, "try", &db.envs.try_env) } RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), + RunType::MasterJob => return Ok(vec![]), }; let jobs = substitute_github_vars(jobs.clone()) .context("Failed to substitute GitHub context variables in jobs")?; @@ -262,7 +265,7 @@ pub fn calculate_job_matrix( eprintln!("Run type: {run_type:?}"); let jobs = calculate_jobs(&run_type, &db, channel)?; - if jobs.is_empty() { + if jobs.is_empty() && !matches!(run_type, RunType::MasterJob) { return Err(anyhow::anyhow!("Computed job list is empty")); } @@ -270,6 +273,7 @@ pub fn calculate_job_matrix( RunType::PullRequest => "pr", RunType::TryJob { .. } => "try", RunType::AutoJob => "auto", + RunType::MasterJob => "master", }; eprintln!("Output"); diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index bb73a5ef909f..fe1b36673a1b 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -47,6 +47,7 @@ impl GitHubContext { Some(RunType::TryJob { job_patterns: patterns }) } ("push", "refs/heads/auto") => Some(RunType::AutoJob), + ("push", "refs/heads/master") => Some(RunType::MasterJob), _ => None, } } diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index 2374eaa13af9..83f2fc0ed1f3 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -45,6 +45,15 @@ fn pr_jobs() { "#); } +#[test] +fn master_jobs() { + let stdout = get_matrix("push", "commit", "refs/heads/master"); + insta::assert_snapshot!(stdout, @r#" + jobs=[] + run_type=master + "#); +} + fn get_matrix(event_name: &str, commit_msg: &str, branch_ref: &str) -> String { let path = std::env::var("PATH"); let mut cmd = Command::new("cargo"); From cb9980133cbb670387a597c349397cd38f52edee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 8 Jun 2025 21:19:24 +0200 Subject: [PATCH 107/183] Do not checkout GCC submodule for the tidy job --- src/ci/github-actions/jobs.yml | 4 ++++ src/ci/scripts/checkout-submodules.sh | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 3f8ea696ee2e..43c77d1ddf7f 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -129,6 +129,10 @@ pr: - name: mingw-check-tidy continue_on_error: true free_disk: false + env: + # This submodule is expensive to checkout, and it should not be needed for + # tidy. This speeds up the PR CI job by ~1 minute. + SKIP_SUBMODULES: src/gcc <<: *job-linux-4c - name: x86_64-gnu-llvm-19 env: diff --git a/src/ci/scripts/checkout-submodules.sh b/src/ci/scripts/checkout-submodules.sh index 5bb343241aea..3b646587dc28 100755 --- a/src/ci/scripts/checkout-submodules.sh +++ b/src/ci/scripts/checkout-submodules.sh @@ -55,7 +55,11 @@ for i in ${!modules[@]}; do bg_pids[${i}]=$! continue else + # Submodule paths contained in SKIP_SUBMODULES (comma-separated list) will not be + # checked out. + if [ -z "${SKIP_SUBMODULES:-}" ] || [[ ! ",$SKIP_SUBMODULES," = *",$module,"* ]]; then use_git="$use_git $module" + fi fi done retry sh -c "git submodule deinit -f $use_git && \ From c2986eed43be1d33b07207dc098b2392eea57d61 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 27 May 2025 17:24:17 +0800 Subject: [PATCH 108/183] Add ui test removed-features-note-version-and-pr-issue-141619 Signed-off-by: xizheyin --- ...atures-note-version-and-pr-issue-141619.rs | 4 ++++ ...es-note-version-and-pr-issue-141619.stderr | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs create mode 100644 tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs new file mode 100644 index 000000000000..d8c5f48f9fd9 --- /dev/null +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs @@ -0,0 +1,4 @@ +#![feature(external_doc)] //~ ERROR feature has been removed +#![doc(include("README.md"))] //~ ERROR unknown `doc` attribute `include` + +fn main(){} diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr new file mode 100644 index 000000000000..3614e226c888 --- /dev/null +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr @@ -0,0 +1,19 @@ +error[E0557]: feature has been removed + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:1:12 + | +LL | #![feature(external_doc)] + | ^^^^^^^^^^^^ feature has been removed + | + = note: use #[doc = include_str!("filename")] instead, which handles macro invocations + +error: unknown `doc` attribute `include` + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:8 + | +LL | #![doc(include("README.md"))] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[deny(invalid_doc_attributes)]` on by default + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0557`. From b4ba017c3306bbdb8f3da3dff80e58ff3ed9a1ab Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 27 May 2025 17:29:17 +0800 Subject: [PATCH 109/183] Note the version and PR of removed features when using it Signed-off-by: xizheyin --- compiler/rustc_expand/messages.ftl | 1 + compiler/rustc_expand/src/config.rs | 11 +++++++++++ compiler/rustc_expand/src/errors.rs | 4 ++++ compiler/rustc_feature/src/removed.rs | 19 ++++++++++++++++--- .../deprecation/deprecated_no_stack_check.rs | 2 ++ .../deprecated_no_stack_check.stderr | 4 +++- .../feature-gate-coverage-attribute.rs | 2 ++ .../feature-gate-coverage-attribute.stderr | 5 +++-- tests/ui/feature-gates/gated-bad-feature.rs | 1 + .../ui/feature-gates/gated-bad-feature.stderr | 16 +++++++++------- ...atures-note-version-and-pr-issue-141619.rs | 2 ++ ...es-note-version-and-pr-issue-141619.stderr | 5 +++-- tests/ui/macros/macro-reexport-removed.rs | 1 + tests/ui/macros/macro-reexport-removed.stderr | 5 +++-- .../renamed-features-rustdoc_internals.rs | 2 ++ .../renamed-features-rustdoc_internals.stderr | 6 ++++-- .../const-trait-impl-parameter-mismatch.rs | 1 + ...const-trait-impl-parameter-mismatch.stderr | 5 +++-- 18 files changed, 71 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index f26c7c1ba0bc..08b7a3620830 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -62,6 +62,7 @@ expand_feature_not_allowed = expand_feature_removed = feature has been removed .label = feature has been removed + .note = removed in {$removed_rustc_version} (you are using {$current_rustc_version}){$pull_note} .reason = {$reason} expand_glob_delegation_outside_impls = diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index c50ab5959e25..9a359e9b0310 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -80,9 +80,20 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - // If the enabled feature has been removed, issue an error. if let Some(f) = REMOVED_LANG_FEATURES.iter().find(|f| name == f.feature.name) { + let pull_note = if let Some(pull) = f.pull { + format!( + "; see for more information", + pull + ) + } else { + "".to_owned() + }; sess.dcx().emit_err(FeatureRemoved { span: mi.span(), reason: f.reason.map(|reason| FeatureRemovedReason { reason }), + removed_rustc_version: f.feature.since, + current_rustc_version: sess.cfg_version, + pull_note, }); continue; } diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 89bdc7b6dfa5..ec0af67c0463 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -154,12 +154,16 @@ pub(crate) struct HelperAttributeNameInvalid { #[derive(Diagnostic)] #[diag(expand_feature_removed, code = E0557)] +#[note] pub(crate) struct FeatureRemoved<'a> { #[primary_span] #[label] pub span: Span, #[subdiagnostic] pub reason: Option>, + pub removed_rustc_version: &'a str, + pub current_rustc_version: &'a str, + pub pull_note: String, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 013e1d5d0fa7..3aa363674a9e 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -1,5 +1,7 @@ //! List of the removed feature gates. +use std::num::{NonZero, NonZeroU32}; + use rustc_span::sym; use super::{Feature, to_nonzero}; @@ -7,11 +9,21 @@ use super::{Feature, to_nonzero}; pub struct RemovedFeature { pub feature: Feature, pub reason: Option<&'static str>, + pub pull: Option>, +} + +macro_rules! opt_nonzero_u32 { + () => { + None + }; + ($val:expr) => { + Some(NonZeroU32::new($val).unwrap()) + }; } macro_rules! declare_features { ($( - $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, $reason:expr), + $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, $reason:expr $(, $pull:expr)?), )+) => { /// Formerly unstable features that have now been removed. pub static REMOVED_LANG_FEATURES: &[RemovedFeature] = &[ @@ -21,7 +33,8 @@ macro_rules! declare_features { since: $ver, issue: to_nonzero($issue), }, - reason: $reason + reason: $reason, + pull: opt_nonzero_u32!($($pull)?), }),+ ]; }; @@ -120,7 +133,7 @@ declare_features! ( Some("subsumed by `::foo::bar` paths")), /// Allows `#[doc(include = "some-file")]`. (removed, external_doc, "1.54.0", Some(44732), - Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")), + Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations"), 85457), /// Allows using `#[ffi_returns_twice]` on foreign functions. (removed, ffi_returns_twice, "1.78.0", Some(58314), Some("being investigated by the ffi-unwind project group")), diff --git a/tests/ui/deprecation/deprecated_no_stack_check.rs b/tests/ui/deprecation/deprecated_no_stack_check.rs index 8e1f5bbf045a..ef482098634a 100644 --- a/tests/ui/deprecation/deprecated_no_stack_check.rs +++ b/tests/ui/deprecation/deprecated_no_stack_check.rs @@ -1,3 +1,5 @@ +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" + #![deny(warnings)] #![feature(no_stack_check)] //~^ ERROR: feature has been removed [E0557] diff --git a/tests/ui/deprecation/deprecated_no_stack_check.stderr b/tests/ui/deprecation/deprecated_no_stack_check.stderr index d78ca20f10b4..be15d6bea074 100644 --- a/tests/ui/deprecation/deprecated_no_stack_check.stderr +++ b/tests/ui/deprecation/deprecated_no_stack_check.stderr @@ -1,8 +1,10 @@ error[E0557]: feature has been removed - --> $DIR/deprecated_no_stack_check.rs:2:12 + --> $DIR/deprecated_no_stack_check.rs:4:12 | LL | #![feature(no_stack_check)] | ^^^^^^^^^^^^^^ feature has been removed + | + = note: removed in 1.0.0 (you are using $RUSTC_VERSION) error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs index 0a463755f137..2cf4b76180e1 100644 --- a/tests/ui/feature-gates/feature-gate-coverage-attribute.rs +++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.rs @@ -1,3 +1,5 @@ +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" + #![crate_type = "lib"] #![feature(no_coverage)] //~ ERROR feature has been removed [E0557] diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr index 00e0f0afbde6..d8196242b544 100644 --- a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr @@ -1,13 +1,14 @@ error[E0557]: feature has been removed - --> $DIR/feature-gate-coverage-attribute.rs:2:12 + --> $DIR/feature-gate-coverage-attribute.rs:4:12 | LL | #![feature(no_coverage)] | ^^^^^^^^^^^ feature has been removed | + = note: removed in 1.74.0 (you are using $RUSTC_VERSION) = note: renamed to `coverage_attribute` error[E0658]: the `#[coverage]` attribute is an experimental feature - --> $DIR/feature-gate-coverage-attribute.rs:10:1 + --> $DIR/feature-gate-coverage-attribute.rs:12:1 | LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/gated-bad-feature.rs b/tests/ui/feature-gates/gated-bad-feature.rs index 51f2db5556e2..3114f661dc5b 100644 --- a/tests/ui/feature-gates/gated-bad-feature.rs +++ b/tests/ui/feature-gates/gated-bad-feature.rs @@ -1,3 +1,4 @@ +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] //~^ ERROR malformed `feature` //~| ERROR malformed `feature` diff --git a/tests/ui/feature-gates/gated-bad-feature.stderr b/tests/ui/feature-gates/gated-bad-feature.stderr index 2d01bdf3c1df..0e75dff14f8a 100644 --- a/tests/ui/feature-gates/gated-bad-feature.stderr +++ b/tests/ui/feature-gates/gated-bad-feature.stderr @@ -1,41 +1,43 @@ error[E0556]: malformed `feature` attribute input - --> $DIR/gated-bad-feature.rs:1:25 + --> $DIR/gated-bad-feature.rs:2:25 | LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] | ^^^^^^^^ help: expected just one word: `foo` error[E0556]: malformed `feature` attribute input - --> $DIR/gated-bad-feature.rs:1:35 + --> $DIR/gated-bad-feature.rs:2:35 | LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] | ^^^^^^^^^^^ help: expected just one word: `foo` error[E0557]: feature has been removed - --> $DIR/gated-bad-feature.rs:8:12 + --> $DIR/gated-bad-feature.rs:9:12 | LL | #![feature(test_removed_feature)] | ^^^^^^^^^^^^^^^^^^^^ feature has been removed + | + = note: removed in 1.0.0 (you are using $RUSTC_VERSION) error: malformed `feature` attribute input - --> $DIR/gated-bad-feature.rs:6:1 + --> $DIR/gated-bad-feature.rs:7:1 | LL | #![feature] | ^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name2, ...)]` error: malformed `feature` attribute input - --> $DIR/gated-bad-feature.rs:7:1 + --> $DIR/gated-bad-feature.rs:8:1 | LL | #![feature = "foo"] | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![feature(name1, name2, ...)]` error[E0635]: unknown feature `foo_bar_baz` - --> $DIR/gated-bad-feature.rs:1:12 + --> $DIR/gated-bad-feature.rs:2:12 | LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] | ^^^^^^^^^^^ error[E0635]: unknown feature `foo` - --> $DIR/gated-bad-feature.rs:1:48 + --> $DIR/gated-bad-feature.rs:2:48 | LL | #![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] | ^^^ diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs index d8c5f48f9fd9..ec6adb471ba5 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs @@ -1,3 +1,5 @@ +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" + #![feature(external_doc)] //~ ERROR feature has been removed #![doc(include("README.md"))] //~ ERROR unknown `doc` attribute `include` diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr index 3614e226c888..43205c7360b2 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr @@ -1,13 +1,14 @@ error[E0557]: feature has been removed - --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:1:12 + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:3:12 | LL | #![feature(external_doc)] | ^^^^^^^^^^^^ feature has been removed | + = note: removed in 1.54.0 (you are using $RUSTC_VERSION); see for more information = note: use #[doc = include_str!("filename")] instead, which handles macro invocations error: unknown `doc` attribute `include` - --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:8 + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:4:8 | LL | #![doc(include("README.md"))] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/macros/macro-reexport-removed.rs b/tests/ui/macros/macro-reexport-removed.rs index 4a054686d776..c1267f14cd86 100644 --- a/tests/ui/macros/macro-reexport-removed.rs +++ b/tests/ui/macros/macro-reexport-removed.rs @@ -1,4 +1,5 @@ //@ aux-build:two_macros.rs +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" #![feature(macro_reexport)] //~ ERROR feature has been removed diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index 475a586ddc08..3c6f011e39b9 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -1,13 +1,14 @@ error[E0557]: feature has been removed - --> $DIR/macro-reexport-removed.rs:3:12 + --> $DIR/macro-reexport-removed.rs:4:12 | LL | #![feature(macro_reexport)] | ^^^^^^^^^^^^^^ feature has been removed | + = note: removed in 1.0.0 (you are using $RUSTC_VERSION) = note: subsumed by `pub use` error: cannot find attribute `macro_reexport` in this scope - --> $DIR/macro-reexport-removed.rs:5:3 + --> $DIR/macro-reexport-removed.rs:6:3 | LL | #[macro_reexport(macro_one)] | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` diff --git a/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs b/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs index 739c624d0c6f..2257130280dc 100644 --- a/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs +++ b/tests/ui/rustdoc/renamed-features-rustdoc_internals.rs @@ -1,3 +1,5 @@ +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" + #![feature(doc_keyword)] //~ ERROR #![feature(doc_primitive)] //~ ERROR #![crate_type = "lib"] diff --git a/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr b/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr index d0979ce97ac8..d55825c8d794 100644 --- a/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr +++ b/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr @@ -1,17 +1,19 @@ error[E0557]: feature has been removed - --> $DIR/renamed-features-rustdoc_internals.rs:1:12 + --> $DIR/renamed-features-rustdoc_internals.rs:3:12 | LL | #![feature(doc_keyword)] | ^^^^^^^^^^^ feature has been removed | + = note: removed in 1.28.0 (you are using $RUSTC_VERSION) = note: merged into `#![feature(rustdoc_internals)]` error[E0557]: feature has been removed - --> $DIR/renamed-features-rustdoc_internals.rs:2:12 + --> $DIR/renamed-features-rustdoc_internals.rs:4:12 | LL | #![feature(doc_primitive)] | ^^^^^^^^^^^^^ feature has been removed | + = note: removed in 1.56.0 (you are using $RUSTC_VERSION) = note: merged into `#![feature(rustdoc_internals)]` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs index f90ff91aff4b..b563b78f78a1 100644 --- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs +++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.rs @@ -6,6 +6,7 @@ // Regression test for issue #125877. //@ compile-flags: -Znext-solver +//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION" #![feature(const_trait_impl, effects)] //~^ ERROR feature has been removed diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr index d45c4cba1f8b..70d0a4758205 100644 --- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr +++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr @@ -1,13 +1,14 @@ error[E0557]: feature has been removed - --> $DIR/const-trait-impl-parameter-mismatch.rs:10:30 + --> $DIR/const-trait-impl-parameter-mismatch.rs:11:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ feature has been removed | + = note: removed in 1.84.0 (you are using $RUSTC_VERSION) = note: removed, redundant with `#![feature(const_trait_impl)]` error[E0049]: associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter - --> $DIR/const-trait-impl-parameter-mismatch.rs:19:16 + --> $DIR/const-trait-impl-parameter-mismatch.rs:20:16 | LL | fn compute() -> u32; | - expected 1 type parameter From 4b898041f63c488e7173a5e161955aa3cafceb2f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 4 Jun 2025 17:10:31 +0800 Subject: [PATCH 110/183] Make `since` of removed features the version removed and fill `pull` Signed-off-by: xizheyin --- compiler/rustc_feature/src/removed.rs | 163 +++++++++--------- .../deprecated_no_stack_check.stderr | 2 +- .../feature-gate-coverage-attribute.stderr | 2 +- tests/ui/macros/macro-reexport-removed.stderr | 2 +- .../renamed-features-rustdoc_internals.stderr | 4 +- ...const-trait-impl-parameter-mismatch.stderr | 2 +- 6 files changed, 88 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 3aa363674a9e..9738f169595e 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -53,64 +53,64 @@ declare_features! ( // version they got originally added in.) /// Allows using the `amdgpu-kernel` ABI. - (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None), - (removed, advanced_slice_patterns, "1.0.0", Some(62254), - Some("merged into `#![feature(slice_patterns)]`")), + (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None, 120495), + (removed, advanced_slice_patterns, "1.42.0", Some(62254), + Some("merged into `#![feature(slice_patterns)]`"), 67712), (removed, allocator, "1.0.0", None, None), /// Allows a test to fail without failing the whole suite. - (removed, allow_fail, "1.19.0", Some(46488), Some("removed due to no clear use cases")), + (removed, allow_fail, "1.60.0", Some(46488), Some("removed due to no clear use cases"), 93416), (removed, await_macro, "1.38.0", Some(50547), - Some("subsumed by `.await` syntax")), + Some("subsumed by `.await` syntax"), 62293), /// Allows using the `box $expr` syntax. - (removed, box_syntax, "1.70.0", Some(49733), Some("replaced with `#[rustc_box]`")), + (removed, box_syntax, "1.70.0", Some(49733), Some("replaced with `#[rustc_box]`"), 108471), /// Allows capturing disjoint fields in a closure/coroutine (RFC 2229). - (removed, capture_disjoint_fields, "1.49.0", Some(53488), Some("stabilized in Rust 2021")), + (removed, capture_disjoint_fields, "1.69.0", Some(53488), Some("stabilized in Rust 2021"), 108550), /// Allows comparing raw pointers during const eval. (removed, const_compare_raw_pointers, "1.46.0", Some(53020), - Some("cannot be allowed in const eval in any meaningful way")), + Some("cannot be allowed in const eval in any meaningful way"), 73398), /// Allows limiting the evaluation steps of const expressions - (removed, const_eval_limit, "1.43.0", Some(67217), Some("removed the limit entirely")), + (removed, const_eval_limit, "1.72.0", Some(67217), Some("removed the limit entirely"), 103877), /// Allows non-trivial generic constants which have to be manually propagated upwards. - (removed, const_evaluatable_checked, "1.48.0", Some(76560), Some("renamed to `generic_const_exprs`")), + (removed, const_evaluatable_checked, "1.56.0", Some(76560), Some("renamed to `generic_const_exprs`"), 88369), /// Allows the definition of `const` functions with some advanced features. (removed, const_fn, "1.54.0", Some(57563), - Some("split into finer-grained feature gates")), + Some("split into finer-grained feature gates"), 85109), /// Allows const generic types (e.g. `struct Foo(...);`). - (removed, const_generics, "1.34.0", Some(44580), - Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")), + (removed, const_generics, "1.56.0", Some(44580), + Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`"), 88369), /// Allows `[x; N]` where `x` is a constant (RFC 2203). - (removed, const_in_array_repeat_expressions, "1.37.0", Some(49147), - Some("removed due to causing promotable bugs")), + (removed, const_in_array_repeat_expressions, "1.51.0", Some(49147), + Some("removed due to causing promotable bugs"), 80404), /// Allows casting raw pointers to `usize` during const eval. (removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), - Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")), + Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported"), 87020), /// Allows `T: ?const Trait` syntax in bounds. - (removed, const_trait_bound_opt_out, "1.42.0", Some(67794), - Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]")), + (removed, const_trait_bound_opt_out, "1.56.0", Some(67794), + Some("Removed in favor of `~const` bound in #![feature(const_trait_impl)]"), 88328), /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. - (removed, crate_visibility_modifier, "1.63.0", Some(53120), Some("removed in favor of `pub(crate)`")), + (removed, crate_visibility_modifier, "1.63.0", Some(53120), Some("removed in favor of `pub(crate)`"), 97254), /// Allows using custom attributes (RFC 572). (removed, custom_attribute, "1.0.0", Some(29642), - Some("removed in favor of `#![register_tool]` and `#![register_attr]`")), + Some("removed in favor of `#![register_tool]` and `#![register_attr]`"), 66070), /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`. (removed, custom_derive, "1.32.0", Some(29644), Some("subsumed by `#[proc_macro_derive]`")), /// Allows default type parameters to influence type inference. (removed, default_type_parameter_fallback, "1.82.0", Some(27336), - Some("never properly implemented; requires significant design work")), + Some("never properly implemented; requires significant design work"), 127655), /// Allows deriving traits as per `SmartPointer` specification - (removed, derive_smart_pointer, "1.79.0", Some(123430), Some("replaced by `CoercePointee`")), + (removed, derive_smart_pointer, "1.84.0", Some(123430), Some("replaced by `CoercePointee`"), 131284), /// Allows using `#[doc(keyword = "...")]`. - (removed, doc_keyword, "1.28.0", Some(51315), - Some("merged into `#![feature(rustdoc_internals)]`")), + (removed, doc_keyword, "1.58.0", Some(51315), + Some("merged into `#![feature(rustdoc_internals)]`"), 90420), /// Allows using `doc(primitive)` without a future-incompat warning. - (removed, doc_primitive, "1.56.0", Some(88070), - Some("merged into `#![feature(rustdoc_internals)]`")), + (removed, doc_primitive, "1.58.0", Some(88070), + Some("merged into `#![feature(rustdoc_internals)]`"), 90420), /// Allows `#[doc(spotlight)]`. /// The attribute was renamed to `#[doc(notable_trait)]` /// and the feature to `doc_notable_trait`. - (removed, doc_spotlight, "1.22.0", Some(45040), - Some("renamed to `doc_notable_trait`")), + (removed, doc_spotlight, "1.53.0", Some(45040), + Some("renamed to `doc_notable_trait`"), 80965), /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). (removed, dropck_parametricity, "1.38.0", Some(28498), None), /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible[^1]. @@ -120,161 +120,162 @@ declare_features! ( /// Renamed from `object_safe_for_dispatch`. /// /// [^1]: Formerly known as "object safe". - (removed, dyn_compatible_for_dispatch, "1.83.0", Some(43561), - Some("removed, not used heavily and represented additional complexity in dyn compatibility")), + (removed, dyn_compatible_for_dispatch, "1.87.0", Some(43561), + Some("removed, not used heavily and represented additional complexity in dyn compatibility"), 136522), /// Uses generic effect parameters for ~const bounds (removed, effects, "1.84.0", Some(102090), - Some("removed, redundant with `#![feature(const_trait_impl)]`")), + Some("removed, redundant with `#![feature(const_trait_impl)]`"), 132479), /// Allows defining `existential type`s. (removed, existential_type, "1.38.0", Some(63063), Some("removed in favor of `#![feature(type_alias_impl_trait)]`")), /// Paths of the form: `extern::foo::bar` (removed, extern_in_paths, "1.33.0", Some(55600), - Some("subsumed by `::foo::bar` paths")), + Some("subsumed by `::foo::bar` paths"), 57572), /// Allows `#[doc(include = "some-file")]`. (removed, external_doc, "1.54.0", Some(44732), Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations"), 85457), /// Allows using `#[ffi_returns_twice]` on foreign functions. (removed, ffi_returns_twice, "1.78.0", Some(58314), - Some("being investigated by the ffi-unwind project group")), + Some("being investigated by the ffi-unwind project group"), 120502), /// Allows generators to be cloned. - (removed, generator_clone, "1.65.0", Some(95360), Some("renamed to `coroutine_clone`")), + (removed, generator_clone, "1.75.0", Some(95360), Some("renamed to `coroutine_clone`"), 116958), /// Allows defining generators. - (removed, generators, "1.21.0", Some(43122), Some("renamed to `coroutines`")), + (removed, generators, "1.75.0", Some(43122), Some("renamed to `coroutines`"), 116958), /// An extension to the `generic_associated_types` feature, allowing incomplete features. (removed, generic_associated_types_extended, "1.85.0", Some(95451), Some( "feature needs overhaul and reimplementation pending \ better implied higher-ranked implied bounds support" - ) + ), + 133768 ), (removed, import_shadowing, "1.0.0", None, None), /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). - (removed, in_band_lifetimes, "1.23.0", Some(44524), - Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity")), + (removed, in_band_lifetimes, "1.61.0", Some(44524), + Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity"), 93845), /// Allows inferring `'static` outlives requirements (RFC 2093). (removed, infer_static_outlives_requirements, "1.63.0", Some(54185), - Some("removed as it caused some confusion and discussion was inactive for years")), + Some("removed as it caused some confusion and discussion was inactive for years"), 97875), /// Allow anonymous constants from an inline `const` block in pattern position (removed, inline_const_pat, "1.88.0", Some(76001), - Some("removed due to implementation concerns as it requires significant refactorings")), + Some("removed due to implementation concerns as it requires significant refactorings"), 138492), /// Lazily evaluate constants. This allows constants to depend on type parameters. - (removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")), + (removed, lazy_normalization_consts, "1.56.0", Some(72219), Some("superseded by `generic_const_exprs`"), 88369), /// Changes `impl Trait` to capture all lifetimes in scope. - (removed, lifetime_capture_rules_2024, "1.76.0", None, Some("unnecessary -- use edition 2024 instead")), + (removed, lifetime_capture_rules_2024, "1.87.0", None, Some("unnecessary -- use edition 2024 instead"), 136787), /// Allows using the `#[link_args]` attribute. (removed, link_args, "1.53.0", Some(29596), Some("removed in favor of using `-C link-arg=ARG` on command line, \ - which is available from cargo build scripts with `cargo:rustc-link-arg` now")), + which is available from cargo build scripts with `cargo:rustc-link-arg` now"), 83820), (removed, macro_reexport, "1.0.0", Some(29638), - Some("subsumed by `pub use`")), + Some("subsumed by `pub use`"), 49982), /// Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls. - (removed, main, "1.53.0", Some(29634), None), + (removed, main, "1.53.0", Some(29634), None, 84217), (removed, managed_boxes, "1.0.0", None, None), /// Allows the use of type alias impl trait in function return positions (removed, min_type_alias_impl_trait, "1.56.0", Some(63063), - Some("removed in favor of full type_alias_impl_trait")), + Some("removed in favor of full type_alias_impl_trait"), 87564), /// Make `mut` not reset the binding mode on edition >= 2024. - (removed, mut_preserve_binding_mode_2024, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`")), + (removed, mut_preserve_binding_mode_2024, "1.80.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`"), 125168), (removed, needs_allocator, "1.4.0", Some(27389), Some("subsumed by `#![feature(allocator_internals)]`")), /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8 (removed, negate_unsigned, "1.0.0", Some(29645), None), /// Allows `#[no_coverage]` on functions. /// The feature was renamed to `coverage_attribute` and the attribute to `#[coverage(on|off)]` - (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`")), + (removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656), /// Allows `#[no_debug]`. - (removed, no_debug, "1.43.0", Some(29721), Some("removed due to lack of demand")), + (removed, no_debug, "1.43.0", Some(29721), Some("removed due to lack of demand"), 69667), /// Note: this feature was previously recorded in a separate /// `STABLE_REMOVED` list because it, uniquely, was once stable but was /// then removed. But there was no utility storing it separately, so now /// it's in this list. - (removed, no_stack_check, "1.0.0", None, None), + (removed, no_stack_check, "1.0.0", None, None, 40110), /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn compatible (object safe). /// Renamed to `dyn_compatible_for_dispatch`. (removed, object_safe_for_dispatch, "1.83.0", Some(43561), - Some("renamed to `dyn_compatible_for_dispatch`")), + Some("renamed to `dyn_compatible_for_dispatch`"), 131511), /// Allows using `#[on_unimplemented(..)]` on traits. /// (Moved to `rustc_attrs`.) - (removed, on_unimplemented, "1.40.0", None, None), + (removed, on_unimplemented, "1.40.0", None, None, 65794), /// A way to temporarily opt out of opt-in copy. This will *never* be accepted. - (removed, opt_out_copy, "1.0.0", None, None), + (removed, opt_out_copy, "1.0.0", None, None, 20740), /// Allows features specific to OIBIT (now called auto traits). /// Renamed to `auto_traits`. - (removed, optin_builtin_traits, "1.0.0", Some(13231), - Some("renamed to `auto_traits`")), + (removed, optin_builtin_traits, "1.50.0", Some(13231), + Some("renamed to `auto_traits`"), 79336), /// Allows overlapping impls of marker traits. (removed, overlapping_marker_traits, "1.42.0", Some(29864), - Some("removed in favor of `#![feature(marker_trait_attr)]`")), + Some("removed in favor of `#![feature(marker_trait_attr)]`"), 68544), (removed, panic_implementation, "1.28.0", Some(44489), - Some("subsumed by `#[panic_handler]`")), + Some("subsumed by `#[panic_handler]`"), 53619), /// Allows `extern "platform-intrinsic" { ... }`. - (removed, platform_intrinsics, "1.4.0", Some(27731), - Some("SIMD intrinsics use the regular intrinsics ABI now")), + (removed, platform_intrinsics, "1.78.0", Some(27731), + Some("SIMD intrinsics use the regular intrinsics ABI now"), 121516), /// Allows using `#![plugin(myplugin)]`. (removed, plugin, "1.75.0", Some(29597), - Some("plugins are no longer supported")), + Some("plugins are no longer supported"), 116412), /// Allows using `#[plugin_registrar]` on functions. - (removed, plugin_registrar, "1.54.0", Some(29597), - Some("plugins are no longer supported")), + (removed, plugin_registrar, "1.75.0", Some(29597), + Some("plugins are no longer supported"), 116412), /// Allows exhaustive integer pattern matching with `usize::MAX`/`isize::MIN`/`isize::MAX`. - (removed, precise_pointer_size_matching, "1.32.0", Some(56354), - Some("removed in favor of half-open ranges")), + (removed, precise_pointer_size_matching, "1.76.0", Some(56354), + Some("removed in favor of half-open ranges"), 118598), (removed, pref_align_of, "CURRENT_RUSTC_VERSION", Some(91971), Some("removed due to marginal use and inducing compiler complications")), (removed, proc_macro_expr, "1.27.0", Some(54727), - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121), (removed, proc_macro_gen, "1.27.0", Some(54727), - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121), (removed, proc_macro_mod, "1.27.0", Some(54727), - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121), (removed, proc_macro_non_items, "1.27.0", Some(54727), - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + Some("subsumed by `#![feature(proc_macro_hygiene)]`"), 52121), (removed, pub_macro_rules, "1.53.0", Some(78855), Some("removed due to being incomplete, in particular it does not work across crates")), (removed, pushpop_unsafe, "1.2.0", None, None), (removed, quad_precision_float, "1.0.0", None, None), (removed, quote, "1.33.0", Some(29601), None), - (removed, ref_pat_everywhere, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024")), + (removed, ref_pat_everywhere, "1.80.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024"), 125168), (removed, reflect, "1.0.0", Some(27749), None), /// Allows using the `#[register_attr]` attribute. (removed, register_attr, "1.65.0", Some(66080), - Some("removed in favor of `#![register_tool]`")), + Some("removed in favor of `#![register_tool]`"), 66070), (removed, rust_2018_preview, "1.76.0", None, Some("2018 Edition preview is no longer relevant")), /// Allows using the macros: /// + `__diagnostic_used` /// + `__register_diagnostic` /// +`__build_diagnostic_array` - (removed, rustc_diagnostic_macros, "1.38.0", None, None), + (removed, rustc_diagnostic_macros, "1.38.0", None, None, 64139), /// Allows identifying crates that contain sanitizer runtimes. - (removed, sanitizer_runtime, "1.17.0", None, None), + (removed, sanitizer_runtime, "1.17.0", None, None, 65241), (removed, simd, "1.0.0", Some(27731), Some("removed in favor of `#[repr(simd)]`")), /// Allows using `#[start]` on a function indicating that it is the program entrypoint. - (removed, start, "1.0.0", Some(29633), Some("not portable enough and never RFC'd")), + (removed, start, "1.86.0", Some(29633), Some("not portable enough and never RFC'd"), 134299), /// Allows `#[link(kind = "static-nobundle", ...)]`. - (removed, static_nobundle, "1.16.0", Some(37403), - Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#)), + (removed, static_nobundle, "1.63.0", Some(37403), + Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#), 95818), (removed, struct_inherit, "1.0.0", None, None), (removed, test_removed_feature, "1.0.0", None, None), /// Allows using items which are missing stability attributes (removed, unmarked_api, "1.0.0", None, None), /// Allows unnamed fields of struct and union type - (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")), + (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign"), 131045), (removed, unsafe_no_drop_flag, "1.0.0", None, None), (removed, unsized_tuple_coercion, "1.87.0", Some(42877), - Some("The feature restricts possible layouts for tuples, and this restriction is not worth it.")), + Some("The feature restricts possible layouts for tuples, and this restriction is not worth it."), 137728), /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue. - (removed, untagged_unions, "1.13.0", Some(55149), - Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more")), + (removed, untagged_unions, "1.64.0", Some(55149), + Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more"), 97995), /// Allows `#[unwind(..)]`. /// /// Permits specifying whether a function should permit unwinding or abort on unwind. - (removed, unwind_attributes, "1.56.0", Some(58760), Some("use the C-unwind ABI instead")), + (removed, unwind_attributes, "1.56.0", Some(58760), Some("use the C-unwind ABI instead"), 86155), (removed, visible_private_types, "1.0.0", None, None), /// Allows `extern "wasm" fn` (removed, wasm_abi, "1.81.0", Some(83788), - Some("non-standard wasm ABI is no longer supported")), + Some("non-standard wasm ABI is no longer supported"), 127605), // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way. // !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! !!!! diff --git a/tests/ui/deprecation/deprecated_no_stack_check.stderr b/tests/ui/deprecation/deprecated_no_stack_check.stderr index be15d6bea074..2d08b1b8db54 100644 --- a/tests/ui/deprecation/deprecated_no_stack_check.stderr +++ b/tests/ui/deprecation/deprecated_no_stack_check.stderr @@ -4,7 +4,7 @@ error[E0557]: feature has been removed LL | #![feature(no_stack_check)] | ^^^^^^^^^^^^^^ feature has been removed | - = note: removed in 1.0.0 (you are using $RUSTC_VERSION) + = note: removed in 1.0.0 (you are using $RUSTC_VERSION); see for more information error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr index d8196242b544..8c23544698d0 100644 --- a/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-coverage-attribute.stderr @@ -4,7 +4,7 @@ error[E0557]: feature has been removed LL | #![feature(no_coverage)] | ^^^^^^^^^^^ feature has been removed | - = note: removed in 1.74.0 (you are using $RUSTC_VERSION) + = note: removed in 1.74.0 (you are using $RUSTC_VERSION); see for more information = note: renamed to `coverage_attribute` error[E0658]: the `#[coverage]` attribute is an experimental feature diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index 3c6f011e39b9..d4940eeb7755 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -4,7 +4,7 @@ error[E0557]: feature has been removed LL | #![feature(macro_reexport)] | ^^^^^^^^^^^^^^ feature has been removed | - = note: removed in 1.0.0 (you are using $RUSTC_VERSION) + = note: removed in 1.0.0 (you are using $RUSTC_VERSION); see for more information = note: subsumed by `pub use` error: cannot find attribute `macro_reexport` in this scope diff --git a/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr b/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr index d55825c8d794..9c664da8ee6c 100644 --- a/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr +++ b/tests/ui/rustdoc/renamed-features-rustdoc_internals.stderr @@ -4,7 +4,7 @@ error[E0557]: feature has been removed LL | #![feature(doc_keyword)] | ^^^^^^^^^^^ feature has been removed | - = note: removed in 1.28.0 (you are using $RUSTC_VERSION) + = note: removed in 1.58.0 (you are using $RUSTC_VERSION); see for more information = note: merged into `#![feature(rustdoc_internals)]` error[E0557]: feature has been removed @@ -13,7 +13,7 @@ error[E0557]: feature has been removed LL | #![feature(doc_primitive)] | ^^^^^^^^^^^^^ feature has been removed | - = note: removed in 1.56.0 (you are using $RUSTC_VERSION) + = note: removed in 1.58.0 (you are using $RUSTC_VERSION); see for more information = note: merged into `#![feature(rustdoc_internals)]` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr index 70d0a4758205..a04f98e68a63 100644 --- a/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr +++ b/tests/ui/traits/const-traits/const-trait-impl-parameter-mismatch.stderr @@ -4,7 +4,7 @@ error[E0557]: feature has been removed LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ feature has been removed | - = note: removed in 1.84.0 (you are using $RUSTC_VERSION) + = note: removed in 1.84.0 (you are using $RUSTC_VERSION); see for more information = note: removed, redundant with `#![feature(const_trait_impl)]` error[E0049]: associated function `compute` has 0 type parameters but its trait declaration has 1 type parameter From c3de813944873940b8e1a7734991f3c9f3f55156 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 9 Jun 2025 12:47:05 +0300 Subject: [PATCH 111/183] add `Cargo.lock` to CI-rustc allowed list for non-CI env Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 51 ++++++++++++++++--------- src/bootstrap/src/core/config/tests.rs | 4 +- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a92d58ef9e87..824b159c3263 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -50,26 +50,39 @@ use crate::utils::channel; use crate::utils::helpers::exe; use crate::{Command, GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, output, t}; -/// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic. +/// Each path from this function is considered "allowed" in the `download-rustc="if-unchanged"` logic. /// This means they can be modified and changes to these paths should never trigger a compiler build /// when "if-unchanged" is set. -/// -/// NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during -/// the diff check. -/// -/// WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build -/// is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results. -/// For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the -/// final output/compiler, which can be significantly affected by changes made to the bootstrap sources. -#[rustfmt::skip] // We don't want rustfmt to oneline this list -pub const RUSTC_IF_UNCHANGED_ALLOWED_PATHS: &[&str] = &[ - ":!library", - ":!src/tools", - ":!src/librustdoc", - ":!src/rustdoc-json-types", - ":!tests", - ":!triagebot.toml", -]; +pub fn rustc_if_unchanged_allowed_paths() -> Vec<&'static str> { + // NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during + // the diff check. + // + // WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build + // is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results. + // For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the + // final output/compiler, which can be significantly affected by changes made to the bootstrap sources. + let mut paths = vec![ + ":!library", + ":!src/tools", + ":!src/librustdoc", + ":!src/rustdoc-json-types", + ":!tests", + ":!triagebot.toml", + ]; + + if !CiEnv::is_ci() { + // When a dependency is added/updated/removed in the library tree (or in some tools), + // `Cargo.lock` will be updated by `cargo`. This update will incorrectly invalidate the + // `download-rustc=if-unchanged` cache. + // + // To prevent this, add `Cargo.lock` to the list of allowed paths when not running on CI. + // This is generally safe because changes to dependencies typically involve modifying + // `Cargo.toml`, which would already invalidate the CI-rustc cache on non-allowed paths. + paths.push(":!Cargo.lock"); + } + + paths +} /// Global configuration for the entire build and/or bootstrap. /// @@ -1503,7 +1516,7 @@ impl Config { let commit = if self.rust_info.is_managed_git_subrepository() { // Look for a version to compare to based on the current commit. // Only commits merged by bors will have CI artifacts. - let freshness = self.check_path_modifications(RUSTC_IF_UNCHANGED_ALLOWED_PATHS); + let freshness = self.check_path_modifications(&rustc_if_unchanged_allowed_paths()); self.verbose(|| { eprintln!("rustc freshness: {freshness:?}"); }); diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 50eba12aba74..e660addfb2cc 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -11,7 +11,7 @@ use serde::Deserialize; use super::flags::Flags; use super::toml::change_id::ChangeIdWrapper; -use super::{Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS}; +use super::{Config, rustc_if_unchanged_allowed_paths}; use crate::ChangeId; use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order}; use crate::core::build_steps::llvm; @@ -459,7 +459,7 @@ fn jobs_precedence() { #[test] fn check_rustc_if_unchanged_paths() { let config = parse(""); - let normalised_allowed_paths: Vec<_> = RUSTC_IF_UNCHANGED_ALLOWED_PATHS + let normalised_allowed_paths: Vec<_> = rustc_if_unchanged_allowed_paths() .iter() .map(|t| { t.strip_prefix(":!").expect(&format!("{t} doesn't have ':!' prefix, but it should.")) From 3164ca8bb4ad6af6114926a4160edd95bbb18872 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Jun 2025 12:36:24 +0200 Subject: [PATCH 112/183] stabilize nonnull_provenance --- library/alloc/src/lib.rs | 1 - library/alloctests/lib.rs | 1 - library/core/src/ptr/non_null.rs | 7 ++++--- library/std/src/lib.rs | 1 - 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 30540f48aa10..f416732a8d63 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -131,7 +131,6 @@ #![feature(local_waker)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array_transpose)] -#![feature(nonnull_provenance)] #![feature(panic_internals)] #![feature(pattern)] #![feature(pin_coerce_unsized_trait)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 56e60ed4c844..3241b4b00454 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -28,7 +28,6 @@ #![feature(iter_next_chunk)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array_transpose)] -#![feature(nonnull_provenance)] #![feature(ptr_alignment_type)] #![feature(ptr_internals)] #![feature(sized_type_properties)] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 91b8d1bf9a70..1fae5b839024 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -89,7 +89,8 @@ impl NonNull { /// For more details, see the equivalent method on a raw pointer, [`ptr::without_provenance_mut`]. /// /// This is a [Strict Provenance][crate::ptr#strict-provenance] API. - #[unstable(feature = "nonnull_provenance", issue = "135243")] + #[stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] pub const fn without_provenance(addr: NonZero) -> Self { @@ -132,7 +133,7 @@ impl NonNull { /// For more details, see the equivalent method on a raw pointer, [`ptr::with_exposed_provenance_mut`]. /// /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. - #[unstable(feature = "nonnull_provenance", issue = "135243")] + #[stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn with_exposed_provenance(addr: NonZero) -> Self { // SAFETY: we know `addr` is non-zero. @@ -329,7 +330,7 @@ impl NonNull { /// For more details, see the equivalent method on a raw pointer, [`pointer::expose_provenance`]. /// /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API. - #[unstable(feature = "nonnull_provenance", issue = "135243")] + #[stable(feature = "nonnull_provenance", since = "CURRENT_RUSTC_VERSION")] pub fn expose_provenance(self) -> NonZero { // SAFETY: The pointer is guaranteed by the type to be non-null, // meaning that the address will be non-zero. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 7c54e731edc6..2bb7a63772d6 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -351,7 +351,6 @@ #![feature(lazy_get)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_write_slice)] -#![feature(nonnull_provenance)] #![feature(panic_can_unwind)] #![feature(panic_internals)] #![feature(pin_coerce_unsized_trait)] From ee8853b21f31d2f274aa982a8ac037ed58f6a6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 9 Jun 2025 13:54:20 +0200 Subject: [PATCH 113/183] Disable download-rustc on CI --- src/ci/run.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index b6143af632dd..e0c00dc1925d 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -186,9 +186,11 @@ else # Download GCC from CI on test builders RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set gcc.download-ci-gcc=true" - if [ "$NO_DOWNLOAD_CI_RUSTC" = "" ]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.download-rustc=if-unchanged" - fi + # download-rustc seems to be broken on CI after the stage0 redesign + # Disable it until these issues are debugged and resolved +# if [ "$NO_DOWNLOAD_CI_RUSTC" = "" ]; then +# RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.download-rustc=if-unchanged" +# fi fi if [ "$ENABLE_GCC_CODEGEN" = "1" ]; then From cbe6fe86ef60ceedd46128df8f09da982f44191a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 9 Jun 2025 15:44:03 +0300 Subject: [PATCH 114/183] Preparing for merge from rust-lang/rust --- src/tools/rust-analyzer/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 5b47d1bbaed7..af0dd5c9acda 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -a8e4c68dcb4dc1e48a0db294c5323cab0227fcb9 +7c10378e1fee5ddc6573b916aeb884ab10e0de17 From 33beaba7c8b78e9d4908e98dd1d6b4e15c6ba6f8 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 8 Jun 2025 20:36:47 +0200 Subject: [PATCH 115/183] Always consider `const _` items as live for dead code analysis --- compiler/rustc_passes/src/dead.rs | 13 ++++++++++++- .../dead-code/const-underscore-issue-142104.rs | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lint/dead-code/const-underscore-issue-142104.rs diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 6b82252f32c2..e597c819a3aa 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::DEAD_CODE; use rustc_session::lint::{self, LintExpectationId}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Symbol, kw, sym}; use crate::errors::{ ChangeFields, IgnoredDerivedImpls, MultipleDeadCodes, ParentInfo, UselessAssignment, @@ -793,6 +793,17 @@ fn check_item<'tcx>( // global_asm! is always live. worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); } + DefKind::Const => { + let item = tcx.hir_item(id); + if let hir::ItemKind::Const(ident, ..) = item.kind + && ident.name == kw::Underscore + { + // `const _` is always live, as that syntax only exists for the side effects + // of type checking and evaluating the constant expression, and marking them + // as dead code would defeat that purpose. + worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); + } + } _ => {} } } diff --git a/tests/ui/lint/dead-code/const-underscore-issue-142104.rs b/tests/ui/lint/dead-code/const-underscore-issue-142104.rs new file mode 100644 index 000000000000..b255027e0f1c --- /dev/null +++ b/tests/ui/lint/dead-code/const-underscore-issue-142104.rs @@ -0,0 +1,15 @@ +//@ check-pass + +// This test makes sure we always considers `const _` items as live for dead code analysis. + +#![deny(dead_code)] + +const fn is_nonzero(x: u8) -> bool { + x != 0 +} + +const _: () = { + assert!(is_nonzero(2)); +}; + +fn main() {} From 9b0ad97287c877c992ff15307adcb20c3583cbfb Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 9 Jun 2025 19:28:11 +0800 Subject: [PATCH 116/183] deduplicate the rest of AST walker functions --- compiler/rustc_ast/src/mut_visit.rs | 616 +------------ compiler/rustc_ast/src/visit.rs | 1219 ++++++++++++++------------ tests/crashes/139825.rs | 5 - tests/ui/check-cfg/hrtb-crash.rs | 7 + tests/ui/check-cfg/hrtb-crash.stderr | 13 + 5 files changed, 688 insertions(+), 1172 deletions(-) delete mode 100644 tests/crashes/139825.rs create mode 100644 tests/ui/check-cfg/hrtb-crash.rs create mode 100644 tests/ui/check-cfg/hrtb-crash.stderr diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 77cbdde61a42..71a47dcfcba2 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -11,7 +11,7 @@ use std::ops::DerefMut; use std::panic; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; -use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span}; use smallvec::{Array, SmallVec, smallvec}; use thin_vec::ThinVec; @@ -19,7 +19,7 @@ use thin_vec::ThinVec; use crate::ast::*; use crate::ptr::P; use crate::tokenstream::*; -use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit, visit_opt, walk_list}; +use crate::visit::{AssocCtxt, BoundKind, FnCtxt, VisitorResult, try_visit, visit_opt, walk_list}; pub trait ExpectOne { fn expect_one(self, err: &'static str) -> A::Item; @@ -32,7 +32,22 @@ impl ExpectOne for SmallVec { } } -pub trait MutVisitor: Sized { +mod sealed { + use rustc_ast_ir::visit::VisitorResult; + + /// This is for compatibility with the regular `Visitor`. + pub trait MutVisitorResult { + type Result: VisitorResult; + } + + impl MutVisitorResult for T { + type Result = (); + } +} + +use sealed::MutVisitorResult; + +pub trait MutVisitor: Sized + MutVisitorResult { // Methods in this trait have one of three forms: // // fn visit_t(&mut self, t: &mut T); // common @@ -227,14 +242,6 @@ pub trait MutVisitor: Sized { walk_generic_args(self, p); } - fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { - walk_angle_bracketed_parameter_data(self, p); - } - - fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { - walk_parenthesized_parameter_data(self, p); - } - fn visit_local(&mut self, l: &mut Local) { walk_local(self, l); } @@ -303,10 +310,6 @@ pub trait MutVisitor: Sized { walk_flat_map_expr_field(self, f) } - fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { - walk_where_clause(self, where_clause); - } - fn flat_map_where_predicate( &mut self, where_predicate: WherePredicate, @@ -385,19 +388,14 @@ generate_flat_map_visitor_fns! { visit_generic_params, GenericParam, flat_map_generic_param; visit_stmts, Stmt, flat_map_stmt; visit_exprs, P, filter_map_expr; + visit_expr_fields, ExprField, flat_map_expr_field; visit_pat_fields, PatField, flat_map_pat_field; visit_variants, Variant, flat_map_variant; visit_assoc_items, P, flat_map_assoc_item, ctxt: AssocCtxt; -} - -#[inline] -fn visit_vec(elems: &mut Vec, mut visit_elem: F) -where - F: FnMut(&mut T), -{ - for elem in elems { - visit_elem(elem); - } + visit_where_predicates, WherePredicate, flat_map_where_predicate; + visit_params, Param, flat_map_param; + visit_field_defs, FieldDef, flat_map_field_def; + visit_arms, Arm, flat_map_arm; } #[inline] @@ -410,40 +408,12 @@ where } } -#[inline] -fn visit_opt(opt: &mut Option, mut visit_elem: F) -where - F: FnMut(&mut T), -{ - if let Some(elem) = opt { - visit_elem(elem); - } -} - fn visit_attrs(vis: &mut T, attrs: &mut AttrVec) { for attr in attrs.iter_mut() { vis.visit_attribute(attr); } } -fn visit_attr_args(vis: &mut T, args: &mut AttrArgs) { - match args { - AttrArgs::Empty => {} - AttrArgs::Delimited(args) => visit_delim_args(vis, args), - AttrArgs::Eq { eq_span, expr } => { - vis.visit_expr(expr); - vis.visit_span(eq_span); - } - } -} - -fn visit_delim_args(vis: &mut T, args: &mut DelimArgs) { - let DelimArgs { dspan, delim: _, tokens: _ } = args; - let DelimSpan { open, close } = dspan; - vis.visit_span(open); - vis.visit_span(close); -} - pub fn walk_flat_map_pat_field( vis: &mut T, mut fp: PatField, @@ -461,40 +431,11 @@ fn visit_nested_use_tree( vis.visit_use_tree(nested_tree); } -pub fn walk_arm(vis: &mut T, arm: &mut Arm) { - let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - visit_opt(guard, |guard| vis.visit_expr(guard)); - visit_opt(body, |body| vis.visit_expr(body)); - vis.visit_span(span); -} - pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { vis.visit_arm(&mut arm); smallvec![arm] } -fn walk_assoc_item_constraint( - vis: &mut T, - AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint, -) { - vis.visit_id(id); - vis.visit_ident(ident); - if let Some(gen_args) = gen_args { - vis.visit_generic_args(gen_args); - } - match kind { - AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => vis.visit_ty(ty), - Term::Const(c) => vis.visit_anon_const(c), - }, - AssocItemConstraintKind::Bound { bounds } => visit_bounds(vis, bounds, BoundKind::Bound), - } - vis.visit_span(span); -} - pub fn walk_flat_map_variant( vis: &mut T, mut variant: Variant, @@ -503,64 +444,6 @@ pub fn walk_flat_map_variant( smallvec![variant] } -fn walk_generic_args(vis: &mut T, generic_args: &mut GenericArgs) { - match generic_args { - GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), - GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), - GenericArgs::ParenthesizedElided(span) => vis.visit_span(span), - } -} - -fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { - match arg { - GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), - GenericArg::Type(ty) => vis.visit_ty(ty), - GenericArg::Const(ct) => vis.visit_anon_const(ct), - } -} - -fn walk_angle_bracketed_parameter_data(vis: &mut T, data: &mut AngleBracketedArgs) { - let AngleBracketedArgs { args, span } = data; - visit_thin_vec(args, |arg| match arg { - AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), - AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint), - }); - vis.visit_span(span); -} - -fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut ParenthesizedArgs) { - let ParenthesizedArgs { inputs, output, span, inputs_span } = args; - visit_thin_vec(inputs, |input| vis.visit_ty(input)); - vis.visit_fn_ret_ty(output); - vis.visit_span(span); - vis.visit_span(inputs_span); -} - -fn walk_attribute(vis: &mut T, attr: &mut Attribute) { - let Attribute { kind, id: _, style: _, span } = attr; - match kind { - AttrKind::Normal(normal) => { - let NormalAttr { item: AttrItem { unsafety: _, path, args, tokens: _ }, tokens: _ } = - &mut **normal; - vis.visit_path(path); - visit_attr_args(vis, args); - } - AttrKind::DocComment(_kind, _sym) => {} - } - vis.visit_span(span); -} - -fn walk_mac(vis: &mut T, mac: &mut MacCall) { - let MacCall { path, args } = mac; - vis.visit_path(path); - visit_delim_args(vis, args); -} - -fn walk_macro_def(vis: &mut T, macro_def: &mut MacroDef) { - let MacroDef { body, macro_rules: _ } = macro_def; - visit_delim_args(vis, body); -} - fn walk_meta_list_item(vis: &mut T, li: &mut MetaItemInner) { match li { MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi), @@ -578,138 +461,11 @@ fn walk_meta_item(vis: &mut T, mi: &mut MetaItem) { vis.visit_span(span); } -pub fn walk_param(vis: &mut T, param: &mut Param) { - let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - vis.visit_ty(ty); - vis.visit_span(span); -} - pub fn walk_flat_map_param(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> { vis.visit_param(&mut param); smallvec![param] } -fn walk_closure_binder(vis: &mut T, binder: &mut ClosureBinder) { - match binder { - ClosureBinder::NotPresent => {} - ClosureBinder::For { span: _, generic_params } => { - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - } - } -} - -fn walk_fn(vis: &mut T, kind: FnKind<'_>) { - match kind { - FnKind::Fn( - _ctxt, - _vis, - Fn { - defaultness, - ident, - generics, - contract, - body, - sig: FnSig { header, decl, span }, - define_opaque, - }, - ) => { - // Visibility is visited as a part of the item. - visit_defaultness(vis, defaultness); - vis.visit_ident(ident); - vis.visit_fn_header(header); - vis.visit_generics(generics); - vis.visit_fn_decl(decl); - if let Some(contract) = contract { - vis.visit_contract(contract); - } - if let Some(body) = body { - vis.visit_block(body); - } - vis.visit_span(span); - - walk_define_opaques(vis, define_opaque); - } - FnKind::Closure(binder, coroutine_kind, decl, body) => { - vis.visit_closure_binder(binder); - coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); - vis.visit_fn_decl(decl); - vis.visit_expr(body); - } - } -} - -fn walk_contract(vis: &mut T, contract: &mut FnContract) { - let FnContract { requires, ensures } = contract; - if let Some(pred) = requires { - vis.visit_expr(pred); - } - if let Some(pred) = ensures { - vis.visit_expr(pred); - } -} - -fn walk_fn_decl(vis: &mut T, decl: &mut FnDecl) { - let FnDecl { inputs, output } = decl; - inputs.flat_map_in_place(|param| vis.flat_map_param(param)); - vis.visit_fn_ret_ty(output); -} - -fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { - match fn_ret_ty { - FnRetTy::Default(span) => vis.visit_span(span), - FnRetTy::Ty(ty) => vis.visit_ty(ty), - } -} - -fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { - match pb { - GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref), - GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), - GenericBound::Use(args, span) => { - for arg in args { - vis.visit_precise_capturing_arg(arg); - } - vis.visit_span(span); - } - } -} - -fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCapturingArg) { - match arg { - PreciseCapturingArg::Lifetime(lt) => { - vis.visit_lifetime(lt); - } - PreciseCapturingArg::Arg(path, id) => { - vis.visit_id(id); - vis.visit_path(path); - } - } -} - -pub fn walk_generic_param(vis: &mut T, param: &mut GenericParam) { - let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - match kind { - GenericParamKind::Lifetime => {} - GenericParamKind::Type { default } => { - visit_opt(default, |default| vis.visit_ty(default)); - } - GenericParamKind::Const { ty, kw_span: _, default } => { - vis.visit_ty(ty); - visit_opt(default, |default| vis.visit_anon_const(default)); - } - } - if let Some(colon_span) = colon_span { - vis.visit_span(colon_span); - } -} - pub fn walk_flat_map_generic_param( vis: &mut T, mut param: GenericParam, @@ -718,13 +474,6 @@ pub fn walk_flat_map_generic_param( smallvec![param] } -fn walk_generics(vis: &mut T, generics: &mut Generics) { - let Generics { params, where_clause, span } = generics; - params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_where_clause(where_clause); - vis.visit_span(span); -} - fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWhereClauses) { let TyAliasWhereClauses { before, after, split: _ } = tawcs; let TyAliasWhereClause { has_where_token: _, span: span_before } = before; @@ -733,70 +482,14 @@ fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWh vis.visit_span(span_after); } -fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { - let WhereClause { has_where_token: _, predicates, span } = wc; - predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate)); - vis.visit_span(span); -} - pub fn walk_flat_map_where_predicate( vis: &mut T, mut pred: WherePredicate, ) -> SmallVec<[WherePredicate; 1]> { - let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_where_predicate_kind(kind); - vis.visit_span(span); + walk_where_predicate(vis, &mut pred); smallvec![pred] } -pub fn walk_where_predicate_kind(vis: &mut T, kind: &mut WherePredicateKind) { - match kind { - WherePredicateKind::BoundPredicate(bp) => { - let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp; - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_ty(bounded_ty); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - } - WherePredicateKind::RegionPredicate(rp) => { - let WhereRegionPredicate { lifetime, bounds } = rp; - vis.visit_lifetime(lifetime); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - } - WherePredicateKind::EqPredicate(ep) => { - let WhereEqPredicate { lhs_ty, rhs_ty } = ep; - vis.visit_ty(lhs_ty); - vis.visit_ty(rhs_ty); - } - } -} - -fn walk_variant_data(vis: &mut T, vdata: &mut VariantData) { - match vdata { - VariantData::Struct { fields, recovered: _ } => { - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } - VariantData::Tuple(fields, id) => { - vis.visit_id(id); - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } - VariantData::Unit(id) => vis.visit_id(id), - } -} - -pub fn walk_field_def(visitor: &mut T, fd: &mut FieldDef) { - let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd; - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visit_safety(visitor, safety); - visit_opt(ident, |ident| visitor.visit_ident(ident)); - visitor.visit_ty(ty); - visit_opt(default, |default| visitor.visit_anon_const(default)); - visitor.visit_span(span); -} - pub fn walk_flat_map_field_def( vis: &mut T, mut fd: FieldDef, @@ -846,255 +539,6 @@ pub fn walk_flat_map_assoc_item( smallvec![item] } -fn walk_inline_asm(vis: &mut T, asm: &mut InlineAsm) { - // FIXME: Visit spans inside all this currently ignored stuff. - let InlineAsm { - asm_macro: _, - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; - for (op, span) in operands { - match op { - InlineAsmOperand::In { expr, reg: _ } - | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } - | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr), - InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} - InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { - vis.visit_expr(in_expr); - if let Some(out_expr) = out_expr { - vis.visit_expr(out_expr); - } - } - InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const), - InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym), - InlineAsmOperand::Label { block } => vis.visit_block(block), - } - vis.visit_span(span); - } -} - -fn walk_inline_asm_sym( - vis: &mut T, - InlineAsmSym { id, qself, path }: &mut InlineAsmSym, -) { - vis.visit_id(id); - vis.visit_qself(qself); - vis.visit_path(path); -} - -fn walk_format_args(vis: &mut T, fmt: &mut FormatArgs) { - // FIXME: visit the template exhaustively. - let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt; - for FormatArgument { kind, expr } in arguments.all_args_mut() { - match kind { - FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - vis.visit_ident(ident) - } - FormatArgumentKind::Normal => {} - } - vis.visit_expr(expr); - } - vis.visit_span(span); -} - -pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, tokens: _ }: &mut Expr) { - vis.visit_id(id); - visit_attrs(vis, attrs); - match kind { - ExprKind::Array(exprs) => visit_exprs(vis, exprs), - ExprKind::ConstBlock(anon_const) => { - vis.visit_anon_const(anon_const); - } - ExprKind::Repeat(expr, count) => { - vis.visit_expr(expr); - vis.visit_anon_const(count); - } - ExprKind::Tup(exprs) => visit_exprs(vis, exprs), - ExprKind::Call(f, args) => { - vis.visit_expr(f); - visit_exprs(vis, args); - } - ExprKind::MethodCall(box MethodCall { - seg: PathSegment { ident, id, args: seg_args }, - receiver, - args: call_args, - span, - }) => { - vis.visit_method_receiver_expr(receiver); - vis.visit_id(id); - vis.visit_ident(ident); - visit_opt(seg_args, |args| vis.visit_generic_args(args)); - visit_exprs(vis, call_args); - vis.visit_span(span); - } - ExprKind::Binary(binop, lhs, rhs) => { - vis.visit_expr(lhs); - vis.visit_expr(rhs); - vis.visit_span(&mut binop.span); - } - ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), - ExprKind::Cast(expr, ty) => { - vis.visit_expr(expr); - vis.visit_ty(ty); - } - ExprKind::Type(expr, ty) => { - vis.visit_expr(expr); - vis.visit_ty(ty); - } - ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs), - ExprKind::Let(pat, scrutinee, span, _recovered) => { - vis.visit_pat(pat); - vis.visit_expr(scrutinee); - vis.visit_span(span); - } - ExprKind::If(cond, tr, fl) => { - vis.visit_expr(cond); - vis.visit_block(tr); - visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl))); - } - ExprKind::While(cond, body, label) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_expr(cond); - vis.visit_block(body); - } - ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_pat(pat); - vis.visit_expr(iter); - vis.visit_block(body); - } - ExprKind::Loop(body, label, span) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_block(body); - vis.visit_span(span); - } - ExprKind::Match(expr, arms, _kind) => { - vis.visit_expr(expr); - arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); - } - ExprKind::Closure(box Closure { - binder, - capture_clause, - constness, - coroutine_kind, - movability: _, - fn_decl, - body, - fn_decl_span, - fn_arg_span, - }) => { - visit_constness(vis, constness); - vis.visit_capture_by(capture_clause); - vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id); - vis.visit_span(fn_decl_span); - vis.visit_span(fn_arg_span); - } - ExprKind::Block(blk, label) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_block(blk); - } - ExprKind::Gen(_capture_by, body, _kind, decl_span) => { - vis.visit_block(body); - vis.visit_span(decl_span); - } - ExprKind::Await(expr, await_kw_span) => { - vis.visit_expr(expr); - vis.visit_span(await_kw_span); - } - ExprKind::Use(expr, use_kw_span) => { - vis.visit_expr(expr); - vis.visit_span(use_kw_span); - } - ExprKind::Assign(el, er, span) => { - vis.visit_expr(el); - vis.visit_expr(er); - vis.visit_span(span); - } - ExprKind::AssignOp(_op, el, er) => { - vis.visit_expr(el); - vis.visit_expr(er); - } - ExprKind::Field(el, ident) => { - vis.visit_expr(el); - vis.visit_ident(ident); - } - ExprKind::Index(el, er, brackets_span) => { - vis.visit_expr(el); - vis.visit_expr(er); - vis.visit_span(brackets_span); - } - ExprKind::Range(e1, e2, _lim) => { - visit_opt(e1, |e1| vis.visit_expr(e1)); - visit_opt(e2, |e2| vis.visit_expr(e2)); - } - ExprKind::Underscore => {} - ExprKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path); - } - ExprKind::Break(label, expr) => { - visit_opt(label, |label| vis.visit_label(label)); - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Continue(label) => { - visit_opt(label, |label| vis.visit_label(label)); - } - ExprKind::Ret(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Yeet(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Become(expr) => vis.visit_expr(expr), - ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), - ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), - ExprKind::OffsetOf(container, fields) => { - vis.visit_ty(container); - for field in fields.iter_mut() { - vis.visit_ident(field); - } - } - ExprKind::MacCall(mac) => vis.visit_mac_call(mac), - ExprKind::Struct(se) => { - let StructExpr { qself, path, fields, rest } = se.deref_mut(); - vis.visit_qself(qself); - vis.visit_path(path); - fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); - match rest { - StructRest::Base(expr) => vis.visit_expr(expr), - StructRest::Rest(_span) => {} - StructRest::None => {} - } - } - ExprKind::Paren(expr) => { - vis.visit_expr(expr); - } - ExprKind::Yield(kind) => { - let expr = kind.expr_mut(); - if let Some(expr) = expr { - vis.visit_expr(expr); - } - } - ExprKind::Try(expr) => vis.visit_expr(expr), - ExprKind::TryBlock(body) => vis.visit_block(body), - ExprKind::Lit(_token) => {} - ExprKind::IncludedBytes(_bytes) => {} - ExprKind::UnsafeBinderCast(_kind, expr, ty) => { - vis.visit_expr(expr); - if let Some(ty) = ty { - vis.visit_ty(ty); - } - } - ExprKind::Err(_guar) => {} - ExprKind::Dummy => {} - } - vis.visit_span(span); -} - pub fn walk_filter_map_expr(vis: &mut T, mut e: P) -> Option> { vis.visit_expr(&mut e); Some(e) @@ -1139,18 +583,6 @@ fn walk_flat_map_stmt_kind(vis: &mut T, kind: StmtKind) -> SmallV } } -fn walk_vis(vis: &mut T, visibility: &mut Visibility) { - let Visibility { kind, span, tokens: _ } = visibility; - match kind { - VisibilityKind::Public | VisibilityKind::Inherited => {} - VisibilityKind::Restricted { path, id, shorthand: _ } => { - vis.visit_id(id); - vis.visit_path(path); - } - } - vis.visit_span(span); -} - fn walk_capture_by(vis: &mut T, capture_by: &mut CaptureBy) { match capture_by { CaptureBy::Ref => {} diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d2f22b04a671..c88aa5c33ea9 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -15,11 +15,13 @@ pub use rustc_ast_ir::visit::VisitorResult; pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; +use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span}; use thin_vec::ThinVec; use crate::ast::*; use crate::ptr::P; +use crate::tokenstream::DelimSpan; #[derive(Copy, Clone, Debug, PartialEq)] pub enum AssocCtxt { @@ -237,8 +239,8 @@ pub trait Visitor<'ast>: Sized { fn visit_id(&mut self, _id: NodeId) -> Self::Result { Self::Result::output() } - fn visit_macro_def(&mut self, _mac: &'ast MacroDef) -> Self::Result { - Self::Result::output() + fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) -> Self::Result { + walk_macro_def(self, macro_def) } fn visit_path(&mut self, path: &'ast Path) -> Self::Result { walk_path(self, path) @@ -320,8 +322,8 @@ macro_rules! common_visitor_and_walkers { id: NodeId, visibility: &$($lt)? $($mut)? Visibility, ctxt: Self::Ctxt, - visitor: &mut V, - ) $(-> >::Result)?; + vis: &mut V, + ) -> V::Result; } // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier @@ -329,12 +331,12 @@ macro_rules! common_visitor_and_walkers { #[expect(unused, rustc::pass_by_value)] #[inline] )? - fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, span: &$($lt)? $($mut)? Span) $(-> >::Result)? { + fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result { $( ${ignore($mut)} - visitor.visit_span(span); + vis.visit_span(span); )? - $(${ignore($lt)}V::Result::output())? + V::Result::output() } /// helper since `Visitor` wants `NodeId` but `MutVisitor` wants `&mut NodeId` @@ -342,34 +344,34 @@ macro_rules! common_visitor_and_walkers { #[expect(rustc::pass_by_value)] )? #[inline] - fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> >::Result)? { + fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, id: &$($lt)? $($mut)? NodeId) -> V::Result { // deref `&NodeId` into `NodeId` only for `Visitor` - visitor.visit_id( $(${ignore($lt)} * )? id) + vis.visit_id( $(${ignore($lt)} * )? id) } // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier - fn visit_safety<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, safety: &$($lt)? $($mut)? Safety) $(-> >::Result)? { + fn visit_safety<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, safety: &$($lt)? $($mut)? Safety) -> V::Result { match safety { Safety::Unsafe(span) => visit_span(vis, span), Safety::Safe(span) => visit_span(vis, span), - Safety::Default => { $(${ignore($lt)}V::Result::output())? } + Safety::Default => { V::Result::output() } } } - fn visit_constness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, constness: &$($lt)? $($mut)? Const) $(-> >::Result)? { + fn visit_constness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, constness: &$($lt)? $($mut)? Const) -> V::Result { match constness { Const::Yes(span) => visit_span(vis, span), Const::No => { - $(>::Result::output())? + V::Result::output() } } } - fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) $(-> >::Result)? { + fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) -> V::Result { match defaultness { Defaultness::Default(span) => visit_span(vis, span), Defaultness::Final => { - $(>::Result::output())? + V::Result::output() } } } @@ -377,9 +379,9 @@ macro_rules! common_visitor_and_walkers { fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity, - ) $(-> >::Result)? { + ) -> V::Result { match polarity { - ImplPolarity::Positive => { $(>::Result::output())? } + ImplPolarity::Positive => { V::Result::output() } ImplPolarity::Negative(span) => visit_span(vis, span), } } @@ -390,7 +392,7 @@ macro_rules! common_visitor_and_walkers { fn visit_modifiers<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, m: &$($lt)? $($mut)? TraitBoundModifiers - ) $(-> >::Result)? { + ) -> V::Result { let TraitBoundModifiers { constness, asyncness, polarity } = m; match constness { BoundConstness::Never => {} @@ -404,26 +406,26 @@ macro_rules! common_visitor_and_walkers { BoundPolarity::Positive => {} BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => try_visit!(visit_span(vis, span)), } - $(>::Result::output())? + V::Result::output() } - fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> >::Result)? { + fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) -> V::Result { walk_list!(visitor, visit_param_bound, bounds, ctxt); - $(>::Result::output())? + V::Result::output() } - pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) $(-> >::Result)? { + pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) -> V::Result { visitor.visit_ident(ident) } - pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) $(-> >::Result)? { + pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) -> V::Result { let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; try_visit!(visit_constness(visitor, constness)); visit_opt!(visitor, visit_coroutine_kind, coroutine_kind); visit_safety(visitor, safety) } - pub fn walk_lifetime<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Lifetime { id, ident }: &$($lt)? $($mut)? Lifetime) $(-> >::Result)? { + pub fn walk_lifetime<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Lifetime { id, ident }: &$($lt)? $($mut)? Lifetime) -> V::Result { try_visit!(visit_id(visitor, id)); visitor.visit_ident(ident) } @@ -432,7 +434,7 @@ macro_rules! common_visitor_and_walkers { visitor: &mut V, item: &$($mut)? $($lt)? Item, ctxt: K::Ctxt, - ) $(-> >::Result)? { + ) -> V::Result { let Item { attrs, id, kind, vis, span, tokens: _ } = item; try_visit!(visit_id(visitor, id)); walk_list!(visitor, visit_attribute, attrs); @@ -444,7 +446,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_item<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind>( visitor: &mut V, item: &$($mut)? $($lt)? Item, - ) $(-> >::Result)? { + ) -> V::Result { walk_item_ctxt(visitor, item, ()) } @@ -452,7 +454,7 @@ macro_rules! common_visitor_and_walkers { visitor: &mut V, item: &$($mut)? $($lt)? AssocItem, ctxt: AssocCtxt, - ) $(-> >::Result)? { + ) -> V::Result { walk_item_ctxt(visitor, item, ctxt) } @@ -465,7 +467,7 @@ macro_rules! common_visitor_and_walkers { visibility: &$($lt)? $($mut)? Visibility, _ctxt: Self::Ctxt, vis: &mut V, - ) $(-> >::Result)? { + ) -> V::Result { match self { ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident), ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), @@ -505,7 +507,7 @@ macro_rules! common_visitor_and_walkers { } ModKind::Unloaded => {} } - $(>::Result::output())? + V::Result::output() } ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), @@ -526,7 +528,7 @@ macro_rules! common_visitor_and_walkers { $(${ignore($mut)} walk_ty_alias_where_clauses(vis, where_clauses); )? - $(>::Result::output())? + V::Result::output() } ItemKind::Enum(ident, generics, enum_definition) => { try_visit!(vis.visit_ident(ident)); @@ -590,7 +592,7 @@ macro_rules! common_visitor_and_walkers { try_visit!(vis.visit_ident(ident)); visit_opt!(vis, visit_ident, rename); visit_opt!(vis, visit_block, body); - $(>::Result::output())? + V::Result::output() } ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { try_visit!(vis.visit_qself(qself)); @@ -602,7 +604,7 @@ macro_rules! common_visitor_and_walkers { } } visit_opt!(vis, visit_block, body); - $(>::Result::output())? + V::Result::output() } } } @@ -611,7 +613,7 @@ macro_rules! common_visitor_and_walkers { fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, item: &$($lt)? $($mut)? ConstItem, - ) $(-> >::Result)? { + ) -> V::Result { let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item; try_visit!(visit_defaultness(vis, defaultness)); try_visit!(vis.visit_ident(ident)); @@ -621,7 +623,7 @@ macro_rules! common_visitor_and_walkers { walk_define_opaques(vis, define_opaque) } - fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> >::Result)? { + fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) -> V::Result { let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod; try_visit!(visit_safety(vis, safety)); visit_foreign_items(vis, items) @@ -630,14 +632,14 @@ macro_rules! common_visitor_and_walkers { fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>( visitor: &mut V, define_opaque: &$($lt)? $($mut)? Option>, - ) $(-> >::Result)? { + ) -> V::Result { if let Some(define_opaque) = define_opaque { for (id, path) in define_opaque { try_visit!(visit_id(visitor, id)); try_visit!(visitor.visit_path(path)); } } - $(>::Result::output())? + V::Result::output() } impl WalkItemKind for AssocItemKind { @@ -649,7 +651,7 @@ macro_rules! common_visitor_and_walkers { visibility: &$($lt)? $($mut)? Visibility, ctxt: Self::Ctxt, vis: &mut V, - ) $(-> >::Result)? { + ) -> V::Result { match self { AssocItemKind::Const(item) => { walk_const_item(vis, item) @@ -674,7 +676,7 @@ macro_rules! common_visitor_and_walkers { $(${ignore($mut)} walk_ty_alias_where_clauses(vis, where_clauses); )? - $(>::Result::output())? + V::Result::output() } AssocItemKind::MacCall(mac) => { vis.visit_mac_call(mac) @@ -694,7 +696,7 @@ macro_rules! common_visitor_and_walkers { try_visit!(vis.visit_ident(ident)); visit_opt!(vis, visit_ident, rename); visit_opt!(vis, visit_block, body); - $(>::Result::output())? + V::Result::output() } AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { try_visit!(vis.visit_qself(qself)); @@ -706,7 +708,7 @@ macro_rules! common_visitor_and_walkers { } } visit_opt!(vis, visit_block, body); - $(>::Result::output())? + V::Result::output() } } } @@ -721,7 +723,7 @@ macro_rules! common_visitor_and_walkers { visibility: &$($lt)? $($mut)? Visibility, _ctxt: Self::Ctxt, vis: &mut V, - ) $(-> >::Result)? { + ) -> V::Result { match self { ForeignItemKind::Static(box StaticItem { ident, @@ -756,7 +758,7 @@ macro_rules! common_visitor_and_walkers { $(${ignore($mut)} walk_ty_alias_where_clauses(vis, where_clauses); )? - $(>::Result::output())? + V::Result::output() } ForeignItemKind::MacCall(mac) => { vis.visit_mac_call(mac) @@ -768,7 +770,7 @@ macro_rules! common_visitor_and_walkers { fn walk_coroutine_kind<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, coroutine_kind: &$($lt)? $($mut)? CoroutineKind, - ) $(-> >::Result)? { + ) -> V::Result { let (CoroutineKind::Async { span, closure_id, return_impl_trait_id } | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id }) @@ -781,7 +783,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_pat<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, pattern: &$($lt)? $($mut)? Pat - ) $(-> >::Result)? { + ) -> V::Result { let Pat { id, kind, span, tokens: _ } = pattern; try_visit!(visit_id(vis, id)); match kind { @@ -832,7 +834,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_anon_const<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, constant: &$($lt)? $($mut)? AnonConst, - ) $(-> >::Result)? { + ) -> V::Result { let AnonConst { id, value } = constant; try_visit!(visit_id(vis, id)); vis.visit_expr(value) @@ -841,18 +843,18 @@ macro_rules! common_visitor_and_walkers { pub fn walk_path_segment<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, segment: &$($lt)? $($mut)? PathSegment, - ) $(-> >::Result)? { + ) -> V::Result { let PathSegment { ident, id, args } = segment; try_visit!(visit_id(vis, id)); try_visit!(vis.visit_ident(ident)); visit_opt!(vis, visit_generic_args, args); - $(>::Result::output())? + V::Result::output() } pub fn walk_block<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, block: &$($lt)? $($mut)? Block - ) $(-> >::Result)? { + ) -> V::Result { let Block { stmts, id, rules: _, span, tokens: _ } = block; try_visit!(visit_id(vis, id)); try_visit!(visit_stmts(vis, stmts)); @@ -862,7 +864,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_ty<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, ty: &$($lt)? $($mut)? Ty - ) $(-> >::Result)? { + ) -> V::Result { let Ty { id, kind, span, tokens: _ } = ty; try_visit!(visit_id(vis, id)); match kind { @@ -920,7 +922,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_crate<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, krate: &$($lt)? $($mut)? Crate, - ) $(-> >::Result)? { + ) -> V::Result { let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; try_visit!(visit_id(vis, id)); walk_list!(vis, visit_attribute, attrs); @@ -933,7 +935,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_local<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, local: &$($lt)? $($mut)? Local, - ) $(-> >::Result)? { + ) -> V::Result { let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local; if let Some(sp) = super_ { try_visit!(visit_span(vis, sp)); @@ -961,7 +963,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_poly_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, p: &$($lt)? $($mut)? PolyTraitRef, - ) $(-> >::Result)? { + ) -> V::Result { let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p; try_visit!(visit_modifiers(vis, modifiers)); try_visit!(visit_generic_params(vis, bound_generic_params)); @@ -972,7 +974,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, TraitRef { path, ref_id }: &$($lt)? $($mut)? TraitRef, - ) $(-> >::Result)? { + ) -> V::Result { try_visit!(vis.visit_path(path)); visit_id(vis, ref_id) } @@ -980,7 +982,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_variant<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, variant: &$($lt)? $($mut)? Variant, - ) $(-> >::Result)? { + ) -> V::Result { let Variant { attrs, id, span, vis: visibility, ident, data, disr_expr, is_placeholder: _ } = variant; try_visit!(visit_id(vis, id)); walk_list!(vis, visit_attribute, attrs); @@ -995,7 +997,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_expr_field<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, f: &$($lt)? $($mut)? ExprField, - ) $(-> >::Result)? { + ) -> V::Result { let ExprField { attrs, id, span, ident, expr, is_shorthand: _, is_placeholder: _ } = f; try_visit!(visit_id(vis, id)); walk_list!(vis, visit_attribute, attrs); @@ -1007,7 +1009,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_pat_field<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, fp: &$($lt)? $($mut)? PatField, - ) $(-> >::Result)? { + ) -> V::Result { let PatField { ident, pat, is_shorthand: _, attrs, id, span, is_placeholder: _ } = fp; try_visit!(visit_id(vis, id)); walk_list!(vis, visit_attribute, attrs); @@ -1019,7 +1021,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_ty_pat<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, tp: &$($lt)? $($mut)? TyPat, - ) $(-> >::Result)? { + ) -> V::Result { let TyPat { id, kind, span, tokens: _ } = tp; try_visit!(visit_id(vis, id)); match kind { @@ -1036,19 +1038,19 @@ macro_rules! common_visitor_and_walkers { fn walk_qself<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, qself: &$($lt)? $($mut)? Option>, - ) $(-> >::Result)? { + ) -> V::Result { if let Some(qself) = qself { let QSelf { ty, path_span, position: _ } = &$($mut)? **qself; try_visit!(vis.visit_ty(ty)); try_visit!(visit_span(vis, path_span)); } - $(>::Result::output())? + V::Result::output() } pub fn walk_path<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, path: &$($lt)? $($mut)? Path, - ) $(-> >::Result)? { + ) -> V::Result { let Path { span, segments, tokens: _ } = path; walk_list!(vis, visit_path_segment, segments); visit_span(vis, span) @@ -1057,7 +1059,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_use_tree<$($lt,)? V: $Visitor$(<$lt>)?>( vis: &mut V, use_tree: &$($lt)? $($mut)? UseTree, - ) $(-> >::Result)? { + ) -> V::Result { let UseTree { prefix, kind, span } = use_tree; try_visit!(vis.visit_path(prefix)); match kind { @@ -1075,6 +1077,581 @@ macro_rules! common_visitor_and_walkers { } visit_span(vis, span) } + + pub fn walk_generic_args<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + generic_args: &$($lt)? $($mut)? GenericArgs + ) -> V::Result { + match generic_args { + GenericArgs::AngleBracketed(AngleBracketedArgs { span, args }) => { + for arg in args { + match arg { + AngleBracketedArg::Arg(a) => try_visit!(vis.visit_generic_arg(a)), + AngleBracketedArg::Constraint(c) => { + try_visit!(vis.visit_assoc_item_constraint(c)) + } + } + } + visit_span(vis, span) + } + GenericArgs::Parenthesized(data) => { + let ParenthesizedArgs { span, inputs, inputs_span, output } = data; + walk_list!(vis, visit_ty, inputs); + try_visit!(vis.visit_fn_ret_ty(output)); + try_visit!(visit_span(vis, span)); + visit_span(vis, inputs_span) + } + GenericArgs::ParenthesizedElided(span) => visit_span(vis, span) + } + } + + pub fn walk_generic_arg<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + generic_arg: &$($lt)? $($mut)? GenericArg, + ) -> V::Result { + match generic_arg { + GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, $(${ignore($lt)} LifetimeCtxt::GenericArg)? ), + GenericArg::Type(ty) => vis.visit_ty(ty), + GenericArg::Const(ct) => vis.visit_anon_const(ct), + } + } + + pub fn walk_assoc_item_constraint<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + constraint: &$($lt)? $($mut)? AssocItemConstraint, + ) -> V::Result { + let AssocItemConstraint { id, ident, gen_args, kind, span } = constraint; + try_visit!(visit_id(vis, id)); + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_generic_args, gen_args); + match kind { + AssocItemConstraintKind::Equality { term } => match term { + Term::Ty(ty) => try_visit!(vis.visit_ty(ty)), + Term::Const(c) => try_visit!(vis.visit_anon_const(c)), + }, + AssocItemConstraintKind::Bound { bounds } => { + try_visit!(visit_bounds(vis, bounds, BoundKind::Bound)); + } + } + visit_span(vis, span) + } + + pub fn walk_param_bound<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, bound: &$($lt)? $($mut)? GenericBound) -> V::Result { + match bound { + GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref), + GenericBound::Outlives(lifetime) => vis.visit_lifetime(lifetime, $(${ignore($lt)} LifetimeCtxt::Bound)?), + GenericBound::Use(args, span) => { + walk_list!(vis, visit_precise_capturing_arg, args); + visit_span(vis, span) + } + } + } + + pub fn walk_precise_capturing_arg<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + arg: &$($lt)? $($mut)? PreciseCapturingArg, + ) -> V::Result { + match arg { + PreciseCapturingArg::Lifetime(lt) => vis.visit_lifetime(lt, $(${ignore($lt)} LifetimeCtxt::GenericArg)?), + PreciseCapturingArg::Arg(path, id) => { + try_visit!(visit_id(vis, id)); + vis.visit_path(path) + } + } + } + + pub fn walk_generic_param<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + param: &$($lt)? $($mut)? GenericParam, + ) -> V::Result { + let GenericParam { id, ident, attrs, bounds, is_placeholder: _, kind, colon_span } = + param; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_ident(ident)); + walk_list!(vis, visit_param_bound, bounds, BoundKind::Bound); + match kind { + GenericParamKind::Lifetime => (), + GenericParamKind::Type { default } => visit_opt!(vis, visit_ty, default), + GenericParamKind::Const { ty, default, kw_span: _ } => { + try_visit!(vis.visit_ty(ty)); + visit_opt!(vis, visit_anon_const, default); + } + } + if let Some(sp) = colon_span { + try_visit!(visit_span(vis, sp)) + } + V::Result::output() + } + + pub fn walk_generics<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, generics: &$($lt)? $($mut)? Generics) -> V::Result { + let Generics { params, where_clause, span } = generics; + let WhereClause { has_where_token: _, predicates, span: where_clause_span } = where_clause; + try_visit!(visit_generic_params(vis, params)); + try_visit!(visit_where_predicates(vis, predicates)); + try_visit!(visit_span(vis, span)); + visit_span(vis, where_clause_span) + } + + pub fn walk_contract<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, c: &$($lt)? $($mut)? FnContract) -> V::Result { + let FnContract { requires, ensures } = c; + visit_opt!(vis, visit_expr, requires); + visit_opt!(vis, visit_expr, ensures); + V::Result::output() + } + + pub fn walk_where_predicate<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + predicate: &$($lt)? $($mut)? WherePredicate, + ) -> V::Result { + let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = predicate; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(visit_span(vis, span)); + vis.visit_where_predicate_kind(kind) + } + + pub fn walk_closure_binder<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + binder: &$($lt)? $($mut)? ClosureBinder, + ) -> V::Result { + match binder { + ClosureBinder::NotPresent => {} + ClosureBinder::For { generic_params, span } => { + try_visit!(visit_generic_params(vis, generic_params)); + try_visit!(visit_span(vis, span)); + } + } + V::Result::output() + } + + pub fn walk_where_predicate_kind<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + kind: &$($lt)? $($mut)? WherePredicateKind, + ) -> V::Result { + match kind { + WherePredicateKind::BoundPredicate(WhereBoundPredicate { + bounded_ty, + bounds, + bound_generic_params, + }) => { + visit_generic_params(vis, bound_generic_params); + try_visit!(vis.visit_ty(bounded_ty)); + walk_list!(vis, visit_param_bound, bounds, BoundKind::Bound); + } + WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => { + try_visit!(vis.visit_lifetime(lifetime, $(${ignore($lt)} LifetimeCtxt::Bound )?)); + walk_list!(vis, visit_param_bound, bounds, BoundKind::Bound); + } + WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { + try_visit!(vis.visit_ty(lhs_ty)); + try_visit!(vis.visit_ty(rhs_ty)); + } + } + V::Result::output() + } + + pub fn walk_fn_decl<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + FnDecl { inputs, output }: &$($lt)? $($mut)? FnDecl, + ) -> V::Result { + try_visit!(visit_params(vis, inputs)); + vis.visit_fn_ret_ty(output) + } + + pub fn walk_fn_ret_ty<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, ret_ty: &$($lt)? $($mut)? FnRetTy) -> V::Result { + match ret_ty { + FnRetTy::Default(span) => visit_span(vis, span), + FnRetTy::Ty(output_ty) => vis.visit_ty(output_ty), + } + } + + pub fn walk_fn<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, kind: FnKind<$($lt)? $(${ignore($mut)} '_)?>) -> V::Result { + match kind { + FnKind::Fn( + _ctxt, + _vis, + Fn { + defaultness, + ident, + sig: FnSig { header, decl, span }, + generics, + contract, + body, + define_opaque, + }, + ) => { + // Visibility is visited as a part of the item. + try_visit!(visit_defaultness(vis, defaultness)); + try_visit!(vis.visit_ident(ident)); + try_visit!(vis.visit_fn_header(header)); + try_visit!(vis.visit_generics(generics)); + try_visit!(vis.visit_fn_decl(decl)); + visit_opt!(vis, visit_contract, contract); + visit_opt!(vis, visit_block, body); + try_visit!(visit_span(vis, span)); + walk_define_opaques(vis, define_opaque) + } + FnKind::Closure(binder, coroutine_kind, decl, body) => { + try_visit!(vis.visit_closure_binder(binder)); + visit_opt!(vis, visit_coroutine_kind, coroutine_kind); + try_visit!(vis.visit_fn_decl(decl)); + vis.visit_expr(body) + } + } + } + + pub fn walk_variant_data<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, data: &$($lt)? $($mut)? VariantData) -> V::Result { + match data { + VariantData::Struct { fields, recovered: _ } => { + visit_field_defs(vis, fields) + } + VariantData::Tuple(fields, id) => { + try_visit!(visit_id(vis, id)); + visit_field_defs(vis, fields) + } + VariantData::Unit(id) => visit_id(vis, id), + } + } + + pub fn walk_field_def<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, field: &$($lt)? $($mut)? FieldDef) -> V::Result { + let FieldDef { attrs, id, span, vis: visibility, ident, ty, is_placeholder: _, safety: _, default } = + field; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_vis(visibility)); + visit_opt!(vis, visit_ident, ident); + try_visit!(vis.visit_ty(ty)); + visit_opt!(vis, visit_anon_const, default); + visit_span(vis, span) + } + + fn visit_delim_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, args: &$($lt)? $($mut)? DelimArgs) -> V::Result { + let DelimArgs { dspan, delim: _, tokens: _ } = args; + let DelimSpan { open, close } = dspan; + try_visit!(visit_span(vis, open)); + visit_span(vis, close) + } + + pub fn walk_mac<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, mac: &$($lt)? $($mut)? MacCall) -> V::Result { + let MacCall { path, args } = mac; + try_visit!(vis.visit_path(path)); + visit_delim_args(vis, args) + } + + fn walk_macro_def<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, macro_def: &$($lt)? $($mut)? MacroDef) -> V::Result { + let MacroDef { body, macro_rules: _ } = macro_def; + visit_delim_args(vis, body) + } + + pub fn walk_inline_asm<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, asm: &$($lt)? $($mut)? InlineAsm) -> V::Result { + // FIXME: Visit spans inside all this currently ignored stuff. + let InlineAsm { + asm_macro: _, + template: _, + template_strs: _, + operands, + clobber_abis: _, + options: _, + line_spans: _, + } = asm; + for (op, span) in operands { + match op { + InlineAsmOperand::In { expr, reg: _ } + | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } + | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { + try_visit!(vis.visit_expr(expr)) + } + InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} + InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { + try_visit!(vis.visit_expr(in_expr)); + visit_opt!(vis, visit_expr, out_expr); + } + InlineAsmOperand::Const { anon_const } => { + try_visit!(vis.visit_anon_const(anon_const)) + } + InlineAsmOperand::Sym { sym } => try_visit!(vis.visit_inline_asm_sym(sym)), + InlineAsmOperand::Label { block } => try_visit!(vis.visit_block(block)), + } + try_visit!(visit_span(vis, span)); + } + V::Result::output() + } + + pub fn walk_inline_asm_sym<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + InlineAsmSym { id, qself, path }: &$($lt)? $($mut)? InlineAsmSym, + ) -> V::Result { + try_visit!(visit_id(vis, id)); + try_visit!(vis.visit_qself(qself)); + vis.visit_path(path) + } + + // FIXME: visit the template exhaustively. + pub fn walk_format_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, fmt: &$($lt)? $($mut)? FormatArgs) -> V::Result { + let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt; + let args = $(${ignore($mut)} arguments.all_args_mut())? $(${ignore($lt)} arguments.all_args())? ; + for FormatArgument { kind, expr } in args { + match kind { + FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { + try_visit!(vis.visit_ident(ident)) + } + FormatArgumentKind::Normal => {} + } + try_visit!(vis.visit_expr(expr)); + } + visit_span(vis, span) + } + + pub fn walk_expr<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, expression: &$($lt)? $($mut)? Expr) -> V::Result { + let Expr { id, kind, span, attrs, tokens: _ } = expression; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + match kind { + ExprKind::Array(exprs) => { + try_visit!(visit_exprs(vis, exprs)); + } + ExprKind::ConstBlock(anon_const) => try_visit!(vis.visit_anon_const(anon_const)), + ExprKind::Repeat(element, count) => { + try_visit!(vis.visit_expr(element)); + try_visit!(vis.visit_anon_const(count)); + } + ExprKind::Struct(se) => { + let StructExpr { qself, path, fields, rest } = &$($mut)?**se; + try_visit!(vis.visit_qself(qself)); + try_visit!(vis.visit_path(path)); + visit_expr_fields(vis, fields); + match rest { + StructRest::Base(expr) => try_visit!(vis.visit_expr(expr)), + StructRest::Rest(_span) => {} + StructRest::None => {} + } + } + ExprKind::Tup(exprs) => { + try_visit!(visit_exprs(vis, exprs)); + } + ExprKind::Call(callee_expression, arguments) => { + try_visit!(vis.visit_expr(callee_expression)); + try_visit!(visit_exprs(vis, arguments)); + } + ExprKind::MethodCall(box MethodCall { seg, receiver, args, span }) => { + try_visit!(vis.visit_method_receiver_expr(receiver)); + try_visit!(vis.visit_path_segment(seg)); + try_visit!(visit_exprs(vis, args)); + try_visit!(visit_span(vis, span)); + } + ExprKind::Binary(Spanned { span, node: _ }, left_expression, right_expression) => { + try_visit!(vis.visit_expr(left_expression)); + try_visit!(vis.visit_expr(right_expression)); + try_visit!(visit_span(vis, span)) + } + ExprKind::AddrOf(_kind, _mutbl, subexpression) => { + try_visit!(vis.visit_expr(subexpression)); + } + ExprKind::Unary(_op, subexpression) => { + try_visit!(vis.visit_expr(subexpression)); + } + ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { + try_visit!(vis.visit_expr(subexpression)); + try_visit!(vis.visit_ty(typ)); + } + ExprKind::Let(pat, expr, span, _recovered) => { + try_visit!(vis.visit_pat(pat)); + try_visit!(vis.visit_expr(expr)); + try_visit!(visit_span(vis, span)) + } + ExprKind::If(head_expression, if_block, optional_else) => { + try_visit!(vis.visit_expr(head_expression)); + try_visit!(vis.visit_block(if_block)); + visit_opt!(vis, visit_expr, optional_else); + } + ExprKind::While(subexpression, block, opt_label) => { + visit_opt!(vis, visit_label, opt_label); + try_visit!(vis.visit_expr(subexpression)); + try_visit!(vis.visit_block(block)); + } + ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { + visit_opt!(vis, visit_label, label); + try_visit!(vis.visit_pat(pat)); + try_visit!(vis.visit_expr(iter)); + try_visit!(vis.visit_block(body)); + } + ExprKind::Loop(block, opt_label, span) => { + visit_opt!(vis, visit_label, opt_label); + try_visit!(vis.visit_block(block)); + try_visit!(visit_span(vis, span)) + } + ExprKind::Match(subexpression, arms, _kind) => { + try_visit!(vis.visit_expr(subexpression)); + try_visit!(visit_arms(vis, arms)); + } + ExprKind::Closure(box Closure { + binder, + capture_clause, + coroutine_kind, + constness, + movability: _, + fn_decl, + body, + fn_decl_span, + fn_arg_span, + }) => { + try_visit!(visit_constness(vis, constness)); + try_visit!(vis.visit_capture_by(capture_clause)); + try_visit!(vis.visit_fn( + FnKind::Closure(binder, coroutine_kind, fn_decl, body), + *span, + *id + )); + try_visit!(visit_span(vis, fn_decl_span)); + try_visit!(visit_span(vis, fn_arg_span)); + } + ExprKind::Block(block, opt_label) => { + visit_opt!(vis, visit_label, opt_label); + try_visit!(vis.visit_block(block)); + } + ExprKind::Gen(_capt, body, _kind, decl_span) => { + try_visit!(vis.visit_block(body)); + try_visit!(visit_span(vis, decl_span)); + } + ExprKind::Await(expr, span) => { + try_visit!(vis.visit_expr(expr)); + try_visit!(visit_span(vis, span)); + } + ExprKind::Use(expr, span) => { + try_visit!(vis.visit_expr(expr)); + try_visit!(visit_span(vis, span)); + } + ExprKind::Assign(lhs, rhs, span) => { + try_visit!(vis.visit_expr(lhs)); + try_visit!(vis.visit_expr(rhs)); + try_visit!(visit_span(vis, span)); + } + ExprKind::AssignOp(_op, left_expression, right_expression) => { + try_visit!(vis.visit_expr(left_expression)); + try_visit!(vis.visit_expr(right_expression)); + } + ExprKind::Field(subexpression, ident) => { + try_visit!(vis.visit_expr(subexpression)); + try_visit!(vis.visit_ident(ident)); + } + ExprKind::Index(main_expression, index_expression, span) => { + try_visit!(vis.visit_expr(main_expression)); + try_visit!(vis.visit_expr(index_expression)); + try_visit!(visit_span(vis, span)); + } + ExprKind::Range(start, end, _limit) => { + visit_opt!(vis, visit_expr, start); + visit_opt!(vis, visit_expr, end); + } + ExprKind::Underscore => {} + ExprKind::Path(maybe_qself, path) => { + try_visit!(vis.visit_qself(maybe_qself)); + try_visit!(vis.visit_path(path)); + } + ExprKind::Break(opt_label, opt_expr) => { + visit_opt!(vis, visit_label, opt_label); + visit_opt!(vis, visit_expr, opt_expr); + } + ExprKind::Continue(opt_label) => { + visit_opt!(vis, visit_label, opt_label); + } + ExprKind::Ret(optional_expression) => { + visit_opt!(vis, visit_expr, optional_expression); + } + ExprKind::Yeet(optional_expression) => { + visit_opt!(vis, visit_expr, optional_expression); + } + ExprKind::Become(expr) => try_visit!(vis.visit_expr(expr)), + ExprKind::MacCall(mac) => try_visit!(vis.visit_mac_call(mac)), + ExprKind::Paren(subexpression) => try_visit!(vis.visit_expr(subexpression)), + ExprKind::InlineAsm(asm) => try_visit!(vis.visit_inline_asm(asm)), + ExprKind::FormatArgs(f) => try_visit!(vis.visit_format_args(f)), + ExprKind::OffsetOf(container, fields) => { + try_visit!(vis.visit_ty(container)); + walk_list!(vis, visit_ident, fields); + } + ExprKind::Yield(kind) => { + match kind { + YieldKind::Postfix(expr) => { + try_visit!(vis.visit_expr(expr)); + } + YieldKind::Prefix(expr) => { + visit_opt!(vis, visit_expr, expr); + } + } + } + ExprKind::Try(subexpression) => try_visit!(vis.visit_expr(subexpression)), + ExprKind::TryBlock(body) => try_visit!(vis.visit_block(body)), + ExprKind::Lit(_token) => {} + ExprKind::IncludedBytes(_bytes) => {} + ExprKind::UnsafeBinderCast(_kind, expr, ty) => { + try_visit!(vis.visit_expr(expr)); + visit_opt!(vis, visit_ty, ty); + } + ExprKind::Err(_guar) => {} + ExprKind::Dummy => {} + } + + visit_span(vis, span) + } + + pub fn walk_param<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, param: &$($lt)? $($mut)? Param) -> V::Result { + let Param { attrs, ty, pat, id, span, is_placeholder: _ } = param; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_pat(pat)); + try_visit!(vis.visit_ty(ty)); + visit_span(vis, span) + } + + pub fn walk_arm<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, arm: &$($lt)? $($mut)? Arm) -> V::Result { + let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_pat(pat)); + visit_opt!(vis, visit_expr, guard); + visit_opt!(vis, visit_expr, body); + visit_span(vis, span) + } + + pub fn walk_vis<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, visibility: &$($lt)? $($mut)? Visibility) -> V::Result { + let Visibility { kind, span, tokens: _ } = visibility; + match kind { + VisibilityKind::Restricted { path, id, shorthand: _ } => { + try_visit!(visit_id(vis, id)); + try_visit!(vis.visit_path(path)); + } + VisibilityKind::Public | VisibilityKind::Inherited => {} + } + visit_span(vis, span) + } + + pub fn walk_attribute<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, attr: &$($lt)? $($mut)? Attribute) -> V::Result { + let Attribute { kind, id: _, style: _, span } = attr; + match kind { + AttrKind::Normal(normal) => { + let NormalAttr { item, tokens: _ } = &$($mut)?**normal; + let AttrItem { unsafety: _, path, args, tokens: _ } = item; + try_visit!(vis.visit_path(path)); + try_visit!(walk_attr_args(vis, args)); + } + AttrKind::DocComment(_kind, _sym) => {} + } + visit_span(vis, span) + } + + pub fn walk_attr_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, args: &$($lt)? $($mut)? AttrArgs) -> V::Result { + match args { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => try_visit!(visit_delim_args(vis, args)), + AttrArgs::Eq { eq_span, expr } => { + try_visit!(vis.visit_expr(expr)); + try_visit!(visit_span(vis, eq_span)); + } + } + V::Result::output() + } }; } @@ -1102,9 +1679,15 @@ generate_list_visit_fns! { visit_foreign_items, P, visit_foreign_item; visit_generic_params, GenericParam, visit_generic_param; visit_stmts, Stmt, visit_stmt; + visit_exprs, P, visit_expr; + visit_expr_fields, ExprField, visit_expr_field; visit_pat_fields, PatField, visit_pat_field; visit_variants, Variant, visit_variant; visit_assoc_items, P, visit_assoc_item, ctxt: AssocCtxt; + visit_where_predicates, WherePredicate, visit_where_predicate; + visit_params, Param, visit_param; + visit_field_defs, FieldDef, visit_field_def; + visit_arms, Arm, visit_arm; } #[expect(rustc::pass_by_value)] // needed for symmetry with mut_visit @@ -1116,239 +1699,6 @@ fn visit_nested_use_tree<'a, V: Visitor<'a>>( vis.visit_nested_use_tree(nested_tree, nested_id) } -pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result -where - V: Visitor<'a>, -{ - match generic_args { - GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => { - for arg in args { - match arg { - AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)), - AngleBracketedArg::Constraint(c) => { - try_visit!(visitor.visit_assoc_item_constraint(c)) - } - } - } - } - GenericArgs::Parenthesized(data) => { - let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data; - walk_list!(visitor, visit_ty, inputs); - try_visit!(visitor.visit_fn_ret_ty(output)); - } - GenericArgs::ParenthesizedElided(_span) => {} - } - V::Result::output() -} - -pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result -where - V: Visitor<'a>, -{ - match generic_arg { - GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), - GenericArg::Type(ty) => visitor.visit_ty(ty), - GenericArg::Const(ct) => visitor.visit_anon_const(ct), - } -} - -pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( - visitor: &mut V, - constraint: &'a AssocItemConstraint, -) -> V::Result { - let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint; - try_visit!(visitor.visit_ident(ident)); - visit_opt!(visitor, visit_generic_args, gen_args); - match kind { - AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)), - Term::Const(c) => try_visit!(visitor.visit_anon_const(c)), - }, - AssocItemConstraintKind::Bound { bounds } => { - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - } - V::Result::output() -} - -pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result { - match bound { - GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref), - GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), - GenericBound::Use(args, _span) => { - walk_list!(visitor, visit_precise_capturing_arg, args); - V::Result::output() - } - } -} - -pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( - visitor: &mut V, - arg: &'a PreciseCapturingArg, -) -> V::Result { - match arg { - PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), - PreciseCapturingArg::Arg(path, id) => { - try_visit!(visitor.visit_id(*id)); - visitor.visit_path(path) - } - } -} - -pub fn walk_generic_param<'a, V: Visitor<'a>>( - visitor: &mut V, - param: &'a GenericParam, -) -> V::Result { - let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } = - param; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(ident)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - match kind { - GenericParamKind::Lifetime => (), - GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default), - GenericParamKind::Const { ty, default, kw_span: _ } => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_anon_const, default); - } - } - V::Result::output() -} - -pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result { - let Generics { params, where_clause, span: _ } = generics; - let WhereClause { has_where_token: _, predicates, span: _ } = where_clause; - walk_list!(visitor, visit_generic_param, params); - walk_list!(visitor, visit_where_predicate, predicates); - V::Result::output() -} - -pub fn walk_closure_binder<'a, V: Visitor<'a>>( - visitor: &mut V, - binder: &'a ClosureBinder, -) -> V::Result { - match binder { - ClosureBinder::NotPresent => {} - ClosureBinder::For { generic_params, span: _ } => { - walk_list!(visitor, visit_generic_param, generic_params) - } - } - V::Result::output() -} - -pub fn walk_contract<'a, V: Visitor<'a>>(visitor: &mut V, c: &'a FnContract) -> V::Result { - let FnContract { requires, ensures } = c; - if let Some(pred) = requires { - visitor.visit_expr(pred); - } - if let Some(pred) = ensures { - visitor.visit_expr(pred); - } - V::Result::output() -} - -pub fn walk_where_predicate<'a, V: Visitor<'a>>( - visitor: &mut V, - predicate: &'a WherePredicate, -) -> V::Result { - let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate; - walk_list!(visitor, visit_attribute, attrs); - visitor.visit_where_predicate_kind(kind) -} - -pub fn walk_where_predicate_kind<'a, V: Visitor<'a>>( - visitor: &mut V, - kind: &'a WherePredicateKind, -) -> V::Result { - match kind { - WherePredicateKind::BoundPredicate(WhereBoundPredicate { - bounded_ty, - bounds, - bound_generic_params, - }) => { - walk_list!(visitor, visit_generic_param, bound_generic_params); - try_visit!(visitor.visit_ty(bounded_ty)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => { - try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { - try_visit!(visitor.visit_ty(lhs_ty)); - try_visit!(visitor.visit_ty(rhs_ty)); - } - } - V::Result::output() -} - -pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result { - match ret_ty { - FnRetTy::Default(_span) => {} - FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)), - } - V::Result::output() -} - -pub fn walk_fn_decl<'a, V: Visitor<'a>>( - visitor: &mut V, - FnDecl { inputs, output }: &'a FnDecl, -) -> V::Result { - walk_list!(visitor, visit_param, inputs); - visitor.visit_fn_ret_ty(output) -} - -pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { - match kind { - FnKind::Fn( - _ctxt, - _vis, - Fn { - defaultness: _, - ident, - sig: FnSig { header, decl, span: _ }, - generics, - contract, - body, - define_opaque, - }, - ) => { - // Visibility is visited as a part of the item. - try_visit!(visitor.visit_ident(ident)); - try_visit!(visitor.visit_fn_header(header)); - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_fn_decl(decl)); - visit_opt!(visitor, visit_contract, contract); - visit_opt!(visitor, visit_block, body); - try_visit!(walk_define_opaques(visitor, define_opaque)); - } - FnKind::Closure(binder, coroutine_kind, decl, body) => { - try_visit!(visitor.visit_closure_binder(binder)); - visit_opt!(visitor, visit_coroutine_kind, coroutine_kind.as_ref()); - try_visit!(visitor.visit_fn_decl(decl)); - try_visit!(visitor.visit_expr(body)); - } - } - V::Result::output() -} - -pub fn walk_variant_data<'a, V: Visitor<'a>>(visitor: &mut V, data: &'a VariantData) -> V::Result { - visit_opt!(visitor, visit_id, data.ctor_node_id()); - walk_list!(visitor, visit_field_def, data.fields()); - V::Result::output() -} - -pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { - let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, safety: _, default } = - field; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - visit_opt!(visitor, visit_ident, ident); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_anon_const, &*default); - V::Result::output() -} - pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { let Stmt { id: _, kind, span: _ } = statement; match kind { @@ -1364,284 +1714,3 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V: } V::Result::output() } - -pub fn walk_mac<'a, V: Visitor<'a>>(visitor: &mut V, mac: &'a MacCall) -> V::Result { - let MacCall { path, args: _ } = mac; - visitor.visit_path(path) -} - -pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result { - let InlineAsm { - asm_macro: _, - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; - for (op, _span) in operands { - match op { - InlineAsmOperand::In { expr, reg: _ } - | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } - | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { - try_visit!(visitor.visit_expr(expr)) - } - InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} - InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { - try_visit!(visitor.visit_expr(in_expr)); - visit_opt!(visitor, visit_expr, out_expr); - } - InlineAsmOperand::Const { anon_const } => { - try_visit!(visitor.visit_anon_const(anon_const)) - } - InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)), - InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)), - } - } - V::Result::output() -} - -pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>( - visitor: &mut V, - InlineAsmSym { id, qself, path }: &'a InlineAsmSym, -) -> V::Result { - try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_id(*id)); - visitor.visit_path(path) -} - -pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result { - let FormatArgs { span: _, template: _, arguments, uncooked_fmt_str: _ } = fmt; - for FormatArgument { kind, expr } in arguments.all_args() { - match kind { - FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - try_visit!(visitor.visit_ident(ident)) - } - FormatArgumentKind::Normal => {} - } - try_visit!(visitor.visit_expr(expr)); - } - V::Result::output() -} - -pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { - let Expr { id, kind, span, attrs, tokens: _ } = expression; - walk_list!(visitor, visit_attribute, attrs); - match kind { - ExprKind::Array(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)), - ExprKind::Repeat(element, count) => { - try_visit!(visitor.visit_expr(element)); - try_visit!(visitor.visit_anon_const(count)); - } - ExprKind::Struct(se) => { - let StructExpr { qself, path, fields, rest } = &**se; - try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_id(*id)); - try_visit!(visitor.visit_path(path)); - walk_list!(visitor, visit_expr_field, fields); - match rest { - StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)), - StructRest::Rest(_span) => {} - StructRest::None => {} - } - } - ExprKind::Tup(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::Call(callee_expression, arguments) => { - try_visit!(visitor.visit_expr(callee_expression)); - walk_list!(visitor, visit_expr, arguments); - } - ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => { - try_visit!(visitor.visit_expr(receiver)); - try_visit!(visitor.visit_path_segment(seg)); - walk_list!(visitor, visit_expr, args); - } - ExprKind::Binary(_op, left_expression, right_expression) => { - try_visit!(visitor.visit_expr(left_expression)); - try_visit!(visitor.visit_expr(right_expression)); - } - ExprKind::AddrOf(_kind, _mutbl, subexpression) => { - try_visit!(visitor.visit_expr(subexpression)); - } - ExprKind::Unary(_op, subexpression) => { - try_visit!(visitor.visit_expr(subexpression)); - } - ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ty(typ)); - } - ExprKind::Let(pat, expr, _span, _recovered) => { - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_expr(expr)); - } - ExprKind::If(head_expression, if_block, optional_else) => { - try_visit!(visitor.visit_expr(head_expression)); - try_visit!(visitor.visit_block(if_block)); - visit_opt!(visitor, visit_expr, optional_else); - } - ExprKind::While(subexpression, block, opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_block(block)); - } - ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { - visit_opt!(visitor, visit_label, label); - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_expr(iter)); - try_visit!(visitor.visit_block(body)); - } - ExprKind::Loop(block, opt_label, _span) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_block(block)); - } - ExprKind::Match(subexpression, arms, _kind) => { - try_visit!(visitor.visit_expr(subexpression)); - walk_list!(visitor, visit_arm, arms); - } - ExprKind::Closure(box Closure { - binder, - capture_clause, - coroutine_kind, - constness: _, - movability: _, - fn_decl, - body, - fn_decl_span: _, - fn_arg_span: _, - }) => { - try_visit!(visitor.visit_capture_by(capture_clause)); - try_visit!(visitor.visit_fn( - FnKind::Closure(binder, coroutine_kind, fn_decl, body), - *span, - *id - )); - } - ExprKind::Block(block, opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_block(block)); - } - ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)), - ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)), - ExprKind::Use(expr, _span) => try_visit!(visitor.visit_expr(expr)), - ExprKind::Assign(lhs, rhs, _span) => { - try_visit!(visitor.visit_expr(lhs)); - try_visit!(visitor.visit_expr(rhs)); - } - ExprKind::AssignOp(_op, left_expression, right_expression) => { - try_visit!(visitor.visit_expr(left_expression)); - try_visit!(visitor.visit_expr(right_expression)); - } - ExprKind::Field(subexpression, ident) => { - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ident(ident)); - } - ExprKind::Index(main_expression, index_expression, _span) => { - try_visit!(visitor.visit_expr(main_expression)); - try_visit!(visitor.visit_expr(index_expression)); - } - ExprKind::Range(start, end, _limit) => { - visit_opt!(visitor, visit_expr, start); - visit_opt!(visitor, visit_expr, end); - } - ExprKind::Underscore => {} - ExprKind::Path(maybe_qself, path) => { - try_visit!(visitor.visit_qself(maybe_qself)); - try_visit!(visitor.visit_id(*id)); - try_visit!(visitor.visit_path(path)); - } - ExprKind::Break(opt_label, opt_expr) => { - visit_opt!(visitor, visit_label, opt_label); - visit_opt!(visitor, visit_expr, opt_expr); - } - ExprKind::Continue(opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - } - ExprKind::Ret(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Yeet(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Become(expr) => try_visit!(visitor.visit_expr(expr)), - ExprKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - ExprKind::Paren(subexpression) => try_visit!(visitor.visit_expr(subexpression)), - ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), - ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), - ExprKind::OffsetOf(container, fields) => { - try_visit!(visitor.visit_ty(container)); - walk_list!(visitor, visit_ident, fields.iter()); - } - ExprKind::Yield(kind) => { - visit_opt!(visitor, visit_expr, kind.expr()); - } - ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)), - ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)), - ExprKind::Lit(_token) => {} - ExprKind::IncludedBytes(_bytes) => {} - ExprKind::UnsafeBinderCast(_kind, expr, ty) => { - try_visit!(visitor.visit_expr(expr)); - visit_opt!(visitor, visit_ty, ty); - } - ExprKind::Err(_guar) => {} - ExprKind::Dummy => {} - } - - V::Result::output() -} - -pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result { - let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_ty(ty)); - V::Result::output() -} - -pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result { - let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - visit_opt!(visitor, visit_expr, guard); - visit_opt!(visitor, visit_expr, body); - V::Result::output() -} - -pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result { - let Visibility { kind, span: _, tokens: _ } = vis; - match kind { - VisibilityKind::Restricted { path, id, shorthand: _ } => { - try_visit!(visitor.visit_id(*id)); - try_visit!(visitor.visit_path(path)); - } - VisibilityKind::Public | VisibilityKind::Inherited => {} - } - V::Result::output() -} - -pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result { - let Attribute { kind, id: _, style: _, span: _ } = attr; - match kind { - AttrKind::Normal(normal) => { - let NormalAttr { item, tokens: _ } = &**normal; - let AttrItem { unsafety: _, path, args, tokens: _ } = item; - try_visit!(visitor.visit_path(path)); - try_visit!(walk_attr_args(visitor, args)); - } - AttrKind::DocComment(_kind, _sym) => {} - } - V::Result::output() -} - -pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result { - match args { - AttrArgs::Empty => {} - AttrArgs::Delimited(_args) => {} - AttrArgs::Eq { expr, .. } => try_visit!(visitor.visit_expr(expr)), - } - V::Result::output() -} diff --git a/tests/crashes/139825.rs b/tests/crashes/139825.rs deleted file mode 100644 index 8c5b6b80f0ba..000000000000 --- a/tests/crashes/139825.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #139825 -//@compile-flags: --check-cfg=cfg(docsrs,test) --crate-type lib -struct a -where - for<#[cfg(b)] c> u8:; diff --git a/tests/ui/check-cfg/hrtb-crash.rs b/tests/ui/check-cfg/hrtb-crash.rs new file mode 100644 index 000000000000..f2bce33f9f9a --- /dev/null +++ b/tests/ui/check-cfg/hrtb-crash.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/139825 +//@ compile-flags: --check-cfg=cfg(docsrs,test) --crate-type lib +//@ check-pass +struct A +where + for<#[cfg(b)] c> u8:; +//~^ WARN: unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/hrtb-crash.stderr b/tests/ui/check-cfg/hrtb-crash.stderr new file mode 100644 index 000000000000..431cf9cf53e2 --- /dev/null +++ b/tests/ui/check-cfg/hrtb-crash.stderr @@ -0,0 +1,13 @@ +warning: unexpected `cfg` condition name: `b` + --> $DIR/hrtb-crash.rs:6:15 + | +LL | for<#[cfg(b)] c> u8:; + | ^ help: found config with similar value: `target_feature = "b"` + | + = help: expected names are: `FALSE`, `docsrs`, and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(b)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + From 81abbe1f12e417275aa96ad1deb146d20e1b673d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 6 Jun 2025 22:19:31 +0530 Subject: [PATCH 117/183] moved sanity command to exec context --- src/bootstrap/src/core/sanity.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index af4ec679d080..4ef9316d00b6 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -361,8 +361,11 @@ than building it. // There are three builds of cmake on windows: MSVC, MinGW, and // Cygwin. The Cygwin build does not have generators for Visual // Studio, so detect that here and error. - let out = - command("cmake").arg("--help").run_always().run_capture_stdout(build).stdout(); + let out = command("cmake") + .arg("--help") + .run_always() + .run_capture_stdout_exec_ctx(&build) + .stdout(); if !out.contains("Visual Studio") { panic!( " From 2d1ca83ab58c2510350975dc219faa6a80885c0f Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 6 Jun 2025 22:36:48 +0530 Subject: [PATCH 118/183] moved curl to use new execution_context --- src/bootstrap/src/core/download.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index ba00b405c61d..ccb03ad21e58 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -22,8 +22,7 @@ fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> { config.try_run(cmd) } -fn extract_curl_version(out: &[u8]) -> semver::Version { - let out = String::from_utf8_lossy(out); +fn extract_curl_version(out: String) -> semver::Version { // The output should look like this: "curl .. ..." out.lines() .next() @@ -32,12 +31,15 @@ fn extract_curl_version(out: &[u8]) -> semver::Version { .unwrap_or(semver::Version::new(1, 0, 0)) } -fn curl_version() -> semver::Version { - let mut curl = Command::new("curl"); +fn curl_version(config: &Config) -> semver::Version { + let mut curl = command("curl"); curl.arg("-V"); - let Ok(out) = curl.output() else { return semver::Version::new(1, 0, 0) }; - let out = out.stdout; - extract_curl_version(&out) + let curl = curl.run_capture_stdout_exec_ctx(config); + if curl.is_failure() { + return semver::Version::new(1, 0, 0); + } + let output = curl.stdout(); + extract_curl_version(output) } /// Generic helpers that are useful anywhere in bootstrap. @@ -267,7 +269,7 @@ impl Config { curl.arg("--progress-bar"); } // --retry-all-errors was added in 7.71.0, don't use it if curl is old. - if curl_version() >= semver::Version::new(7, 71, 0) { + if curl_version(self) >= semver::Version::new(7, 71, 0) { curl.arg("--retry-all-errors"); } curl.arg(url); From d544c2b8d005c6f5de6796f6a9c9dd3407153c59 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 7 Jun 2025 00:23:44 +0530 Subject: [PATCH 119/183] covert uname to new extext method --- src/bootstrap/src/core/download.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index ccb03ad21e58..8d75fb48ccee 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -3,7 +3,7 @@ use std::ffi::OsString; use std::fs::{self, File}; use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Write}; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::Command; use std::sync::OnceLock; use xz2::bufread::XzDecoder; @@ -87,20 +87,14 @@ impl Config { /// on NixOS fn should_fix_bins_and_dylibs(&self) -> bool { let val = *SHOULD_FIX_BINS_AND_DYLIBS.get_or_init(|| { - match Command::new("uname").arg("-s").stderr(Stdio::inherit()).output() { - Err(_) => return false, - Ok(output) if !output.status.success() => return false, - Ok(output) => { - let mut os_name = output.stdout; - if os_name.last() == Some(&b'\n') { - os_name.pop(); - } - if os_name != b"Linux" { - return false; - } - } + let uname = command("uname").arg("-s").run_capture_stdout_exec_ctx(self); + if uname.is_failure() { + return false; + } + let output = uname.stdout(); + if !output.starts_with("Linux") { + return false; } - // If the user has asked binaries to be patched for Nix, then // don't check for NixOS or `/lib`. // NOTE: this intentionally comes after the Linux check: From bae39b8f10b0ee748c6420ba4ab71662e3c17b09 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 7 Jun 2025 00:42:19 +0530 Subject: [PATCH 120/183] move all download.rs method to new execution context command invocation --- src/bootstrap/src/core/config/config.rs | 12 --------- src/bootstrap/src/core/download.rs | 35 +++++++++---------------- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ee068f2bf52f..cb905a099ba8 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1034,18 +1034,6 @@ impl Config { self.explicit_stage_from_cli || self.explicit_stage_from_config } - /// Runs a command, printing out nice contextual information if it fails. - /// Exits if the command failed to execute at all, otherwise returns its - /// `status.success()`. - #[deprecated = "use `Builder::try_run` instead where possible"] - pub(crate) fn try_run(&self, cmd: &mut Command) -> Result<(), ()> { - if self.dry_run() { - return Ok(()); - } - self.verbose(|| println!("running: {cmd:?}")); - build_helper::util::try_run(cmd, self.is_verbose()) - } - pub(crate) fn test_args(&self) -> Vec<&str> { let mut test_args = match self.cmd { Subcommand::Test { ref test_args, .. } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 8d75fb48ccee..48604023c97a 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -3,7 +3,6 @@ use std::ffi::OsString; use std::fs::{self, File}; use std::io::{BufRead, BufReader, BufWriter, ErrorKind, Write}; use std::path::{Path, PathBuf}; -use std::process::Command; use std::sync::OnceLock; use xz2::bufread::XzDecoder; @@ -16,12 +15,6 @@ use crate::{Config, t}; static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock = OnceLock::new(); -/// `Config::try_run` wrapper for this module to avoid warnings on `try_run`, since we don't have access to a `builder` yet. -fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> { - #[expect(deprecated)] - config.try_run(cmd) -} - fn extract_curl_version(out: String) -> semver::Version { // The output should look like this: "curl .. ..." out.lines() @@ -169,23 +162,18 @@ impl Config { ]; } "; - nix_build_succeeded = try_run( - self, - Command::new("nix-build").args([ - Path::new("-E"), - Path::new(NIX_EXPR), - Path::new("-o"), - &nix_deps_dir, - ]), - ) - .is_ok(); + nix_build_succeeded = command("nix-build") + .allow_failure() + .args([Path::new("-E"), Path::new(NIX_EXPR), Path::new("-o"), &nix_deps_dir]) + .run_capture_stdout_exec_ctx(self) + .is_success(); nix_deps_dir }); if !nix_build_succeeded { return; } - let mut patchelf = Command::new(nix_deps_dir.join("bin/patchelf")); + let mut patchelf = command(nix_deps_dir.join("bin/patchelf")); patchelf.args(&[ OsString::from("--add-rpath"), OsString::from(t!(fs::canonicalize(nix_deps_dir)).join("lib")), @@ -196,8 +184,8 @@ impl Config { let dynamic_linker = t!(fs::read_to_string(dynamic_linker_path)); patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]); } - - let _ = try_run(self, patchelf.arg(fname)); + patchelf.arg(fname); + let _ = patchelf.run_capture_stdout_exec_ctx(self); } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { @@ -271,7 +259,7 @@ impl Config { if self.build.contains("windows-msvc") { eprintln!("Fallback to PowerShell"); for _ in 0..3 { - if try_run(self, Command::new("PowerShell.exe").args([ + let powershell = command("PowerShell.exe").args([ "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", @@ -279,9 +267,12 @@ impl Config { "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')", url, tempfile.to_str().expect("invalid UTF-8 not supported with powershell downloads"), ), - ])).is_err() { + ]).run_capture_stdout_exec_ctx(self); + + if powershell.is_failure() { return; } + eprintln!("\nspurious failure, trying again"); } } From 746276cfb26a3a8ceab2fed795ab76b1989f9650 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 7 Jun 2025 07:46:38 +0530 Subject: [PATCH 121/183] moved git command to new exec context --- src/bootstrap/src/core/config/config.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index cb905a099ba8..c9f37332a285 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -445,14 +445,9 @@ impl Config { // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path. cmd.arg("rev-parse").arg("--show-cdup"); // Discard stderr because we expect this to fail when building from a tarball. - let output = cmd - .as_command_mut() - .stderr(std::process::Stdio::null()) - .output() - .ok() - .and_then(|output| if output.status.success() { Some(output) } else { None }); - if let Some(output) = output { - let git_root_relative = String::from_utf8(output.stdout).unwrap(); + let output = cmd.run_capture_stdout_exec_ctx(&config); + if output.is_success() { + let git_root_relative = output.stdout(); // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes, // and to resolve any relative components. let git_root = env::current_dir() From 98be2a0498529db0f40628bf9ecef0ae833d937d Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 7 Jun 2025 09:40:48 +0530 Subject: [PATCH 122/183] move all config command invocation to new execution context invocation --- src/bootstrap/src/core/config/config.rs | 55 ++++++++++++++----------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index c9f37332a285..e37101381ddb 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -24,7 +24,7 @@ use std::{cmp, env, fs}; use build_helper::ci::CiEnv; use build_helper::exit; -use build_helper::git::{GitConfig, PathFreshness, check_path_modifications, output_result}; +use build_helper::git::{GitConfig, PathFreshness, check_path_modifications}; use serde::Deserialize; #[cfg(feature = "tracing")] use tracing::{instrument, span}; @@ -47,9 +47,10 @@ use crate::core::config::{ }; use crate::core::download::is_download_ci_available; use crate::utils::channel; +use crate::utils::exec::command; use crate::utils::execution_context::ExecutionContext; use crate::utils::helpers::exe; -use crate::{Command, GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, output, t}; +use crate::{GitInfo, OnceLock, TargetSelection, check_ci_llvm, helpers, t}; /// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic. /// This means they can be modified and changes to these paths should never trigger a compiler build @@ -445,7 +446,7 @@ impl Config { // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path. cmd.arg("rev-parse").arg("--show-cdup"); // Discard stderr because we expect this to fail when building from a tarball. - let output = cmd.run_capture_stdout_exec_ctx(&config); + let output = cmd.allow_failure().run_capture_stdout_exec_ctx(&config); if output.is_success() { let git_root_relative = output.stdout(); // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes, @@ -749,7 +750,12 @@ impl Config { }; config.initial_sysroot = t!(PathBuf::from_str( - output(Command::new(&config.initial_rustc).args(["--print", "sysroot"])).trim() + command(&config.initial_rustc) + .args(["--print", "sysroot"]) + .run_always() + .run_capture_stdout_exec_ctx(&config) + .stdout() + .trim() )); config.initial_cargo_clippy = cargo_clippy; @@ -1062,7 +1068,7 @@ impl Config { let mut git = helpers::git(Some(&self.src)); git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); - output(git.as_command_mut()) + git.allow_failure().run_capture_stdout_exec_ctx(self).stdout() } /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. @@ -1333,16 +1339,20 @@ impl Config { }; // Determine commit checked out in submodule. - let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"]).as_command_mut()); + let checked_out_hash = submodule_git() + .allow_failure() + .args(["rev-parse", "HEAD"]) + .run_capture_stdout_exec_ctx(self) + .stdout(); let checked_out_hash = checked_out_hash.trim_end(); // Determine commit that the submodule *should* have. - let recorded = output( - helpers::git(Some(&self.src)) - .run_always() - .args(["ls-tree", "HEAD"]) - .arg(relative_path) - .as_command_mut(), - ); + let recorded = helpers::git(Some(&self.src)) + .allow_failure() + .run_always() + .args(["ls-tree", "HEAD"]) + .arg(relative_path) + .run_capture_stdout_exec_ctx(self) + .stdout(); let actual_hash = recorded .split_whitespace() @@ -1366,20 +1376,18 @@ impl Config { let update = |progress: bool| { // Git is buggy and will try to fetch submodules from the tracking branch for *this* repository, // even though that has no relation to the upstream for the submodule. - let current_branch = output_result( - helpers::git(Some(&self.src)) - .allow_failure() - .run_always() - .args(["symbolic-ref", "--short", "HEAD"]) - .as_command_mut(), - ) - .map(|b| b.trim().to_owned()); + let current_branch = helpers::git(Some(&self.src)) + .allow_failure() + .run_always() + .args(["symbolic-ref", "--short", "HEAD"]) + .run_capture_exec_ctx(self); let mut git = helpers::git(Some(&self.src)).allow_failure(); git.run_always(); - if let Ok(branch) = current_branch { + if current_branch.is_success() { // If there is a tag named after the current branch, git will try to disambiguate by prepending `heads/` to the branch name. // This syntax isn't accepted by `branch.{branch}`. Strip it. + let branch = current_branch.stdout(); let branch = branch.strip_prefix("heads/").unwrap_or(&branch); git.arg("-c").arg(format!("branch.{branch}.remote=origin")); } @@ -1425,7 +1433,8 @@ impl Config { return; } - let stage0_output = output(Command::new(program_path).arg("--version")); + let stage0_output = + command(program_path).arg("--version").run_capture_stdout_exec_ctx(self).stdout(); let mut stage0_output = stage0_output.lines().next().unwrap().split(' '); let stage0_name = stage0_output.next().unwrap(); From 50725f325b32d3de2a0f159c7b90b21cfc91a2d3 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 7 Jun 2025 15:05:04 +0530 Subject: [PATCH 123/183] move all commands to new execution context --- src/bootstrap/src/core/config/config.rs | 14 +-- src/bootstrap/src/core/download.rs | 10 +- src/bootstrap/src/core/sanity.rs | 7 +- src/bootstrap/src/lib.rs | 127 ------------------------ src/bootstrap/src/utils/channel.rs | 2 +- src/bootstrap/src/utils/exec.rs | 34 +------ 6 files changed, 20 insertions(+), 174 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index e37101381ddb..8b5e252d1d7b 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -446,7 +446,7 @@ impl Config { // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path. cmd.arg("rev-parse").arg("--show-cdup"); // Discard stderr because we expect this to fail when building from a tarball. - let output = cmd.allow_failure().run_capture_stdout_exec_ctx(&config); + let output = cmd.allow_failure().run_capture_stdout(&config); if output.is_success() { let git_root_relative = output.stdout(); // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes, @@ -753,7 +753,7 @@ impl Config { command(&config.initial_rustc) .args(["--print", "sysroot"]) .run_always() - .run_capture_stdout_exec_ctx(&config) + .run_capture_stdout(&config) .stdout() .trim() )); @@ -1068,7 +1068,7 @@ impl Config { let mut git = helpers::git(Some(&self.src)); git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); - git.allow_failure().run_capture_stdout_exec_ctx(self).stdout() + git.allow_failure().run_capture_stdout(self).stdout() } /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. @@ -1342,7 +1342,7 @@ impl Config { let checked_out_hash = submodule_git() .allow_failure() .args(["rev-parse", "HEAD"]) - .run_capture_stdout_exec_ctx(self) + .run_capture_stdout(self) .stdout(); let checked_out_hash = checked_out_hash.trim_end(); // Determine commit that the submodule *should* have. @@ -1351,7 +1351,7 @@ impl Config { .run_always() .args(["ls-tree", "HEAD"]) .arg(relative_path) - .run_capture_stdout_exec_ctx(self) + .run_capture_stdout(self) .stdout(); let actual_hash = recorded @@ -1380,7 +1380,7 @@ impl Config { .allow_failure() .run_always() .args(["symbolic-ref", "--short", "HEAD"]) - .run_capture_exec_ctx(self); + .run_capture(self); let mut git = helpers::git(Some(&self.src)).allow_failure(); git.run_always(); @@ -1434,7 +1434,7 @@ impl Config { } let stage0_output = - command(program_path).arg("--version").run_capture_stdout_exec_ctx(self).stdout(); + command(program_path).arg("--version").run_capture_stdout(self).stdout(); let mut stage0_output = stage0_output.lines().next().unwrap().split(' '); let stage0_name = stage0_output.next().unwrap(); diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 48604023c97a..c518cc8bcd48 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -27,7 +27,7 @@ fn extract_curl_version(out: String) -> semver::Version { fn curl_version(config: &Config) -> semver::Version { let mut curl = command("curl"); curl.arg("-V"); - let curl = curl.run_capture_stdout_exec_ctx(config); + let curl = curl.run_capture_stdout(config); if curl.is_failure() { return semver::Version::new(1, 0, 0); } @@ -80,7 +80,7 @@ impl Config { /// on NixOS fn should_fix_bins_and_dylibs(&self) -> bool { let val = *SHOULD_FIX_BINS_AND_DYLIBS.get_or_init(|| { - let uname = command("uname").arg("-s").run_capture_stdout_exec_ctx(self); + let uname = command("uname").arg("-s").run_capture_stdout(self); if uname.is_failure() { return false; } @@ -165,7 +165,7 @@ impl Config { nix_build_succeeded = command("nix-build") .allow_failure() .args([Path::new("-E"), Path::new(NIX_EXPR), Path::new("-o"), &nix_deps_dir]) - .run_capture_stdout_exec_ctx(self) + .run_capture_stdout(self) .is_success(); nix_deps_dir }); @@ -185,7 +185,7 @@ impl Config { patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]); } patchelf.arg(fname); - let _ = patchelf.run_capture_stdout_exec_ctx(self); + let _ = patchelf.run_capture_stdout(self); } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { @@ -267,7 +267,7 @@ impl Config { "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')", url, tempfile.to_str().expect("invalid UTF-8 not supported with powershell downloads"), ), - ]).run_capture_stdout_exec_ctx(self); + ]).run_capture_stdout(self); if powershell.is_failure() { return; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 4ef9316d00b6..f55d924fdd8a 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -361,11 +361,8 @@ than building it. // There are three builds of cmake on windows: MSVC, MinGW, and // Cygwin. The Cygwin build does not have generators for Visual // Studio, so detect that here and error. - let out = command("cmake") - .arg("--help") - .run_always() - .run_capture_stdout_exec_ctx(&build) - .stdout(); + let out = + command("cmake").arg("--help").run_always().run_capture_stdout(&build).stdout(); if !out.contains("Visual Studio") { panic!( " diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 9bace4eb77ce..c8b6d59f38f7 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -941,133 +941,6 @@ impl Build { }) } - /// Execute a command and return its output. - /// Note: Ideally, you should use one of the BootstrapCommand::run* functions to - /// execute commands. They internally call this method. - #[track_caller] - fn run( - &self, - command: &mut BootstrapCommand, - stdout: OutputMode, - stderr: OutputMode, - ) -> CommandOutput { - command.mark_as_executed(); - if self.config.dry_run() && !command.run_always { - return CommandOutput::default(); - } - - #[cfg(feature = "tracing")] - let _run_span = trace_cmd!(command); - - let created_at = command.get_created_location(); - let executed_at = std::panic::Location::caller(); - - self.verbose(|| { - println!("running: {command:?} (created at {created_at}, executed at {executed_at})") - }); - - let cmd = command.as_command_mut(); - cmd.stdout(stdout.stdio()); - cmd.stderr(stderr.stdio()); - - let output = cmd.output(); - - use std::fmt::Write; - - let mut message = String::new(); - let output: CommandOutput = match output { - // Command has succeeded - Ok(output) if output.status.success() => { - CommandOutput::from_output(output, stdout, stderr) - } - // Command has started, but then it failed - Ok(output) => { - writeln!( - message, - r#" -Command {command:?} did not execute successfully. -Expected success, got {} -Created at: {created_at} -Executed at: {executed_at}"#, - output.status, - ) - .unwrap(); - - let output: CommandOutput = CommandOutput::from_output(output, stdout, stderr); - - // If the output mode is OutputMode::Capture, we can now print the output. - // If it is OutputMode::Print, then the output has already been printed to - // stdout/stderr, and we thus don't have anything captured to print anyway. - if stdout.captures() { - writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); - } - if stderr.captures() { - writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); - } - output - } - // The command did not even start - Err(e) => { - writeln!( - message, - "\n\nCommand {command:?} did not execute successfully.\ - \nIt was not possible to execute the command: {e:?}" - ) - .unwrap(); - CommandOutput::did_not_start(stdout, stderr) - } - }; - - let fail = |message: &str, output: CommandOutput| -> ! { - if self.is_verbose() { - println!("{message}"); - } else { - let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present()); - // If the command captures output, the user would not see any indication that - // it has failed. In this case, print a more verbose error, since to provide more - // context. - if stdout.is_some() || stderr.is_some() { - if let Some(stdout) = - output.stdout_if_present().take_if(|s| !s.trim().is_empty()) - { - println!("STDOUT:\n{stdout}\n"); - } - if let Some(stderr) = - output.stderr_if_present().take_if(|s| !s.trim().is_empty()) - { - println!("STDERR:\n{stderr}\n"); - } - println!("Command {command:?} has failed. Rerun with -v to see more details."); - } else { - println!("Command has failed. Rerun with -v to see more details."); - } - } - exit!(1); - }; - - if !output.is_success() { - match command.failure_behavior { - BehaviorOnFailure::DelayFail => { - if self.fail_fast { - fail(&message, output); - } - - let mut failures = self.delayed_failures.borrow_mut(); - failures.push(message); - } - BehaviorOnFailure::Exit => { - fail(&message, output); - } - BehaviorOnFailure::Ignore => { - // If failures are allowed, either the error has been printed already - // (OutputMode::Print) or the user used a capture output mode and wants to - // handle the error output on their own. - } - } - } - output - } - /// Check if verbosity is greater than the `level` pub fn is_verbose_than(&self, level: usize) -> bool { self.verbosity > level diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs index 333c04c3c264..fec9f068f6df 100644 --- a/src/bootstrap/src/utils/channel.rs +++ b/src/bootstrap/src/utils/channel.rs @@ -46,7 +46,7 @@ impl GitInfo { let mut git_command = helpers::git(Some(dir)); git_command.arg("rev-parse"); - let output = git_command.allow_failure().run_capture_stdout_exec_ctx(exec_ctx); + let output = git_command.allow_failure().run_capture_stdout(exec_ctx); if output.is_failure() { return GitInfo::Absent; diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index c03fd2772ad8..f297300e34a8 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -12,7 +12,6 @@ use build_helper::ci::CiEnv; use build_helper::drop_bomb::DropBomb; use super::execution_context::ExecutionContext; -use crate::Build; /// What should be done when the command fails. #[derive(Debug, Copy, Clone)] @@ -140,48 +139,25 @@ impl BootstrapCommand { self } + /// Run the command, while printing stdout and stderr. + /// Returns true if the command has succeeded. #[track_caller] - pub fn run_exec_ctx(&mut self, exec_ctx: impl AsRef) -> bool { + pub fn run(&mut self, exec_ctx: impl AsRef) -> bool { exec_ctx.as_ref().run(self, OutputMode::Print, OutputMode::Print).is_success() } /// Run the command, while capturing and returning all its output. #[track_caller] - pub fn run_capture_exec_ctx( - &mut self, - exec_ctx: impl AsRef, - ) -> CommandOutput { + pub fn run_capture(&mut self, exec_ctx: impl AsRef) -> CommandOutput { exec_ctx.as_ref().run(self, OutputMode::Capture, OutputMode::Capture) } /// Run the command, while capturing and returning stdout, and printing stderr. #[track_caller] - pub fn run_capture_stdout_exec_ctx( - &mut self, - exec_ctx: impl AsRef, - ) -> CommandOutput { + pub fn run_capture_stdout(&mut self, exec_ctx: impl AsRef) -> CommandOutput { exec_ctx.as_ref().run(self, OutputMode::Capture, OutputMode::Print) } - /// Run the command, while printing stdout and stderr. - /// Returns true if the command has succeeded. - #[track_caller] - pub fn run(&mut self, builder: &Build) -> bool { - builder.run(self, OutputMode::Print, OutputMode::Print).is_success() - } - - /// Run the command, while capturing and returning all its output. - #[track_caller] - pub fn run_capture(&mut self, builder: &Build) -> CommandOutput { - builder.run(self, OutputMode::Capture, OutputMode::Capture) - } - - /// Run the command, while capturing and returning stdout, and printing stderr. - #[track_caller] - pub fn run_capture_stdout(&mut self, builder: &Build) -> CommandOutput { - builder.run(self, OutputMode::Capture, OutputMode::Print) - } - /// Provides access to the stdlib Command inside. /// FIXME: This function should be eventually removed from bootstrap. pub fn as_command_mut(&mut self) -> &mut Command { From f3e1eb1dcade3e846c8624d2db85fc2d11a6d82a Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 8 Jun 2025 11:00:42 +0530 Subject: [PATCH 124/183] update dry_run value in exec_ctx and start forwarding exec_ctx verbose methods via config --- src/bootstrap/src/core/config/config.rs | 9 ++------- src/bootstrap/src/core/download.rs | 2 +- src/bootstrap/src/lib.rs | 2 ++ src/bootstrap/src/utils/channel.rs | 5 ----- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 8b5e252d1d7b..6b6d9c9e5ba4 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1025,10 +1025,7 @@ impl Config { } pub fn dry_run(&self) -> bool { - match self.dry_run { - DryRun::Disabled => false, - DryRun::SelfCheck | DryRun::UserSelected => true, - } + self.exec_ctx.dry_run() } pub fn is_explicit_stage(&self) -> bool { @@ -1256,9 +1253,7 @@ impl Config { /// Runs a function if verbosity is greater than 0 pub fn verbose(&self, f: impl Fn()) { - if self.is_verbose() { - f() - } + self.exec_ctx.verbose(f); } pub fn any_sanitizers_to_build(&self) -> bool { diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index c518cc8bcd48..16d097661b1d 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -38,7 +38,7 @@ fn curl_version(config: &Config) -> semver::Version { /// Generic helpers that are useful anywhere in bootstrap. impl Config { pub fn is_verbose(&self) -> bool { - self.verbose > 0 + self.exec_ctx.is_verbose() } pub(crate) fn create>(&self, path: P, s: &str) { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index c8b6d59f38f7..75dee300ec5e 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -673,6 +673,7 @@ impl Build { let _sanity_check_span = span!(tracing::Level::DEBUG, "(1) executing dry-run sanity-check").entered(); self.config.dry_run = DryRun::SelfCheck; + self.config.exec_ctx.set_dry_run(DryRun::SelfCheck); let builder = builder::Builder::new(self); builder.execute_cli(); } @@ -683,6 +684,7 @@ impl Build { let _actual_run_span = span!(tracing::Level::DEBUG, "(2) executing actual run").entered(); self.config.dry_run = DryRun::Disabled; + self.config.exec_ctx.set_dry_run(DryRun::Disabled); let builder = builder::Builder::new(self); builder.execute_cli(); } diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs index fec9f068f6df..8bd090e1a017 100644 --- a/src/bootstrap/src/utils/channel.rs +++ b/src/bootstrap/src/utils/channel.rs @@ -51,11 +51,6 @@ impl GitInfo { if output.is_failure() { return GitInfo::Absent; } - // Make sure git commands work - // match helpers::git(Some(dir)).arg("rev-parse").as_command_mut().output() { - // Ok(ref out) if out.status.success() => {} - // _ => return GitInfo::Absent, - // } // If we're ignoring the git info, we don't actually need to collect it, just make sure this // was a git repo in the first place. From e9ced508f4feeadd9d5b63aa752c1d39dcfbbb6c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 9 Jun 2025 20:34:30 +0530 Subject: [PATCH 125/183] remove execution context from flag module and correct the command invocation according to suggestions --- src/bootstrap/src/bin/main.rs | 4 ++-- src/bootstrap/src/core/config/config.rs | 16 ++++++++-------- src/bootstrap/src/core/config/flags.rs | 16 +++++----------- src/bootstrap/src/core/download.rs | 6 +++--- src/bootstrap/src/utils/channel.rs | 2 +- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 9f1fde74359c..833f80279517 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -29,9 +29,9 @@ fn main() { } debug!("parsing flags"); - let (flags, exec_ctx) = Flags::parse(&args); + let flags = Flags::parse(&args); debug!("parsing config based on flags"); - let config = Config::parse(flags, exec_ctx); + let config = Config::parse(flags); let mut build_lock; let _build_lock_guard; diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 6b6d9c9e5ba4..8d244f438f0f 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -368,7 +368,11 @@ impl Config { feature = "tracing", instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::parse", skip_all) )] - pub fn parse(flags: Flags, exec_ctx: ExecutionContext) -> Config { + pub fn parse(flags: Flags) -> Config { + let mut exec_ctx = ExecutionContext::new(); + exec_ctx.set_dry_run(if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }); + exec_ctx.set_verbose(flags.verbose); + exec_ctx.set_fail_fast(flags.cmd.fail_fast()); Self::parse_inner(flags, Self::get_toml, exec_ctx) } @@ -1065,7 +1069,7 @@ impl Config { let mut git = helpers::git(Some(&self.src)); git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); - git.allow_failure().run_capture_stdout(self).stdout() + git.run_capture_stdout(self).stdout() } /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. @@ -1334,15 +1338,11 @@ impl Config { }; // Determine commit checked out in submodule. - let checked_out_hash = submodule_git() - .allow_failure() - .args(["rev-parse", "HEAD"]) - .run_capture_stdout(self) - .stdout(); + let checked_out_hash = + submodule_git().args(["rev-parse", "HEAD"]).run_capture_stdout(self).stdout(); let checked_out_hash = checked_out_hash.trim_end(); // Determine commit that the submodule *should* have. let recorded = helpers::git(Some(&self.src)) - .allow_failure() .run_always() .args(["ls-tree", "HEAD"]) .arg(relative_path) diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index a50ff4caaf46..bc4fa73a3626 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -14,8 +14,7 @@ use crate::core::build_steps::setup::Profile; use crate::core::builder::{Builder, Kind}; use crate::core::config::Config; use crate::core::config::target_selection::{TargetSelectionList, target_selection_list}; -use crate::utils::execution_context::ExecutionContext; -use crate::{Build, DocTests, DryRun}; +use crate::{Build, DocTests}; #[derive(Copy, Clone, Default, Debug, ValueEnum)] pub enum Color { @@ -210,8 +209,8 @@ impl Flags { HelpVerboseOnly::try_parse_from(normalize_args(args)) { println!("NOTE: updating submodules before printing available paths"); - let (flags, exec_ctx) = Self::parse(&[String::from("build")]); - let config = Config::parse(flags, exec_ctx); + let flags = Self::parse(&[String::from("build")]); + let config = Config::parse(flags); let build = Build::new(config); let paths = Builder::get_help(&build, subcommand); if let Some(s) = paths { @@ -229,13 +228,8 @@ impl Flags { feature = "tracing", instrument(level = "trace", name = "Flags::parse", skip_all, fields(args = ?args)) )] - pub fn parse(args: &[String]) -> (Self, ExecutionContext) { - let mut exec_ctx = ExecutionContext::new(); - let flags = Flags::parse_from(normalize_args(args)); - exec_ctx.set_dry_run(if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }); - exec_ctx.set_verbose(flags.verbose); - exec_ctx.set_fail_fast(flags.cmd.fail_fast()); - (flags, exec_ctx) + pub fn parse(args: &[String]) -> Self { + Flags::parse_from(normalize_args(args)) } } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 16d097661b1d..f349b9a87edb 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -80,7 +80,7 @@ impl Config { /// on NixOS fn should_fix_bins_and_dylibs(&self) -> bool { let val = *SHOULD_FIX_BINS_AND_DYLIBS.get_or_init(|| { - let uname = command("uname").arg("-s").run_capture_stdout(self); + let uname = command("uname").allow_failure().arg("-s").run_capture_stdout(self); if uname.is_failure() { return false; } @@ -185,7 +185,7 @@ impl Config { patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]); } patchelf.arg(fname); - let _ = patchelf.run_capture_stdout(self); + let _ = patchelf.allow_failure().run_capture_stdout(self); } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { @@ -259,7 +259,7 @@ impl Config { if self.build.contains("windows-msvc") { eprintln!("Fallback to PowerShell"); for _ in 0..3 { - let powershell = command("PowerShell.exe").args([ + let powershell = command("PowerShell.exe").allow_failure().args([ "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs index 8bd090e1a017..38f250af42f0 100644 --- a/src/bootstrap/src/utils/channel.rs +++ b/src/bootstrap/src/utils/channel.rs @@ -46,7 +46,7 @@ impl GitInfo { let mut git_command = helpers::git(Some(dir)); git_command.arg("rev-parse"); - let output = git_command.allow_failure().run_capture_stdout(exec_ctx); + let output = git_command.allow_failure().run_capture(exec_ctx); if output.is_failure() { return GitInfo::Absent; From 4e8d5837df7cd7c83d91e14ad107a7422ab0ed36 Mon Sep 17 00:00:00 2001 From: Xinglu Chen Date: Mon, 2 Jun 2025 12:21:39 +0200 Subject: [PATCH 126/183] Add `-Zmiri-tree-borrows-no-precise-interior-mut` flag --- src/tools/miri/README.md | 4 + src/tools/miri/src/bin/miri.rs | 20 ++++- src/tools/miri/src/borrow_tracker/mod.rs | 29 +++++-- .../src/borrow_tracker/tree_borrows/mod.rs | 87 ++++++++++++++----- src/tools/miri/src/diagnostics.rs | 5 +- src/tools/miri/src/lib.rs | 4 +- .../pass/tree_borrows/cell-inside-struct.rs | 34 ++++++++ .../tree_borrows/cell-inside-struct.stderr | 6 ++ 8 files changed, 154 insertions(+), 35 deletions(-) create mode 100644 src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs create mode 100644 src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index de521393cd0a..f89708e0d8f2 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -458,6 +458,10 @@ to Miri failing to detect cases of undefined behavior in a program. This is much less likely with Stacked Borrows. Using Tree Borrows currently implies `-Zmiri-strict-provenance` because integer-to-pointer casts are not supported in this mode, but that may change in the future. +* `-Zmiri-tree-borrows-no-precise-interior-mut` makes Tree Borrows + track interior mutable data on the level of references instead of on the + byte-level as is done by default. Therefore, with this flag, Tree + Borrows will be more permissive. * `-Zmiri-force-page-size=` overrides the default page size for an architecture, in multiples of 1k. `4` is default for most targets. This value should always be a power of 2 and nonzero. diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 0121472d330f..1d3742cb0e98 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -35,7 +35,7 @@ use std::sync::{Arc, Once}; use miri::{ BacktraceStyle, BorrowTrackerMethod, GenmcConfig, GenmcCtx, MiriConfig, MiriEntryFnType, - ProvenanceMode, RetagFields, ValidationMode, + ProvenanceMode, RetagFields, TreeBorrowsParams, ValidationMode, }; use rustc_abi::ExternAbi; use rustc_data_structures::sync; @@ -554,8 +554,21 @@ fn main() { } else if arg == "-Zmiri-disable-stacked-borrows" { miri_config.borrow_tracker = None; } else if arg == "-Zmiri-tree-borrows" { - miri_config.borrow_tracker = Some(BorrowTrackerMethod::TreeBorrows); + miri_config.borrow_tracker = + Some(BorrowTrackerMethod::TreeBorrows(TreeBorrowsParams { + precise_interior_mut: true, + })); miri_config.provenance_mode = ProvenanceMode::Strict; + } else if arg == "-Zmiri-tree-borrows-no-precise-interior-mut" { + match &mut miri_config.borrow_tracker { + Some(BorrowTrackerMethod::TreeBorrows(params)) => { + params.precise_interior_mut = false; + } + _ => + show_error!( + "`-Zmiri-tree-borrows` is required before `-Zmiri-tree-borrows-no-precise-interior-mut`" + ), + }; } else if arg == "-Zmiri-disable-data-race-detector" { miri_config.data_race_detector = false; miri_config.weak_memory_emulation = false; @@ -725,7 +738,7 @@ fn main() { } } // Tree Borrows implies strict provenance, and is not compatible with native calls. - if matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows)) { + if matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows { .. })) { if miri_config.provenance_mode != ProvenanceMode::Strict { show_error!( "Tree Borrows does not support integer-to-pointer casts, and hence requires strict provenance" @@ -735,6 +748,7 @@ fn main() { show_error!("Tree Borrows is not compatible with calling native functions"); } } + // Native calls and strict provenance are not compatible. if miri_config.native_lib.is_some() && miri_config.provenance_mode == ProvenanceMode::Strict { show_error!("strict provenance is not compatible with calling native functions"); diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index b66c561d2b8a..36c61053a320 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -226,7 +226,13 @@ pub enum BorrowTrackerMethod { /// Stacked Borrows, as implemented in borrow_tracker/stacked_borrows StackedBorrows, /// Tree borrows, as implemented in borrow_tracker/tree_borrows - TreeBorrows, + TreeBorrows(TreeBorrowsParams), +} + +/// Parameters that Tree Borrows can take. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct TreeBorrowsParams { + pub precise_interior_mut: bool, } impl BorrowTrackerMethod { @@ -237,6 +243,13 @@ impl BorrowTrackerMethod { config.retag_fields, )) } + + pub fn get_tree_borrows_params(self) -> TreeBorrowsParams { + match self { + BorrowTrackerMethod::TreeBorrows(params) => params, + _ => panic!("can only be called when `BorrowTrackerMethod` is `TreeBorrows`"), + } + } } impl GlobalStateInner { @@ -252,7 +265,7 @@ impl GlobalStateInner { AllocState::StackedBorrows(Box::new(RefCell::new(Stacks::new_allocation( id, alloc_size, self, kind, machine, )))), - BorrowTrackerMethod::TreeBorrows => + BorrowTrackerMethod::TreeBorrows { .. } => AllocState::TreeBorrows(Box::new(RefCell::new(Tree::new_allocation( id, alloc_size, self, kind, machine, )))), @@ -271,7 +284,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; match method { BorrowTrackerMethod::StackedBorrows => this.sb_retag_ptr_value(kind, val), - BorrowTrackerMethod::TreeBorrows => this.tb_retag_ptr_value(kind, val), + BorrowTrackerMethod::TreeBorrows { .. } => this.tb_retag_ptr_value(kind, val), } } @@ -284,7 +297,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; match method { BorrowTrackerMethod::StackedBorrows => this.sb_retag_place_contents(kind, place), - BorrowTrackerMethod::TreeBorrows => this.tb_retag_place_contents(kind, place), + BorrowTrackerMethod::TreeBorrows { .. } => this.tb_retag_place_contents(kind, place), } } @@ -293,7 +306,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; match method { BorrowTrackerMethod::StackedBorrows => this.sb_protect_place(place), - BorrowTrackerMethod::TreeBorrows => this.tb_protect_place(place), + BorrowTrackerMethod::TreeBorrows { .. } => this.tb_protect_place(place), } } @@ -302,7 +315,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method; match method { BorrowTrackerMethod::StackedBorrows => this.sb_expose_tag(alloc_id, tag), - BorrowTrackerMethod::TreeBorrows => this.tb_expose_tag(alloc_id, tag), + BorrowTrackerMethod::TreeBorrows { .. } => this.tb_expose_tag(alloc_id, tag), } } @@ -319,7 +332,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.tcx.tcx.dcx().warn("Stacked Borrows does not support named pointers; `miri_pointer_name` is a no-op"); interp_ok(()) } - BorrowTrackerMethod::TreeBorrows => + BorrowTrackerMethod::TreeBorrows { .. } => this.tb_give_pointer_debug_name(ptr, nth_parent, name), } } @@ -333,7 +346,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let method = borrow_tracker.borrow().borrow_tracker_method; match method { BorrowTrackerMethod::StackedBorrows => this.print_stacks(alloc_id), - BorrowTrackerMethod::TreeBorrows => this.print_tree(alloc_id, show_unnamed), + BorrowTrackerMethod::TreeBorrows { .. } => this.print_tree(alloc_id, show_unnamed), } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 411ae89da906..ce8fe03ee477 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -312,8 +312,6 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let span = this.machine.current_span(); - let alloc_extra = this.get_alloc_extra(alloc_id)?; - let mut tree_borrows = alloc_extra.borrow_tracker_tb().borrow_mut(); // Store initial permissions and their corresponding range. let mut perms_map: RangeMap = RangeMap::new( @@ -342,36 +340,83 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert!(new_perm.freeze_access); let protected = new_perm.protector.is_some(); - this.visit_freeze_sensitive(place, ptr_size, |range, frozen| { - has_unsafe_cell = has_unsafe_cell || !frozen; + let precise_interior_mut = this + .machine + .borrow_tracker + .as_mut() + .unwrap() + .get_mut() + .borrow_tracker_method + .get_tree_borrows_params() + .precise_interior_mut; - // We are only ever `Frozen` inside the frozen bits. - let (perm, access) = if frozen { + let default_perm = if !precise_interior_mut { + // NOTE: Using `ty_is_freeze` doesn't give the same result as going through the range + // and computing `has_unsafe_cell`. This is because of zero-sized `UnsafeCell`, for which + // `has_unsafe_cell` is false, but `!ty_is_freeze` is true. + let ty_is_freeze = place.layout.ty.is_freeze(*this.tcx, this.typing_env()); + let (perm, access) = if ty_is_freeze { (new_perm.freeze_perm, new_perm.freeze_access) } else { (new_perm.nonfreeze_perm, new_perm.nonfreeze_access) }; + let sifa = perm.strongest_idempotent_foreign_access(protected); + let new_loc = if access { + LocationState::new_accessed(perm, sifa) + } else { + LocationState::new_non_accessed(perm, sifa) + }; - // Store initial permissions. - for (_loc_range, loc) in perms_map.iter_mut(range.start, range.size) { + for (_loc_range, loc) in perms_map.iter_mut_all() { + *loc = new_loc; + } + + perm + } else { + this.visit_freeze_sensitive(place, ptr_size, |range, frozen| { + has_unsafe_cell = has_unsafe_cell || !frozen; + + // We are only ever `Frozen` inside the frozen bits. + let (perm, access) = if frozen { + (new_perm.freeze_perm, new_perm.freeze_access) + } else { + (new_perm.nonfreeze_perm, new_perm.nonfreeze_access) + }; let sifa = perm.strongest_idempotent_foreign_access(protected); // NOTE: Currently, `access` is false if and only if `perm` is Cell, so this `if` // doesn't not change whether any code is UB or not. We could just always use // `new_accessed` and everything would stay the same. But that seems conceptually // odd, so we keep the initial "accessed" bit of the `LocationState` in sync with whether // a read access is performed below. - if access { - *loc = LocationState::new_accessed(perm, sifa); + let new_loc = if access { + LocationState::new_accessed(perm, sifa) } else { - *loc = LocationState::new_non_accessed(perm, sifa); - } - } + LocationState::new_non_accessed(perm, sifa) + }; - // Some reborrows incur a read access to the parent. - if access { + // Store initial permissions. + for (_loc_range, loc) in perms_map.iter_mut(range.start, range.size) { + *loc = new_loc; + } + + interp_ok(()) + })?; + + // Allow lazily writing to surrounding data if we found an `UnsafeCell`. + if has_unsafe_cell { new_perm.nonfreeze_perm } else { new_perm.freeze_perm } + }; + + let alloc_extra = this.get_alloc_extra(alloc_id)?; + let mut tree_borrows = alloc_extra.borrow_tracker_tb().borrow_mut(); + + for (perm_range, perm) in perms_map.iter_mut_all() { + if perm.is_accessed() { + // Some reborrows incur a read access to the parent. // Adjust range to be relative to allocation start (rather than to `place`). - let mut range_in_alloc = range; - range_in_alloc.start += base_offset; + let range_in_alloc = AllocRange { + start: Size::from_bytes(perm_range.start) + base_offset, + size: Size::from_bytes(perm_range.end - perm_range.start), + }; tree_borrows.perform_access( orig_tag, @@ -382,7 +427,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; // Also inform the data race model (but only if any bytes are actually affected). - if range.size.bytes() > 0 { + if range_in_alloc.size.bytes() > 0 { if let Some(data_race) = alloc_extra.data_race.as_vclocks_ref() { data_race.read( alloc_id, @@ -394,8 +439,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } } - interp_ok(()) - })?; + } // Record the parent-child pair in the tree. tree_borrows.new_child( @@ -403,8 +447,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { orig_tag, new_tag, perms_map, - // Allow lazily writing to surrounding data if we found an `UnsafeCell`. - if has_unsafe_cell { new_perm.nonfreeze_perm } else { new_perm.freeze_perm }, + default_perm, protected, span, )?; diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 1728a9cfd6de..58bf163bfade 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -682,7 +682,10 @@ impl<'tcx> MiriMachine<'tcx> { ), ]; if self.borrow_tracker.as_ref().is_some_and(|b| { - matches!(b.borrow().borrow_tracker_method(), BorrowTrackerMethod::TreeBorrows) + matches!( + b.borrow().borrow_tracker_method(), + BorrowTrackerMethod::TreeBorrows { .. } + ) }) { v.push( note!("Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used") diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 8802216448f6..8b457b98017e 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -112,7 +112,9 @@ pub use crate::borrow_tracker::stacked_borrows::{ EvalContextExt as _, Item, Permission, Stack, Stacks, }; pub use crate::borrow_tracker::tree_borrows::{EvalContextExt as _, Tree}; -pub use crate::borrow_tracker::{BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields}; +pub use crate::borrow_tracker::{ + BorTag, BorrowTrackerMethod, EvalContextExt as _, RetagFields, TreeBorrowsParams, +}; pub use crate::clock::{Instant, MonotonicClock}; pub use crate::concurrency::cpu_affinity::MAX_CPUS; pub use crate::concurrency::data_race::{ diff --git a/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs new file mode 100644 index 000000000000..fd68685a2f44 --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.rs @@ -0,0 +1,34 @@ +//! The same as `tests/fail/tree-borrows/cell-inside-struct` but with +//! precise tracking of interior mutability disabled. +//@compile-flags: -Zmiri-tree-borrows -Zmiri-tree-borrows-no-precise-interior-mut +#[path = "../../utils/mod.rs"] +#[macro_use] +mod utils; + +use std::cell::Cell; + +struct Foo { + field1: u32, + field2: Cell, +} + +pub fn main() { + let root = Foo { field1: 42, field2: Cell::new(88) }; + unsafe { + let a = &root; + + name!(a as *const Foo, "a"); + + let a: *const Foo = a as *const Foo; + let a: *mut Foo = a as *mut Foo; + + let alloc_id = alloc_id!(a); + print_state!(alloc_id); + + // Writing to `field2`, which is interior mutable, should be allowed. + (*a).field2.set(10); + + // Writing to `field1` should be allowed because it also has the `Cell` permission. + (*a).field1 = 88; + } +} diff --git a/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr new file mode 100644 index 000000000000..1d939329040f --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/cell-inside-struct.stderr @@ -0,0 +1,6 @@ +────────────────────────────────────────────────── +Warning: this tree is indicative only. Some tags may have been hidden. +0.. 8 +| Act | └─┬── +|?Cel | └──── +────────────────────────────────────────────────── From 51fbd145f95cb193bde3c675a9236e2777973d07 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 9 Jun 2025 21:11:45 +0530 Subject: [PATCH 127/183] Initialize the execution context in parse_inner, start using dry run from the execution context, add getters and setters in the config, and update the tests and other relevant areas accordingly. --- src/bootstrap/src/core/builder/cargo.rs | 2 +- src/bootstrap/src/core/builder/mod.rs | 6 ++++-- src/bootstrap/src/core/builder/tests.rs | 2 +- src/bootstrap/src/core/config/config.rs | 22 +++++++++++++------- src/bootstrap/src/lib.rs | 21 +++++-------------- src/bootstrap/src/utils/execution_context.rs | 4 ++++ 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 1e9af68a92df..6026765d32a4 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -551,7 +551,7 @@ impl Builder<'_> { let libdir = self.rustc_libdir(compiler); let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8"); - if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) { + if self.is_verbose() && !matches!(self.config.get_dry_run(), DryRun::SelfCheck) { println!("using sysroot {sysroot_str}"); } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index e8686c75e02f..8b1520de3a85 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -443,13 +443,15 @@ impl StepDescription { fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) { - if !matches!(builder.config.dry_run, DryRun::SelfCheck) { + if !matches!(builder.config.get_dry_run(), DryRun::SelfCheck) { println!("Skipping {pathset:?} because it is excluded"); } return true; } - if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) { + if !builder.config.skip.is_empty() + && !matches!(builder.config.get_dry_run(), DryRun::SelfCheck) + { builder.verbose(|| { println!( "{:?} not skipped for {:?} -- not in {:?}", diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index baa22fc7f72a..a264d772c562 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -22,7 +22,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config let mut config = Config::parse(Flags::parse(cmd)); // don't save toolstates config.save_toolstates = None; - config.dry_run = DryRun::SelfCheck; + config.set_dry_run(DryRun::SelfCheck); // Ignore most submodules, since we don't need them for a dry run, and the // tests run much faster without them. diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 8d244f438f0f..8f3c95ab5bf4 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -131,7 +131,6 @@ pub struct Config { pub jobs: Option, pub cmd: Subcommand, pub incremental: bool, - pub dry_run: DryRun, pub dump_bootstrap_shims: bool, /// Arguments appearing after `--` to be forwarded to tools, /// e.g. `--fix-broken` or test arguments. @@ -364,16 +363,20 @@ impl Config { } } + pub fn set_dry_run(&mut self, dry_run: DryRun) { + self.exec_ctx.set_dry_run(dry_run); + } + + pub fn get_dry_run(&self) -> &DryRun { + self.exec_ctx.get_dry_run() + } + #[cfg_attr( feature = "tracing", instrument(target = "CONFIG_HANDLING", level = "trace", name = "Config::parse", skip_all) )] pub fn parse(flags: Flags) -> Config { - let mut exec_ctx = ExecutionContext::new(); - exec_ctx.set_dry_run(if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }); - exec_ctx.set_verbose(flags.verbose); - exec_ctx.set_fail_fast(flags.cmd.fail_fast()); - Self::parse_inner(flags, Self::get_toml, exec_ctx) + Self::parse_inner(flags, Self::get_toml) } #[cfg_attr( @@ -388,9 +391,12 @@ impl Config { pub(crate) fn parse_inner( mut flags: Flags, get_toml: impl Fn(&Path) -> Result, - exec_ctx: ExecutionContext, ) -> Config { let mut config = Config::default_opts(); + let mut exec_ctx = ExecutionContext::new(); + exec_ctx.set_verbose(flags.verbose); + exec_ctx.set_fail_fast(flags.cmd.fail_fast()); + config.exec_ctx = exec_ctx; // Set flags. @@ -420,7 +426,7 @@ impl Config { config.on_fail = flags.on_fail; config.cmd = flags.cmd; config.incremental = flags.incremental; - config.dry_run = if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }; + config.set_dry_run(if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }); config.dump_bootstrap_shims = flags.dump_bootstrap_shims; config.keep_stage = flags.keep_stage; config.keep_stage_std = flags.keep_stage_std; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 75dee300ec5e..ea688f6f86bd 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -196,7 +196,6 @@ pub struct Build { crates: HashMap, crate_paths: HashMap, is_sudo: bool, - delayed_failures: RefCell>, prerelease_version: Cell>, #[cfg(feature = "build-metrics")] @@ -457,7 +456,6 @@ impl Build { crates: HashMap::new(), crate_paths: HashMap::new(), is_sudo, - delayed_failures: RefCell::new(Vec::new()), prerelease_version: Cell::new(None), #[cfg(feature = "build-metrics")] @@ -672,8 +670,7 @@ impl Build { #[cfg(feature = "tracing")] let _sanity_check_span = span!(tracing::Level::DEBUG, "(1) executing dry-run sanity-check").entered(); - self.config.dry_run = DryRun::SelfCheck; - self.config.exec_ctx.set_dry_run(DryRun::SelfCheck); + self.config.set_dry_run(DryRun::SelfCheck); let builder = builder::Builder::new(self); builder.execute_cli(); } @@ -683,8 +680,7 @@ impl Build { #[cfg(feature = "tracing")] let _actual_run_span = span!(tracing::Level::DEBUG, "(2) executing actual run").entered(); - self.config.dry_run = DryRun::Disabled; - self.config.exec_ctx.set_dry_run(DryRun::Disabled); + self.config.set_dry_run(DryRun::Disabled); let builder = builder::Builder::new(self); builder.execute_cli(); } @@ -700,14 +696,7 @@ impl Build { debug!("checking for postponed test failures from `test --no-fail-fast`"); // Check for postponed failures from `test --no-fail-fast`. - let failures = self.delayed_failures.borrow(); - if !failures.is_empty() { - eprintln!("\n{} command(s) did not execute successfully:\n", failures.len()); - for failure in failures.iter() { - eprintln!(" - {failure}\n"); - } - exit!(1); - } + self.config.exec_ctx().report_failures_and_exit(); #[cfg(feature = "build-metrics")] self.metrics.persist(self); @@ -956,7 +945,7 @@ impl Build { } fn info(&self, msg: &str) { - match self.config.dry_run { + match self.config.get_dry_run() { DryRun::SelfCheck => (), DryRun::Disabled | DryRun::UserSelected => { println!("{msg}"); @@ -1079,7 +1068,7 @@ impl Build { #[track_caller] fn group(&self, msg: &str) -> Option { - match self.config.dry_run { + match self.config.get_dry_run() { DryRun::SelfCheck => None, DryRun::Disabled | DryRun::UserSelected => Some(gha::group(msg)), } diff --git a/src/bootstrap/src/utils/execution_context.rs b/src/bootstrap/src/utils/execution_context.rs index 17af98babb49..d12c02c161df 100644 --- a/src/bootstrap/src/utils/execution_context.rs +++ b/src/bootstrap/src/utils/execution_context.rs @@ -28,6 +28,10 @@ impl ExecutionContext { } } + pub fn get_dry_run(&self) -> &DryRun { + &self.dry_run + } + pub fn verbose(&self, f: impl Fn()) { if self.is_verbose() { f() From 1cdd33ebe2bec7eea928e147c0adc4e36c22a1da Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 5 Jun 2025 19:46:16 -0500 Subject: [PATCH 128/183] core::ptr: deduplicate more method docs --- library/core/src/ptr/const_ptr.rs | 64 +----------------- library/core/src/ptr/docs/as_uninit_slice.md | 44 +++++++++++++ library/core/src/ptr/docs/is_null.md | 18 ++++++ library/core/src/ptr/mut_ptr.rs | 68 ++------------------ 4 files changed, 68 insertions(+), 126 deletions(-) create mode 100644 library/core/src/ptr/docs/as_uninit_slice.md create mode 100644 library/core/src/ptr/docs/is_null.md diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index a1dab23ea7b4..9366cb36c6ef 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -5,24 +5,7 @@ use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; impl *const T { - /// Returns `true` if the pointer is null. - /// - /// Note that unsized types have many possible null pointers, as only the - /// raw data pointer is considered, not their length, vtable, etc. - /// Therefore, two pointers that are null may still not compare equal to - /// each other. - /// - /// # Panics during const evaluation - /// - /// If this method is used during const evaluation, and `self` is a pointer - /// that is offset beyond the bounds of the memory it initially pointed to, - /// then there might not be enough information to determine whether the - /// pointer is null. This is because the absolute address in memory is not - /// known at compile time. If the nullness of the pointer cannot be - /// determined, this method will panic. - /// - /// In-bounds pointers are never null, so the method will never panic for - /// such pointers. + #[doc = include_str!("docs/is_null.md")] /// /// # Examples /// @@ -1550,50 +1533,7 @@ impl *const [T] { unsafe { index.get_unchecked(self) } } - /// Returns `None` if the pointer is null, or else returns a shared slice to - /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require - /// that the value has to be initialized. - /// - /// [`as_ref`]: #method.as_ref - /// - /// # Safety - /// - /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, - /// and it must be properly aligned. This means in particular: - /// - /// * The entire memory range of this slice must be contained within a single [allocation]! - /// Slices can never span across multiple allocations. - /// - /// * The pointer must be aligned even for zero-length slices. One - /// reason for this is that enum layout optimizations may rely on references - /// (including slices of any length) being aligned and non-null to distinguish - /// them from other data. You can obtain a pointer that is usable as `data` - /// for zero-length slices using [`NonNull::dangling()`]. - /// - /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. - /// See the safety documentation of [`pointer::offset`]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// - /// See also [`slice::from_raw_parts`][]. - /// - /// [valid]: crate::ptr#safety - /// [allocation]: crate::ptr#allocation - /// - /// # Panics during const evaluation - /// - /// This method will panic during const evaluation if the pointer cannot be - /// determined to be null or not. See [`is_null`] for more information. - /// - /// [`is_null`]: #method.is_null + #[doc = include_str!("docs/as_uninit_slice.md")] #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { diff --git a/library/core/src/ptr/docs/as_uninit_slice.md b/library/core/src/ptr/docs/as_uninit_slice.md new file mode 100644 index 000000000000..c80c04058838 --- /dev/null +++ b/library/core/src/ptr/docs/as_uninit_slice.md @@ -0,0 +1,44 @@ +Returns `None` if the pointer is null, or else returns a shared slice to +the value wrapped in `Some`. In contrast to [`as_ref`], this does not require +that the value has to be initialized. + +[`as_ref`]: #method.as_ref + +# Safety + +When calling this method, you have to ensure that *either* the pointer is null *or* +all of the following is true: + +* The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, +and it must be properly aligned. This means in particular: + +* The entire memory range of this slice must be contained within a single [allocation]! +Slices can never span across multiple allocations. + +* The pointer must be aligned even for zero-length slices. One +reason for this is that enum layout optimizations may rely on references +(including slices of any length) being aligned and non-null to distinguish +them from other data. You can obtain a pointer that is usable as `data` +for zero-length slices using [`NonNull::dangling()`]. + +* The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. +See the safety documentation of [`pointer::offset`]. + +* You must enforce Rust's aliasing rules, since the returned lifetime `'a` is +arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. +In particular, while this reference exists, the memory the pointer points to must +not get mutated (except inside `UnsafeCell`). + +This applies even if the result of this method is unused! + +See also [`slice::from_raw_parts`][]. + +[valid]: crate::ptr#safety +[allocation]: crate::ptr#allocation + +# Panics during const evaluation + +This method will panic during const evaluation if the pointer cannot be +determined to be null or not. See [`is_null`] for more information. + +[`is_null`]: #method.is_null diff --git a/library/core/src/ptr/docs/is_null.md b/library/core/src/ptr/docs/is_null.md new file mode 100644 index 000000000000..7368ab9b5763 --- /dev/null +++ b/library/core/src/ptr/docs/is_null.md @@ -0,0 +1,18 @@ +Returns `true` if the pointer is null. + +Note that unsized types have many possible null pointers, as only the +raw data pointer is considered, not their length, vtable, etc. +Therefore, two pointers that are null may still not compare equal to +each other. + +# Panics during const evaluation + +If this method is used during const evaluation, and `self` is a pointer +that is offset beyond the bounds of the memory it initially pointed to, +then there might not be enough information to determine whether the +pointer is null. This is because the absolute address in memory is not +known at compile time. If the nullness of the pointer cannot be +determined, this method will panic. + +In-bounds pointers are never null, so the method will never panic for +such pointers. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 968f033bf598..efe1031b79ca 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -5,24 +5,7 @@ use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; impl *mut T { - /// Returns `true` if the pointer is null. - /// - /// Note that unsized types have many possible null pointers, as only the - /// raw data pointer is considered, not their length, vtable, etc. - /// Therefore, two pointers that are null may still not compare equal to - /// each other. - /// - /// # Panics during const evaluation - /// - /// If this method is used during const evaluation, and `self` is a pointer - /// that is offset beyond the bounds of the memory it initially pointed to, - /// then there might not be enough information to determine whether the - /// pointer is null. This is because the absolute address in memory is not - /// known at compile time. If the nullness of the pointer cannot be - /// determined, this method will panic. - /// - /// In-bounds pointers are never null, so the method will never panic for - /// such pointers. + #[doc = include_str!("docs/is_null.md")] /// /// # Examples /// @@ -1906,53 +1889,10 @@ impl *mut [T] { unsafe { index.get_unchecked_mut(self) } } - /// Returns `None` if the pointer is null, or else returns a shared slice to - /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require - /// that the value has to be initialized. + #[doc = include_str!("docs/as_uninit_slice.md")] /// - /// For the mutable counterpart see [`as_uninit_slice_mut`]. - /// - /// [`as_ref`]: pointer#method.as_ref-1 - /// [`as_uninit_slice_mut`]: #method.as_uninit_slice_mut - /// - /// # Safety - /// - /// When calling this method, you have to ensure that *either* the pointer is null *or* - /// all of the following is true: - /// - /// * The pointer must be [valid] for reads for `ptr.len() * size_of::()` many bytes, - /// and it must be properly aligned. This means in particular: - /// - /// * The entire memory range of this slice must be contained within a single [allocation]! - /// Slices can never span across multiple allocations. - /// - /// * The pointer must be aligned even for zero-length slices. One - /// reason for this is that enum layout optimizations may rely on references - /// (including slices of any length) being aligned and non-null to distinguish - /// them from other data. You can obtain a pointer that is usable as `data` - /// for zero-length slices using [`NonNull::dangling()`]. - /// - /// * The total size `ptr.len() * size_of::()` of the slice must be no larger than `isize::MAX`. - /// See the safety documentation of [`pointer::offset`]. - /// - /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is - /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. - /// In particular, while this reference exists, the memory the pointer points to must - /// not get mutated (except inside `UnsafeCell`). - /// - /// This applies even if the result of this method is unused! - /// - /// See also [`slice::from_raw_parts`][]. - /// - /// [valid]: crate::ptr#safety - /// [allocation]: crate::ptr#allocation - /// - /// # Panics during const evaluation - /// - /// This method will panic during const evaluation if the pointer cannot be - /// determined to be null or not. See [`is_null`] for more information. - /// - /// [`is_null`]: #method.is_null-1 + /// # See Also + /// For the mutable counterpart see [`as_uninit_slice_mut`](pointer::as_uninit_slice_mut). #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { From a9401ea657d24878ebee7511d6a51a5df8ed3071 Mon Sep 17 00:00:00 2001 From: Teoh Han Hui Date: Tue, 10 Jun 2025 02:24:04 +0800 Subject: [PATCH 129/183] platform-support.md: Mention specific Linux kernel version or later --- src/doc/rustc/src/platform-support.md | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e2e2ad9ac3b5..559e4867bbb1 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -33,7 +33,7 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+) -`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) +`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1+, glibc 2.17+) `i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment] `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+, Pentium 4) [^x86_32-floats-return-ABI] [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+) @@ -91,20 +91,20 @@ target | notes `aarch64-pc-windows-msvc` | ARM64 Windows MSVC `aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony -`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17) -`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17) -`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17) +`arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17) +`arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17) +`armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2+, glibc 2.17) [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | Armv7-A OpenHarmony -[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) -[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) +[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, glibc 2.36) +[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, musl 1.2.5) [`i686-pc-windows-gnu`](platform-support/windows-gnu.md) | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment] -`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) -`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) -[`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10, glibc 2.17) -[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19, musl 1.2.3) -[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29) -[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) -[`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17) +`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2+, glibc 2.17) +`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2+, glibc 2.17) +[`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10+, glibc 2.17) +[`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.3) +[`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20+, glibc 2.29) +[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.3) +[`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2+, glibc 2.17) [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit x86 FreeBSD [`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 @@ -158,16 +158,16 @@ target | std | notes [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC [`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian [`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat -[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23) +[`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | ✓ | Armv5TE Linux (kernel 4.4+, glibc 2.23) `armv5te-unknown-linux-musleabi` | ✓ | Armv5TE Linux with musl 1.2.3 [`armv7-linux-androideabi`](platform-support/android.md) | ✓ | Armv7-A Android -`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27) +`armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15+, glibc 2.27) `armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3 `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat [`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat -`i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2, glibc 2.17, original Pentium) [^x86_32-floats-x87] +`i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87] [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] [`i686-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 32-bit x86 MinGW (Windows 10+, Pentium 4), LLVM ABI [^x86_32-floats-return-ABI] @@ -184,13 +184,13 @@ target | std | notes [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) -`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) +`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M [`thumbv7em-none-eabi`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M [`thumbv7em-none-eabihf`](platform-support/thumbv7em-none-eabi.md) | * | Bare Armv7E-M, hardfloat [`thumbv7m-none-eabi`](platform-support/thumbv7m-none-eabi.md) | * | Bare Armv7-M [`thumbv7neon-linux-androideabi`](platform-support/android.md) | ✓ | Thumb2-mode Armv7-A Android with NEON -`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode Armv7-A Linux with NEON (kernel 4.4, glibc 2.23) +`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode Armv7-A Linux with NEON (kernel 4.4+, glibc 2.23) [`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare Armv8-M Baseline [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat @@ -206,7 +206,7 @@ target | std | notes [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android [`x86_64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia -`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) +`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15+, glibc 2.27) [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat [`x86_64-unknown-redox`](platform-support/redox.md) | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI From a096de73ea6f9a41026f6c6ad5a393f9418aab97 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Jun 2025 21:49:50 +0200 Subject: [PATCH 130/183] native_lib: skip to next .so if function was in dependency of the first --- src/tools/miri/src/shims/native_lib.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index 40440bf6da41..acf258f4eedd 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -114,18 +114,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // using the `libc` crate where this interface is public. let mut info = std::mem::MaybeUninit::::zeroed(); unsafe { - if libc::dladdr(fn_ptr, info.as_mut_ptr()) != 0 { - let info = info.assume_init(); - #[cfg(target_os = "cygwin")] - let fname_ptr = info.dli_fname.as_ptr(); - #[cfg(not(target_os = "cygwin"))] - let fname_ptr = info.dli_fname; - assert!(!fname_ptr.is_null()); - if std::ffi::CStr::from_ptr(fname_ptr).to_str().unwrap() - != lib_path.to_str().unwrap() - { - return None; - } + let res = libc::dladdr(fn_ptr, info.as_mut_ptr()); + assert!(res != 0, "failed to load info about function we already loaded"); + let info = info.assume_init(); + #[cfg(target_os = "cygwin")] + let fname_ptr = info.dli_fname.as_ptr(); + #[cfg(not(target_os = "cygwin"))] + let fname_ptr = info.dli_fname; + assert!(!fname_ptr.is_null()); + if std::ffi::CStr::from_ptr(fname_ptr).to_str().unwrap() + != lib_path.to_str().unwrap() + { + // The function is not actually in this .so, check the next one. + continue; } } From 11581df1ba8b8473dd2a1fb6f43d06d01b0d9f20 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Jun 2025 21:52:43 +0200 Subject: [PATCH 131/183] native-lib: update readme (to mention folders in header) --- src/tools/miri/README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 508228ede9ee..fc7942a49c0c 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -396,20 +396,22 @@ to Miri failing to detect cases of undefined behavior in a program. * `-Zmiri-force-intrinsic-fallback` forces the use of the "fallback" body for all intrinsics that have one. This is useful to test the fallback bodies, but should not be used otherwise. It is **unsound** since the fallback body might not be checking for all UB. -* `-Zmiri-native-lib=` is an experimental flag for providing support - for calling native functions from inside the interpreter via FFI. The flag is supported only on - Unix systems. Functions not provided by that file are still executed via the usual Miri shims. If - a path to a directory is specified, all files in that directory are included nonrecursively. This - flag can be passed multiple times to specify multiple files and/or directories. +* `-Zmiri-native-lib=` is an experimental flag for providing + support for calling native functions from inside the interpreter via FFI. The flag is supported + only on Unix systems. Functions not provided by that file are still executed via the usual Miri + shims. If a path to a directory is specified, all files in that directory are included + non-recursively. This flag can be passed multiple times to specify multiple files and/or + directories. **WARNING**: If an invalid/incorrect `.so` file is specified, this can cause Undefined Behavior in Miri itself! And of course, Miri often cannot do any checks on the actions taken by the native code. Note that Miri has its own handling of file descriptors, so if you want to replace *some* functions working on file descriptors, you will have to replace *all* of them, or the two kinds of - file descriptors will be mixed up. This is **work in progress**; currently, only integer and - pointers arguments and return values are supported and memory allocated by the native code cannot - be accessed from Rust (only the other way around). Native code must not spawn threads that keep - running in the background after the call has returned to Rust and that access Rust-allocated - memory. Finally, the flag is **unsound** in the sense that Miri stops tracking details such as + file descriptors will be mixed up. + This is **work in progress**; currently, only integer and pointers arguments and return values are + supported and memory allocated by the native code cannot be accessed from Rust (only the other way + around). Native code must not spawn threads that keep running in the background after the call has + returned to Rust and that access Rust-allocated memory. + Finally, the flag is **unsound** in the sense that Miri stops tracking details such as initialization and provenance on memory shared with native code, so it is easily possible to write code that has UB which is missed by Miri. * `-Zmiri-measureme=` enables `measureme` profiling for the interpreted program. From 3fce086d79afd9bc5b52a13e051934694cf196c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 4 Jun 2025 21:10:27 +0000 Subject: [PATCH 132/183] Make E0621 missing lifetime suggestion verbose ``` error[E0621]: explicit lifetime required in the type of `x` --> $DIR/42701_one_named_and_one_anonymous.rs:10:9 | LL | &*x | ^^^ lifetime `'a` required | help: add explicit lifetime `'a` to the type of `x` | LL | fn foo2<'a>(a: &'a Foo, x: &'a i32) -> &'a i32 { | ++ ``` --- compiler/rustc_trait_selection/src/errors.rs | 12 ++++++++---- ...hout-precise-captures-we-are-powerless.stderr | 16 ++++++++++------ tests/ui/async-await/issues/issue-63388-1.stderr | 9 ++++++--- .../must_outlive_least_region_or_bound.stderr | 9 ++++++--- tests/ui/issues/issue-13058.stderr | 8 +++++--- tests/ui/issues/issue-14285.stderr | 8 ++++++-- tests/ui/issues/issue-15034.stderr | 7 +++++-- tests/ui/issues/issue-3154.stderr | 7 +++++-- tests/ui/issues/issue-40288-2.stderr | 16 ++++++++++------ .../42701_one_named_and_one_anonymous.stderr | 8 +++++--- ...ne-existing-name-early-bound-in-struct.stderr | 8 +++++--- ...ex1-return-one-existing-name-if-else-2.stderr | 7 +++++-- ...ex1-return-one-existing-name-if-else-3.stderr | 7 +++++-- ...one-existing-name-if-else-using-impl-2.stderr | 7 +++++-- ...one-existing-name-if-else-using-impl-3.stderr | 7 +++++-- .../ex1-return-one-existing-name-if-else.stderr | 7 +++++-- .../ex2a-push-one-existing-name-2.stderr | 7 +++++-- ...x2a-push-one-existing-name-early-bound.stderr | 8 +++++--- .../ex2a-push-one-existing-name.stderr | 7 +++++-- tests/ui/lifetimes/noisy-follow-up-erro.stderr | 9 ++++++--- ...object-lifetime-default-from-box-error.stderr | 8 +++++--- tests/ui/regions/regions-glb-free-free.stderr | 7 +++++-- .../regions/regions-infer-at-fn-not-param.stderr | 9 ++++++--- .../missing-lifetimes-in-signature.stderr | 8 +++++--- tests/ui/variance/variance-trait-matching.stderr | 8 +++++--- 25 files changed, 143 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 06f81ac554e6..7bf49056e299 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -759,7 +759,8 @@ pub enum ExplicitLifetimeRequired<'a> { #[suggestion( trait_selection_explicit_lifetime_required_sugg_with_ident, code = "{new_ty}", - applicability = "unspecified" + applicability = "unspecified", + style = "verbose" )] new_ty_span: Span, #[skip_arg] @@ -774,7 +775,8 @@ pub enum ExplicitLifetimeRequired<'a> { #[suggestion( trait_selection_explicit_lifetime_required_sugg_with_param_type, code = "{new_ty}", - applicability = "unspecified" + applicability = "unspecified", + style = "verbose" )] new_ty_span: Span, #[skip_arg] @@ -1462,7 +1464,8 @@ pub enum SuggestAccessingField<'a> { #[suggestion( trait_selection_suggest_accessing_field, code = "{snippet}.{name}", - applicability = "maybe-incorrect" + applicability = "maybe-incorrect", + style = "verbose" )] Safe { #[primary_span] @@ -1474,7 +1477,8 @@ pub enum SuggestAccessingField<'a> { #[suggestion( trait_selection_suggest_accessing_field, code = "unsafe {{ {snippet}.{name} }}", - applicability = "maybe-incorrect" + applicability = "maybe-incorrect", + style = "verbose" )] Unsafe { #[primary_span] diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index 329cec6dad3a..b7259074bf64 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -106,11 +106,13 @@ LL | } error[E0621]: explicit lifetime required in the type of `x` --> $DIR/without-precise-captures-we-are-powerless.rs:38:5 | -LL | fn through_field_and_ref<'a>(x: &S<'a>) { - | ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>` -... LL | outlives::<'a>(call_once(c)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn through_field_and_ref<'a>(x: &'a S<'a>) { + | ++ error[E0597]: `c` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:43:20 @@ -131,11 +133,13 @@ LL | } error[E0621]: explicit lifetime required in the type of `x` --> $DIR/without-precise-captures-we-are-powerless.rs:44:5 | -LL | fn through_field_and_ref_move<'a>(x: &S<'a>) { - | ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>` -... LL | outlives::<'a>(call_once(c)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn through_field_and_ref_move<'a>(x: &'a S<'a>) { + | ++ error: aborting due to 10 previous errors diff --git a/tests/ui/async-await/issues/issue-63388-1.stderr b/tests/ui/async-await/issues/issue-63388-1.stderr index 277f7fa6f63e..a59fe7dbc20e 100644 --- a/tests/ui/async-await/issues/issue-63388-1.stderr +++ b/tests/ui/async-await/issues/issue-63388-1.stderr @@ -1,11 +1,14 @@ error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/issue-63388-1.rs:14:9 | -LL | &'a self, foo: &dyn Foo - | -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)` -... LL | foo | ^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `foo` + | +LL - &'a self, foo: &dyn Foo +LL + &'a self, foo: &'a (dyn Foo + 'a) + | error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr index ba7d7770e503..53c556866041 100644 --- a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -65,9 +65,12 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/must_outlive_least_region_or_bound.rs:15:41 | LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } - | ---- ^ lifetime `'a` required - | | - | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` + | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn foo<'a>(x: &'a i32) -> impl Copy + 'a { x } + | ++ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:30:55 diff --git a/tests/ui/issues/issue-13058.stderr b/tests/ui/issues/issue-13058.stderr index 7cc2860eb508..4f4108fa1825 100644 --- a/tests/ui/issues/issue-13058.stderr +++ b/tests/ui/issues/issue-13058.stderr @@ -1,11 +1,13 @@ error[E0621]: explicit lifetime required in the type of `cont` --> $DIR/issue-13058.rs:14:21 | -LL | fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool - | -- help: add explicit lifetime `'r` to the type of `cont`: `&'r T` -LL | { LL | let cont_iter = cont.iter(); | ^^^^^^^^^^^ lifetime `'r` required + | +help: add explicit lifetime `'r` to the type of `cont` + | +LL | fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &'r T) -> bool + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-14285.stderr b/tests/ui/issues/issue-14285.stderr index 4f89ae51157b..edd139eecba4 100644 --- a/tests/ui/issues/issue-14285.stderr +++ b/tests/ui/issues/issue-14285.stderr @@ -1,10 +1,14 @@ error[E0621]: explicit lifetime required in the type of `a` --> $DIR/issue-14285.rs:12:5 | -LL | fn foo<'a>(a: &dyn Foo) -> B<'a> { - | -------- help: add explicit lifetime `'a` to the type of `a`: `&'a (dyn Foo + 'a)` LL | B(a) | ^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `a` + | +LL - fn foo<'a>(a: &dyn Foo) -> B<'a> { +LL + fn foo<'a>(a: &'a (dyn Foo + 'a)) -> B<'a> { + | error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-15034.stderr b/tests/ui/issues/issue-15034.stderr index 587a5c85e924..7db8ade2e482 100644 --- a/tests/ui/issues/issue-15034.stderr +++ b/tests/ui/issues/issue-15034.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `lexer` --> $DIR/issue-15034.rs:17:9 | -LL | pub fn new(lexer: &'a mut Lexer) -> Parser<'a> { - | ------------- help: add explicit lifetime `'a` to the type of `lexer`: `&'a mut Lexer<'a>` LL | Parser { lexer: lexer } | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `lexer` + | +LL | pub fn new(lexer: &'a mut Lexer<'a>) -> Parser<'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-3154.stderr b/tests/ui/issues/issue-3154.stderr index 3106aaddc4a1..c17e59f7fc3d 100644 --- a/tests/ui/issues/issue-3154.stderr +++ b/tests/ui/issues/issue-3154.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/issue-3154.rs:6:5 | -LL | fn thing<'a,Q>(x: &Q) -> Thing<'a,Q> { - | -- help: add explicit lifetime `'a` to the type of `x`: `&'a Q` LL | Thing { x: x } | ^^^^^^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn thing<'a,Q>(x: &'a Q) -> Thing<'a,Q> { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-40288-2.stderr b/tests/ui/issues/issue-40288-2.stderr index 2c64856b08f8..81cb7cdd51ff 100644 --- a/tests/ui/issues/issue-40288-2.stderr +++ b/tests/ui/issues/issue-40288-2.stderr @@ -1,20 +1,24 @@ error[E0621]: explicit lifetime required in the type of `y` --> $DIR/issue-40288-2.rs:9:5 | -LL | fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T { - | -- help: add explicit lifetime `'a` to the type of `y`: `&'a T` -... LL | out[0] | ^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `y` + | +LL | fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &'a T) -> &'a T { + | ++ error[E0621]: explicit lifetime required in the type of `y` --> $DIR/issue-40288-2.rs:24:5 | -LL | fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T { - | -- help: add explicit lifetime `'a` to the type of `y`: `&'a T` -... LL | out.head | ^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `y` + | +LL | fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &'a T) -> &'a T { + | ++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr index af22078aff59..c524aabfacb8 100644 --- a/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr +++ b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr @@ -1,11 +1,13 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/42701_one_named_and_one_anonymous.rs:10:9 | -LL | fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 { - | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32` -... LL | &*x | ^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn foo2<'a>(a: &'a Foo, x: &'a i32) -> &'a i32 { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr index e202c31214d3..44a542eeeeb6 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr @@ -1,11 +1,13 @@ error[E0621]: explicit lifetime required in the type of `other` --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:11:21 | -LL | fn bar(&self, other: Foo) -> Foo<'a> { - | --- help: add explicit lifetime `'a` to the type of `other`: `Foo<'a>` -... LL | other | ^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `other` + | +LL | fn bar(&self, other: Foo<'a>) -> Foo<'a> { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr index 5518ded0106d..52cf8595448d 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex1-return-one-existing-name-if-else-2.rs:2:16 | -LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { - | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32` LL | if x > y { x } else { y } | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr index c689fa9884a7..fbd9695e85fa 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in parameter type --> $DIR/ex1-return-one-existing-name-if-else-3.rs:2:27 | -LL | fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 { - | --------------- help: add explicit lifetime `'a` to type: `(&'a i32, &'a i32)` LL | if x > y { x } else { y } | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to type + | +LL | fn foo<'a>((x, y): (&'a i32, &'a i32)) -> &'a i32 { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr index 3da50cfbb1d0..c875381c615f 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex1-return-one-existing-name-if-else-using-impl-2.rs:4:15 | -LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { - | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32` LL | if x > y { x } else { y } | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 071bda24ef8d..83cd11baf391 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:7:36 | -LL | fn foo<'a>(&'a self, x: &i32) -> &i32 { - | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32` LL | if true { &self.field } else { x } | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr index 1df0776a51b5..bf09bd26359c 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `y` --> $DIR/ex1-return-one-existing-name-if-else.rs:2:27 | -LL | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { - | ---- help: add explicit lifetime `'a` to the type of `y`: `&'a i32` LL | if x > y { x } else { y } | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `y` + | +LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr index 25a2f4b96f40..f37e1ba00e7e 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/ex2a-push-one-existing-name-2.rs:6:5 | -LL | fn foo<'a>(x: Ref, y: &mut Vec>) { - | -------- help: add explicit lifetime `'a` to the type of `x`: `Ref<'a, i32>` LL | y.push(x); | ^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `x` + | +LL | fn foo<'a>(x: Ref<'a, i32>, y: &mut Vec>) { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr index e2725977d837..c25b4c9921f8 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr @@ -1,11 +1,13 @@ error[E0621]: explicit lifetime required in the type of `y` --> $DIR/ex2a-push-one-existing-name-early-bound.rs:8:5 | -LL | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T) - | -- help: add explicit lifetime `'a` to the type of `y`: `&'a T` -... LL | x.push(y); | ^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `y` + | +LL | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &'a T) + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr index 1025581d5acf..8c7bee4bfc40 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr @@ -1,10 +1,13 @@ error[E0621]: explicit lifetime required in the type of `y` --> $DIR/ex2a-push-one-existing-name.rs:6:5 | -LL | fn foo<'a>(x: &mut Vec>, y: Ref) { - | -------- help: add explicit lifetime `'a` to the type of `y`: `Ref<'a, i32>` LL | x.push(y); | ^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `y` + | +LL | fn foo<'a>(x: &mut Vec>, y: Ref<'a, i32>) { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/noisy-follow-up-erro.stderr b/tests/ui/lifetimes/noisy-follow-up-erro.stderr index 04863badbd1e..eb52147dba4b 100644 --- a/tests/ui/lifetimes/noisy-follow-up-erro.stderr +++ b/tests/ui/lifetimes/noisy-follow-up-erro.stderr @@ -15,11 +15,14 @@ LL | struct Foo<'c, 'd>(&'c (), &'d ()); error[E0621]: explicit lifetime required in the type of `foo` --> $DIR/noisy-follow-up-erro.rs:14:9 | -LL | fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> { - | -------------------- help: add explicit lifetime `'a` to the type of `foo`: `&mut Foo<'_, 'a>` -LL | LL | self.bar().map_err(|()| foo.acc(self))?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `foo` + | +LL - fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> { +LL + fn boom(&self, foo: &mut Foo<'_, 'a>) -> Result<(), &'a ()> { + | error: aborting due to 2 previous errors diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/tests/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 15b36925c47b..05eb611081a4 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -21,11 +21,13 @@ LL | ss.r error[E0621]: explicit lifetime required in the type of `ss` --> $DIR/object-lifetime-default-from-box-error.rs:33:5 | -LL | fn store1<'b>(ss: &mut SomeStruct, b: Box) { - | --------------- help: add explicit lifetime `'b` to the type of `ss`: `&mut SomeStruct<'b>` -... LL | ss.r = b; | ^^^^ lifetime `'b` required + | +help: add explicit lifetime `'b` to the type of `ss` + | +LL | fn store1<'b>(ss: &mut SomeStruct<'b>, b: Box) { + | ++++ error: aborting due to 3 previous errors diff --git a/tests/ui/regions/regions-glb-free-free.stderr b/tests/ui/regions/regions-glb-free-free.stderr index 727669f26835..6ea09e3e1d76 100644 --- a/tests/ui/regions/regions-glb-free-free.stderr +++ b/tests/ui/regions/regions-glb-free-free.stderr @@ -1,8 +1,6 @@ error[E0621]: explicit lifetime required in the type of `s` --> $DIR/regions-glb-free-free.rs:15:13 | -LL | pub fn set_desc(self, s: &str) -> Flag<'a> { - | ---- help: add explicit lifetime `'a` to the type of `s`: `&'a str` LL | / Flag { LL | | name: self.name, LL | | desc: s, @@ -10,6 +8,11 @@ LL | | max_count: self.max_count, LL | | value: self.value LL | | } | |_____________^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `s` + | +LL | pub fn set_desc(self, s: &'a str) -> Flag<'a> { + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-infer-at-fn-not-param.stderr b/tests/ui/regions/regions-infer-at-fn-not-param.stderr index 4c7660276f2d..58ff2586a82c 100644 --- a/tests/ui/regions/regions-infer-at-fn-not-param.stderr +++ b/tests/ui/regions/regions-infer-at-fn-not-param.stderr @@ -2,9 +2,12 @@ error[E0621]: explicit lifetime required in the type of `p` --> $DIR/regions-infer-at-fn-not-param.rs:13:57 | LL | fn take1<'a>(p: Parameterized1) -> Parameterized1<'a> { p } - | -------------- ^ lifetime `'a` required - | | - | help: add explicit lifetime `'a` to the type of `p`: `Parameterized1<'a>` + | ^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `p` + | +LL | fn take1<'a>(p: Parameterized1<'a>) -> Parameterized1<'a> { p } + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 41cb2ee46bb5..0aa33d3b6fb1 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -101,15 +101,17 @@ LL + fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + 'b error[E0621]: explicit lifetime required in the type of `dest` --> $DIR/missing-lifetimes-in-signature.rs:73:5 | -LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - | ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T` -... LL | / move || { LL | | LL | | LL | | *dest = g.get(); LL | | } | |_____^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `dest` + | +LL | fn bat<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a + | ++ error[E0309]: the parameter type `G` may not live long enough --> $DIR/missing-lifetimes-in-signature.rs:85:5 diff --git a/tests/ui/variance/variance-trait-matching.stderr b/tests/ui/variance/variance-trait-matching.stderr index 9c72fe239dde..495669668c55 100644 --- a/tests/ui/variance/variance-trait-matching.stderr +++ b/tests/ui/variance/variance-trait-matching.stderr @@ -1,11 +1,13 @@ error[E0621]: explicit lifetime required in the type of `get` --> $DIR/variance-trait-matching.rs:24:5 | -LL | fn get<'a, G>(get: &G) -> i32 - | -- help: add explicit lifetime `'a` to the type of `get`: `&'a G` -... LL | pick(get, &22) | ^^^^^^^^^^^^^^ lifetime `'a` required + | +help: add explicit lifetime `'a` to the type of `get` + | +LL | fn get<'a, G>(get: &'a G) -> i32 + | ++ error: aborting due to 1 previous error From 1b9d7eab7af9567e9d4289586be4c15da7f56ec9 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Mon, 9 Jun 2025 20:03:21 +0000 Subject: [PATCH 133/183] Mark `core::slice::memchr` as `#[doc(hidden)]` It's purely internal, and not intended to be a public API, even on nightly. This stops it showing up and being misleading in rustdoc search. It also mirrors the (also internal) `core::slice::sort` module. --- library/core/src/slice/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 4f7e14408804..c26bbad087a2 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -21,6 +21,7 @@ use crate::{fmt, hint, ptr, range, slice}; issue = "none", reason = "exposed from core to be reused in std; use the memchr crate" )] +#[doc(hidden)] /// Pure Rust memchr implementation, taken from rust-memchr pub mod memchr; From fea6a2289bd3412da1f61ded1f3825c10a361b53 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 17 Dec 2024 15:42:39 -0600 Subject: [PATCH 134/183] Specify the behavior of `file!` This takes the current behavior of `file!` and documents it so it is safe to make assumptions about. For example, Cargo could provide a `CARGO_RUSTC_CURRENT_DIR` as a base path for `file!`. Example use cases - Being able to look up test assets relative to the current file ([example](https://github.com/rust-lang/cargo/blob/b9026bf654d7fac283465e58b8b76742244ef07d/tests/testsuite/cargo_add/add_basic/mod.rs#L34)) - Inline snapshotting libraries being able to update Rust source code ([example](https://github.com/rust-lang/cargo/blob/b9026bf654d7fac283465e58b8b76742244ef07d/tests/testsuite/alt_registry.rs#L36-L45)) T-libs-api discussed two solutions - `file_absolute!`: - Has less meaning in other build tools like buck2 - Bakes in the assumption that a full path is available (e.g. with trim-paths) - Specifying `file!`s behavior (this PR): - Leaves it to the user to deal with trim-paths - Even though `file!` is currently unspecified, changing it would likely have too large of an impact on the ecosystem at this time. A future possibility is that rustc could have a flag that controls modifies the base path used for `file!`. That seems purely additive with specifying the behavior and we do not want to block on it. It would also likely be too disruptive for Cargo users (as mentioned). However, we tried to keep this in mind when specifying the behavior. --- library/core/src/macros/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index d5efb03cfbcb..b21845a1c169 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1273,6 +1273,19 @@ pub(crate) mod builtin { /// first macro invocation leading up to the invocation of the `file!` /// macro. /// + /// The file name is derived from the crate root's source path passed to the Rust compiler + /// and the sequence the compiler takes to get from the crate root to the + /// module containing `file!`, modified by any flags passed to the Rust compiler (e.g. + /// `--remap-path-prefix`). If the crate's source path is relative, the initial base + /// directory will be the working directory of the Rust compiler. For example, if the source + /// path passed to the compiler is `./src/lib.rs` which has a `mod foo;` with a source path of + /// `src/foo/mod.rs`, then calling `file!` inside `mod foo;` will return `./src/foo/mod.rs`. + /// + /// Future compiler options might make further changes to the behavior of `file!`, + /// including potentially making it entirely empty. Code (e.g. test libraries) + /// relying on `file!` producing an openable file path would be incompatible + /// with such options, and might wish to recommend not using those options. + /// /// # Examples /// /// ``` From 4f0b60aa7146297e2f73f48449ffe7e4f74e679a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Tue, 6 May 2025 18:40:18 +0200 Subject: [PATCH 135/183] Don't create .msi installer for gnullvm hosts WIX toolset works only on Windows hosts and we need to boostrap this host. --- src/bootstrap/src/core/build_steps/dist.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 587fca803746..7aa9e6cc2b53 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1681,7 +1681,8 @@ impl Step for Extended { cmd.run(builder); } - if target.is_windows() { + // FIXME(mati865): `gnullvm` here is temporary, remove it once it can host itself + if target.is_windows() && !target.contains("gnullvm") { let exe = tmp.join("exe"); let _ = fs::remove_dir_all(&exe); From 580a9555d51a5c8e29f4f27f652cf0d6700ea879 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 9 Jun 2025 15:36:48 -0700 Subject: [PATCH 136/183] compiler: Fix reusing same lint on fn ptrs with newly-deprecated ABIs --- .../rustc_hir_analysis/src/check/check.rs | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 064b42413f03..87fac985dcc1 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -37,22 +37,23 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; +fn add_abi_diag_help(abi: ExternAbi, diag: &mut Diag<'_, T>) { + if let ExternAbi::Cdecl { unwind } = abi { + let c_abi = ExternAbi::C { unwind }; + diag.help(format!("use `extern {c_abi}` instead",)); + } else if let ExternAbi::Stdcall { unwind } = abi { + let c_abi = ExternAbi::C { unwind }; + let system_abi = ExternAbi::System { unwind }; + diag.help(format!( + "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \ + use `extern {system_abi}`" + )); + } +} + pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) { // FIXME: this should be checked earlier, e.g. in `rustc_ast_lowering`, to fix // things like #86232. - fn add_help(abi: ExternAbi, diag: &mut Diag<'_, T>) { - if let ExternAbi::Cdecl { unwind } = abi { - let c_abi = ExternAbi::C { unwind }; - diag.help(format!("use `extern {c_abi}` instead",)); - } else if let ExternAbi::Stdcall { unwind } = abi { - let c_abi = ExternAbi::C { unwind }; - let system_abi = ExternAbi::System { unwind }; - diag.help(format!( - "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \ - use `extern {system_abi}`" - )); - } - } match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { AbiMapping::Direct(..) => (), @@ -63,13 +64,13 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi E0570, "`{abi}` is not a supported ABI for the current target", ); - add_help(abi, &mut err); + add_abi_diag_help(abi, &mut err); err.emit(); } AbiMapping::Deprecated(..) => { tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { lint.primary_message("use of calling convention not supported on this target"); - add_help(abi, lint); + add_abi_diag_help(abi, lint); }); } } @@ -80,7 +81,14 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ex // in `check_abi` above. match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { AbiMapping::Direct(..) => (), - AbiMapping::Deprecated(..) | AbiMapping::Invalid => { + // this is not a redundant match arm: these ABIs started linting after reviving this lint + AbiMapping::Deprecated(..) => { + tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { + lint.primary_message("use of calling convention not supported on this target"); + add_abi_diag_help(abi, lint); + }); + } + AbiMapping::Invalid => { tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { lint.primary_message(format!( "the calling convention {abi} is not supported on this target" From 0df01a04fd6951489b327806d31b556aeebc3d2c Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 9 Jun 2025 15:50:01 -0700 Subject: [PATCH 137/183] tests: bless unsupported_calling_conventions linting on some fn_ptrs --- tests/ui/abi/unsupported.aarch64.stderr | 66 +++++++++++---------- tests/ui/abi/unsupported.arm.stderr | 66 +++++++++++---------- tests/ui/abi/unsupported.i686.stderr | 12 ++-- tests/ui/abi/unsupported.riscv32.stderr | 66 +++++++++++---------- tests/ui/abi/unsupported.riscv64.stderr | 66 +++++++++++---------- tests/ui/abi/unsupported.rs | 8 ++- tests/ui/abi/unsupported.x64.stderr | 58 +++++++++--------- tests/ui/abi/unsupported.x64_win.stderr | 78 +++++++++++++------------ 8 files changed, 218 insertions(+), 202 deletions(-) diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index ea645780b0d7..22dca00e3b29 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -114,7 +114,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:119:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -122,35 +122,36 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - -warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 - | -LL | extern "cdecl" {} - | ^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:136:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,7 +161,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,13 +170,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:148:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -184,7 +185,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +194,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +256,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,13 +266,13 @@ LL | extern "cdecl" fn cdecl() {} = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:143:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -368,19 +369,20 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -392,7 +394,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -404,7 +406,7 @@ LL | extern "cdecl-unwind" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -415,7 +417,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -426,7 +428,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -437,7 +439,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index 2c82e2951e22..0ac6d888f8dc 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:119:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -107,35 +107,36 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - -warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 - | -LL | extern "cdecl" {} - | ^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:136:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +146,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,13 +155,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:148:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +170,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +179,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +235,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -244,13 +245,13 @@ LL | extern "cdecl" fn cdecl() {} = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:143:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,19 +337,20 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -360,7 +362,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -372,7 +374,7 @@ LL | extern "cdecl-unwind" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -383,7 +385,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -394,7 +396,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +407,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index d552f9a132cf..4d903b435d87 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -75,7 +75,7 @@ LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | extern "riscv-interrupt-m" fn riscv() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +200,7 @@ LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -211,7 +211,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index a0e2901c759f..ad57a89e4553 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:119:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -107,35 +107,36 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - -warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 - | -LL | extern "cdecl" {} - | ^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:136:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +146,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,13 +155,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:148:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +170,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +179,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +235,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -244,13 +245,13 @@ LL | extern "cdecl" fn cdecl() {} = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:143:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,19 +337,20 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -360,7 +362,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -372,7 +374,7 @@ LL | extern "cdecl-unwind" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -383,7 +385,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -394,7 +396,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +407,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index a0e2901c759f..ad57a89e4553 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:119:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -107,35 +107,36 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - -warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 - | -LL | extern "cdecl" {} - | ^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:136:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +146,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,13 +155,13 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:148:1 + --> $DIR/unsupported.rs:150:1 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +170,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -178,7 +179,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +235,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -244,13 +245,13 @@ LL | extern "cdecl" fn cdecl() {} = help: use `extern "C"` instead error[E0570]: `"vectorcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:141:1 + --> $DIR/unsupported.rs:143:1 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,19 +337,20 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -360,7 +362,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -372,7 +374,7 @@ LL | extern "cdecl-unwind" {} Future breakage diagnostic: warning: the calling convention "vectorcall" is not supported on this target - --> $DIR/unsupported.rs:143:22 + --> $DIR/unsupported.rs:145:22 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -383,7 +385,7 @@ LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -394,7 +396,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +407,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 9ea22ca516b4..43bdfe3ea240 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -110,8 +110,10 @@ extern "stdcall" fn stdcall() {} //[x64_win]~^^ WARN unsupported_calling_conventions //[x64_win]~^^^ WARN this was previously accepted fn stdcall_ptr(f: extern "stdcall" fn()) { - //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions - //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted + //[x64_win]~^ WARN unsupported_calling_conventions + //[x64_win]~| WARN this was previously accepted + //[x64,arm,aarch64,riscv32,riscv64]~^^^ WARN unsupported_fn_ptr_calling_conventions + //[x64,arm,aarch64,riscv32,riscv64]~| WARN this was previously accepted f() } extern "stdcall" {} @@ -127,7 +129,7 @@ extern "cdecl" fn cdecl() {} //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted fn cdecl_ptr(f: extern "cdecl" fn()) { - //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_fn_ptr_calling_conventions + //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^ WARN unsupported_calling_conventions //[x64,x64_win,arm,aarch64,riscv32,riscv64]~^^ WARN this was previously accepted f() } diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 732a5f84f50e..f777fe86e241 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: for more information, see issue #130260 error[E0570]: `"stdcall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:119:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -107,35 +107,36 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: `"stdcall-unwind"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - -warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 - | -LL | extern "cdecl" {} - | ^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 = help: use `extern "C"` instead = note: `#[warn(unsupported_calling_conventions)]` on by default warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:136:1 + | +LL | extern "cdecl" {} + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +146,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -154,7 +155,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +164,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -219,7 +220,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +230,7 @@ LL | extern "cdecl" fn cdecl() {} = help: use `extern "C"` instead error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -315,19 +316,20 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -339,7 +341,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -351,7 +353,7 @@ LL | extern "cdecl-unwind" {} Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -362,7 +364,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -373,7 +375,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr index 5597440d5d91..328f4c3b0433 100644 --- a/tests/ui/abi/unsupported.x64_win.stderr +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -89,28 +89,29 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: the calling convention "stdcall" is not supported on this target +warning: use of calling convention not supported on this target --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - -warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:117:1 - | -LL | extern "stdcall" {} - | ^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #137018 = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` = note: `#[warn(unsupported_calling_conventions)]` on by default warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:119:1 + | +LL | extern "stdcall" {} + | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,17 +120,18 @@ LL | extern "stdcall-unwind" {} = note: for more information, see issue #137018 = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 + = note: for more information, see issue #137018 + = help: use `extern "C"` instead warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -139,7 +141,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +151,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +160,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = note: for more information, see issue #130260 warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,13 +169,13 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { = note: for more information, see issue #130260 error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:164:1 + --> $DIR/unsupported.rs:166:1 | LL | extern "C-cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:169:1 + --> $DIR/unsupported.rs:171:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -235,7 +237,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -245,7 +247,7 @@ LL | extern "cdecl" fn cdecl() {} = help: use `extern "C"` instead error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:157:1 + --> $DIR/unsupported.rs:159:1 | LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -320,19 +322,20 @@ LL | fn thiscall_ptr(f: extern "thiscall" fn()) { = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "stdcall" is not supported on this target +warning: use of calling convention not supported on this target --> $DIR/unsupported.rs:112:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:117:1 + --> $DIR/unsupported.rs:119:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -344,7 +347,7 @@ LL | extern "stdcall" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:121:1 + --> $DIR/unsupported.rs:123:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -355,19 +358,20 @@ LL | extern "stdcall-unwind" {} = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: -warning: the calling convention "cdecl" is not supported on this target - --> $DIR/unsupported.rs:129:17 +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:131:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #130260 - = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default + = note: for more information, see issue #137018 + = help: use `extern "C"` instead + = note: `#[warn(unsupported_calling_conventions)]` on by default Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:134:1 + --> $DIR/unsupported.rs:136:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -379,7 +383,7 @@ LL | extern "cdecl" {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:137:1 + --> $DIR/unsupported.rs:139:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +395,7 @@ LL | extern "cdecl-unwind" {} Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target - --> $DIR/unsupported.rs:151:21 + --> $DIR/unsupported.rs:153:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -402,7 +406,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { Future breakage diagnostic: warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target - --> $DIR/unsupported.rs:159:22 + --> $DIR/unsupported.rs:161:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -413,7 +417,7 @@ LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:169:1 + --> $DIR/unsupported.rs:171:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -437,7 +441,7 @@ LL | extern "stdcall" fn stdcall() {} Future breakage diagnostic: warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:126:1 + --> $DIR/unsupported.rs:128:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ From 643a9d233b4f1547220134daea4bcca809302d40 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 6 Jun 2025 15:19:08 -0700 Subject: [PATCH 138/183] tests: Change "fastcall" to "system" in some tests Lets the test still work on different architectures. --- tests/debuginfo/type-names.rs | 4 ++-- tests/incremental/hashes/trait_defs.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs index 3c7eab7e8d71..ac61fef48fe1 100644 --- a/tests/debuginfo/type-names.rs +++ b/tests/debuginfo/type-names.rs @@ -19,7 +19,7 @@ // gdb-check:type = type_names::GenericStruct // gdb-command:whatis generic_struct2 -// gdb-check:type = type_names::GenericStruct usize> +// gdb-check:type = type_names::GenericStruct usize> // gdb-command:whatis mod_struct // gdb-check:type = type_names::mod1::Struct2 @@ -379,7 +379,7 @@ fn main() { let simple_struct = Struct1; let generic_struct1: GenericStruct = GenericStruct(PhantomData); - let generic_struct2: GenericStruct usize> = + let generic_struct2: GenericStruct usize> = GenericStruct(PhantomData); let mod_struct = mod1::Struct2; diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index cb8716d90b07..7141ddb0d7ed 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -440,7 +440,7 @@ trait TraitAddExternModifier { // Change extern "C" to extern "stdcall" #[cfg(any(cfail1,cfail4))] -trait TraitChangeExternCToRustIntrinsic { +trait TraitChangeExternCToExternSystem { // -------------------------------------------------------------- // ------------------------- // -------------------------------------------------------------- @@ -458,7 +458,7 @@ trait TraitChangeExternCToRustIntrinsic { #[rustc_clean(cfg="cfail3")] #[rustc_clean(except="opt_hir_owner_nodes,fn_sig", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] - extern "stdcall" fn method(); + extern "system" fn method(); } From 518eb0d5dd9ba822795fc5bc8e434e7139b0acbd Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 2 Jun 2025 07:20:42 -0700 Subject: [PATCH 139/183] rustdoc-json: Rearrange deck chairs in ABI testing We move the vectorcall ABI tests into their own file which is now only run on x86-64, while replacing them with rust-cold ABI tests so that aarch64 hosts continue to test an unstable ABI. A better solution might be cross-compiling or something but I really don't have time for that right now. --- tests/rustdoc-json/fn_pointer/abi.rs | 9 +++------ tests/rustdoc-json/fns/abi.rs | 9 +++------ tests/rustdoc-json/methods/abi.rs | 17 +++++------------ tests/rustdoc-json/vectorcall.rs | 27 +++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 tests/rustdoc-json/vectorcall.rs diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs index 34150c0fe89e..ec76e0f66362 100644 --- a/tests/rustdoc-json/fn_pointer/abi.rs +++ b/tests/rustdoc-json/fn_pointer/abi.rs @@ -1,4 +1,4 @@ -#![feature(abi_vectorcall)] +#![feature(rust_cold_cc)] //@ is "$.index[?(@.name=='AbiRust')].inner.type_alias.type.function_pointer.header.abi" \"Rust\" pub type AbiRust = fn(); @@ -15,8 +15,5 @@ pub type AbiCUnwind = extern "C-unwind" fn(); //@ is "$.index[?(@.name=='AbiSystemUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": true}}' pub type AbiSystemUnwind = extern "system-unwind" fn(); -//@ is "$.index[?(@.name=='AbiVecorcall')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall\""' -pub type AbiVecorcall = extern "vectorcall" fn(); - -//@ is "$.index[?(@.name=='AbiVecorcallUnwind')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall-unwind\""' -pub type AbiVecorcallUnwind = extern "vectorcall-unwind" fn(); +//@ is "$.index[?(@.name=='AbiRustCold')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"rust-cold\""' +pub type AbiRustCold = extern "rust-cold" fn(); diff --git a/tests/rustdoc-json/fns/abi.rs b/tests/rustdoc-json/fns/abi.rs index 7277bb1f59a4..3373d135c89d 100644 --- a/tests/rustdoc-json/fns/abi.rs +++ b/tests/rustdoc-json/fns/abi.rs @@ -1,4 +1,4 @@ -#![feature(abi_vectorcall)] +#![feature(rust_cold_cc)] //@ is "$.index[?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\" pub fn abi_rust() {} @@ -15,8 +15,5 @@ pub extern "C-unwind" fn abi_c_unwind() {} //@ is "$.index[?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' pub extern "system-unwind" fn abi_system_unwind() {} -//@ is "$.index[?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' -pub extern "vectorcall" fn abi_vectorcall() {} - -//@ is "$.index[?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' -pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {} +//@ is "$.index[?(@.name=='abi_rust_cold')].inner.function.header.abi.Other" '"\"rust-cold\""' +pub extern "rust-cold" fn abi_rust_cold() {} diff --git a/tests/rustdoc-json/methods/abi.rs b/tests/rustdoc-json/methods/abi.rs index fa2387ddf67a..be6a11784f55 100644 --- a/tests/rustdoc-json/methods/abi.rs +++ b/tests/rustdoc-json/methods/abi.rs @@ -1,5 +1,4 @@ -#![feature(abi_vectorcall)] - +#![feature(rust_cold_cc)] //@ has "$.index[?(@.name=='Foo')]" pub struct Foo; @@ -19,11 +18,8 @@ impl Foo { //@ is "$.index[?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' pub extern "system-unwind" fn abi_system_unwind() {} - //@ is "$.index[?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' - pub extern "vectorcall" fn abi_vectorcall() {} - - //@ is "$.index[?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' - pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {} + //@ is "$.index[?(@.name=='abi_rust_cold')].inner.function.header.abi.Other" '"\"rust-cold\""' + pub extern "rust-cold" fn abi_rust_cold() {} } pub trait Bar { @@ -42,9 +38,6 @@ pub trait Bar { //@ is "$.index[?(@.name=='trait_abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' extern "system-unwind" fn trait_abi_system_unwind() {} - //@ is "$.index[?(@.name=='trait_abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' - extern "vectorcall" fn trait_abi_vectorcall() {} - - //@ is "$.index[?(@.name=='trait_abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' - extern "vectorcall-unwind" fn trait_abi_vectorcall_unwind() {} + //@ is "$.index[?(@.name=='trait_abi_rust_cold')].inner.function.header.abi.Other" '"\"rust-cold\""' + extern "rust-cold" fn trait_abi_rust_cold() {} } diff --git a/tests/rustdoc-json/vectorcall.rs b/tests/rustdoc-json/vectorcall.rs new file mode 100644 index 000000000000..19cac244f422 --- /dev/null +++ b/tests/rustdoc-json/vectorcall.rs @@ -0,0 +1,27 @@ +#![feature(abi_vectorcall)] +//@ only-x86_64 + +//@ is "$.index[?(@.name=='AbiVectorcall')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall\""' +pub type AbiVectorcall = extern "vectorcall" fn(); + +//@ is "$.index[?(@.name=='AbiVectorcallUnwind')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall-unwind\""' +pub type AbiVectorcallUnwind = extern "vectorcall-unwind" fn(); + +//@ has "$.index[?(@.name=='Foo')]" +pub struct Foo; + +impl Foo { + //@ is "$.index[?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' + pub extern "vectorcall" fn abi_vectorcall() {} + + //@ is "$.index[?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' + pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {} +} + +pub trait Bar { + //@ is "$.index[?(@.name=='trait_abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' + extern "vectorcall" fn trait_abi_vectorcall() {} + + //@ is "$.index[?(@.name=='trait_abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' + extern "vectorcall-unwind" fn trait_abi_vectorcall_unwind() {} +} From 856c9971fd374afef057257f086814997c72a9b3 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Tue, 10 Jun 2025 00:39:07 +0000 Subject: [PATCH 140/183] rustdoc: Refractor `clean_ty_generics` --- src/librustdoc/clean/auto_trait.rs | 4 +- src/librustdoc/clean/blanket_impl.rs | 6 +-- src/librustdoc/clean/inline.rs | 69 ++++------------------------ src/librustdoc/clean/mod.rs | 14 +++--- 4 files changed, 19 insertions(+), 74 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 138ac3c97f7b..a91ea55bcae6 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -11,7 +11,7 @@ use tracing::{debug, instrument}; use crate::clean::{ self, Lifetime, clean_generic_param_def, clean_middle_ty, clean_predicate, - clean_trait_ref_with_constraints, clean_ty_generics, simplify, + clean_trait_ref_with_constraints, clean_ty_generics_inner, simplify, }; use crate::core::DocContext; @@ -101,7 +101,7 @@ fn synthesize_auto_trait_impl<'tcx>( // Instead, we generate `impl !Send for Foo`, which better // expresses the fact that `Foo` never implements `Send`, // regardless of the choice of `T`. - let mut generics = clean_ty_generics( + let mut generics = clean_ty_generics_inner( cx, tcx.generics_of(item_def_id), ty::GenericPredicates::default(), diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 89245fee5155..c889f52b789a 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -90,11 +90,7 @@ pub(crate) fn synthesize_blanket_impls( stability: None, kind: clean::ImplItem(Box::new(clean::Impl { safety: hir::Safety::Safe, - generics: clean_ty_generics( - cx, - tcx.generics_of(impl_def_id), - tcx.explicit_predicates_of(impl_def_id), - ), + generics: clean_ty_generics(cx, impl_def_id), // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. trait_: Some(clean_trait_ref_with_constraints( diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 55a116a018a8..9b5491310b42 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -264,16 +264,13 @@ pub(crate) fn build_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait { .map(|item| clean_middle_assoc_item(item, cx)) .collect(); - let predicates = cx.tcx.predicates_of(did); - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); - let generics = filter_non_trait_generics(did, generics); + let generics = clean_ty_generics(cx, did); let (generics, supertrait_bounds) = separate_self_bounds(generics); clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } } fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias { - let predicates = cx.tcx.predicates_of(did); - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + let generics = clean_ty_generics(cx, did); let (generics, bounds) = separate_self_bounds(generics); clean::TraitAlias { generics, bounds } } @@ -281,8 +278,7 @@ fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias { pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box { let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); // The generics need to be cleaned before the signature. - let mut generics = - clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id)); + let mut generics = clean_ty_generics(cx, def_id); let bound_vars = clean_bound_vars(sig.bound_vars()); // At the time of writing early & late-bound params are stored separately in rustc, @@ -311,30 +307,26 @@ pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box, did: DefId) -> clean::Enum { - let predicates = cx.tcx.explicit_predicates_of(did); - clean::Enum { - generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), + generics: clean_ty_generics(cx, did), variants: cx.tcx.adt_def(did).variants().iter().map(|v| clean_variant_def(v, cx)).collect(), } } fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct { - let predicates = cx.tcx.explicit_predicates_of(did); let variant = cx.tcx.adt_def(did).non_enum_variant(); clean::Struct { ctor_kind: variant.ctor_kind(), - generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), + generics: clean_ty_generics(cx, did), fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(), } } fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { - let predicates = cx.tcx.explicit_predicates_of(did); let variant = cx.tcx.adt_def(did).non_enum_variant(); - let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); + let generics = clean_ty_generics(cx, did); let fields = variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(); clean::Union { generics, fields } } @@ -344,14 +336,13 @@ fn build_type_alias( did: DefId, ret: &mut Vec, ) -> Box { - let predicates = cx.tcx.explicit_predicates_of(did); let ty = cx.tcx.type_of(did).instantiate_identity(); let type_ = clean_middle_ty(ty::Binder::dummy(ty), cx, Some(did), None); let inner_type = clean_ty_alias_inner_type(ty, cx, ret); Box::new(clean::TypeAlias { type_, - generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), + generics: clean_ty_generics(cx, did), inner_type, item_type: None, }) @@ -483,7 +474,6 @@ pub(crate) fn build_impl( } let document_hidden = cx.render_options.document_hidden; - let predicates = tcx.explicit_predicates_of(did); let (trait_items, generics) = match impl_item { Some(impl_) => ( impl_ @@ -549,9 +539,7 @@ pub(crate) fn build_impl( }) .map(|item| clean_middle_assoc_item(item, cx)) .collect::>(), - clean::enter_impl_trait(cx, |cx| { - clean_ty_generics(cx, tcx.generics_of(did), predicates) - }), + clean::enter_impl_trait(cx, |cx| clean_ty_generics(cx, did)), ), }; let polarity = tcx.impl_polarity(did); @@ -713,8 +701,7 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { } fn build_const_item(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { - let mut generics = - clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id)); + let mut generics = clean_ty_generics(cx, def_id); clean::simplify::move_bounds_to_generic_parameters(&mut generics); let ty = clean_middle_ty( ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()), @@ -761,44 +748,6 @@ fn build_macro( } } -/// A trait's generics clause actually contains all of the predicates for all of -/// its associated types as well. We specifically move these clauses to the -/// associated types instead when displaying, so when we're generating the -/// generics for the trait itself we need to be sure to remove them. -/// We also need to remove the implied "recursive" Self: Trait bound. -/// -/// The inverse of this filtering logic can be found in the `Clean` -/// implementation for `AssociatedType` -fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics { - for pred in &mut g.where_predicates { - if let clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref mut bounds, .. } = - *pred - { - bounds.retain(|bound| match bound { - clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => { - trait_.def_id() != trait_did - } - _ => true, - }); - } - } - - g.where_predicates.retain(|pred| match pred { - clean::WherePredicate::BoundPredicate { - ty: - clean::QPath(box clean::QPathData { - self_type: clean::Generic(_), - trait_: Some(trait_), - .. - }), - bounds, - .. - } => !bounds.is_empty() && trait_.def_id() != trait_did, - _ => true, - }); - g -} - fn separate_self_bounds(mut g: clean::Generics) -> (clean::Generics, Vec) { let mut ty_bounds = Vec::new(); g.where_predicates.retain(|pred| match *pred { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7658e7ad35f3..db4bcdaeb6c1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -793,7 +793,11 @@ pub(crate) fn clean_generics<'tcx>( } } -fn clean_ty_generics<'tcx>( +fn clean_ty_generics<'tcx>(cx: &mut DocContext<'tcx>, def_id: DefId) -> Generics { + clean_ty_generics_inner(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id)) +} + +fn clean_ty_generics_inner<'tcx>( cx: &mut DocContext<'tcx>, gens: &ty::Generics, preds: ty::GenericPredicates<'tcx>, @@ -1297,11 +1301,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo None, ); - let mut generics = clean_ty_generics( - cx, - tcx.generics_of(assoc_item.def_id), - tcx.explicit_predicates_of(assoc_item.def_id), - ); + let mut generics = clean_ty_generics(cx, assoc_item.def_id); simplify::move_bounds_to_generic_parameters(&mut generics); match assoc_item.container { @@ -1389,7 +1389,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied(); predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); } - let mut generics = clean_ty_generics( + let mut generics = clean_ty_generics_inner( cx, tcx.generics_of(assoc_item.def_id), ty::GenericPredicates { parent: None, predicates }, From 5eb5f2a2269c1f83a65cde57fb0ce0562d931be3 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 10 Jun 2025 04:55:12 +0000 Subject: [PATCH 141/183] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index c8721bb36001..43632bf86a73 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c31cccb7b5cc098b1a8c1794ed38d7fdbec0ccb0 +c6768de2d63de7a41124a0fb8fc78f9e26111c01 From 89db7778d664a88d679ce3a58dbba208dd180629 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 10 Jun 2025 05:03:44 +0000 Subject: [PATCH 142/183] fmt --- src/tools/miri/tests/pass/float.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 7ce0bc88517e..c08a5d9ddaad 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -45,7 +45,6 @@ macro_rules! assert_approx_eq { }; } - /// From IEEE 754 a Signaling NaN for single precision has the following representation: /// ``` /// s | 1111 1111 | 0x..x From 7d7fedbab4bd4ff030ac98640f2f18f94041d433 Mon Sep 17 00:00:00 2001 From: kiseitai3 Date: Fri, 6 Jun 2025 21:39:11 -0400 Subject: [PATCH 143/183] docs: Small clarification on the usage of read_to_string and read_to_end trait methods --- library/std/src/io/mod.rs | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 03f5f838311a..23b826291ffd 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -917,6 +917,19 @@ pub trait Read { /// # } /// ``` /// + /// # Usage Notes + /// + /// `read_to_end` attempts to read a source until EOF, but many sources are continuous streams + /// that do not send EOF. In these cases, `read_to_end` will block indefinitely. Standard input + /// is one such stream which may be finite if piped, but is typically continuous. For example, + /// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat. + /// Reading user input or running programs that remain open indefinitely will never terminate + /// the stream with `EOF` (e.g. `yes | my-rust-program`). + /// + /// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution + /// + ///[`read`]: Read::read + /// /// [`Vec::try_reserve`]: crate::vec::Vec::try_reserve #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec) -> Result { @@ -960,6 +973,19 @@ pub trait Read { /// (See also the [`std::fs::read_to_string`] convenience function for /// reading from a file.) /// + /// # Usage Notes + /// + /// `read_to_string` attempts to read a source until EOF, but many sources are continuous streams + /// that do not send EOF. In these cases, `read_to_string` will block indefinitely. Standard input + /// is one such stream which may be finite if piped, but is typically continuous. For example, + /// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat. + /// Reading user input or running programs that remain open indefinitely will never terminate + /// the stream with `EOF` (e.g. `yes | my-rust-program`). + /// + /// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution + /// + ///[`read`]: Read::read + /// /// [`std::fs::read_to_string`]: crate::fs::read_to_string #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result { @@ -1262,6 +1288,20 @@ pub trait Read { /// Ok(()) /// } /// ``` +/// +/// # Usage Notes +/// +/// `read_to_string` attempts to read a source until EOF, but many sources are continuous streams +/// that do not send EOF. In these cases, `read_to_string` will block indefinitely. Standard input +/// is one such stream which may be finite if piped, but is typically continuous. For example, +/// `cat file | my-rust-program` will correctly terminate with an `EOF` upon closure of cat. +/// Reading user input or running programs that remain open indefinitely will never terminate +/// the stream with `EOF` (e.g. `yes | my-rust-program`). +/// +/// Using `.lines()` with a [`BufReader`] or using [`read`] can provide a better solution +/// +///[`read`]: Read::read +/// #[stable(feature = "io_read_to_string", since = "1.65.0")] pub fn read_to_string(mut reader: R) -> Result { let mut buf = String::new(); From cb3d074f6a21f0c5ae36d811bfbe0c10578680ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 10 Jun 2025 08:00:13 +0200 Subject: [PATCH 144/183] Only run `citool` tests on the `auto` branch --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5054a075676..841bc39bf1e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,12 +64,18 @@ jobs: uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8 with: workspaces: src/ci/citool + - name: Test citool + # Only test citool on the auto branch, to reduce latency of the calculate matrix job + # on PR/try builds. + if: ${{ github.ref == 'refs/heads/auto' }} + run: | + cd src/ci/citool + CARGO_INCREMENTAL=0 cargo test - name: Calculate the CI job matrix env: COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: | cd src/ci/citool - CARGO_INCREMENTAL=0 cargo test CARGO_INCREMENTAL=0 cargo run calculate-job-matrix >> $GITHUB_OUTPUT id: jobs job: From fceb8d65107cb081bed799050519ec805ddb8ef7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 10 Jun 2025 08:10:16 +0200 Subject: [PATCH 145/183] sync max_fundamental_align with alloc crate --- src/tools/miri/src/shims/alloc.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index d7bb16f0858d..f05c5fbbe1d4 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -15,11 +15,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is given by `alignof(max_align_t)`. The following list is taken from // `library/std/src/sys/alloc/mod.rs` (where this is called `MIN_ALIGN`) and should // be kept in sync. + let os = this.tcx.sess.target.os.as_ref(); let max_fundamental_align = match this.tcx.sess.target.arch.as_ref() { - "x86" | "arm" | "loongarch32" | "mips" | "mips32r6" | "powerpc" | "powerpc64" - | "wasm32" => 8, - "x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" => - 16, + "riscv32" if matches!(os, "espidf" | "zkvm") => 4, + "xtensa" if matches!(os, "espidf") => 4, + "x86" | "arm" | "m68k" | "csky" | "loongarch32" | "mips" | "mips32r6" | "powerpc" + | "powerpc64" | "sparc" | "wasm32" | "hexagon" | "riscv32" | "xtensa" => 8, + "x86_64" | "aarch64" | "arm64ec" | "loongarch64" | "mips64" | "mips64r6" | "s390x" + | "sparc64" | "riscv64" | "wasm64" => 16, arch => bug!("unsupported target architecture for malloc: `{}`", arch), }; // The C standard only requires sufficient alignment for any *type* with size less than or From 3e980d5f643f840bef74ac96bd657b2a6d7fe71a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 10 Jun 2025 08:45:12 +0200 Subject: [PATCH 146/183] add SmallVec test --- .../miri/tests/pass/both_borrows/smallvec.rs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/tools/miri/tests/pass/both_borrows/smallvec.rs diff --git a/src/tools/miri/tests/pass/both_borrows/smallvec.rs b/src/tools/miri/tests/pass/both_borrows/smallvec.rs new file mode 100644 index 000000000000..f48815e37be3 --- /dev/null +++ b/src/tools/miri/tests/pass/both_borrows/smallvec.rs @@ -0,0 +1,99 @@ +//! This test represents a core part of `SmallVec`'s `extend_impl`. +//! What makes it interesting as a test is that it relies on Stacked Borrow's "quirk" +//! in a fundamental, hard-to-fix-without-full-trees way. + +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +use std::marker::PhantomData; +use std::mem::{ManuallyDrop, MaybeUninit}; +use std::ptr::NonNull; + +#[repr(C)] +pub union RawSmallVec { + inline: ManuallyDrop>, + heap: (NonNull, usize), +} + +impl RawSmallVec { + const fn new() -> Self { + Self::new_inline(MaybeUninit::uninit()) + } + + const fn new_inline(inline: MaybeUninit<[T; N]>) -> Self { + Self { inline: ManuallyDrop::new(inline) } + } + + const fn as_mut_ptr_inline(&mut self) -> *mut T { + (unsafe { &raw mut self.inline }) as *mut T + } + + const unsafe fn as_mut_ptr_heap(&mut self) -> *mut T { + self.heap.0.as_ptr() + } +} + +#[repr(transparent)] +#[derive(Clone, Copy)] +struct TaggedLen(usize); + +impl TaggedLen { + pub const fn new(len: usize, on_heap: bool, is_zst: bool) -> Self { + if is_zst { + debug_assert!(!on_heap); + TaggedLen(len) + } else { + debug_assert!(len < isize::MAX as usize); + TaggedLen((len << 1) | on_heap as usize) + } + } + + pub const fn on_heap(self, is_zst: bool) -> bool { + if is_zst { false } else { (self.0 & 1_usize) == 1 } + } + + pub const fn value(self, is_zst: bool) -> usize { + if is_zst { self.0 } else { self.0 >> 1 } + } +} + +#[repr(C)] +pub struct SmallVec { + len: TaggedLen, + raw: RawSmallVec, + _marker: PhantomData, +} + +impl SmallVec { + pub const fn new() -> SmallVec { + Self { + len: TaggedLen::new(0, false, Self::is_zst()), + raw: RawSmallVec::new(), + _marker: PhantomData, + } + } + + const fn is_zst() -> bool { + size_of::() == 0 + } + + pub const fn as_mut_ptr(&mut self) -> *mut T { + if self.len.on_heap(Self::is_zst()) { + // SAFETY: see above + unsafe { self.raw.as_mut_ptr_heap() } + } else { + self.raw.as_mut_ptr_inline() + } + } + + pub const fn len(&self) -> usize { + self.len.value(Self::is_zst()) + } +} + +fn main() { + let mut v = SmallVec::::new(); + let ptr = v.as_mut_ptr(); + let _len = v.len(); // this call incurs a reborrow which just barely does not invalidate `ptr` + unsafe { ptr.write(0) }; +} From 8808a9c17ff8b41b3ac6d6f10be79d0325e356d4 Mon Sep 17 00:00:00 2001 From: Jubilee Date: Mon, 9 Jun 2025 23:48:33 -0700 Subject: [PATCH 147/183] hir_analysis: Elaborate on lint strategy for unsupported ABIs Co-authored-by: Ralf Jung --- compiler/rustc_hir_analysis/src/check/check.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 87fac985dcc1..60ca0155bdd5 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -81,7 +81,9 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ex // in `check_abi` above. match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) { AbiMapping::Direct(..) => (), - // this is not a redundant match arm: these ABIs started linting after reviving this lint + // This is not a redundant match arm: these ABIs started linting after introducing + // UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS already existed and we want to + // avoid expanding the scope of that lint so it can move to a hard error sooner. AbiMapping::Deprecated(..) => { tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { lint.primary_message("use of calling convention not supported on this target"); From a7153db254acc387e271e75153bdbd3caa2bed89 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Jun 2025 22:24:58 +0200 Subject: [PATCH 148/183] float tests: test non-determinism for more operations --- src/tools/miri/tests/pass/float.rs | 47 ++++++++++++++++-------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index c08a5d9ddaad..383579198bbe 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1386,7 +1386,6 @@ fn test_non_determinism() { frem_algebraic, frem_fast, fsub_algebraic, fsub_fast, }; use std::{f32, f64}; - // TODO: Also test powi and powf when the non-determinism is implemented for them /// Ensure that the operation is non-deterministic #[track_caller] @@ -1426,21 +1425,23 @@ fn test_non_determinism() { } pub fn test_operations_f32(a: f32, b: f32) { test_operations_f!(a, b); - // FIXME: temporarily disabled as it breaks std tests. - // ensure_nondet(|| a.log(b)); - // ensure_nondet(|| a.exp()); - // ensure_nondet(|| 10f32.exp2()); - // ensure_nondet(|| f32::consts::E.ln()); + // FIXME: some are temporarily disabled as it breaks std tests. + ensure_nondet(|| a.powf(b)); + ensure_nondet(|| a.powi(2)); + ensure_nondet(|| a.log(b)); + ensure_nondet(|| a.exp()); + ensure_nondet(|| 10f32.exp2()); + ensure_nondet(|| f32::consts::E.ln()); + ensure_nondet(|| 10f32.log10()); + ensure_nondet(|| 8f32.log2()); // ensure_nondet(|| 1f32.ln_1p()); - // ensure_nondet(|| 10f32.log10()); - // ensure_nondet(|| 8f32.log2()); // ensure_nondet(|| 27.0f32.cbrt()); // ensure_nondet(|| 3.0f32.hypot(4.0f32)); - // ensure_nondet(|| 1f32.sin()); - // ensure_nondet(|| 0f32.cos()); - // // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version, - // // which means the little rounding errors Miri introduces are discard by the cast down to `f32`. - // // Just skip the test for them. + ensure_nondet(|| 1f32.sin()); + ensure_nondet(|| 1f32.cos()); + // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version, + // which means the little rounding errors Miri introduces are discarded by the cast down to + // `f32`. Just skip the test for them. // if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) { // ensure_nondet(|| 1.0f32.tan()); // ensure_nondet(|| 1.0f32.asin()); @@ -1461,18 +1462,20 @@ fn test_non_determinism() { } pub fn test_operations_f64(a: f64, b: f64) { test_operations_f!(a, b); - // FIXME: temporarily disabled as it breaks std tests. - // ensure_nondet(|| a.log(b)); - // ensure_nondet(|| a.exp()); - // ensure_nondet(|| 50f64.exp2()); - // ensure_nondet(|| 3f64.ln()); + // FIXME: some are temporarily disabled as it breaks std tests. + ensure_nondet(|| a.powf(b)); + ensure_nondet(|| a.powi(2)); + ensure_nondet(|| a.log(b)); + ensure_nondet(|| a.exp()); + ensure_nondet(|| 50f64.exp2()); + ensure_nondet(|| 3f64.ln()); + ensure_nondet(|| f64::consts::E.log10()); + ensure_nondet(|| f64::consts::E.log2()); // ensure_nondet(|| 1f64.ln_1p()); - // ensure_nondet(|| f64::consts::E.log10()); - // ensure_nondet(|| f64::consts::E.log2()); // ensure_nondet(|| 27.0f64.cbrt()); // ensure_nondet(|| 3.0f64.hypot(4.0f64)); - // ensure_nondet(|| 1f64.sin()); - // ensure_nondet(|| 0f64.cos()); + ensure_nondet(|| 1f64.sin()); + ensure_nondet(|| 1f64.cos()); // ensure_nondet(|| 1.0f64.tan()); // ensure_nondet(|| 1.0f64.asin()); // ensure_nondet(|| 5.0f64.acos()); From f3af86010b3a084c35a11d347bfca500743209e5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 10 Jun 2025 00:59:09 +0200 Subject: [PATCH 149/183] add a fixme to use `extern_custom` when available --- .../compiler-builtins/src/probestack.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs index c9070cf55c64..16faaa67f8ad 100644 --- a/library/compiler-builtins/compiler-builtins/src/probestack.rs +++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs @@ -125,6 +125,9 @@ macro_rules! define_rust_probestack { // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, // ensuring that if any pages are unmapped we'll make a page fault. // +// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, +// it does not actually match `extern "C"`. +// // The ABI here is that the stack frame size is located in `%rax`. Upon // return we're not supposed to modify `%rsp` or `%rax`. // @@ -260,6 +263,9 @@ core::arch::global_asm!( // that on Unix we're expected to restore everything as it was, this // function basically can't tamper with anything. // +// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, +// it does not actually match `extern "C"`. +// // The ABI here is the same as x86_64, except everything is 32-bits large. core::arch::global_asm!( define_rust_probestack!( @@ -303,6 +309,9 @@ core::arch::global_asm!( // probestack function will also do things like _chkstk in MSVC. // So we need to sub %ax %sp in probestack when arch is x86. // +// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, +// it does not actually match `extern "C"`. +// // REF: Rust commit(74e80468347) // rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805 // Comments in LLVM: From b6eb4f9c3a8c1f2228322095e83c56ea226d0a28 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 4 Jun 2025 01:31:34 +0200 Subject: [PATCH 150/183] use `#[naked]` for `__rust_probestack` --- compiler/rustc_codegen_llvm/src/attributes.rs | 5 +- .../compiler-builtins/src/lib.rs | 1 + .../compiler-builtins/src/probestack.rs | 129 +++++------------- 3 files changed, 36 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 443c2eace554..27fd09745ff0 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -5,6 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; +use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; @@ -256,11 +257,11 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { StackProbeType::Inline => "inline-asm", // Flag our internal `__rust_probestack` function as the stack probe symbol. // This is defined in the `compiler-builtins` crate for each architecture. - StackProbeType::Call => "__rust_probestack", + StackProbeType::Call => &mangle_internal_symbol(cx.tcx, "__rust_probestack"), // Pick from the two above based on the LLVM version. StackProbeType::InlineOrCall { min_llvm_version_for_inline } => { if llvm_util::get_version() < min_llvm_version_for_inline { - "__rust_probestack" + &mangle_internal_symbol(cx.tcx, "__rust_probestack") } else { "inline-asm" } diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index 6a6b28067e8c..6549d4cef9ed 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -8,6 +8,7 @@ #![feature(linkage)] #![feature(naked_functions)] #![feature(repr_simd)] +#![feature(rustc_attrs)] #![cfg_attr(f16_enabled, feature(f16))] #![cfg_attr(f128_enabled, feature(f128))] #![no_builtins] diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs index 16faaa67f8ad..e9a26dff188d 100644 --- a/library/compiler-builtins/compiler-builtins/src/probestack.rs +++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs @@ -49,79 +49,6 @@ // We only define stack probing for these architectures today. #![cfg(any(target_arch = "x86_64", target_arch = "x86"))] -// SAFETY: defined in this module. -// FIXME(extern_custom): the ABI is not correct. -unsafe extern "C" { - pub fn __rust_probestack(); -} - -// A wrapper for our implementation of __rust_probestack, which allows us to -// keep the assembly inline while controlling all CFI directives in the assembly -// emitted for the function. -// -// This is the ELF version. -#[cfg(not(any(target_vendor = "apple", target_os = "uefi")))] -macro_rules! define_rust_probestack { - ($body: expr) => { - concat!( - " - .pushsection .text.__rust_probestack - .globl __rust_probestack - .type __rust_probestack, @function - .hidden __rust_probestack - __rust_probestack: - ", - $body, - " - .size __rust_probestack, . - __rust_probestack - .popsection - " - ) - }; -} - -#[cfg(all(target_os = "uefi", target_arch = "x86_64"))] -macro_rules! define_rust_probestack { - ($body: expr) => { - concat!( - " - .globl __rust_probestack - __rust_probestack: - ", - $body - ) - }; -} - -// Same as above, but for Mach-O. Note that the triple underscore -// is deliberate -#[cfg(target_vendor = "apple")] -macro_rules! define_rust_probestack { - ($body: expr) => { - concat!( - " - .globl ___rust_probestack - ___rust_probestack: - ", - $body - ) - }; -} - -// In UEFI x86 arch, triple underscore is deliberate. -#[cfg(all(target_os = "uefi", target_arch = "x86"))] -macro_rules! define_rust_probestack { - ($body: expr) => { - concat!( - " - .globl ___rust_probestack - ___rust_probestack: - ", - $body - ) - }; -} - // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, // ensuring that if any pages are unmapped we'll make a page fault. // @@ -136,8 +63,10 @@ macro_rules! define_rust_probestack { target_arch = "x86_64", not(all(target_env = "sgx", target_vendor = "fortanix")) ))] -core::arch::global_asm!( - define_rust_probestack!( +#[unsafe(naked)] +#[rustc_std_internal_symbol] +pub unsafe extern "C" fn __rust_probestack() { + core::arch::naked_asm!( " .cfi_startproc pushq %rbp @@ -187,10 +116,10 @@ core::arch::global_asm!( .cfi_adjust_cfa_offset -8 ret .cfi_endproc - " - ), - options(att_syntax) -); + ", + options(att_syntax) + ) +} // This function is the same as above, except that some instructions are // [manually patched for LVI]. @@ -200,8 +129,10 @@ core::arch::global_asm!( target_arch = "x86_64", all(target_env = "sgx", target_vendor = "fortanix") ))] -core::arch::global_asm!( - define_rust_probestack!( +#[unsafe(naked)] +#[no_mangle] +pub unsafe extern "C" fn __rust_probestack() { + core::arch::naked_asm!( " .cfi_startproc pushq %rbp @@ -253,10 +184,10 @@ core::arch::global_asm!( lfence jmp *%r11 .cfi_endproc - " - ), - options(att_syntax) -); + ", + options(att_syntax) + ) +} #[cfg(all(target_arch = "x86", not(target_os = "uefi")))] // This is the same as x86_64 above, only translated for 32-bit sizes. Note @@ -267,8 +198,10 @@ core::arch::global_asm!( // it does not actually match `extern "C"`. // // The ABI here is the same as x86_64, except everything is 32-bits large. -core::arch::global_asm!( - define_rust_probestack!( +#[unsafe(naked)] +#[rustc_std_internal_symbol] +pub unsafe extern "C" fn __rust_probestack() { + core::arch::naked_asm!( " .cfi_startproc push %ebp @@ -299,10 +232,10 @@ core::arch::global_asm!( .cfi_adjust_cfa_offset -4 ret .cfi_endproc - " - ), - options(att_syntax) -); + ", + options(att_syntax) + ) +} #[cfg(all(target_arch = "x86", target_os = "uefi"))] // UEFI target is windows like target. LLVM will do _chkstk things like windows. @@ -318,8 +251,10 @@ core::arch::global_asm!( // MSVC x32's _chkstk and cygwin/mingw's _alloca adjust %esp themselves. // MSVC x64's __chkstk and cygwin/mingw's ___chkstk_ms do not adjust %rsp // themselves. -core::arch::global_asm!( - define_rust_probestack!( +#[unsafe(naked)] +#[rustc_std_internal_symbol] +pub unsafe extern "C" fn __rust_probestack() { + core::arch::naked_asm!( " .cfi_startproc push %ebp @@ -355,7 +290,7 @@ core::arch::global_asm!( .cfi_adjust_cfa_offset -4 ret .cfi_endproc - " - ), - options(att_syntax) -); + ", + options(att_syntax) + ) +} From 45d649e2ea83416cbbcf52e4053163b31c718ed0 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 4 Jun 2025 01:32:04 +0200 Subject: [PATCH 151/183] merge the sgx/fortanix `__rust_probestack` into the general `x86_64` one --- .../compiler-builtins/src/probestack.rs | 96 +++++-------------- 1 file changed, 23 insertions(+), 73 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs index e9a26dff188d..2375107e3d5c 100644 --- a/library/compiler-builtins/compiler-builtins/src/probestack.rs +++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs @@ -57,15 +57,31 @@ // // The ABI here is that the stack frame size is located in `%rax`. Upon // return we're not supposed to modify `%rsp` or `%rax`. -// -// Any changes to this function should be replicated to the SGX version below. -#[cfg(all( - target_arch = "x86_64", - not(all(target_env = "sgx", target_vendor = "fortanix")) -))] +#[cfg(target_arch = "x86_64")] #[unsafe(naked)] #[rustc_std_internal_symbol] pub unsafe extern "C" fn __rust_probestack() { + #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))] + macro_rules! ret { + () => { + "ret" + }; + } + + #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] + macro_rules! ret { + // for this target, [manually patch for LVI]. + // + // [manually patch for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions + () => { + " + pop %r11 + lfence + jmp *%r11 + " + }; + } + core::arch::naked_asm!( " .cfi_startproc @@ -114,75 +130,9 @@ pub unsafe extern "C" fn __rust_probestack() { leave .cfi_def_cfa_register %rsp .cfi_adjust_cfa_offset -8 - ret - .cfi_endproc ", - options(att_syntax) - ) -} - -// This function is the same as above, except that some instructions are -// [manually patched for LVI]. -// -// [manually patched for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions -#[cfg(all( - target_arch = "x86_64", - all(target_env = "sgx", target_vendor = "fortanix") -))] -#[unsafe(naked)] -#[no_mangle] -pub unsafe extern "C" fn __rust_probestack() { - core::arch::naked_asm!( + ret!(), " - .cfi_startproc - pushq %rbp - .cfi_adjust_cfa_offset 8 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp - - mov %rax,%r11 // duplicate %rax as we're clobbering %r11 - - // Main loop, taken in one page increments. We're decrementing rsp by - // a page each time until there's less than a page remaining. We're - // guaranteed that this function isn't called unless there's more than a - // page needed. - // - // Note that we're also testing against `8(%rsp)` to account for the 8 - // bytes pushed on the stack orginally with our return address. Using - // `8(%rsp)` simulates us testing the stack pointer in the caller's - // context. - - // It's usually called when %rax >= 0x1000, but that's not always true. - // Dynamic stack allocation, which is needed to implement unsized - // rvalues, triggers stackprobe even if %rax < 0x1000. - // Thus we have to check %r11 first to avoid segfault. - cmp $0x1000,%r11 - jna 3f -2: - sub $0x1000,%rsp - test %rsp,8(%rsp) - sub $0x1000,%r11 - cmp $0x1000,%r11 - ja 2b - -3: - // Finish up the last remaining stack space requested, getting the last - // bits out of r11 - sub %r11,%rsp - test %rsp,8(%rsp) - - // Restore the stack pointer to what it previously was when entering - // this function. The caller will readjust the stack pointer after we - // return. - add %rax,%rsp - - leave - .cfi_def_cfa_register %rsp - .cfi_adjust_cfa_offset -8 - pop %r11 - lfence - jmp *%r11 .cfi_endproc ", options(att_syntax) From b030442eb692cdbc30d13613db778aefe7397fa7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 4 Jun 2025 01:33:16 +0200 Subject: [PATCH 152/183] indent the probestack inline assembly --- .../compiler-builtins/src/probestack.rs | 196 +++++++++--------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs index 2375107e3d5c..1441fd73b8d6 100644 --- a/library/compiler-builtins/compiler-builtins/src/probestack.rs +++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs @@ -84,56 +84,56 @@ pub unsafe extern "C" fn __rust_probestack() { core::arch::naked_asm!( " - .cfi_startproc - pushq %rbp - .cfi_adjust_cfa_offset 8 - .cfi_offset %rbp, -16 - movq %rsp, %rbp - .cfi_def_cfa_register %rbp + .cfi_startproc + pushq %rbp + .cfi_adjust_cfa_offset 8 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp - mov %rax,%r11 // duplicate %rax as we're clobbering %r11 + mov %rax,%r11 // duplicate %rax as we're clobbering %r11 - // Main loop, taken in one page increments. We're decrementing rsp by - // a page each time until there's less than a page remaining. We're - // guaranteed that this function isn't called unless there's more than a - // page needed. - // - // Note that we're also testing against `8(%rsp)` to account for the 8 - // bytes pushed on the stack orginally with our return address. Using - // `8(%rsp)` simulates us testing the stack pointer in the caller's - // context. + // Main loop, taken in one page increments. We're decrementing rsp by + // a page each time until there's less than a page remaining. We're + // guaranteed that this function isn't called unless there's more than a + // page needed. + // + // Note that we're also testing against `8(%rsp)` to account for the 8 + // bytes pushed on the stack orginally with our return address. Using + // `8(%rsp)` simulates us testing the stack pointer in the caller's + // context. - // It's usually called when %rax >= 0x1000, but that's not always true. - // Dynamic stack allocation, which is needed to implement unsized - // rvalues, triggers stackprobe even if %rax < 0x1000. - // Thus we have to check %r11 first to avoid segfault. - cmp $0x1000,%r11 - jna 3f -2: - sub $0x1000,%rsp - test %rsp,8(%rsp) - sub $0x1000,%r11 - cmp $0x1000,%r11 - ja 2b + // It's usually called when %rax >= 0x1000, but that's not always true. + // Dynamic stack allocation, which is needed to implement unsized + // rvalues, triggers stackprobe even if %rax < 0x1000. + // Thus we have to check %r11 first to avoid segfault. + cmp $0x1000,%r11 + jna 3f + 2: + sub $0x1000,%rsp + test %rsp,8(%rsp) + sub $0x1000,%r11 + cmp $0x1000,%r11 + ja 2b -3: - // Finish up the last remaining stack space requested, getting the last - // bits out of r11 - sub %r11,%rsp - test %rsp,8(%rsp) + 3: + // Finish up the last remaining stack space requested, getting the last + // bits out of r11 + sub %r11,%rsp + test %rsp,8(%rsp) - // Restore the stack pointer to what it previously was when entering - // this function. The caller will readjust the stack pointer after we - // return. - add %rax,%rsp + // Restore the stack pointer to what it previously was when entering + // this function. The caller will readjust the stack pointer after we + // return. + add %rax,%rsp - leave - .cfi_def_cfa_register %rsp - .cfi_adjust_cfa_offset -8 + leave + .cfi_def_cfa_register %rsp + .cfi_adjust_cfa_offset -8 ", ret!(), " - .cfi_endproc + .cfi_endproc ", options(att_syntax) ) @@ -153,35 +153,35 @@ pub unsafe extern "C" fn __rust_probestack() { pub unsafe extern "C" fn __rust_probestack() { core::arch::naked_asm!( " - .cfi_startproc - push %ebp - .cfi_adjust_cfa_offset 4 - .cfi_offset %ebp, -8 - mov %esp, %ebp - .cfi_def_cfa_register %ebp - push %ecx - mov %eax,%ecx + .cfi_startproc + push %ebp + .cfi_adjust_cfa_offset 4 + .cfi_offset %ebp, -8 + mov %esp, %ebp + .cfi_def_cfa_register %ebp + push %ecx + mov %eax,%ecx - cmp $0x1000,%ecx - jna 3f -2: - sub $0x1000,%esp - test %esp,8(%esp) - sub $0x1000,%ecx - cmp $0x1000,%ecx - ja 2b + cmp $0x1000,%ecx + jna 3f + 2: + sub $0x1000,%esp + test %esp,8(%esp) + sub $0x1000,%ecx + cmp $0x1000,%ecx + ja 2b -3: - sub %ecx,%esp - test %esp,8(%esp) + 3: + sub %ecx,%esp + test %esp,8(%esp) - add %eax,%esp - pop %ecx - leave - .cfi_def_cfa_register %esp - .cfi_adjust_cfa_offset -4 - ret - .cfi_endproc + add %eax,%esp + pop %ecx + leave + .cfi_def_cfa_register %esp + .cfi_adjust_cfa_offset -4 + ret + .cfi_endproc ", options(att_syntax) ) @@ -206,40 +206,40 @@ pub unsafe extern "C" fn __rust_probestack() { pub unsafe extern "C" fn __rust_probestack() { core::arch::naked_asm!( " - .cfi_startproc - push %ebp - .cfi_adjust_cfa_offset 4 - .cfi_offset %ebp, -8 - mov %esp, %ebp - .cfi_def_cfa_register %ebp - push %ecx - push %edx - mov %eax,%ecx + .cfi_startproc + push %ebp + .cfi_adjust_cfa_offset 4 + .cfi_offset %ebp, -8 + mov %esp, %ebp + .cfi_def_cfa_register %ebp + push %ecx + push %edx + mov %eax,%ecx - cmp $0x1000,%ecx - jna 3f -2: - sub $0x1000,%esp - test %esp,8(%esp) - sub $0x1000,%ecx - cmp $0x1000,%ecx - ja 2b + cmp $0x1000,%ecx + jna 3f + 2: + sub $0x1000,%esp + test %esp,8(%esp) + sub $0x1000,%ecx + cmp $0x1000,%ecx + ja 2b -3: - sub %ecx,%esp - test %esp,8(%esp) - mov 4(%ebp),%edx - mov %edx, 12(%esp) - add %eax,%esp - pop %edx - pop %ecx - leave + 3: + sub %ecx,%esp + test %esp,8(%esp) + mov 4(%ebp),%edx + mov %edx, 12(%esp) + add %eax,%esp + pop %edx + pop %ecx + leave - sub %eax, %esp - .cfi_def_cfa_register %esp - .cfi_adjust_cfa_offset -4 - ret - .cfi_endproc + sub %eax, %esp + .cfi_def_cfa_register %esp + .cfi_adjust_cfa_offset -4 + ret + .cfi_endproc ", options(att_syntax) ) From b73bf3c0b52d3fa61f0110f3fc867ca69f9f43ae Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 30 May 2025 16:17:48 +0000 Subject: [PATCH 153/183] Add regression test for break inside const items --- .../break-inside-inline-const-issue-128604.rs | 6 ++++++ .../break-inside-inline-const-issue-128604.stderr | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs index a9795d1569c8..cc0d757885de 100644 --- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs @@ -23,3 +23,9 @@ fn main() { } } } + +const FOO: () = break; +//~^ ERROR: `break` outside of a loop or labeled block + +static BAR: () = break; +//~^ ERROR: `break` outside of a loop or labeled block diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr index 300cd45ad691..dcd571a028b9 100644 --- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr @@ -10,6 +10,18 @@ error[E0268]: `break` outside of a loop or labeled block LL | break; | ^^^^^ cannot `break` outside of a loop or labeled block +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-inside-inline-const-issue-128604.rs:27:17 + | +LL | const FOO: () = break; + | ^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-inside-inline-const-issue-128604.rs:30:18 + | +LL | static BAR: () = break; + | ^^^^^ cannot `break` outside of a loop or labeled block + error[E0268]: `break` outside of a loop or labeled block --> $DIR/break-inside-inline-const-issue-128604.rs:2:21 | @@ -34,6 +46,6 @@ LL | LL ~ break 'block; | -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0268`. From 1b9d38dd08d2e09b2ea6b18a0201252203f63e27 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 30 May 2025 16:01:00 +0000 Subject: [PATCH 154/183] Remove check_mod_loops query and run the checks per-body instead --- compiler/rustc_hir_typeck/messages.ftl | 44 ++++++ compiler/rustc_hir_typeck/src/errors.rs | 128 ++++++++++++++++++ compiler/rustc_hir_typeck/src/lib.rs | 9 ++ .../src/loops.rs | 30 +--- compiler/rustc_interface/src/passes.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 5 - compiler/rustc_passes/messages.ftl | 40 ------ compiler/rustc_passes/src/errors.rs | 128 +----------------- compiler/rustc_passes/src/lib.rs | 2 - ...block-control-flow-static-semantics.stderr | 32 ++--- ...ak-inside-inline-const-issue-128604.stderr | 24 ++-- .../cross-const-control-flow-125846.stderr | 20 +-- tests/ui/loops/issue-43162.stderr | 12 +- tests/ui/track-diagnostics/track.stderr | 2 +- 14 files changed, 230 insertions(+), 247 deletions(-) rename compiler/{rustc_passes => rustc_hir_typeck}/src/loops.rs (93%) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 6c33dfb4ec05..3bdd1b48666e 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -17,6 +17,24 @@ hir_typeck_base_expression_double_dot_enable_default_field_values = add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields hir_typeck_base_expression_double_dot_remove = remove the `..` as all the fields are already present +hir_typeck_break_inside_closure = + `{$name}` inside of a closure + .label = cannot `{$name}` inside of a closure + .closure_label = enclosing closure + +hir_typeck_break_inside_coroutine = + `{$name}` inside `{$kind}` {$source} + .label = cannot `{$name}` inside `{$kind}` {$source} + .coroutine_label = enclosing `{$kind}` {$source} + +hir_typeck_break_non_loop = + `break` with value from a `{$kind}` loop + .label = can only break with a value inside `loop` or breakable block + .label2 = you can't `break` with a value in a `{$kind}` loop + .suggestion = use `break` on its own without a value inside this `{$kind}` loop + .break_expr_suggestion = alternatively, you might have meant to use the available loop label + + hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> [NONE] {""} [implement] , perhaps you need to implement it @@ -64,6 +82,12 @@ hir_typeck_const_select_must_be_fn = this argument must be a function item .note = expected a function item, found {$ty} .help = consult the documentation on `const_eval_select` for more information +hir_typeck_continue_labeled_block = + `continue` pointing to a labeled block + .label = labeled blocks cannot be `continue`'d + .block_label = labeled block the `continue` points to + + hir_typeck_convert_to_str = try converting the passed type into a `&str` hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `{$expected}` @@ -182,6 +206,19 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` +hir_typeck_outside_loop = + `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + .label = cannot `{$name}` outside of a loop{$is_break -> + [true] {" or labeled block"} + *[false] {""} + } + +hir_typeck_outside_loop_suggestion = consider labeling this block to be able to break within it + + hir_typeck_params_not_allowed = referencing function parameters is not allowed in naked functions .help = follow the calling convention in asm block to use parameters @@ -254,6 +291,13 @@ hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field +hir_typeck_unlabeled_cf_in_while_condition = + `break` or `continue` with no label in the condition of a `while` loop + .label = unlabeled `{$cf_type}` in the condition of a `while` loop + +hir_typeck_unlabeled_in_labeled_block = + unlabeled `{$cf_type}` inside of a labeled block + .label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label hir_typeck_use_is_empty = consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 97a90548fc54..774815015d54 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -2,11 +2,14 @@ use std::borrow::Cow; +use rustc_ast::Label; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic, }; +use rustc_hir as hir; +use rustc_hir::ExprKind; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; @@ -721,6 +724,131 @@ pub(crate) struct TrivialCast<'tcx> { pub cast_ty: Ty<'tcx>, } +pub(crate) struct BreakNonLoop<'a> { + pub span: Span, + pub head: Option, + pub kind: &'a str, + pub suggestion: String, + pub loop_label: Option