From 78245286dcde9f2cf99a370ec0cd4383fa684404 Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 31 Dec 2022 11:00:54 +0100 Subject: [PATCH 01/47] std: use id-based thread parking on SOLID --- library/std/src/sys/itron/thread_parking.rs | 37 +++++++ library/std/src/sys/itron/wait_flag.rs | 72 ------------- library/std/src/sys/solid/mod.rs | 4 +- .../std/src/sys_common/thread_parking/mod.rs | 4 +- .../sys_common/thread_parking/wait_flag.rs | 102 ------------------ 5 files changed, 40 insertions(+), 179 deletions(-) create mode 100644 library/std/src/sys/itron/thread_parking.rs delete mode 100644 library/std/src/sys/itron/wait_flag.rs delete mode 100644 library/std/src/sys_common/thread_parking/wait_flag.rs diff --git a/library/std/src/sys/itron/thread_parking.rs b/library/std/src/sys/itron/thread_parking.rs new file mode 100644 index 0000000000000..fe9934439d152 --- /dev/null +++ b/library/std/src/sys/itron/thread_parking.rs @@ -0,0 +1,37 @@ +use super::abi; +use super::error::expect_success_aborting; +use super::time::with_tmos; +use crate::time::Duration; + +pub type ThreadId = abi::ID; + +pub use super::task::current_task_id_aborting as current; + +pub fn park(_hint: usize) { + match unsafe { abi::slp_tsk() } { + abi::E_OK | abi::E_RLWAI => {} + err => { + expect_success_aborting(err, &"slp_tsk"); + } + } +} + +pub fn park_timeout(dur: Duration, _hint: usize) { + match with_tmos(dur, |tmo| unsafe { abi::tslp_tsk(tmo) }) { + abi::E_OK | abi::E_RLWAI | abi::E_TMOUT => {} + err => { + expect_success_aborting(err, &"tslp_tsk"); + } + } +} + +pub fn unpark(id: ThreadId, _hint: usize) { + match unsafe { abi::wup_tsk(id) } { + // It is allowed to try to wake up a destroyed or unrelated task, so we ignore all + // errors that could result from that situation. + abi::E_OK | abi::E_NOEXS | abi::E_OBJ | abi::E_QOVR => {} + err => { + expect_success_aborting(err, &"wup_tsk"); + } + } +} diff --git a/library/std/src/sys/itron/wait_flag.rs b/library/std/src/sys/itron/wait_flag.rs deleted file mode 100644 index e432edd207754..0000000000000 --- a/library/std/src/sys/itron/wait_flag.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::mem::MaybeUninit; -use crate::time::Duration; - -use super::{ - abi, - error::{expect_success, fail}, - time::with_tmos, -}; - -const CLEAR: abi::FLGPTN = 0; -const RAISED: abi::FLGPTN = 1; - -/// A thread parking primitive that is not susceptible to race conditions, -/// but provides no atomic ordering guarantees and allows only one `raise` per wait. -pub struct WaitFlag { - flag: abi::ID, -} - -impl WaitFlag { - /// Creates a new wait flag. - pub fn new() -> WaitFlag { - let flag = expect_success( - unsafe { - abi::acre_flg(&abi::T_CFLG { - flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR, - iflgptn: CLEAR, - }) - }, - &"acre_flg", - ); - - WaitFlag { flag } - } - - /// Wait for the wait flag to be raised. - pub fn wait(&self) { - let mut token = MaybeUninit::uninit(); - expect_success( - unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) }, - &"wai_flg", - ); - } - - /// Wait for the wait flag to be raised or the timeout to occur. - /// - /// Returns whether the flag was raised (`true`) or the operation timed out (`false`). - pub fn wait_timeout(&self, dur: Duration) -> bool { - let mut token = MaybeUninit::uninit(); - let res = with_tmos(dur, |tmout| unsafe { - abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout) - }); - - match res { - abi::E_OK => true, - abi::E_TMOUT => false, - error => fail(error, &"twai_flg"), - } - } - - /// Raise the wait flag. - /// - /// Calls to this function should be balanced with the number of successful waits. - pub fn raise(&self) { - expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg"); - } -} - -impl Drop for WaitFlag { - fn drop(&mut self) { - expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg"); - } -} diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs index 5867979a2a729..923d27fd9369d 100644 --- a/library/std/src/sys/solid/mod.rs +++ b/library/std/src/sys/solid/mod.rs @@ -13,9 +13,9 @@ mod itron { pub(super) mod spin; pub(super) mod task; pub mod thread; + pub mod thread_parking; pub(super) mod time; use super::unsupported; - pub mod wait_flag; } pub mod alloc; @@ -43,8 +43,8 @@ pub use self::itron::thread; pub mod memchr; pub mod thread_local_dtor; pub mod thread_local_key; +pub use self::itron::thread_parking; pub mod time; -pub use self::itron::wait_flag; mod rwlock; diff --git a/library/std/src/sys_common/thread_parking/mod.rs b/library/std/src/sys_common/thread_parking/mod.rs index 0ead6633c3501..e8e028bb3308f 100644 --- a/library/std/src/sys_common/thread_parking/mod.rs +++ b/library/std/src/sys_common/thread_parking/mod.rs @@ -14,12 +14,10 @@ cfg_if::cfg_if! { } else if #[cfg(any( target_os = "netbsd", all(target_vendor = "fortanix", target_env = "sgx"), + target_os = "solid_asp3", ))] { mod id; pub use id::Parker; - } else if #[cfg(target_os = "solid_asp3")] { - mod wait_flag; - pub use wait_flag::Parker; } else if #[cfg(any(windows, target_family = "unix"))] { pub use crate::sys::thread_parking::Parker; } else { diff --git a/library/std/src/sys_common/thread_parking/wait_flag.rs b/library/std/src/sys_common/thread_parking/wait_flag.rs deleted file mode 100644 index d0f8899a94eb8..0000000000000 --- a/library/std/src/sys_common/thread_parking/wait_flag.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! A wait-flag-based thread parker. -//! -//! Some operating systems provide low-level parking primitives like wait counts, -//! event flags or semaphores which are not susceptible to race conditions (meaning -//! the wakeup can occur before the wait operation). To implement the `std` thread -//! parker on top of these primitives, we only have to ensure that parking is fast -//! when the thread token is available, the atomic ordering guarantees are maintained -//! and spurious wakeups are minimized. -//! -//! To achieve this, this parker uses an atomic variable with three states: `EMPTY`, -//! `PARKED` and `NOTIFIED`: -//! * `EMPTY` means the token has not been made available, but the thread is not -//! currently waiting on it. -//! * `PARKED` means the token is not available and the thread is parked. -//! * `NOTIFIED` means the token is available. -//! -//! `park` and `park_timeout` change the state from `EMPTY` to `PARKED` and from -//! `NOTIFIED` to `EMPTY`. If the state was `NOTIFIED`, the thread was unparked and -//! execution can continue without calling into the OS. If the state was `EMPTY`, -//! the token is not available and the thread waits on the primitive (here called -//! "wait flag"). -//! -//! `unpark` changes the state to `NOTIFIED`. If the state was `PARKED`, the thread -//! is or will be sleeping on the wait flag, so we raise it. - -use crate::pin::Pin; -use crate::sync::atomic::AtomicI8; -use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; -use crate::sys::wait_flag::WaitFlag; -use crate::time::Duration; - -const EMPTY: i8 = 0; -const PARKED: i8 = -1; -const NOTIFIED: i8 = 1; - -pub struct Parker { - state: AtomicI8, - wait_flag: WaitFlag, -} - -impl Parker { - /// Construct a parker for the current thread. The UNIX parker - /// implementation requires this to happen in-place. - pub unsafe fn new_in_place(parker: *mut Parker) { - parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() }) - } - - // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. - pub unsafe fn park(self: Pin<&Self>) { - match self.state.fetch_sub(1, Acquire) { - // NOTIFIED => EMPTY - NOTIFIED => return, - // EMPTY => PARKED - EMPTY => (), - _ => panic!("inconsistent park state"), - } - - // Avoid waking up from spurious wakeups (these are quite likely, see below). - loop { - self.wait_flag.wait(); - - match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) { - Ok(_) => return, - Err(PARKED) => (), - Err(_) => panic!("inconsistent park state"), - } - } - } - - // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. - pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) { - match self.state.fetch_sub(1, Acquire) { - NOTIFIED => return, - EMPTY => (), - _ => panic!("inconsistent park state"), - } - - self.wait_flag.wait_timeout(dur); - - // Either a wakeup or a timeout occurred. Wakeups may be spurious, as there can be - // a race condition when `unpark` is performed between receiving the timeout and - // resetting the state, resulting in the eventflag being set unnecessarily. `park` - // is protected against this by looping until the token is actually given, but - // here we cannot easily tell. - - // Use `swap` to provide acquire ordering. - match self.state.swap(EMPTY, Acquire) { - NOTIFIED => (), - PARKED => (), - _ => panic!("inconsistent park state"), - } - } - - // This implementation doesn't require `Pin`, but other implementations do. - pub fn unpark(self: Pin<&Self>) { - let state = self.state.swap(NOTIFIED, Release); - - if state == PARKED { - self.wait_flag.raise(); - } - } -} From 640ede7b0a1840415cb6ec881c2210302bfeba18 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 29 Jan 2023 13:50:33 -0500 Subject: [PATCH 02/47] Enable CopyProp by default, tune the impl a bit --- compiler/rustc_middle/src/ty/adt.rs | 1 + compiler/rustc_mir_transform/src/copy_prop.rs | 4 +- compiler/rustc_mir_transform/src/ssa.rs | 43 +++++- tests/codegen/move-operands.rs | 2 +- .../simd-intrinsic-transmute-array.rs | 3 - .../copy-prop/custom_move_arg.f.CopyProp.diff | 30 ++++ tests/mir-opt/copy-prop/custom_move_arg.rs | 32 ++++ ...herit_overflow.main.DataflowConstProp.diff | 12 +- .../inline/inline_generator.main.Inline.diff | 60 ++++---- .../mir-opt/issue_101973.inner.ConstProp.diff | 6 +- ...ue_59352.num_to_digit.PreCodegen.after.mir | 14 +- ...t_switch.identity.SeparateConstSwitch.diff | 64 ++++---- ...s_fixedpoint.foo.SimplifyLocals-final.diff | 7 +- ...filter.variant_a-{closure#0}.CopyProp.diff | 144 +++++++++--------- 14 files changed, 248 insertions(+), 174 deletions(-) create mode 100644 tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff create mode 100644 tests/mir-opt/copy-prop/custom_move_arg.rs diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 099a784511827..f127b6275a21d 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -406,6 +406,7 @@ impl<'tcx> AdtDef<'tcx> { } /// Return the index of `VariantDef` given a variant id. + #[inline] pub fn variant_index_with_id(self, vid: DefId) -> VariantIdx { self.variants() .iter_enumerated() diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index 6e279232bcb48..c57ec137d4b77 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -22,7 +22,7 @@ pub struct CopyProp; impl<'tcx> MirPass<'tcx> for CopyProp { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 4 + sess.mir_opt_level() >= 1 } #[instrument(level = "trace", skip(self, tcx, body))] @@ -96,7 +96,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet { fully_moved } -/// Utility to help performing subtitution of `*pattern` by `target`. +/// Utility to help performing substitution of `*pattern` by `target`. struct Replacer<'a, 'tcx> { tcx: TyCtxt<'tcx>, fully_moved: BitSet, diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index bc3fe65cf6c34..65c15d9c67497 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -19,6 +19,33 @@ pub struct SsaLocals { copy_classes: IndexVec, } +/// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to +/// actually compute dominators, we can just compare block indices because bb0 is always the first +/// block, and in any body all other blocks are always always dominated by bb0. +struct SmallDominators { + inner: Option>, +} + +trait DomExt { + fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool; +} + +impl DomExt for Location { + fn dominates(self, other: Location, dominators: &SmallDominators) -> bool { + if self.block == other.block { + self.statement_index <= other.statement_index + } else { + dominators.dominates(self.block, other.block) + } + } +} + +impl SmallDominators { + fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool { + if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node } + } +} + impl SsaLocals { pub fn new<'tcx>( tcx: TyCtxt<'tcx>, @@ -29,7 +56,9 @@ impl SsaLocals { let assignment_order = Vec::new(); let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls); - let dominators = body.basic_blocks.dominators(); + let dominators = + if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None }; + let dominators = SmallDominators { inner: dominators }; let mut visitor = SsaVisitor { assignments, assignment_order, dominators }; for (local, decl) in body.local_decls.iter_enumerated() { @@ -41,8 +70,14 @@ impl SsaLocals { } } - for (bb, data) in traversal::reverse_postorder(body) { - visitor.visit_basic_block_data(bb, data); + if body.basic_blocks.len() > 2 { + for (bb, data) in traversal::reverse_postorder(body) { + visitor.visit_basic_block_data(bb, data); + } + } else { + for (bb, data) in body.basic_blocks.iter_enumerated() { + visitor.visit_basic_block_data(bb, data); + } } for var_debug_info in &body.var_debug_info { @@ -139,7 +174,7 @@ enum LocationExtended { } struct SsaVisitor { - dominators: Dominators, + dominators: SmallDominators, assignments: IndexVec>, assignment_order: Vec, } diff --git a/tests/codegen/move-operands.rs b/tests/codegen/move-operands.rs index 6c51324a312d0..871b54d0404f6 100644 --- a/tests/codegen/move-operands.rs +++ b/tests/codegen/move-operands.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation +// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation,+CopyProp #![crate_type = "lib"] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index db5b60567faa4..7c77398dfcce5 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -21,7 +21,6 @@ pub struct U(f32, f32, f32, f32); // CHECK-LABEL: @build_array_s #[no_mangle] pub fn build_array_s(x: [f32; 4]) -> S<4> { - // CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false) // CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false) S::<4>(x) } @@ -29,7 +28,6 @@ pub fn build_array_s(x: [f32; 4]) -> S<4> { // CHECK-LABEL: @build_array_t #[no_mangle] pub fn build_array_t(x: [f32; 4]) -> T { - // CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false) // CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false) T(x) } @@ -37,7 +35,6 @@ pub fn build_array_t(x: [f32; 4]) -> T { // CHECK-LABEL: @build_array_u #[no_mangle] pub fn build_array_u(x: [f32; 4]) -> U { - // CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false) // CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false) unsafe { std::mem::transmute(x) } } diff --git a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff new file mode 100644 index 0000000000000..8d5bd10b6cffc --- /dev/null +++ b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff @@ -0,0 +1,30 @@ +- // MIR for `f` before CopyProp ++ // MIR for `f` after CopyProp + + fn f(_1: NotCopy) -> () { + let mut _0: (); // return place in scope 0 at $DIR/custom_move_arg.rs:+0:19: +0:19 + let mut _2: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { +- _2 = move _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _0 = opaque::(move _1) -> bb1; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41 + // mir::Constant + // + span: $DIR/custom_move_arg.rs:15:24: 15:30 + // + literal: Const { ty: fn(NotCopy) {opaque::}, val: Value() } + } + + bb1: { +- _3 = move _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _0 = opaque::(_3) -> bb2; // scope 0 at $DIR/custom_move_arg.rs:+7:9: +7:35 ++ _0 = opaque::(_1) -> bb2; // scope 0 at $DIR/custom_move_arg.rs:+7:9: +7:35 + // mir::Constant + // + span: $DIR/custom_move_arg.rs:19:24: 19:30 + // + literal: Const { ty: fn(NotCopy) {opaque::}, val: Value() } + } + + bb2: { + return; // scope 0 at $DIR/custom_move_arg.rs:+10:9: +10:17 + } + } + diff --git a/tests/mir-opt/copy-prop/custom_move_arg.rs b/tests/mir-opt/copy-prop/custom_move_arg.rs new file mode 100644 index 0000000000000..67911f0f59c2b --- /dev/null +++ b/tests/mir-opt/copy-prop/custom_move_arg.rs @@ -0,0 +1,32 @@ +// unit-test: CopyProp + +#![feature(custom_mir, core_intrinsics)] +#![allow(unused_assignments)] +extern crate core; +use core::intrinsics::mir::*; + +struct NotCopy(bool); + +// EMIT_MIR custom_move_arg.f.CopyProp.diff +#[custom_mir(dialect = "analysis", phase = "post-cleanup")] +fn f(_1: NotCopy) { + mir!({ + let _2 = Move(_1); + Call(RET, bb1, opaque(Move(_1))) + } + bb1 = { + let _3 = Move(_2); + Call(RET, bb2, opaque(_3)) + } + bb2 = { + Return() + }) +} + +#[inline(never)] +fn opaque(_t: T) {} + +fn main() { + f(NotCopy(true)); + println!("hi"); +} diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff index 9c3f87f47c12c..33122f465fe4d 100644 --- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff @@ -10,19 +10,21 @@ scope 2 (inlined ::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47 debug self => _1; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL debug other => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - let mut _3: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - let mut _4: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - let mut _5: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _3: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL } bb0: { + StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 _1 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 _2 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - _5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _3 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL } bb1: { + StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.diff b/tests/mir-opt/inline/inline_generator.main.Inline.diff index 95d649f89ba6b..01f5052b65287 100644 --- a/tests/mir-opt/inline/inline_generator.main.Inline.diff +++ b/tests/mir-opt/inline/inline_generator.main.Inline.diff @@ -7,7 +7,7 @@ let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:32 let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:23: +1:31 let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:28: +1:31 -+ let mut _7: bool; // in scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ let mut _5: bool; // in scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 scope 1 { debug _r => _1; // in scope 1 at $DIR/inline_generator.rs:+1:9: +1:11 } @@ -15,21 +15,19 @@ + } + scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) { // at $DIR/inline_generator.rs:9:14: 9:32 + debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL -+ let mut _5: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL + scope 4 { + scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL -+ debug pointer => _5; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL ++ debug pointer => _3; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + } + } + } + scope 6 (inlined g::{closure#0}) { // at $DIR/inline_generator.rs:9:33: 9:46 -+ debug a => _7; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7 -+ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39 -+ let mut _9: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ debug a => _5; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7 ++ let mut _6: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ let mut _7: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _8: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ let mut _9: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 -+ let mut _11: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 -+ let mut _12: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41 + } bb0: { @@ -64,28 +62,22 @@ - } - - bb2: { -+ StorageLive(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL -+ _5 = move _3; // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL -+ StorageLive(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ _6 = move _5; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _6 }; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL -+ StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL ++ _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _3 }; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL StorageDead(_3); // scope 0 at $DIR/inline_generator.rs:+1:31: +1:32 - _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46 - // mir::Constant - // + span: $DIR/inline_generator.rs:9:33: 9:39 - // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::Yield, <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::Return> {<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator>::resume}, val: Value() } -+ StorageLive(_7); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 -+ _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 -+ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 -+ _9 = discriminant((*_10)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 -+ switchInt(move _9) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ StorageLive(_5); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ _5 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ _8 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ _7 = discriminant((*_8)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ switchInt(move _7) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 } - bb3: { + bb1: { -+ StorageDead(_7); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 ++ StorageDead(_5); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46 StorageDead(_2); // scope 0 at $DIR/inline_generator.rs:+1:45: +1:46 StorageDead(_4); // scope 0 at $DIR/inline_generator.rs:+1:46: +1:47 _0 = const (); // scope 0 at $DIR/inline_generator.rs:+0:11: +2:2 @@ -99,33 +91,33 @@ + } + + bb3: { -+ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 -+ switchInt(_7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 ++ StorageLive(_6); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 ++ switchInt(_5) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21 + } + + bb4: { -+ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25 ++ _6 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25 + goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 + } + + bb5: { -+ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37 ++ _6 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37 + goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39 + } + + bb6: { -+ _1 = GeneratorState::::Yielded(move _8); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 -+ _11 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 -+ discriminant((*_11)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ _1 = GeneratorState::::Yielded(move _6); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 ++ discriminant((*_9)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39 + goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39 + } + + bb7: { -+ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 -+ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39 -+ _1 = GeneratorState::::Complete(_7); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 -+ _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 -+ discriminant((*_12)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ StorageLive(_6); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41 ++ StorageDead(_6); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39 ++ _1 = GeneratorState::::Complete(_5); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 ++ discriminant((*_10)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41 + goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41 + } + diff --git a/tests/mir-opt/issue_101973.inner.ConstProp.diff b/tests/mir-opt/issue_101973.inner.ConstProp.diff index 002392c5cf81a..6db8e4d266472 100644 --- a/tests/mir-opt/issue_101973.inner.ConstProp.diff +++ b/tests/mir-opt/issue_101973.inner.ConstProp.diff @@ -26,13 +26,12 @@ scope 3 (inlined core::num::::rotate_right) { // at $DIR/issue_101973.rs:14:18: 14:58 debug self => _4; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug n => _6; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _15: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _16: u32; // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL } bb0: { StorageLive(_2); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 StorageLive(_3); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:58 + StorageLive(_4); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:17 StorageLive(_12); // scope 2 at $DIR/issue_101973.rs:7:12: 7:27 StorageLive(_13); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 _14 = CheckedShr(_1, const 0_i32); // scope 2 at $DIR/issue_101973.rs:7:12: 7:20 @@ -62,6 +61,7 @@ StorageDead(_13); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 _4 = BitOr(const 0_u32, move _12); // scope 2 at $DIR/issue_101973.rs:7:5: 7:27 StorageDead(_12); // scope 2 at $DIR/issue_101973.rs:7:26: 7:27 + StorageLive(_6); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:57 StorageLive(_7); // scope 0 at $DIR/issue_101973.rs:+1:31: +1:52 StorageLive(_8); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 _10 = CheckedShr(_1, const 8_i32); // scope 0 at $DIR/issue_101973.rs:+1:32: +1:45 @@ -69,6 +69,8 @@ } bb4: { + StorageDead(_6); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 + StorageDead(_4); // scope 0 at $DIR/issue_101973.rs:+1:57: +1:58 _2 = move _3 as i32 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:65 StorageDead(_3); // scope 0 at $DIR/issue_101973.rs:+1:64: +1:65 _0 = move _2 as i64 (IntToInt); // scope 0 at $DIR/issue_101973.rs:+1:5: +1:72 diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index c17d221f86a84..291fc5063d28c 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -5,15 +5,14 @@ fn num_to_digit(_1: char) -> u32 { let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38 let mut _2: std::option::Option; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 - let mut _9: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 (inlined char::methods::::is_digit) { // at $DIR/issue_59352.rs:14:12: 14:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL let mut _4: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL let _5: std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let mut _6: char; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL scope 2 (inlined Option::::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL debug self => _4; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _6: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL } } scope 3 (inlined #[track_caller] Option::::unwrap) { // at $DIR/issue_59352.rs:14:42: 14:50 @@ -29,9 +28,7 @@ fn num_to_digit(_1: char) -> u32 { StorageLive(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageLive(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _6 = _1; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _5 = char::methods::::to_digit(move _6, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _5 = char::methods::::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value() } @@ -39,7 +36,7 @@ fn num_to_digit(_1: char) -> u32 { bb1: { StorageLive(_2); // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 - _2 = char::methods::::to_digit(move _1, const 8_u32) -> bb2; // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 + _2 = char::methods::::to_digit(_1, const 8_u32) -> bb2; // scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 // mir::Constant // + span: $DIR/issue_59352.rs:14:30: 14:38 // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value() } @@ -61,12 +58,11 @@ fn num_to_digit(_1: char) -> u32 { bb5: { _4 = &_5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_6); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _9 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + _6 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 - switchInt(move _9) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + switchInt(move _6) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 } bb6: { diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff index cb89d6340760f..cfcd43093c079 100644 --- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff +++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff @@ -12,18 +12,18 @@ let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 let mut _8: std::result::Result; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + let mut _16: i32; // in scope 0 at $SRC_DIR/core/src/result.rs:LL:COL scope 1 { debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10 scope 2 { scope 8 (inlined #[track_caller] as FromResidual>>::from_residual) { // at $DIR/separate_const_switch.rs:25:8: 25:10 debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _18: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let _14: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _15: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL scope 9 { - debug e => _16; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL scope 10 (inlined >::from) { // at $SRC_DIR/core/src/result.rs:LL:COL - debug t => _18; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL } } } @@ -38,15 +38,13 @@ debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _13: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _14: std::result::Result; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _15: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _13: std::result::Result; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL scope 6 { debug v => _11; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL } scope 7 { - debug e => _13; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + debug e => _12; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } } @@ -55,11 +53,15 @@ StorageLive(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 StorageLive(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 _4 = _1; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9 + StorageLive(_11); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageLive(_12); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 _10 = discriminant(_4); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL switchInt(move _10) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL } bb1: { + StorageDead(_12); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 + StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10 @@ -85,16 +87,16 @@ _6 = ((_3 as Break).0: std::result::Result); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 StorageLive(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 _8 = _6; // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 - StorageLive(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - _16 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _18 = move _16; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _17 = move _18; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - StorageDead(_18); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - _0 = Result::::Err(move _17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_17); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_16); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_14); // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10 + _14 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + _0 = Result::::Err(move _15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_14); // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10 StorageDead(_8); // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10 StorageDead(_6); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10 StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11 @@ -103,16 +105,11 @@ } bb5: { - StorageLive(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _13 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _15 = move _13; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _14 = Result::::Err(move _15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_15); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - _3 = ControlFlow::, i32>::Break(move _14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageLive(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _13 = Result::::Err(move _12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _3 = ControlFlow::, i32>::Break(move _13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL } @@ -121,13 +118,8 @@ } bb7: { - StorageLive(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL _11 = move ((_4 as Ok).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - StorageLive(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - _12 = move _11; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - _3 = ControlFlow::, i32>::Continue(move _12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _3 = ControlFlow::, i32>::Continue(move _11); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL } } diff --git a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff index 9b7dd73382034..f908e8dd0c1f8 100644 --- a/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff +++ b/tests/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff @@ -34,15 +34,10 @@ } bb2: { - StorageLive(_6); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 - StorageLive(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 -- StorageLive(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 -- _8 = _6; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 -- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 -- StorageDead(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:19: +2:20 +- _7 = Gt(_6, const 42_u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 - StorageDead(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+4:9: +4:10 - StorageDead(_6); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+5:5: +5:6 goto -> bb3; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:5: +5:6 } diff --git a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff index da6389676f0d4..3bb0358ffe3e6 100644 --- a/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff +++ b/tests/mir-opt/slice_filter.variant_a-{closure#0}.CopyProp.diff @@ -29,6 +29,14 @@ let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38 + let mut _31: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _37: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _38: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _43: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _44: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _49: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL + let mut _50: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 1 { debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28 debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31 @@ -39,13 +47,11 @@ debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _29: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _30: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _31: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _32: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 3 (inlined cmp::impls::::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug self => _31; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug other => _32; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _31; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _32; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _33: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _34: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL } @@ -55,13 +61,11 @@ debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _35: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _36: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _37: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _38: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 5 (inlined cmp::impls::::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug self => _35; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug other => _36; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug self => _37; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug other => _38; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _37; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _38; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => _35; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => _36; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _39: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _40: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL } @@ -71,13 +75,11 @@ debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _41: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _42: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _43: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _44: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 7 (inlined cmp::impls::::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug self => _41; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug other => _42; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug self => _43; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug other => _44; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _43; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _44; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => _41; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => _42; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _45: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _46: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL } @@ -87,13 +89,11 @@ debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _47: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _48: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _49: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - let mut _50: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL scope 9 (inlined cmp::impls::::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug self => _47; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -- debug other => _48; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug self => _49; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ debug other => _50; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug self => _49; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- debug other => _50; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug self => _47; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ debug other => _48; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _51: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL let mut _52: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL } @@ -121,23 +121,23 @@ StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 _10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 -- StorageLive(_29); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - _31 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _29 = _31; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageLive(_30); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL - _32 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _30 = _32; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL + _29 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL + _30 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_31); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _31 = _29; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_32); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _32 = _30; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _33 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _33 = (*_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _33 = (*_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _33 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _34 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _34 = (*_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _34 = (*_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _34 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL _8 = Le(move _33, move _34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_30); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_29); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_32); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_31); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46 @@ -158,23 +158,23 @@ StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 _19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 -- StorageLive(_35); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - _37 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _35 = _37; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageLive(_36); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL - _38 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _36 = _38; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL + _35 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL + _36 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_37); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _37 = _35; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_38); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _38 = _36; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _39 = (*_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _39 = (*_37); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _39 = (*_37); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _39 = (*_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _40 = (*_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _40 = (*_38); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _40 = (*_38); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _40 = (*_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL _17 = Le(move _39, move _40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_36); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_35); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_38); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_37); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66 @@ -206,23 +206,23 @@ StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 _14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 -- StorageLive(_41); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - _43 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _41 = _43; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageLive(_42); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL - _44 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _42 = _44; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL + _41 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL + _42 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_43); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _43 = _41; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_44); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _44 = _42; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _45 = (*_41); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _45 = (*_43); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _45 = (*_43); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _45 = (*_41); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _46 = (*_42); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _46 = (*_44); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _46 = (*_44); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _46 = (*_42); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL _12 = Le(move _45, move _46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_42); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_41); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_44); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_43); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56 @@ -245,23 +245,23 @@ StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 _23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 -- StorageLive(_47); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - _49 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _47 = _49; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageLive(_48); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL - _50 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _48 = _50; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + _47 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL + _48 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_49); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _49 = _47; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageLive(_50); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _50 = _48; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _51 = (*_47); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _51 = (*_49); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _51 = (*_49); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _51 = (*_47); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageLive(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -- _52 = (*_48); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -+ _52 = (*_50); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL +- _52 = (*_50); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL ++ _52 = (*_48); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL _21 = Le(move _51, move _52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_48); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL -- StorageDead(_47); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_50); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL +- StorageDead(_49); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76 From d8d18aae03896b66959fddbce58186904eb9ce04 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 12 Feb 2023 14:42:16 -0500 Subject: [PATCH 03/47] Fix UB in the test case --- tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff | 5 +++-- tests/mir-opt/copy-prop/custom_move_arg.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff index 8d5bd10b6cffc..6ca73ffdde280 100644 --- a/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff +++ b/tests/mir-opt/copy-prop/custom_move_arg.f.CopyProp.diff @@ -7,8 +7,9 @@ let mut _3: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL bb0: { -- _2 = move _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL - _0 = opaque::(move _1) -> bb1; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41 +- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _0 = opaque::(move _1) -> bb1; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41 ++ _0 = opaque::(_1) -> bb1; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41 // mir::Constant // + span: $DIR/custom_move_arg.rs:15:24: 15:30 // + literal: Const { ty: fn(NotCopy) {opaque::}, val: Value() } diff --git a/tests/mir-opt/copy-prop/custom_move_arg.rs b/tests/mir-opt/copy-prop/custom_move_arg.rs index 67911f0f59c2b..4a591146e619f 100644 --- a/tests/mir-opt/copy-prop/custom_move_arg.rs +++ b/tests/mir-opt/copy-prop/custom_move_arg.rs @@ -11,7 +11,7 @@ struct NotCopy(bool); #[custom_mir(dialect = "analysis", phase = "post-cleanup")] fn f(_1: NotCopy) { mir!({ - let _2 = Move(_1); + let _2 = _1; Call(RET, bb1, opaque(Move(_1))) } bb1 = { From eb286dd07082b35be7532984054204a3d9fd5617 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 Feb 2023 19:28:10 +0000 Subject: [PATCH 04/47] Make can_eq and can_sub return booleans --- compiler/rustc_borrowck/src/diagnostics/mod.rs | 2 +- compiler/rustc_hir_analysis/src/astconv/mod.rs | 1 - .../src/check/compare_impl_item.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_hir_typeck/src/demand.rs | 14 +++++++------- .../src/fn_ctxt/suggestions.rs | 4 ++-- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 6 +++--- .../infer/error_reporting/note_and_explain.rs | 4 ++-- compiler/rustc_infer/src/infer/mod.rs | 18 ++++-------------- .../src/traits/error_reporting/mod.rs | 2 +- .../traits/error_reporting/on_unimplemented.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 17 +++++++++-------- 13 files changed, 33 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 3006e27e1d5b5..0a7d675f9f820 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1144,7 +1144,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { LateBoundRegionConversionTime::FnCall, tcx.fn_sig(method_did).subst(tcx, method_substs).input(0), ) - && infcx.can_eq(self.param_env, ty, self_ty).is_ok() + && infcx.can_eq(self.param_env, ty, self_ty) { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8c753a99a09f0..0a243b47b5c71 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2232,7 +2232,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.erase_regions(impl_.self_ty()), tcx.erase_regions(qself_ty), ) - .is_ok() }) && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative }) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c86af6a379bfa..d5f16a9af00b9 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1116,7 +1116,7 @@ fn compare_self_type<'tcx>( let infcx = tcx.infer_ctxt().build(); let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty); - let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok(); + let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty); match ExplicitSelf::determine(self_arg_ty, can_eq_self) { ExplicitSelf::ByValue => "self".to_owned(), ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5f95622883b8f..88b2c7fa28256 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1716,7 +1716,7 @@ fn receiver_is_valid<'tcx>( let cause = ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver); - let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty).is_ok(); + let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty); // `self: Self` is always valid. if can_eq_self(receiver_ty) { diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index ae00042eae73d..149c7dbef22f5 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -321,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut param_args = FxHashMap::default(); let mut param_expected = FxHashMap::default(); let mut param_found = FxHashMap::default(); - if self.can_eq(self.param_env, ty, found).is_ok() { + if self.can_eq(self.param_env, ty, found) { // We only point at the first place where the found type was inferred. for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() { if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { @@ -369,7 +369,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (param, (arg, arg_ty)) in param_args.iter() { let Some(expected) = param_expected.get(param) else { continue; }; let Some(found) = param_found.get(param) else { continue; }; - if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; } + if !self.can_eq(self.param_env, *arg_ty, *found) { continue; } self.emit_coerce_suggestions(err, arg, *found, *expected, None, None); } @@ -379,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if ty != prev && param_args.is_empty() - && self.can_eq(self.param_env, ty, found).is_ok() + && self.can_eq(self.param_env, ty, found) { // We only point at the first place where the found type was inferred. if !segment.ident.span.overlaps(mismatch_span) { @@ -401,7 +401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if ty != prev && let Some(span) = prev_span - && self.can_eq(self.param_env, ty, found).is_ok() + && self.can_eq(self.param_env, ty, found) { // We only point at the first place where the found type was inferred. // We use the *previous* span because if the type is known *here* it means @@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::Adt(expected_adt, substs) = expected.kind() { if let hir::ExprKind::Field(base, ident) = expr.kind { let base_ty = self.typeck_results.borrow().expr_ty(base); - if self.can_eq(self.param_env, base_ty, expected).is_ok() + if self.can_eq(self.param_env, base_ty, expected) && let Some(base_span) = base.span.find_ancestor_inside(expr.span) { err.span_suggestion_verbose( @@ -1357,7 +1357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr), _, &ty::Ref(_, checked, _), - ) if self.can_sub(self.param_env, checked, expected).is_ok() => { + ) if self.can_sub(self.param_env, checked, expected) => { // We have `&T`, check if what was expected was `T`. If so, // we may want to suggest removing a `&`. if sm.is_imported(expr.span) { @@ -2003,7 +2003,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; }; - if self.can_eq(self.param_env, expected_ty, ty).is_ok() { + if self.can_eq(self.param_env, expected_ty, ty) { err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index eaad57d8c2e9f..7ce721e94cb23 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1015,7 +1015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_inner_ty = substs.type_at(0); let expected_inner_ty = expected_substs.type_at(0); if let ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind() - && self.can_eq(self.param_env, *ty, expected_inner_ty).is_ok() + && self.can_eq(self.param_env, *ty, expected_inner_ty) { let def_path = self.tcx.def_path_str(adt_def.did()); if self.type_is_copy_modulo_regions(self.param_env, *ty, expr.span) { @@ -1054,7 +1054,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result) && adt_def.did() == result_did // Check that the error types are equal - && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)).is_ok() + && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)) { return suggest_copied_or_cloned(); } else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 16b0d48002efc..b9c9a614e40c6 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -936,7 +936,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return false; } } - self.can_sub(self.param_env, fty.output(), expected).is_ok() + self.can_sub(self.param_env, fty.output(), expected) }), _ => false, } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 3201035bdd8ba..948e332ceab67 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -90,7 +90,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; if let Some(expr) = ti.origin_expr { self.suggest_fn_call(&mut diag, expr, expected, |output| { - self.can_eq(self.param_env, output, actual).is_ok() + self.can_eq(self.param_env, output, actual) }); } Some(diag) @@ -675,7 +675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { match (expected.kind(), actual.kind(), ba) { (ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::NONE) - if self.can_eq(self.param_env, *inner_ty, actual).is_ok() => + if self.can_eq(self.param_env, *inner_ty, actual) => { err.span_suggestion_verbose( span.shrink_to_lo(), @@ -685,7 +685,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } (_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::REF) - if self.can_eq(self.param_env, expected, *inner_ty).is_ok() => + if self.can_eq(self.param_env, expected, *inner_ty) => { err.span_suggestion_verbose( span.with_hi(span.lo() + BytePos(4)), diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 984e8cf6a0eb9..c3fe41586189a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -576,7 +576,7 @@ fn foo(&self) -> Self::T { String::new() } tcx.impl_defaultness(item.id.owner_id) { let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity(); - if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() { + if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label( item.span, "associated type defaults can't be assumed inside the \ @@ -598,7 +598,7 @@ fn foo(&self) -> Self::T { String::new() } if let hir::AssocItemKind::Type = item.kind { let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity(); - if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() { + if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label(item.span, "expected this associated type"); return true; } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ae196a7133cae..a6f94d5adef79 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -880,30 +880,20 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); } - pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> + pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| { - self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) - }) + self.probe(|_| self.at(origin, param_env).sub(a, b).is_ok()) } - pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> + pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| { - self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) - }) + self.probe(|_| self.at(origin, param_env).eq(a, b).is_ok()) } #[instrument(skip(self), level = "debug")] diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 4867855c2ae95..ffbdd03575cb1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1629,7 +1629,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Eventually I'll need to implement param-env-aware // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. let param_env = ty::ParamEnv::empty(); - if self.can_sub(param_env, error, implication).is_ok() { + if self.can_sub(param_env, error, implication) { debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); return true; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index a3209d35e58be..39241696a34c5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -72,7 +72,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let impl_self_ty = impl_trait_ref.self_ty(); - if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { + if self.can_eq(param_env, trait_self_ty, impl_self_ty) { self_match_impls.push((def_id, impl_substs)); if iter::zip( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index cca178299df11..a80689002839d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -748,10 +748,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let real_ty = real_trait_pred.self_ty(); // We `erase_late_bound_regions` here because `make_subregion` does not handle // `ReLateBound`, and we don't particularly care about the regions. - if self - .can_eq(obligation.param_env, self.tcx.erase_late_bound_regions(real_ty), arg_ty) - .is_err() - { + if !self.can_eq( + obligation.param_env, + self.tcx.erase_late_bound_regions(real_ty), + arg_ty, + ) { continue; } @@ -3690,7 +3691,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let Some((span, (assoc, ty))) = entry else { continue; }; if primary_spans.is_empty() || type_diffs.iter().any(|diff| { let Sorts(expected_found) = diff else { return false; }; - self.can_eq(param_env, expected_found.found, ty).is_ok() + self.can_eq(param_env, expected_found.found, ty) }) { // FIXME: this doesn't quite work for `Iterator::collect` // because we have `Vec` and `()`, but we'd want `i32` @@ -3717,10 +3718,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty)); let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc)); - if self.can_eq(param_env, ty, *prev_ty).is_err() { + if !self.can_eq(param_env, ty, *prev_ty) { if type_diffs.iter().any(|diff| { let Sorts(expected_found) = diff else { return false; }; - self.can_eq(param_env, expected_found.found, ty).is_ok() + self.can_eq(param_env, expected_found.found, ty) }) { primary_spans.push(span); } @@ -3868,7 +3869,7 @@ fn hint_missing_borrow<'tcx>( let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg); let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg); - if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() { + if infcx.can_eq(param_env, found_ty, expected_ty) { // FIXME: This could handle more exotic cases like mutability mismatches too! if found_refs.len() < expected_refs.len() && found_refs[..] == expected_refs[expected_refs.len() - found_refs.len()..] From 087a0136d01d0ee05d4e8c5e91f2e01978244a67 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 Feb 2023 21:07:46 +0000 Subject: [PATCH 05/47] Don't ICE in might_permit_raw_init if reference is polymorphic --- .../src/util/might_permit_raw_init.rs | 9 +++++-- .../dont_yeet_assert.generic.InstCombine.diff | 24 +++++++++++++++++++ tests/mir-opt/dont_yeet_assert.rs | 11 +++++++++ tests/ui/lint/invalid_value-polymorphic.rs | 8 +++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff create mode 100644 tests/mir-opt/dont_yeet_assert.rs create mode 100644 tests/ui/lint/invalid_value-polymorphic.rs diff --git a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs index 48961b7aac645..a2db98683b529 100644 --- a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs +++ b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs @@ -1,5 +1,5 @@ use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; -use rustc_middle::ty::{ParamEnv, TyCtxt}; +use rustc_middle::ty::{ParamEnv, TyCtxt, TypeVisitable}; use rustc_session::Limit; use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants}; @@ -108,7 +108,12 @@ fn might_permit_raw_init_lax<'tcx>( // Special magic check for references and boxes (i.e., special pointer types). if let Some(pointee) = this.ty.builtin_deref(false) { - let pointee = cx.layout_of(pointee.ty).expect("need to be able to compute layouts"); + let Ok(pointee) = cx.layout_of(pointee.ty) else { + // Reference is too polymorphic, it has a layout but the pointee does not. + // So we must assume that there may be some substitution that is valid. + assert!(pointee.ty.needs_subst()); + return true; + }; // We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied. if pointee.align.abi.bytes() > 1 { // 0x01-filling is not aligned. diff --git a/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff b/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff new file mode 100644 index 0000000000000..fb08ad582d927 --- /dev/null +++ b/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff @@ -0,0 +1,24 @@ +- // MIR for `generic` before InstCombine ++ // MIR for `generic` after InstCombine + + fn generic() -> () { + let mut _0: (); // return place in scope 0 at $DIR/dont_yeet_assert.rs:+0:21: +0:21 + let _1: (); // in scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 + + bb0: { + StorageLive(_1); // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 +- _1 = assert_mem_uninitialized_valid::<&T>() -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 +- // mir::Constant +- // + span: $DIR/dont_yeet_assert.rs:10:5: 10:59 +- // + user_ty: UserType(0) +- // + literal: Const { ty: extern "rust-intrinsic" fn() {assert_mem_uninitialized_valid::<&T>}, val: Value() } ++ goto -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/dont_yeet_assert.rs:+1:61: +1:62 + _0 = const (); // scope 0 at $DIR/dont_yeet_assert.rs:+0:21: +2:2 + return; // scope 0 at $DIR/dont_yeet_assert.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/dont_yeet_assert.rs b/tests/mir-opt/dont_yeet_assert.rs new file mode 100644 index 0000000000000..7cec761eabac1 --- /dev/null +++ b/tests/mir-opt/dont_yeet_assert.rs @@ -0,0 +1,11 @@ +// compile-flags: --crate-type=lib +// unit-test: InstCombine + +#![feature(core_intrinsics)] + +// Want to make sure this assertion isn't compiled away in generic code. + +// EMIT_MIR dont_yeet_assert.generic.InstCombine.diff +pub fn generic() { + core::intrinsics::assert_mem_uninitialized_valid::<&T>(); +} diff --git a/tests/ui/lint/invalid_value-polymorphic.rs b/tests/ui/lint/invalid_value-polymorphic.rs new file mode 100644 index 0000000000000..055173e9842dd --- /dev/null +++ b/tests/ui/lint/invalid_value-polymorphic.rs @@ -0,0 +1,8 @@ +// compile-flags: --crate-type=lib -Zmir-enable-passes=+InstCombine +// build-pass + +#![feature(core_intrinsics)] + +pub fn generic() { + core::intrinsics::assert_mem_uninitialized_valid::<&T>(); +} From 22f853c620d970c6f80c8c206614a3bf766d028f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Tue, 14 Feb 2023 16:11:15 +0100 Subject: [PATCH 06/47] Avoid looping past bounds of args There might be more type params than args to a method call, which leads to an index out of bounds panic. --- compiler/rustc_hir_typeck/src/demand.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index ae00042eae73d..16d3115c233b0 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -323,13 +323,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut param_found = FxHashMap::default(); if self.can_eq(self.param_env, ty, found).is_ok() { // We only point at the first place where the found type was inferred. - for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() { + for (param_ty, arg) in sig.inputs().skip_binder().iter().skip(1).zip(args) { if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { // We found an argument that references a type parameter in `Self`, // so we assume that this is the argument that caused the found // type, which we know already because of `can_eq` above was first // inferred in this method call. - let arg = &args[i]; let arg_ty = self.node_ty(arg.hir_id); if !arg.span.overlaps(mismatch_span) { err.span_label( From 8fc5ba65e1a6f2e7600c98579d4a0f488560c5bf Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Wed, 18 Jan 2023 16:34:08 +0300 Subject: [PATCH 07/47] Port OutlivesContent, OutlivesBound, FUllfillReqLifetime, LfBoundNotSatisfied diagnostics --- .../locales/en-US/infer.ftl | 14 ++ compiler/rustc_infer/src/errors/mod.rs | 37 ++++++ .../src/errors/note_and_explain.rs | 36 +++++- .../src/infer/error_reporting/note.rs | 120 ++++++++---------- 4 files changed, 131 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index bcc1d9002dfde..505dd98049444 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -140,6 +140,14 @@ infer_lifetime_param_suggestion_elided = each elided lifetime in input position infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$pref_kind}] + [ref_valid_for] ...the reference is valid for + [content_valid_for] ...but the borrowed content is only valid for + [type_valid_for] object type is valid for + [source_pointer_valid_for] source pointer is only valid for + [type_satisfy] type must satisfy + [type_outlive] type must outlive + [lf_instantiated_with] lifetime parameter instantiated with + [lf_must_outlive] but lifetime parameter must outlive [empty] {""} }{$pref_kind -> [empty] {""} @@ -158,8 +166,14 @@ infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$suff_kind}] [empty]{""} [continues] ... + [req_by_binding] {" "}as required by this binding } +infer_outlives_content = lifetime of reference outlives lifetime of borrowed content... +infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type +infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime +infer_lf_bound_not_satisfied = lifetime bound not satisfied + infer_mismatched_static_lifetime = incompatible lifetime on type infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl` infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 8bf3a160abbb4..ae2985d456b79 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -933,3 +933,40 @@ pub struct ButNeedsToSatisfy { pub has_lifetime: bool, pub lifetime: String, } + +#[derive(Diagnostic)] +#[diag(infer_outlives_content, code = "E0312")] +pub struct OutlivesContent<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub notes: Vec>, +} + +#[derive(Diagnostic)] +#[diag(infer_outlives_bound, code = "E0476")] +pub struct OutlivesBound<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub notes: Vec>, +} + +#[derive(Diagnostic)] +#[diag(infer_fullfill_req_lifetime, code = "E0477")] +pub struct FullfillReqLifetime<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, + #[subdiagnostic] + pub note: Option>, +} + +#[derive(Diagnostic)] +#[diag(infer_lf_bound_not_satisfied, code = "E0478")] +pub struct LfBoundNotSatisfied<'a> { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub notes: Vec>, +} diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 5d861a78af800..c60eee609946b 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -121,16 +121,34 @@ impl<'a> DescriptionCtx<'a> { pub enum PrefixKind { Empty, + RefValidFor, + ContentValidFor, + TypeValidFor, + SourcePointerValidFor, + TypeSatisfy, + TypeOutlive, + LfInstantiatedWith, + LfMustOutlive, } pub enum SuffixKind { + Empty, Continues, + ReqByBinding, } impl IntoDiagnosticArg for PrefixKind { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { let kind = match self { Self::Empty => "empty", + Self::RefValidFor => "ref_valid_for", + Self::ContentValidFor => "content_valid_for", + Self::TypeValidFor => "type_valid_for", + Self::SourcePointerValidFor => "source_pointer_valid_for", + Self::TypeSatisfy => "type_satisfy", + Self::TypeOutlive => "type_outlive", + Self::LfInstantiatedWith => "lf_instantiated_with", + Self::LfMustOutlive => "lf_must_outlive", } .into(); rustc_errors::DiagnosticArgValue::Str(kind) @@ -140,7 +158,9 @@ impl IntoDiagnosticArg for PrefixKind { impl IntoDiagnosticArg for SuffixKind { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { let kind = match self { + Self::Empty => "empty", Self::Continues => "continues", + Self::ReqByBinding => "req_by_binding", } .into(); rustc_errors::DiagnosticArgValue::Str(kind) @@ -166,17 +186,19 @@ impl RegionExplanation<'_> { } impl AddToDiagnostic for RegionExplanation<'_> { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, f: F) where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { - if let Some(span) = self.desc.span { - diag.span_note(span, fluent::infer_region_explanation); - } else { - diag.note(fluent::infer_region_explanation); - } - self.desc.add_to(diag); diag.set_arg("pref_kind", self.prefix); diag.set_arg("suff_kind", self.suffix); + let desc_span = self.desc.span; + self.desc.add_to(diag); + let msg = f(diag, fluent::infer_region_explanation.into()); + if let Some(span) = desc_span { + diag.span_note(span, msg); + } else { + diag.note(msg); + } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index bdd09a995dc23..c2b936c3402a2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,9 +1,12 @@ -use crate::errors::RegionOriginNote; +use crate::errors::{ + note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, + RegionOriginNote, +}; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; use rustc_errors::{ fluent, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, + ErrorGuaranteed, IntoDiagnostic, }; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::traits::ObligationCauseCode; @@ -119,104 +122,83 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err } infer::Reborrow(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0312, - "lifetime of reference outlives lifetime of borrowed content..." - ); - note_and_explain_region( + let reference_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "...the reference is valid for ", sub, - "...", None, + note_and_explain::PrefixKind::RefValidFor, + note_and_explain::SuffixKind::Continues, ); - note_and_explain_region( + let content_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "...but the borrowed content is only valid for ", sup, - "", None, + note_and_explain::PrefixKind::ContentValidFor, + note_and_explain::SuffixKind::Empty, ); - err + OutlivesContent { + span, + notes: reference_valid.into_iter().chain(content_valid).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateObjectBound(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0476, - "lifetime of the source pointer does not outlive lifetime bound of the \ - object type" - ); - note_and_explain_region( + let object_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "object type is valid for ", sub, - "", None, + note_and_explain::PrefixKind::TypeValidFor, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "source pointer is only valid for ", sup, - "", None, + note_and_explain::PrefixKind::SourcePointerValidFor, + note_and_explain::SuffixKind::Empty, ); - err + OutlivesBound { + span, + notes: object_valid.into_iter().chain(pointer_valid).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateParamBound(span, ty, opt_span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0477, - "the type `{}` does not fulfill the required lifetime", - self.ty_to_string(ty) + let prefix = match *sub { + ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy, + _ => note_and_explain::PrefixKind::TypeOutlive, + }; + let suffix = if opt_span.is_some() { + note_and_explain::SuffixKind::ReqByBinding + } else { + note_and_explain::SuffixKind::Empty + }; + let note = note_and_explain::RegionExplanation::new( + self.tcx, sub, opt_span, prefix, suffix, ); - match *sub { - ty::ReStatic => note_and_explain_region( - self.tcx, - &mut err, - "type must satisfy ", - sub, - if opt_span.is_some() { " as required by this binding" } else { "" }, - opt_span, - ), - _ => note_and_explain_region( - self.tcx, - &mut err, - "type must outlive ", - sub, - if opt_span.is_some() { " as required by this binding" } else { "" }, - opt_span, - ), - } - err + FullfillReqLifetime { span, ty: self.resolve_vars_if_possible(ty), note } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::RelateRegionParamBound(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - note_and_explain_region( + let param_instantiated = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "lifetime parameter instantiated with ", sup, - "", None, + note_and_explain::PrefixKind::LfInstantiatedWith, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let param_must_outlive = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "but lifetime parameter must outlive ", sub, - "", None, + note_and_explain::PrefixKind::LfMustOutlive, + note_and_explain::SuffixKind::Empty, ); - err + LfBoundNotSatisfied { + span, + notes: param_instantiated.into_iter().chain(param_must_outlive).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::ReferenceOutlivesReferent(ty, span) => { let mut err = struct_span_err!( From 58e901b6fd1163172149fd422565523b17eed5f0 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 19 Jan 2023 17:35:09 +0300 Subject: [PATCH 08/47] Port "BorrowedTooLong" diagnostic --- .../locales/en-US/infer.ftl | 6 ++-- compiler/rustc_infer/src/errors/mod.rs | 10 +++++++ .../src/errors/note_and_explain.rs | 8 ++++-- .../src/infer/error_reporting/note.rs | 28 +++++++++++++++++-- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 505dd98049444..0fcde81174038 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -142,12 +142,14 @@ infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$pref_kind}] [ref_valid_for] ...the reference is valid for [content_valid_for] ...but the borrowed content is only valid for - [type_valid_for] object type is valid for + [type_obj_valid_for] object type is valid for [source_pointer_valid_for] source pointer is only valid for [type_satisfy] type must satisfy [type_outlive] type must outlive [lf_instantiated_with] lifetime parameter instantiated with [lf_must_outlive] but lifetime parameter must outlive + [type_valid_for] the type is valid for + [borrow_lasts_for] but the borrow lasts for [empty] {""} }{$pref_kind -> [empty] {""} @@ -156,7 +158,6 @@ infer_region_explanation = {$pref_kind -> *[should_not_happen] [{$desc_kind}] [restatic] the static lifetime [revar] lifetime {$desc_arg} - [as_defined] the lifetime `{$desc_arg}` as defined here [as_defined_anon] the anonymous lifetime as defined here [defined_here] the anonymous lifetime defined here @@ -173,6 +174,7 @@ infer_outlives_content = lifetime of reference outlives lifetime of borrowed con infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime infer_lf_bound_not_satisfied = lifetime bound not satisfied +infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long infer_mismatched_static_lifetime = incompatible lifetime on type infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl` diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index ae2985d456b79..6efe72bfc365b 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -970,3 +970,13 @@ pub struct LfBoundNotSatisfied<'a> { #[subdiagnostic] pub notes: Vec>, } + +#[derive(Diagnostic)] +#[diag(infer_borrowed_too_long, code = "E0490")] +pub struct BorrowedTooLong<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, + #[subdiagnostic] + pub notes: Vec>, +} diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index c60eee609946b..e779fdd6e5509 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -123,12 +123,14 @@ pub enum PrefixKind { Empty, RefValidFor, ContentValidFor, - TypeValidFor, + TypeObjValidFor, SourcePointerValidFor, TypeSatisfy, TypeOutlive, LfInstantiatedWith, LfMustOutlive, + TypeValidFor, + BorrowLastsFor, } pub enum SuffixKind { @@ -143,12 +145,14 @@ impl IntoDiagnosticArg for PrefixKind { Self::Empty => "empty", Self::RefValidFor => "ref_valid_for", Self::ContentValidFor => "content_valid_for", - Self::TypeValidFor => "type_valid_for", + Self::TypeObjValidFor => "type_obj_valid_for", Self::SourcePointerValidFor => "source_pointer_valid_for", Self::TypeSatisfy => "type_satisfy", Self::TypeOutlive => "type_outlive", Self::LfInstantiatedWith => "lf_instantiated_with", Self::LfMustOutlive => "lf_must_outlive", + Self::TypeValidFor => "type_valid_for", + Self::BorrowLastsFor => "borrow_lasts_for", } .into(); rustc_errors::DiagnosticArgValue::Str(kind) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index c2b936c3402a2..e470d9d905371 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,6 +1,6 @@ use crate::errors::{ - note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, - RegionOriginNote, + note_and_explain, BorrowedTooLong, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, + OutlivesContent, RegionOriginNote, }; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; @@ -147,7 +147,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.tcx, sub, None, - note_and_explain::PrefixKind::TypeValidFor, + note_and_explain::PrefixKind::TypeObjValidFor, note_and_explain::SuffixKind::Empty, ); let pointer_valid = note_and_explain::RegionExplanation::new( @@ -200,6 +200,28 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } + infer::DataBorrowed(ty, span) => { + let type_valid = note_and_explain::RegionExplanation::new( + self.tcx, + sub, + None, + note_and_explain::PrefixKind::TypeValidFor, + note_and_explain::SuffixKind::Empty, + ); + let borrow_lasts_for = note_and_explain::RegionExplanation::new( + self.tcx, + sup, + None, + note_and_explain::PrefixKind::BorrowLastsFor, + note_and_explain::SuffixKind::Empty, + ); + BorrowedTooLong { + span, + ty: self.resolve_vars_if_possible(ty), + notes: type_valid.into_iter().chain(borrow_lasts_for).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) + } infer::ReferenceOutlivesReferent(ty, span) => { let mut err = struct_span_err!( self.tcx.sess, From cb8ea01096fb14ea25bbe69fd0b92f7e7752cb78 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sat, 21 Jan 2023 18:16:53 +0300 Subject: [PATCH 09/47] Port RefLongerThanData --- .../locales/en-US/infer.ftl | 3 ++ compiler/rustc_infer/src/errors/mod.rs | 10 +++++++ .../src/errors/note_and_explain.rs | 4 +++ .../src/infer/error_reporting/note.rs | 30 ++++++++----------- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 0fcde81174038..c012973f1ddc3 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -150,6 +150,8 @@ infer_region_explanation = {$pref_kind -> [lf_must_outlive] but lifetime parameter must outlive [type_valid_for] the type is valid for [borrow_lasts_for] but the borrow lasts for + [pointer_valid_for] the pointer is valid for + [data_valid_for] but the referenced data is only valid for [empty] {""} }{$pref_kind -> [empty] {""} @@ -175,6 +177,7 @@ infer_outlives_bound = lifetime of the source pointer does not outlive lifetime infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime infer_lf_bound_not_satisfied = lifetime bound not satisfied infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long +infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references infer_mismatched_static_lifetime = incompatible lifetime on type infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl` diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 6efe72bfc365b..7088be05ef78d 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -980,3 +980,13 @@ pub struct BorrowedTooLong<'a> { #[subdiagnostic] pub notes: Vec>, } + +#[derive(Diagnostic)] +#[diag(infer_ref_longer_than_data, code = "E0491")] +pub struct RefLongerThanData<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, + #[subdiagnostic] + pub notes: Vec>, +} diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index e779fdd6e5509..3516517dcc3ab 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -131,6 +131,8 @@ pub enum PrefixKind { LfMustOutlive, TypeValidFor, BorrowLastsFor, + PointerValidFor, + DataValidFor, } pub enum SuffixKind { @@ -153,6 +155,8 @@ impl IntoDiagnosticArg for PrefixKind { Self::LfMustOutlive => "lf_must_outlive", Self::TypeValidFor => "type_valid_for", Self::BorrowLastsFor => "borrow_lasts_for", + Self::PointerValidFor => "pointer_valid_for", + Self::DataValidFor => "data_valid_for", } .into(); rustc_errors::DiagnosticArgValue::Str(kind) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e470d9d905371..4c07cc0b6a252 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,6 +1,6 @@ use crate::errors::{ note_and_explain, BorrowedTooLong, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, - OutlivesContent, RegionOriginNote, + OutlivesContent, RefLongerThanData, RegionOriginNote, }; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; @@ -223,30 +223,26 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::ReferenceOutlivesReferent(ty, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0491, - "in type `{}`, reference has a longer lifetime than the data it references", - self.ty_to_string(ty) - ); - note_and_explain_region( + let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "the pointer is valid for ", sub, - "", None, + note_and_explain::PrefixKind::PointerValidFor, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let data_valid = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "but the referenced data is only valid for ", sup, - "", None, + note_and_explain::PrefixKind::DataValidFor, + note_and_explain::SuffixKind::Empty, ); - err + RefLongerThanData { + span, + ty: self.resolve_vars_if_possible(ty), + notes: pointer_valid.into_iter().chain(data_valid).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { let mut err = self.report_extra_impl_obligation( From 35dbec338ac837c533843ff7cf0441c3b6052b5e Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sat, 21 Jan 2023 19:45:45 +0300 Subject: [PATCH 10/47] Port another diagnostic --- .../locales/en-US/infer.ftl | 6 ++-- .../src/errors/note_and_explain.rs | 4 +++ .../src/infer/error_reporting/note.rs | 30 +++++++++---------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index c012973f1ddc3..c257bf739d11a 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -146,8 +146,10 @@ infer_region_explanation = {$pref_kind -> [source_pointer_valid_for] source pointer is only valid for [type_satisfy] type must satisfy [type_outlive] type must outlive - [lf_instantiated_with] lifetime parameter instantiated with - [lf_must_outlive] but lifetime parameter must outlive + [lf_param_instantiated_with] lifetime parameter instantiated with + [lf_param_must_outlive] but lifetime parameter must outlive + [lf_instantiated_with] lifetime instantiated with + [lf_must_outlive] but lifetime must outlive [type_valid_for] the type is valid for [borrow_lasts_for] but the borrow lasts for [pointer_valid_for] the pointer is valid for diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 3516517dcc3ab..b212a5a09c01d 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -127,6 +127,8 @@ pub enum PrefixKind { SourcePointerValidFor, TypeSatisfy, TypeOutlive, + LfParamInstantiatedWith, + LfParamMustOutlive, LfInstantiatedWith, LfMustOutlive, TypeValidFor, @@ -151,6 +153,8 @@ impl IntoDiagnosticArg for PrefixKind { Self::SourcePointerValidFor => "source_pointer_valid_for", Self::TypeSatisfy => "type_satisfy", Self::TypeOutlive => "type_outlive", + Self::LfParamInstantiatedWith => "lf_param_instantiated_with", + Self::LfParamMustOutlive => "lf_param_must_outlive", Self::LfInstantiatedWith => "lf_instantiated_with", Self::LfMustOutlive => "lf_must_outlive", Self::TypeValidFor => "type_valid_for", diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 4c07cc0b6a252..adf240e7ce5d7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -5,8 +5,8 @@ use crate::errors::{ use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; use rustc_errors::{ - fluent, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, IntoDiagnostic, + fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, + IntoDiagnostic, }; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::traits::ObligationCauseCode; @@ -184,14 +184,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.tcx, sup, None, - note_and_explain::PrefixKind::LfInstantiatedWith, + note_and_explain::PrefixKind::LfParamInstantiatedWith, note_and_explain::SuffixKind::Empty, ); let param_must_outlive = note_and_explain::RegionExplanation::new( self.tcx, sub, None, - note_and_explain::PrefixKind::LfMustOutlive, + note_and_explain::PrefixKind::LfParamMustOutlive, note_and_explain::SuffixKind::Empty, ); LfBoundNotSatisfied { @@ -279,25 +279,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err } infer::AscribeUserTypeProvePredicate(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - note_and_explain_region( + let instantiated = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "lifetime instantiated with ", sup, - "", None, + note_and_explain::PrefixKind::LfInstantiatedWith, + note_and_explain::SuffixKind::Empty, ); - note_and_explain_region( + let must_outlive = note_and_explain::RegionExplanation::new( self.tcx, - &mut err, - "but lifetime must outlive ", sub, - "", None, + note_and_explain::PrefixKind::LfMustOutlive, + note_and_explain::SuffixKind::Empty, ); - err + LfBoundNotSatisfied { + span, + notes: instantiated.into_iter().chain(must_outlive).collect(), + } + .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } }; if sub.is_error() || sup.is_error() { From 8d590dc3039d49cb8b54f3aec380d43b3ed5e2dd Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sat, 21 Jan 2023 20:55:37 +0300 Subject: [PATCH 11/47] Resolve rebase --- .../locales/en-US/infer.ftl | 2 -- compiler/rustc_infer/src/errors/mod.rs | 10 ------- .../src/errors/note_and_explain.rs | 4 --- .../src/infer/error_reporting/note.rs | 26 ++----------------- 4 files changed, 2 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index c257bf739d11a..0398634da021e 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -150,8 +150,6 @@ infer_region_explanation = {$pref_kind -> [lf_param_must_outlive] but lifetime parameter must outlive [lf_instantiated_with] lifetime instantiated with [lf_must_outlive] but lifetime must outlive - [type_valid_for] the type is valid for - [borrow_lasts_for] but the borrow lasts for [pointer_valid_for] the pointer is valid for [data_valid_for] but the referenced data is only valid for [empty] {""} diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 7088be05ef78d..49b6a325f68e3 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -971,16 +971,6 @@ pub struct LfBoundNotSatisfied<'a> { pub notes: Vec>, } -#[derive(Diagnostic)] -#[diag(infer_borrowed_too_long, code = "E0490")] -pub struct BorrowedTooLong<'a> { - #[primary_span] - pub span: Span, - pub ty: Ty<'a>, - #[subdiagnostic] - pub notes: Vec>, -} - #[derive(Diagnostic)] #[diag(infer_ref_longer_than_data, code = "E0491")] pub struct RefLongerThanData<'a> { diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index b212a5a09c01d..cb96aeec5f34f 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -131,8 +131,6 @@ pub enum PrefixKind { LfParamMustOutlive, LfInstantiatedWith, LfMustOutlive, - TypeValidFor, - BorrowLastsFor, PointerValidFor, DataValidFor, } @@ -157,8 +155,6 @@ impl IntoDiagnosticArg for PrefixKind { Self::LfParamMustOutlive => "lf_param_must_outlive", Self::LfInstantiatedWith => "lf_instantiated_with", Self::LfMustOutlive => "lf_must_outlive", - Self::TypeValidFor => "type_valid_for", - Self::BorrowLastsFor => "borrow_lasts_for", Self::PointerValidFor => "pointer_valid_for", Self::DataValidFor => "data_valid_for", } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index adf240e7ce5d7..c43e5713283ad 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,6 +1,6 @@ use crate::errors::{ - note_and_explain, BorrowedTooLong, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, - OutlivesContent, RefLongerThanData, RegionOriginNote, + note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, + RefLongerThanData, RegionOriginNote, }; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; @@ -200,28 +200,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) } - infer::DataBorrowed(ty, span) => { - let type_valid = note_and_explain::RegionExplanation::new( - self.tcx, - sub, - None, - note_and_explain::PrefixKind::TypeValidFor, - note_and_explain::SuffixKind::Empty, - ); - let borrow_lasts_for = note_and_explain::RegionExplanation::new( - self.tcx, - sup, - None, - note_and_explain::PrefixKind::BorrowLastsFor, - note_and_explain::SuffixKind::Empty, - ); - BorrowedTooLong { - span, - ty: self.resolve_vars_if_possible(ty), - notes: type_valid.into_iter().chain(borrow_lasts_for).collect(), - } - .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic) - } infer::ReferenceOutlivesReferent(ty, span) => { let pointer_valid = note_and_explain::RegionExplanation::new( self.tcx, From b8feb63345b70f98c33ce68e844d9334b9a6f847 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 22 Jan 2023 18:16:47 +0300 Subject: [PATCH 12/47] Port WhereClauseSuggestions --- .../locales/en-US/infer.ftl | 3 ++ compiler/rustc_infer/src/errors/mod.rs | 26 +++++++++++++++++ .../src/infer/error_reporting/note.rs | 28 ++++++++----------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 0398634da021e..f7e1420d76c43 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -327,3 +327,6 @@ infer_ril_introduced_here = `'static` requirement introduced here infer_ril_introduced_by = requirement introduced by this return type infer_ril_because_of = because of this returned expression infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type + +infer_where_remove = remove the `where` clause +infer_where_copy_predicates = copy the `where` clause predicates from the trait diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 49b6a325f68e3..7fa04043edf4d 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -980,3 +980,29 @@ pub struct RefLongerThanData<'a> { #[subdiagnostic] pub notes: Vec>, } + +#[derive(Subdiagnostic)] +pub enum WhereClauseSuggestions { + #[suggestion( + infer_where_remove, + code = "", + applicability = "machine-applicable", + style = "verbose" + )] + Remove { + #[primary_span] + span: Span, + }, + #[suggestion( + infer_where_copy_predicates, + code = "{space}where {}", + applicability = "machine-applicable", + style = "verbose" + )] + CopyPredicates { + #[primary_span] + span: Span, + space: &'static str, + trait_predicates: String, + }, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index c43e5713283ad..e0e89158a5838 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -1,12 +1,11 @@ use crate::errors::{ note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, - RefLongerThanData, RegionOriginNote, + RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, }; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; use rustc_errors::{ - fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, - IntoDiagnostic, + fluent, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, }; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::traits::ObligationCauseCode; @@ -325,22 +324,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { return; }; - if trait_predicates.is_empty() { - err.span_suggestion_verbose( - generics.where_clause_span, - "remove the `where` clause", - String::new(), - Applicability::MachineApplicable, - ); + let suggestion = if trait_predicates.is_empty() { + WhereClauseSuggestions::Remove { span: generics.where_clause_span } } else { let space = if generics.where_clause_span.is_empty() { " " } else { "" }; - err.span_suggestion_verbose( - generics.where_clause_span, - "copy the `where` clause predicates from the trait", - format!("{space}where {}", trait_predicates.join(", ")), - Applicability::MachineApplicable, - ); - } + WhereClauseSuggestions::CopyPredicates { + span: generics.where_clause_span, + space, + trait_predicates: trait_predicates.join(", "), + } + }; + err.subdiagnostic(suggestion); } pub(super) fn report_placeholder_failure( From 6fa4c7d89c48146af0b246c7640ad3a611412a23 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 22 Jan 2023 18:54:47 +0300 Subject: [PATCH 13/47] Make sure tests pass --- compiler/rustc_infer/src/errors/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 7fa04043edf4d..83c5178751696 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -995,7 +995,7 @@ pub enum WhereClauseSuggestions { }, #[suggestion( infer_where_copy_predicates, - code = "{space}where {}", + code = "{space}where {trait_predicates}", applicability = "machine-applicable", style = "verbose" )] From 9f06c3d87f5a40078319e60ebe91bba279bf3f76 Mon Sep 17 00:00:00 2001 From: IQuant Date: Sat, 28 Jan 2023 19:41:14 +0300 Subject: [PATCH 14/47] Port SuggestRemoveSemiOrReturnBinding --- .../locales/en-US/infer.ftl | 5 ++ compiler/rustc_infer/src/errors/mod.rs | 44 ++++++++++ .../src/infer/error_reporting/mod.rs | 14 ++-- .../src/infer/error_reporting/suggest.rs | 80 +++++++++---------- 4 files changed, 97 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index f7e1420d76c43..1019b6114641c 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -330,3 +330,8 @@ infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by t infer_where_remove = remove the `where` clause infer_where_copy_predicates = copy the `where` clause predicates from the trait + +infer_srs_remove_and_box = consider removing this semicolon and boxing the expressions +infer_srs_remove = consider removing this semicolon +infer_srs_add = consider returning the local binding `{$ident}` +infer_srs_add_one = consider returning one of these bindings diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 83c5178751696..41691ff4f72bc 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1006,3 +1006,47 @@ pub enum WhereClauseSuggestions { trait_predicates: String, }, } + +#[derive(Subdiagnostic)] +pub enum SuggestRemoveSemiOrReturnBinding { + #[multipart_suggestion(infer_srs_remove_and_box, applicability = "machine-applicable")] + RemoveAndBox { + #[suggestion_part(code = "Box::new(")] + first_lo: Span, + #[suggestion_part(code = ")")] + first_hi: Span, + #[suggestion_part(code = "Box::new(")] + second_lo: Span, + #[suggestion_part(code = ")")] + second_hi: Span, + #[suggestion_part(code = "")] + sp: Span, + }, + #[suggestion( + infer_srs_remove, + style = "short", + code = "", + applicability = "machine-applicable" + )] + Remove { + #[primary_span] + sp: Span, + }, + #[suggestion( + infer_srs_add, + style = "verbose", + code = "{code}", + applicability = "maybe-incorrect" + )] + Add { + #[primary_span] + sp: Span, + code: String, + ident: Ident, + }, + #[note(infer_srs_add_one)] + AddOne { + #[primary_span] + spans: MultiSpan, + }, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index c56149c114920..ae231b1188d3c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -750,15 +750,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let msg = "`match` arms have incompatible types"; err.span_label(outer, msg); - self.suggest_remove_semi_or_return_binding( - err, + if let Some(subdiag) = self.suggest_remove_semi_or_return_binding( prior_arm_block_id, prior_arm_ty, prior_arm_span, arm_block_id, arm_ty, arm_span, - ); + ) { + err.subdiagnostic(subdiag); + } if let Some(ret_sp) = opt_suggest_box_span { // Get return type span and point to it. self.suggest_boxing_for_return_impl_trait( @@ -783,15 +784,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some(sp) = outer_span { err.span_label(sp, "`if` and `else` have incompatible types"); } - self.suggest_remove_semi_or_return_binding( - err, + if let Some(subdiag) = self.suggest_remove_semi_or_return_binding( Some(then_id), then_ty, then_span, Some(else_id), else_ty, else_span, - ); + ) { + err.subdiagnostic(subdiag); + } if let Some(ret_sp) = opt_suggest_box_span { self.suggest_boxing_for_return_impl_trait( err, diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 7d9a53d1c025f..8d84264ee8c0d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -11,21 +11,20 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitable}; use rustc_span::{sym, BytePos, Span}; -use crate::errors::SuggAddLetForLetChains; +use crate::errors::{SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding}; use super::TypeErrCtxt; impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub(super) fn suggest_remove_semi_or_return_binding( &self, - err: &mut Diagnostic, first_id: Option, first_ty: Ty<'tcx>, first_span: Span, second_id: Option, second_ty: Ty<'tcx>, second_span: Span, - ) { + ) -> Option { let remove_semicolon = [ (first_id, self.resolve_vars_if_possible(second_ty)), (second_id, self.resolve_vars_if_possible(first_ty)), @@ -37,35 +36,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }); match remove_semicolon { Some((sp, StatementAsExpression::NeedsBoxing)) => { - err.multipart_suggestion( - "consider removing this semicolon and boxing the expressions", - vec![ - (first_span.shrink_to_lo(), "Box::new(".to_string()), - (first_span.shrink_to_hi(), ")".to_string()), - (second_span.shrink_to_lo(), "Box::new(".to_string()), - (second_span.shrink_to_hi(), ")".to_string()), - (sp, String::new()), - ], - Applicability::MachineApplicable, - ); + Some(SuggestRemoveSemiOrReturnBinding::RemoveAndBox { + first_lo: first_span.shrink_to_lo(), + first_hi: first_span.shrink_to_hi(), + second_lo: second_span.shrink_to_lo(), + second_hi: second_span.shrink_to_hi(), + sp, + }) } Some((sp, StatementAsExpression::CorrectType)) => { - err.span_suggestion_short( - sp, - "consider removing this semicolon", - "", - Applicability::MachineApplicable, - ); + Some(SuggestRemoveSemiOrReturnBinding::Remove { sp }) } None => { + let mut ret = None; for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] { if let Some(id) = id && let hir::Node::Block(blk) = self.tcx.hir().get(id) - && self.consider_returning_binding(blk, ty, err) + && let Some(diag) = self.consider_returning_binding_diag(blk, ty) { + ret = Some(diag); break; } } + ret } } } @@ -655,16 +648,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { /// Suggest returning a local binding with a compatible type if the block /// has no return expression. - pub fn consider_returning_binding( + pub fn consider_returning_binding_diag( &self, blk: &'tcx hir::Block<'tcx>, expected_ty: Ty<'tcx>, - err: &mut Diagnostic, - ) -> bool { + ) -> Option { let blk = blk.innermost_block(); // Do not suggest if we have a tail expr. if blk.expr.is_some() { - return false; + return None; } let mut shadowed = FxIndexSet::default(); let mut candidate_idents = vec![]; @@ -733,7 +725,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { match &candidate_idents[..] { [(ident, _ty)] => { let sm = self.tcx.sess.source_map(); - if let Some(stmt) = blk.stmts.last() { + let (span, sugg) = if let Some(stmt) = blk.stmts.last() { let stmt_span = sm.stmt_span(stmt.span, blk.span); let sugg = if sm.is_multiline(blk.span) && let Some(spacing) = sm.indentation_before(stmt_span) @@ -742,12 +734,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } else { format!(" {ident}") }; - err.span_suggestion_verbose( - stmt_span.shrink_to_hi(), - format!("consider returning the local binding `{ident}`"), - sugg, - Applicability::MaybeIncorrect, - ); + (stmt_span.shrink_to_hi(), sugg) } else { let sugg = if sm.is_multiline(blk.span) && let Some(spacing) = sm.indentation_before(blk.span.shrink_to_lo()) @@ -757,21 +744,34 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { format!(" {ident} ") }; let left_span = sm.span_through_char(blk.span, '{').shrink_to_hi(); - err.span_suggestion_verbose( + ( sm.span_extend_while(left_span, |c| c.is_whitespace()).unwrap_or(left_span), - format!("consider returning the local binding `{ident}`"), sugg, - Applicability::MaybeIncorrect, - ); - } - true + ) + }; + Some(SuggestRemoveSemiOrReturnBinding::Add { sp: span, code: sugg, ident: *ident }) } values if (1..3).contains(&values.len()) => { let spans = values.iter().map(|(ident, _)| ident.span).collect::>(); - err.span_note(spans, "consider returning one of these bindings"); + Some(SuggestRemoveSemiOrReturnBinding::AddOne { spans: spans.into() }) + } + _ => None, + } + } + + pub fn consider_returning_binding( + &self, + blk: &'tcx hir::Block<'tcx>, + expected_ty: Ty<'tcx>, + err: &mut Diagnostic, + ) -> bool { + let diag = self.consider_returning_binding_diag(blk, expected_ty); + match diag { + Some(diag) => { + err.subdiagnostic(diag); true } - _ => false, + None => false, } } } From fdbec623c42ef022bd9461fef7639358a7b2968f Mon Sep 17 00:00:00 2001 From: IQuant Date: Tue, 31 Jan 2023 19:12:48 +0300 Subject: [PATCH 15/47] Port ConsiderAddingAwait --- .../locales/en-US/infer.ftl | 4 ++ compiler/rustc_infer/src/errors/mod.rs | 43 ++++++++++++ .../src/infer/error_reporting/suggest.rs | 65 ++++++++----------- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 1019b6114641c..8f4ac5234ce33 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -335,3 +335,7 @@ infer_srs_remove_and_box = consider removing this semicolon and boxing the expre infer_srs_remove = consider removing this semicolon infer_srs_add = consider returning the local binding `{$ident}` infer_srs_add_one = consider returning one of these bindings + +infer_await_both_futures = consider `await`ing on both `Future`s +infer_await_future = consider `await`ing on the `Future` +infer_await_note = calling an async function returns a future \ No newline at end of file diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 41691ff4f72bc..ba9821b2151bb 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1050,3 +1050,46 @@ pub enum SuggestRemoveSemiOrReturnBinding { spans: MultiSpan, }, } + +#[derive(Subdiagnostic)] +pub enum ConsiderAddingAwait { + #[help(infer_await_both_futures)] + BothFuturesHelp, + #[multipart_suggestion(infer_await_both_futures, applicability = "maybe-incorrect")] + BothFuturesSugg { + #[suggestion_part(code = ".await")] + first: Span, + #[suggestion_part(code = ".await")] + second: Span, + }, + #[suggestion( + infer_await_future, + code = ".await", + style = "verbose", + applicability = "maybe-incorrect" + )] + FutureSugg { + #[primary_span] + span: Span, + }, + #[suggestion( + infer_await_future, + code = ".await", + style = "verbose", + applicability = "maybe-incorrect" + )] + #[note(infer_await_note)] + FutureSuggWithNote { + #[primary_span] + span: Span, + }, + #[multipart_suggestion( + infer_await_future, + style = "verbose", + applicability = "maybe-incorrect" + )] + FutureSuggMultiple { + #[suggestion_part(code = ".await")] + spans: Vec, + }, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 8d84264ee8c0d..b183abf977f4d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -11,7 +11,9 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitable}; use rustc_span::{sym, BytePos, Span}; -use crate::errors::{SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding}; +use crate::errors::{ + ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding, +}; use super::TypeErrCtxt; @@ -191,7 +193,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return; } - match ( + let subdiag = match ( self.get_impl_future_output_ty(exp_found.expected), self.get_impl_future_output_ty(exp_found.found), ) { @@ -200,65 +202,52 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { let then_span = self.find_block_span_from_hir_id(*then_id); - diag.multipart_suggestion( - "consider `await`ing on both `Future`s", - vec![ - (then_span.shrink_to_hi(), ".await".to_string()), - (exp_span.shrink_to_hi(), ".await".to_string()), - ], - Applicability::MaybeIncorrect, - ); + Some(ConsiderAddingAwait::BothFuturesSugg { + first: then_span.shrink_to_hi(), + second: exp_span.shrink_to_hi(), + }) } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { prior_arms, .. }) => { if let [.., arm_span] = &prior_arms[..] { - diag.multipart_suggestion( - "consider `await`ing on both `Future`s", - vec![ - (arm_span.shrink_to_hi(), ".await".to_string()), - (exp_span.shrink_to_hi(), ".await".to_string()), - ], - Applicability::MaybeIncorrect, - ); + Some(ConsiderAddingAwait::BothFuturesSugg { + first: arm_span.shrink_to_hi(), + second: exp_span.shrink_to_hi(), + }) } else { - diag.help("consider `await`ing on both `Future`s"); + Some(ConsiderAddingAwait::BothFuturesHelp) } } - _ => { - diag.help("consider `await`ing on both `Future`s"); - } + _ => Some(ConsiderAddingAwait::BothFuturesHelp), }, (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { - self.suggest_await_on_future(diag, exp_span); - diag.span_note(exp_span, "calling an async function returns a future"); + Some(ConsiderAddingAwait::FutureSuggWithNote { span: exp_span.shrink_to_hi() }) } (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() { ObligationCauseCode::Pattern { span: Some(then_span), .. } => { - self.suggest_await_on_future(diag, then_span.shrink_to_hi()); + Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() }) } ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => { let then_span = self.find_block_span_from_hir_id(*then_id); - self.suggest_await_on_future(diag, then_span.shrink_to_hi()); + Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() }) } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { ref prior_arms, .. - }) => { - diag.multipart_suggestion_verbose( - "consider `await`ing on the `Future`", - prior_arms - .iter() - .map(|arm| (arm.shrink_to_hi(), ".await".to_string())) - .collect(), - Applicability::MaybeIncorrect, - ); - } - _ => {} + }) => Some({ + ConsiderAddingAwait::FutureSuggMultiple { + spans: prior_arms.iter().map(|arm| arm.shrink_to_hi()).collect(), + } + }), + _ => None, }, - _ => {} + _ => None, + }; + if let Some(subdiag) = subdiag { + diag.subdiagnostic(subdiag); } } From 5c7afde6f2729963b06477f25ef66680e68e434f Mon Sep 17 00:00:00 2001 From: IQuant Date: Fri, 3 Feb 2023 17:24:53 +0300 Subject: [PATCH 16/47] Port PlaceholderRelationLfNotSatisfied diagnostic --- .../locales/en-US/infer.ftl | 8 ++- compiler/rustc_infer/src/errors/mod.rs | 59 +++++++++++++++++ .../nice_region_error/placeholder_relation.rs | 66 +++++++++++-------- 3 files changed, 103 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 8f4ac5234ce33..c5b2b6c2d7357 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -338,4 +338,10 @@ infer_srs_add_one = consider returning one of these bindings infer_await_both_futures = consider `await`ing on both `Future`s infer_await_future = consider `await`ing on the `Future` -infer_await_note = calling an async function returns a future \ No newline at end of file +infer_await_note = calling an async function returns a future + +infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here... +infer_prlf_defined_without_sub = the lifetime defined here... +infer_prlf_must_oultive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here +infer_prlf_must_oultive_without_sup = ...must outlive the lifetime defined here +infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 for more information) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index ba9821b2151bb..f4af251d11fc8 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1093,3 +1093,62 @@ pub enum ConsiderAddingAwait { spans: Vec, }, } + +#[derive(Diagnostic)] +pub enum PlaceholderRelationLfNotSatisfied { + #[diag(infer_lf_bound_not_satisfied)] + HasBoth { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_with_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_with_sup)] + sup_span: Span, + sub_symbol: Symbol, + sup_symbol: Symbol, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + HasSub { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_with_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_without_sup)] + sup_span: Span, + sub_symbol: Symbol, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + HasSup { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_without_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_with_sup)] + sup_span: Span, + sup_symbol: Symbol, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + HasNone { + #[primary_span] + span: Span, + #[note(infer_prlf_defined_without_sub)] + sub_span: Span, + #[note(infer_prlf_must_oultive_without_sup)] + sup_span: Span, + #[note(infer_prlf_known_limitation)] + note: (), + }, + #[diag(infer_lf_bound_not_satisfied)] + OnlyPrimarySpan { + #[primary_span] + span: Span, + #[note(infer_prlf_known_limitation)] + note: (), + }, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs index 9534bce54ef0e..e8d94f0c04eaa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs @@ -1,5 +1,8 @@ -use crate::infer::{ - error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin, +use crate::{ + errors::PlaceholderRelationLfNotSatisfied, + infer::{ + error_reporting::nice_region_error::NiceRegionError, RegionResolutionError, SubregionOrigin, + }, }; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; @@ -16,8 +19,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { Region(Interned(RePlaceholder(ty::Placeholder { name: sub_name, .. }), _)), Region(Interned(RePlaceholder(ty::Placeholder { name: sup_name, .. }), _)), )) => { - let msg = "lifetime bound not satisfied"; - let mut err = self.tcx().sess.struct_span_err(*span, msg); + let span = *span; let (sub_span, sub_symbol) = match sub_name { ty::BrNamed(def_id, symbol) => { (Some(self.tcx().def_span(def_id)), Some(symbol)) @@ -32,41 +34,47 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { ty::BrAnon(_, span) => (*span, None), ty::BrEnv => (None, None), }; - match (sub_span, sup_span, sub_symbol, sup_symbol) { - (Some(sub_span), Some(sup_span), Some(sub_symbol), Some(sup_symbol)) => { - err.span_note( + let diag = match (sub_span, sup_span, sub_symbol, sup_symbol) { + (Some(sub_span), Some(sup_span), Some(&sub_symbol), Some(&sup_symbol)) => { + PlaceholderRelationLfNotSatisfied::HasBoth { + span, sub_span, - format!("the lifetime `{sub_symbol}` defined here..."), - ); - err.span_note( sup_span, - format!("...must outlive the lifetime `{sup_symbol}` defined here"), - ); + sub_symbol, + sup_symbol, + note: (), + } } - (Some(sub_span), Some(sup_span), _, Some(sup_symbol)) => { - err.span_note(sub_span, "the lifetime defined here..."); - err.span_note( + (Some(sub_span), Some(sup_span), _, Some(&sup_symbol)) => { + PlaceholderRelationLfNotSatisfied::HasSup { + span, + sub_span, sup_span, - format!("...must outlive the lifetime `{sup_symbol}` defined here"), - ); + sup_symbol, + note: (), + } } - (Some(sub_span), Some(sup_span), Some(sub_symbol), _) => { - err.span_note( + (Some(sub_span), Some(sup_span), Some(&sub_symbol), _) => { + PlaceholderRelationLfNotSatisfied::HasSub { + span, sub_span, - format!("the lifetime `{sub_symbol}` defined here..."), - ); - err.span_note(sup_span, "...must outlive the lifetime defined here"); + sup_span, + sub_symbol, + note: (), + } } (Some(sub_span), Some(sup_span), _, _) => { - err.span_note(sub_span, "the lifetime defined here..."); - err.span_note(sup_span, "...must outlive the lifetime defined here"); + PlaceholderRelationLfNotSatisfied::HasNone { + span, + sub_span, + sup_span, + note: (), + } } - _ => {} - } - err.note("this is a known limitation that will be removed in the future (see issue #100013 for more information)"); - Some(err) + _ => PlaceholderRelationLfNotSatisfied::OnlyPrimarySpan { span, note: () }, + }; + Some(self.tcx().sess.create_err(diag)) } - _ => None, } } From 03dff82d598233d4f1193d763f73c71a76ad6187 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:26:47 +0000 Subject: [PATCH 17/47] Add `of_trait` to DefKind::Impl. --- .../rustc_borrowck/src/diagnostics/mod.rs | 14 +++++----- .../src/diagnostics/region_name.rs | 4 +-- .../src/const_eval/fn_queries.rs | 3 +- compiler/rustc_hir/src/def.rs | 12 ++++---- compiler/rustc_hir/src/target.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 28 ++++++++++--------- .../src/coherence/inherent_impls.rs | 2 +- .../src/collect/lifetimes.rs | 2 +- .../rustc_hir_analysis/src/impl_wf_check.rs | 2 +- .../infer/error_reporting/need_type_info.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 16 +++++------ compiler/rustc_metadata/src/rmeta/table.rs | 3 +- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- .../rustc_monomorphize/src/polymorphize.rs | 2 +- compiler/rustc_passes/src/dead.rs | 8 ++---- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_passes/src/reachable.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 4 +-- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_save_analysis/src/lib.rs | 2 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 2 +- src/librustdoc/formats/item_type.rs | 2 +- .../passes/collect_intra_doc_links.rs | 4 +-- .../clippy_lints/src/same_name_method.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- 28 files changed, 68 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 3006e27e1d5b5..a89643fcfd484 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1182,13 +1182,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } let parent_did = tcx.parent(method_did); - let parent_self_ty = (tcx.def_kind(parent_did) - == rustc_hir::def::DefKind::Impl) - .then_some(parent_did) - .and_then(|did| match tcx.type_of(did).kind() { - ty::Adt(def, ..) => Some(def.did()), - _ => None, - }); + let parent_self_ty = + matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. }) + .then_some(parent_did) + .and_then(|did| match tcx.type_of(did).kind() { + ty::Adt(def, ..) => Some(def.did()), + _ => None, + }); let is_option_or_result = parent_self_ty.map_or(false, |def_id| { matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result)) }); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 237e063d8d11f..a82e695d64905 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -852,9 +852,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let tcx = self.infcx.tcx; let region_parent = tcx.parent(region.def_id); - if tcx.def_kind(region_parent) != DefKind::Impl { + let DefKind::Impl { .. } = tcx.def_kind(region_parent) else { return None; - } + }; let found = tcx .any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region)); diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index f92277b111374..9eaab1f47a7ea 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -17,7 +17,8 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let parent_id = tcx.local_parent(def_id); - tcx.def_kind(parent_id) == DefKind::Impl && tcx.constness(parent_id) == hir::Constness::Const + matches!(tcx.def_kind(parent_id), DefKind::Impl { .. }) + && tcx.constness(parent_id) == hir::Constness::Const } /// Checks whether an item is considered to be `const`. If it is a constructor, it is const. If diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index f1801a0f844f7..0599ae04a90ab 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -116,7 +116,9 @@ pub enum DefKind { LifetimeParam, /// A use of `global_asm!`. GlobalAsm, - Impl, + Impl { + of_trait: bool, + }, Closure, Generator, } @@ -155,7 +157,7 @@ impl DefKind { DefKind::AnonConst => "constant expression", DefKind::InlineConst => "inline constant", DefKind::Field => "field", - DefKind::Impl => "implementation", + DefKind::Impl { .. } => "implementation", DefKind::Closure => "closure", DefKind::Generator => "generator", DefKind::ExternCrate => "extern crate", @@ -171,7 +173,7 @@ impl DefKind { | DefKind::AssocFn | DefKind::Enum | DefKind::OpaqueTy - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Use | DefKind::InlineConst | DefKind::ExternCrate => "an", @@ -216,7 +218,7 @@ impl DefKind { | DefKind::Use | DefKind::ForeignMod | DefKind::GlobalAsm - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::ImplTraitPlaceholder => None, } } @@ -255,7 +257,7 @@ impl DefKind { | DefKind::ForeignMod | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Field | DefKind::TyParam | DefKind::ConstParam diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 5917d5e346e37..961deac544a88 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -116,7 +116,7 @@ impl Target { DefKind::Union => Target::Union, DefKind::Trait => Target::Trait, DefKind::TraitAlias => Target::TraitAlias, - DefKind::Impl => Target::Impl, + DefKind::Impl { .. } => Target::Impl, _ => panic!("impossible case reached"), } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 15a66ccc0f412..02d7c7e9d8499 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -529,19 +529,21 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { check_enum(tcx, id.owner_id.def_id); } DefKind::Fn => {} // entirely within check_item_body - DefKind::Impl => { - let it = tcx.hir().item(id); - let hir::ItemKind::Impl(impl_) = it.kind else { return }; - debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); - if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { - check_impl_items_against_trait( - tcx, - it.span, - it.owner_id.def_id, - impl_trait_ref.subst_identity(), - &impl_.items, - ); - check_on_unimplemented(tcx, it); + DefKind::Impl { of_trait } => { + if of_trait { + let it = tcx.hir().item(id); + let hir::ItemKind::Impl(impl_) = it.kind else { return }; + debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); + if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { + check_impl_items_against_trait( + tcx, + it.span, + it.owner_id.def_id, + impl_trait_ref.subst_identity(), + &impl_.items, + ); + check_on_unimplemented(tcx, it); + } } } DefKind::Trait => { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 940a450101ca0..2d2ac4f61947b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -177,7 +177,7 @@ impl<'tcx> InherentCollect<'tcx> { } fn check_item(&mut self, id: hir::ItemId) { - if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl) { + if !matches!(self.tcx.def_kind(id.owner_id), DefKind::Impl { of_trait: false }) { return; } diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 3f8d620fe6934..d8606f759b24b 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -1563,7 +1563,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // See issue #83753. If someone writes an associated type on a non-trait, just treat it as // there being no supertrait HRTBs. match tcx.def_kind(def_id) { - DefKind::Trait | DefKind::TraitAlias | DefKind::Impl => {} + DefKind::Trait | DefKind::TraitAlias | DefKind::Impl { .. } => {} _ => break None, } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 4fe893442b9bd..4f30318412d7e 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -55,7 +55,7 @@ fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { let min_specialization = tcx.features().min_specialization; let module = tcx.hir_module_items(module_def_id); for id in module.items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) { enforce_impl_params_are_constrained(tcx, id.owner_id.def_id); if min_specialization { check_min_specialization(tcx, id.owner_id.def_id); diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index c092efbb557cf..2b5a19914a327 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1061,7 +1061,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { }; let parent_def_id = generics.parent.unwrap(); - if tcx.def_kind(parent_def_id) == DefKind::Impl { + if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) { let parent_ty = tcx.bound_type_of(parent_def_id).subst(tcx, substs); match (parent_ty.kind(), &ty.kind) { ( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 060ade8a42f71..43047051f0f65 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -838,7 +838,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::ForeignMod | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Field => true, DefKind::TyParam | DefKind::ConstParam @@ -873,7 +873,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool { | DefKind::ImplTraitPlaceholder | DefKind::Enum | DefKind::Union - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Trait | DefKind::TraitAlias | DefKind::Macro(..) @@ -951,7 +951,7 @@ fn should_encode_variances(def_kind: DefKind) -> bool { | DefKind::Const | DefKind::ForeignMod | DefKind::TyAlias - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Trait | DefKind::TraitAlias | DefKind::Macro(..) @@ -988,7 +988,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool { | DefKind::InlineConst | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Field | DefKind::TyParam | DefKind::Closure @@ -1018,7 +1018,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::TyAlias | DefKind::OpaqueTy | DefKind::ForeignTy - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::AssocFn | DefKind::AssocConst | DefKind::Closure @@ -1081,7 +1081,7 @@ fn should_encode_const(def_kind: DefKind) -> bool { | DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder | DefKind::ForeignTy - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::AssocFn | DefKind::Closure | DefKind::Generator @@ -1860,7 +1860,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { FxHashMap::default(); for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) { if let Some(trait_ref) = tcx.impl_trait_ref(id.owner_id) { let trait_ref = trait_ref.subst_identity(); @@ -2261,7 +2261,7 @@ pub fn provide(providers: &mut Providers) { let mut trait_impls = Vec::new(); for id in tcx.hir().items() { - if matches!(tcx.def_kind(id.owner_id), DefKind::Impl) + if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) && tcx.impl_trait_ref(id.owner_id).is_some() { trait_impls.push(id.owner_id.to_def_id()) diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 99bec570600a0..b89d48ec15ae9 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -136,7 +136,8 @@ fixed_size_enum! { ( Field ) ( LifetimeParam ) ( GlobalAsm ) - ( Impl ) + ( Impl { of_trait: false } ) + ( Impl { of_trait: true } ) ( Closure ) ( Generator ) ( Static(ast::Mutability::Not) ) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 7f2994fd79b98..ba93330d58120 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -203,7 +203,7 @@ impl<'hir> Map<'hir> { ItemKind::Use(..) => DefKind::Use, ItemKind::ForeignMod { .. } => DefKind::ForeignMod, ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, - ItemKind::Impl { .. } => DefKind::Impl, + ItemKind::Impl(impl_) => DefKind::Impl { of_trait: impl_.of_trait.is_some() }, }, Node::ForeignItem(item) => match item.kind { ForeignItemKind::Fn(..) => DefKind::Fn, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6d8c9d7376333..e49c6062b3354 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2427,7 +2427,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn impl_of_method(self, def_id: DefId) -> Option { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { let parent = self.parent(def_id); - if let DefKind::Impl = self.def_kind(parent) { + if let DefKind::Impl { .. } = self.def_kind(parent) { return Some(parent); } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e907ce46c86fb..35831ff870642 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -167,7 +167,7 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::Fn | DefKind::AssocFn | DefKind::AssocConst - | DefKind::Impl, + | DefKind::Impl { .. }, def_id, ) => Some(def_id), Res::Err => None, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 83b8988cecaf8..8f6338472df58 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1238,7 +1238,7 @@ impl<'v> RootCollector<'_, 'v> { collect_const_value(self.tcx, val, &mut self.output); } } - DefKind::Impl => { + DefKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { let item = self.tcx.hir().item(id); create_mono_items_for_default_impls(self.tcx, item, self.output); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index aba842817ef7a..207ad332c22c2 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -172,7 +172,7 @@ fn mark_used_by_default_parameters<'tcx>( | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl => { + | DefKind::Impl { .. } => { for param in &generics.params { debug!(?param, "(other)"); if let ty::GenericParamDefKind::Lifetime = param.kind { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 83adfeb6b10b6..fe0cb71d2c18d 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -526,10 +526,8 @@ fn check_item<'tcx>( } } } - DefKind::Impl => { - let of_trait = tcx.impl_trait_ref(id.owner_id); - - if of_trait.is_some() { + DefKind::Impl { of_trait } => { + if of_trait { worklist.push(id.owner_id.def_id); } @@ -541,7 +539,7 @@ fn check_item<'tcx>( // And we access the Map here to get HirId from LocalDefId for id in local_def_ids { - if of_trait.is_some() || has_allow_dead_code_or_lang_attr(tcx, id) { + if of_trait || has_allow_dead_code_or_lang_attr(tcx, id) { worklist.push(id); } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6afdcc37fe86e..678f1815d012c 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -145,7 +145,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { // Don't run unused pass for #[derive()] let parent = tcx.local_parent(local_def_id); - if let DefKind::Impl = tcx.def_kind(parent) + if let DefKind::Impl { .. } = tcx.def_kind(parent) && tcx.has_attr(parent.to_def_id(), sym::automatically_derived) { return; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index ad09522038678..9559ee9320f5c 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -320,7 +320,7 @@ fn check_item<'tcx>( worklist.push(id.owner_id.def_id); } - if !matches!(tcx.def_kind(id.owner_id), DefKind::Impl) { + if !matches!(tcx.def_kind(id.owner_id), DefKind::Impl { of_trait: true }) { return; } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9cff62e85146e..4675bd79c4629 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -593,7 +593,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { | DefKind::InlineConst | DefKind::Field | DefKind::GlobalAsm - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => (), } @@ -1997,7 +1997,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { // Subitems of inherent impls have their own publicity. // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. - DefKind::Impl => { + DefKind::Impl { .. } => { let item = tcx.hir().item(id); if let hir::ItemKind::Impl(ref impl_) = item.kind { let impl_vis = diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 44f3bf1be055d..e927ec9cb67ff 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -987,7 +987,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Generator, _, ) diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index a9a92cc4f62ed..ad151bc2e1bf5 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -733,7 +733,7 @@ impl<'tcx> SaveContext<'tcx> { | HirDefKind::Use | HirDefKind::Field | HirDefKind::GlobalAsm - | HirDefKind::Impl + | HirDefKind::Impl { .. } | HirDefKind::Closure | HirDefKind::Generator, _, diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 961c04974e508..2fe9d135fa562 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -21,7 +21,7 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { assumed_wf_types.extend(liberated_sig.inputs_and_output); tcx.intern_type_list(&assumed_wf_types) } - DefKind::Impl => { + DefKind::Impl { .. } => { match tcx.impl_trait_ref(def_id) { Some(trait_ref) => { let types: Vec<_> = trait_ref.skip_binder().substs.types().collect(); diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index aafedc17499a7..452e14918faf7 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -140,7 +140,7 @@ impl From for ItemType { | DefKind::Field | DefKind::LifetimeParam | DefKind::GlobalAsm - | DefKind::Impl + | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => Self::ForeignType, } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 7e3149a59e3af..b2208da9060dc 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -359,7 +359,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { _ => def_id, }) .and_then(|self_id| match tcx.def_kind(self_id) { - DefKind::Impl => self.def_id_to_res(self_id), + DefKind::Impl { .. } => self.def_id_to_res(self_id), DefKind::Use => None, def_kind => Some(Res::Def(def_kind, self_id)), }) @@ -1761,7 +1761,7 @@ fn resolution_failure( } Trait | TyAlias | ForeignTy | OpaqueTy | ImplTraitPlaceholder | TraitAlias | TyParam | Static(_) => "associated item", - Impl | GlobalAsm => unreachable!("not a path"), + Impl { .. } | GlobalAsm => unreachable!("not a path"), } } else { "associated item" diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 17763128cd143..a37e2772d3558 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { let mut map = FxHashMap::::default(); for id in cx.tcx.hir().items() { - if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl) + if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. }) && let item = cx.tcx.hir().item(id) && let ItemKind::Impl(Impl { items, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 26f279f55855f..3b8713e2b108c 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -552,7 +552,7 @@ fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) .filter(|item| item.ident.name == name) .map(|child| child.res.expect_non_local()) .collect(), - DefKind::Impl => tcx + DefKind::Impl { .. } => tcx .associated_item_def_ids(def_id) .iter() .copied() From 2a51e73ac9a1616300e3db93e094baa4b86b895f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:31:04 +0000 Subject: [PATCH 18/47] Do not fetch HIR for inherent impls. --- .../src/coherence/inherent_impls.rs | 92 ++++++++----------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 2d2ac4f61947b..f0b6ab03ad693 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -14,7 +14,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; use rustc_span::symbol::sym; -use rustc_span::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls(tcx: TyCtxt<'_>, (): ()) -> CrateInherentImpls { @@ -57,86 +56,76 @@ const ADD_ATTR: &str = "alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items"; impl<'tcx> InherentCollect<'tcx> { - fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) { - let impl_def_id = item.owner_id; - if let Some(def_id) = def_id.as_local() { + fn check_def_id(&mut self, impl_def_id: LocalDefId, self_ty: Ty<'tcx>, ty_def_id: DefId) { + if let Some(ty_def_id) = ty_def_id.as_local() { // Add the implementation to the mapping from implementation to base // type def ID, if there is a base type for this implementation and // the implementation does not have any associated traits. - let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); + let vec = self.impls_map.inherent_impls.entry(ty_def_id).or_default(); vec.push(impl_def_id.to_def_id()); return; } if self.tcx.features().rustc_attrs { - let hir::ItemKind::Impl(&hir::Impl { items, .. }) = item.kind else { - bug!("expected `impl` item: {:?}", item); - }; + let items = self.tcx.associated_item_def_ids(impl_def_id); - if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { + if !self.tcx.has_attr(ty_def_id, sym::rustc_has_incoherent_inherent_impls) { + let impl_span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, - span, + impl_span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(span, ADD_ATTR_TO_TY) + .span_help(impl_span, ADD_ATTR_TO_TY) .emit(); return; } - for impl_item in items { - if !self - .tcx - .has_attr(impl_item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl) - { + for &impl_item in items { + if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + let impl_span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, - span, + impl_span, E0390, "cannot define inherent `impl` for a type outside of the crate where the type is defined", ) .help(INTO_DEFINING_CRATE) - .span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR) + .span_help(self.tcx.def_span(impl_item), ADD_ATTR) .emit(); return; } } if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) { - self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id.def_id); + self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id); } else { bug!("unexpected self type: {:?}", self_ty); } } else { + let impl_span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, - span, + impl_span, E0116, "cannot define inherent `impl` for a type outside of the crate \ where the type is defined" ) - .span_label(span, "impl for type defined outside of crate.") + .span_label(impl_span, "impl for type defined outside of crate.") .note("define and implement a trait or new type instead") .emit(); } } - fn check_primitive_impl( - &mut self, - impl_def_id: LocalDefId, - ty: Ty<'tcx>, - items: &[hir::ImplItemRef], - span: Span, - ) { + fn check_primitive_impl(&mut self, impl_def_id: LocalDefId, ty: Ty<'tcx>) { + let items = self.tcx.associated_item_def_ids(impl_def_id); if !self.tcx.hir().rustc_coherence_is_core() { if self.tcx.features().rustc_attrs { - for item in items { - if !self - .tcx - .has_attr(item.id.owner_id.to_def_id(), sym::rustc_allow_incoherent_impl) - { + for &impl_item in items { + if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + let span = self.tcx.def_span(impl_def_id); struct_span_err!( self.tcx.sess, span, @@ -144,12 +133,13 @@ impl<'tcx> InherentCollect<'tcx> { "cannot define inherent `impl` for primitive types outside of `core`", ) .help(INTO_CORE) - .span_help(item.span, ADD_ATTR) + .span_help(self.tcx.def_span(impl_item), ADD_ATTR) .emit(); return; } } } else { + let span = self.tcx.def_span(impl_def_id); let mut err = struct_span_err!( self.tcx.sess, span, @@ -181,31 +171,23 @@ impl<'tcx> InherentCollect<'tcx> { return; } - let item = self.tcx.hir().item(id); - let impl_span = self.tcx.hir().span(id.hir_id()); - let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else { - return; - }; - - let self_ty = self.tcx.type_of(item.owner_id); + let id = id.owner_id.def_id; + let item_span = self.tcx.def_span(id); + let self_ty = self.tcx.type_of(id); match *self_ty.kind() { - ty::Adt(def, _) => { - self.check_def_id(item, self_ty, def.did(), impl_span); - } - ty::Foreign(did) => { - self.check_def_id(item, self_ty, did, impl_span); - } + ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), + ty::Foreign(did) => self.check_def_id(id, self_ty, did), ty::Dynamic(data, ..) if data.principal_def_id().is_some() => { - self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span); + self.check_def_id(id, self_ty, data.principal_def_id().unwrap()); } ty::Dynamic(..) => { struct_span_err!( self.tcx.sess, - impl_span, + item_span, E0785, "cannot define inherent `impl` for a dyn auto trait" ) - .span_label(impl_span, "impl requires at least one non-auto trait") + .span_label(item_span, "impl requires at least one non-auto trait") .note("define and implement a new trait or type instead") .emit(); } @@ -221,18 +203,16 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Ref(..) | ty::Never | ty::FnPtr(_) - | ty::Tuple(..) => { - self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span) - } + | ty::Tuple(..) => self.check_primitive_impl(id, self_ty), ty::Alias(..) | ty::Param(_) => { let mut err = struct_span_err!( self.tcx.sess, - impl_span, + item_span, E0118, "no nominal type found for inherent implementation" ); - err.span_label(impl_span, "impl requires a nominal type") + err.span_label(item_span, "impl requires a nominal type") .note("either implement a trait on it or create a newtype to wrap it instead"); err.emit(); @@ -245,7 +225,7 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => { - bug!("unexpected impl self type of impl: {:?} {:?}", item.owner_id, self_ty); + bug!("unexpected impl self type of impl: {:?} {:?}", id, self_ty); } ty::Error(_) => {} } From 58939b9520e71b6caa2ccc5ca28071e6379d39c0 Mon Sep 17 00:00:00 2001 From: IQuant Date: Tue, 14 Feb 2023 23:16:29 +0300 Subject: [PATCH 19/47] Specify correct spans in suggest_await_on_expect_found --- compiler/rustc_infer/src/errors/mod.rs | 8 +------- compiler/rustc_infer/src/infer/error_reporting/suggest.rs | 6 +++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index f4af251d11fc8..0c2713fb1a7c8 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1072,14 +1072,8 @@ pub enum ConsiderAddingAwait { #[primary_span] span: Span, }, - #[suggestion( - infer_await_future, - code = ".await", - style = "verbose", - applicability = "maybe-incorrect" - )] #[note(infer_await_note)] - FutureSuggWithNote { + FutureSuggNote { #[primary_span] span: Span, }, diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index b183abf977f4d..18c5097a26289 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -223,7 +223,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _ => Some(ConsiderAddingAwait::BothFuturesHelp), }, (_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => { - Some(ConsiderAddingAwait::FutureSuggWithNote { span: exp_span.shrink_to_hi() }) + // FIXME: Seems like we can't have a suggestion and a note with different spans in a single subdiagnostic + diag.subdiagnostic(ConsiderAddingAwait::FutureSugg { + span: exp_span.shrink_to_hi(), + }); + Some(ConsiderAddingAwait::FutureSuggNote { span: exp_span }) } (Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code() { From e9e12266ced4c43f07c53017f5ed094e93157a18 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:35:31 +0000 Subject: [PATCH 20/47] Do not fetch HIR for reachable. --- compiler/rustc_passes/src/reachable.rs | 29 ++++++++++++-------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 9559ee9320f5c..051100c56f813 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -325,26 +325,23 @@ fn check_item<'tcx>( } // We need only trait impls here, not inherent impls, and only non-exported ones - let item = tcx.hir().item(id); - if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) = - item.kind - { - if !effective_visibilities.is_reachable(item.owner_id.def_id) { - worklist.extend(items.iter().map(|ii_ref| ii_ref.id.owner_id.def_id)); + if effective_visibilities.is_reachable(id.owner_id.def_id) { + return; + } - let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else { - unreachable!(); - }; + let items = tcx.associated_item_def_ids(id.owner_id); + worklist.extend(items.iter().map(|ii_ref| ii_ref.expect_local())); - if !trait_def_id.is_local() { - return; - } + let Some(trait_def_id) = tcx.trait_id_of_impl(id.owner_id.to_def_id()) else { + unreachable!(); + }; - worklist.extend( - tcx.provided_trait_methods(trait_def_id).map(|assoc| assoc.def_id.expect_local()), - ); - } + if !trait_def_id.is_local() { + return; } + + worklist + .extend(tcx.provided_trait_methods(trait_def_id).map(|assoc| assoc.def_id.expect_local())); } fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { From facecf6e1b96f3dc1c2a3f1bcfb56caa018e78cf Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 18:49:54 +0000 Subject: [PATCH 21/47] Fetch less HIR in signature check. --- .../rustc_hir_analysis/src/check/check.rs | 99 ++--- .../src/check/compare_impl_item.rs | 64 ++-- compiler/rustc_hir_analysis/src/check/mod.rs | 20 +- tests/rustdoc-ui/issue-105742.rs | 21 - tests/rustdoc-ui/issue-105742.stderr | 362 +----------------- tests/ui/error-codes/E0520.stderr | 2 +- .../specialization-no-default.stderr | 10 +- .../ui/specialization/issue-50452-fail.stderr | 2 +- .../non-defaulted-item-fail.stderr | 12 +- .../specialization-no-default.stderr | 10 +- .../ui/traits/negative-impls/no-items.stderr | 2 +- 11 files changed, 97 insertions(+), 507 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 02d7c7e9d8499..d5def62885043 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -530,46 +530,33 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } DefKind::Fn => {} // entirely within check_item_body DefKind::Impl { of_trait } => { - if of_trait { - let it = tcx.hir().item(id); - let hir::ItemKind::Impl(impl_) = it.kind else { return }; - debug!("ItemKind::Impl {} with id {:?}", it.ident, it.owner_id); - if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.owner_id) { - check_impl_items_against_trait( - tcx, - it.span, - it.owner_id.def_id, - impl_trait_ref.subst_identity(), - &impl_.items, - ); - check_on_unimplemented(tcx, it); - } + if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(id.owner_id) { + check_impl_items_against_trait( + tcx, + id.owner_id.def_id, + impl_trait_ref.subst_identity(), + ); + check_on_unimplemented(tcx, id); } } DefKind::Trait => { - let it = tcx.hir().item(id); - let hir::ItemKind::Trait(_, _, _, _, items) = it.kind else { - return; - }; - check_on_unimplemented(tcx, it); - - for item in items.iter() { - let item = tcx.hir().trait_item(item.id); - match &item.kind { - hir::TraitItemKind::Fn(sig, _) => { - let abi = sig.header.abi; - fn_maybe_err(tcx, item.ident.span, abi); + let assoc_items = tcx.associated_items(id.owner_id); + check_on_unimplemented(tcx, id); + + for assoc_item in assoc_items.in_definition_order() { + match assoc_item.kind { + ty::AssocKind::Fn => { + let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi(); + fn_maybe_err(tcx, assoc_item.ident(tcx).span, abi); } - hir::TraitItemKind::Type(.., Some(default)) => { - let assoc_item = tcx.associated_item(item.owner_id); + ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => { let trait_substs = - InternalSubsts::identity_for_item(tcx, it.owner_id.to_def_id()); + InternalSubsts::identity_for_item(tcx, id.owner_id.to_def_id()); let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds( tcx, assoc_item, assoc_item, - default.span, - tcx.mk_trait_ref(it.owner_id.to_def_id(), trait_substs), + tcx.mk_trait_ref(id.owner_id.to_def_id(), trait_substs), ); } _ => {} @@ -681,7 +668,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { } } -pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { +pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) { // an error would be reported if this fails. let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id()); } @@ -691,7 +678,7 @@ pub(super) fn check_specialization_validity<'tcx>( trait_def: &ty::TraitDef, trait_item: &ty::AssocItem, impl_id: DefId, - impl_item: &hir::ImplItemRef, + impl_item: DefId, ) { let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) else { return }; let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| { @@ -737,10 +724,8 @@ pub(super) fn check_specialization_validity<'tcx>( fn check_impl_items_against_trait<'tcx>( tcx: TyCtxt<'tcx>, - full_impl_span: Span, impl_id: LocalDefId, impl_trait_ref: ty::TraitRef<'tcx>, - impl_item_refs: &[hir::ImplItemRef], ) { // If the trait reference itself is erroneous (so the compilation is going // to fail), skip checking the items here -- the `impl_item` table in `tcx` @@ -749,12 +734,14 @@ fn check_impl_items_against_trait<'tcx>( return; } + let impl_item_refs = tcx.associated_item_def_ids(impl_id); + // Negative impls are not expected to have any items match tcx.impl_polarity(impl_id) { ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { if let [first_item_ref, ..] = impl_item_refs { - let first_item_span = tcx.hir().impl_item(first_item_ref.id).span; + let first_item_span = tcx.def_span(first_item_ref); struct_span_err!( tcx.sess, first_item_span, @@ -769,43 +756,27 @@ fn check_impl_items_against_trait<'tcx>( let trait_def = tcx.trait_def(impl_trait_ref.def_id); - for impl_item in impl_item_refs { - let ty_impl_item = tcx.associated_item(impl_item.id.owner_id); + for &impl_item in impl_item_refs { + let ty_impl_item = tcx.associated_item(impl_item); let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id { tcx.associated_item(trait_item_id) } else { // Checked in `associated_item`. - tcx.sess.delay_span_bug(impl_item.span, "missing associated item in trait"); + tcx.sess.delay_span_bug(tcx.def_span(impl_item), "missing associated item in trait"); continue; }; - let impl_item_full = tcx.hir().impl_item(impl_item.id); - match impl_item_full.kind { - hir::ImplItemKind::Const(..) => { + match ty_impl_item.kind { + ty::AssocKind::Const => { let _ = tcx.compare_impl_const(( - impl_item.id.owner_id.def_id, + impl_item.expect_local(), ty_impl_item.trait_item_def_id.unwrap(), )); } - hir::ImplItemKind::Fn(..) => { - let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - compare_impl_method( - tcx, - &ty_impl_item, - &ty_trait_item, - impl_trait_ref, - opt_trait_span, - ); + ty::AssocKind::Fn => { + compare_impl_method(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref); } - hir::ImplItemKind::Type(impl_ty) => { - let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - compare_impl_ty( - tcx, - &ty_impl_item, - impl_ty.span, - &ty_trait_item, - impl_trait_ref, - opt_trait_span, - ); + ty::AssocKind::Type => { + compare_impl_ty(tcx, &ty_impl_item, &ty_trait_item, impl_trait_ref); } } @@ -840,6 +811,8 @@ fn check_impl_items_against_trait<'tcx>( .map_or(false, |node_item| !node_item.defining_node.is_from_trait()); if !is_implemented_here { + let full_impl_span = + tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); match tcx.eval_default_body_stability(trait_item_id, full_impl_span) { EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable( tcx, @@ -866,6 +839,8 @@ fn check_impl_items_against_trait<'tcx>( } if !missing_items.is_empty() { + let full_impl_span = + tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span); } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index a926deb2393de..50f9bbc022e7c 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -33,7 +33,6 @@ use std::iter; /// # Parameters /// /// - `impl_m`: type of the method we are checking -/// - `impl_m_span`: span to use for reporting errors /// - `trait_m`: the method in the trait /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation pub(super) fn compare_impl_method<'tcx>( @@ -41,23 +40,19 @@ pub(super) fn compare_impl_method<'tcx>( impl_m: &ty::AssocItem, trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, - trait_item_span: Option, ) { debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); - let impl_m_span = tcx.def_span(impl_m.def_id); - let _: Result<_, ErrorGuaranteed> = try { - compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref)?; - compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false)?; + compare_self_type(tcx, impl_m, trait_m, impl_trait_ref)?; + compare_number_of_generics(tcx, impl_m, trait_m, false)?; compare_generic_param_kinds(tcx, impl_m, trait_m, false)?; - compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?; + compare_number_of_method_arguments(tcx, impl_m, trait_m)?; compare_synthetic_generics(tcx, impl_m, trait_m)?; - compare_asyncness(tcx, impl_m, impl_m_span, trait_m, trait_item_span)?; + compare_asyncness(tcx, impl_m, trait_m)?; compare_method_predicate_entailment( tcx, impl_m, - impl_m_span, trait_m, impl_trait_ref, CheckImpliedWfMode::Check, @@ -131,11 +126,10 @@ pub(super) fn compare_impl_method<'tcx>( /// /// Finally we register each of these predicates as an obligation and check that /// they hold. -#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))] +#[instrument(level = "debug", skip(tcx, impl_trait_ref))] fn compare_method_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, check_implied_wf: CheckImpliedWfMode, @@ -148,6 +142,7 @@ fn compare_method_predicate_entailment<'tcx>( // FIXME(@lcnr): remove that after removing `cause.body_id` from // obligations. let impl_m_def_id = impl_m.def_id.expect_local(); + let impl_m_span = tcx.def_span(impl_m_def_id); let cause = ObligationCause::new( impl_m_span, impl_m_def_id, @@ -315,7 +310,6 @@ fn compare_method_predicate_entailment<'tcx>( return compare_method_predicate_entailment( tcx, impl_m, - impl_m_span, trait_m, impl_trait_ref, CheckImpliedWfMode::Skip, @@ -353,7 +347,6 @@ fn compare_method_predicate_entailment<'tcx>( return compare_method_predicate_entailment( tcx, impl_m, - impl_m_span, trait_m, impl_trait_ref, CheckImpliedWfMode::Skip, @@ -535,9 +528,7 @@ enum CheckImpliedWfMode { fn compare_asyncness<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, - trait_item_span: Option, ) -> Result<(), ErrorGuaranteed> { if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async { match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() { @@ -549,9 +540,9 @@ fn compare_asyncness<'tcx>( } _ => { return Err(tcx.sess.emit_err(crate::errors::AsyncTraitImplShouldBeAsync { - span: impl_m_span, + span: tcx.def_span(impl_m.def_id), method_name: trait_m.name, - trait_item_span, + trait_item_span: tcx.hir().span_if_local(trait_m.def_id), })); } }; @@ -606,7 +597,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during substitution later. - compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?; + compare_number_of_generics(tcx, impl_m, trait_m, true)?; compare_generic_param_kinds(tcx, impl_m, trait_m, true)?; check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?; @@ -1094,7 +1085,6 @@ fn extract_spans_for_error_reporting<'tcx>( fn compare_self_type<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { @@ -1130,6 +1120,7 @@ fn compare_self_type<'tcx>( (false, true) => { let self_descr = self_string(impl_m); + let impl_m_span = tcx.def_span(impl_m.def_id); let mut err = struct_span_err!( tcx.sess, impl_m_span, @@ -1149,6 +1140,7 @@ fn compare_self_type<'tcx>( (true, false) => { let self_descr = self_string(trait_m); + let impl_m_span = tcx.def_span(impl_m.def_id); let mut err = struct_span_err!( tcx.sess, impl_m_span, @@ -1196,7 +1188,6 @@ fn compare_number_of_generics<'tcx>( tcx: TyCtxt<'tcx>, impl_: &ty::AssocItem, trait_: &ty::AssocItem, - trait_span: Option, delay: bool, ) -> Result<(), ErrorGuaranteed> { let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts(); @@ -1256,6 +1247,7 @@ fn compare_number_of_generics<'tcx>( .collect(); (Some(arg_spans), impl_trait_spans) } else { + let trait_span = tcx.hir().span_if_local(trait_.def_id); (trait_span.map(|s| vec![s]), vec![]) }; @@ -1338,9 +1330,7 @@ fn compare_number_of_generics<'tcx>( fn compare_number_of_method_arguments<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, - impl_m_span: Span, trait_m: &ty::AssocItem, - trait_item_span: Option, ) -> Result<(), ErrorGuaranteed> { let impl_m_fty = tcx.fn_sig(impl_m.def_id); let trait_m_fty = tcx.fn_sig(trait_m.def_id); @@ -1362,7 +1352,7 @@ fn compare_number_of_method_arguments<'tcx>( } }) }) - .or(trait_item_span); + .or_else(|| tcx.hir().span_if_local(trait_m.def_id)); let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let pos = impl_number_args.saturating_sub(1); @@ -1377,7 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>( arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo()) } }) - .unwrap_or(impl_m_span); + .unwrap_or_else(|| tcx.def_span(impl_m.def_id)); let mut err = struct_span_err!( tcx.sess, @@ -1747,22 +1737,16 @@ pub(super) fn compare_impl_const_raw( pub(super) fn compare_impl_ty<'tcx>( tcx: TyCtxt<'tcx>, impl_ty: &ty::AssocItem, - impl_ty_span: Span, trait_ty: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, - trait_item_span: Option, ) { debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref); let _: Result<(), ErrorGuaranteed> = try { - compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?; - + compare_number_of_generics(tcx, impl_ty, trait_ty, false)?; compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?; - - let sp = tcx.def_span(impl_ty.def_id); - compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?; - - check_type_bounds(tcx, trait_ty, impl_ty, impl_ty_span, impl_trait_ref)?; + compare_type_predicate_entailment(tcx, impl_ty, trait_ty, impl_trait_ref)?; + check_type_bounds(tcx, trait_ty, impl_ty, impl_trait_ref)?; }; } @@ -1771,7 +1755,6 @@ pub(super) fn compare_impl_ty<'tcx>( fn compare_type_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, impl_ty: &ty::AssocItem, - impl_ty_span: Span, trait_ty: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { @@ -1808,6 +1791,7 @@ fn compare_type_predicate_entailment<'tcx>( debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); + let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id); let param_env = ty::ParamEnv::new( tcx.intern_predicates(&hybrid_preds.predicates), @@ -1873,7 +1857,6 @@ pub(super) fn check_type_bounds<'tcx>( tcx: TyCtxt<'tcx>, trait_ty: &ty::AssocItem, impl_ty: &ty::AssocItem, - impl_ty_span: Span, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { // Given @@ -2009,8 +1992,15 @@ pub(super) fn check_type_bounds<'tcx>( let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); - let assumed_wf_types = - ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty.def_id.expect_local()); + let impl_ty_span = match tcx.hir().get_by_def_id(impl_ty_def_id) { + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(_, Some(ty)), + .. + }) => ty.span, + hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span, + _ => bug!(), + }; + let assumed_wf_types = ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty_def_id); let normalize_cause = ObligationCause::new( impl_ty_span, diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index bec693439a46c..7b013cabc3ab5 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -75,7 +75,6 @@ pub use check::check_abi; use check::check_mod_item_types; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; -use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; @@ -169,27 +168,24 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { } } -fn report_forbidden_specialization( - tcx: TyCtxt<'_>, - impl_item: &hir::ImplItemRef, - parent_impl: DefId, -) { +fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_impl: DefId) { + let span = tcx.def_span(impl_item); + let ident = tcx.item_name(impl_item); let mut err = struct_span_err!( tcx.sess, - impl_item.span, + span, E0520, - "`{}` specializes an item from a parent `impl`, but \ - that item is not marked `default`", - impl_item.ident + "`{}` specializes an item from a parent `impl`, but that item is not marked `default`", + ident, ); - err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident)); + err.span_label(span, format!("cannot specialize default item `{}`", ident)); match tcx.span_of_impl(parent_impl) { Ok(span) => { err.span_label(span, "parent `impl` is here"); err.note(&format!( "to specialize, `{}` in the parent `impl` must be marked `default`", - impl_item.ident + ident )); } Err(cname) => { diff --git a/tests/rustdoc-ui/issue-105742.rs b/tests/rustdoc-ui/issue-105742.rs index cb1de7433cfaa..9f36e5315ecc2 100644 --- a/tests/rustdoc-ui/issue-105742.rs +++ b/tests/rustdoc-ui/issue-105742.rs @@ -3,38 +3,17 @@ use std::ops::Index; pub fn next<'a, T>(s: &'a mut dyn SVec) { -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR let _ = s; } pub trait SVec: Index< ::Item, -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR Output = ::Item, -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR Output = ::Item> as SVec>::Item, -//~^ ERROR -//~^^ ERROR -//~^^^ ERROR -//~^^^^ ERROR -//~^^^^^ ERROR -//~^^^^^^ ERROR -//~^^^^^^^ ERROR -//~^^^^^^^^ ERROR > { type Item<'a, T>; fn len(&self) -> ::Item; //~^ ERROR //~^^ ERROR - //~^^^ ERROR - //~^^^^ ERROR } diff --git a/tests/rustdoc-ui/issue-105742.stderr b/tests/rustdoc-ui/issue-105742.stderr index ffb602cf86190..4d2ee97268917 100644 --- a/tests/rustdoc-ui/issue-105742.stderr +++ b/tests/rustdoc-ui/issue-105742.stderr @@ -1,360 +1,11 @@ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>> as SVec>::Item, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item> as SVec>::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:5:40 - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:5:40 - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:13:21 - | -LL | ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:18:37 - | -LL | Output = ::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item<'a>> as SVec>::Item, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:30 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | Output = ::Item> as SVec>::Item<'a>, - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:23:46 - | -LL | Output = ::Item> as SVec>::Item, - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | Output = ::Item> as SVec>::Item, - | +++ - -error[E0038]: the trait `SVec` cannot be made into an object - --> $DIR/issue-105742.rs:5:31 - | -LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-105742.rs:12:17 - | -LL | pub trait SVec: Index< - | ____________----__^ - | | | - | | this trait cannot be made into an object... -LL | | ::Item, -LL | | -LL | | -... | -LL | |/ Output = ::Item, -LL | || -LL | || -LL | || -LL | || -LL | || Output = ::Item> as SVec>::Item, - | ||_________________________________________________^ ...because it uses `Self` as a type parameter -... | -LL | | -LL | | > { - | |__^ ...because it uses `Self` as a type parameter - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 - | -LL | fn len(&self) -> ::Item; - | ^^^^ expected 1 lifetime argument - | -note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ -- -help: add missing lifetime argument - | -LL | fn len(&self) -> ::Item<'_>; - | ++++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 - | -LL | fn len(&self) -> ::Item; - | ^^^^ expected 1 generic argument - | -note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 - | -LL | type Item<'a, T>; - | ^^^^ - -help: add missing generic argument - | -LL | fn len(&self) -> ::Item; - | +++ - -error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 + --> $DIR/issue-105742.rs:16:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:33:10 + --> $DIR/issue-105742.rs:14:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -364,13 +15,13 @@ LL | fn len(&self) -> ::Item<'_>; | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:35:38 + --> $DIR/issue-105742.rs:16:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:33:10 + --> $DIR/issue-105742.rs:14:10 | LL | type Item<'a, T>; | ^^^^ - @@ -379,7 +30,6 @@ help: add missing generic argument LL | fn len(&self) -> ::Item; | +++ -error: aborting due to 23 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/error-codes/E0520.stderr b/tests/ui/error-codes/E0520.stderr index 12ecead13de5f..06658a49b83aa 100644 --- a/tests/ui/error-codes/E0520.stderr +++ b/tests/ui/error-codes/E0520.stderr @@ -15,7 +15,7 @@ LL | impl SpaceLlama for T { | ------------------------------- parent `impl` is here ... LL | default fn fly(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `fly` + | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `fly` | = note: to specialize, `fly` in the parent `impl` must be marked `default` diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr index 770be2af28146..f9e62a99baee8 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.stderr +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.stderr @@ -15,7 +15,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn foo(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` @@ -26,7 +26,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn bar(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `bar` + | ^^^^^^^^^^^^^ cannot specialize default item `bar` | = note: to specialize, `bar` in the parent `impl` must be marked `default` @@ -37,7 +37,7 @@ LL | impl Bar for T { | ----------------- parent `impl` is here ... LL | type T = (); - | ^^^^^^^^^^^^ cannot specialize default item `T` + | ^^^^^^ cannot specialize default item `T` | = note: to specialize, `T` in the parent `impl` must be marked `default` @@ -48,7 +48,7 @@ LL | impl Baz for T { | ------------------------ parent `impl` is here ... LL | fn baz(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `baz` + | ^^^^^^^^^^^^^ cannot specialize default item `baz` | = note: to specialize, `baz` in the parent `impl` must be marked `default` @@ -59,7 +59,7 @@ LL | impl Redundant for T { | ------------------------------ parent `impl` is here ... LL | fn redundant(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` + | ^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` | = note: to specialize, `redundant` in the parent `impl` must be marked `default` diff --git a/tests/ui/specialization/issue-50452-fail.stderr b/tests/ui/specialization/issue-50452-fail.stderr index 5c136adc451d5..3fc29fff230a3 100644 --- a/tests/ui/specialization/issue-50452-fail.stderr +++ b/tests/ui/specialization/issue-50452-fail.stderr @@ -12,7 +12,7 @@ error[E0520]: `foo` specializes an item from a parent `impl`, but that item is n --> $DIR/issue-50452-fail.rs:10:5 | LL | fn foo() {} - | ^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^ cannot specialize default item `foo` ... LL | impl Foo for T { | ----------------- parent `impl` is here diff --git a/tests/ui/specialization/non-defaulted-item-fail.stderr b/tests/ui/specialization/non-defaulted-item-fail.stderr index faa14555a4f39..9d62a353da728 100644 --- a/tests/ui/specialization/non-defaulted-item-fail.stderr +++ b/tests/ui/specialization/non-defaulted-item-fail.stderr @@ -15,7 +15,7 @@ LL | impl Foo for Box { | ---------------------- parent `impl` is here ... LL | type Ty = Vec<()>; - | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `Ty` + | ^^^^^^^ cannot specialize default item `Ty` | = note: to specialize, `Ty` in the parent `impl` must be marked `default` @@ -26,7 +26,7 @@ LL | impl Foo for Box { | ---------------------- parent `impl` is here ... LL | const CONST: u8 = 42; - | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `CONST` + | ^^^^^^^^^^^^^^^ cannot specialize default item `CONST` | = note: to specialize, `CONST` in the parent `impl` must be marked `default` @@ -37,7 +37,7 @@ LL | impl Foo for Box { | ---------------------- parent `impl` is here ... LL | fn foo(&self) -> bool { true } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` @@ -48,7 +48,7 @@ LL | impl Foo for Vec {} | ---------------------- parent `impl` is here ... LL | type Ty = Vec<()>; - | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `Ty` + | ^^^^^^^ cannot specialize default item `Ty` | = note: to specialize, `Ty` in the parent `impl` must be marked `default` @@ -59,7 +59,7 @@ LL | impl Foo for Vec {} | ---------------------- parent `impl` is here ... LL | const CONST: u8 = 42; - | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `CONST` + | ^^^^^^^^^^^^^^^ cannot specialize default item `CONST` | = note: to specialize, `CONST` in the parent `impl` must be marked `default` @@ -70,7 +70,7 @@ LL | impl Foo for Vec {} | ---------------------- parent `impl` is here ... LL | fn foo(&self) -> bool { true } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` diff --git a/tests/ui/specialization/specialization-no-default.stderr b/tests/ui/specialization/specialization-no-default.stderr index 842cec9c79fbb..695a3f6cc45d1 100644 --- a/tests/ui/specialization/specialization-no-default.stderr +++ b/tests/ui/specialization/specialization-no-default.stderr @@ -15,7 +15,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn foo(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `foo` + | ^^^^^^^^^^^^^ cannot specialize default item `foo` | = note: to specialize, `foo` in the parent `impl` must be marked `default` @@ -26,7 +26,7 @@ LL | impl Foo for T { | ----------------- parent `impl` is here ... LL | fn bar(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `bar` + | ^^^^^^^^^^^^^ cannot specialize default item `bar` | = note: to specialize, `bar` in the parent `impl` must be marked `default` @@ -37,7 +37,7 @@ LL | impl Bar for T { | ----------------- parent `impl` is here ... LL | type T = (); - | ^^^^^^^^^^^^ cannot specialize default item `T` + | ^^^^^^ cannot specialize default item `T` | = note: to specialize, `T` in the parent `impl` must be marked `default` @@ -48,7 +48,7 @@ LL | impl Baz for T { | ------------------------ parent `impl` is here ... LL | fn baz(&self) {} - | ^^^^^^^^^^^^^^^^ cannot specialize default item `baz` + | ^^^^^^^^^^^^^ cannot specialize default item `baz` | = note: to specialize, `baz` in the parent `impl` must be marked `default` @@ -59,7 +59,7 @@ LL | impl Redundant for T { | ------------------------------ parent `impl` is here ... LL | default fn redundant(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `redundant` | = note: to specialize, `redundant` in the parent `impl` must be marked `default` diff --git a/tests/ui/traits/negative-impls/no-items.stderr b/tests/ui/traits/negative-impls/no-items.stderr index 67b94bba12143..040d9d14503f0 100644 --- a/tests/ui/traits/negative-impls/no-items.stderr +++ b/tests/ui/traits/negative-impls/no-items.stderr @@ -2,7 +2,7 @@ error[E0749]: negative impls cannot have any items --> $DIR/no-items.rs:8:5 | LL | type Foo = i32; - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to previous error From 0d39f9d94d2eddd31e4743ae1e3ea269bb3e0984 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 19:46:51 +0000 Subject: [PATCH 22/47] Do not fetch HIR to monomorphize impls. --- compiler/rustc_monomorphize/src/collector.rs | 114 +++++++------------ 1 file changed, 42 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8f6338472df58..dd7ee220d7311 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1191,28 +1191,14 @@ impl<'v> RootCollector<'_, 'v> { fn process_item(&mut self, id: hir::ItemId) { match self.tcx.def_kind(id.owner_id) { DefKind::Enum | DefKind::Struct | DefKind::Union => { - let item = self.tcx.hir().item(id); - match item.kind { - hir::ItemKind::Enum(_, ref generics) - | hir::ItemKind::Struct(_, ref generics) - | hir::ItemKind::Union(_, ref generics) => { - if generics.params.is_empty() { - if self.mode == MonoItemCollectionMode::Eager { - debug!( - "RootCollector: ADT drop-glue for {}", - self.tcx.def_path_str(item.owner_id.to_def_id()) - ); - - let ty = Instance::new( - item.owner_id.to_def_id(), - InternalSubsts::empty(), - ) - .ty(self.tcx, ty::ParamEnv::reveal_all()); - visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); - } - } - } - _ => bug!(), + if self.tcx.generics_of(id.owner_id).count() == 0 + && self.mode == MonoItemCollectionMode::Eager + { + debug!("RootCollector: ADT drop-glue for `{id:?}`",); + + let ty = + self.tcx.bound_type_of(id.owner_id.to_def_id()).no_bound_vars().unwrap(); + visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } } DefKind::GlobalAsm => { @@ -1240,8 +1226,7 @@ impl<'v> RootCollector<'_, 'v> { } DefKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { - let item = self.tcx.hir().item(id); - create_mono_items_for_default_impls(self.tcx, item, self.output); + create_mono_items_for_default_impls(self.tcx, id, self.output); } } DefKind::Fn => { @@ -1326,66 +1311,51 @@ fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { generics.requires_monomorphization(tcx) } +#[instrument(level = "debug", skip(tcx, output))] fn create_mono_items_for_default_impls<'tcx>( tcx: TyCtxt<'tcx>, - item: &'tcx hir::Item<'tcx>, + item: hir::ItemId, output: &mut MonoItems<'tcx>, ) { - match item.kind { - hir::ItemKind::Impl(ref impl_) => { - if matches!(impl_.polarity, hir::ImplPolarity::Negative(_)) { - return; - } + let polarity = tcx.impl_polarity(item.owner_id); + if matches!(polarity, ty::ImplPolarity::Negative) { + return; + } - for param in impl_.generics.params { - match param.kind { - hir::GenericParamKind::Lifetime { .. } => {} - hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => { - return; - } - } - } + if tcx.generics_of(item.owner_id).own_requires_monomorphization() { + return; + } - debug!( - "create_mono_items_for_default_impls(item={})", - tcx.def_path_str(item.owner_id.to_def_id()) - ); + let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else { + return; + }; - if let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) { - let trait_ref = trait_ref.subst_identity(); + let trait_ref = trait_ref.subst_identity(); - let param_env = ty::ParamEnv::reveal_all(); - let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); - let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); - for method in tcx.provided_trait_methods(trait_ref.def_id) { - if overridden_methods.contains_key(&method.def_id) { - continue; - } + let param_env = ty::ParamEnv::reveal_all(); + let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); + let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); + for method in tcx.provided_trait_methods(trait_ref.def_id) { + if overridden_methods.contains_key(&method.def_id) { + continue; + } - if tcx.generics_of(method.def_id).own_requires_monomorphization() { - continue; - } + if tcx.generics_of(method.def_id).own_requires_monomorphization() { + continue; + } - let substs = - InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize] - } - }); - let instance = - ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs); - - let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); - if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, &instance) - { - output.push(mono_item); - } - } + let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { + GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + trait_ref.substs[param.index as usize] } + }); + let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs); + + let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); + if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, &instance) { + output.push(mono_item); } - _ => bug!(), } } From e49e7f6a2e62670704ec52e10f7639c17afe4f8e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 20:15:12 +0000 Subject: [PATCH 23/47] Do not fetch HIR to compute symbols. --- .../src/back/symbol_export.rs | 67 ++++++++++--------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 57a99e74c21ad..11bd47a8f0c79 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -2,9 +2,8 @@ use std::collections::hash_map::Entry::*; use rustc_ast::expand::allocator::ALLOCATOR_METHODS; use rustc_data_structures::fx::FxHashMap; -use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; -use rustc_hir::Node; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::exported_symbols::{ metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel, @@ -12,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::Instance; -use rustc_middle::ty::{self, SymbolName, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, SymbolName, TyCtxt}; use rustc_session::config::{CrateType, OomStrategy}; use rustc_target::spec::SanitizerSet; @@ -74,32 +73,34 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< // // As a result, if this id is an FFI item (foreign item) then we only // let it through if it's included statically. - match tcx.hir().get_by_def_id(def_id) { - Node::ForeignItem(..) => { - tcx.native_library(def_id).map_or(false, |library| library.kind.is_statically_included()).then_some(def_id) - } + if let Some(parent_id) = tcx.opt_local_parent(def_id) + && let DefKind::ForeignMod = tcx.def_kind(parent_id) + { + let library = tcx.native_library(def_id)?; + return library.kind.is_statically_included().then_some(def_id); + } - // Only consider nodes that actually have exported symbols. - Node::Item(&hir::Item { - kind: hir::ItemKind::Static(..) | hir::ItemKind::Fn(..), - .. - }) - | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => { - let generics = tcx.generics_of(def_id); - if !generics.requires_monomorphization(tcx) - // Functions marked with #[inline] are codegened with "internal" - // linkage and are not exported unless marked with an extern - // indicator - && (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) - || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator()) - { - Some(def_id) - } else { - None - } - } + // Only consider nodes that actually have exported symbols. + match tcx.def_kind(def_id) { + DefKind::Fn | DefKind::Static(_) => {} + DefKind::AssocFn if tcx.impl_of_method(def_id.to_def_id()).is_some() => {} + _ => return None, + }; - _ => None, + let generics = tcx.generics_of(def_id); + if generics.requires_monomorphization(tcx) { + return None; + } + + // Functions marked with #[inline] are codegened with "internal" + // linkage and are not exported unless marked with an extern + // indicator + if !Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) + || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator() + { + Some(def_id) + } else { + None } }) .map(|def_id| { @@ -118,7 +119,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())), export_level ); - (def_id.to_def_id(), SymbolExportInfo { + let info = SymbolExportInfo { level: export_level, kind: if tcx.is_static(def_id.to_def_id()) { if codegen_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { @@ -130,8 +131,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< SymbolExportKind::Text }, used: codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) - || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) || used, - }) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + || used, + }; + (def_id.to_def_id(), info) }) .collect(); @@ -457,9 +460,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel let target = &tcx.sess.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level if target.contains("emscripten") { - if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) = - tcx.hir().get_if_local(sym_def_id) - { + if let DefKind::Static(_) = tcx.def_kind(sym_def_id) { return SymbolExportLevel::Rust; } } From 68fb752035aa954b7881b846ec1cd5bd3354a4cf Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 20:20:45 +0000 Subject: [PATCH 24/47] Do not fetch HIR to check target features. --- compiler/rustc_codegen_ssa/src/target_features.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 739963fffd132..a6afbad5b2402 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -3,12 +3,12 @@ use rustc_attr::InstructionSetAttr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::sym; @@ -440,12 +440,9 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxHashSet { /// Checks the function annotated with `#[target_feature]` is not a safe /// trait method implementation, reporting an error if it is. pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) { - let hir_id = tcx.hir().local_def_id_to_hir_id(id); - let node = tcx.hir().get(hir_id); - if let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) = node { - let parent_id = tcx.hir().get_parent_item(hir_id); - let parent_item = tcx.hir().expect_item(parent_id.def_id); - if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = parent_item.kind { + if let DefKind::AssocFn = tcx.def_kind(id) { + let parent_id = tcx.local_parent(id); + if let DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) { tcx.sess .struct_span_err( attr_span, From 40cb4d1bc78f9479b6c29ade5d2ecf89dc4eba35 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Feb 2023 21:08:14 +0000 Subject: [PATCH 25/47] Even less HIR. --- .../rustc_hir_analysis/src/check/check.rs | 18 ++++------ .../src/check/intrinsicck.rs | 4 +-- .../src/coherence/builtin.rs | 3 +- .../src/coherence/orphan.rs | 36 ++++++++++--------- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d5def62885043..71ed9253668cb 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -21,7 +21,9 @@ use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, AdtDef, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{ + self, AdtDef, DefIdTree, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, +}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, Span}; @@ -174,16 +176,8 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { Ok(l) => l, // Foreign statics that overflow their allowed size should emit an error Err(LayoutError::SizeOverflow(_)) - if { - let node = tcx.hir().get_by_def_id(def_id); - matches!( - node, - hir::Node::ForeignItem(hir::ForeignItem { - kind: hir::ForeignItemKind::Static(..), - .. - }) - ) - } => + if matches!(tcx.def_kind(def_id), DefKind::Static(_) + if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) => { tcx.sess .struct_span_err(span, "extern static is too large for the current architecture") @@ -215,7 +209,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { let item = tcx.hir().item(id); let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else { - tcx.sess.delay_span_bug(tcx.hir().span(id.hir_id()), "expected opaque item"); + tcx.sess.delay_span_bug(item.span, "expected opaque item"); return; }; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 122b6ead8e9d7..56ac18c492792 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -414,7 +414,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that sym actually points to a function. Later passes // depend on this. hir::InlineAsmOperand::SymFn { anon_const } => { - let ty = self.tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + let ty = self.tcx.type_of(anon_const.def_id); match ty.kind() { ty::Never | ty::Error(_) => {} ty::FnDef(..) => {} @@ -422,7 +422,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let mut err = self.tcx.sess.struct_span_err(*op_sp, "invalid `sym` operand"); err.span_label( - self.tcx.hir().span(anon_const.body.hir_id), + self.tcx.def_span(anon_const.def_id), &format!("is {} `{}`", ty.kind().article(), ty), ); err.help("`sym` operands must refer to either a function or a static"); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 8c2423e3ca0d1..c0ba385987d77 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -202,8 +202,7 @@ fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'_>, impl_did: LocalDefId) fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); - let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_did); - let span = tcx.hir().span(impl_hir_id); + let span = tcx.def_span(impl_did); let dispatch_from_dyn_trait = tcx.require_lang_item(LangItem::DispatchFromDyn, Some(span)); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index d0db8cabfddb2..49a9a2ea29309 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -38,26 +38,28 @@ fn do_orphan_check_impl<'tcx>( def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let trait_def_id = trait_ref.def_id; - - let item = tcx.hir().expect_item(def_id); - let hir::ItemKind::Impl(impl_) = item.kind else { - bug!("{:?} is not an impl: {:?}", def_id, item); - }; let sp = tcx.def_span(def_id); - let tr = impl_.of_trait.as_ref().unwrap(); - match traits::orphan_check(tcx, item.owner_id.to_def_id()) { + match traits::orphan_check(tcx, def_id.to_def_id()) { Ok(()) => {} - Err(err) => emit_orphan_check_error( - tcx, - sp, - item.span, - tr.path.span, - trait_ref, - impl_.self_ty.span, - &impl_.generics, - err, - )?, + Err(err) => { + let item = tcx.hir().expect_item(def_id); + let hir::ItemKind::Impl(impl_) = item.kind else { + bug!("{:?} is not an impl: {:?}", def_id, item); + }; + let tr = impl_.of_trait.as_ref().unwrap(); + + emit_orphan_check_error( + tcx, + sp, + item.span, + tr.path.span, + trait_ref, + impl_.self_ty.span, + &impl_.generics, + err, + )? + } } // In addition to the above rules, we restrict impls of auto traits From 065f0b222d4e23ae3d4215061c5df7d248855717 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 14 Feb 2023 18:12:49 +0000 Subject: [PATCH 26/47] Move query out of path. --- compiler/rustc_hir_analysis/src/coherence/orphan.rs | 9 +++++++-- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 49a9a2ea29309..f0a0e7e3e9293 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -38,7 +38,6 @@ fn do_orphan_check_impl<'tcx>( def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { let trait_def_id = trait_ref.def_id; - let sp = tcx.def_span(def_id); match traits::orphan_check(tcx, def_id.to_def_id()) { Ok(()) => {} @@ -48,6 +47,7 @@ fn do_orphan_check_impl<'tcx>( bug!("{:?} is not an impl: {:?}", def_id, item); }; let tr = impl_.of_trait.as_ref().unwrap(); + let sp = tcx.def_span(def_id); emit_orphan_check_error( tcx, @@ -237,7 +237,10 @@ fn do_orphan_check_impl<'tcx>( | ty::GeneratorWitnessMIR(..) | ty::Bound(..) | ty::Placeholder(..) - | ty::Infer(..) => span_bug!(sp, "weird self type for autotrait impl"), + | ty::Infer(..) => { + let sp = tcx.def_span(def_id); + span_bug!(sp, "weird self type for autotrait impl") + } ty::Error(..) => (LocalImpl::Allow, NonlocalImpl::Allow), }; @@ -256,6 +259,7 @@ fn do_orphan_check_impl<'tcx>( is one of the trait object's trait bounds", trait = tcx.def_path_str(trait_def_id), ); + let sp = tcx.def_span(def_id); let reported = struct_span_err!(tcx.sess, sp, E0321, "{}", msg).note(label).emit(); return Err(reported); @@ -284,6 +288,7 @@ fn do_orphan_check_impl<'tcx>( non-struct/enum type", )), } { + let sp = tcx.def_span(def_id); let reported = struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); return Err(reported); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index dd7ee220d7311..bbe4e67977c94 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1191,8 +1191,8 @@ impl<'v> RootCollector<'_, 'v> { fn process_item(&mut self, id: hir::ItemId) { match self.tcx.def_kind(id.owner_id) { DefKind::Enum | DefKind::Struct | DefKind::Union => { - if self.tcx.generics_of(id.owner_id).count() == 0 - && self.mode == MonoItemCollectionMode::Eager + if self.mode == MonoItemCollectionMode::Eager + && self.tcx.generics_of(id.owner_id).count() == 0 { debug!("RootCollector: ADT drop-glue for `{id:?}`",); From b096f0e0f01f9cc1f13d4d664fda93f9efe95485 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Feb 2023 00:59:40 +0000 Subject: [PATCH 27/47] Make permit_uninit/zero_init fallible --- .../src/intrinsics/mod.rs | 13 ++++-- compiler/rustc_codegen_ssa/src/mir/block.rs | 10 ++++- .../src/interpret/intrinsics.rs | 10 ++++- compiler/rustc_const_eval/src/lib.rs | 9 ++-- .../src/util/might_permit_raw_init.rs | 40 +++++++---------- compiler/rustc_middle/src/query/mod.rs | 8 ++-- compiler/rustc_middle/src/ty/query.rs | 1 - .../rustc_mir_transform/src/instcombine.rs | 44 ++++++++++--------- .../dont_yeet_assert.generic.InstCombine.diff | 11 +++-- 9 files changed, 79 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 892e7c30e2f7a..0d2367c2f83d3 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -640,7 +640,8 @@ fn codegen_regular_intrinsic_call<'tcx>( sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => { intrinsic_args!(fx, args => (); intrinsic); - let layout = fx.layout_of(substs.type_at(0)); + let ty = substs.type_at(0); + let layout = fx.layout_of(ty); if layout.abi.is_uninhabited() { with_no_trimmed_paths!({ crate::base::codegen_panic_nounwind( @@ -653,7 +654,10 @@ fn codegen_regular_intrinsic_call<'tcx>( } if intrinsic == sym::assert_zero_valid - && !fx.tcx.permits_zero_init(fx.param_env().and(layout)) + && !fx + .tcx + .permits_zero_init(fx.param_env().and(ty)) + .expect("expected to have layout during codegen") { with_no_trimmed_paths!({ crate::base::codegen_panic_nounwind( @@ -669,7 +673,10 @@ fn codegen_regular_intrinsic_call<'tcx>( } if intrinsic == sym::assert_mem_uninitialized_valid - && !fx.tcx.permits_uninit_init(fx.param_env().and(layout)) + && !fx + .tcx + .permits_uninit_init(fx.param_env().and(ty)) + .expect("expected to have layout during codegen") { with_no_trimmed_paths!({ crate::base::codegen_panic_nounwind( diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 2623a650e07b2..9af408646ae03 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -674,8 +674,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); let do_panic = match intrinsic { Inhabited => layout.abi.is_uninhabited(), - ZeroValid => !bx.tcx().permits_zero_init(bx.param_env().and(layout)), - MemUninitializedValid => !bx.tcx().permits_uninit_init(bx.param_env().and(layout)), + ZeroValid => !bx + .tcx() + .permits_zero_init(bx.param_env().and(ty)) + .expect("expected to have layout during codegen"), + MemUninitializedValid => !bx + .tcx() + .permits_uninit_init(bx.param_env().and(ty)) + .expect("expected to have layout during codegen"), }; Some(if do_panic { let msg_str = with_no_visible_paths!({ diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 907f014dfb518..14cb83eb709be 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -448,7 +448,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } if intrinsic_name == sym::assert_zero_valid { - let should_panic = !self.tcx.permits_zero_init(self.param_env.and(layout)); + let should_panic = !self + .tcx + .permits_zero_init(self.param_env.and(ty)) + .map_err(|_| err_inval!(TooGeneric))?; if should_panic { M::abort( @@ -462,7 +465,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } if intrinsic_name == sym::assert_mem_uninitialized_valid { - let should_panic = !self.tcx.permits_uninit_init(self.param_env.and(layout)); + let should_panic = !self + .tcx + .permits_uninit_init(self.param_env.and(ty)) + .map_err(|_| err_inval!(TooGeneric))?; if should_panic { M::abort( diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 51624a0c6c817..964efcc9062db 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -59,11 +59,8 @@ pub fn provide(providers: &mut Providers) { const_eval::deref_mir_constant(tcx, param_env, value) }; providers.permits_uninit_init = |tcx, param_env_and_ty| { - let (param_env, ty) = param_env_and_ty.into_parts(); - util::might_permit_raw_init(tcx, param_env, ty, InitKind::UninitMitigated0x01Fill) - }; - providers.permits_zero_init = |tcx, param_env_and_ty| { - let (param_env, ty) = param_env_and_ty.into_parts(); - util::might_permit_raw_init(tcx, param_env, ty, InitKind::Zero) + util::might_permit_raw_init(tcx, param_env_and_ty, InitKind::UninitMitigated0x01Fill) }; + providers.permits_zero_init = + |tcx, param_env_and_ty| util::might_permit_raw_init(tcx, param_env_and_ty, InitKind::Zero); } diff --git a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs index a2db98683b529..2eba1e11466a4 100644 --- a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs +++ b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs @@ -1,5 +1,5 @@ -use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; -use rustc_middle::ty::{ParamEnv, TyCtxt, TypeVisitable}; +use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout}; +use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_session::Limit; use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants}; @@ -20,15 +20,14 @@ use crate::interpret::{InterpCx, MemoryKind, OpTy}; /// to the full uninit check). pub fn might_permit_raw_init<'tcx>( tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - ty: TyAndLayout<'tcx>, + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, kind: InitKind, -) -> bool { +) -> Result> { if tcx.sess.opts.unstable_opts.strict_init_checks { - might_permit_raw_init_strict(ty, tcx, kind) + might_permit_raw_init_strict(tcx.layout_of(param_env_and_ty)?, tcx, kind) } else { - let layout_cx = LayoutCx { tcx, param_env }; - might_permit_raw_init_lax(ty, &layout_cx, kind) + let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env }; + might_permit_raw_init_lax(tcx.layout_of(param_env_and_ty)?, &layout_cx, kind) } } @@ -38,7 +37,7 @@ fn might_permit_raw_init_strict<'tcx>( ty: TyAndLayout<'tcx>, tcx: TyCtxt<'tcx>, kind: InitKind, -) -> bool { +) -> Result> { let machine = CompileTimeInterpreter::new( Limit::new(0), /*can_access_statics:*/ false, @@ -65,7 +64,7 @@ fn might_permit_raw_init_strict<'tcx>( // This does *not* actually check that references are dereferenceable, but since all types that // require dereferenceability also require non-null, we don't actually get any false negatives // due to this. - cx.validate_operand(&ot).is_ok() + Ok(cx.validate_operand(&ot).is_ok()) } /// Implements the 'lax' (default) version of the `might_permit_raw_init` checks; see that function for @@ -74,7 +73,7 @@ fn might_permit_raw_init_lax<'tcx>( this: TyAndLayout<'tcx>, cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, init_kind: InitKind, -) -> bool { +) -> Result> { let scalar_allows_raw_init = move |s: Scalar| -> bool { match init_kind { InitKind::Zero => { @@ -103,25 +102,20 @@ fn might_permit_raw_init_lax<'tcx>( }; if !valid { // This is definitely not okay. - return false; + return Ok(false); } // Special magic check for references and boxes (i.e., special pointer types). if let Some(pointee) = this.ty.builtin_deref(false) { - let Ok(pointee) = cx.layout_of(pointee.ty) else { - // Reference is too polymorphic, it has a layout but the pointee does not. - // So we must assume that there may be some substitution that is valid. - assert!(pointee.ty.needs_subst()); - return true; - }; + let pointee = cx.layout_of(pointee.ty)?; // We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied. if pointee.align.abi.bytes() > 1 { // 0x01-filling is not aligned. - return false; + return Ok(false); } if pointee.size.bytes() > 0 { // A 'fake' integer pointer is not sufficiently dereferenceable. - return false; + return Ok(false); } } @@ -134,9 +128,9 @@ fn might_permit_raw_init_lax<'tcx>( } FieldsShape::Arbitrary { offsets, .. } => { for idx in 0..offsets.len() { - if !might_permit_raw_init_lax(this.field(cx, idx), cx, init_kind) { + if !might_permit_raw_init_lax(this.field(cx, idx), cx, init_kind)? { // We found a field that is unhappy with this kind of initialization. - return false; + return Ok(false); } } } @@ -153,5 +147,5 @@ fn might_permit_raw_init_lax<'tcx>( } } - true + Ok(true) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d37d6b37a37c3..29a33b02243ca 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2138,12 +2138,12 @@ rustc_queries! { separate_provide_extern } - query permits_uninit_init(key: ty::ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool { - desc { "checking to see if `{}` permits being left uninit", key.value.ty } + query permits_uninit_init(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result> { + desc { "checking to see if `{}` permits being left uninit", key.value } } - query permits_zero_init(key: ty::ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool { - desc { "checking to see if `{}` permits being left zeroed", key.value.ty } + query permits_zero_init(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result> { + desc { "checking to see if `{}` permits being left zeroed", key.value } } query compare_impl_const( diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index bec70974dde04..ed54aa96f5b89 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -30,7 +30,6 @@ use crate::traits::specialization_graph; use crate::traits::{self, ImplSource}; use crate::ty::context::TyCtxtFeed; use crate::ty::fast_reject::SimplifiedType; -use crate::ty::layout::TyAndLayout; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::GeneratorDiagnosticData; diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index e1faa7a08d939..1079377fbacd2 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -6,7 +6,8 @@ use rustc_middle::mir::{ BinOp, Body, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnOp, }; -use rustc_middle::ty::{self, layout::TyAndLayout, ParamEnv, ParamEnvAnd, SubstsRef, Ty, TyCtxt}; +use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::{self, ParamEnv, ParamEnvAnd, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; pub struct InstCombine; @@ -230,38 +231,41 @@ impl<'tcx> InstCombineContext<'tcx, '_> { // Check this is a foldable intrinsic before we query the layout of our generic parameter let Some(assert_panics) = intrinsic_assert_panics(intrinsic_name) else { return; }; - let Ok(layout) = self.tcx.layout_of(self.param_env.and(ty)) else { return; }; - if assert_panics(self.tcx, self.param_env.and(layout)) { - // If we know the assert panics, indicate to later opts that the call diverges - *target = None; - } else { - // If we know the assert does not panic, turn the call into a Goto - terminator.kind = TerminatorKind::Goto { target: *target_block }; + match assert_panics(self.tcx, self.param_env.and(ty)) { + // We don't know the layout, don't touch the assertion + Err(_) => {} + Ok(true) => { + // If we know the assert panics, indicate to later opts that the call diverges + *target = None; + } + Ok(false) => { + // If we know the assert does not panic, turn the call into a Goto + terminator.kind = TerminatorKind::Goto { target: *target_block }; + } } } } fn intrinsic_assert_panics<'tcx>( intrinsic_name: Symbol, -) -> Option, ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool> { +) -> Option, ParamEnvAnd<'tcx, Ty<'tcx>>) -> Result>> { fn inhabited_predicate<'tcx>( - _tcx: TyCtxt<'tcx>, - param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>, - ) -> bool { - let (_param_env, layout) = param_env_and_layout.into_parts(); - layout.abi.is_uninhabited() + tcx: TyCtxt<'tcx>, + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result> { + Ok(tcx.layout_of(param_env_and_ty)?.abi.is_uninhabited()) } fn zero_valid_predicate<'tcx>( tcx: TyCtxt<'tcx>, - param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>, - ) -> bool { - !tcx.permits_zero_init(param_env_and_layout) + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result> { + Ok(!tcx.permits_zero_init(param_env_and_ty)?) } fn mem_uninitialized_valid_predicate<'tcx>( tcx: TyCtxt<'tcx>, - param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>, - ) -> bool { - !tcx.permits_uninit_init(param_env_and_layout) + param_env_and_ty: ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result> { + Ok(!tcx.permits_uninit_init(param_env_and_ty)?) } match intrinsic_name { diff --git a/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff b/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff index fb08ad582d927..c1a42a47ed218 100644 --- a/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff +++ b/tests/mir-opt/dont_yeet_assert.generic.InstCombine.diff @@ -7,12 +7,11 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 -- _1 = assert_mem_uninitialized_valid::<&T>() -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 -- // mir::Constant -- // + span: $DIR/dont_yeet_assert.rs:10:5: 10:59 -- // + user_ty: UserType(0) -- // + literal: Const { ty: extern "rust-intrinsic" fn() {assert_mem_uninitialized_valid::<&T>}, val: Value() } -+ goto -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 + _1 = assert_mem_uninitialized_valid::<&T>() -> bb1; // scope 0 at $DIR/dont_yeet_assert.rs:+1:5: +1:61 + // mir::Constant + // + span: $DIR/dont_yeet_assert.rs:10:5: 10:59 + // + user_ty: UserType(0) + // + literal: Const { ty: extern "rust-intrinsic" fn() {assert_mem_uninitialized_valid::<&T>}, val: Value() } } bb1: { From 3f80017f03a42f9e352139aa4fd75c3408283b33 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Feb 2023 22:15:32 +0000 Subject: [PATCH 28/47] Better label for illegal impl trait types --- compiler/rustc_ast_lowering/src/expr.rs | 4 +-- compiler/rustc_ast_lowering/src/item.rs | 33 +++++++++++-------- compiler/rustc_ast_lowering/src/lib.rs | 26 ++++++++++++--- .../ui/associated-consts/issue-105330.stderr | 2 +- ...feature-gate-associated_type_bounds.stderr | 4 +-- tests/ui/impl-trait/issues/issue-58956.stderr | 2 +- ...83929-impl-trait-in-generic-default.stderr | 4 +-- tests/ui/impl-trait/issues/issue-86642.stderr | 2 +- tests/ui/impl-trait/where-allowed.stderr | 32 +++++++++--------- 9 files changed, 67 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index cc523fe7d08f5..c4442b34fe42b 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -139,13 +139,13 @@ impl<'hir> LoweringContext<'_, 'hir> { ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); let ty = - self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); hir::ExprKind::Cast(expr, ty) } ExprKind::Type(expr, ty) => { let expr = self.lower_expr(expr); let ty = - self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast)); hir::ExprKind::Type(expr, ty) } ExprKind::AddrOf(k, m, ohs) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 2865082bd7a47..6bafbfbc14c73 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -378,8 +378,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }); - let lowered_ty = this - .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let lowered_ty = this.lower_ty( + ty, + &ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf), + ); (trait_ref, lowered_ty) }); @@ -458,7 +460,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, body: Option<&Expr>, ) -> (&'hir hir::Ty<'hir>, hir::BodyId) { - let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); (ty, self.lower_const_body(span, body)) } @@ -608,8 +610,8 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ForeignItemKind::Fn(fn_dec, fn_args, generics) } ForeignItemKind::Static(t, m, _) => { - let ty = - self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = self + .lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); hir::ForeignItemKind::Static(ty, *m) } ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, @@ -679,11 +681,11 @@ impl<'hir> LoweringContext<'_, 'hir> { qself, path, ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124) - &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy), ); self.arena.alloc(t) } else { - self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy)) }; let hir_id = self.lower_node_id(f.id); self.lower_attrs(hir_id, &f.attrs); @@ -708,7 +710,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind, has_default) = match &i.kind { AssocItemKind::Const(_, ty, default) => { - let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some()) } @@ -746,7 +749,10 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { let ty = ty.as_ref().map(|x| { - this.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + this.lower_ty( + x, + &ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy), + ) }); hir::TraitItemKind::Type( this.lower_param_bounds( @@ -805,7 +811,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = match &i.kind { AssocItemKind::Const(_, ty, expr) => { - let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = + self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy)); ( hir::Generics::empty(), hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())), @@ -1441,7 +1448,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir_id: self.next_id(), bound_generic_params: self.lower_generic_params(bound_generic_params), bounded_ty: self - .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), + .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), bounds: self.arena.alloc_from_iter(bounds.iter().map(|bound| { self.lower_param_bound( bound, @@ -1465,9 +1472,9 @@ impl<'hir> LoweringContext<'_, 'hir> { WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { lhs_ty: self - .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), + .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), rhs_ty: self - .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), + .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)), span: self.lower_span(*span), }) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a04a259529310..b543be3be5083 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -253,7 +253,6 @@ enum ImplTraitContext { enum ImplTraitPosition { Path, Variable, - Type, Trait, AsyncBlock, Bound, @@ -270,6 +269,13 @@ enum ImplTraitPosition { FnTraitReturn, TraitReturn, ImplReturn, + GenericDefault, + ConstTy, + StaticTy, + AssocTy, + FieldTy, + Cast, + ImplSelf, } impl std::fmt::Display for ImplTraitPosition { @@ -277,7 +283,6 @@ impl std::fmt::Display for ImplTraitPosition { let name = match self { ImplTraitPosition::Path => "path", ImplTraitPosition::Variable => "variable binding", - ImplTraitPosition::Type => "type", ImplTraitPosition::Trait => "trait", ImplTraitPosition::AsyncBlock => "async block", ImplTraitPosition::Bound => "bound", @@ -294,6 +299,13 @@ impl std::fmt::Display for ImplTraitPosition { ImplTraitPosition::FnTraitReturn => "`Fn` trait return", ImplTraitPosition::TraitReturn => "trait method return", ImplTraitPosition::ImplReturn => "`impl` method return", + ImplTraitPosition::GenericDefault => "generic parameter default", + ImplTraitPosition::ConstTy => "const type", + ImplTraitPosition::StaticTy => "static type", + ImplTraitPosition::AssocTy => "associated type", + ImplTraitPosition::FieldTy => "field type", + ImplTraitPosition::Cast => "cast type", + ImplTraitPosition::ImplSelf => "impl header", }; write!(f, "{name}") @@ -2166,7 +2178,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericParamKind::Type { default, .. } => { let kind = hir::GenericParamKind::Type { default: default.as_ref().map(|x| { - self.lower_ty(x, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)) + self.lower_ty( + x, + &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), + ) }), synthetic: false, }; @@ -2174,7 +2189,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { (hir::ParamName::Plain(self.lower_ident(param.ident)), kind) } GenericParamKind::Const { ty, kw_span: _, default } => { - let ty = self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)); + let ty = self.lower_ty( + &ty, + &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), + ); let default = default.as_ref().map(|def| self.lower_anon_const(def)); ( hir::ParamName::Plain(self.lower_ident(param.ident)), diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 30c380152a5e6..08570d4a5d982 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -33,7 +33,7 @@ LL | fn main>() { = note: see issue #92827 for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/issue-105330.rs:6:27 | LL | impl TraitWAssocConst for impl Demo { diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 5be1d97a05985..6f2919b6c0909 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -115,13 +115,13 @@ LL | let _: impl Tr1 = S1; = note: see issue #52662 for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/feature-gate-associated_type_bounds.rs:58:14 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/feature-gate-associated_type_bounds.rs:64:15 | LL | static _sdef: impl Tr1 = S1; diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr index 123fb4df4b3c8..f591c07bcf5f4 100644 --- a/tests/ui/impl-trait/issues/issue-58956.stderr +++ b/tests/ui/impl-trait/issues/issue-58956.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/issue-58956.rs:7:11 | LL | const _A: impl Lam = { diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr index e635e554e2384..a227f0ba7d135 100644 --- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16 | LL | struct Foo(T); | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20 | LL | type Result = std::result::Result; diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr index 0ec118d5be802..a137777840b31 100644 --- a/tests/ui/impl-trait/issues/issue-86642.stderr +++ b/tests/ui/impl-trait/issues/issue-86642.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type --> $DIR/issue-86642.rs:1:11 | LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| { diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index e3a9caa646026..201aba3adff96 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -115,31 +115,31 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:81:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:85:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:89:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:94:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type --> $DIR/where-allowed.rs:96:20 | LL | InTupleVariant(impl Debug), @@ -187,31 +187,31 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t LL | impl PartialEq for () { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/where-allowed.rs:166:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/where-allowed.rs:171:6 | LL | impl impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header --> $DIR/where-allowed.rs:177:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound --> $DIR/where-allowed.rs:183:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound --> $DIR/where-allowed.rs:190:15 | LL | where Vec: Debug @@ -235,37 +235,37 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:217:40 | LL | struct InStructGenericParamDefault(T); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:221:36 | LL | enum InEnumGenericParamDefault { Variant(T) } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:225:38 | LL | trait InTraitGenericParamDefault {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:229:41 | LL | type InTypeAliasGenericParamDefault = T; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:233:11 | LL | impl T {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default --> $DIR/where-allowed.rs:240:40 | LL | fn in_method_generic_param_default(_: T) {} From a82adf01253aa6dc16ce979217c9404957cea6f9 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 14 Feb 2023 19:21:58 -0500 Subject: [PATCH 29/47] Fix codegen tests --- tests/codegen/move-operands.rs | 2 +- ...intrinsic-generic-arithmetic-saturating.rs | 166 +++++++++--------- .../simd-intrinsic-generic-bitmask.rs | 10 +- .../simd-intrinsic-generic-extract-insert.rs | 8 +- tests/codegen/simd_arith_offset.rs | 2 +- 5 files changed, 94 insertions(+), 94 deletions(-) diff --git a/tests/codegen/move-operands.rs b/tests/codegen/move-operands.rs index 871b54d0404f6..1d8209e8ea54e 100644 --- a/tests/codegen/move-operands.rs +++ b/tests/codegen/move-operands.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation,+CopyProp +// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation,-CopyProp #![crate_type = "lib"] diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs index 6fb0ceb4025b5..faac7566a0c49 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -116,150 +116,150 @@ extern "platform-intrinsic" { fn simd_saturating_sub(x: T, y: T) -> T; } -// NOTE(eddyb) `%{{x|_3}}` is used because on some targets (e.g. WASM) +// NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, // while on others they're passed indirectly, resulting in `%x` being -// a pointer to a vector, and `%_3` a vector loaded from that pointer. +// a pointer to a vector, and `%1` a vector loaded from that pointer. // This is controlled by the target spec option `simd_types_indirect`. -// The same applies to `%{{y|_4}}` as well. +// The same applies to `%{{y|2}}` as well. // CHECK-LABEL: @sadd_i8x2 #[no_mangle] pub unsafe fn sadd_i8x2(x: i8x2, y: i8x2) -> i8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{x|_3}}, <2 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x4 #[no_mangle] pub unsafe fn sadd_i8x4(x: i8x4, y: i8x4) -> i8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{x|_3}}, <4 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x8 #[no_mangle] pub unsafe fn sadd_i8x8(x: i8x8, y: i8x8) -> i8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{x|_3}}, <8 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x16 #[no_mangle] pub unsafe fn sadd_i8x16(x: i8x16, y: i8x16) -> i8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{x|_3}}, <16 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x32 #[no_mangle] pub unsafe fn sadd_i8x32(x: i8x32, y: i8x32) -> i8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{x|_3}}, <32 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i8x64 #[no_mangle] pub unsafe fn sadd_i8x64(x: i8x64, y: i8x64) -> i8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{x|_3}}, <64 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x2 #[no_mangle] pub unsafe fn sadd_i16x2(x: i16x2, y: i16x2) -> i16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{x|_3}}, <2 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x4 #[no_mangle] pub unsafe fn sadd_i16x4(x: i16x4, y: i16x4) -> i16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{x|_3}}, <4 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x8 #[no_mangle] pub unsafe fn sadd_i16x8(x: i16x8, y: i16x8) -> i16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{x|_3}}, <8 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x16 #[no_mangle] pub unsafe fn sadd_i16x16(x: i16x16, y: i16x16) -> i16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{x|_3}}, <16 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i16x32 #[no_mangle] pub unsafe fn sadd_i16x32(x: i16x32, y: i16x32) -> i16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{x|_3}}, <32 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x2 #[no_mangle] pub unsafe fn sadd_i32x2(x: i32x2, y: i32x2) -> i32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{x|_3}}, <2 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x4 #[no_mangle] pub unsafe fn sadd_i32x4(x: i32x4, y: i32x4) -> i32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{x|_3}}, <4 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x8 #[no_mangle] pub unsafe fn sadd_i32x8(x: i32x8, y: i32x8) -> i32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{x|_3}}, <8 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i32x16 #[no_mangle] pub unsafe fn sadd_i32x16(x: i32x16, y: i32x16) -> i32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{x|_3}}, <16 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i64x2 #[no_mangle] pub unsafe fn sadd_i64x2(x: i64x2, y: i64x2) -> i64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{x|_3}}, <2 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i64x4 #[no_mangle] pub unsafe fn sadd_i64x4(x: i64x4, y: i64x4) -> i64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{x|_3}}, <4 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i64x8 #[no_mangle] pub unsafe fn sadd_i64x8(x: i64x8, y: i64x8) -> i64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{x|_3}}, <8 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i128x2 #[no_mangle] pub unsafe fn sadd_i128x2(x: i128x2, y: i128x2) -> i128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{x|_3}}, <2 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @sadd_i128x4 #[no_mangle] pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{x|_3}}, <4 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) simd_saturating_add(x, y) } @@ -268,140 +268,140 @@ pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 { // CHECK-LABEL: @uadd_u8x2 #[no_mangle] pub unsafe fn uadd_u8x2(x: u8x2, y: u8x2) -> u8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{x|_3}}, <2 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x4 #[no_mangle] pub unsafe fn uadd_u8x4(x: u8x4, y: u8x4) -> u8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{x|_3}}, <4 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x8 #[no_mangle] pub unsafe fn uadd_u8x8(x: u8x8, y: u8x8) -> u8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{x|_3}}, <8 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x16 #[no_mangle] pub unsafe fn uadd_u8x16(x: u8x16, y: u8x16) -> u8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{x|_3}}, <16 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x32 #[no_mangle] pub unsafe fn uadd_u8x32(x: u8x32, y: u8x32) -> u8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{x|_3}}, <32 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u8x64 #[no_mangle] pub unsafe fn uadd_u8x64(x: u8x64, y: u8x64) -> u8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{x|_3}}, <64 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x2 #[no_mangle] pub unsafe fn uadd_u16x2(x: u16x2, y: u16x2) -> u16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{x|_3}}, <2 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x4 #[no_mangle] pub unsafe fn uadd_u16x4(x: u16x4, y: u16x4) -> u16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{x|_3}}, <4 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x8 #[no_mangle] pub unsafe fn uadd_u16x8(x: u16x8, y: u16x8) -> u16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{x|_3}}, <8 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x16 #[no_mangle] pub unsafe fn uadd_u16x16(x: u16x16, y: u16x16) -> u16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{x|_3}}, <16 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u16x32 #[no_mangle] pub unsafe fn uadd_u16x32(x: u16x32, y: u16x32) -> u16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{x|_3}}, <32 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x2 #[no_mangle] pub unsafe fn uadd_u32x2(x: u32x2, y: u32x2) -> u32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{x|_3}}, <2 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x4 #[no_mangle] pub unsafe fn uadd_u32x4(x: u32x4, y: u32x4) -> u32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{x|_3}}, <4 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x8 #[no_mangle] pub unsafe fn uadd_u32x8(x: u32x8, y: u32x8) -> u32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{x|_3}}, <8 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u32x16 #[no_mangle] pub unsafe fn uadd_u32x16(x: u32x16, y: u32x16) -> u32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{x|_3}}, <16 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u64x2 #[no_mangle] pub unsafe fn uadd_u64x2(x: u64x2, y: u64x2) -> u64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{x|_3}}, <2 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u64x4 #[no_mangle] pub unsafe fn uadd_u64x4(x: u64x4, y: u64x4) -> u64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{x|_3}}, <4 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u64x8 #[no_mangle] pub unsafe fn uadd_u64x8(x: u64x8, y: u64x8) -> u64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{x|_3}}, <8 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u128x2 #[no_mangle] pub unsafe fn uadd_u128x2(x: u128x2, y: u128x2) -> u128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{x|_3}}, <2 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) simd_saturating_add(x, y) } // CHECK-LABEL: @uadd_u128x4 #[no_mangle] pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{x|_3}}, <4 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) simd_saturating_add(x, y) } @@ -412,140 +412,140 @@ pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 { // CHECK-LABEL: @ssub_i8x2 #[no_mangle] pub unsafe fn ssub_i8x2(x: i8x2, y: i8x2) -> i8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{x|_3}}, <2 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x4 #[no_mangle] pub unsafe fn ssub_i8x4(x: i8x4, y: i8x4) -> i8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{x|_3}}, <4 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x8 #[no_mangle] pub unsafe fn ssub_i8x8(x: i8x8, y: i8x8) -> i8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{x|_3}}, <8 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x16 #[no_mangle] pub unsafe fn ssub_i8x16(x: i8x16, y: i8x16) -> i8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{x|_3}}, <16 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x32 #[no_mangle] pub unsafe fn ssub_i8x32(x: i8x32, y: i8x32) -> i8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{x|_3}}, <32 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i8x64 #[no_mangle] pub unsafe fn ssub_i8x64(x: i8x64, y: i8x64) -> i8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{x|_3}}, <64 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x2 #[no_mangle] pub unsafe fn ssub_i16x2(x: i16x2, y: i16x2) -> i16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{x|_3}}, <2 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x4 #[no_mangle] pub unsafe fn ssub_i16x4(x: i16x4, y: i16x4) -> i16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{x|_3}}, <4 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x8 #[no_mangle] pub unsafe fn ssub_i16x8(x: i16x8, y: i16x8) -> i16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{x|_3}}, <8 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x16 #[no_mangle] pub unsafe fn ssub_i16x16(x: i16x16, y: i16x16) -> i16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{x|_3}}, <16 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i16x32 #[no_mangle] pub unsafe fn ssub_i16x32(x: i16x32, y: i16x32) -> i16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{x|_3}}, <32 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x2 #[no_mangle] pub unsafe fn ssub_i32x2(x: i32x2, y: i32x2) -> i32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{x|_3}}, <2 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x4 #[no_mangle] pub unsafe fn ssub_i32x4(x: i32x4, y: i32x4) -> i32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{x|_3}}, <4 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x8 #[no_mangle] pub unsafe fn ssub_i32x8(x: i32x8, y: i32x8) -> i32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{x|_3}}, <8 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i32x16 #[no_mangle] pub unsafe fn ssub_i32x16(x: i32x16, y: i32x16) -> i32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{x|_3}}, <16 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i64x2 #[no_mangle] pub unsafe fn ssub_i64x2(x: i64x2, y: i64x2) -> i64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{x|_3}}, <2 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i64x4 #[no_mangle] pub unsafe fn ssub_i64x4(x: i64x4, y: i64x4) -> i64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{x|_3}}, <4 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i64x8 #[no_mangle] pub unsafe fn ssub_i64x8(x: i64x8, y: i64x8) -> i64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{x|_3}}, <8 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i128x2 #[no_mangle] pub unsafe fn ssub_i128x2(x: i128x2, y: i128x2) -> i128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{x|_3}}, <2 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @ssub_i128x4 #[no_mangle] pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{x|_3}}, <4 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) simd_saturating_sub(x, y) } @@ -554,139 +554,139 @@ pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 { // CHECK-LABEL: @usub_u8x2 #[no_mangle] pub unsafe fn usub_u8x2(x: u8x2, y: u8x2) -> u8x2 { - // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{x|_3}}, <2 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{x|1}}, <2 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x4 #[no_mangle] pub unsafe fn usub_u8x4(x: u8x4, y: u8x4) -> u8x4 { - // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{x|_3}}, <4 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{x|1}}, <4 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x8 #[no_mangle] pub unsafe fn usub_u8x8(x: u8x8, y: u8x8) -> u8x8 { - // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{x|_3}}, <8 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{x|1}}, <8 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x16 #[no_mangle] pub unsafe fn usub_u8x16(x: u8x16, y: u8x16) -> u8x16 { - // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{x|_3}}, <16 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{x|1}}, <16 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x32 #[no_mangle] pub unsafe fn usub_u8x32(x: u8x32, y: u8x32) -> u8x32 { - // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{x|_3}}, <32 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{x|1}}, <32 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u8x64 #[no_mangle] pub unsafe fn usub_u8x64(x: u8x64, y: u8x64) -> u8x64 { - // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{x|_3}}, <64 x i8> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{x|1}}, <64 x i8> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x2 #[no_mangle] pub unsafe fn usub_u16x2(x: u16x2, y: u16x2) -> u16x2 { - // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{x|_3}}, <2 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{x|1}}, <2 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x4 #[no_mangle] pub unsafe fn usub_u16x4(x: u16x4, y: u16x4) -> u16x4 { - // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{x|_3}}, <4 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{x|1}}, <4 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x8 #[no_mangle] pub unsafe fn usub_u16x8(x: u16x8, y: u16x8) -> u16x8 { - // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{x|_3}}, <8 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{x|1}}, <8 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x16 #[no_mangle] pub unsafe fn usub_u16x16(x: u16x16, y: u16x16) -> u16x16 { - // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{x|_3}}, <16 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{x|1}}, <16 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u16x32 #[no_mangle] pub unsafe fn usub_u16x32(x: u16x32, y: u16x32) -> u16x32 { - // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{x|_3}}, <32 x i16> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{x|1}}, <32 x i16> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x2 #[no_mangle] pub unsafe fn usub_u32x2(x: u32x2, y: u32x2) -> u32x2 { - // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{x|_3}}, <2 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{x|1}}, <2 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x4 #[no_mangle] pub unsafe fn usub_u32x4(x: u32x4, y: u32x4) -> u32x4 { - // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{x|_3}}, <4 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{x|1}}, <4 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x8 #[no_mangle] pub unsafe fn usub_u32x8(x: u32x8, y: u32x8) -> u32x8 { - // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{x|_3}}, <8 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{x|1}}, <8 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u32x16 #[no_mangle] pub unsafe fn usub_u32x16(x: u32x16, y: u32x16) -> u32x16 { - // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{x|_3}}, <16 x i32> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{x|1}}, <16 x i32> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u64x2 #[no_mangle] pub unsafe fn usub_u64x2(x: u64x2, y: u64x2) -> u64x2 { - // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{x|_3}}, <2 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{x|1}}, <2 x i64> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u64x4 #[no_mangle] pub unsafe fn usub_u64x4(x: u64x4, y: u64x4) -> u64x4 { - // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{x|_3}}, <4 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{x|1}}, <4 x i64> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u64x8 #[no_mangle] pub unsafe fn usub_u64x8(x: u64x8, y: u64x8) -> u64x8 { - // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{x|_3}}, <8 x i64> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{x|1}}, <8 x i64> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u128x2 #[no_mangle] pub unsafe fn usub_u128x2(x: u128x2, y: u128x2) -> u128x2 { - // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{x|_3}}, <2 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{x|1}}, <2 x i128> %{{y|2}}) simd_saturating_sub(x, y) } // CHECK-LABEL: @usub_u128x4 #[no_mangle] pub unsafe fn usub_u128x4(x: u128x4, y: u128x4) -> u128x4 { - // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{x|_3}}, <4 x i128> %{{y|_4}}) + // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{x|1}}, <4 x i128> %{{y|2}}) simd_saturating_sub(x, y) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs index 4a98d797b526b..04bba5df45fc5 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -26,16 +26,16 @@ extern "platform-intrinsic" { fn simd_bitmask(x: T) -> U; } -// NOTE(eddyb) `%{{x|_2}}` is used because on some targets (e.g. WASM) +// NOTE(eddyb) `%{{x|1}}` is used because on some targets (e.g. WASM) // SIMD vectors are passed directly, resulting in `%x` being a vector, // while on others they're passed indirectly, resulting in `%x` being -// a pointer to a vector, and `%_2` a vector loaded from that pointer. +// a pointer to a vector, and `%1` a vector loaded from that pointer. // This is controlled by the target spec option `simd_types_indirect`. // CHECK-LABEL: @bitmask_int #[no_mangle] pub unsafe fn bitmask_int(x: i32x2) -> u8 { - // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{x|_2}}, + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{x|1}}, // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: [[C:%[0-9]+]] = bitcast <2 x i1> [[B]] to i2 // CHECK: %{{[0-9]+}} = zext i2 [[C]] to i8 @@ -45,7 +45,7 @@ pub unsafe fn bitmask_int(x: i32x2) -> u8 { // CHECK-LABEL: @bitmask_uint #[no_mangle] pub unsafe fn bitmask_uint(x: u32x2) -> u8 { - // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{x|_2}}, + // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{x|1}}, // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> // CHECK: [[C:%[0-9]+]] = bitcast <2 x i1> [[B]] to i2 // CHECK: %{{[0-9]+}} = zext i2 [[C]] to i8 @@ -55,7 +55,7 @@ pub unsafe fn bitmask_uint(x: u32x2) -> u8 { // CHECK-LABEL: @bitmask_int16 #[no_mangle] pub unsafe fn bitmask_int16(x: i8x16) -> u16 { - // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{x|_2}}, + // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{x|1}}, // CHECK: [[B:%[0-9]+]] = trunc <16 x i8> [[A]] to <16 x i1> // CHECK: %{{[0-9]+}} = bitcast <16 x i1> [[B]] to i16 // CHECK-NOT: zext diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs index b5b0b1330a629..078b2fa1edf8c 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs @@ -21,27 +21,27 @@ extern "platform-intrinsic" { // CHECK-LABEL: @extract_m #[no_mangle] pub unsafe fn extract_m(v: M, i: u32) -> f32 { - // CHECK: extractelement <4 x float> %{{v|_3}}, i32 %i + // CHECK: extractelement <4 x float> %{{v|1}}, i32 %i simd_extract(v, i) } // CHECK-LABEL: @extract_s #[no_mangle] pub unsafe fn extract_s(v: S<4>, i: u32) -> f32 { - // CHECK: extractelement <4 x float> %{{v|_3}}, i32 %i + // CHECK: extractelement <4 x float> %{{v|1}}, i32 %i simd_extract(v, i) } // CHECK-LABEL: @insert_m #[no_mangle] pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M { - // CHECK: insertelement <4 x float> %{{v|_4}}, float %j, i32 %i + // CHECK: insertelement <4 x float> %{{v|1}}, float %j, i32 %i simd_insert(v, i, j) } // CHECK-LABEL: @insert_s #[no_mangle] pub unsafe fn insert_s(v: S<4>, i: u32, j: f32) -> S<4> { - // CHECK: insertelement <4 x float> %{{v|_4}}, float %j, i32 %i + // CHECK: insertelement <4 x float> %{{v|1}}, float %j, i32 %i simd_insert(v, i, j) } diff --git a/tests/codegen/simd_arith_offset.rs b/tests/codegen/simd_arith_offset.rs index 7b623a22a0b21..f2333777391f1 100644 --- a/tests/codegen/simd_arith_offset.rs +++ b/tests/codegen/simd_arith_offset.rs @@ -21,6 +21,6 @@ pub struct Simd([T; LANES]); // CHECK-LABEL: smoke #[no_mangle] pub fn smoke(ptrs: SimdConstPtr, offsets: Simd) -> SimdConstPtr { - // CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %_3, <8 x i64> %_4 + // CHECK: getelementptr i8, <8 x {{i8\*|ptr}}> %1, <8 x i64> %2 unsafe { simd_arith_offset(ptrs, offsets) } } From 37a875cbdb5e111df378517bb0e45265af8879e3 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 14 Feb 2023 19:49:49 -0500 Subject: [PATCH 30/47] Try to fix codegen tests for ??? LLVM 14 ??? --- .../simd-intrinsic/simd-intrinsic-generic-bitmask.rs | 2 +- .../simd-intrinsic-generic-extract-insert.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs index 04bba5df45fc5..ea24569bd10c1 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -55,7 +55,7 @@ pub unsafe fn bitmask_uint(x: u32x2) -> u8 { // CHECK-LABEL: @bitmask_int16 #[no_mangle] pub unsafe fn bitmask_int16(x: i8x16) -> u16 { - // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{x|1}}, + // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{x|1|2}}, // CHECK: [[B:%[0-9]+]] = trunc <16 x i8> [[A]] to <16 x i1> // CHECK: %{{[0-9]+}} = bitcast <16 x i1> [[B]] to i16 // CHECK-NOT: zext diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs index 078b2fa1edf8c..80583dec19524 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs @@ -21,27 +21,27 @@ extern "platform-intrinsic" { // CHECK-LABEL: @extract_m #[no_mangle] pub unsafe fn extract_m(v: M, i: u32) -> f32 { - // CHECK: extractelement <4 x float> %{{v|1}}, i32 %i + // CHECK: extractelement <4 x float> %{{v|1|2}}, i32 %i simd_extract(v, i) } // CHECK-LABEL: @extract_s #[no_mangle] pub unsafe fn extract_s(v: S<4>, i: u32) -> f32 { - // CHECK: extractelement <4 x float> %{{v|1}}, i32 %i + // CHECK: extractelement <4 x float> %{{v|1|2}}, i32 %i simd_extract(v, i) } // CHECK-LABEL: @insert_m #[no_mangle] pub unsafe fn insert_m(v: M, i: u32, j: f32) -> M { - // CHECK: insertelement <4 x float> %{{v|1}}, float %j, i32 %i + // CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i simd_insert(v, i, j) } // CHECK-LABEL: @insert_s #[no_mangle] pub unsafe fn insert_s(v: S<4>, i: u32, j: f32) -> S<4> { - // CHECK: insertelement <4 x float> %{{v|1}}, float %j, i32 %i + // CHECK: insertelement <4 x float> %{{v|1|2}}, float %j, i32 %i simd_insert(v, i, j) } From 54cfc10fa593b512315f17a7df5235c5595dac9e Mon Sep 17 00:00:00 2001 From: Zephaniah Ong Date: Tue, 14 Feb 2023 10:38:18 +0800 Subject: [PATCH 31/47] make x look for x.py if shell script does not exist bump up x version Refactor code --- src/tools/x/Cargo.toml | 2 +- src/tools/x/src/main.rs | 74 ++++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml index 3150272796234..84a42ca36ef1c 100644 --- a/src/tools/x/Cargo.toml +++ b/src/tools/x/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "x" -version = "0.1.0" +version = "0.1.1" description = "Run x.py slightly more conveniently" edition = "2021" publish = false diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index 01f7187851e38..5da8a2888ec83 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -9,11 +9,47 @@ //! We also don't use `pwsh` on Windows, because it is not installed by default; use std::{ - env, io, + env::{self, consts::EXE_EXTENSION}, + io, path::Path, process::{self, Command, ExitStatus}, }; +const PYTHON: &str = "python"; +const PYTHON2: &str = "python2"; +const PYTHON3: &str = "python3"; + +fn python() -> &'static str { + let val = match env::var_os("PATH") { + Some(val) => val, + None => return PYTHON, + }; + + let mut python2 = false; + let mut python3 = false; + + for dir in env::split_paths(&val) { + // `python` should always take precedence over python2 / python3 if it exists + if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() { + return PYTHON; + } + + python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists(); + python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists(); + } + + // try 3 before 2 + if python3 { + PYTHON3 + } else if python2 { + PYTHON2 + } else { + // Python was not found on path, so exit + eprintln!("Unable to find python in your PATH. Please check it is installed."); + process::exit(1); + } +} + #[cfg(windows)] fn x_command(dir: &Path) -> Command { let mut cmd = Command::new("powershell.exe"); @@ -51,6 +87,17 @@ fn exec_or_status(command: &mut Command) -> io::Result { command.status() } +fn handle_result(result: io::Result, cmd: Command) { + match result { + Err(error) => { + eprintln!("Failed to invoke `{:?}`: {}", cmd, error); + } + Ok(status) => { + process::exit(status.code().unwrap_or(1)); + } + } +} + fn main() { match env::args().skip(1).next().as_deref() { Some("--wrapper-version") => { @@ -70,22 +117,19 @@ fn main() { for dir in current.ancestors() { let candidate = dir.join("x.py"); - if candidate.exists() { - let mut cmd = x_command(dir); - - cmd.args(env::args().skip(1)).current_dir(dir); - - let result = exec_or_status(&mut cmd); - - match result { - Err(error) => { - eprintln!("Failed to invoke `{:?}`: {}", cmd, error); - } - Ok(status) => { - process::exit(status.code().unwrap_or(1)); - } + let shell_script_candidate = dir.join("x"); + let mut cmd: Command; + if shell_script_candidate.exists() { + cmd = x_command(dir); + cmd.args(env::args().skip(1)).current_dir(dir); + } else { + // For older checkouts that do not have the x shell script, default to python + cmd = Command::new(python()); + cmd.arg(&candidate).args(env::args().skip(1)).current_dir(dir); } + let result = exec_or_status(&mut cmd); + handle_result(result, cmd); } } From 38b7cdf393737ee6702a2b4cc01275c6bffbd3e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 14 Feb 2023 14:31:26 +0000 Subject: [PATCH 32/47] Use target instead of machine for mir interpreter integer handling. The naming of `machine` only makes sense from a mir interpreter internals perspective, but outside users talk about the `target` platform --- .../src/const_eval/eval_queries.rs | 2 +- .../src/const_eval/machine.rs | 12 +++--- .../rustc_const_eval/src/const_eval/mod.rs | 2 +- .../src/const_eval/valtrees.rs | 6 +-- .../rustc_const_eval/src/interpret/cast.rs | 2 +- .../src/interpret/eval_context.rs | 2 +- .../src/interpret/intrinsics.rs | 32 ++++++++-------- .../rustc_const_eval/src/interpret/memory.rs | 2 +- .../rustc_const_eval/src/interpret/operand.rs | 10 ++--- .../rustc_const_eval/src/interpret/place.rs | 4 +- .../src/interpret/projection.rs | 6 +-- .../rustc_const_eval/src/interpret/step.rs | 4 +- .../src/interpret/validity.rs | 2 +- .../rustc_middle/src/mir/interpret/pointer.rs | 16 ++++---- .../rustc_middle/src/mir/interpret/value.rs | 16 ++++---- compiler/rustc_middle/src/mir/mod.rs | 4 +- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/consts/int.rs | 2 +- compiler/rustc_middle/src/ty/consts/kind.rs | 4 +- .../rustc_middle/src/ty/consts/valtree.rs | 4 +- .../ty/inhabitedness/inhabited_predicate.rs | 2 +- .../rustc_middle/src/ty/inhabitedness/mod.rs | 2 +- .../error_reporting/on_unimplemented.rs | 2 +- .../clippy_lints/src/large_const_arrays.rs | 2 +- .../clippy_lints/src/large_stack_arrays.rs | 2 +- src/tools/clippy/clippy_utils/src/consts.rs | 4 +- .../src/borrow_tracker/stacked_borrows/mod.rs | 2 +- src/tools/miri/src/eval.rs | 4 +- src/tools/miri/src/helpers.rs | 4 +- src/tools/miri/src/intptrcast.rs | 2 +- src/tools/miri/src/operator.rs | 6 +-- src/tools/miri/src/shims/backtrace.rs | 6 +-- src/tools/miri/src/shims/env.rs | 2 +- src/tools/miri/src/shims/ffi_support.rs | 4 +- src/tools/miri/src/shims/foreign_items.rs | 38 +++++++++---------- src/tools/miri/src/shims/intrinsics/mod.rs | 6 +-- src/tools/miri/src/shims/intrinsics/simd.rs | 2 +- src/tools/miri/src/shims/mod.rs | 4 +- src/tools/miri/src/shims/tls.rs | 4 +- .../miri/src/shims/unix/foreign_items.rs | 24 ++++++------ src/tools/miri/src/shims/unix/fs.rs | 20 +++++----- .../src/shims/unix/linux/foreign_items.rs | 16 ++++---- src/tools/miri/src/shims/unix/linux/sync.rs | 14 +++---- src/tools/miri/src/shims/unix/macos/dlsym.rs | 2 +- .../src/shims/unix/macos/foreign_items.rs | 6 +-- src/tools/miri/src/shims/unix/thread.rs | 12 +++--- src/tools/miri/src/shims/windows/dlsym.rs | 6 +-- .../miri/src/shims/windows/foreign_items.rs | 22 +++++------ src/tools/miri/src/shims/windows/handle.rs | 4 +- src/tools/miri/src/shims/windows/sync.rs | 2 +- src/tools/miri/src/shims/windows/thread.rs | 2 +- 51 files changed, 181 insertions(+), 181 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index b4a49e1df610c..45f7c75605584 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -186,7 +186,7 @@ pub(super) fn op_to_const<'tcx>( 0, ), }; - let len = b.to_machine_usize(ecx).unwrap(); + let len = b.to_target_usize(ecx).unwrap(); let start = start.try_into().unwrap(); let len: usize = len.try_into().unwrap(); ConstValue::Slice { data, start, end: start + len } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index d865d5bc974e0..a44f70ed05906 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -244,7 +244,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { assert_eq!(args.len(), 2); let ptr = self.read_pointer(&args[0])?; - let target_align = self.read_scalar(&args[1])?.to_machine_usize(self)?; + let target_align = self.read_scalar(&args[1])?.to_target_usize(self)?; if !target_align.is_power_of_two() { throw_ub_format!("`align_offset` called with non-power-of-two align: {}", target_align); @@ -276,7 +276,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { Ok(ControlFlow::Break(())) } else { // Not alignable in const, return `usize::MAX`. - let usize_max = Scalar::from_machine_usize(self.machine_usize_max(), self); + let usize_max = Scalar::from_target_usize(self.target_usize_max(), self); self.write_scalar(usize_max, dest)?; self.return_to_block(ret)?; Ok(ControlFlow::Break(())) @@ -470,8 +470,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.write_scalar(Scalar::from_u8(cmp), dest)?; } sym::const_allocate => { - let size = ecx.read_scalar(&args[0])?.to_machine_usize(ecx)?; - let align = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?; + let size = ecx.read_scalar(&args[0])?.to_target_usize(ecx)?; + let align = ecx.read_scalar(&args[1])?.to_target_usize(ecx)?; let align = match Align::from_bytes(align) { Ok(a) => a, @@ -487,8 +487,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } sym::const_deallocate => { let ptr = ecx.read_pointer(&args[0])?; - let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?; - let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?; + let size = ecx.read_scalar(&args[1])?.to_target_usize(ecx)?; + let align = ecx.read_scalar(&args[2])?.to_target_usize(ecx)?; let size = Size::from_bytes(size); let align = match Align::from_bytes(align) { diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 3bd586c81b0bd..3cdf1e6e30c99 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -155,7 +155,7 @@ pub(crate) fn deref_mir_constant<'tcx>( // In case of unsized types, figure out the real type behind. MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { ty::Str => bug!("there's no sized equivalent of a `str`"), - ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()), + ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_target_usize(&tcx).unwrap()), _ => bug!( "type {} should not have metadata, but had {:?}", mplace.layout.ty, diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index fc546e4de0ef6..a73f778d4db20 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -239,7 +239,7 @@ fn create_pointee_place<'tcx>( MPlaceTy::from_aligned_ptr_with_meta( ptr.into(), layout, - MemPlaceMeta::Meta(Scalar::from_machine_usize(num_elems as u64, &tcx)), + MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)), ) } else { create_mplace_from_layout(ecx, ty) @@ -355,7 +355,7 @@ fn valtree_into_mplace<'tcx>( let imm = match inner_ty.kind() { ty::Slice(_) | ty::Str => { let len = valtree.unwrap_branch().len(); - let len_scalar = Scalar::from_machine_usize(len as u64, &tcx); + let len_scalar = Scalar::from_target_usize(len as u64, &tcx); Immediate::ScalarPair( Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx), @@ -426,7 +426,7 @@ fn valtree_into_mplace<'tcx>( place .offset_with_meta( offset, - MemPlaceMeta::Meta(Scalar::from_machine_usize( + MemPlaceMeta::Meta(Scalar::from_target_usize( num_elems as u64, &tcx, )), diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 9d00e338d453c..68a91eabda7b9 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -231,7 +231,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // First cast to usize. let scalar = src.to_scalar(); let addr = self.cast_from_int_like(scalar, src.layout, self.tcx.types.usize)?; - let addr = addr.to_machine_usize(self)?; + let addr = addr.to_target_usize(self)?; // Then turn address into pointer. let ptr = M::ptr_from_addr_cast(&self, addr)?; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d13fed7a9c263..c8bf769cfd8b7 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -639,7 +639,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } ty::Slice(_) | ty::Str => { - let len = metadata.unwrap_meta().to_machine_usize(self)?; + let len = metadata.unwrap_meta().to_target_usize(self)?; let elem = layout.field(self, 0); // Make sure the slice is not too big. diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 907f014dfb518..f0b9490458dd5 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -71,7 +71,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( sym::pref_align_of => { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; - ConstValue::from_machine_usize(layout.align.pref.bytes(), &tcx) + ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx) } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; @@ -79,7 +79,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( } sym::variant_count => match tp_ty.kind() { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. - ty::Adt(adt, _) => ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx), + ty::Adt(adt, _) => ConstValue::from_target_usize(adt.variants().len() as u64, &tcx), ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => { throw_inval!(TooGeneric) } @@ -104,7 +104,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( | ty::GeneratorWitnessMIR(_, _) | ty::Never | ty::Tuple(_) - | ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx), + | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx), }, other => bug!("`{}` is not a zero arg intrinsic", other), }) @@ -156,7 +156,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => bug!(), }; - self.write_scalar(Scalar::from_machine_usize(result, self), dest)?; + self.write_scalar(Scalar::from_target_usize(result, self), dest)?; } sym::pref_align_of @@ -302,7 +302,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::offset => { let ptr = self.read_pointer(&args[0])?; - let offset_count = self.read_machine_isize(&args[1])?; + let offset_count = self.read_target_isize(&args[1])?; let pointee_ty = substs.type_at(0); let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?; @@ -310,7 +310,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } sym::arith_offset => { let ptr = self.read_pointer(&args[0])?; - let offset_count = self.read_machine_isize(&args[1])?; + let offset_count = self.read_target_isize(&args[1])?; let pointee_ty = substs.type_at(0); let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap(); @@ -376,7 +376,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // The signed form of the intrinsic allows this. If we interpret the // difference as isize, we'll get the proper signed difference. If that // seems *positive*, they were more than isize::MAX apart. - let dist = val.to_machine_isize(self)?; + let dist = val.to_target_isize(self)?; if dist >= 0 { throw_ub_format!( "`{}` called when first pointer is too far before second", @@ -386,7 +386,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { dist } else { // b >= a - let dist = val.to_machine_isize(self)?; + let dist = val.to_target_isize(self)?; // If converting to isize produced a *negative* result, we had an overflow // because they were more than isize::MAX apart. if dist < 0 { @@ -411,10 +411,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Perform division by size to compute return value. let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned { - assert!(0 <= dist && dist <= self.machine_isize_max()); + assert!(0 <= dist && dist <= self.target_isize_max()); usize_layout } else { - assert!(self.machine_isize_min() <= dist && dist <= self.machine_isize_max()); + assert!(self.target_isize_min() <= dist && dist <= self.target_isize_max()); isize_layout }; let pointee_layout = self.layout_of(substs.type_at(0))?; @@ -525,12 +525,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::vtable_size => { let ptr = self.read_pointer(&args[0])?; let (size, _align) = self.get_vtable_size_and_align(ptr)?; - self.write_scalar(Scalar::from_machine_usize(size.bytes(), self), dest)?; + self.write_scalar(Scalar::from_target_usize(size.bytes(), self), dest)?; } sym::vtable_align => { let ptr = self.read_pointer(&args[0])?; let (_size, align) = self.get_vtable_size_and_align(ptr)?; - self.write_scalar(Scalar::from_machine_usize(align.bytes(), self), dest)?; + self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } _ => return Ok(false), @@ -669,10 +669,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { count: &OpTy<'tcx, >::Provenance>, nonoverlapping: bool, ) -> InterpResult<'tcx> { - let count = self.read_machine_usize(&count)?; + let count = self.read_target_usize(&count)?; let layout = self.layout_of(src.layout.ty.builtin_deref(true).unwrap().ty)?; let (size, align) = (layout.size, layout.align.abi); - // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. let size = size.checked_mul(count, self).ok_or_else(|| { err_ub_format!( @@ -697,9 +697,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let dst = self.read_pointer(&dst)?; let byte = self.read_scalar(&byte)?.to_u8()?; - let count = self.read_machine_usize(&count)?; + let count = self.read_target_usize(&count)?; - // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. let len = layout .size diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index cfad930b1e52e..635987d039e09 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -425,7 +425,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub!(PointerOutOfBounds { alloc_id, alloc_size, - ptr_offset: self.machine_usize_to_isize(offset.bytes()), + ptr_offset: self.target_usize_to_isize(offset.bytes()), ptr_size: size, msg, }) diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 52613d5ca1f9b..ba41019aa938c 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -52,7 +52,7 @@ impl Immediate { } pub fn new_slice(val: Scalar, len: u64, cx: &impl HasDataLayout) -> Self { - Immediate::ScalarPair(val, Scalar::from_machine_usize(len, cx)) + Immediate::ScalarPair(val, Scalar::from_target_usize(len, cx)) } pub fn new_dyn_trait( @@ -414,12 +414,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.read_scalar(op)?.to_pointer(self) } /// Read a pointer-sized unsigned integer from a place. - pub fn read_machine_usize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, u64> { - self.read_scalar(op)?.to_machine_usize(self) + pub fn read_target_usize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, u64> { + self.read_scalar(op)?.to_target_usize(self) } /// Read a pointer-sized signed integer from a place. - pub fn read_machine_isize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, i64> { - self.read_scalar(op)?.to_machine_isize(self) + pub fn read_target_isize(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx, i64> { + self.read_scalar(op)?.to_target_isize(self) } /// Turn the wide MPlace into a string (must already be dereferenced!) diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index f83e5ba59dc3e..88485c06ed86c 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -229,7 +229,7 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> { if self.layout.is_unsized() { // We need to consult `meta` metadata match self.layout.ty.kind() { - ty::Slice(..) | ty::Str => self.mplace.meta.unwrap_meta().to_machine_usize(cx), + ty::Slice(..) | ty::Str => self.mplace.meta.unwrap_meta().to_target_usize(cx), _ => bug!("len not supported on unsized type {:?}", self.layout.ty), } } else { @@ -756,7 +756,7 @@ where mutbl: Mutability, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?; - let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self); + let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self); let mplace = MemPlace { ptr: ptr.into(), meta: MemPlaceMeta::Meta(meta) }; let ty = self.tcx.mk_ref( diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 291464ab58ae2..91da930db4fbf 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -319,7 +319,7 @@ where // implement this. ty::Array(inner, _) => (MemPlaceMeta::None, self.tcx.mk_array(*inner, inner_len)), ty::Slice(..) => { - let len = Scalar::from_machine_usize(inner_len, self); + let len = Scalar::from_target_usize(inner_len, self); (MemPlaceMeta::Meta(len), base.layout.ty) } _ => { @@ -363,7 +363,7 @@ where Index(local) => { let layout = self.layout_of(self.tcx.types.usize)?; let n = self.local_to_op(self.frame(), local, Some(layout))?; - let n = self.read_machine_usize(&n)?; + let n = self.read_target_usize(&n)?; self.place_index(base, n)? } ConstantIndex { offset, min_length, from_end } => { @@ -392,7 +392,7 @@ where Index(local) => { let layout = self.layout_of(self.tcx.types.usize)?; let n = self.local_to_op(self.frame(), local, Some(layout))?; - let n = self.read_machine_usize(&n)?; + let n = self.read_target_usize(&n)?; self.operand_index(base, n)? } ConstantIndex { offset, min_length, from_end } => { diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 7d9a98da08a9a..8252e73c5d937 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -242,7 +242,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let src = self.eval_place(place)?; let op = self.place_to_op(&src)?; let len = op.len(self)?; - self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?; + self.write_scalar(Scalar::from_target_usize(len, self), &dest)?; } Ref(_, borrow_kind, place) => { @@ -297,7 +297,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), }; - self.write_scalar(Scalar::from_machine_usize(val, self), &dest)?; + self.write_scalar(Scalar::from_target_usize(val, self), &dest)?; } ShallowInitBox(ref operand, _) => { diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index aa539516d5e50..820ee32047424 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -348,7 +348,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' // FIXME: check if the type/trait match what ty::Dynamic says? } ty::Slice(..) | ty::Str => { - let _len = meta.unwrap_meta().to_machine_usize(self.ecx)?; + let _len = meta.unwrap_meta().to_target_usize(self.ecx)?; // We do not check that `len * elem_size <= isize::MAX`: // that is only required for references, and there it falls out of the // "dereferenceable" check performed by Stacked Borrows. diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index ab667c22a1453..60927eed85d3b 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -19,29 +19,29 @@ pub trait PointerArithmetic: HasDataLayout { #[inline(always)] fn max_size_of_val(&self) -> Size { - Size::from_bytes(self.machine_isize_max()) + Size::from_bytes(self.target_isize_max()) } #[inline] - fn machine_usize_max(&self) -> u64 { + fn target_usize_max(&self) -> u64 { self.pointer_size().unsigned_int_max().try_into().unwrap() } #[inline] - fn machine_isize_min(&self) -> i64 { + fn target_isize_min(&self) -> i64 { self.pointer_size().signed_int_min().try_into().unwrap() } #[inline] - fn machine_isize_max(&self) -> i64 { + fn target_isize_max(&self) -> i64 { self.pointer_size().signed_int_max().try_into().unwrap() } #[inline] - fn machine_usize_to_isize(&self, val: u64) -> i64 { + fn target_usize_to_isize(&self, val: u64) -> i64 { let val = val as i64; // Now wrap-around into the machine_isize range. - if val > self.machine_isize_max() { + if val > self.target_isize_max() { // This can only happen if the ptr size is < 64, so we know max_usize_plus_1 fits into // i64. debug_assert!(self.pointer_size().bits() < 64); @@ -76,11 +76,11 @@ pub trait PointerArithmetic: HasDataLayout { let n = i.unsigned_abs(); if i >= 0 { let (val, over) = self.overflowing_offset(val, n); - (val, over || i > self.machine_isize_max()) + (val, over || i > self.target_isize_max()) } else { let res = val.overflowing_sub(n); let (val, over) = self.truncate_to_ptr(res); - (val, over || i < self.machine_isize_min()) + (val, over || i < self.target_isize_min()) } } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 77594e3440e36..36dbbe4bf7765 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -75,8 +75,8 @@ impl<'tcx> ConstValue<'tcx> { self.try_to_scalar_int()?.try_into().ok() } - pub fn try_to_machine_usize(&self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int()?.try_to_machine_usize(tcx).ok() + pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() } pub fn try_to_bits_for_ty( @@ -97,8 +97,8 @@ impl<'tcx> ConstValue<'tcx> { ConstValue::Scalar(Scalar::from_u64(i)) } - pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self { - ConstValue::Scalar(Scalar::from_machine_usize(i, cx)) + pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { + ConstValue::Scalar(Scalar::from_target_usize(i, cx)) } } @@ -241,7 +241,7 @@ impl Scalar { } #[inline] - pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self { + pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self { Self::from_uint(i, cx.data_layout().pointer_size) } @@ -268,7 +268,7 @@ impl Scalar { } #[inline] - pub fn from_machine_isize(i: i64, cx: &impl HasDataLayout) -> Self { + pub fn from_target_isize(i: i64, cx: &impl HasDataLayout) -> Self { Self::from_int(i, cx.data_layout().pointer_size) } @@ -429,7 +429,7 @@ impl<'tcx, Prov: Provenance> Scalar { /// Converts the scalar to produce a machine-pointer-sized unsigned integer. /// Fails if the scalar is a pointer. - pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { + pub fn to_target_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { let b = self.to_uint(cx.data_layout().pointer_size)?; Ok(u64::try_from(b).unwrap()) } @@ -469,7 +469,7 @@ impl<'tcx, Prov: Provenance> Scalar { /// Converts the scalar to produce a machine-pointer-sized signed integer. /// Fails if the scalar is a pointer. - pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> { + pub fn to_target_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> { let b = self.to_int(cx.data_layout().pointer_size)?; Ok(i64::try_from(b).unwrap()) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 752f5be785358..8ec3b5b0a6f24 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2349,10 +2349,10 @@ impl<'tcx> ConstantKind<'tcx> { ) -> Option { match self { Self::Ty(ct) => ct.try_eval_target_usize(tcx, param_env), - Self::Val(val, _) => val.try_to_machine_usize(tcx), + Self::Val(val, _) => val.try_to_target_usize(tcx), Self::Unevaluated(uneval, _) => { match tcx.const_eval_resolve(param_env, *uneval, None) { - Ok(val) => val.try_to_machine_usize(tcx), + Ok(val) => val.try_to_target_usize(tcx), Err(_) => None, } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 3ad56e8f273df..927f18f59b979 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -206,7 +206,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ) -> Option { - self.kind().eval(tcx, param_env).try_to_machine_usize(tcx) + self.kind().eval(tcx, param_env).try_to_target_usize(tcx) } #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 48958e0d9e91c..eecd78ab6c048 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -232,7 +232,7 @@ impl ScalarInt { } #[inline] - pub fn try_to_machine_usize(&self, tcx: TyCtxt<'_>) -> Result { + pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result { Ok(self.to_bits(tcx.data_layout.pointer_size)? as u64) } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index d9721863a58c8..58c5e21df66b9 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -125,8 +125,8 @@ impl<'tcx> ConstKind<'tcx> { } #[inline] - pub fn try_to_machine_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_value()?.try_to_machine_usize(tcx) + pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_value()?.try_to_target_usize(tcx) } } diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index a803fca0d5b89..5ed4af2e9229d 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -78,8 +78,8 @@ impl<'tcx> ValTree<'tcx> { } } - pub fn try_to_machine_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int().map(|s| s.try_to_machine_usize(tcx).ok()).flatten() + pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { + self.try_to_scalar_int().map(|s| s.try_to_target_usize(tcx).ok()).flatten() } /// Get the values inside the ValTree as a slice of bytes. This only works for diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index 8d0c7bf2f478f..e268553f8268b 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -159,7 +159,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { match self { Self::ConstIsZero(c) => { let c = ty::EarlyBinder(c).subst(tcx, substs); - let pred = match c.kind().try_to_machine_usize(tcx) { + let pred = match c.kind().try_to_target_usize(tcx) { Some(0) => Self::True, Some(1..) => Self::False, None => Self::ConstIsZero(c), diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 5d5089cec82a6..690c0d58e01c1 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -191,7 +191,7 @@ fn inhabited_predicate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> InhabitedP // If we can evaluate the array length before having a `ParamEnv`, then // we can simplify the predicate. This is an optimization. - Array(ty, len) => match len.kind().try_to_machine_usize(tcx) { + Array(ty, len) => match len.kind().try_to_target_usize(tcx) { Some(0) => InhabitedPredicate::True, Some(1..) => ty.inhabited_predicate(tcx), None => ty.inhabited_predicate(tcx).or(tcx, InhabitedPredicate::ConstIsZero(len)), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index a3209d35e58be..840bc6df2d56a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -261,7 +261,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Arrays give us `[]`, `[{ty}; _]` and `[{ty}; N]` if let ty::Array(aty, len) = self_ty.kind() { flags.push((sym::_Self, Some("[]".to_string()))); - let len = len.kind().try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx)); + let len = len.kind().try_to_value().and_then(|v| v.try_to_target_usize(self.tcx)); flags.push((sym::_Self, Some(format!("[{}; _]", aty)))); if let Some(n) = len { flags.push((sym::_Self, Some(format!("[{}; {}]", aty, n)))); diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index db637dfc068d4..4dc750c03b488 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { let ty = hir_ty_to_ty(cx.tcx, hir_ty); if let ty::Array(element_type, cst) = ty.kind(); if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind(); - if let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx); + if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx); if let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()); if self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size); diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 89ae83d48f536..32c6312e06946 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { if let ExprKind::Repeat(_, _) = expr.kind && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx) + && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && !cx.tcx.hir().parent_iter(expr.hir_id) .any(|(_, node)| matches!(node, Node::Item(Item { kind: ItemKind::Static(..), .. }))) diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 9d812fbdcc37e..8b00ce2cc2586 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -640,7 +640,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) - }, mir::ConstantKind::Val(ConstValue::ByRef { alloc, offset: _ }, _) => match result.ty().kind() { ty::Array(sub_type, len) => match sub_type.kind() { - ty::Float(FloatTy::F32) => match len.kind().try_to_machine_usize(tcx) { + ty::Float(FloatTy::F32) => match len.kind().try_to_target_usize(tcx) { Some(len) => alloc .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap())) @@ -651,7 +651,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) - .map(Constant::Vec), _ => None, }, - ty::Float(FloatTy::F64) => match len.kind().try_to_machine_usize(tcx) { + ty::Float(FloatTy::F64) => match len.kind().try_to_target_usize(tcx) { Some(len) => alloc .inner() .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap())) diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 106e93751d219..cf1ff603281ee 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -718,7 +718,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' throw_ub!(PointerOutOfBounds { alloc_id, alloc_size, - ptr_offset: this.machine_usize_to_isize(base_offset.bytes()), + ptr_offset: this.target_usize_to_isize(base_offset.bytes()), ptr_size: size, msg: CheckInAllocMsg::InboundsTest }); diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 96ab8b0d98e63..d61e17cbf9a4a 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -236,7 +236,7 @@ impl MainThreadState { this.machine.main_fn_ret_place.unwrap().ptr, this.machine.layouts.isize, ); - let exit_code = this.read_machine_isize(&ret_place.into())?; + let exit_code = this.read_target_isize(&ret_place.into())?; // Need to call this ourselves since we are not going to return to the scheduler // loop, and we want the main thread TLS to not show up as memory leaks. this.terminate_active_thread()?; @@ -287,7 +287,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( // First argument is constructed later, because it's skipped if the entry function uses #[start]. // Second argument (argc): length of `config.args`. - let argc = Scalar::from_machine_usize(u64::try_from(config.args.len()).unwrap(), &ecx); + let argc = Scalar::from_target_usize(u64::try_from(config.args.len()).unwrap(), &ecx); // Third argument (`argv`): created from `config.args`. let argv = { // Put each argument in memory, collect pointers. diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 527d31d1f0ae8..5286023e0f64e 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -758,10 +758,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let seconds_place = this.mplace_field(tp, 0)?; let seconds_scalar = this.read_scalar(&seconds_place.into())?; - let seconds = seconds_scalar.to_machine_isize(this)?; + let seconds = seconds_scalar.to_target_isize(this)?; let nanoseconds_place = this.mplace_field(tp, 1)?; let nanoseconds_scalar = this.read_scalar(&nanoseconds_place.into())?; - let nanoseconds = nanoseconds_scalar.to_machine_isize(this)?; + let nanoseconds = nanoseconds_scalar.to_target_isize(this)?; Ok(try { // tv_sec must be non-negative. diff --git a/src/tools/miri/src/intptrcast.rs b/src/tools/miri/src/intptrcast.rs index dcb1879042041..2ba18293121dc 100644 --- a/src/tools/miri/src/intptrcast.rs +++ b/src/tools/miri/src/intptrcast.rs @@ -207,7 +207,7 @@ impl<'mir, 'tcx> GlobalStateInner { .checked_add(max(size.bytes(), 1)) .ok_or_else(|| err_exhaust!(AddressSpaceFull))?; // Even if `Size` didn't overflow, we might still have filled up the address space. - if global_state.next_base_addr > ecx.machine_usize_max() { + if global_state.next_base_addr > ecx.target_usize_max() { throw_exhaust!(AddressSpaceFull); } // Given that `next_base_addr` increases in each allocation, pushing the diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index a0ef7fcad16dc..79d5dfb5551bd 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -56,7 +56,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> { Offset => { assert!(left.layout.ty.is_unsafe_ptr()); let ptr = left.to_scalar().to_pointer(self)?; - let offset = right.to_scalar().to_machine_isize(self)?; + let offset = right.to_scalar().to_target_isize(self)?; let pointee_ty = left.layout.ty.builtin_deref(true).expect("Offset called on non-ptr type").ty; @@ -73,14 +73,14 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> { // We do the actual operation with usize-typed scalars. let left = ImmTy::from_uint(ptr.addr().bytes(), self.machine.layouts.usize); let right = ImmTy::from_uint( - right.to_scalar().to_machine_usize(self)?, + right.to_scalar().to_target_usize(self)?, self.machine.layouts.usize, ); let (result, overflowing, _ty) = self.overflowing_binary_op(bin_op, &left, &right)?; // Construct a new pointer with the provenance of `ptr` (the LHS). let result_ptr = - Pointer::new(ptr.provenance, Size::from_bytes(result.to_machine_usize(self)?)); + Pointer::new(ptr.provenance, Size::from_bytes(result.to_target_usize(self)?)); (Scalar::from_maybe_pointer(result_ptr, self), overflowing, left.layout.ty) } diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index ed1c6ebfece76..1e4ab2f0f6227 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let frame_count = this.active_thread_stack().len(); - this.write_scalar(Scalar::from_machine_usize(frame_count.try_into().unwrap(), this), dest) + this.write_scalar(Scalar::from_target_usize(frame_count.try_into().unwrap(), this), dest) } fn handle_miri_get_backtrace( @@ -205,11 +205,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } 1 => { this.write_scalar( - Scalar::from_machine_usize(name.len().try_into().unwrap(), this), + Scalar::from_target_usize(name.len().try_into().unwrap(), this), &this.mplace_field(&dest, 0)?.into(), )?; this.write_scalar( - Scalar::from_machine_usize(filename.len().try_into().unwrap(), this), + Scalar::from_target_usize(filename.len().try_into().unwrap(), this), &this.mplace_field(&dest, 1)?.into(), )?; } diff --git a/src/tools/miri/src/shims/env.rs b/src/tools/miri/src/shims/env.rs index ce24b23ca3273..f50c135435fd7 100644 --- a/src/tools/miri/src/shims/env.rs +++ b/src/tools/miri/src/shims/env.rs @@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.assert_target_os_is_unix("getcwd"); let buf = this.read_pointer(buf_op)?; - let size = this.read_machine_usize(size_op)?; + let size = this.read_target_usize(size_op)?; if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { this.reject_in_isolation("`getcwd`", reject_with)?; diff --git a/src/tools/miri/src/shims/ffi_support.rs b/src/tools/miri/src/shims/ffi_support.rs index c5db868cdc7c5..e628c44a86788 100644 --- a/src/tools/miri/src/shims/ffi_support.rs +++ b/src/tools/miri/src/shims/ffi_support.rs @@ -36,7 +36,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ty::Int(IntTy::Isize) => { // This will fail if host != target, but then the entire FFI thing probably won't work well // in that situation. - return Ok(CArg::ISize(k.to_machine_isize(cx)?.try_into().unwrap())); + return Ok(CArg::ISize(k.to_target_isize(cx)?.try_into().unwrap())); } // the uints ty::Uint(UintTy::U8) => { @@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ty::Uint(UintTy::Usize) => { // This will fail if host != target, but then the entire FFI thing probably won't work well // in that situation. - return Ok(CArg::USize(k.to_machine_usize(cx)?.try_into().unwrap())); + return Ok(CArg::USize(k.to_target_usize(cx)?.try_into().unwrap())); } _ => {} } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index c792a27ab4ca2..2d9eb37a25806 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -449,7 +449,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr, out, out_size] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; - let out_size = this.read_scalar(out_size)?.to_machine_usize(this)?; + let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; // The host affects program behavior here, so this requires isolation to be disabled. this.check_no_isolation("`miri_host_to_target_path`")?; @@ -490,7 +490,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [bytes] = this.check_shim(abi, Abi::Rust, link_name, args)?; let (ptr, len) = this.read_immediate(bytes)?.to_scalar_pair(); let ptr = ptr.to_pointer(this)?; - let len = len.to_machine_usize(this)?; + let len = len.to_target_usize(this)?; let msg = this.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(len))?; // Note: we're ignoring errors writing to host stdout/stderr. @@ -504,15 +504,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Standard C allocation "malloc" => { let [size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let size = this.read_machine_usize(size)?; + let size = this.read_target_usize(size)?; let res = this.malloc(size, /*zero_init:*/ false, MiriMemoryKind::C)?; this.write_pointer(res, dest)?; } "calloc" => { let [items, len] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let items = this.read_machine_usize(items)?; - let len = this.read_machine_usize(len)?; + let items = this.read_target_usize(items)?; + let len = this.read_target_usize(len)?; let size = items .checked_mul(len) .ok_or_else(|| err_ub_format!("overflow during calloc size computation"))?; @@ -528,7 +528,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [old_ptr, new_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; - let new_size = this.read_machine_usize(new_size)?; + let new_size = this.read_target_usize(new_size)?; let res = this.realloc(old_ptr, new_size, MiriMemoryKind::C)?; this.write_pointer(res, dest)?; } @@ -536,8 +536,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Rust allocation "__rust_alloc" | "miri_alloc" => { let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; - let size = this.read_machine_usize(size)?; - let align = this.read_machine_usize(align)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { Self::check_alloc_request(size, align)?; @@ -569,8 +569,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } "__rust_alloc_zeroed" => { let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; - let size = this.read_machine_usize(size)?; - let align = this.read_machine_usize(align)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; return this.emulate_allocator(Symbol::intern("__rg_alloc_zeroed"), |this| { Self::check_alloc_request(size, align)?; @@ -593,8 +593,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "__rust_dealloc" | "miri_dealloc" => { let [ptr, old_size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; - let old_size = this.read_machine_usize(old_size)?; - let align = this.read_machine_usize(align)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { let memory_kind = match link_name.as_str() { @@ -625,9 +625,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr, old_size, align, new_size] = this.check_shim(abi, Abi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; - let old_size = this.read_machine_usize(old_size)?; - let align = this.read_machine_usize(align)?; - let new_size = this.read_machine_usize(new_size)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; + let new_size = this.read_target_usize(new_size)?; // No need to check old_size; we anyway check that they match the allocation. return this.emulate_allocator(Symbol::intern("__rg_realloc"), |this| { @@ -651,7 +651,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; - let n = Size::from_bytes(this.read_machine_usize(n)?); + let n = Size::from_bytes(this.read_target_usize(n)?); let result = { let left_bytes = this.read_bytes_ptr_strip_provenance(left, n)?; @@ -672,7 +672,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; - let num = this.read_machine_usize(num)?; + let num = this.read_target_usize(num)?; // The docs say val is "interpreted as unsigned char". #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let val = val as u8; @@ -696,7 +696,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; - let num = this.read_machine_usize(num)?; + let num = this.read_target_usize(num)?; // The docs say val is "interpreted as unsigned char". #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let val = val as u8; @@ -717,7 +717,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr = this.read_pointer(ptr)?; let n = this.read_c_str(ptr)?.len(); this.write_scalar( - Scalar::from_machine_usize(u64::try_from(n).unwrap(), this), + Scalar::from_target_usize(u64::try_from(n).unwrap(), this), dest, )?; } diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index 1b97a9d20de0c..d21a1560699c2 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -111,8 +111,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ty_layout = this.layout_of(ty)?; let val_byte = this.read_scalar(val_byte)?.to_u8()?; let ptr = this.read_pointer(ptr)?; - let count = this.read_machine_usize(count)?; - // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + let count = this.read_target_usize(count)?; + // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| { err_ub_format!("overflow computing total size of `{intrinsic_name}`") @@ -124,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [ptr, mask] = check_arg_count(args)?; let ptr = this.read_pointer(ptr)?; - let mask = this.read_machine_usize(mask)?; + let mask = this.read_target_usize(mask)?; let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask); diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index f24ddb887b95a..f2e16521290fe 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -202,7 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } Op::WrappingOffset => { let ptr = left.to_scalar().to_pointer(this)?; - let offset_count = right.to_scalar().to_machine_isize(this)?; + let offset_count = right.to_scalar().to_target_isize(this)?; let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty; let pointee_size = i64::try_from(this.layout_of(pointee_ty)?.size.bytes()).unwrap(); diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs index 39db97b72e2ce..dbc48876a4b06 100644 --- a/src/tools/miri/src/shims/mod.rs +++ b/src/tools/miri/src/shims/mod.rs @@ -80,7 +80,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return Ok(false); } - let req_align = this.read_machine_usize(align_op)?; + let req_align = this.read_target_usize(align_op)?; // Stop if the alignment is not a power of two. if !req_align.is_power_of_two() { @@ -106,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // Return error result (usize::MAX), and jump to caller. - this.write_scalar(Scalar::from_machine_usize(this.machine_usize_max(), this), dest)?; + this.write_scalar(Scalar::from_target_usize(this.target_usize_max(), this), dest)?; this.go_to_block(ret); Ok(true) } diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index ca31efa486c27..e9119f9e1eced 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -108,7 +108,7 @@ impl<'tcx> TlsData<'tcx> { ) -> InterpResult<'tcx> { match self.keys.get_mut(&key) { Some(TlsEntry { data, .. }) => { - if new_data.to_machine_usize(cx)? != 0 { + if new_data.to_target_usize(cx)? != 0 { trace!("TLS key {} for thread {:?} stored: {:?}", key, thread_id, new_data); data.insert(thread_id, new_data); } else { @@ -356,7 +356,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { state.last_key = Some(key); trace!("Running TLS dtor {:?} on {:?} at {:?}", instance, ptr, active_thread); assert!( - !ptr.to_machine_usize(this).unwrap() != 0, + !ptr.to_target_usize(this).unwrap() != 0, "data can't be NULL when dtor is called!" ); diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index d018a7ea252b7..c371e85c312e8 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -78,19 +78,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [fd, buf, count] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; - let count = this.read_machine_usize(count)?; + let count = this.read_target_usize(count)?; let result = this.read(fd, buf, count)?; - this.write_scalar(Scalar::from_machine_isize(result, this), dest)?; + this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "write" => { let [fd, buf, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; - let count = this.read_machine_usize(n)?; + let count = this.read_target_usize(n)?; trace!("Called write({:?}, {:?}, {:?})", fd, buf, count); let result = this.write(fd, buf, count)?; // Now, `result` is the value we return back to the program. - this.write_scalar(Scalar::from_machine_isize(result, this), dest)?; + this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "unlink" => { let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; @@ -151,14 +151,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "readlink" => { let [pathname, buf, bufsize] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let result = this.readlink(pathname, buf, bufsize)?; - this.write_scalar(Scalar::from_machine_isize(result, this), dest)?; + this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "posix_fadvise" => { let [fd, offset, len, advice] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.read_scalar(fd)?.to_i32()?; - this.read_machine_isize(offset)?; - this.read_machine_isize(len)?; + this.read_target_isize(offset)?; + this.read_target_isize(len)?; this.read_scalar(advice)?.to_i32()?; // fadvise is only informational, we can ignore it. this.write_null(dest)?; @@ -191,8 +191,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "posix_memalign" => { let [ret, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let ret = this.deref_operand(ret)?; - let align = this.read_machine_usize(align)?; - let size = this.read_machine_usize(size)?; + let align = this.read_target_usize(align)?; + let size = this.read_target_usize(size)?; // Align must be power of 2, and also at least ptr-sized (POSIX rules). // But failure to adhere to this is not UB, it's an error condition. if !align.is_power_of_two() || align < this.pointer_size().bytes() { @@ -216,7 +216,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Dynamic symbol loading "dlsym" => { let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_machine_usize(handle)?; + this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; let symbol_name = this.read_c_str(symbol)?; if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)? { @@ -472,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [errnum, buf, buflen] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let errnum = this.read_scalar(errnum)?; let buf = this.read_pointer(buf)?; - let buflen = this.read_machine_usize(buflen)?; + let buflen = this.read_target_usize(buflen)?; let error = this.try_errnum_to_io_error(errnum)?; let formatted = match error { @@ -565,7 +565,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let uid = this.read_scalar(uid)?.to_u32()?; let pwd = this.deref_operand(pwd)?; let buf = this.read_pointer(buf)?; - let buflen = this.read_machine_usize(buflen)?; + let buflen = this.read_target_usize(buflen)?; let result = this.deref_operand(result)?; // Must be for "us". diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 1b8f52f36657d..d05c4d98fad6f 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -754,7 +754,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We cap the number of read bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. let count = count - .min(u64::try_from(this.machine_isize_max()).unwrap()) + .min(u64::try_from(this.target_isize_max()).unwrap()) .min(u64::try_from(isize::MAX).unwrap()); let communicate = this.machine.communicate(); @@ -807,7 +807,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // We cap the number of written bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. let count = count - .min(u64::try_from(this.machine_isize_max()).unwrap()) + .min(u64::try_from(this.target_isize_max()).unwrap()) .min(u64::try_from(isize::MAX).unwrap()); let communicate = this.machine.communicate(); @@ -1290,7 +1290,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // The libc API for opendir says that this method returns a pointer to an opaque // structure, but we are returning an ID number. Thus, pass it as a scalar of // pointer width. - Ok(Scalar::from_machine_usize(id, this)) + Ok(Scalar::from_target_usize(id, this)) } Err(e) => { this.set_last_error_from_io_error(e.kind())?; @@ -1307,7 +1307,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.assert_target_os("linux", "readdir64"); - let dirp = this.read_machine_usize(dirp_op)?; + let dirp = this.read_target_usize(dirp_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1399,7 +1399,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.assert_target_os("macos", "readdir_r"); - let dirp = this.read_machine_usize(dirp_op)?; + let dirp = this.read_target_usize(dirp_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1492,7 +1492,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn closedir(&mut self, dirp_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - let dirp = this.read_machine_usize(dirp_op)?; + let dirp = this.read_target_usize(dirp_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1656,7 +1656,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let pathname = this.read_path_from_c_str(this.read_pointer(pathname_op)?)?; let buf = this.read_pointer(buf_op)?; - let bufsize = this.read_machine_usize(bufsize_op)?; + let bufsize = this.read_target_usize(bufsize_op)?; // Reject if isolation is enabled. if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { @@ -1727,7 +1727,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.reject_in_isolation("`realpath`", reject_with)?; let eacc = this.eval_libc("EACCES"); this.set_last_error(eacc)?; - return Ok(Scalar::from_machine_usize(0, this)); + return Ok(Scalar::from_target_usize(0, this)); } let result = std::fs::canonicalize(pathname); @@ -1758,7 +1758,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // seems like a bit of a mess anyway: . let enametoolong = this.eval_libc("ENAMETOOLONG"); this.set_last_error(enametoolong)?; - return Ok(Scalar::from_machine_usize(0, this)); + return Ok(Scalar::from_target_usize(0, this)); } processed_ptr }; @@ -1767,7 +1767,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } Err(e) => { this.set_last_error_from_io_error(e.kind())?; - Ok(Scalar::from_machine_usize(0, this)) + Ok(Scalar::from_target_usize(0, this)) } } } diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index 82cb21c124a26..9f6938424fb2d 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -119,18 +119,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // argument, we have to also check all arguments *before* it to ensure that they // have the right type. - let sys_getrandom = this.eval_libc("SYS_getrandom").to_machine_usize(this)?; + let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?; - let sys_statx = this.eval_libc("SYS_statx").to_machine_usize(this)?; + let sys_statx = this.eval_libc("SYS_statx").to_target_usize(this)?; - let sys_futex = this.eval_libc("SYS_futex").to_machine_usize(this)?; + let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?; if args.is_empty() { throw_ub_format!( "incorrect number of arguments for syscall: got 0, expected at least 1" ); } - match this.read_machine_usize(&args[0])? { + match this.read_target_usize(&args[0])? { // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)` // is called if a `HashMap` is created the regular way (e.g. HashMap). id if id == sys_getrandom => { @@ -155,7 +155,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } let result = this.linux_statx(&args[1], &args[2], &args[3], &args[4], &args[5])?; - this.write_scalar(Scalar::from_machine_isize(result.into(), this), dest)?; + this.write_scalar(Scalar::from_target_isize(result.into(), this), dest)?; } // `futex` is used by some synchonization primitives. id if id == sys_futex => { @@ -178,7 +178,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [pid, cpusetsize, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.read_scalar(pid)?.to_i32()?; - this.read_machine_usize(cpusetsize)?; + this.read_target_usize(cpusetsize)?; this.deref_operand(mask)?; // FIXME: we just return an error; `num_cpus` then falls back to `sysconf`. let einval = this.eval_libc("EINVAL"); @@ -210,7 +210,7 @@ fn getrandom<'tcx>( dest: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { let ptr = this.read_pointer(ptr)?; - let len = this.read_machine_usize(len)?; + let len = this.read_target_usize(len)?; // The only supported flags are GRND_RANDOM and GRND_NONBLOCK, // neither of which have any effect on our current PRNG. @@ -218,6 +218,6 @@ fn getrandom<'tcx>( let _flags = this.read_scalar(flags)?.to_i32(); this.gen_random(ptr, len)?; - this.write_scalar(Scalar::from_machine_usize(len, this), dest)?; + this.write_scalar(Scalar::from_target_usize(len, this), dest)?; Ok(()) } diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index ef43c9b0ff438..ffe3ca69c5866 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -81,7 +81,7 @@ pub fn futex<'tcx>( if bitset == 0 { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; return Ok(()); } @@ -101,7 +101,7 @@ pub fn futex<'tcx>( None => { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; return Ok(()); } }; @@ -173,7 +173,7 @@ pub fn futex<'tcx>( this.block_thread(thread); this.futex_wait(addr_usize, thread, bitset); // Succesfully waking up from FUTEX_WAIT always returns zero. - this.write_scalar(Scalar::from_machine_isize(0, this), dest)?; + this.write_scalar(Scalar::from_target_isize(0, this), dest)?; // Register a timeout callback if a timeout was specified. // This callback will override the return value when the timeout triggers. if let Some(timeout_time) = timeout_time { @@ -196,7 +196,7 @@ pub fn futex<'tcx>( this.futex_remove_waiter(self.addr_usize, self.thread); let etimedout = this.eval_libc("ETIMEDOUT"); this.set_last_error(etimedout)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), &self.dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), &self.dest)?; Ok(()) } @@ -213,7 +213,7 @@ pub fn futex<'tcx>( // right away without sleeping: -1 and errno set to EAGAIN. let eagain = this.eval_libc("EAGAIN"); this.set_last_error(eagain)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; } } // FUTEX_WAKE: (int *addr, int op = FUTEX_WAKE, int val) @@ -239,7 +239,7 @@ pub fn futex<'tcx>( if bitset == 0 { let einval = this.eval_libc("EINVAL"); this.set_last_error(einval)?; - this.write_scalar(Scalar::from_machine_isize(-1, this), dest)?; + this.write_scalar(Scalar::from_target_isize(-1, this), dest)?; return Ok(()); } // Together with the SeqCst fence in futex_wait, this makes sure that futex_wait @@ -257,7 +257,7 @@ pub fn futex<'tcx>( break; } } - this.write_scalar(Scalar::from_machine_isize(n, this), dest)?; + this.write_scalar(Scalar::from_target_isize(n, this), dest)?; } op => throw_unsup_format!("Miri does not support `futex` syscall with op={}", op), } diff --git a/src/tools/miri/src/shims/unix/macos/dlsym.rs b/src/tools/miri/src/shims/unix/macos/dlsym.rs index 44b9af79005a9..9177ecefe1207 100644 --- a/src/tools/miri/src/shims/unix/macos/dlsym.rs +++ b/src/tools/miri/src/shims/unix/macos/dlsym.rs @@ -39,7 +39,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Dlsym::getentropy => { let [ptr, len] = check_arg_count(args)?; let ptr = this.read_pointer(ptr)?; - let len = this.read_machine_usize(len)?; + let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index a55b0ee523b08..1271788a97ef0 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -161,13 +161,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Querying system information "pthread_get_stackaddr_np" => { let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_machine_usize(thread)?; + this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.read_machine_usize(thread)?; + this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); this.write_scalar(stack_size, dest)?; } @@ -176,7 +176,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "pthread_setname_np" => { let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let thread = this.pthread_self()?; - let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_machine_usize(this)?; + let max_len = this.eval_libc("MAXTHREADNAMESIZE").to_target_usize(this)?; let res = this.pthread_setname_np( thread, this.read_scalar(name)?, diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs index 832628003d770..6165cfd282307 100644 --- a/src/tools/miri/src/shims/unix/thread.rs +++ b/src/tools/miri/src/shims/unix/thread.rs @@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { throw_unsup_format!("Miri supports pthread_join only with retval==NULL"); } - let thread_id = this.read_machine_usize(thread)?; + let thread_id = this.read_target_usize(thread)?; this.join_thread_exclusive(thread_id.try_into().expect("thread ID should fit in u32"))?; Ok(0) @@ -51,7 +51,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn pthread_detach(&mut self, thread: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - let thread_id = this.read_machine_usize(thread)?; + let thread_id = this.read_target_usize(thread)?; this.detach_thread( thread_id.try_into().expect("thread ID should fit in u32"), /*allow_terminated_joined*/ false, @@ -64,7 +64,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let this = self.eval_context_mut(); let thread_id = this.get_active_thread(); - Ok(Scalar::from_machine_usize(thread_id.into(), this)) + Ok(Scalar::from_target_usize(thread_id.into(), this)) } /// Set the name of the current thread. `max_name_len` is the maximal length of the name @@ -77,7 +77,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap(); + let thread = ThreadId::try_from(thread.to_target_usize(this)?).unwrap(); let name = name.to_pointer(this)?; let name = this.read_c_str(name)?.to_owned(); @@ -100,9 +100,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); - let thread = ThreadId::try_from(thread.to_machine_usize(this)?).unwrap(); + let thread = ThreadId::try_from(thread.to_target_usize(this)?).unwrap(); let name_out = name_out.to_pointer(this)?; - let len = len.to_machine_usize(this)?; + let len = len.to_target_usize(this)?; let name = this.get_thread_name(thread).to_owned(); let (success, _written) = this.write_c_str(&name, name_out, len)?; diff --git a/src/tools/miri/src/shims/windows/dlsym.rs b/src/tools/miri/src/shims/windows/dlsym.rs index 857cf1ae7037b..60dd299c43813 100644 --- a/src/tools/miri/src/shims/windows/dlsym.rs +++ b/src/tools/miri/src/shims/windows/dlsym.rs @@ -67,10 +67,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { byte_offset, _key, ] = check_arg_count(args)?; - let handle = this.read_machine_isize(handle)?; + let handle = this.read_target_isize(handle)?; let buf = this.read_pointer(buf)?; let n = this.read_scalar(n)?.to_u32()?; - let byte_offset = this.read_machine_usize(byte_offset)?; // is actually a pointer + let byte_offset = this.read_target_usize(byte_offset)?; // is actually a pointer let io_status_block = this.deref_operand(io_status_block)?; if byte_offset != 0 { @@ -104,7 +104,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let io_status_information = this.mplace_field_named(&io_status_block, "Information")?; this.write_scalar( - Scalar::from_machine_usize(n.into(), this), + Scalar::from_target_usize(n.into(), this), &io_status_information.into(), )?; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index f310d16e86198..a3d7176a97686 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -73,9 +73,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "HeapAlloc" => { let [handle, flags, size] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(handle)?; + this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; - let size = this.read_machine_usize(size)?; + let size = this.read_target_usize(size)?; let heap_zero_memory = 0x00000008; // HEAP_ZERO_MEMORY let zero_init = (flags & heap_zero_memory) == heap_zero_memory; let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap)?; @@ -84,7 +84,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "HeapFree" => { let [handle, flags, ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(handle)?; + this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; this.free(ptr, MiriMemoryKind::WinHeap)?; @@ -93,10 +93,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "HeapReAlloc" => { let [handle, flags, ptr, size] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(handle)?; + this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; - let size = this.read_machine_usize(size)?; + let size = this.read_target_usize(size)?; let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?; this.write_pointer(res, dest)?; } @@ -299,7 +299,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { #[allow(non_snake_case)] let [hModule, lpProcName] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(hModule)?; + this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.os)? { let ptr = this.create_fn_alloc_ptr(FnVal::Other(dlsym)); @@ -323,7 +323,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [algorithm, ptr, len, flags] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; let algorithm = this.read_scalar(algorithm)?; - let algorithm = algorithm.to_machine_usize(this)?; + let algorithm = algorithm.to_target_usize(this)?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; let flags = this.read_scalar(flags)?.to_u32()?; @@ -357,7 +357,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // `term` needs this, so we fake it. let [console, buffer_info] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(console)?; + this.read_target_isize(console)?; this.deref_operand(buffer_info)?; // Indicate an error. // FIXME: we should set last_error, but to what? @@ -371,7 +371,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // one it is. This is very fake, but libtest needs it so we cannot make it a // std-only shim. // FIXME: this should return real HANDLEs when io support is added - this.write_scalar(Scalar::from_machine_isize(which.into(), this), dest)?; + this.write_scalar(Scalar::from_target_isize(which.into(), this), dest)?; } "CloseHandle" => { let [handle] = @@ -386,7 +386,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; this.check_no_isolation("`GetModuleFileNameW`")?; - let handle = this.read_machine_usize(handle)?; + let handle = this.read_target_usize(handle)?; let filename = this.read_pointer(filename)?; let size = this.read_scalar(size)?.to_u32()?; @@ -473,7 +473,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "GetConsoleMode" if this.frame_in_std() => { let [console, mode] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; - this.read_machine_isize(console)?; + this.read_target_isize(console)?; this.deref_operand(mode)?; // Indicate an error. this.write_null(dest)?; diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs index 5b22c4bd73584..8bffa9991c75a 100644 --- a/src/tools/miri/src/shims/windows/handle.rs +++ b/src/tools/miri/src/shims/windows/handle.rs @@ -124,14 +124,14 @@ impl Handle { // see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication #[allow(clippy::cast_possible_wrap)] // we want it to wrap let signed_handle = self.to_packed() as i32; - Scalar::from_machine_isize(signed_handle.into(), cx) + Scalar::from_target_isize(signed_handle.into(), cx) } pub fn from_scalar<'tcx>( handle: Scalar, cx: &impl HasDataLayout, ) -> InterpResult<'tcx, Option> { - let sign_extended_handle = handle.to_machine_isize(cx)?; + let sign_extended_handle = handle.to_target_isize(cx)?; #[allow(clippy::cast_sign_loss)] // we want to lose the sign let handle = if let Ok(signed_handle) = i32::try_from(sign_extended_handle) { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 9177f1632f704..b9cc3e15be9fe 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -273,7 +273,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr = this.read_pointer(ptr_op)?; let compare = this.read_pointer(compare_op)?; - let size = this.read_machine_usize(size_op)?; + let size = this.read_target_usize(size_op)?; let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?; let thread = this.get_active_thread(); diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs index f5bf362ea1caf..9cbae15885985 100644 --- a/src/tools/miri/src/shims/windows/thread.rs +++ b/src/tools/miri/src/shims/windows/thread.rs @@ -21,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let security = this.read_pointer(security_op)?; // stacksize is ignored, but still needs to be a valid usize - this.read_machine_usize(stacksize_op)?; + this.read_target_usize(stacksize_op)?; let start_routine = this.read_pointer(start_op)?; let func_arg = this.read_immediate(arg_op)?; let flags = this.read_scalar(flags_op)?.to_u32()?; From 86fd5a1b44afe71888b1d4e62373a6a6a8fc2cbd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Feb 2023 11:30:14 +0100 Subject: [PATCH 33/47] Use more let chain --- src/librustdoc/clean/cfg.rs | 8 +- src/librustdoc/clean/inline.rs | 27 ++-- src/librustdoc/clean/mod.rs | 119 +++++++++--------- src/librustdoc/clean/types.rs | 14 +-- src/librustdoc/clean/utils.rs | 8 +- src/librustdoc/doctest.rs | 59 ++++----- src/librustdoc/formats/cache.rs | 19 ++- src/librustdoc/html/format.rs | 8 +- src/librustdoc/html/highlight.rs | 6 +- src/librustdoc/html/render/context.rs | 14 +-- src/librustdoc/html/render/mod.rs | 52 ++++---- src/librustdoc/json/mod.rs | 11 +- .../passes/check_doc_test_visibility.rs | 23 ++-- src/librustdoc/passes/collect_trait_impls.rs | 63 +++++----- src/librustdoc/passes/lint/html_tags.rs | 8 +- src/librustdoc/passes/stripper.rs | 32 +++-- 16 files changed, 220 insertions(+), 251 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index f1853f3697df2..dd58a5b51fc1a 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -164,10 +164,10 @@ impl Cfg { /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { let mut msg = Display(self, Format::ShortHtml).to_string(); - if self.should_capitalize_first_letter() { - if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) { - msg[i..i + 1].make_ascii_uppercase(); - } + if self.should_capitalize_first_letter() && + let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) + { + msg[i..i + 1].make_ascii_uppercase(); } msg } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 6592692d8b214..8bb8f122e2268 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -390,18 +390,17 @@ pub(crate) fn build_impl( // Only inline impl if the implemented trait is // reachable in rustdoc generated documentation - if !did.is_local() { - if let Some(traitref) = associated_trait { - let did = traitref.def_id; - if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { - return; - } + if !did.is_local() && let Some(traitref) = associated_trait { + let did = traitref.def_id; + if !cx.cache.effective_visibilities.is_directly_public(tcx, did) { + return; + } - if let Some(stab) = tcx.lookup_stability(did) { - if stab.is_unstable() && stab.feature == sym::rustc_private { - return; - } - } + if let Some(stab) = tcx.lookup_stability(did) && + stab.is_unstable() && + stab.feature == sym::rustc_private + { + return; } } @@ -525,10 +524,8 @@ pub(crate) fn build_impl( } while let Some(ty) = stack.pop() { - if let Some(did) = ty.def_id(&cx.cache) { - if tcx.is_doc_hidden(did) { - return; - } + if let Some(did) = ty.def_id(&cx.cache) && tcx.is_doc_hidden(did) { + return; } if let Some(generics) = ty.generics() { stack.extend(generics); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bf3bbeb2dd133..65736bb16fc05 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -787,43 +787,43 @@ fn clean_ty_generics<'tcx>( None })(); - if let Some(param_idx) = param_idx { - if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { - let p: WherePredicate = clean_predicate(*p, cx)?; + if let Some(param_idx) = param_idx + && let Some(b) = impl_trait.get_mut(¶m_idx.into()) + { + let p: WherePredicate = clean_predicate(*p, cx)?; + + b.extend( + p.get_bounds() + .into_iter() + .flatten() + .cloned() + .filter(|b| !b.is_sized_bound(cx)), + ); - b.extend( - p.get_bounds() + let proj = projection.map(|p| { + ( + clean_projection(p.map_bound(|p| p.projection_ty), cx, None), + p.map_bound(|p| p.term), + ) + }); + if let Some(((_, trait_did, name), rhs)) = proj + .as_ref() + .and_then(|(lhs, rhs): &(Type, _)| Some((lhs.projection()?, rhs))) + { + // FIXME(...): Remove this unwrap() + impl_trait_proj.entry(param_idx).or_default().push(( + trait_did, + name, + rhs.map_bound(|rhs| rhs.ty().unwrap()), + p.get_bound_params() .into_iter() .flatten() - .cloned() - .filter(|b| !b.is_sized_bound(cx)), - ); - - let proj = projection.map(|p| { - ( - clean_projection(p.map_bound(|p| p.projection_ty), cx, None), - p.map_bound(|p| p.term), - ) - }); - if let Some(((_, trait_did, name), rhs)) = proj - .as_ref() - .and_then(|(lhs, rhs): &(Type, _)| Some((lhs.projection()?, rhs))) - { - // FIXME(...): Remove this unwrap() - impl_trait_proj.entry(param_idx).or_default().push(( - trait_did, - name, - rhs.map_bound(|rhs| rhs.ty().unwrap()), - p.get_bound_params() - .into_iter() - .flatten() - .map(|param| GenericParamDef::lifetime(param.0)) - .collect(), - )); - } - - return None; + .map(|param| GenericParamDef::lifetime(param.0)) + .collect(), + )); } + + return None; } Some(p) @@ -886,7 +886,7 @@ fn clean_ty_generics<'tcx>( // `?Sized` bound for each one we didn't find to be `Sized`. for tp in &stripped_params { if let types::GenericParamDefKind::Type { .. } = tp.kind - && !sized_params.contains(&tp.name) + && !sized_params.contains(&tp.name) { where_predicates.push(WherePredicate::BoundPredicate { ty: Type::Generic(tp.name), @@ -1461,10 +1461,10 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type // Try to normalize `::T` to a type let ty = hir_ty_to_ty(cx.tcx, hir_ty); // `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>` - if !ty.has_escaping_bound_vars() { - if let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty)) { - return clean_middle_ty(normalized_value, cx, None); - } + if !ty.has_escaping_bound_vars() + && let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty)) + { + return clean_middle_ty(normalized_value, cx, None); } let trait_segments = &p.segments[..p.segments.len() - 1]; @@ -1878,11 +1878,9 @@ fn clean_middle_opaque_bounds<'tcx>( _ => return None, }; - if let Some(sized) = cx.tcx.lang_items().sized_trait() { - if trait_ref.def_id() == sized { - has_sized = true; - return None; - } + if let Some(sized) = cx.tcx.lang_items().sized_trait() && trait_ref.def_id() == sized { + has_sized = true; + return None; } let bindings: ThinVec<_> = bounds @@ -2392,17 +2390,15 @@ fn clean_use_statement_inner<'tcx>( let is_visible_from_parent_mod = visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module(); - if pub_underscore { - if let Some(ref inline) = inline_attr { - rustc_errors::struct_span_err!( - cx.tcx.sess, - inline.span(), - E0780, - "anonymous imports cannot be inlined" - ) - .span_label(import.span, "anonymous import") - .emit(); - } + if pub_underscore && let Some(ref inline) = inline_attr { + rustc_errors::struct_span_err!( + cx.tcx.sess, + inline.span(), + E0780, + "anonymous imports cannot be inlined" + ) + .span_label(import.span, "anonymous import") + .emit(); } // We consider inlining the documentation of `pub use` statements, but we @@ -2438,14 +2434,13 @@ fn clean_use_statement_inner<'tcx>( } Import::new_glob(resolve_use_source(cx, path), true) } else { - if inline_attr.is_none() { - if let Res::Def(DefKind::Mod, did) = path.res { - if !did.is_local() && did.is_crate_root() { - // if we're `pub use`ing an extern crate root, don't inline it unless we - // were specifically asked for it - denied = true; - } - } + if inline_attr.is_none() + && let Res::Def(DefKind::Mod, did) = path.res + && !did.is_local() && did.is_crate_root() + { + // if we're `pub use`ing an extern crate root, don't inline it unless we + // were specifically asked for it + denied = true; } if !denied { let mut visited = DefIdSet::default(); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ffe6fea7ea447..b3b917ad7311b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -182,10 +182,8 @@ impl ExternalCrate { return Local; } - if extern_url_takes_precedence { - if let Some(url) = extern_url { - return to_remote(url); - } + if extern_url_takes_precedence && let Some(url) = extern_url { + return to_remote(url); } // Failing that, see if there's an attribute specifying where to find this @@ -1172,10 +1170,10 @@ impl GenericBound { pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { use rustc_hir::TraitBoundModifier as TBM; - if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self { - if Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() { - return true; - } + if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self && + Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() + { + return true; } false } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index ca3a70c7236fe..4d8ce54dc5c62 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -345,10 +345,10 @@ pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { return true; } - if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind { - if let hir::ExprKind::Lit(_) = &expr.kind { - return true; - } + if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind && + let hir::ExprKind::Lit(_) = &expr.kind + { + return true; } } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 57c41b57311df..0eba81c7c1ee3 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -229,11 +229,11 @@ fn scrape_test_config(attrs: &[ast::Attribute]) -> GlobalTestOptions { if attr.has_name(sym::no_crate_inject) { opts.no_crate_inject = true; } - if attr.has_name(sym::attr) { - if let Some(l) = attr.meta_item_list() { - for item in l { - opts.attrs.push(pprust::meta_list_item_to_string(item)); - } + if attr.has_name(sym::attr) + && let Some(l) = attr.meta_item_list() + { + for item in l { + opts.attrs.push(pprust::meta_list_item_to_string(item)); } } } @@ -594,31 +594,28 @@ pub(crate) fn make_test( loop { match parser.parse_item(ForceCollect::No) { Ok(Some(item)) => { - if !found_main { - if let ast::ItemKind::Fn(..) = item.kind { - if item.ident.name == sym::main { - found_main = true; - } - } + if !found_main && + let ast::ItemKind::Fn(..) = item.kind && + item.ident.name == sym::main + { + found_main = true; } - if !found_extern_crate { - if let ast::ItemKind::ExternCrate(original) = item.kind { - // This code will never be reached if `crate_name` is none because - // `found_extern_crate` is initialized to `true` if it is none. - let crate_name = crate_name.unwrap(); + if !found_extern_crate && + let ast::ItemKind::ExternCrate(original) = item.kind + { + // This code will never be reached if `crate_name` is none because + // `found_extern_crate` is initialized to `true` if it is none. + let crate_name = crate_name.unwrap(); - match original { - Some(name) => found_extern_crate = name.as_str() == crate_name, - None => found_extern_crate = item.ident.as_str() == crate_name, - } + match original { + Some(name) => found_extern_crate = name.as_str() == crate_name, + None => found_extern_crate = item.ident.as_str() == crate_name, } } - if !found_macro { - if let ast::ItemKind::MacCall(..) = item.kind { - found_macro = true; - } + if !found_macro && let ast::ItemKind::MacCall(..) = item.kind { + found_macro = true; } if found_main && found_extern_crate { @@ -972,14 +969,12 @@ impl Collector { fn get_filename(&self) -> FileName { if let Some(ref source_map) = self.source_map { let filename = source_map.span_to_filename(self.position); - if let FileName::Real(ref filename) = filename { - if let Ok(cur_dir) = env::current_dir() { - if let Some(local_path) = filename.local_path() { - if let Ok(path) = local_path.strip_prefix(&cur_dir) { - return path.to_owned().into(); - } - } - } + if let FileName::Real(ref filename) = filename && + let Ok(cur_dir) = env::current_dir() && + let Some(local_path) = filename.local_path() && + let Ok(path) = local_path.strip_prefix(&cur_dir) + { + return path.to_owned().into(); } filename } else if let Some(ref filename) = self.filename { diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 24752cddb337c..b1db16cfe3cac 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -229,16 +229,15 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { } // Collect all the implementors of traits. - if let clean::ImplItem(ref i) = *item.kind { - if let Some(trait_) = &i.trait_ { - if !i.kind.is_blanket() { - self.cache - .implementors - .entry(trait_.def_id()) - .or_default() - .push(Impl { impl_item: item.clone() }); - } - } + if let clean::ImplItem(ref i) = *item.kind && + let Some(trait_) = &i.trait_ && + !i.kind.is_blanket() + { + self.cache + .implementors + .entry(trait_.def_id()) + .or_default() + .push(Impl { impl_item: item.clone() }); } // Index this method for searching later on. diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 8a7a8ea5fd1f2..fd0fcdbd4ab48 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -709,11 +709,9 @@ pub(crate) fn href_with_root_path( } } }; - if !is_remote { - if let Some(root_path) = root_path { - let root = root_path.trim_end_matches('/'); - url_parts.push_front(root); - } + if !is_remote && let Some(root_path) = root_path { + let root = root_path.trim_end_matches('/'); + url_parts.push_front(root); } debug!(?url_parts); match shortty { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 3c10eb524d724..2c9fc4e3ca378 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -466,10 +466,8 @@ impl<'a> PeekIter<'a> { } /// Returns the next item after the current one. It doesn't interfere with `peek_next` output. fn peek(&mut self) -> Option<&(TokenKind, &'a str)> { - if self.stored.is_empty() { - if let Some(next) = self.iter.next() { - self.stored.push_back(next); - } + if self.stored.is_empty() && let Some(next) = self.iter.next() { + self.stored.push_back(next); } self.stored.front() } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 6762fba9275cf..5e4a595627b4a 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -705,14 +705,12 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared.fs.write(scrape_examples_help_file, v)?; } - if let Some(ref redirections) = shared.redirections { - if !redirections.borrow().is_empty() { - let redirect_map_path = - self.dst.join(crate_name.as_str()).join("redirect-map.json"); - let paths = serde_json::to_string(&*redirections.borrow()).unwrap(); - shared.ensure_dir(&self.dst.join(crate_name.as_str()))?; - shared.fs.write(redirect_map_path, paths)?; - } + if let Some(ref redirections) = shared.redirections && !redirections.borrow().is_empty() { + let redirect_map_path = + self.dst.join(crate_name.as_str()).join("redirect-map.json"); + let paths = serde_json::to_string(&*redirections.borrow()).unwrap(); + shared.ensure_dir(&self.dst.join(crate_name.as_str()))?; + shared.fs.write(redirect_map_path, paths)?; } // No need for it anymore. diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 2086faf78ac8a..e6a040d02e565 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2225,14 +2225,13 @@ fn sidebar_deref_methods( }) { debug!("found target, real_target: {:?} {:?}", target, real_target); - if let Some(did) = target.def_id(c) { - if let Some(type_did) = impl_.inner_impl().for_.def_id(c) { - // `impl Deref for S` - if did == type_did || !derefs.insert(did) { - // Avoid infinite cycles - return; - } - } + if let Some(did) = target.def_id(c) && + let Some(type_did) = impl_.inner_impl().for_.def_id(c) && + // `impl Deref for S` + (did == type_did || !derefs.insert(did)) + { + // Avoid infinite cycles + return; } let deref_mut = v.iter().any(|i| i.trait_did() == cx.tcx().lang_items().deref_mut_trait()); let inner_impl = target @@ -2266,25 +2265,24 @@ fn sidebar_deref_methods( } // Recurse into any further impls that might exist for `target` - if let Some(target_did) = target.def_id(c) { - if let Some(target_impls) = c.impls.get(&target_did) { - if let Some(target_deref_impl) = target_impls.iter().find(|i| { - i.inner_impl() - .trait_ - .as_ref() - .map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait()) - .unwrap_or(false) - }) { - sidebar_deref_methods( - cx, - out, - target_deref_impl, - target_impls, - derefs, - used_links, - ); - } - } + if let Some(target_did) = target.def_id(c) && + let Some(target_impls) = c.impls.get(&target_did) && + let Some(target_deref_impl) = target_impls.iter().find(|i| { + i.inner_impl() + .trait_ + .as_ref() + .map(|t| Some(t.def_id()) == cx.tcx().lang_items().deref_trait()) + .unwrap_or(false) + }) + { + sidebar_deref_methods( + cx, + out, + target_deref_impl, + target_impls, + derefs, + used_links, + ); } } } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 7c5c6eb3d2bbf..e3788fe57d013 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -80,12 +80,11 @@ impl<'tcx> JsonRenderer<'tcx> { // document primitive items in an arbitrary crate by using // `doc(primitive)`. let mut is_primitive_impl = false; - if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind { - if impl_.trait_.is_none() { - if let clean::types::Type::Primitive(_) = impl_.for_ { - is_primitive_impl = true; - } - } + if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind && + impl_.trait_.is_none() && + let clean::types::Type::Primitive(_) = impl_.for_ + { + is_primitive_impl = true; } if item.item_id.is_local() || is_primitive_impl { diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index f3961d5017ef4..a39d57d42b72e 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -82,18 +82,17 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - let def_id = item.item_id.expect_def_id().expect_local(); // check if parent is trait impl - if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) { - if let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) { - if matches!( - parent_node, - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }), - .. - }) - ) { - return false; - } - } + if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) && + let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) && + matches!( + parent_node, + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }), + .. + }) + ) + { + return false; } if cx.tcx.is_doc_hidden(def_id.to_def_id()) diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 878e738fe508c..189b37b69d132 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -156,39 +156,38 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> // scan through included items ahead of time to splice in Deref targets to the "valid" sets for it in new_items_external.iter().chain(new_items_local.iter()) { - if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { - if trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait() - && cleaner.keep_impl(for_, true) - { - let target = items - .iter() - .find_map(|item| match *item.kind { - AssocTypeItem(ref t, _) => Some(&t.type_), - _ => None, - }) - .expect("Deref impl without Target type"); + if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind && + trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait() && + cleaner.keep_impl(for_, true) + { + let target = items + .iter() + .find_map(|item| match *item.kind { + AssocTypeItem(ref t, _) => Some(&t.type_), + _ => None, + }) + .expect("Deref impl without Target type"); - if let Some(prim) = target.primitive_type() { - cleaner.prims.insert(prim); - } else if let Some(did) = target.def_id(&cx.cache) { - cleaner.items.insert(did.into()); - } - if let Some(for_did) = for_.def_id(&cx.cache) { - if type_did_to_deref_target.insert(for_did, target).is_none() { - // Since only the `DefId` portion of the `Type` instances is known to be same for both the - // `Deref` target type and the impl for type positions, this map of types is keyed by - // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(for_did.into()) { - let mut targets = DefIdSet::default(); - targets.insert(for_did); - add_deref_target( - cx, - &type_did_to_deref_target, - &mut cleaner, - &mut targets, - for_did, - ); - } + if let Some(prim) = target.primitive_type() { + cleaner.prims.insert(prim); + } else if let Some(did) = target.def_id(&cx.cache) { + cleaner.items.insert(did.into()); + } + if let Some(for_did) = for_.def_id(&cx.cache) { + if type_did_to_deref_target.insert(for_did, target).is_none() { + // Since only the `DefId` portion of the `Type` instances is known to be same for both the + // `Deref` target type and the impl for type positions, this map of types is keyed by + // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. + if cleaner.keep_impl_with_def_id(for_did.into()) { + let mut targets = DefIdSet::default(); + targets.insert(for_did); + add_deref_target( + cx, + &type_did_to_deref_target, + &mut cleaner, + &mut targets, + for_did, + ); } } } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index 070c0aab5868b..eac362b37b209 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -210,11 +210,9 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option { .take_while(|(_, c)| is_id_start(*c) || is_id_continue(*c)) .reduce(|_accum, item| item) .and_then(|(new_pos, c)| is_id_start(c).then_some(new_pos)); - if let Some(new_pos) = new_pos { - if current_pos != new_pos { - current_pos = new_pos; - continue; - } + if let Some(new_pos) = new_pos && current_pos != new_pos { + current_pos = new_pos; + continue; } break; } diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 048ed2646233c..cba55e5fe655c 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -201,27 +201,25 @@ impl<'a> DocFolder for ImplStripper<'a, '_> { // Because we don't inline in `maybe_inline_local` if the output format is JSON, // we need to make a special check for JSON output: we want to keep it unless it has // a `#[doc(hidden)]` attribute if the `for_` type is exported. - if let Some(did) = imp.for_.def_id(self.cache) { - if !imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did) { - debug!("ImplStripper: impl item for stripped type; removing"); - return None; - } + if let Some(did) = imp.for_.def_id(self.cache) && + !imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did) + { + debug!("ImplStripper: impl item for stripped type; removing"); + return None; } - if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) { - if !self.should_keep_impl(&i, did) { - debug!("ImplStripper: impl item for stripped trait; removing"); - return None; - } + if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) && + !self.should_keep_impl(&i, did) { + debug!("ImplStripper: impl item for stripped trait; removing"); + return None; } if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) { for typaram in generics { - if let Some(did) = typaram.def_id(self.cache) { - if !self.should_keep_impl(&i, did) { - debug!( - "ImplStripper: stripped item in trait's generics; removing impl" - ); - return None; - } + if let Some(did) = typaram.def_id(self.cache) && !self.should_keep_impl(&i, did) + { + debug!( + "ImplStripper: stripped item in trait's generics; removing impl" + ); + return None; } } } From f4de121951edc326f605c7e3109d98bbc7897a8e Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 14 Feb 2023 14:31:18 +0000 Subject: [PATCH 34/47] Don't suggest `#[doc(hidden)]` methods --- .../infer/error_reporting/note_and_explain.rs | 4 +++- tests/ui/suggestions/trait-hidden-method.rs | 11 +++++++++ .../ui/suggestions/trait-hidden-method.stderr | 24 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/ui/suggestions/trait-hidden-method.rs create mode 100644 tests/ui/suggestions/trait-hidden-method.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 984e8cf6a0eb9..1cf3758c69da2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -504,7 +504,9 @@ fn foo(&self) -> Self::T { String::new() } let methods: Vec<(Span, String)> = items .in_definition_order() .filter(|item| { - ty::AssocKind::Fn == item.kind && Some(item.name) != current_method_ident + ty::AssocKind::Fn == item.kind + && Some(item.name) != current_method_ident + && !tcx.is_doc_hidden(item.def_id) }) .filter_map(|item| { let method = tcx.fn_sig(item.def_id).subst_identity(); diff --git a/tests/ui/suggestions/trait-hidden-method.rs b/tests/ui/suggestions/trait-hidden-method.rs new file mode 100644 index 0000000000000..ae7ef47e1d4de --- /dev/null +++ b/tests/ui/suggestions/trait-hidden-method.rs @@ -0,0 +1,11 @@ +// #107983 - testing that `__iterator_get_unchecked` isn't suggested +// HELP included so that compiletest errors on the bad suggestion +pub fn i_can_has_iterator() -> impl Iterator { + //~^ ERROR expected `Box` + //~| HELP consider constraining the associated type + Box::new(1..=10) as Box + //~^ ERROR the value of the associated type `Item` + //~| HELP specify the associated type +} + +fn main() {} diff --git a/tests/ui/suggestions/trait-hidden-method.stderr b/tests/ui/suggestions/trait-hidden-method.stderr new file mode 100644 index 0000000000000..a5a65d193db06 --- /dev/null +++ b/tests/ui/suggestions/trait-hidden-method.stderr @@ -0,0 +1,24 @@ +error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified + --> $DIR/trait-hidden-method.rs:6:33 + | +LL | Box::new(1..=10) as Box + | ^^^^^^^^ help: specify the associated type: `Iterator` + +error[E0271]: expected `Box` to be an iterator that yields `u32`, but it yields `::Item` + --> $DIR/trait-hidden-method.rs:3:32 + | +LL | pub fn i_can_has_iterator() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `u32` +... +LL | Box::new(1..=10) as Box + | ------------------------------------- return type was inferred to be `Box` here + | + = note: expected associated type `::Item` + found type `u32` + = help: consider constraining the associated type `::Item` to `u32` or calling a method that returns `::Item` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0191, E0271. +For more information about an error, try `rustc --explain E0191`. From de01ea26c915cc1acdd739da2150d39d144bbcad Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 12 Feb 2023 14:37:09 -0500 Subject: [PATCH 35/47] Fix unintentional UB in ui tests --- .../2229_closure_analysis/migrations/auto_traits.fixed | 4 ++-- .../closures/2229_closure_analysis/migrations/auto_traits.rs | 4 ++-- .../2229_closure_analysis/migrations/auto_traits.stderr | 4 ++-- .../2229_closure_analysis/migrations/multi_diagnostics.fixed | 2 +- .../2229_closure_analysis/migrations/multi_diagnostics.rs | 2 +- .../migrations/multi_diagnostics.stderr | 2 +- tests/ui/consts/const-eval/issue-91827-extern-types.rs | 5 ++++- tests/ui/unsized/unsized3-rpass.rs | 4 ++-- 8 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed index 26703fbf81193..b74b5e94e2b75 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed +++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.fixed @@ -26,7 +26,7 @@ fn test_send_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0` - } }); + } }).join().unwrap(); } /* Test Sync Trait Migration */ @@ -47,7 +47,7 @@ fn test_sync_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0` - } }); + } }).join().unwrap(); } /* Test Clone Trait Migration */ diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs index 932db51d43713..e4965e33cc16f 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.rs @@ -26,7 +26,7 @@ fn test_send_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0` - }); + }).join().unwrap(); } /* Test Sync Trait Migration */ @@ -47,7 +47,7 @@ fn test_sync_trait() { //~| HELP: add a dummy let to cause `fptr` to be fully captured *fptr.0.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0` - }); + }).join().unwrap(); } /* Test Clone Trait Migration */ diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr index 3a42cc8b8439b..856ec4a5b9eb3 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr @@ -19,7 +19,7 @@ LL ~ thread::spawn(move || { let _ = &fptr; unsafe { LL | ... LL | -LL ~ } }); +LL ~ } }).join().unwrap(); | error: changes to closure capture in Rust 2021 will affect which traits the closure implements @@ -41,7 +41,7 @@ LL ~ thread::spawn(move || { let _ = &fptr; unsafe { LL | ... LL | -LL ~ } }); +LL ~ } }).join().unwrap(); | error: changes to closure capture in Rust 2021 will affect drop order and which traits the closure implements diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed index 173dd2e2cff2e..bde8c7497310d 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed +++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.fixed @@ -145,7 +145,7 @@ fn test_multi_traits_issues() { //~^ NOTE: in Rust 2018, this closure captures all of `fptr1`, but in Rust 2021, it will only capture `fptr1.0.0` *fptr2.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr2`, but in Rust 2021, it will only capture `fptr2.0` - } }); + } }).join().unwrap(); } fn main() { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs index cfc4555ca03a0..584c52ea13430 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.rs @@ -141,7 +141,7 @@ fn test_multi_traits_issues() { //~^ NOTE: in Rust 2018, this closure captures all of `fptr1`, but in Rust 2021, it will only capture `fptr1.0.0` *fptr2.0 = 20; //~^ NOTE: in Rust 2018, this closure captures all of `fptr2`, but in Rust 2021, it will only capture `fptr2.0` - }); + }).join().unwrap(); } fn main() { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr index efb264447f68d..344bc662ee73f 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr @@ -111,7 +111,7 @@ LL ~ thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe { LL | ... LL | -LL ~ } }); +LL ~ } }).join().unwrap(); | error: aborting due to 5 previous errors diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types.rs b/tests/ui/consts/const-eval/issue-91827-extern-types.rs index 43c99799f7704..c9aaa6e558747 100644 --- a/tests/ui/consts/const-eval/issue-91827-extern-types.rs +++ b/tests/ui/consts/const-eval/issue-91827-extern-types.rs @@ -28,7 +28,10 @@ pub struct ListImpl { impl List { const fn as_slice(&self) -> &[T] { - unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) } + unsafe { + let ptr = addr_of!(self.tail) as *const T; + std::slice::from_raw_parts(ptr, self.len) + } } } diff --git a/tests/ui/unsized/unsized3-rpass.rs b/tests/ui/unsized/unsized3-rpass.rs index 4d5e89575bef6..a3f92be6cf61f 100644 --- a/tests/ui/unsized/unsized3-rpass.rs +++ b/tests/ui/unsized/unsized3-rpass.rs @@ -59,7 +59,7 @@ pub fn main() { } let data: Box> = Box::new(Foo_ { f: [1, 2, 3] }); - let x: &Foo = mem::transmute(slice::from_raw_parts(&*data, 3)); + let x: &Foo = mem::transmute(ptr::slice_from_raw_parts(&*data, 3)); assert_eq!(x.f.len(), 3); assert_eq!(x.f[0], 1); @@ -70,7 +70,7 @@ pub fn main() { let data: Box<_> = Box::new(Baz_ { f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] }); - let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5)); + let x: &Baz = mem::transmute(ptr::slice_from_raw_parts(&*data, 5)); assert_eq!(x.f1, 42); let chs: Vec = x.f2.chars().collect(); assert_eq!(chs.len(), 5); From a14a4fc3d03482a2a42768bdee35201e37bab16c Mon Sep 17 00:00:00 2001 From: onestacked Date: Wed, 15 Feb 2023 15:49:17 +0100 Subject: [PATCH 36/47] Constify `RangeBounds`, `RangeX::contains` and `RangeX::is_empty`. --- library/core/src/cmp.rs | 5 +- library/core/src/ops/range.rs | 98 +++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 40 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index f290e5baf9dd3..b4d58376aea5d 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1491,9 +1491,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd<&B> for &A + #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + impl const PartialOrd<&B> for &A where - A: PartialOrd, + A: ~const PartialOrd, { #[inline] fn partial_cmp(&self, other: &&B) -> Option { diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index d29ae35614c1c..b8ab2656473df 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -96,7 +96,7 @@ impl fmt::Debug for Range { } } -impl> Range { +impl> Range { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -116,10 +116,11 @@ impl> Range { /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: ~const PartialOrd, + U: ?Sized + ~const PartialOrd, { >::contains(self, item) } @@ -142,7 +143,8 @@ impl> Range { /// assert!( (f32::NAN..5.0).is_empty()); /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] - pub fn is_empty(&self) -> bool { + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn is_empty(&self) -> bool { !(self.start < self.end) } } @@ -199,7 +201,7 @@ impl fmt::Debug for RangeFrom { } } -impl> RangeFrom { +impl> RangeFrom { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -214,10 +216,11 @@ impl> RangeFrom { /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: ~const PartialOrd, + U: ?Sized + ~const PartialOrd, { >::contains(self, item) } @@ -280,7 +283,7 @@ impl fmt::Debug for RangeTo { } } -impl> RangeTo { +impl> RangeTo { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -295,10 +298,11 @@ impl> RangeTo { /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: ~const PartialOrd, + U: ?Sized + ~const PartialOrd, { >::contains(self, item) } @@ -437,7 +441,8 @@ impl RangeInclusive { /// ``` #[stable(feature = "inclusive_range_methods", since = "1.27.0")] #[inline] - pub fn into_inner(self) -> (Idx, Idx) { + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn into_inner(self) -> (Idx, Idx) { (self.start, self.end) } } @@ -469,7 +474,7 @@ impl fmt::Debug for RangeInclusive { } } -impl> RangeInclusive { +impl> RangeInclusive { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -500,10 +505,11 @@ impl> RangeInclusive { /// assert!(!r.contains(&3) && !r.contains(&5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: ~const PartialOrd, + U: ?Sized + ~const PartialOrd, { >::contains(self, item) } @@ -535,8 +541,9 @@ impl> RangeInclusive { /// assert!(r.is_empty()); /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] #[inline] - pub fn is_empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.exhausted || !(self.start <= self.end) } } @@ -598,7 +605,7 @@ impl fmt::Debug for RangeToInclusive { } } -impl> RangeToInclusive { +impl> RangeToInclusive { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -613,10 +620,11 @@ impl> RangeToInclusive { /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - pub fn contains(&self, item: &U) -> bool + #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] + pub const fn contains(&self, item: &U) -> bool where - Idx: PartialOrd, - U: ?Sized + PartialOrd, + Idx: ~const PartialOrd, + U: ?Sized + ~const PartialOrd, { >::contains(self, item) } @@ -757,6 +765,7 @@ impl Bound<&T> { /// `RangeBounds` is implemented by Rust's built-in range types, produced /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[stable(feature = "collections_range", since = "1.28.0")] +#[const_trait] pub trait RangeBounds { /// Start index bound. /// @@ -809,8 +818,8 @@ pub trait RangeBounds { #[stable(feature = "range_contains", since = "1.35.0")] fn contains(&self, item: &U) -> bool where - T: PartialOrd, - U: ?Sized + PartialOrd, + T: ~const PartialOrd, + U: ?Sized + ~const PartialOrd, { (match self.start_bound() { Included(start) => start <= item, @@ -827,7 +836,8 @@ pub trait RangeBounds { use self::Bound::{Excluded, Included, Unbounded}; #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeFull { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeFull { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -837,7 +847,8 @@ impl RangeBounds for RangeFull { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeFrom { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeFrom { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -847,7 +858,8 @@ impl RangeBounds for RangeFrom { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeTo { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeTo { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -857,7 +869,8 @@ impl RangeBounds for RangeTo { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for Range { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for Range { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -867,7 +880,8 @@ impl RangeBounds for Range { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeInclusive { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeInclusive { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -883,7 +897,8 @@ impl RangeBounds for RangeInclusive { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeToInclusive { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeToInclusive { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -893,7 +908,8 @@ impl RangeBounds for RangeToInclusive { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for (Bound, Bound) { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for (Bound, Bound) { fn start_bound(&self) -> Bound<&T> { match *self { (Included(ref start), _) => Included(start), @@ -912,7 +928,8 @@ impl RangeBounds for (Bound, Bound) { } #[stable(feature = "collections_range", since = "1.28.0")] -impl<'a, T: ?Sized + 'a> RangeBounds for (Bound<&'a T>, Bound<&'a T>) { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl<'a, T: ?Sized + 'a> const RangeBounds for (Bound<&'a T>, Bound<&'a T>) { fn start_bound(&self) -> Bound<&T> { self.0 } @@ -923,7 +940,8 @@ impl<'a, T: ?Sized + 'a> RangeBounds for (Bound<&'a T>, Bound<&'a T>) { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeFrom<&T> { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -933,7 +951,8 @@ impl RangeBounds for RangeFrom<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeTo<&T> { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeTo<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -943,7 +962,8 @@ impl RangeBounds for RangeTo<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for Range<&T> { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for Range<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -953,7 +973,8 @@ impl RangeBounds for Range<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeInclusive<&T> { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -963,7 +984,8 @@ impl RangeBounds for RangeInclusive<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -impl RangeBounds for RangeToInclusive<&T> { +#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] +impl const RangeBounds for RangeToInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } From 29621ba28876696a8dd01d746c49f3affc843c49 Mon Sep 17 00:00:00 2001 From: Callum Leslie Date: Wed, 15 Feb 2023 16:22:08 +0000 Subject: [PATCH 37/47] clarify correctness of `black_box` --- library/core/src/hint.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 5a76e86692336..ee13dae60b198 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -216,7 +216,8 @@ pub fn spin_loop() { /// /// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The /// extent to which it can block optimisations may vary depending upon the platform and code-gen -/// backend used. Programs cannot rely on `black_box` for *correctness* in any way. +/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the +/// identity function. /// /// [`std::convert::identity`]: crate::convert::identity /// From 08cc628e7334b7f200b09f5f2c77700231103fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Wed, 15 Feb 2023 15:51:48 +0100 Subject: [PATCH 38/47] Add point-at-inference ui test for wrong arity case --- .../type/type-check/point-at-inference-4.rs | 23 +++++++++++ .../type-check/point-at-inference-4.stderr | 38 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/ui/type/type-check/point-at-inference-4.rs create mode 100644 tests/ui/type/type-check/point-at-inference-4.stderr diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs new file mode 100644 index 0000000000000..647c7d622fa56 --- /dev/null +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -0,0 +1,23 @@ +struct S(Option<(A, B)>); + +impl S { + fn infer(&self, a: A, b: B) {} + //~^ NOTE associated function defined here + //~| NOTE + //~| NOTE +} + +fn main() { + let s = S(None); + s.infer(0i32); + //~^ ERROR this method takes 2 arguments but 1 argument was supplied + //~| NOTE an argument is missing + //~| HELP provide the argument + //~| NOTE this is of type `i32`, which causes `s` to be inferred as `S` + //~| HELP change the type of the numeric literal from `i32` to `u32` + let t: S = s; + //~^ ERROR mismatched types + //~| NOTE expected `S`, found `S` + //~| NOTE expected due to this + //~| NOTE expected struct `S` +} diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr new file mode 100644 index 0000000000000..62e798e56f7cd --- /dev/null +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -0,0 +1,38 @@ +error[E0061]: this method takes 2 arguments but 1 argument was supplied + --> $DIR/point-at-inference-4.rs:12:7 + | +LL | s.infer(0i32); + | ^^^^^------ an argument is missing + | +note: associated function defined here + --> $DIR/point-at-inference-4.rs:4:8 + | +LL | fn infer(&self, a: A, b: B) {} + | ^^^^^ ---- ---- +help: provide the argument + | +LL | s.infer(0i32, /* b */); + | ~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/point-at-inference-4.rs:18:24 + | +LL | s.infer(0i32); + | ---- this is of type `i32`, which causes `s` to be inferred as `S` +... +LL | let t: S = s; + | --------- ^ expected `S`, found `S` + | | + | expected due to this + | + = note: expected struct `S` + found struct `S` +help: change the type of the numeric literal from `i32` to `u32` + | +LL | s.infer(0u32); + | ~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. From e159c1e0ec3c70c1876790984e769f1e20b19a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Wed, 15 Feb 2023 18:45:20 +0100 Subject: [PATCH 39/47] Skip method calls with arity mismatch --- compiler/rustc_hir_typeck/src/demand.rs | 8 +++++++- tests/ui/type/type-check/point-at-inference-4.rs | 2 -- tests/ui/type/type-check/point-at-inference-4.stderr | 9 +-------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 16d3115c233b0..79b3c0590b6bf 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -298,6 +298,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // call's arguments and we can provide a more explicit span. let sig = self.tcx.fn_sig(def_id).subst_identity(); let def_self_ty = sig.input(0).skip_binder(); + let param_tys = sig.inputs().skip_binder().iter().skip(1); + // If there's an arity mismatch, pointing out the call as the source of an inference + // can be misleading, so we skip it. + if param_tys.len() != args.len() { + continue; + } let rcvr_ty = self.node_ty(rcvr.hir_id); // Get the evaluated type *after* calling the method call, so that the influence // of the arguments can be reflected in the receiver type. The receiver @@ -323,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut param_found = FxHashMap::default(); if self.can_eq(self.param_env, ty, found).is_ok() { // We only point at the first place where the found type was inferred. - for (param_ty, arg) in sig.inputs().skip_binder().iter().skip(1).zip(args) { + for (param_ty, arg) in param_tys.zip(args) { if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { // We found an argument that references a type parameter in `Self`, // so we assume that this is the argument that caused the found diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs index 647c7d622fa56..7903e9e83cfb3 100644 --- a/tests/ui/type/type-check/point-at-inference-4.rs +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -13,8 +13,6 @@ fn main() { //~^ ERROR this method takes 2 arguments but 1 argument was supplied //~| NOTE an argument is missing //~| HELP provide the argument - //~| NOTE this is of type `i32`, which causes `s` to be inferred as `S` - //~| HELP change the type of the numeric literal from `i32` to `u32` let t: S = s; //~^ ERROR mismatched types //~| NOTE expected `S`, found `S` diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index 62e798e56f7cd..fac9701e4a11e 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -15,11 +15,8 @@ LL | s.infer(0i32, /* b */); | ~~~~~~~~~~~~~~~ error[E0308]: mismatched types - --> $DIR/point-at-inference-4.rs:18:24 + --> $DIR/point-at-inference-4.rs:16:24 | -LL | s.infer(0i32); - | ---- this is of type `i32`, which causes `s` to be inferred as `S` -... LL | let t: S = s; | --------- ^ expected `S`, found `S` | | @@ -27,10 +24,6 @@ LL | let t: S = s; | = note: expected struct `S` found struct `S` -help: change the type of the numeric literal from `i32` to `u32` - | -LL | s.infer(0u32); - | ~~~ error: aborting due to 2 previous errors From 15adc7b5e430bdef0c6ba1526b510878ac0c69eb Mon Sep 17 00:00:00 2001 From: Kornel Date: Wed, 15 Feb 2023 18:47:50 +0000 Subject: [PATCH 40/47] Demonstrate I/O in File examples --- library/std/src/fs.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 286ad68fd13e8..8a2799b17b9e4 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -343,9 +343,12 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::Read; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::open("foo.txt")?; + /// let mut data = vec![]; + /// f.read_to_end(&mut data)?; /// Ok(()) /// } /// ``` @@ -368,9 +371,11 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::Write; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::create("foo.txt")?; + /// f.write_all(&1234_u32.to_be_bytes())?; /// Ok(()) /// } /// ``` @@ -397,9 +402,11 @@ impl File { /// #![feature(file_create_new)] /// /// use std::fs::File; + /// use std::io::Write; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::create_new("foo.txt")?; + /// f.write_all("Hello, world!".as_bytes())?; /// Ok(()) /// } /// ``` @@ -426,9 +433,11 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::Write; /// /// fn main() -> std::io::Result<()> { /// let mut f = File::options().append(true).open("example.log")?; + /// writeln!(&mut f, "new line")?; /// Ok(()) /// } /// ``` From 4c2d48ee800dd79bfb64b91ccee5262295fea9d5 Mon Sep 17 00:00:00 2001 From: Kornel Date: Wed, 15 Feb 2023 18:48:19 +0000 Subject: [PATCH 41/47] Suggest simpler fs helper methods in File::{open,create} --- library/std/src/fs.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8a2799b17b9e4..c550378e7d6b7 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -334,6 +334,10 @@ impl File { /// /// See the [`OpenOptions::open`] method for more details. /// + /// If you only need to read the entire file contents, + /// consider [`std::fs::read()`][self::read] or + /// [`std::fs::read_to_string()`][self::read_to_string] instead. + /// /// # Errors /// /// This function will return an error if `path` does not already exist. @@ -364,9 +368,11 @@ impl File { /// /// Depending on the platform, this function may fail if the /// full directory path does not exist. - /// /// See the [`OpenOptions::open`] function for more details. /// + /// See also [`std::fs::write()`][self::write] for a simple function to + /// create a file with a given data. + /// /// # Examples /// /// ```no_run @@ -975,6 +981,9 @@ impl OpenOptions { /// In order for the file to be created, [`OpenOptions::write`] or /// [`OpenOptions::append`] access must be used. /// + /// See also [`std::fs::write()`][self::write] for a simple function to + /// create a file with a given data. + /// /// # Examples /// /// ```no_run From e087f61075814ae2612193f98a84c7f77101f90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 15 Feb 2023 23:18:40 +0100 Subject: [PATCH 42/47] don't clone types that are copy --- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +-- compiler/rustc_query_system/src/query/caches.rs | 6 +++--- compiler/rustc_trait_selection/src/solve/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/object_safety.rs | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b5e6727bfbadf..6dd3726a2be38 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -517,8 +517,7 @@ fn method_autoderef_steps<'tcx>( .by_ref() .map(|(ty, d)| { let step = CandidateStep { - self_ty: infcx - .make_query_response_ignoring_pending_obligations(inference_vars.clone(), ty), + self_ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, ty), autoderefs: d, from_unsafe_deref: reached_raw_pointer, unsize: false, diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index c9dd75e4d554b..81c7e4673d41b 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -92,7 +92,7 @@ where let mut lock = self.cache.lock(); // We may be overwriting another value. This is all right, since the dep-graph // will check that the fingerprint matches. - lock.insert(key, (value.clone(), index)); + lock.insert(key, (value, index)); value } @@ -153,7 +153,7 @@ where #[inline] fn complete(&self, _key: (), value: V, index: DepNodeIndex) -> Self::Stored { - *self.cache.lock() = Some((value.clone(), index)); + *self.cache.lock() = Some((value, index)); value } @@ -283,7 +283,7 @@ where let mut lock = self.cache.get_shard_by_hash(key.index() as u64).lock(); #[cfg(not(parallel_compiler))] let mut lock = self.cache.lock(); - lock.insert(key, (value.clone(), index)); + lock.insert(key, (value, index)); value } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 301eb4d95f892..28aa3d5270590 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -547,7 +547,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { response.value.certainty == Certainty::Yes && response.has_no_inference_or_external_constraints() }) { - return Ok(response.clone()); + return Ok(*response); } let certainty = candidates.iter().fold(Certainty::AMBIGUOUS, |certainty, response| { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index c12ba103c340c..7ef39b2010743 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -599,7 +599,7 @@ fn virtual_call_violation_for_method<'tcx>( return false; } - contains_illegal_self_type_reference(tcx, trait_def_id, pred.clone()) + contains_illegal_self_type_reference(tcx, trait_def_id, pred) }) { return Some(MethodViolationCode::WhereClauseReferencesSelf); } From 46f895caddacf82ae6bf706272d73960a864b6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 15 Feb 2023 23:41:23 +0100 Subject: [PATCH 43/47] simplify some refs --- compiler/rustc_middle/src/ty/flags.rs | 2 +- compiler/rustc_type_ir/src/sty.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 258bc9c3e4188..c9aa0ec66d561 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -125,7 +125,7 @@ impl FlagComputation { self.bound_computation(ts, |flags, ts| flags.add_tys(ts)); } - &ty::GeneratorWitnessMIR(_, ref substs) => { + ty::GeneratorWitnessMIR(_, substs) => { let should_remove_further_specializable = !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); self.add_substs(substs); diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 61557fdc0eda4..e080726d91d58 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -336,7 +336,7 @@ impl PartialEq for TyKind { a_d == b_d && a_s == b_s && a_m == b_m } (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g, - (&GeneratorWitnessMIR(ref a_d, ref a_s), &GeneratorWitnessMIR(ref b_d, ref b_s)) => { + (GeneratorWitnessMIR(a_d, a_s), GeneratorWitnessMIR(b_d, b_s)) => { a_d == b_d && a_s == b_s } (Tuple(a_t), Tuple(b_t)) => a_t == b_t, @@ -397,8 +397,8 @@ impl Ord for TyKind { } (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g.cmp(b_g), ( - &GeneratorWitnessMIR(ref a_d, ref a_s), - &GeneratorWitnessMIR(ref b_d, ref b_s), + GeneratorWitnessMIR(a_d, a_s), + GeneratorWitnessMIR(b_d, b_s), ) => match Ord::cmp(a_d, b_d) { Ordering::Equal => Ord::cmp(a_s, b_s), cmp => cmp, From e17cd0c01961e58e551958f5878b88141dc5aefb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 16 Feb 2023 00:06:51 +0100 Subject: [PATCH 44/47] be nice and don't slice These are already slices, no need to slice them again --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8c753a99a09f0..9f560ebaf3318 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1970,7 +1970,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) = &qself.kind { // If the path segment already has type params, we want to overwrite // them. - match &path.segments[..] { + match &path.segments { // `segment` is the previous to last element on the path, // which would normally be the `enum` itself, while the last // `_` `PathSegment` corresponds to the variant. @@ -2671,7 +2671,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // `Self` in trait or type alias. assert_eq!(opt_self_ty, None); self.prohibit_generics(path.segments.iter(), |err| { - if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments[..] { + if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments { err.span_suggestion_verbose( ident.span.shrink_to_hi().to(args.span_ext), "the `Self` type doesn't accept type parameters", From 22a5125a367eedc9f1d6b49bac6557a4b4864423 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 15 Sep 2022 11:29:12 +1000 Subject: [PATCH 45/47] Remove save-analysis. Most tests involving save-analysis were removed, but I kept a few where the `-Zsave-analysis` was an add-on to the main thing being tested, rather than the main thing being tested. For `x.py install`, the `rust-analysis` target has been removed. For `x.py dist`, the `rust-analysis` target has been kept in a degenerate form: it just produces a single file `reduced.json` indicating that save-analysis has been removed. This is necessary for rustup to keep working. Closes #43606. --- Cargo.lock | 41 - compiler/rustc_driver_impl/Cargo.toml | 1 - compiler/rustc_driver_impl/src/lib.rs | 20 +- .../locales/en-US/save_analysis.ftl | 1 - compiler/rustc_error_messages/src/lib.rs | 1 - compiler/rustc_interface/src/tests.rs | 1 - compiler/rustc_save_analysis/Cargo.toml | 21 - .../rustc_save_analysis/src/dump_visitor.rs | 1465 ----------------- compiler/rustc_save_analysis/src/dumper.rs | 91 - compiler/rustc_save_analysis/src/errors.rs | 10 - compiler/rustc_save_analysis/src/lib.rs | 1067 ------------ compiler/rustc_save_analysis/src/sig.rs | 931 ----------- .../rustc_save_analysis/src/span_utils.rs | 96 -- compiler/rustc_session/src/options.rs | 3 - src/bootstrap/builder.rs | 11 - src/bootstrap/dist.rs | 11 +- src/bootstrap/install.rs | 12 - src/doc/rustc/src/json.md | 1 - src/tools/tidy/src/deps.rs | 2 - .../issues-41478-43796/Makefile | 8 - .../run-make-fulldeps/issues-41478-43796/a.rs | 9 - .../save-analysis-fail/Makefile | 6 - .../save-analysis-fail/SameDir.rs | 5 - .../save-analysis-fail/SameDir3.rs | 3 - .../save-analysis-fail/SubDir/mod.rs | 27 - .../save-analysis-fail/foo.rs | 463 ------ .../save-analysis-fail/krate2.rs | 8 - .../save-analysis-rfc2126/Makefile | 8 - .../extern_absolute_paths.rs | 6 - .../save-analysis-rfc2126/krate2.rs | 5 - .../save-analysis-rfc2126/validate_json.py | 7 - .../run-make-fulldeps/save-analysis/Makefile | 6 - .../save-analysis/SameDir.rs | 5 - .../save-analysis/SameDir3.rs | 3 - .../save-analysis/SubDir/mod.rs | 27 - .../save-analysis/extra-docs.md | 1 - tests/run-make-fulldeps/save-analysis/foo.rs | 465 ------ .../run-make-fulldeps/save-analysis/krate2.rs | 8 - tests/rustdoc-ui/z-help.stdout | 1 - tests/ui/asm/issue-72570.rs | 2 - tests/ui/asm/issue-72570.stderr | 2 +- ...st-argument-non-static-lifetime.min.stderr | 2 +- .../const-argument-non-static-lifetime.rs | 1 - ...aram-type-depends-on-type-param-ungated.rs | 3 - ...-type-depends-on-type-param-ungated.stderr | 2 +- tests/ui/const-generics/issues/issue-73260.rs | 1 - .../const-generics/issues/issue-73260.stderr | 8 +- .../feature-gate-associated_type_bounds.rs | 3 - ...feature-gate-associated_type_bounds.stderr | 34 +- .../ui/impl-trait/bound-normalization-pass.rs | 2 - tests/ui/issues/issue-3763.rs | 3 +- tests/ui/issues/issue-3763.stderr | 10 +- tests/ui/methods/assign-to-method.rs | 3 +- tests/ui/methods/assign-to-method.stderr | 4 +- .../emit-notifications.polonius.stderr | 2 - tests/ui/save-analysis/emit-notifications.rs | 7 - .../save-analysis/emit-notifications.stderr | 2 - tests/ui/save-analysis/issue-26459.rs | 8 - tests/ui/save-analysis/issue-26459.stderr | 9 - tests/ui/save-analysis/issue-37323.rs | 20 - tests/ui/save-analysis/issue-59134-0.rs | 12 - tests/ui/save-analysis/issue-59134-0.stderr | 9 - tests/ui/save-analysis/issue-59134-1.rs | 12 - tests/ui/save-analysis/issue-59134-1.stderr | 9 - tests/ui/save-analysis/issue-63663.rs | 28 - tests/ui/save-analysis/issue-64659.rs | 10 - tests/ui/save-analysis/issue-65411.rs | 15 - tests/ui/save-analysis/issue-65590.rs | 21 - tests/ui/save-analysis/issue-68621.rs | 17 - tests/ui/save-analysis/issue-68621.stderr | 10 - tests/ui/save-analysis/issue-72267.rs | 7 - tests/ui/save-analysis/issue-72267.stderr | 15 - tests/ui/save-analysis/issue-73020.rs | 5 - tests/ui/save-analysis/issue-73020.stderr | 9 - tests/ui/save-analysis/issue-73022.rs | 13 - tests/ui/save-analysis/issue-89066.rs | 28 - tests/ui/save-analysis/issue-89066.stderr | 39 - tests/ui/traits/alias/self-in-generics.rs | 4 - tests/ui/traits/alias/self-in-generics.stderr | 2 +- tests/ui/type-alias-impl-trait/issue-63279.rs | 2 - .../type-alias-impl-trait/issue-63279.stderr | 12 +- ...sue-65679-inst-opaque-ty-from-val-twice.rs | 1 - 82 files changed, 50 insertions(+), 5215 deletions(-) delete mode 100644 compiler/rustc_error_messages/locales/en-US/save_analysis.ftl delete mode 100644 compiler/rustc_save_analysis/Cargo.toml delete mode 100644 compiler/rustc_save_analysis/src/dump_visitor.rs delete mode 100644 compiler/rustc_save_analysis/src/dumper.rs delete mode 100644 compiler/rustc_save_analysis/src/errors.rs delete mode 100644 compiler/rustc_save_analysis/src/lib.rs delete mode 100644 compiler/rustc_save_analysis/src/sig.rs delete mode 100644 compiler/rustc_save_analysis/src/span_utils.rs delete mode 100644 tests/run-make-fulldeps/issues-41478-43796/Makefile delete mode 100644 tests/run-make-fulldeps/issues-41478-43796/a.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-fail/Makefile delete mode 100644 tests/run-make-fulldeps/save-analysis-fail/SameDir.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-fail/SameDir3.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-fail/foo.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-fail/krate2.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-rfc2126/Makefile delete mode 100644 tests/run-make-fulldeps/save-analysis-rfc2126/extern_absolute_paths.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-rfc2126/krate2.rs delete mode 100644 tests/run-make-fulldeps/save-analysis-rfc2126/validate_json.py delete mode 100644 tests/run-make-fulldeps/save-analysis/Makefile delete mode 100644 tests/run-make-fulldeps/save-analysis/SameDir.rs delete mode 100644 tests/run-make-fulldeps/save-analysis/SameDir3.rs delete mode 100644 tests/run-make-fulldeps/save-analysis/SubDir/mod.rs delete mode 100644 tests/run-make-fulldeps/save-analysis/extra-docs.md delete mode 100644 tests/run-make-fulldeps/save-analysis/foo.rs delete mode 100644 tests/run-make-fulldeps/save-analysis/krate2.rs delete mode 100644 tests/ui/save-analysis/emit-notifications.polonius.stderr delete mode 100644 tests/ui/save-analysis/emit-notifications.rs delete mode 100644 tests/ui/save-analysis/emit-notifications.stderr delete mode 100644 tests/ui/save-analysis/issue-26459.rs delete mode 100644 tests/ui/save-analysis/issue-26459.stderr delete mode 100644 tests/ui/save-analysis/issue-37323.rs delete mode 100644 tests/ui/save-analysis/issue-59134-0.rs delete mode 100644 tests/ui/save-analysis/issue-59134-0.stderr delete mode 100644 tests/ui/save-analysis/issue-59134-1.rs delete mode 100644 tests/ui/save-analysis/issue-59134-1.stderr delete mode 100644 tests/ui/save-analysis/issue-63663.rs delete mode 100644 tests/ui/save-analysis/issue-64659.rs delete mode 100644 tests/ui/save-analysis/issue-65411.rs delete mode 100644 tests/ui/save-analysis/issue-65590.rs delete mode 100644 tests/ui/save-analysis/issue-68621.rs delete mode 100644 tests/ui/save-analysis/issue-68621.stderr delete mode 100644 tests/ui/save-analysis/issue-72267.rs delete mode 100644 tests/ui/save-analysis/issue-72267.stderr delete mode 100644 tests/ui/save-analysis/issue-73020.rs delete mode 100644 tests/ui/save-analysis/issue-73020.stderr delete mode 100644 tests/ui/save-analysis/issue-73022.rs delete mode 100644 tests/ui/save-analysis/issue-89066.rs delete mode 100644 tests/ui/save-analysis/issue-89066.stderr diff --git a/Cargo.lock b/Cargo.lock index 15f051d0cff1a..6a1525f7530d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3495,25 +3495,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rls-data" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58135eb039f3a3279a33779192f0ee78b56f57ae636e25cec83530e41debb99" -dependencies = [ - "rls-span", - "serde", -] - -[[package]] -name = "rls-span" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eea58478fc06e15f71b03236612173a1b81e9770314edecfa664375e3e4c86" -dependencies = [ - "serde", -] - [[package]] name = "rust-demangler" version = "0.0.1" @@ -3965,7 +3946,6 @@ dependencies = [ "rustc_middle", "rustc_parse", "rustc_plugin_impl", - "rustc_save_analysis", "rustc_session", "rustc_span", "rustc_target", @@ -4625,27 +4605,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "rustc_save_analysis" -version = "0.0.0" -dependencies = [ - "rls-data", - "rls-span", - "rustc_ast", - "rustc_ast_pretty", - "rustc_data_structures", - "rustc_errors", - "rustc_hir", - "rustc_hir_pretty", - "rustc_lexer", - "rustc_macros", - "rustc_middle", - "rustc_session", - "rustc_span", - "serde_json", - "tracing", -] - [[package]] name = "rustc_serialize" version = "0.0.0" diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index af85b12c52b20..cdec4f912779c 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -22,7 +22,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_parse = { path = "../rustc_parse" } rustc_plugin_impl = { path = "../rustc_plugin_impl" } -rustc_save_analysis = { path = "../rustc_save_analysis" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_session = { path = "../rustc_session" } rustc_error_codes = { path = "../rustc_error_codes" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 1067fcebcf395..1a4fe07b47656 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -25,13 +25,10 @@ use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; use rustc_errors::{ErrorGuaranteed, PResult, TerminalUrl}; use rustc_feature::find_gated_cfg; -use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; use rustc_metadata::locator; -use rustc_save_analysis as save; -use rustc_save_analysis::DumpHandler; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; use rustc_session::cstore::MetadataLoader; @@ -343,22 +340,7 @@ fn run_compiler( return early_exit(); } - queries.global_ctxt()?.enter(|tcx| { - let result = tcx.analysis(()); - if sess.opts.unstable_opts.save_analysis { - let crate_name = tcx.crate_name(LOCAL_CRATE); - sess.time("save_analysis", || { - save::process_crate( - tcx, - crate_name, - &sess.io.input, - None, - DumpHandler::new(sess.io.output_dir.as_deref(), crate_name), - ) - }); - } - result - })?; + queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?; if callbacks.after_analysis(compiler, queries) == Compilation::Stop { return early_exit(); diff --git a/compiler/rustc_error_messages/locales/en-US/save_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/save_analysis.ftl deleted file mode 100644 index 36c2ff4682301..0000000000000 --- a/compiler/rustc_error_messages/locales/en-US/save_analysis.ftl +++ /dev/null @@ -1 +0,0 @@ -save_analysis_could_not_open = Could not open `{$file_name}`: `{$err}` diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 1882d4b698e61..579466ed366d8 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -67,7 +67,6 @@ fluent_messages! { privacy => "../locales/en-US/privacy.ftl", query_system => "../locales/en-US/query_system.ftl", resolve => "../locales/en-US/resolve.ftl", - save_analysis => "../locales/en-US/save_analysis.ftl", session => "../locales/en-US/session.ftl", symbol_mangling => "../locales/en-US/symbol_mangling.ftl", trait_selection => "../locales/en-US/trait_selection.ftl", diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0d3499ca9a048..ac32988d3ac6e 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -691,7 +691,6 @@ fn test_unstable_options_tracking_hash() { untracked!(proc_macro_execution_strategy, ProcMacroExecutionStrategy::CrossThread); untracked!(profile_closures, true); untracked!(query_dep_graph, true); - untracked!(save_analysis, true); untracked!(self_profile, SwitchWithOptPath::Enabled(None)); untracked!(self_profile_events, Some(vec![String::new()])); untracked!(span_debug, true); diff --git a/compiler/rustc_save_analysis/Cargo.toml b/compiler/rustc_save_analysis/Cargo.toml deleted file mode 100644 index 181e27f334b40..0000000000000 --- a/compiler/rustc_save_analysis/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "rustc_save_analysis" -version = "0.0.0" -edition = "2021" - -[dependencies] -tracing = "0.1" -rustc_middle = { path = "../rustc_middle" } -rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_data_structures = { path = "../rustc_data_structures" } -rustc_errors = { path = "../rustc_errors" } -rustc_hir = { path = "../rustc_hir" } -rustc_hir_pretty = { path = "../rustc_hir_pretty" } -rustc_lexer = { path = "../rustc_lexer" } -rustc_macros = { path = "../rustc_macros" } -serde_json = "1" -rustc_session = { path = "../rustc_session" } -rustc_span = { path = "../rustc_span" } -rls-data = "0.19" -rls-span = "0.5" diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs deleted file mode 100644 index 3982111e38e08..0000000000000 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ /dev/null @@ -1,1465 +0,0 @@ -//! Write the output of rustc's analysis to an implementor of Dump. -//! -//! Dumping the analysis is implemented by walking the AST and getting a bunch of -//! info out from all over the place. We use `DefId`s to identify objects. The -//! tricky part is getting syntactic (span, source text) and semantic (reference -//! `DefId`s) information for parts of expressions which the compiler has discarded. -//! E.g., in a path `foo::bar::baz`, the compiler only keeps a span for the whole -//! path and a reference to `baz`, but we want spans and references for all three -//! idents. -//! -//! SpanUtils is used to manipulate spans. In particular, to extract sub-spans -//! from spans (e.g., the span for `bar` from the above example path). -//! DumpVisitor walks the AST and processes it, and Dumper is used for -//! recording the output. - -use rustc_ast as ast; -use rustc_ast::walk_list; -use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; -use rustc_hir::def::{DefKind as HirDefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; -use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir_pretty::{bounds_to_string, fn_to_string, generic_params_to_string, ty_to_string}; -use rustc_middle::hir::nested_filter; -use rustc_middle::span_bug; -use rustc_middle::ty::{self, DefIdTree, TyCtxt}; -use rustc_session::config::Input; -use rustc_span::symbol::Ident; -use rustc_span::*; - -use std::env; -use std::path::Path; - -use crate::dumper::{Access, Dumper}; -use crate::sig; -use crate::span_utils::SpanUtils; -use crate::{ - escape, generated_code, id_from_def_id, id_from_hir_id, lower_attributes, PathCollector, - SaveContext, -}; - -use rls_data::{ - CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, - RefKind, Relation, RelationKind, SpanData, -}; - -#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5213 -macro_rules! down_cast_data { - ($id:ident, $kind:ident, $sp:expr) => { - let super::Data::$kind($id) = $id else { - span_bug!($sp, "unexpected data kind: {:?}", $id); - }; - }; -} - -macro_rules! access_from { - ($save_ctxt:expr, $id:expr) => { - Access { - public: $save_ctxt.tcx.visibility($id).is_public(), - reachable: $save_ctxt.effective_visibilities.is_reachable($id), - } - }; -} - -pub struct DumpVisitor<'tcx> { - pub save_ctxt: SaveContext<'tcx>, - tcx: TyCtxt<'tcx>, - dumper: Dumper, - - span: SpanUtils<'tcx>, - // Set of macro definition (callee) spans, and the set - // of macro use (callsite) spans. We store these to ensure - // we only write one macro def per unique macro definition, and - // one macro use per unique callsite span. - // mac_defs: FxHashSet, - // macro_calls: FxHashSet, -} - -impl<'tcx> DumpVisitor<'tcx> { - pub fn new(save_ctxt: SaveContext<'tcx>) -> DumpVisitor<'tcx> { - let span_utils = SpanUtils::new(&save_ctxt.tcx.sess); - let dumper = Dumper::new(save_ctxt.config.clone()); - DumpVisitor { tcx: save_ctxt.tcx, save_ctxt, dumper, span: span_utils } - } - - pub fn analysis(&self) -> &rls_data::Analysis { - self.dumper.analysis() - } - - fn nest_typeck_results(&mut self, item_def_id: LocalDefId, f: F) - where - F: FnOnce(&mut Self), - { - let typeck_results = if self.tcx.has_typeck_results(item_def_id) { - Some(self.tcx.typeck(item_def_id)) - } else { - None - }; - - let old_maybe_typeck_results = self.save_ctxt.maybe_typeck_results; - self.save_ctxt.maybe_typeck_results = typeck_results; - f(self); - self.save_ctxt.maybe_typeck_results = old_maybe_typeck_results; - } - - fn span_from_span(&self, span: Span) -> SpanData { - self.save_ctxt.span_from_span(span) - } - - fn lookup_def_id(&self, ref_id: hir::HirId) -> Option { - self.save_ctxt.lookup_def_id(ref_id) - } - - pub fn dump_crate_info(&mut self, name: Symbol) { - let crate_root = self.tcx.sess.local_crate_source_file().map(|source_file| { - match source_file.file_name() { - Some(_) => source_file.parent().unwrap().display(), - None => source_file.display(), - } - .to_string() - }); - - let data = CratePreludeData { - crate_id: GlobalCrateId { - name: name.to_string(), - disambiguator: (self.tcx.sess.local_stable_crate_id().to_u64(), 0), - }, - crate_root: crate_root.unwrap_or_else(|| "".to_owned()), - external_crates: self.save_ctxt.get_external_crates(), - span: self.span_from_span(self.tcx.def_span(CRATE_DEF_ID)), - }; - - self.dumper.crate_prelude(data); - } - - pub fn dump_compilation_options(&mut self, input: &Input, crate_name: Symbol) { - // Apply possible `remap-path-prefix` remapping to the input source file - // (and don't include remapping args anymore) - let (program, arguments) = { - let remap_arg_indices = { - let mut indices = FxHashSet::default(); - // Args are guaranteed to be valid UTF-8 (checked early) - for (i, e) in env::args().enumerate() { - if e.starts_with("--remap-path-prefix=") { - indices.insert(i); - } else if e == "--remap-path-prefix" { - indices.insert(i); - indices.insert(i + 1); - } - } - indices - }; - - let mut args = env::args() - .enumerate() - .filter(|(i, _)| !remap_arg_indices.contains(i)) - .map(|(_, arg)| match input { - Input::File(ref path) if path == Path::new(&arg) => self - .tcx - .sess - .local_crate_source_file() - .as_ref() - .unwrap() - .to_string_lossy() - .into(), - _ => arg, - }); - - (args.next().unwrap(), args.collect()) - }; - - let data = CompilationOptions { - directory: self.tcx.sess.opts.working_dir.remapped_path_if_available().into(), - program, - arguments, - output: self.save_ctxt.compilation_output(crate_name), - }; - - self.dumper.compilation_opts(data); - } - - fn write_segments(&mut self, segments: impl IntoIterator>) { - for seg in segments { - if let Some(data) = self.save_ctxt.get_path_segment_data(seg) { - self.dumper.dump_ref(data); - } - } - } - - fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx, R>) { - self.write_segments(path.segments) - } - - // As write_sub_paths, but does not process the last ident in the path (assuming it - // will be processed elsewhere). See note on write_sub_paths about global. - fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx, R>) { - if let [segments @ .., _] = path.segments { - self.write_segments(segments) - } - } - - fn process_formals(&mut self, formals: &'tcx [hir::Param<'tcx>], qualname: &str) { - for arg in formals { - self.visit_pat(&arg.pat); - let mut collector = PathCollector::new(self.tcx); - collector.visit_pat(&arg.pat); - - for (hir_id, ident, ..) in collector.collected_idents { - let typ = match self.save_ctxt.typeck_results().node_type_opt(hir_id) { - Some(s) => s.to_string(), - None => continue, - }; - if !self.span.filter_generated(ident.span) { - let id = id_from_hir_id(hir_id); - let span = self.span_from_span(ident.span); - - self.dumper.dump_def( - &Access { public: false, reachable: false }, - Def { - kind: DefKind::Local, - id, - span, - name: ident.to_string(), - qualname: format!("{}::{}", qualname, ident), - value: typ, - parent: None, - children: vec![], - decl_id: None, - docs: String::new(), - sig: None, - attributes: vec![], - }, - ); - } - } - } - } - - fn process_method( - &mut self, - sig: &'tcx hir::FnSig<'tcx>, - body: Option, - owner_id: hir::OwnerId, - ident: Ident, - generics: &'tcx hir::Generics<'tcx>, - span: Span, - ) { - debug!("process_method: {:?}:{}", owner_id, ident); - - let map = self.tcx.hir(); - let hir_id: hir::HirId = owner_id.into(); - self.nest_typeck_results(owner_id.def_id, |v| { - if let Some(mut method_data) = v.save_ctxt.get_method_data(owner_id, ident, span) { - if let Some(body) = body { - v.process_formals(map.body(body).params, &method_data.qualname); - } - v.process_generic_params(&generics, &method_data.qualname, hir_id); - - method_data.value = - fn_to_string(sig.decl, sig.header, Some(ident.name), generics, &[], None); - method_data.sig = - sig::method_signature(owner_id, ident, generics, sig, &v.save_ctxt); - - v.dumper.dump_def(&access_from!(v.save_ctxt, owner_id.def_id), method_data); - } - - // walk arg and return types - for arg in sig.decl.inputs { - v.visit_ty(arg); - } - - if let hir::FnRetTy::Return(ref ret_ty) = sig.decl.output { - v.visit_ty(ret_ty) - } - - // walk the fn body - if let Some(body) = body { - v.visit_expr(&map.body(body).value); - } - }); - } - - fn process_struct_field_def( - &mut self, - field: &'tcx hir::FieldDef<'tcx>, - parent_id: LocalDefId, - ) { - let field_data = self.save_ctxt.get_field_data(field, parent_id); - if let Some(field_data) = field_data { - self.dumper.dump_def(&access_from!(self.save_ctxt, field.def_id), field_data); - } - } - - // Dump generic params bindings, then visit_generics - fn process_generic_params( - &mut self, - generics: &'tcx hir::Generics<'tcx>, - prefix: &str, - id: hir::HirId, - ) { - for param in generics.params { - match param.kind { - hir::GenericParamKind::Lifetime { .. } => {} - hir::GenericParamKind::Type { .. } => { - let param_ss = param.name.ident().span; - let name = escape(self.span.snippet(param_ss)); - // Append $id to name to make sure each one is unique. - let qualname = format!("{}::{}${}", prefix, name, id); - if !self.span.filter_generated(param_ss) { - let id = id_from_def_id(param.def_id.to_def_id()); - let span = self.span_from_span(param_ss); - - self.dumper.dump_def( - &Access { public: false, reachable: false }, - Def { - kind: DefKind::Type, - id, - span, - name, - qualname, - value: String::new(), - parent: None, - children: vec![], - decl_id: None, - docs: String::new(), - sig: None, - attributes: vec![], - }, - ); - } - } - hir::GenericParamKind::Const { .. } => {} - } - } - - self.visit_generics(generics) - } - - fn process_fn( - &mut self, - item: &'tcx hir::Item<'tcx>, - decl: &'tcx hir::FnDecl<'tcx>, - _header: &'tcx hir::FnHeader, - ty_params: &'tcx hir::Generics<'tcx>, - body: hir::BodyId, - ) { - let map = self.tcx.hir(); - self.nest_typeck_results(item.owner_id.def_id, |v| { - let body = map.body(body); - if let Some(fn_data) = v.save_ctxt.get_item_data(item) { - down_cast_data!(fn_data, DefData, item.span); - v.process_formals(body.params, &fn_data.qualname); - v.process_generic_params(ty_params, &fn_data.qualname, item.hir_id()); - - v.dumper.dump_def(&access_from!(v.save_ctxt, item.owner_id.def_id), fn_data); - } - - for arg in decl.inputs { - v.visit_ty(arg) - } - - if let hir::FnRetTy::Return(ref ret_ty) = decl.output { - v.visit_ty(ret_ty) - } - - v.visit_expr(&body.value); - }); - } - - fn process_static_or_const_item( - &mut self, - item: &'tcx hir::Item<'tcx>, - typ: &'tcx hir::Ty<'tcx>, - expr: &'tcx hir::Expr<'tcx>, - ) { - self.nest_typeck_results(item.owner_id.def_id, |v| { - if let Some(var_data) = v.save_ctxt.get_item_data(item) { - down_cast_data!(var_data, DefData, item.span); - v.dumper.dump_def(&access_from!(v.save_ctxt, item.owner_id.def_id), var_data); - } - v.visit_ty(&typ); - v.visit_expr(expr); - }); - } - - fn process_assoc_const( - &mut self, - owner_id: hir::OwnerId, - ident: Ident, - typ: &'tcx hir::Ty<'tcx>, - expr: Option<&'tcx hir::Expr<'tcx>>, - parent_id: DefId, - attrs: &'tcx [ast::Attribute], - ) { - let qualname = format!("::{}", self.tcx.def_path_str(owner_id.to_def_id())); - - if !self.span.filter_generated(ident.span) { - let sig = sig::assoc_const_signature(owner_id, ident.name, typ, expr, &self.save_ctxt); - let span = self.span_from_span(ident.span); - - self.dumper.dump_def( - &access_from!(self.save_ctxt, owner_id.def_id), - Def { - kind: DefKind::Const, - id: id_from_def_id(owner_id.to_def_id()), - span, - name: ident.name.to_string(), - qualname, - value: ty_to_string(&typ), - parent: Some(id_from_def_id(parent_id)), - children: vec![], - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig, - attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt), - }, - ); - } - - // walk type and init value - self.nest_typeck_results(owner_id.def_id, |v| { - v.visit_ty(typ); - if let Some(expr) = expr { - v.visit_expr(expr); - } - }); - } - - // FIXME tuple structs should generate tuple-specific data. - fn process_struct( - &mut self, - item: &'tcx hir::Item<'tcx>, - def: &'tcx hir::VariantData<'tcx>, - ty_params: &'tcx hir::Generics<'tcx>, - ) { - debug!("process_struct {:?} {:?}", item, item.span); - let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.def_path_str(item.owner_id.to_def_id())); - - let kind = match item.kind { - hir::ItemKind::Struct(_, _) => DefKind::Struct, - hir::ItemKind::Union(_, _) => DefKind::Union, - _ => unreachable!(), - }; - - let (value, fields) = match item.kind { - hir::ItemKind::Struct(hir::VariantData::Struct(ref fields, ..), ..) - | hir::ItemKind::Union(hir::VariantData::Struct(ref fields, ..), ..) => { - let include_priv_fields = !self.save_ctxt.config.pub_only; - let fields_str = fields - .iter() - .filter_map(|f| { - if include_priv_fields { - return Some(f.ident.to_string()); - } - if self.save_ctxt.tcx.visibility(f.def_id).is_public() { - Some(f.ident.to_string()) - } else { - None - } - }) - .collect::>() - .join(", "); - let value = format!("{} {{ {} }}", name, fields_str); - (value, fields.iter().map(|f| id_from_def_id(f.def_id.to_def_id())).collect()) - } - _ => (String::new(), vec![]), - }; - - if !self.span.filter_generated(item.ident.span) { - let span = self.span_from_span(item.ident.span); - let attrs = self.tcx.hir().attrs(item.hir_id()); - self.dumper.dump_def( - &access_from!(self.save_ctxt, item.owner_id.def_id), - Def { - kind, - id: id_from_def_id(item.owner_id.to_def_id()), - span, - name, - qualname: qualname.clone(), - value, - parent: None, - children: fields, - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: sig::item_signature(item, &self.save_ctxt), - attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt), - }, - ); - } - - self.nest_typeck_results(item.owner_id.def_id, |v| { - for field in def.fields() { - v.process_struct_field_def(field, item.owner_id.def_id); - v.visit_ty(&field.ty); - } - - v.process_generic_params(ty_params, &qualname, item.hir_id()); - }); - } - - fn process_enum( - &mut self, - item: &'tcx hir::Item<'tcx>, - enum_definition: &'tcx hir::EnumDef<'tcx>, - ty_params: &'tcx hir::Generics<'tcx>, - ) { - let enum_data = self.save_ctxt.get_item_data(item); - let Some(enum_data) = enum_data else { - return; - }; - down_cast_data!(enum_data, DefData, item.span); - - let access = access_from!(self.save_ctxt, item.owner_id.def_id); - - for variant in enum_definition.variants { - let name = variant.ident.name.to_string(); - let qualname = format!("{}::{}", enum_data.qualname, name); - let name_span = variant.ident.span; - - match variant.data { - hir::VariantData::Struct(ref fields, ..) => { - let fields_str = - fields.iter().map(|f| f.ident.to_string()).collect::>().join(", "); - let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str); - if !self.span.filter_generated(name_span) { - let span = self.span_from_span(name_span); - let id = id_from_def_id(variant.def_id.to_def_id()); - let parent = Some(id_from_def_id(item.owner_id.to_def_id())); - let attrs = self.tcx.hir().attrs(variant.hir_id); - - self.dumper.dump_def( - &access, - Def { - kind: DefKind::StructVariant, - id, - span, - name, - qualname, - value, - parent, - children: vec![], - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: sig::variant_signature(variant, &self.save_ctxt), - attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt), - }, - ); - } - } - ref v => { - let mut value = format!("{}::{}", enum_data.name, name); - if let hir::VariantData::Tuple(fields, _, _) = v { - value.push('('); - value.push_str( - &fields - .iter() - .map(|f| ty_to_string(&f.ty)) - .collect::>() - .join(", "), - ); - value.push(')'); - } - if !self.span.filter_generated(name_span) { - let span = self.span_from_span(name_span); - let id = id_from_def_id(variant.def_id.to_def_id()); - let parent = Some(id_from_def_id(item.owner_id.to_def_id())); - let attrs = self.tcx.hir().attrs(variant.hir_id); - - self.dumper.dump_def( - &access, - Def { - kind: DefKind::TupleVariant, - id, - span, - name, - qualname, - value, - parent, - children: vec![], - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: sig::variant_signature(variant, &self.save_ctxt), - attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt), - }, - ); - } - } - } - - for field in variant.data.fields() { - self.process_struct_field_def(field, variant.def_id); - self.visit_ty(field.ty); - } - } - self.process_generic_params(ty_params, &enum_data.qualname, item.hir_id()); - self.dumper.dump_def(&access, enum_data); - } - - fn process_impl(&mut self, item: &'tcx hir::Item<'tcx>, impl_: &'tcx hir::Impl<'tcx>) { - if let Some(impl_data) = self.save_ctxt.get_item_data(item) { - if !self.span.filter_generated(item.span) { - if let super::Data::RelationData(rel, imp) = impl_data { - self.dumper.dump_relation(rel); - self.dumper.dump_impl(imp); - } else { - span_bug!(item.span, "unexpected data kind: {:?}", impl_data); - } - } - } - - let map = self.tcx.hir(); - self.nest_typeck_results(item.owner_id.def_id, |v| { - v.visit_ty(&impl_.self_ty); - if let Some(trait_ref) = &impl_.of_trait { - v.process_path(trait_ref.hir_ref_id, &hir::QPath::Resolved(None, &trait_ref.path)); - } - v.process_generic_params(&impl_.generics, "", item.hir_id()); - for impl_item in impl_.items { - v.process_impl_item(map.impl_item(impl_item.id), item.owner_id.to_def_id()); - } - }); - } - - fn process_trait( - &mut self, - item: &'tcx hir::Item<'tcx>, - generics: &'tcx hir::Generics<'tcx>, - trait_refs: hir::GenericBounds<'tcx>, - methods: &'tcx [hir::TraitItemRef], - ) { - let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.def_path_str(item.owner_id.to_def_id())); - let mut val = name.clone(); - if !generics.params.is_empty() { - val.push_str(&generic_params_to_string(generics.params)); - } - if !trait_refs.is_empty() { - val.push_str(": "); - val.push_str(&bounds_to_string(trait_refs)); - } - if !self.span.filter_generated(item.ident.span) { - let id = id_from_def_id(item.owner_id.to_def_id()); - let span = self.span_from_span(item.ident.span); - let children = - methods.iter().map(|i| id_from_def_id(i.id.owner_id.to_def_id())).collect(); - let attrs = self.tcx.hir().attrs(item.hir_id()); - self.dumper.dump_def( - &access_from!(self.save_ctxt, item.owner_id.def_id), - Def { - kind: DefKind::Trait, - id, - span, - name, - qualname: qualname.clone(), - value: val, - parent: None, - children, - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: sig::item_signature(item, &self.save_ctxt), - attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt), - }, - ); - } - - // supertraits - for super_bound in trait_refs.iter() { - let (def_id, sub_span) = match *super_bound { - hir::GenericBound::Trait(ref trait_ref, _) => ( - self.lookup_def_id(trait_ref.trait_ref.hir_ref_id), - trait_ref.trait_ref.path.segments.last().unwrap().ident.span, - ), - hir::GenericBound::LangItemTrait(lang_item, span, _, _) => { - (Some(self.tcx.require_lang_item(lang_item, Some(span))), span) - } - hir::GenericBound::Outlives(..) => continue, - }; - - if let Some(id) = def_id { - if !self.span.filter_generated(sub_span) { - let span = self.span_from_span(sub_span); - self.dumper.dump_ref(Ref { - kind: RefKind::Type, - span: span.clone(), - ref_id: id_from_def_id(id), - }); - - self.dumper.dump_relation(Relation { - kind: RelationKind::SuperTrait, - span, - from: id_from_def_id(id), - to: id_from_def_id(item.owner_id.to_def_id()), - }); - } - } - } - - // walk generics and methods - self.process_generic_params(generics, &qualname, item.hir_id()); - for method in methods { - let map = self.tcx.hir(); - self.process_trait_item(map.trait_item(method.id), item.owner_id.to_def_id()) - } - } - - // `item` is the module in question, represented as an( item. - fn process_mod(&mut self, item: &'tcx hir::Item<'tcx>) { - if let Some(mod_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(mod_data, DefData, item.span); - self.dumper.dump_def(&access_from!(self.save_ctxt, item.owner_id.def_id), mod_data); - } - } - - fn dump_path_ref(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) { - let path_data = self.save_ctxt.get_path_data(id, path); - if let Some(path_data) = path_data { - self.dumper.dump_ref(path_data); - } - } - - fn dump_path_segment_ref(&mut self, id: hir::HirId, segment: &hir::PathSegment<'tcx>) { - let segment_data = self.save_ctxt.get_path_segment_data_with_id(segment, id); - if let Some(segment_data) = segment_data { - self.dumper.dump_ref(segment_data); - } - } - - fn process_path(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) { - if self.span.filter_generated(path.span()) { - return; - } - self.dump_path_ref(id, path); - - // Type arguments - let segments = match path { - hir::QPath::Resolved(ty, path) => { - if let Some(ty) = ty { - self.visit_ty(ty); - } - path.segments - } - hir::QPath::TypeRelative(ty, segment) => { - self.visit_ty(ty); - std::slice::from_ref(*segment) - } - hir::QPath::LangItem(..) => return, - }; - for seg in segments { - if let Some(ref generic_args) = seg.args { - for arg in generic_args.args { - if let hir::GenericArg::Type(ref ty) = arg { - self.visit_ty(ty); - } - } - } - } - - if let hir::QPath::Resolved(_, path) = path { - self.write_sub_paths_truncated(path); - } - } - - fn process_struct_lit( - &mut self, - ex: &'tcx hir::Expr<'tcx>, - path: &'tcx hir::QPath<'tcx>, - fields: &'tcx [hir::ExprField<'tcx>], - variant: &'tcx ty::VariantDef, - rest: Option<&'tcx hir::Expr<'tcx>>, - ) { - if let Some(_ex_res_data) = self.save_ctxt.get_expr_data(ex) { - if let hir::QPath::Resolved(_, path) = path { - self.write_sub_paths_truncated(path); - } - // For MyEnum::MyVariant, get_expr_data gives us MyEnum, not MyVariant. - // For recording the span's ref id, we want MyVariant. - if !generated_code(ex.span) { - let sub_span = path.last_segment_span(); - let span = self.save_ctxt.span_from_span(sub_span); - let reff = - Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(variant.def_id) }; - self.dumper.dump_ref(reff); - } - - for field in fields { - if let Some(field_data) = self.save_ctxt.get_field_ref_data(field, variant) { - self.dumper.dump_ref(field_data); - } - - self.visit_expr(&field.expr) - } - } - - if let Some(base) = rest { - self.visit_expr(&base); - } - } - - fn process_method_call( - &mut self, - ex: &'tcx hir::Expr<'tcx>, - seg: &'tcx hir::PathSegment<'tcx>, - receiver: &'tcx hir::Expr<'tcx>, - args: &'tcx [hir::Expr<'tcx>], - ) { - debug!("process_method_call {:?} {:?}", ex, ex.span); - if let Some(mcd) = self.save_ctxt.get_expr_data(ex) { - down_cast_data!(mcd, RefData, ex.span); - if !generated_code(ex.span) { - self.dumper.dump_ref(mcd); - } - } - - // Explicit types in the turbo-fish. - if let Some(generic_args) = seg.args { - for arg in generic_args.args { - if let hir::GenericArg::Type(ty) = arg { - self.visit_ty(&ty) - }; - } - } - - // walk receiver and args - self.visit_expr(receiver); - walk_list!(self, visit_expr, args); - } - - fn process_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { - match p.kind { - hir::PatKind::Struct(ref _path, fields, _) => { - // FIXME do something with _path? - let adt = match self.save_ctxt.typeck_results().node_type_opt(p.hir_id) { - Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(), - _ => { - intravisit::walk_pat(self, p); - return; - } - }; - let variant = adt.variant_of_res(self.save_ctxt.get_path_res(p.hir_id)); - - for field in fields { - if let Some(index) = self.tcx.find_field_index(field.ident, variant) { - if !self.span.filter_generated(field.ident.span) { - let span = self.span_from_span(field.ident.span); - self.dumper.dump_ref(Ref { - kind: RefKind::Variable, - span, - ref_id: id_from_def_id(variant.fields[index].did), - }); - } - } - self.visit_pat(&field.pat); - } - } - _ => intravisit::walk_pat(self, p), - } - } - - fn process_var_decl(&mut self, pat: &'tcx hir::Pat<'tcx>) { - // The pattern could declare multiple new vars, - // we must walk the pattern and collect them all. - let mut collector = PathCollector::new(self.tcx); - collector.visit_pat(&pat); - self.visit_pat(&pat); - - // Process collected paths. - for (id, ident, _) in collector.collected_idents { - let res = self.save_ctxt.get_path_res(id); - match res { - Res::Local(hir_id) => { - let typ = self - .save_ctxt - .typeck_results() - .node_type_opt(hir_id) - .map(|t| t.to_string()) - .unwrap_or_default(); - - // Rust uses the id of the pattern for var lookups, so we'll use it too. - if !self.span.filter_generated(ident.span) { - let qualname = format!("{}${}", ident, hir_id); - let id = id_from_hir_id(hir_id); - let span = self.span_from_span(ident.span); - - self.dumper.dump_def( - &Access { public: false, reachable: false }, - Def { - kind: DefKind::Local, - id, - span, - name: ident.to_string(), - qualname, - value: typ, - parent: None, - children: vec![], - decl_id: None, - docs: String::new(), - sig: None, - attributes: vec![], - }, - ); - } - } - Res::Def( - HirDefKind::Ctor(..) - | HirDefKind::Const - | HirDefKind::AssocConst - | HirDefKind::Struct - | HirDefKind::Variant - | HirDefKind::TyAlias - | HirDefKind::AssocTy, - _, - ) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } => { - self.dump_path_segment_ref( - id, - &hir::PathSegment::new(ident, hir::HirId::INVALID, Res::Err), - ); - } - def => { - error!("unexpected definition kind when processing collected idents: {:?}", def) - } - } - } - - for (id, ref path) in collector.collected_paths { - self.process_path(id, path); - } - } - - /// Extracts macro use and definition information from the AST node defined - /// by the given NodeId, using the expansion information from the node's - /// span. - /// - /// If the span is not macro-generated, do nothing, else use callee and - /// callsite spans to record macro definition and use data, using the - /// mac_uses and mac_defs sets to prevent multiples. - fn process_macro_use(&mut self, _span: Span) { - // FIXME if we're not dumping the defs (see below), there is no point - // dumping refs either. - // let source_span = span.source_callsite(); - // if !self.macro_calls.insert(source_span) { - // return; - // } - - // let data = match self.save_ctxt.get_macro_use_data(span) { - // None => return, - // Some(data) => data, - // }; - - // self.dumper.macro_use(data); - - // FIXME write the macro def - // let mut hasher = DefaultHasher::new(); - // data.callee_span.hash(&mut hasher); - // let hash = hasher.finish(); - // let qualname = format!("{}::{}", data.name, hash); - // Don't write macro definition for imported macros - // if !self.mac_defs.contains(&data.callee_span) - // && !data.imported { - // self.mac_defs.insert(data.callee_span); - // if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) { - // self.dumper.macro_data(MacroData { - // span: sub_span, - // name: data.name.clone(), - // qualname: qualname.clone(), - // // FIXME where do macro docs come from? - // docs: String::new(), - // }.lower(self.tcx)); - // } - // } - } - - fn process_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>, trait_id: DefId) { - self.process_macro_use(trait_item.span); - match trait_item.kind { - hir::TraitItemKind::Const(ref ty, body) => { - let body = body.map(|b| self.tcx.hir().body(b).value); - let attrs = self.tcx.hir().attrs(trait_item.hir_id()); - self.process_assoc_const( - trait_item.owner_id, - trait_item.ident, - &ty, - body, - trait_id, - attrs, - ); - } - hir::TraitItemKind::Fn(ref sig, ref trait_fn) => { - let body = - if let hir::TraitFn::Provided(body) = trait_fn { Some(*body) } else { None }; - self.process_method( - sig, - body, - trait_item.owner_id, - trait_item.ident, - &trait_item.generics, - trait_item.span, - ); - } - hir::TraitItemKind::Type(ref bounds, ref default_ty) => { - // FIXME do something with _bounds (for type refs) - let name = trait_item.ident.name.to_string(); - let qualname = - format!("::{}", self.tcx.def_path_str(trait_item.owner_id.to_def_id())); - - if !self.span.filter_generated(trait_item.ident.span) { - let span = self.span_from_span(trait_item.ident.span); - let id = id_from_def_id(trait_item.owner_id.to_def_id()); - let attrs = self.tcx.hir().attrs(trait_item.hir_id()); - - self.dumper.dump_def( - &Access { public: true, reachable: true }, - Def { - kind: DefKind::Type, - id, - span, - name, - qualname, - value: self.span.snippet(trait_item.span), - parent: Some(id_from_def_id(trait_id)), - children: vec![], - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: sig::assoc_type_signature( - trait_item.owner_id, - trait_item.ident, - Some(bounds), - default_ty.as_deref(), - &self.save_ctxt, - ), - attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt), - }, - ); - } - - if let Some(default_ty) = default_ty { - self.visit_ty(default_ty) - } - } - } - } - - fn process_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>, impl_id: DefId) { - self.process_macro_use(impl_item.span); - match impl_item.kind { - hir::ImplItemKind::Const(ref ty, body) => { - let body = self.tcx.hir().body(body); - let attrs = self.tcx.hir().attrs(impl_item.hir_id()); - self.process_assoc_const( - impl_item.owner_id, - impl_item.ident, - &ty, - Some(&body.value), - impl_id, - attrs, - ); - } - hir::ImplItemKind::Fn(ref sig, body) => { - self.process_method( - sig, - Some(body), - impl_item.owner_id, - impl_item.ident, - &impl_item.generics, - impl_item.span, - ); - } - hir::ImplItemKind::Type(ref ty) => { - // FIXME: uses of the assoc type should ideally point to this - // 'def' and the name here should be a ref to the def in the - // trait. - self.visit_ty(ty) - } - } - } - - pub(crate) fn process_crate(&mut self) { - let qualname = format!("::{}", self.tcx.def_path_str(CRATE_DEF_ID.to_def_id())); - - let sm = self.tcx.sess.source_map(); - let krate_mod = self.tcx.hir().root_module(); - let filename = sm.span_to_filename(krate_mod.spans.inner_span); - let data_id = id_from_def_id(CRATE_DEF_ID.to_def_id()); - let children = - krate_mod.item_ids.iter().map(|i| id_from_def_id(i.owner_id.to_def_id())).collect(); - let span = self.span_from_span(krate_mod.spans.inner_span); - let attrs = self.tcx.hir().attrs(hir::CRATE_HIR_ID); - - self.dumper.dump_def( - &Access { public: true, reachable: true }, - Def { - kind: DefKind::Mod, - id: data_id, - name: String::new(), - qualname, - span, - value: filename.prefer_remapped().to_string(), - children, - parent: None, - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: None, - attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt), - }, - ); - self.tcx.hir().walk_toplevel_module(self); - } - - fn process_bounds(&mut self, bounds: hir::GenericBounds<'tcx>) { - for bound in bounds { - if let hir::GenericBound::Trait(ref trait_ref, _) = *bound { - self.process_path( - trait_ref.trait_ref.hir_ref_id, - &hir::QPath::Resolved(None, &trait_ref.trait_ref.path), - ) - } - } - } -} - -impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { - type NestedFilter = nested_filter::All; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - self.process_macro_use(item.span); - match item.kind { - hir::ItemKind::Use(path, hir::UseKind::Single) => { - let sub_span = path.segments.last().unwrap().ident.span; - if !self.span.filter_generated(sub_span) { - let access = access_from!(self.save_ctxt, item.owner_id.def_id); - let ref_id = self.lookup_def_id(item.hir_id()).map(id_from_def_id); - let span = self.span_from_span(sub_span); - let parent = self.save_ctxt.tcx.local_parent(item.owner_id.def_id); - self.dumper.import( - &access, - Import { - kind: ImportKind::Use, - ref_id, - span, - alias_span: None, - name: item.ident.to_string(), - value: String::new(), - parent: Some(id_from_def_id(parent.to_def_id())), - }, - ); - self.write_sub_paths_truncated(&path); - } - } - hir::ItemKind::Use(path, hir::UseKind::Glob) => { - // Make a comma-separated list of names of imported modules. - let names = self.tcx.names_imported_by_glob_use(item.owner_id.def_id); - let names: Vec<_> = names.iter().map(|n| n.to_string()).collect(); - - // Otherwise it's a span with wrong macro expansion info, which - // we don't want to track anyway, since it's probably macro-internal `use` - if let Some(sub_span) = self.span.sub_span_of_star(item.span) { - if !self.span.filter_generated(item.span) { - let access = access_from!(self.save_ctxt, item.owner_id.def_id); - let span = self.span_from_span(sub_span); - let parent = self.save_ctxt.tcx.local_parent(item.owner_id.def_id); - self.dumper.import( - &access, - Import { - kind: ImportKind::GlobUse, - ref_id: None, - span, - alias_span: None, - name: "*".to_owned(), - value: names.join(", "), - parent: Some(id_from_def_id(parent.to_def_id())), - }, - ); - self.write_sub_paths(&path); - } - } - } - hir::ItemKind::ExternCrate(_) => { - let name_span = item.ident.span; - if !self.span.filter_generated(name_span) { - let span = self.span_from_span(name_span); - let parent = self.save_ctxt.tcx.local_parent(item.owner_id.def_id); - self.dumper.import( - &Access { public: false, reachable: false }, - Import { - kind: ImportKind::ExternCrate, - ref_id: None, - span, - alias_span: None, - name: item.ident.to_string(), - value: String::new(), - parent: Some(id_from_def_id(parent.to_def_id())), - }, - ); - } - } - hir::ItemKind::Fn(ref sig, ref ty_params, body) => { - self.process_fn(item, sig.decl, &sig.header, ty_params, body) - } - hir::ItemKind::Static(ref typ, _, body) => { - let body = self.tcx.hir().body(body); - self.process_static_or_const_item(item, typ, &body.value) - } - hir::ItemKind::Const(ref typ, body) => { - let body = self.tcx.hir().body(body); - self.process_static_or_const_item(item, typ, &body.value) - } - hir::ItemKind::Struct(ref def, ref ty_params) - | hir::ItemKind::Union(ref def, ref ty_params) => { - self.process_struct(item, def, ty_params) - } - hir::ItemKind::Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), - hir::ItemKind::Impl(ref impl_) => self.process_impl(item, impl_), - hir::ItemKind::Trait(_, _, ref generics, ref trait_refs, methods) => { - self.process_trait(item, generics, trait_refs, methods) - } - hir::ItemKind::Mod(ref m) => { - self.process_mod(item); - intravisit::walk_mod(self, m, item.hir_id()); - } - hir::ItemKind::TyAlias(ty, ref generics) => { - let qualname = format!("::{}", self.tcx.def_path_str(item.owner_id.to_def_id())); - let value = ty_to_string(&ty); - if !self.span.filter_generated(item.ident.span) { - let span = self.span_from_span(item.ident.span); - let id = id_from_def_id(item.owner_id.to_def_id()); - let attrs = self.tcx.hir().attrs(item.hir_id()); - - self.dumper.dump_def( - &access_from!(self.save_ctxt, item.owner_id.def_id), - Def { - kind: DefKind::Type, - id, - span, - name: item.ident.to_string(), - qualname: qualname.clone(), - value, - parent: None, - children: vec![], - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: sig::item_signature(item, &self.save_ctxt), - attributes: lower_attributes(attrs.to_vec(), &self.save_ctxt), - }, - ); - } - - self.visit_ty(ty); - self.process_generic_params(generics, &qualname, item.hir_id()); - } - _ => intravisit::walk_item(self, item), - } - } - - fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) { - for param in generics.params { - match param.kind { - hir::GenericParamKind::Lifetime { .. } => {} - hir::GenericParamKind::Type { ref default, .. } => { - if let Some(ref ty) = default { - self.visit_ty(ty); - } - } - hir::GenericParamKind::Const { ref ty, ref default } => { - self.visit_ty(ty); - if let Some(default) = default { - self.visit_anon_const(default); - } - } - } - } - for pred in generics.predicates { - if let hir::WherePredicate::BoundPredicate(ref wbp) = *pred { - self.process_bounds(wbp.bounds); - self.visit_ty(wbp.bounded_ty); - } - } - } - - fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { - self.process_macro_use(t.span); - match t.kind { - hir::TyKind::Path(ref path) => { - if generated_code(t.span) { - return; - } - - if let Some(id) = self.lookup_def_id(t.hir_id) { - let sub_span = path.last_segment_span(); - let span = self.span_from_span(sub_span); - self.dumper.dump_ref(Ref { - kind: RefKind::Type, - span, - ref_id: id_from_def_id(id), - }); - } - - if let hir::QPath::Resolved(_, path) = path { - self.write_sub_paths_truncated(path); - } - intravisit::walk_qpath(self, path, t.hir_id); - } - hir::TyKind::Array(ref ty, ref length) => { - self.visit_ty(ty); - let map = self.tcx.hir(); - match length { - // FIXME(generic_arg_infer): We probably want to - // output the inferred type here? :shrug: - hir::ArrayLen::Infer(..) => {} - hir::ArrayLen::Body(anon_const) => self - .nest_typeck_results(anon_const.def_id, |v| { - v.visit_expr(&map.body(anon_const.body).value) - }), - } - } - hir::TyKind::OpaqueDef(item_id, _, _) => { - let item = self.tcx.hir().item(item_id); - self.nest_typeck_results(item_id.owner_id.def_id, |v| v.visit_item(item)); - } - _ => intravisit::walk_ty(self, t), - } - } - - fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { - debug!("visit_expr {:?}", ex.kind); - self.process_macro_use(ex.span); - match ex.kind { - hir::ExprKind::Struct(ref path, ref fields, ref rest) => { - let hir_expr = self.save_ctxt.tcx.hir().expect_expr(ex.hir_id); - let adt = match self.save_ctxt.typeck_results().expr_ty_opt(&hir_expr) { - Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(), - _ => { - intravisit::walk_expr(self, ex); - return; - } - }; - let res = self.save_ctxt.get_path_res(hir_expr.hir_id); - self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), *rest) - } - hir::ExprKind::MethodCall(ref seg, receiver, args, _) => { - self.process_method_call(ex, seg, receiver, args) - } - hir::ExprKind::Field(ref sub_ex, _) => { - self.visit_expr(&sub_ex); - - if let Some(field_data) = self.save_ctxt.get_expr_data(ex) { - down_cast_data!(field_data, RefData, ex.span); - if !generated_code(ex.span) { - self.dumper.dump_ref(field_data); - } - } - } - hir::ExprKind::Closure(&hir::Closure { ref fn_decl, body, def_id, .. }) => { - let id = format!("${}", ex.hir_id); - - // walk arg and return types - for ty in fn_decl.inputs { - self.visit_ty(ty); - } - - if let hir::FnRetTy::Return(ref ret_ty) = fn_decl.output { - self.visit_ty(ret_ty); - } - - // walk the body - let map = self.tcx.hir(); - self.nest_typeck_results(def_id, |v| { - let body = map.body(body); - v.process_formals(body.params, &id); - v.visit_expr(&body.value) - }); - } - hir::ExprKind::Repeat(ref expr, ref length) => { - self.visit_expr(expr); - let map = self.tcx.hir(); - match length { - // FIXME(generic_arg_infer): We probably want to - // output the inferred type here? :shrug: - hir::ArrayLen::Infer(..) => {} - hir::ArrayLen::Body(anon_const) => self - .nest_typeck_results(anon_const.def_id, |v| { - v.visit_expr(&map.body(anon_const.body).value) - }), - } - } - // In particular, we take this branch for call and path expressions, - // where we'll index the idents involved just by continuing to walk. - _ => intravisit::walk_expr(self, ex), - } - } - - fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { - self.process_macro_use(p.span); - self.process_pat(p); - } - - fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) { - self.process_var_decl(&arm.pat); - if let Some(hir::Guard::If(expr)) = &arm.guard { - self.visit_expr(expr); - } - self.visit_expr(&arm.body); - } - - fn visit_qpath(&mut self, path: &'tcx hir::QPath<'tcx>, id: hir::HirId, _: Span) { - self.process_path(id, path); - } - - fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) { - self.process_macro_use(s.span); - intravisit::walk_stmt(self, s) - } - - fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { - self.process_macro_use(l.span); - self.process_var_decl(&l.pat); - - // Just walk the initializer, the else branch and type (don't want to walk the pattern again). - walk_list!(self, visit_ty, &l.ty); - walk_list!(self, visit_expr, &l.init); - walk_list!(self, visit_block, l.els); - } - - fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { - let access = access_from!(self.save_ctxt, item.owner_id.def_id); - - match item.kind { - hir::ForeignItemKind::Fn(decl, _, ref generics) => { - if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { - down_cast_data!(fn_data, DefData, item.span); - - self.process_generic_params(generics, &fn_data.qualname, item.hir_id()); - self.dumper.dump_def(&access, fn_data); - } - - for ty in decl.inputs { - self.visit_ty(ty); - } - - if let hir::FnRetTy::Return(ref ret_ty) = decl.output { - self.visit_ty(ret_ty); - } - } - hir::ForeignItemKind::Static(ref ty, _) => { - if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { - down_cast_data!(var_data, DefData, item.span); - self.dumper.dump_def(&access, var_data); - } - - self.visit_ty(ty); - } - hir::ForeignItemKind::Type => { - if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { - down_cast_data!(var_data, DefData, item.span); - self.dumper.dump_def(&access, var_data); - } - } - } - } -} diff --git a/compiler/rustc_save_analysis/src/dumper.rs b/compiler/rustc_save_analysis/src/dumper.rs deleted file mode 100644 index 5a2628287d60d..0000000000000 --- a/compiler/rustc_save_analysis/src/dumper.rs +++ /dev/null @@ -1,91 +0,0 @@ -use rls_data::config::Config; -use rls_data::{ - self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import, MacroRef, - Ref, RefKind, Relation, -}; -use rls_span::{Column, Row}; - -#[derive(Debug)] -pub struct Access { - pub reachable: bool, - pub public: bool, -} - -pub struct Dumper { - result: Analysis, - config: Config, -} - -impl Dumper { - pub fn new(config: Config) -> Dumper { - Dumper { config: config.clone(), result: Analysis::new(config) } - } - - pub fn analysis(&self) -> &Analysis { - &self.result - } -} - -impl Dumper { - pub fn crate_prelude(&mut self, data: CratePreludeData) { - self.result.prelude = Some(data) - } - - pub fn compilation_opts(&mut self, data: CompilationOptions) { - self.result.compilation = Some(data); - } - - pub fn _macro_use(&mut self, data: MacroRef) { - if self.config.pub_only || self.config.reachable_only { - return; - } - self.result.macro_refs.push(data); - } - - pub fn import(&mut self, access: &Access, import: Import) { - if !access.public && self.config.pub_only || !access.reachable && self.config.reachable_only - { - return; - } - self.result.imports.push(import); - } - - pub fn dump_ref(&mut self, data: Ref) { - if self.config.pub_only || self.config.reachable_only { - return; - } - self.result.refs.push(data); - } - - pub fn dump_def(&mut self, access: &Access, mut data: Def) { - if !access.public && self.config.pub_only || !access.reachable && self.config.reachable_only - { - return; - } - if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value { - // If the module is an out-of-line definition, then we'll make the - // definition the first character in the module's file and turn - // the declaration into a reference to it. - let rf = Ref { kind: RefKind::Mod, span: data.span, ref_id: data.id }; - self.result.refs.push(rf); - data.span = rls_data::SpanData { - file_name: data.value.clone().into(), - byte_start: 0, - byte_end: 0, - line_start: Row::new_one_indexed(1), - line_end: Row::new_one_indexed(1), - column_start: Column::new_one_indexed(1), - column_end: Column::new_one_indexed(1), - } - } - self.result.defs.push(data); - } - - pub fn dump_relation(&mut self, data: Relation) { - self.result.relations.push(data); - } - - pub fn dump_impl(&mut self, data: Impl) { - self.result.impls.push(data); - } -} diff --git a/compiler/rustc_save_analysis/src/errors.rs b/compiler/rustc_save_analysis/src/errors.rs deleted file mode 100644 index 585aac8c1c3cc..0000000000000 --- a/compiler/rustc_save_analysis/src/errors.rs +++ /dev/null @@ -1,10 +0,0 @@ -use rustc_macros::Diagnostic; - -use std::path::Path; - -#[derive(Diagnostic)] -#[diag(save_analysis_could_not_open)] -pub(crate) struct CouldNotOpen<'a> { - pub file_name: &'a Path, - pub err: std::io::Error, -} diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs deleted file mode 100644 index ad151bc2e1bf5..0000000000000 --- a/compiler/rustc_save_analysis/src/lib.rs +++ /dev/null @@ -1,1067 +0,0 @@ -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(if_let_guard)] -#![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] -#![feature(never_type)] -#![deny(rustc::untranslatable_diagnostic)] -#![deny(rustc::diagnostic_outside_of_impl)] - -#[macro_use] -extern crate tracing; - -mod dump_visitor; -mod dumper; -#[macro_use] -mod span_utils; -mod errors; -mod sig; - -use rustc_ast as ast; -use rustc_ast::util::comments::beautify_doc_string; -use rustc_ast_pretty::pprust::attribute_to_string; -use rustc_hir as hir; -use rustc_hir::def::{DefKind as HirDefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; -use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::Node; -use rustc_hir_pretty::{enum_def_to_string, fn_to_string, ty_to_string}; -use rustc_middle::hir::nested_filter; -use rustc_middle::middle::privacy::EffectiveVisibilities; -use rustc_middle::ty::{self, print::with_no_trimmed_paths, DefIdTree, TyCtxt}; -use rustc_middle::{bug, span_bug}; -use rustc_session::config::{CrateType, Input, OutputType}; -use rustc_session::cstore::ExternCrate; -use rustc_session::output::{filename_for_metadata, out_filename}; -use rustc_span::symbol::Ident; -use rustc_span::*; - -use std::cell::Cell; -use std::env; -use std::fs::File; -use std::io::BufWriter; -use std::path::{Path, PathBuf}; - -use dump_visitor::DumpVisitor; -use span_utils::SpanUtils; - -use rls_data::config::Config; -use rls_data::{ - Analysis, Def, DefKind, ExternalCrateData, GlobalCrateId, Impl, ImplKind, MacroRef, Ref, - RefKind, Relation, RelationKind, SpanData, -}; - -pub struct SaveContext<'tcx> { - tcx: TyCtxt<'tcx>, - maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, - effective_visibilities: &'tcx EffectiveVisibilities, - span_utils: SpanUtils<'tcx>, - config: Config, - impl_counter: Cell, -} - -#[derive(Debug)] -pub enum Data { - RefData(Ref), - DefData(Def), - RelationData(Relation, Impl), -} - -impl<'tcx> SaveContext<'tcx> { - /// Gets the type-checking results for the current body. - /// As this will ICE if called outside bodies, only call when working with - /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies). - #[track_caller] - fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> { - self.maybe_typeck_results.expect("`SaveContext::typeck_results` called outside of body") - } - - fn span_from_span(&self, span: Span) -> SpanData { - use rls_span::{Column, Row}; - - let sm = self.tcx.sess.source_map(); - let start = sm.lookup_char_pos(span.lo()); - let end = sm.lookup_char_pos(span.hi()); - - SpanData { - file_name: start.file.name.prefer_remapped().to_string().into(), - byte_start: span.lo().0, - byte_end: span.hi().0, - line_start: Row::new_one_indexed(start.line as u32), - line_end: Row::new_one_indexed(end.line as u32), - column_start: Column::new_one_indexed(start.col.0 as u32 + 1), - column_end: Column::new_one_indexed(end.col.0 as u32 + 1), - } - } - - /// Returns path to the compilation output (e.g., libfoo-12345678.rmeta) - pub fn compilation_output(&self, crate_name: Symbol) -> PathBuf { - let sess = &self.tcx.sess; - // Save-analysis is emitted per whole session, not per each crate type - let crate_type = sess.crate_types()[0]; - let outputs = &*self.tcx.output_filenames(()); - - if outputs.outputs.contains_key(&OutputType::Metadata) { - filename_for_metadata(sess, crate_name, outputs) - } else if outputs.outputs.should_codegen() { - out_filename(sess, crate_type, outputs, crate_name) - } else { - // Otherwise it's only a DepInfo, in which case we return early and - // not even reach the analysis stage. - unreachable!() - } - } - - /// List external crates used by the current crate. - pub fn get_external_crates(&self) -> Vec { - let mut result = Vec::with_capacity(self.tcx.crates(()).len()); - - for &n in self.tcx.crates(()).iter() { - let Some(&ExternCrate { span, .. }) = self.tcx.extern_crate(n.as_def_id()) else { - debug!("skipping crate {}, no data", n); - continue; - }; - let lo_loc = self.span_utils.sess.source_map().lookup_char_pos(span.lo()); - result.push(ExternalCrateData { - // FIXME: change file_name field to PathBuf in rls-data - // https://github.com/nrc/rls-data/issues/7 - file_name: self.span_utils.make_filename_string(&lo_loc.file), - num: n.as_u32(), - id: GlobalCrateId { - name: self.tcx.crate_name(n).to_string(), - disambiguator: ( - self.tcx.def_path_hash(n.as_def_id()).stable_crate_id().to_u64(), - 0, - ), - }, - }); - } - - result - } - - pub fn get_extern_item_data(&self, item: &hir::ForeignItem<'_>) -> Option { - let def_id = item.owner_id.to_def_id(); - let qualname = format!("::{}", self.tcx.def_path_str(def_id)); - let attrs = self.tcx.hir().attrs(item.hir_id()); - match item.kind { - hir::ForeignItemKind::Fn(ref decl, arg_names, ref generics) => { - filter!(self.span_utils, item.ident.span); - - Some(Data::DefData(Def { - kind: DefKind::ForeignFunction, - id: id_from_def_id(def_id), - span: self.span_from_span(item.ident.span), - name: item.ident.to_string(), - qualname, - value: fn_to_string( - decl, - hir::FnHeader { - // functions in extern block are implicitly unsafe - unsafety: hir::Unsafety::Unsafe, - // functions in extern block cannot be const - constness: hir::Constness::NotConst, - abi: self.tcx.hir().get_foreign_abi(item.hir_id()), - // functions in extern block cannot be async - asyncness: hir::IsAsync::NotAsync, - }, - Some(item.ident.name), - generics, - arg_names, - None, - ), - parent: None, - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::foreign_item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - hir::ForeignItemKind::Static(ref ty, _) => { - filter!(self.span_utils, item.ident.span); - - let id = id_from_def_id(def_id); - let span = self.span_from_span(item.ident.span); - - Some(Data::DefData(Def { - kind: DefKind::ForeignStatic, - id, - span, - name: item.ident.to_string(), - qualname, - value: ty_to_string(ty), - parent: None, - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::foreign_item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - // FIXME(plietar): needs a new DefKind in rls-data - hir::ForeignItemKind::Type => None, - } - } - - pub fn get_item_data(&self, item: &hir::Item<'_>) -> Option { - let def_id = item.owner_id.to_def_id(); - let attrs = self.tcx.hir().attrs(item.hir_id()); - match item.kind { - hir::ItemKind::Fn(ref sig, ref generics, _) => { - let qualname = format!("::{}", self.tcx.def_path_str(def_id)); - filter!(self.span_utils, item.ident.span); - Some(Data::DefData(Def { - kind: DefKind::Function, - id: id_from_def_id(def_id), - span: self.span_from_span(item.ident.span), - name: item.ident.to_string(), - qualname, - value: fn_to_string( - sig.decl, - sig.header, - Some(item.ident.name), - generics, - &[], - None, - ), - parent: None, - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - hir::ItemKind::Static(ref typ, ..) => { - let qualname = format!("::{}", self.tcx.def_path_str(def_id)); - - filter!(self.span_utils, item.ident.span); - - let id = id_from_def_id(def_id); - let span = self.span_from_span(item.ident.span); - - Some(Data::DefData(Def { - kind: DefKind::Static, - id, - span, - name: item.ident.to_string(), - qualname, - value: ty_to_string(&typ), - parent: None, - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - hir::ItemKind::Const(ref typ, _) => { - let qualname = format!("::{}", self.tcx.def_path_str(def_id)); - filter!(self.span_utils, item.ident.span); - - let id = id_from_def_id(def_id); - let span = self.span_from_span(item.ident.span); - - Some(Data::DefData(Def { - kind: DefKind::Const, - id, - span, - name: item.ident.to_string(), - qualname, - value: ty_to_string(typ), - parent: None, - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - hir::ItemKind::Mod(ref m) => { - let qualname = format!("::{}", self.tcx.def_path_str(def_id)); - - let sm = self.tcx.sess.source_map(); - let filename = sm.span_to_filename(m.spans.inner_span); - - filter!(self.span_utils, item.ident.span); - - Some(Data::DefData(Def { - kind: DefKind::Mod, - id: id_from_def_id(def_id), - name: item.ident.to_string(), - qualname, - span: self.span_from_span(item.ident.span), - value: filename.prefer_remapped().to_string(), - parent: None, - children: m - .item_ids - .iter() - .map(|i| id_from_def_id(i.owner_id.to_def_id())) - .collect(), - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - hir::ItemKind::Enum(ref def, ref generics) => { - let name = item.ident.to_string(); - let qualname = format!("::{}", self.tcx.def_path_str(def_id)); - filter!(self.span_utils, item.ident.span); - let value = - enum_def_to_string(def, generics, item.ident.name, item.span); - Some(Data::DefData(Def { - kind: DefKind::Enum, - id: id_from_def_id(def_id), - span: self.span_from_span(item.ident.span), - name, - qualname, - value, - parent: None, - children: def.variants.iter().map(|v| id_from_def_id(v.def_id.to_def_id())).collect(), - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::item_signature(item, self), - attributes: lower_attributes(attrs.to_vec(), self), - })) - } - hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. }) - if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind => - { - // Common case impl for a struct or something basic. - if generated_code(path.span) { - return None; - } - let sub_span = path.segments.last().unwrap().ident.span; - filter!(self.span_utils, sub_span); - - let impl_id = self.next_impl_id(); - let span = self.span_from_span(sub_span); - - let type_data = self.lookup_def_id(self_ty.hir_id); - type_data.map(|type_data| { - Data::RelationData( - Relation { - kind: RelationKind::Impl { id: impl_id }, - span: span.clone(), - from: id_from_def_id(type_data), - to: of_trait - .as_ref() - .and_then(|t| self.lookup_def_id(t.hir_ref_id)) - .map(id_from_def_id) - .unwrap_or_else(null_id), - }, - Impl { - id: impl_id, - kind: match *of_trait { - Some(_) => ImplKind::Direct, - None => ImplKind::Inherent, - }, - span, - value: String::new(), - parent: None, - children: items - .iter() - .map(|i| id_from_def_id(i.id.owner_id.to_def_id())) - .collect(), - docs: String::new(), - sig: None, - attributes: vec![], - }, - ) - }) - } - hir::ItemKind::Impl(_) => None, - _ => { - // FIXME - bug!(); - } - } - } - - pub fn get_field_data(&self, field: &hir::FieldDef<'_>, scope: LocalDefId) -> Option { - let name = field.ident.to_string(); - let qualname = format!("::{}::{}", self.tcx.def_path_str(scope.to_def_id()), field.ident); - filter!(self.span_utils, field.ident.span); - let field_def_id = field.def_id.to_def_id(); - let typ = self.tcx.type_of(field_def_id).to_string(); - - let id = id_from_def_id(field_def_id); - let span = self.span_from_span(field.ident.span); - let attrs = self.tcx.hir().attrs(field.hir_id); - - Some(Def { - kind: DefKind::Field, - id, - span, - name, - qualname, - value: typ, - parent: Some(id_from_def_id(scope.to_def_id())), - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(attrs), - sig: sig::field_signature(field, self), - attributes: lower_attributes(attrs.to_vec(), self), - }) - } - - // FIXME would be nice to take a MethodItem here, but the ast provides both - // trait and impl flavours, so the caller must do the disassembly. - pub fn get_method_data(&self, owner_id: hir::OwnerId, ident: Ident, span: Span) -> Option { - // The qualname for a method is the trait name or name of the struct in an impl in - // which the method is declared in, followed by the method's name. - let (qualname, parent_scope, decl_id, docs, attributes) = - match self.tcx.impl_of_method(owner_id.to_def_id()) { - Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { - Some(Node::Item(item)) => match item.kind { - hir::ItemKind::Impl(hir::Impl { ref self_ty, .. }) => { - let hir = self.tcx.hir(); - - let mut qualname = String::from("<"); - qualname - .push_str(&rustc_hir_pretty::id_to_string(&hir, self_ty.hir_id)); - - let trait_id = self.tcx.trait_id_of_impl(impl_id); - let mut docs = String::new(); - let mut attrs = vec![]; - if let Some(Node::ImplItem(_)) = hir.find(owner_id.into()) { - attrs = self.tcx.hir().attrs(owner_id.into()).to_vec(); - docs = self.docs_for_attrs(&attrs); - } - - let mut decl_id = None; - if let Some(def_id) = trait_id { - // A method in a trait impl. - qualname.push_str(" as "); - qualname.push_str(&self.tcx.def_path_str(def_id)); - - decl_id = self - .tcx - .associated_items(def_id) - .filter_by_name_unhygienic(ident.name) - .next() - .map(|item| item.def_id); - } - qualname.push('>'); - - (qualname, trait_id, decl_id, docs, attrs) - } - _ => { - span_bug!( - span, - "Container {:?} for method {:?} not an impl?", - impl_id, - owner_id, - ); - } - }, - r => { - span_bug!( - span, - "Container {:?} for method {:?} is not a node item {:?}", - impl_id, - owner_id, - r - ); - } - }, - None => match self.tcx.trait_of_item(owner_id.to_def_id()) { - Some(def_id) => { - let mut docs = String::new(); - let mut attrs = vec![]; - - if let Some(Node::TraitItem(_)) = self.tcx.hir().find(owner_id.into()) { - attrs = self.tcx.hir().attrs(owner_id.into()).to_vec(); - docs = self.docs_for_attrs(&attrs); - } - - ( - format!("::{}", self.tcx.def_path_str(def_id)), - Some(def_id), - None, - docs, - attrs, - ) - } - None => { - debug!("could not find container for method {:?} at {:?}", owner_id, span); - // This is not necessarily a bug, if there was a compilation error, - // the typeck results we need might not exist. - return None; - } - }, - }; - - let qualname = format!("{}::{}", qualname, ident.name); - - filter!(self.span_utils, ident.span); - - Some(Def { - kind: DefKind::Method, - id: id_from_def_id(owner_id.to_def_id()), - span: self.span_from_span(ident.span), - name: ident.name.to_string(), - qualname, - // FIXME you get better data here by using the visitor. - value: String::new(), - parent: parent_scope.map(id_from_def_id), - children: vec![], - decl_id: decl_id.map(id_from_def_id), - docs, - sig: None, - attributes: lower_attributes(attributes, self), - }) - } - - pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option { - let ty = self.typeck_results().expr_ty_adjusted_opt(expr)?; - if matches!(ty.kind(), ty::Error(_)) { - return None; - } - match expr.kind { - hir::ExprKind::Field(ref sub_ex, ident) => { - match self.typeck_results().expr_ty_adjusted(&sub_ex).kind() { - ty::Adt(def, _) if !def.is_enum() => { - let variant = &def.non_enum_variant(); - filter!(self.span_utils, ident.span); - let span = self.span_from_span(ident.span); - Some(Data::RefData(Ref { - kind: RefKind::Variable, - span, - ref_id: self - .tcx - .find_field_index(ident, variant) - .map(|index| id_from_def_id(variant.fields[index].did)) - .unwrap_or_else(null_id), - })) - } - ty::Tuple(..) => None, - _ => { - debug!("expected struct or union type, found {:?}", ty); - None - } - } - } - hir::ExprKind::Struct(qpath, ..) => match ty.kind() { - ty::Adt(def, _) => { - let sub_span = qpath.last_segment_span(); - filter!(self.span_utils, sub_span); - let span = self.span_from_span(sub_span); - Some(Data::RefData(Ref { - kind: RefKind::Type, - span, - ref_id: id_from_def_id(def.did()), - })) - } - _ => { - debug!("expected adt, found {:?}", ty); - None - } - }, - hir::ExprKind::MethodCall(ref seg, ..) => { - let Some(method_id) = self.typeck_results().type_dependent_def_id(expr.hir_id) else { - debug!("could not resolve method id for {:?}", expr); - return None; - }; - let (def_id, decl_id) = match self.tcx.associated_item(method_id).container { - ty::ImplContainer => (Some(method_id), None), - ty::TraitContainer => (None, Some(method_id)), - }; - let sub_span = seg.ident.span; - filter!(self.span_utils, sub_span); - let span = self.span_from_span(sub_span); - Some(Data::RefData(Ref { - kind: RefKind::Function, - span, - ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(null_id), - })) - } - hir::ExprKind::Path(ref path) => { - self.get_path_data(expr.hir_id, path).map(Data::RefData) - } - _ => { - // FIXME - bug!("invalid expression: {:?}", expr); - } - } - } - - pub fn get_path_res(&self, hir_id: hir::HirId) -> Res { - match self.tcx.hir().get(hir_id) { - Node::TraitRef(tr) => tr.path.res, - - Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => { - path.res.get(0).copied().unwrap_or(Res::Err) - } - Node::PathSegment(seg) => { - if seg.res != Res::Err { - seg.res - } else { - let parent_node = self.tcx.hir().parent_id(hir_id); - self.get_path_res(parent_node) - } - } - - Node::Expr(&hir::Expr { kind: hir::ExprKind::Struct(ref qpath, ..), .. }) => { - self.typeck_results().qpath_res(qpath, hir_id) - } - - Node::Expr(&hir::Expr { kind: hir::ExprKind::Path(ref qpath), .. }) - | Node::Pat(&hir::Pat { - kind: - hir::PatKind::Path(ref qpath) - | hir::PatKind::Struct(ref qpath, ..) - | hir::PatKind::TupleStruct(ref qpath, ..), - .. - }) - | Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => match qpath { - hir::QPath::Resolved(_, path) => path.res, - hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => { - // #75962: `self.typeck_results` may be different from the `hir_id`'s result. - if self.tcx.has_typeck_results(hir_id.owner.to_def_id()) { - self.tcx.typeck(hir_id.owner.def_id).qpath_res(qpath, hir_id) - } else { - Res::Err - } - } - }, - - Node::Pat(&hir::Pat { kind: hir::PatKind::Binding(_, canonical_id, ..), .. }) => { - Res::Local(canonical_id) - } - - _ => Res::Err, - } - } - - pub fn get_path_data(&self, id: hir::HirId, path: &hir::QPath<'_>) -> Option { - let segment = match path { - hir::QPath::Resolved(_, path) => path.segments.last(), - hir::QPath::TypeRelative(_, segment) => Some(*segment), - hir::QPath::LangItem(..) => None, - }; - segment.and_then(|seg| { - self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id)) - }) - } - - pub fn get_path_segment_data(&self, path_seg: &hir::PathSegment<'_>) -> Option { - self.get_path_segment_data_with_id(path_seg, path_seg.hir_id) - } - - pub fn get_path_segment_data_with_id( - &self, - path_seg: &hir::PathSegment<'_>, - id: hir::HirId, - ) -> Option { - // Returns true if the path is function type sugar, e.g., `Fn(A) -> B`. - fn fn_type(seg: &hir::PathSegment<'_>) -> bool { - seg.args.map_or(false, |args| args.parenthesized) - } - - let res = self.get_path_res(id); - let span = path_seg.ident.span; - filter!(self.span_utils, span); - let span = self.span_from_span(span); - - match res { - Res::Local(id) => { - Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_hir_id(id) }) - } - Res::Def(HirDefKind::Trait, def_id) if fn_type(path_seg) => { - Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(def_id) }) - } - Res::Def( - HirDefKind::Struct - | HirDefKind::Variant - | HirDefKind::Union - | HirDefKind::Enum - | HirDefKind::TyAlias - | HirDefKind::ForeignTy - | HirDefKind::TraitAlias - | HirDefKind::AssocTy - | HirDefKind::Trait - | HirDefKind::OpaqueTy - | HirDefKind::ImplTraitPlaceholder - | HirDefKind::TyParam, - def_id, - ) => Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(def_id) }), - Res::Def(HirDefKind::ConstParam, def_id) => { - Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_def_id(def_id) }) - } - Res::Def(HirDefKind::Ctor(..), def_id) => { - // This is a reference to a tuple struct or an enum variant where the def_id points - // to an invisible constructor function. That is not a very useful - // def, so adjust to point to the tuple struct or enum variant itself. - let parent_def_id = self.tcx.parent(def_id); - Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(parent_def_id) }) - } - Res::Def(HirDefKind::Static(_) | HirDefKind::Const | HirDefKind::AssocConst, _) => { - Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_def_id(res.def_id()) }) - } - Res::Def(HirDefKind::AssocFn, decl_id) => { - let def_id = if decl_id.is_local() { - if self.tcx.impl_defaultness(decl_id).has_value() { - Some(decl_id) - } else { - None - } - } else { - None - }; - Some(Ref { - kind: RefKind::Function, - span, - ref_id: id_from_def_id(def_id.unwrap_or(decl_id)), - }) - } - Res::Def(HirDefKind::Fn, def_id) => { - Some(Ref { kind: RefKind::Function, span, ref_id: id_from_def_id(def_id) }) - } - Res::Def(HirDefKind::Mod, def_id) => { - Some(Ref { kind: RefKind::Mod, span, ref_id: id_from_def_id(def_id) }) - } - - Res::Def( - HirDefKind::Macro(..) - | HirDefKind::ExternCrate - | HirDefKind::ForeignMod - | HirDefKind::LifetimeParam - | HirDefKind::AnonConst - | HirDefKind::InlineConst - | HirDefKind::Use - | HirDefKind::Field - | HirDefKind::GlobalAsm - | HirDefKind::Impl { .. } - | HirDefKind::Closure - | HirDefKind::Generator, - _, - ) - | Res::PrimTy(..) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } - | Res::ToolMod - | Res::NonMacroAttr(..) - | Res::SelfCtor(..) - | Res::Err => None, - } - } - - pub fn get_field_ref_data( - &self, - field_ref: &hir::ExprField<'_>, - variant: &ty::VariantDef, - ) -> Option { - filter!(self.span_utils, field_ref.ident.span); - self.tcx.find_field_index(field_ref.ident, variant).map(|index| { - let span = self.span_from_span(field_ref.ident.span); - Ref { kind: RefKind::Variable, span, ref_id: id_from_def_id(variant.fields[index].did) } - }) - } - - /// Attempt to return MacroRef for any AST node. - /// - /// For a given piece of AST defined by the supplied Span and NodeId, - /// returns `None` if the node is not macro-generated or the span is malformed, - /// else uses the expansion callsite and callee to return some MacroRef. - /// - /// FIXME: [`DumpVisitor::process_macro_use`] should actually dump this data - #[allow(dead_code)] - fn get_macro_use_data(&self, span: Span) -> Option { - if !generated_code(span) { - return None; - } - // Note we take care to use the source callsite/callee, to handle - // nested expansions and ensure we only generate data for source-visible - // macro uses. - let callsite = span.source_callsite(); - let callsite_span = self.span_from_span(callsite); - let callee = span.source_callee()?; - - let mac_name = match callee.kind { - ExpnKind::Macro(kind, name) => match kind { - MacroKind::Bang => name, - - // Ignore attribute macros, their spans are usually mangled - // FIXME(eddyb) is this really the case anymore? - MacroKind::Attr | MacroKind::Derive => return None, - }, - - // These are not macros. - // FIXME(eddyb) maybe there is a way to handle them usefully? - ExpnKind::Inlined | ExpnKind::Root | ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => { - return None; - } - }; - - let callee_span = self.span_from_span(callee.def_site); - Some(MacroRef { - span: callsite_span, - qualname: mac_name.to_string(), // FIXME: generate the real qualname - callee_span, - }) - } - - fn lookup_def_id(&self, ref_id: hir::HirId) -> Option { - match self.get_path_res(ref_id) { - Res::PrimTy(_) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => None, - def => def.opt_def_id(), - } - } - - fn docs_for_attrs(&self, attrs: &[ast::Attribute]) -> String { - let mut result = String::new(); - - for attr in attrs { - if let Some((val, kind)) = attr.doc_str_and_comment_kind() { - // FIXME: Should save-analysis beautify doc strings itself or leave it to users? - result.push_str(beautify_doc_string(val, kind).as_str()); - result.push('\n'); - } - } - - if !self.config.full_docs { - if let Some(index) = result.find("\n\n") { - result.truncate(index); - } - } - - result - } - - fn next_impl_id(&self) -> u32 { - let next = self.impl_counter.get(); - self.impl_counter.set(next + 1); - next - } -} - -// An AST visitor for collecting paths (e.g., the names of structs) and formal -// variables (idents) from patterns. -struct PathCollector<'l> { - tcx: TyCtxt<'l>, - collected_paths: Vec<(hir::HirId, &'l hir::QPath<'l>)>, - collected_idents: Vec<(hir::HirId, Ident, hir::Mutability)>, -} - -impl<'l> PathCollector<'l> { - fn new(tcx: TyCtxt<'l>) -> PathCollector<'l> { - PathCollector { tcx, collected_paths: vec![], collected_idents: vec![] } - } -} - -impl<'l> Visitor<'l> for PathCollector<'l> { - type NestedFilter = nested_filter::All; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_pat(&mut self, p: &'l hir::Pat<'l>) { - match p.kind { - hir::PatKind::Struct(ref path, ..) => { - self.collected_paths.push((p.hir_id, path)); - } - hir::PatKind::TupleStruct(ref path, ..) | hir::PatKind::Path(ref path) => { - self.collected_paths.push((p.hir_id, path)); - } - hir::PatKind::Binding(hir::BindingAnnotation(_, mutbl), _, ident, _) => { - debug!( - "PathCollector, visit ident in pat {}: {:?} {:?}", - ident, p.span, ident.span - ); - self.collected_idents.push((p.hir_id, ident, mutbl)); - } - _ => {} - } - intravisit::walk_pat(self, p); - } -} - -/// Defines what to do with the results of saving the analysis. -pub trait SaveHandler { - fn save(&mut self, save_ctxt: &SaveContext<'_>, analysis: &Analysis); -} - -/// Dump the save-analysis results to a file. -pub struct DumpHandler<'a> { - odir: Option<&'a Path>, - cratename: String, -} - -impl<'a> DumpHandler<'a> { - pub fn new(odir: Option<&'a Path>, cratename: Symbol) -> DumpHandler<'a> { - DumpHandler { odir, cratename: cratename.to_string() } - } - - fn output_file(&self, ctx: &SaveContext<'_>) -> (BufWriter, PathBuf) { - let sess = &ctx.tcx.sess; - let file_name = match ctx.config.output_file { - Some(ref s) => PathBuf::from(s), - None => { - let mut root_path = match self.odir { - Some(val) => val.join("save-analysis"), - None => PathBuf::from("save-analysis-temp"), - }; - - if let Err(e) = std::fs::create_dir_all(&root_path) { - error!("Could not create directory {}: {}", root_path.display(), e); - } - - let executable = sess.crate_types().iter().any(|ct| *ct == CrateType::Executable); - let mut out_name = if executable { String::new() } else { "lib".to_owned() }; - out_name.push_str(&self.cratename); - out_name.push_str(&sess.opts.cg.extra_filename); - out_name.push_str(".json"); - root_path.push(&out_name); - - root_path - } - }; - - info!("Writing output to {}", file_name.display()); - - let output_file = BufWriter::new(File::create(&file_name).unwrap_or_else(|e| { - sess.emit_fatal(errors::CouldNotOpen { file_name: file_name.as_path(), err: e }) - })); - - (output_file, file_name) - } -} - -impl SaveHandler for DumpHandler<'_> { - fn save(&mut self, save_ctxt: &SaveContext<'_>, analysis: &Analysis) { - let sess = &save_ctxt.tcx.sess; - let (output, file_name) = self.output_file(&save_ctxt); - if let Err(e) = serde_json::to_writer(output, &analysis) { - error!("Can't serialize save-analysis: {:?}", e); - } - - if sess.opts.json_artifact_notifications { - sess.parse_sess.span_diagnostic.emit_artifact_notification(&file_name, "save-analysis"); - } - } -} - -/// Call a callback with the results of save-analysis. -pub struct CallbackHandler<'b> { - pub callback: &'b mut dyn FnMut(&rls_data::Analysis), -} - -impl SaveHandler for CallbackHandler<'_> { - fn save(&mut self, _: &SaveContext<'_>, analysis: &Analysis) { - (self.callback)(analysis) - } -} - -pub fn process_crate( - tcx: TyCtxt<'_>, - cratename: Symbol, - input: &Input, - config: Option, - mut handler: H, -) { - with_no_trimmed_paths!({ - tcx.dep_graph.with_ignore(|| { - info!("Dumping crate {}", cratename); - - // Privacy checking must be done outside of type inference; use a - // fallback in case effective visibilities couldn't have been correctly computed. - let effective_visibilities = match tcx.sess.compile_status() { - Ok(..) => tcx.effective_visibilities(()), - Err(..) => tcx.arena.alloc(EffectiveVisibilities::default()), - }; - - let save_ctxt = SaveContext { - tcx, - maybe_typeck_results: None, - effective_visibilities: &effective_visibilities, - span_utils: SpanUtils::new(&tcx.sess), - config: find_config(config), - impl_counter: Cell::new(0), - }; - - let mut visitor = DumpVisitor::new(save_ctxt); - - visitor.dump_crate_info(cratename); - visitor.dump_compilation_options(input, cratename); - visitor.process_crate(); - - handler.save(&visitor.save_ctxt, &visitor.analysis()) - }) - }) -} - -fn find_config(supplied: Option) -> Config { - if let Some(config) = supplied { - return config; - } - - match env::var_os("RUST_SAVE_ANALYSIS_CONFIG") { - None => Config::default(), - Some(config) => config - .to_str() - .ok_or(()) - .map_err(|_| error!("`RUST_SAVE_ANALYSIS_CONFIG` isn't UTF-8")) - .and_then(|cfg| { - serde_json::from_str(cfg) - .map_err(|_| error!("Could not deserialize save-analysis config")) - }) - .unwrap_or_default(), - } -} - -// Utility functions for the module. - -// Helper function to escape quotes in a string -fn escape(s: String) -> String { - s.replace('\"', "\"\"") -} - -// Helper function to determine if a span came from a -// macro expansion or syntax extension. -fn generated_code(span: Span) -> bool { - span.from_expansion() || span.is_dummy() -} - -// DefId::index is a newtype and so the JSON serialisation is ugly. Therefore -// we use our own Id which is the same, but without the newtype. -fn id_from_def_id(id: DefId) -> rls_data::Id { - rls_data::Id { krate: id.krate.as_u32(), index: id.index.as_u32() } -} - -fn id_from_hir_id(id: hir::HirId) -> rls_data::Id { - // Create a *fake* `DefId` out of a `HirId` by combining the owner - // `local_def_index` and the `local_id`. - // This will work unless you have *billions* of definitions in a single - // crate (very unlikely to actually happen). - rls_data::Id { - krate: LOCAL_CRATE.as_u32(), - index: id.owner.def_id.local_def_index.as_u32() | id.local_id.as_u32().reverse_bits(), - } -} - -fn null_id() -> rls_data::Id { - rls_data::Id { krate: u32::MAX, index: u32::MAX } -} - -fn lower_attributes(attrs: Vec, scx: &SaveContext<'_>) -> Vec { - attrs - .into_iter() - // Only retain real attributes. Doc comments are lowered separately. - .filter(|attr| !attr.has_name(sym::doc)) - .map(|mut attr| { - // Remove the surrounding '#[..]' or '#![..]' of the pretty printed - // attribute. First normalize all inner attribute (#![..]) to outer - // ones (#[..]), then remove the two leading and the one trailing character. - attr.style = ast::AttrStyle::Outer; - let value = attribute_to_string(&attr); - // This str slicing works correctly, because the leading and trailing characters - // are in the ASCII range and thus exactly one byte each. - let value = value[2..value.len() - 1].to_string(); - - rls_data::Attribute { value, span: scx.span_from_span(attr.span) } - }) - .collect() -} diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs deleted file mode 100644 index a50a8178de38b..0000000000000 --- a/compiler/rustc_save_analysis/src/sig.rs +++ /dev/null @@ -1,931 +0,0 @@ -// A signature is a string representation of an item's type signature, excluding -// any body. It also includes ids for any defs or refs in the signature. For -// example: -// -// ``` -// fn foo(x: String) { -// println!("{}", x); -// } -// ``` -// The signature string is something like "fn foo(x: String) {}" and the signature -// will have defs for `foo` and `x` and a ref for `String`. -// -// All signature text should parse in the correct context (i.e., in a module or -// impl, etc.). Clients may want to trim trailing `{}` or `;`. The text of a -// signature is not guaranteed to be stable (it may improve or change as the -// syntax changes, or whitespace or punctuation may change). It is also likely -// not to be pretty - no attempt is made to prettify the text. It is recommended -// that clients run the text through Rustfmt. -// -// This module generates Signatures for items by walking the AST and looking up -// references. -// -// Signatures do not include visibility info. I'm not sure if this is a feature -// or an omission (FIXME). -// -// FIXME where clauses need implementing, defs/refs in generics are mostly missing. - -use crate::{id_from_def_id, SaveContext}; - -use rls_data::{SigElement, Signature}; - -use rustc_hir as hir; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir_pretty::id_to_string; -use rustc_hir_pretty::{bounds_to_string, path_segment_to_string, path_to_string, ty_to_string}; -use rustc_span::def_id::LocalDefId; -use rustc_span::symbol::{Ident, Symbol}; - -pub fn item_signature(item: &hir::Item<'_>, scx: &SaveContext<'_>) -> Option { - if !scx.config.signatures { - return None; - } - item.make(0, None, scx).ok() -} - -pub fn foreign_item_signature( - item: &hir::ForeignItem<'_>, - scx: &SaveContext<'_>, -) -> Option { - if !scx.config.signatures { - return None; - } - item.make(0, None, scx).ok() -} - -/// Signature for a struct or tuple field declaration. -/// Does not include a trailing comma. -pub fn field_signature(field: &hir::FieldDef<'_>, scx: &SaveContext<'_>) -> Option { - if !scx.config.signatures { - return None; - } - field.make(0, None, scx).ok() -} - -/// Does not include a trailing comma. -pub fn variant_signature(variant: &hir::Variant<'_>, scx: &SaveContext<'_>) -> Option { - if !scx.config.signatures { - return None; - } - variant.make(0, None, scx).ok() -} - -pub fn method_signature( - id: hir::OwnerId, - ident: Ident, - generics: &hir::Generics<'_>, - m: &hir::FnSig<'_>, - scx: &SaveContext<'_>, -) -> Option { - if !scx.config.signatures { - return None; - } - make_method_signature(id, ident, generics, m, scx).ok() -} - -pub fn assoc_const_signature( - id: hir::OwnerId, - ident: Symbol, - ty: &hir::Ty<'_>, - default: Option<&hir::Expr<'_>>, - scx: &SaveContext<'_>, -) -> Option { - if !scx.config.signatures { - return None; - } - make_assoc_const_signature(id, ident, ty, default, scx).ok() -} - -pub fn assoc_type_signature( - id: hir::OwnerId, - ident: Ident, - bounds: Option>, - default: Option<&hir::Ty<'_>>, - scx: &SaveContext<'_>, -) -> Option { - if !scx.config.signatures { - return None; - } - make_assoc_type_signature(id, ident, bounds, default, scx).ok() -} - -type Result = std::result::Result; - -trait Sig { - type Parent; - fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_>) -> Result; -} - -fn extend_sig( - mut sig: Signature, - text: String, - defs: Vec, - refs: Vec, -) -> Signature { - sig.text = text; - sig.defs.extend(defs.into_iter()); - sig.refs.extend(refs.into_iter()); - sig -} - -fn replace_text(mut sig: Signature, text: String) -> Signature { - sig.text = text; - sig -} - -fn merge_sigs(text: String, sigs: Vec) -> Signature { - let mut result = Signature { text, defs: vec![], refs: vec![] }; - - let (defs, refs): (Vec<_>, Vec<_>) = sigs.into_iter().map(|s| (s.defs, s.refs)).unzip(); - - result.defs.extend(defs.into_iter().flat_map(|ds| ds.into_iter())); - result.refs.extend(refs.into_iter().flat_map(|rs| rs.into_iter())); - - result -} - -fn text_sig(text: String) -> Signature { - Signature { text, defs: vec![], refs: vec![] } -} - -impl<'hir> Sig for hir::Ty<'hir> { - type Parent = hir::HirId; - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_>) -> Result { - let id = Some(self.hir_id); - match self.kind { - hir::TyKind::Slice(ref ty) => { - let nested = ty.make(offset + 1, id, scx)?; - let text = format!("[{}]", nested.text); - Ok(replace_text(nested, text)) - } - hir::TyKind::Ptr(ref mt) => { - let prefix = match mt.mutbl { - hir::Mutability::Mut => "*mut ", - hir::Mutability::Not => "*const ", - }; - let nested = mt.ty.make(offset + prefix.len(), id, scx)?; - let text = format!("{}{}", prefix, nested.text); - Ok(replace_text(nested, text)) - } - hir::TyKind::Ref(ref lifetime, ref mt) => { - let mut prefix = "&".to_owned(); - prefix.push_str(&lifetime.ident.to_string()); - prefix.push(' '); - if mt.mutbl.is_mut() { - prefix.push_str("mut "); - }; - - let nested = mt.ty.make(offset + prefix.len(), id, scx)?; - let text = format!("{}{}", prefix, nested.text); - Ok(replace_text(nested, text)) - } - hir::TyKind::Never => Ok(text_sig("!".to_owned())), - hir::TyKind::Tup(ts) => { - let mut text = "(".to_owned(); - let mut defs = vec![]; - let mut refs = vec![]; - for t in ts { - let nested = t.make(offset + text.len(), id, scx)?; - text.push_str(&nested.text); - text.push(','); - defs.extend(nested.defs.into_iter()); - refs.extend(nested.refs.into_iter()); - } - text.push(')'); - Ok(Signature { text, defs, refs }) - } - hir::TyKind::BareFn(ref f) => { - let mut text = String::new(); - if !f.generic_params.is_empty() { - // FIXME defs, bounds on lifetimes - text.push_str("for<"); - text.push_str( - &f.generic_params - .iter() - .filter_map(|param| match param.kind { - hir::GenericParamKind::Lifetime { .. } => { - Some(param.name.ident().to_string()) - } - _ => None, - }) - .collect::>() - .join(", "), - ); - text.push('>'); - } - - if let hir::Unsafety::Unsafe = f.unsafety { - text.push_str("unsafe "); - } - text.push_str("fn("); - - let mut defs = vec![]; - let mut refs = vec![]; - for i in f.decl.inputs { - let nested = i.make(offset + text.len(), Some(i.hir_id), scx)?; - text.push_str(&nested.text); - text.push(','); - defs.extend(nested.defs.into_iter()); - refs.extend(nested.refs.into_iter()); - } - text.push(')'); - if let hir::FnRetTy::Return(ref t) = f.decl.output { - text.push_str(" -> "); - let nested = t.make(offset + text.len(), None, scx)?; - text.push_str(&nested.text); - text.push(','); - defs.extend(nested.defs.into_iter()); - refs.extend(nested.refs.into_iter()); - } - - Ok(Signature { text, defs, refs }) - } - hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.make(offset, id, scx), - hir::TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref path)) => { - let nested_ty = qself.make(offset + 1, id, scx)?; - let prefix = format!( - "<{} as {}>::", - nested_ty.text, - path_segment_to_string(&path.segments[0]) - ); - - let name = path_segment_to_string(path.segments.last().ok_or("Bad path")?); - let res = scx.get_path_res(id.ok_or("Missing id for Path")?); - let id = id_from_def_id(res.def_id()); - if path.segments.len() == 2 { - let start = offset + prefix.len(); - let end = start + name.len(); - - Ok(Signature { - text: prefix + &name, - defs: vec![], - refs: vec![SigElement { id, start, end }], - }) - } else { - let start = offset + prefix.len() + 5; - let end = start + name.len(); - // FIXME should put the proper path in there, not ellipsis. - Ok(Signature { - text: prefix + "...::" + &name, - defs: vec![], - refs: vec![SigElement { id, start, end }], - }) - } - } - hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => { - let nested_ty = ty.make(offset + 1, id, scx)?; - let prefix = format!("<{}>::", nested_ty.text); - - let name = path_segment_to_string(segment); - let res = scx.get_path_res(id.ok_or("Missing id for Path")?); - let id = id_from_def_id(res.def_id()); - - let start = offset + prefix.len(); - let end = start + name.len(); - Ok(Signature { - text: prefix + &name, - defs: vec![], - refs: vec![SigElement { id, start, end }], - }) - } - hir::TyKind::Path(hir::QPath::LangItem(lang_item, _, _)) => { - Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name()))) - } - hir::TyKind::TraitObject(bounds, ..) => { - // FIXME recurse into bounds - let bounds: Vec> = bounds - .iter() - .map(|hir::PolyTraitRef { bound_generic_params, trait_ref, span }| { - hir::GenericBound::Trait( - hir::PolyTraitRef { - bound_generic_params, - trait_ref: hir::TraitRef { - path: trait_ref.path, - hir_ref_id: trait_ref.hir_ref_id, - }, - span: *span, - }, - hir::TraitBoundModifier::None, - ) - }) - .collect(); - let nested = bounds_to_string(&bounds); - Ok(text_sig(nested)) - } - hir::TyKind::Array(ref ty, ref length) => { - let nested_ty = ty.make(offset + 1, id, scx)?; - let expr = id_to_string(&scx.tcx.hir(), length.hir_id()).replace('\n', " "); - let text = format!("[{}; {}]", nested_ty.text, expr); - Ok(replace_text(nested_ty, text)) - } - hir::TyKind::OpaqueDef(item_id, _, _) => { - let item = scx.tcx.hir().item(item_id); - item.make(offset, Some(item_id.hir_id()), scx) - } - hir::TyKind::Typeof(_) | hir::TyKind::Infer | hir::TyKind::Err => Err("Ty"), - } - } -} - -impl<'hir> Sig for hir::Item<'hir> { - type Parent = hir::HirId; - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_>) -> Result { - let id = Some(self.hir_id()); - - match self.kind { - hir::ItemKind::Static(ref ty, m, ref body) => { - let mut text = "static ".to_owned(); - if m.is_mut() { - text.push_str("mut "); - } - let name = self.ident.to_string(); - let defs = vec![SigElement { - id: id_from_def_id(self.owner_id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + name.len(), - }]; - text.push_str(&name); - text.push_str(": "); - - let ty = ty.make(offset + text.len(), id, scx)?; - text.push_str(&ty.text); - - text.push_str(" = "); - let expr = id_to_string(&scx.tcx.hir(), body.hir_id).replace('\n', " "); - text.push_str(&expr); - - text.push(';'); - - Ok(extend_sig(ty, text, defs, vec![])) - } - hir::ItemKind::Const(ref ty, ref body) => { - let mut text = "const ".to_owned(); - let name = self.ident.to_string(); - let defs = vec![SigElement { - id: id_from_def_id(self.owner_id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + name.len(), - }]; - text.push_str(&name); - text.push_str(": "); - - let ty = ty.make(offset + text.len(), id, scx)?; - text.push_str(&ty.text); - - text.push_str(" = "); - let expr = id_to_string(&scx.tcx.hir(), body.hir_id).replace('\n', " "); - text.push_str(&expr); - - text.push(';'); - - Ok(extend_sig(ty, text, defs, vec![])) - } - hir::ItemKind::Fn(hir::FnSig { ref decl, header, span: _ }, ref generics, _) => { - let mut text = String::new(); - if let hir::Constness::Const = header.constness { - text.push_str("const "); - } - if hir::IsAsync::Async == header.asyncness { - text.push_str("async "); - } - if let hir::Unsafety::Unsafe = header.unsafety { - text.push_str("unsafe "); - } - text.push_str("fn "); - - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - - sig.text.push('('); - for i in decl.inputs { - // FIXME should descend into patterns to add defs. - sig.text.push_str(": "); - let nested = i.make(offset + sig.text.len(), Some(i.hir_id), scx)?; - sig.text.push_str(&nested.text); - sig.text.push(','); - sig.defs.extend(nested.defs.into_iter()); - sig.refs.extend(nested.refs.into_iter()); - } - sig.text.push(')'); - - if let hir::FnRetTy::Return(ref t) = decl.output { - sig.text.push_str(" -> "); - let nested = t.make(offset + sig.text.len(), None, scx)?; - sig.text.push_str(&nested.text); - sig.defs.extend(nested.defs.into_iter()); - sig.refs.extend(nested.refs.into_iter()); - } - sig.text.push_str(" {}"); - - Ok(sig) - } - hir::ItemKind::Macro(..) => { - let mut text = "macro".to_owned(); - let name = self.ident.to_string(); - text.push_str(&name); - text.push_str(&"! {}"); - - Ok(text_sig(text)) - } - hir::ItemKind::Mod(ref _mod) => { - let mut text = "mod ".to_owned(); - let name = self.ident.to_string(); - let defs = vec![SigElement { - id: id_from_def_id(self.owner_id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + name.len(), - }]; - text.push_str(&name); - // Could be either `mod foo;` or `mod foo { ... }`, but we'll just pick one. - text.push(';'); - - Ok(Signature { text, defs, refs: vec![] }) - } - hir::ItemKind::TyAlias(ref ty, ref generics) => { - let text = "type ".to_owned(); - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - - sig.text.push_str(" = "); - let ty = ty.make(offset + sig.text.len(), id, scx)?; - sig.text.push_str(&ty.text); - sig.text.push(';'); - - Ok(merge_sigs(sig.text.clone(), vec![sig, ty])) - } - hir::ItemKind::Enum(_, ref generics) => { - let text = "enum ".to_owned(); - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - sig.text.push_str(" {}"); - Ok(sig) - } - hir::ItemKind::Struct(_, ref generics) => { - let text = "struct ".to_owned(); - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - sig.text.push_str(" {}"); - Ok(sig) - } - hir::ItemKind::Union(_, ref generics) => { - let text = "union ".to_owned(); - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - sig.text.push_str(" {}"); - Ok(sig) - } - hir::ItemKind::Trait(is_auto, unsafety, ref generics, bounds, _) => { - let mut text = String::new(); - - if is_auto == hir::IsAuto::Yes { - text.push_str("auto "); - } - - if let hir::Unsafety::Unsafe = unsafety { - text.push_str("unsafe "); - } - text.push_str("trait "); - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - - if !bounds.is_empty() { - sig.text.push_str(": "); - sig.text.push_str(&bounds_to_string(bounds)); - } - // FIXME where clause - sig.text.push_str(" {}"); - - Ok(sig) - } - hir::ItemKind::TraitAlias(ref generics, bounds) => { - let mut text = String::new(); - text.push_str("trait "); - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - - if !bounds.is_empty() { - sig.text.push_str(" = "); - sig.text.push_str(&bounds_to_string(bounds)); - } - // FIXME where clause - sig.text.push(';'); - - Ok(sig) - } - hir::ItemKind::Impl(hir::Impl { - unsafety, - polarity, - defaultness, - defaultness_span: _, - constness, - ref generics, - ref of_trait, - ref self_ty, - items: _, - }) => { - let mut text = String::new(); - if let hir::Defaultness::Default { .. } = defaultness { - text.push_str("default "); - } - if let hir::Unsafety::Unsafe = unsafety { - text.push_str("unsafe "); - } - text.push_str("impl"); - if let hir::Constness::Const = constness { - text.push_str(" const"); - } - - let generics_sig = - generics.make(offset + text.len(), Some(self.owner_id.def_id), scx)?; - text.push_str(&generics_sig.text); - - text.push(' '); - - let trait_sig = if let Some(ref t) = *of_trait { - if let hir::ImplPolarity::Negative(_) = polarity { - text.push('!'); - } - let trait_sig = t.path.make(offset + text.len(), id, scx)?; - text.push_str(&trait_sig.text); - text.push_str(" for "); - trait_sig - } else { - text_sig(String::new()) - }; - - let ty_sig = self_ty.make(offset + text.len(), id, scx)?; - text.push_str(&ty_sig.text); - - text.push_str(" {}"); - - Ok(merge_sigs(text, vec![generics_sig, trait_sig, ty_sig])) - - // FIXME where clause - } - hir::ItemKind::ForeignMod { .. } => Err("extern mod"), - hir::ItemKind::GlobalAsm(_) => Err("global asm"), - hir::ItemKind::ExternCrate(_) => Err("extern crate"), - hir::ItemKind::OpaqueTy(ref opaque) => { - if opaque.in_trait { - Err("opaque type in trait") - } else { - Err("opaque type") - } - } - // FIXME should implement this (e.g., pub use). - hir::ItemKind::Use(..) => Err("import"), - } - } -} - -impl<'hir> Sig for hir::Path<'hir> { - type Parent = hir::HirId; - fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_>) -> Result { - let res = scx.get_path_res(id.ok_or("Missing id for Path")?); - - let (name, start, end) = match res { - Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => { - return Ok(Signature { text: path_to_string(self), defs: vec![], refs: vec![] }); - } - Res::Def(DefKind::AssocConst | DefKind::Variant | DefKind::Ctor(..), _) => { - let len = self.segments.len(); - if len < 2 { - return Err("Bad path"); - } - // FIXME: really we should descend into the generics here and add SigElements for - // them. - // FIXME: would be nice to have a def for the first path segment. - let seg1 = path_segment_to_string(&self.segments[len - 2]); - let seg2 = path_segment_to_string(&self.segments[len - 1]); - let start = offset + seg1.len() + 2; - (format!("{}::{}", seg1, seg2), start, start + seg2.len()) - } - _ => { - let name = path_segment_to_string(self.segments.last().ok_or("Bad path")?); - let end = offset + name.len(); - (name, offset, end) - } - }; - - let id = id_from_def_id(res.def_id()); - Ok(Signature { text: name, defs: vec![], refs: vec![SigElement { id, start, end }] }) - } -} - -// This does not cover the where clause, which must be processed separately. -impl<'hir> Sig for hir::Generics<'hir> { - type Parent = LocalDefId; - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_>) -> Result { - if self.params.is_empty() { - return Ok(text_sig(String::new())); - } - - let mut text = "<".to_owned(); - - let mut defs = Vec::with_capacity(self.params.len()); - for param in self.params { - let mut param_text = String::new(); - if let hir::GenericParamKind::Const { .. } = param.kind { - param_text.push_str("const "); - } - param_text.push_str(param.name.ident().as_str()); - defs.push(SigElement { - id: id_from_def_id(param.def_id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + param_text.as_str().len(), - }); - if let hir::GenericParamKind::Const { ref ty, default } = param.kind { - param_text.push_str(": "); - param_text.push_str(&ty_to_string(&ty)); - if let Some(default) = default { - param_text.push_str(" = "); - param_text.push_str(&id_to_string(&scx.tcx.hir(), default.hir_id)); - } - } - text.push_str(¶m_text); - text.push(','); - } - - text.push('>'); - Ok(Signature { text, defs, refs: vec![] }) - } -} - -impl<'hir> Sig for hir::FieldDef<'hir> { - type Parent = LocalDefId; - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_>) -> Result { - let mut text = String::new(); - - text.push_str(&self.ident.to_string()); - let defs = Some(SigElement { - id: id_from_def_id(self.def_id.to_def_id()), - start: offset, - end: offset + text.len(), - }); - text.push_str(": "); - - let mut ty_sig = self.ty.make(offset + text.len(), Some(self.hir_id), scx)?; - text.push_str(&ty_sig.text); - ty_sig.text = text; - ty_sig.defs.extend(defs.into_iter()); - Ok(ty_sig) - } -} - -impl<'hir> Sig for hir::Variant<'hir> { - type Parent = LocalDefId; - fn make(&self, offset: usize, parent_id: Option, scx: &SaveContext<'_>) -> Result { - let mut text = self.ident.to_string(); - match self.data { - hir::VariantData::Struct(fields, r) => { - let id = parent_id.ok_or("Missing id for Variant's parent")?; - let name_def = SigElement { - id: id_from_def_id(id.to_def_id()), - start: offset, - end: offset + text.len(), - }; - text.push_str(" { "); - let mut defs = vec![name_def]; - let mut refs = vec![]; - if r { - text.push_str("/* parse error */ "); - } else { - for f in fields { - let field_sig = f.make(offset + text.len(), Some(id), scx)?; - text.push_str(&field_sig.text); - text.push_str(", "); - defs.extend(field_sig.defs.into_iter()); - refs.extend(field_sig.refs.into_iter()); - } - } - text.push('}'); - Ok(Signature { text, defs, refs }) - } - hir::VariantData::Tuple(fields, _, def_id) => { - let name_def = SigElement { - id: id_from_def_id(def_id.to_def_id()), - start: offset, - end: offset + text.len(), - }; - text.push('('); - let mut defs = vec![name_def]; - let mut refs = vec![]; - for f in fields { - let field_sig = f.make(offset + text.len(), Some(def_id), scx)?; - text.push_str(&field_sig.text); - text.push_str(", "); - defs.extend(field_sig.defs.into_iter()); - refs.extend(field_sig.refs.into_iter()); - } - text.push(')'); - Ok(Signature { text, defs, refs }) - } - hir::VariantData::Unit(_, def_id) => { - let name_def = SigElement { - id: id_from_def_id(def_id.to_def_id()), - start: offset, - end: offset + text.len(), - }; - Ok(Signature { text, defs: vec![name_def], refs: vec![] }) - } - } - } -} - -impl<'hir> Sig for hir::ForeignItem<'hir> { - type Parent = hir::HirId; - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_>) -> Result { - let id = Some(self.hir_id()); - match self.kind { - hir::ForeignItemKind::Fn(decl, _, ref generics) => { - let mut text = String::new(); - text.push_str("fn "); - - let mut sig = - name_and_generics(text, offset, generics, self.owner_id, self.ident, scx)?; - - sig.text.push('('); - for i in decl.inputs { - sig.text.push_str(": "); - let nested = i.make(offset + sig.text.len(), Some(i.hir_id), scx)?; - sig.text.push_str(&nested.text); - sig.text.push(','); - sig.defs.extend(nested.defs.into_iter()); - sig.refs.extend(nested.refs.into_iter()); - } - sig.text.push(')'); - - if let hir::FnRetTy::Return(ref t) = decl.output { - sig.text.push_str(" -> "); - let nested = t.make(offset + sig.text.len(), None, scx)?; - sig.text.push_str(&nested.text); - sig.defs.extend(nested.defs.into_iter()); - sig.refs.extend(nested.refs.into_iter()); - } - sig.text.push(';'); - - Ok(sig) - } - hir::ForeignItemKind::Static(ref ty, m) => { - let mut text = "static ".to_owned(); - text.push_str(m.prefix_str()); - - let name = self.ident.to_string(); - let defs = vec![SigElement { - id: id_from_def_id(self.owner_id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + name.len(), - }]; - text.push_str(&name); - text.push_str(": "); - - let ty_sig = ty.make(offset + text.len(), id, scx)?; - text.push(';'); - - Ok(extend_sig(ty_sig, text, defs, vec![])) - } - hir::ForeignItemKind::Type => { - let mut text = "type ".to_owned(); - let name = self.ident.to_string(); - let defs = vec![SigElement { - id: id_from_def_id(self.owner_id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + name.len(), - }]; - text.push_str(&name); - text.push(';'); - - Ok(Signature { text, defs, refs: vec![] }) - } - } - } -} - -fn name_and_generics( - mut text: String, - offset: usize, - generics: &hir::Generics<'_>, - id: hir::OwnerId, - name: Ident, - scx: &SaveContext<'_>, -) -> Result { - let name = name.to_string(); - let def = SigElement { - id: id_from_def_id(id.to_def_id()), - start: offset + text.len(), - end: offset + text.len() + name.len(), - }; - text.push_str(&name); - let generics: Signature = generics.make(offset + text.len(), Some(id.def_id), scx)?; - // FIXME where clause - let text = format!("{}{}", text, generics.text); - Ok(extend_sig(generics, text, vec![def], vec![])) -} - -fn make_assoc_type_signature( - id: hir::OwnerId, - ident: Ident, - bounds: Option>, - default: Option<&hir::Ty<'_>>, - scx: &SaveContext<'_>, -) -> Result { - let mut text = "type ".to_owned(); - let name = ident.to_string(); - let mut defs = vec![SigElement { - id: id_from_def_id(id.to_def_id()), - start: text.len(), - end: text.len() + name.len(), - }]; - let mut refs = vec![]; - text.push_str(&name); - if let Some(bounds) = bounds { - text.push_str(": "); - // FIXME should descend into bounds - text.push_str(&bounds_to_string(bounds)); - } - if let Some(default) = default { - text.push_str(" = "); - let ty_sig = default.make(text.len(), Some(id.into()), scx)?; - text.push_str(&ty_sig.text); - defs.extend(ty_sig.defs.into_iter()); - refs.extend(ty_sig.refs.into_iter()); - } - text.push(';'); - Ok(Signature { text, defs, refs }) -} - -fn make_assoc_const_signature( - id: hir::OwnerId, - ident: Symbol, - ty: &hir::Ty<'_>, - default: Option<&hir::Expr<'_>>, - scx: &SaveContext<'_>, -) -> Result { - let mut text = "const ".to_owned(); - let name = ident.to_string(); - let mut defs = vec![SigElement { - id: id_from_def_id(id.to_def_id()), - start: text.len(), - end: text.len() + name.len(), - }]; - let mut refs = vec![]; - text.push_str(&name); - text.push_str(": "); - - let ty_sig = ty.make(text.len(), Some(id.into()), scx)?; - text.push_str(&ty_sig.text); - defs.extend(ty_sig.defs.into_iter()); - refs.extend(ty_sig.refs.into_iter()); - - if let Some(default) = default { - text.push_str(" = "); - text.push_str(&id_to_string(&scx.tcx.hir(), default.hir_id)); - } - text.push(';'); - Ok(Signature { text, defs, refs }) -} - -fn make_method_signature( - id: hir::OwnerId, - ident: Ident, - generics: &hir::Generics<'_>, - m: &hir::FnSig<'_>, - scx: &SaveContext<'_>, -) -> Result { - // FIXME code dup with function signature - let mut text = String::new(); - if let hir::Constness::Const = m.header.constness { - text.push_str("const "); - } - if hir::IsAsync::Async == m.header.asyncness { - text.push_str("async "); - } - if let hir::Unsafety::Unsafe = m.header.unsafety { - text.push_str("unsafe "); - } - text.push_str("fn "); - - let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?; - - sig.text.push('('); - for i in m.decl.inputs { - sig.text.push_str(": "); - let nested = i.make(sig.text.len(), Some(i.hir_id), scx)?; - sig.text.push_str(&nested.text); - sig.text.push(','); - sig.defs.extend(nested.defs.into_iter()); - sig.refs.extend(nested.refs.into_iter()); - } - sig.text.push(')'); - - if let hir::FnRetTy::Return(ref t) = m.decl.output { - sig.text.push_str(" -> "); - let nested = t.make(sig.text.len(), None, scx)?; - sig.text.push_str(&nested.text); - sig.defs.extend(nested.defs.into_iter()); - sig.refs.extend(nested.refs.into_iter()); - } - sig.text.push_str(" {}"); - - Ok(sig) -} diff --git a/compiler/rustc_save_analysis/src/span_utils.rs b/compiler/rustc_save_analysis/src/span_utils.rs deleted file mode 100644 index e65d57bb3db3e..0000000000000 --- a/compiler/rustc_save_analysis/src/span_utils.rs +++ /dev/null @@ -1,96 +0,0 @@ -use crate::generated_code; -use rustc_data_structures::sync::Lrc; -use rustc_lexer::{tokenize, TokenKind}; -use rustc_session::Session; -use rustc_span::*; - -#[derive(Clone)] -pub struct SpanUtils<'a> { - pub sess: &'a Session, -} - -impl<'a> SpanUtils<'a> { - pub fn new(sess: &'a Session) -> SpanUtils<'a> { - SpanUtils { sess } - } - - pub fn make_filename_string(&self, file: &SourceFile) -> String { - match &file.name { - FileName::Real(RealFileName::LocalPath(path)) => { - if path.is_absolute() { - self.sess.source_map().path_mapping().map_prefix(path).0.display().to_string() - } else { - self.sess - .opts - .working_dir - .remapped_path_if_available() - .join(&path) - .display() - .to_string() - } - } - filename => filename.prefer_remapped().to_string(), - } - } - - pub fn snippet(&self, span: Span) -> String { - match self.sess.source_map().span_to_snippet(span) { - Ok(s) => s, - Err(_) => String::new(), - } - } - - /// Finds the span of `*` token withing the larger `span`. - pub fn sub_span_of_star(&self, mut span: Span) -> Option { - let begin = self.sess.source_map().lookup_byte_offset(span.lo()); - let end = self.sess.source_map().lookup_byte_offset(span.hi()); - // Make the range zero-length if the span is invalid. - if begin.sf.start_pos != end.sf.start_pos { - span = span.shrink_to_lo(); - } - - let sf = Lrc::clone(&begin.sf); - - self.sess.source_map().ensure_source_file_source_present(Lrc::clone(&sf)); - let src = - sf.src.clone().or_else(|| sf.external_src.borrow().get_source().map(Lrc::clone))?; - let to_index = |pos: BytePos| -> usize { (pos - sf.start_pos).0 as usize }; - let text = &src[to_index(span.lo())..to_index(span.hi())]; - let start_pos = { - let mut pos = 0; - tokenize(text) - .map(|token| { - let start = pos; - pos += token.len; - (start, token) - }) - .find(|(_pos, token)| token.kind == TokenKind::Star)? - .0 - }; - let lo = span.lo() + BytePos(start_pos as u32); - let hi = lo + BytePos(1); - Some(span.with_lo(lo).with_hi(hi)) - } - - /// Return true if the span is generated code, and - /// it is not a subspan of the root callsite. - /// - /// Used to filter out spans of minimal value, - /// such as references to macro internal variables. - pub fn filter_generated(&self, span: Span) -> bool { - if generated_code(span) { - return true; - } - - //If the span comes from a fake source_file, filter it. - !self.sess.source_map().lookup_char_pos(span.lo()).file.is_real_file() - } -} - -macro_rules! filter { - ($util: expr, $parent: expr) => { - if $util.filter_generated($parent) { - return None; - } - }; -} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 81f7f6d72ae4a..d9e68320f8ffa 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1629,9 +1629,6 @@ options! { saturating_float_casts: Option = (None, parse_opt_bool, [TRACKED], "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ the max/min integer respectively, and NaN is mapped to 0 (default: yes)"), - save_analysis: bool = (false, parse_bool, [UNTRACKED], - "write syntax and type analysis (in JSON format) information, in \ - addition to normal output (default: no)"), self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled, parse_switch_with_opt_path, [UNTRACKED], "run the self profiler and output the raw event data"), diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b4fc1d4f28da7..952c70cec1c05 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -780,7 +780,6 @@ impl<'a> Builder<'a> { install::Clippy, install::Miri, install::LlvmTools, - install::Analysis, install::Src, install::Rustc ), @@ -1802,16 +1801,6 @@ impl<'a> Builder<'a> { } } - if mode == Mode::Std && self.config.extended && compiler.is_final_stage(self) { - rustflags.arg("-Zsave-analysis"); - cargo.env( - "RUST_SAVE_ANALYSIS_CONFIG", - "{\"output_file\": null,\"full_docs\": false,\ - \"pub_only\": true,\"reachable_only\": false,\ - \"distro_crate\": true,\"signatures\": false,\"borrow_data\": false}", - ); - } - // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc // when compiling the standard library, since this might be linked into the final outputs // produced by rustc. Since this mitigation is only available on Windows, only enable it diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 02e35d2436e2f..9b2b549612d81 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -12,6 +12,7 @@ use std::collections::HashSet; use std::env; use std::ffi::OsStr; use std::fs; +use std::io::Write; use std::path::{Path, PathBuf}; use std::process::Command; @@ -753,7 +754,7 @@ impl Step for Analysis { }); } - /// Creates a tarball of save-analysis metadata, if available. + /// Creates a tarball of (degenerate) save-analysis metadata, if available. fn run(self, builder: &Builder<'_>) -> Option { let compiler = self.compiler; let target = self.target; @@ -761,7 +762,6 @@ impl Step for Analysis { return None; } - builder.ensure(compile::Std::new(compiler, target)); let src = builder .stage_out(compiler, Mode::Std) .join(target.triple) @@ -769,6 +769,13 @@ impl Step for Analysis { .join("deps") .join("save-analysis"); + // Write a file indicating that this component has been removed. + t!(std::fs::create_dir_all(&src)); + let mut removed = src.clone(); + removed.push("removed.json"); + let mut f = t!(std::fs::File::create(removed)); + t!(write!(f, r#"{{ "warning": "The `rust-analysis` component has been removed." }}"#)); + let mut tarball = Tarball::new(builder, "rust-analysis", &target.triple); tarball.include_target_in_component_name(true); tarball.add_dir(src, format!("lib/rustlib/{}/analysis", target.triple)); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 1815a0973072b..ac3843c3344eb 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -243,18 +243,6 @@ install!((self, builder, _config), ); } }; - Analysis, alias = "analysis", Self::should_build(_config), only_hosts: false, { - // `expect` should be safe, only None with host != build, but this - // only uses the `build` compiler - let tarball = builder.ensure(dist::Analysis { - // Find the actual compiler (handling the full bootstrap option) which - // produced the save-analysis data because that data isn't copied - // through the sysroot uplifting. - compiler: builder.compiler_for(builder.top_stage, builder.config.build, self.target), - target: self.target - }).expect("missing analysis"); - install_sh(builder, "analysis", self.compiler.stage, Some(self.target), &tarball); - }; Rustc, path = "compiler/rustc", true, only_hosts: true, { let tarball = builder.ensure(dist::Rustc { compiler: builder.compiler(builder.top_stage, self.target), diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md index efbf861eaa68c..d8843280b844f 100644 --- a/src/doc/rustc/src/json.md +++ b/src/doc/rustc/src/json.md @@ -223,7 +223,6 @@ flag][option-emit] documentation. - "link": The generated crate as specified by the crate-type. - "dep-info": The `.d` file with dependency information in a Makefile-like syntax. - "metadata": The Rust `.rmeta` file containing metadata about the crate. - - "save-analysis": A JSON file emitted by the `-Zsave-analysis` feature. */ "emit": "link" } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index c4b994af13bfe..4c93f8a16b670 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -192,8 +192,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "regex-automata", "regex-syntax", "remove_dir_all", - "rls-data", - "rls-span", "rustc-demangle", "rustc-hash", "rustc-rayon", diff --git a/tests/run-make-fulldeps/issues-41478-43796/Makefile b/tests/run-make-fulldeps/issues-41478-43796/Makefile deleted file mode 100644 index e451cb03126cc..0000000000000 --- a/tests/run-make-fulldeps/issues-41478-43796/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include ../tools.mk - -all: - # Work in /tmp, because we need to create the `save-analysis-temp` folder. - cp a.rs $(TMPDIR)/ - cd $(TMPDIR) && $(RUSTC) -Zsave-analysis $(TMPDIR)/a.rs 2> $(TMPDIR)/stderr.txt || ( cat $(TMPDIR)/stderr.txt && exit 1 ) - [ ! -s $(TMPDIR)/stderr.txt ] || ( cat $(TMPDIR)/stderr.txt && exit 1 ) - [ -f $(TMPDIR)/save-analysis/liba.json ] || ( ls -la $(TMPDIR) && exit 1 ) diff --git a/tests/run-make-fulldeps/issues-41478-43796/a.rs b/tests/run-make-fulldeps/issues-41478-43796/a.rs deleted file mode 100644 index b072235b5bc5a..0000000000000 --- a/tests/run-make-fulldeps/issues-41478-43796/a.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![crate_type = "lib"] -pub struct V(#[allow(unused_tuple_struct_fields)] S); -pub trait An { - type U; -} -pub trait F { -} -impl F for V<::U> { -} diff --git a/tests/run-make-fulldeps/save-analysis-fail/Makefile b/tests/run-make-fulldeps/save-analysis-fail/Makefile deleted file mode 100644 index 69a2b2746948b..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-fail/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -include ../tools.mk -all: code -krate2: krate2.rs - $(RUSTC) $< -code: foo.rs krate2 - $(RUSTC) foo.rs -Zsave-analysis || exit 0 diff --git a/tests/run-make-fulldeps/save-analysis-fail/SameDir.rs b/tests/run-make-fulldeps/save-analysis-fail/SameDir.rs deleted file mode 100644 index 2c690d5f759d7..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-fail/SameDir.rs +++ /dev/null @@ -1,5 +0,0 @@ -// sub-module in the same directory as the main crate file - -pub struct SameStruct { - pub name: String -} diff --git a/tests/run-make-fulldeps/save-analysis-fail/SameDir3.rs b/tests/run-make-fulldeps/save-analysis-fail/SameDir3.rs deleted file mode 100644 index fab03ee2e3d15..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-fail/SameDir3.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn hello(x: isize) { - println!("macro {} :-(", x); -} diff --git a/tests/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs b/tests/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs deleted file mode 100644 index 511721d92a350..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// sub-module in a sub-directory - -use sub::sub2 as msalias; -use sub::sub2; - -static yy: usize = 25; - -mod sub { - pub mod sub2 { - pub mod sub3 { - pub fn hello() { - println!("hello from module 3"); - } - } - pub fn hello() { - println!("hello from a module"); - } - - pub struct nested_struct { - pub field2: u32, - } - } -} - -pub struct SubStruct { - pub name: String -} diff --git a/tests/run-make-fulldeps/save-analysis-fail/foo.rs b/tests/run-make-fulldeps/save-analysis-fail/foo.rs deleted file mode 100644 index c5a70605e04cb..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-fail/foo.rs +++ /dev/null @@ -1,463 +0,0 @@ -#![crate_name = "test"] -#![feature(rustc_private)] - -extern crate rustc_graphviz; -// A simple rust project - -extern crate krate2; -extern crate krate2 as krate3; - -use rustc_graphviz::RenderOption; -use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; -use std::io::Write; - -use sub::sub2 as msalias; -use sub::sub2; -use sub::sub2::nested_struct as sub_struct; - -use std::mem::size_of; - -use std::char::from_u32; - -static uni: &'static str = "Les Miséééééééérables"; -static yy: usize = 25; - -static bob: Option = None; - -// buglink test - see issue #1337. - -fn test_alias(i: Option<::Item>) { - let s = sub_struct { field2: 45u32 }; - - // import tests - fn foo(x: &Write) {} - let _: Option<_> = from_u32(45); - - let x = 42usize; - - krate2::hello(); - krate3::hello(); - - let x = (3isize, 4usize); - let y = x.1; -} - -// Issue #37700 -const LUT_BITS: usize = 3; -pub struct HuffmanTable { - ac_lut: Option<[(i16, u8); 1 << LUT_BITS]>, -} - -struct TupStruct(isize, isize, Box); - -fn test_tup_struct(x: TupStruct) -> isize { - x.1 -} - -fn println(s: &str) { - std::io::stdout().write_all(s.as_bytes()); -} - -mod sub { - pub mod sub2 { - use std::io::Write; - pub mod sub3 { - use std::io::Write; - pub fn hello() { - ::println("hello from module 3"); - } - } - pub fn hello() { - ::println("hello from a module"); - } - - pub struct nested_struct { - pub field2: u32, - } - - pub enum nested_enum { - Nest2 = 2, - Nest3 = 3, - } - } -} - -pub mod SameDir; -pub mod SubDir; - -#[path = "SameDir3.rs"] -pub mod SameDir2; - -struct nofields; - -#[derive(Clone)] -struct some_fields { - field1: u32, -} - -type SF = some_fields; - -trait SuperTrait { - fn qux(&self) { - panic!(); - } -} - -trait SomeTrait: SuperTrait { - fn Method(&self, x: u32) -> u32; - - fn prov(&self, x: u32) -> u32 { - println(&x.to_string()); - 42 - } - fn provided_method(&self) -> u32 { - 42 - } -} - -trait SubTrait: SomeTrait { - fn stat2(x: &Self) -> u32 { - 32 - } -} - -trait SizedTrait: Sized {} - -fn error(s: &SizedTrait) { - let foo = 42; - println!("Hello world! {}", foo); -} - -impl SomeTrait for some_fields { - fn Method(&self, x: u32) -> u32 { - println(&x.to_string()); - self.field1 - } -} - -impl SuperTrait for some_fields {} - -impl SubTrait for some_fields {} - -impl some_fields { - fn stat(x: u32) -> u32 { - println(&x.to_string()); - 42 - } - fn stat2(x: &some_fields) -> u32 { - 42 - } - - fn align_to(&mut self) {} - - fn test(&mut self) { - self.align_to::(); - } -} - -impl SuperTrait for nofields {} -impl SomeTrait for nofields { - fn Method(&self, x: u32) -> u32 { - self.Method(x); - 43 - } - - fn provided_method(&self) -> u32 { - 21 - } -} - -impl SubTrait for nofields {} - -impl SuperTrait for (Box, Box) {} - -fn f_with_params(x: &T) { - x.Method(41); -} - -type MyType = Box; - -enum SomeEnum<'a> { - Ints(isize, isize), - Floats(f64, f64), - Strings(&'a str, &'a str, &'a str), - MyTypes(MyType, MyType), -} - -#[derive(Copy, Clone)] -enum SomeOtherEnum { - SomeConst1, - SomeConst2, - SomeConst3, -} - -enum SomeStructEnum { - EnumStruct { a: isize, b: isize }, - EnumStruct2 { f1: MyType, f2: MyType }, - EnumStruct3 { f1: MyType, f2: MyType, f3: SomeEnum<'static> }, -} - -fn matchSomeEnum(val: SomeEnum) { - match val { - SomeEnum::Ints(int1, int2) => { - println(&(int1 + int2).to_string()); - } - SomeEnum::Floats(float1, float2) => { - println(&(float2 * float1).to_string()); - } - SomeEnum::Strings(.., s3) => { - println(s3); - } - SomeEnum::MyTypes(mt1, mt2) => { - println(&(mt1.field1 - mt2.field1).to_string()); - } - } -} - -fn matchSomeStructEnum(se: SomeStructEnum) { - match se { - SomeStructEnum::EnumStruct { a: a, .. } => println(&a.to_string()), - SomeStructEnum::EnumStruct2 { f1: f1, f2: f_2 } => println(&f_2.field1.to_string()), - SomeStructEnum::EnumStruct3 { f1, .. } => println(&f1.field1.to_string()), - } -} - -fn matchSomeStructEnum2(se: SomeStructEnum) { - use SomeStructEnum::*; - match se { - EnumStruct { a: ref aaa, .. } => println(&aaa.to_string()), - EnumStruct2 { f1, f2: f2 } => println(&f1.field1.to_string()), - EnumStruct3 { f1, f3: SomeEnum::Ints(..), f2 } => println(&f1.field1.to_string()), - _ => {} - } -} - -fn matchSomeOtherEnum(val: SomeOtherEnum) { - use SomeOtherEnum::{SomeConst2, SomeConst3}; - match val { - SomeOtherEnum::SomeConst1 => { - println("I'm const1."); - } - SomeConst2 | SomeConst3 => { - println("I'm const2 or const3."); - } - } -} - -fn hello((z, a): (u32, String), ex: X) { - SameDir2::hello(43); - - println(&yy.to_string()); - let (x, y): (u32, u32) = (5, 3); - println(&x.to_string()); - println(&z.to_string()); - let x: u32 = x; - println(&x.to_string()); - let x = "hello"; - println(x); - - let x = 32.0f32; - let _ = (x + ((x * x) + 1.0).sqrt()).ln(); - - let s: Box = Box::new(some_fields { field1: 43 }); - let s2: Box = Box::new(some_fields { field1: 43 }); - let s3 = Box::new(nofields); - - s.Method(43); - s3.Method(43); - s2.Method(43); - - ex.prov(43); - - let y: u32 = 56; - // static method on struct - let r = some_fields::stat(y); - // trait static method, calls default - let r = SubTrait::stat2(&*s3); - - let s4 = s3 as Box; - s4.Method(43); - - s4.provided_method(); - s2.prov(45); - - let closure = |x: u32, s: &SomeTrait| { - s.Method(23); - return x + y; - }; - - let z = closure(10, &*s); -} - -pub struct blah { - used_link_args: RefCell<[&'static str; 0]>, -} - -#[macro_use] -mod macro_use_test { - macro_rules! test_rec { - (q, $src: expr) => {{ - print!("{}", $src); - test_rec!($src); - }}; - ($src: expr) => { - print!("{}", $src); - }; - } - - macro_rules! internal_vars { - ($src: ident) => {{ - let mut x = $src; - x += 100; - }}; - } -} - -fn main() { - // foo - let s = Box::new(some_fields { field1: 43 }); - hello((43, "a".to_string()), *s); - sub::sub2::hello(); - sub2::sub3::hello(); - - let h = sub2::sub3::hello; - h(); - - // utf8 chars - let ut = "Les Miséééééééérables"; - - // For some reason, this pattern of macro_rules foiled our generated code - // avoiding strategy. - macro_rules! variable_str(($name:expr) => ( - some_fields { - field1: $name, - } - )); - let vs = variable_str!(32); - - let mut candidates: RefCell> = RefCell::new(HashMap::new()); - let _ = blah { used_link_args: RefCell::new([]) }; - let s1 = nofields; - let s2 = SF { field1: 55 }; - let s3: some_fields = some_fields { field1: 55 }; - let s4: msalias::nested_struct = sub::sub2::nested_struct { field2: 55 }; - let s4: msalias::nested_struct = sub2::nested_struct { field2: 55 }; - println(&s2.field1.to_string()); - let s5: MyType = Box::new(some_fields { field1: 55 }); - let s = SameDir::SameStruct { name: "Bob".to_string() }; - let s = SubDir::SubStruct { name: "Bob".to_string() }; - let s6: SomeEnum = SomeEnum::MyTypes(Box::new(s2.clone()), s5); - let s7: SomeEnum = SomeEnum::Strings("one", "two", "three"); - matchSomeEnum(s6); - matchSomeEnum(s7); - let s8: SomeOtherEnum = SomeOtherEnum::SomeConst2; - matchSomeOtherEnum(s8); - let s9: SomeStructEnum = - SomeStructEnum::EnumStruct2 { f1: Box::new(some_fields { field1: 10 }), f2: Box::new(s2) }; - matchSomeStructEnum(s9); - - for x in &vec![1, 2, 3] { - let _y = x; - } - - let s7: SomeEnum = SomeEnum::Strings("one", "two", "three"); - if let SomeEnum::Strings(..) = s7 { - println!("hello!"); - } - - for i in 0..5 { - foo_foo(i); - } - - if let Some(x) = None { - foo_foo(x); - } - - if false { - } else if let Some(y) = None { - foo_foo(y); - } - - while let Some(z) = None { - foo_foo(z); - } - - let mut x = 4; - test_rec!(q, "Hello"); - assert_eq!(x, 4); - internal_vars!(x); -} - -fn foo_foo(_: i32) {} - -impl Iterator for nofields { - type Item = (usize, usize); - - fn next(&mut self) -> Option<(usize, usize)> { - panic!() - } - - fn size_hint(&self) -> (usize, Option) { - panic!() - } -} - -trait Pattern<'a> { - type Searcher; -} - -struct CharEqPattern; - -impl<'a> Pattern<'a> for CharEqPattern { - type Searcher = CharEqPattern; -} - -struct CharSearcher<'a>(>::Searcher); - -pub trait Error {} - -impl Error + 'static { - pub fn is(&self) -> bool { - panic!() - } -} - -impl Error + 'static + Send { - pub fn is(&self) -> bool { - ::is::(self) - } -} -extern crate serialize; -#[derive(Clone, Copy, Hash, Encodable, Decodable, PartialEq, Eq, PartialOrd, Ord, Debug, Default)] -struct AllDerives(i32); - -fn test_format_args() { - let x = 1; - let y = 2; - let name = "Joe Blogg"; - println!("Hello {}", name); - print!("Hello {0}", name); - print!("{0} + {} = {}", x, y); - print!("x is {}, y is {1}, name is {n}", x, y, n = name); -} - -extern "C" { - static EXTERN_FOO: u8; - fn extern_foo(a: u8, b: i32) -> String; -} - -struct Rls699 { - f: u32, -} - -fn new(f: u32) -> Rls699 { - Rls699 { fs } -} - -fn invalid_tuple_struct_access() { - bar.0; - - struct S; - S.0; -} diff --git a/tests/run-make-fulldeps/save-analysis-fail/krate2.rs b/tests/run-make-fulldeps/save-analysis-fail/krate2.rs deleted file mode 100644 index 7d787e0c9871f..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-fail/krate2.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![ crate_name = "krate2" ] -#![ crate_type = "lib" ] - -use std::io::Write; - -pub fn hello() { - std::io::stdout().write_all(b"hello world!\n"); -} diff --git a/tests/run-make-fulldeps/save-analysis-rfc2126/Makefile b/tests/run-make-fulldeps/save-analysis-rfc2126/Makefile deleted file mode 100644 index 30f57034bba55..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-rfc2126/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include ../tools.mk - -all: extern_absolute_paths.rs krate2 - $(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 --extern krate2 - cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py - -krate2: krate2.rs - $(RUSTC) $< diff --git a/tests/run-make-fulldeps/save-analysis-rfc2126/extern_absolute_paths.rs b/tests/run-make-fulldeps/save-analysis-rfc2126/extern_absolute_paths.rs deleted file mode 100644 index 7a8e3fff098a0..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-rfc2126/extern_absolute_paths.rs +++ /dev/null @@ -1,6 +0,0 @@ -use krate2::hello; - -fn main() { - hello(); - ::krate2::hello(); -} diff --git a/tests/run-make-fulldeps/save-analysis-rfc2126/krate2.rs b/tests/run-make-fulldeps/save-analysis-rfc2126/krate2.rs deleted file mode 100644 index d24c68862b074..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-rfc2126/krate2.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![crate_name = "krate2"] -#![crate_type = "lib"] - -pub fn hello() { -} diff --git a/tests/run-make-fulldeps/save-analysis-rfc2126/validate_json.py b/tests/run-make-fulldeps/save-analysis-rfc2126/validate_json.py deleted file mode 100644 index 882d29a8beb23..0000000000000 --- a/tests/run-make-fulldeps/save-analysis-rfc2126/validate_json.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - -import sys -import json - -crates = json.loads(sys.stdin.readline().strip())["prelude"]["external_crates"] -assert any(map(lambda c: c["id"]["name"] == "krate2", crates)) diff --git a/tests/run-make-fulldeps/save-analysis/Makefile b/tests/run-make-fulldeps/save-analysis/Makefile deleted file mode 100644 index b8b6be13dbd76..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -include ../tools.mk -all: code -krate2: krate2.rs - $(RUSTC) $< -code: foo.rs krate2 - $(RUSTC) foo.rs -Zsave-analysis diff --git a/tests/run-make-fulldeps/save-analysis/SameDir.rs b/tests/run-make-fulldeps/save-analysis/SameDir.rs deleted file mode 100644 index 2c690d5f759d7..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/SameDir.rs +++ /dev/null @@ -1,5 +0,0 @@ -// sub-module in the same directory as the main crate file - -pub struct SameStruct { - pub name: String -} diff --git a/tests/run-make-fulldeps/save-analysis/SameDir3.rs b/tests/run-make-fulldeps/save-analysis/SameDir3.rs deleted file mode 100644 index fab03ee2e3d15..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/SameDir3.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn hello(x: isize) { - println!("macro {} :-(", x); -} diff --git a/tests/run-make-fulldeps/save-analysis/SubDir/mod.rs b/tests/run-make-fulldeps/save-analysis/SubDir/mod.rs deleted file mode 100644 index 511721d92a350..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/SubDir/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -// sub-module in a sub-directory - -use sub::sub2 as msalias; -use sub::sub2; - -static yy: usize = 25; - -mod sub { - pub mod sub2 { - pub mod sub3 { - pub fn hello() { - println!("hello from module 3"); - } - } - pub fn hello() { - println!("hello from a module"); - } - - pub struct nested_struct { - pub field2: u32, - } - } -} - -pub struct SubStruct { - pub name: String -} diff --git a/tests/run-make-fulldeps/save-analysis/extra-docs.md b/tests/run-make-fulldeps/save-analysis/extra-docs.md deleted file mode 100644 index 0605ca517ff3b..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/extra-docs.md +++ /dev/null @@ -1 +0,0 @@ -Extra docs for this struct. diff --git a/tests/run-make-fulldeps/save-analysis/foo.rs b/tests/run-make-fulldeps/save-analysis/foo.rs deleted file mode 100644 index 384589de3b480..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/foo.rs +++ /dev/null @@ -1,465 +0,0 @@ -#![crate_name = "test"] -#![feature(rustc_private)] -#![feature(associated_type_defaults)] - -extern crate rustc_graphviz; -// A simple rust project - -// Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta -// files. -#[allow(unused_extern_crates)] -extern crate rustc_driver; - -extern crate krate2; -extern crate krate2 as krate3; - -use rustc_graphviz::RenderOption; -use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; -use std::io::Write; - -use sub::sub2 as msalias; -use sub::sub2; -use sub::sub2::nested_struct as sub_struct; - -use std::mem::size_of; - -use std::char::from_u32; - -static uni: &'static str = "Les Miséééééééérables"; -static yy: usize = 25; - -static bob: Option = None; - -// buglink test - see issue #1337. - -fn test_alias(i: Option<::Item>) { - let s = sub_struct { field2: 45u32 }; - - // import tests - fn foo(x: &Write) {} - let _: Option<_> = from_u32(45); - - let x = 42usize; - - krate2::hello(); - krate3::hello(); - - let x = (3isize, 4usize); - let y = x.1; -} - -// Issue #37700 -const LUT_BITS: usize = 3; -pub struct HuffmanTable { - ac_lut: Option<[(i16, u8); 1 << LUT_BITS]>, -} - -struct TupStruct(isize, isize, Box); - -fn test_tup_struct(x: TupStruct) -> isize { - x.1 -} - -fn println(s: &str) { - std::io::stdout().write_all(s.as_bytes()); -} - -mod sub { - pub mod sub2 { - use std::io::Write; - pub mod sub3 { - use std::io::Write; - pub fn hello() { - ::println("hello from module 3"); - } - } - pub fn hello() { - ::println("hello from a module"); - } - - pub struct nested_struct { - pub field2: u32, - } - - pub enum nested_enum { - Nest2 = 2, - Nest3 = 3, - } - } -} - -pub mod SameDir; -pub mod SubDir; - -#[path = "SameDir3.rs"] -pub mod SameDir2; - -struct nofields; - -#[derive(Clone)] -struct some_fields { - field1: u32, -} - -type SF = some_fields; - -trait SuperTrait { - fn qux(&self) { - panic!(); - } -} - -trait SomeTrait: SuperTrait { - fn Method(&self, x: u32) -> u32; - - fn prov(&self, x: u32) -> u32 { - println(&x.to_string()); - 42 - } - fn provided_method(&self) -> u32 { - 42 - } -} - -trait SubTrait: SomeTrait { - fn stat2(x: &Self) -> u32 { - 32 - } -} - -impl SomeTrait for some_fields { - fn Method(&self, x: u32) -> u32 { - println(&x.to_string()); - self.field1 - } -} - -impl SuperTrait for some_fields {} - -impl SubTrait for some_fields {} - -impl some_fields { - fn stat(x: u32) -> u32 { - println(&x.to_string()); - 42 - } - fn stat2(x: &some_fields) -> u32 { - 42 - } - - fn align_to(&mut self) {} - - fn test(&mut self) { - self.align_to::(); - } -} - -impl SuperTrait for nofields {} -impl SomeTrait for nofields { - fn Method(&self, x: u32) -> u32 { - self.Method(x); - 43 - } - - fn provided_method(&self) -> u32 { - 21 - } -} - -impl SubTrait for nofields {} - -impl SuperTrait for (Box, Box) {} - -fn f_with_params(x: &T) { - x.Method(41); -} - -type MyType = Box; - -enum SomeEnum<'a> { - Ints(isize, isize), - Floats(f64, f64), - Strings(&'a str, &'a str, &'a str), - MyTypes(MyType, MyType), -} - -#[derive(Copy, Clone)] -enum SomeOtherEnum { - SomeConst1, - SomeConst2, - SomeConst3, -} - -enum SomeStructEnum { - EnumStruct { a: isize, b: isize }, - EnumStruct2 { f1: MyType, f2: MyType }, - EnumStruct3 { f1: MyType, f2: MyType, f3: SomeEnum<'static> }, -} - -fn matchSomeEnum(val: SomeEnum) { - match val { - SomeEnum::Ints(int1, int2) => { - println(&(int1 + int2).to_string()); - } - SomeEnum::Floats(float1, float2) => { - println(&(float2 * float1).to_string()); - } - SomeEnum::Strings(.., s3) => { - println(s3); - } - SomeEnum::MyTypes(mt1, mt2) => { - println(&(mt1.field1 - mt2.field1).to_string()); - } - } -} - -fn matchSomeStructEnum(se: SomeStructEnum) { - match se { - SomeStructEnum::EnumStruct { a: a, .. } => println(&a.to_string()), - SomeStructEnum::EnumStruct2 { f1: f1, f2: f_2 } => println(&f_2.field1.to_string()), - SomeStructEnum::EnumStruct3 { f1, .. } => println(&f1.field1.to_string()), - } -} - -fn matchSomeStructEnum2(se: SomeStructEnum) { - use SomeStructEnum::*; - match se { - EnumStruct { a: ref aaa, .. } => println(&aaa.to_string()), - EnumStruct2 { f1, f2: f2 } => println(&f1.field1.to_string()), - EnumStruct3 { f1, f3: SomeEnum::Ints(..), f2 } => println(&f1.field1.to_string()), - _ => {} - } -} - -fn matchSomeOtherEnum(val: SomeOtherEnum) { - use SomeOtherEnum::{SomeConst2, SomeConst3}; - match val { - SomeOtherEnum::SomeConst1 => { - println("I'm const1."); - } - SomeConst2 | SomeConst3 => { - println("I'm const2 or const3."); - } - } -} - -fn hello((z, a): (u32, String), ex: X) { - SameDir2::hello(43); - - println(&yy.to_string()); - let (x, y): (u32, u32) = (5, 3); - println(&x.to_string()); - println(&z.to_string()); - let x: u32 = x; - println(&x.to_string()); - let x = "hello"; - println(x); - - let x = 32.0f32; - let _ = (x + ((x * x) + 1.0).sqrt()).ln(); - - let s: Box = Box::new(some_fields { field1: 43 }); - let s2: Box = Box::new(some_fields { field1: 43 }); - let s3 = Box::new(nofields); - - s.Method(43); - s3.Method(43); - s2.Method(43); - - ex.prov(43); - - let y: u32 = 56; - // static method on struct - let r = some_fields::stat(y); - // trait static method, calls default - let r = SubTrait::stat2(&*s3); - - let s4 = s3 as Box; - s4.Method(43); - - s4.provided_method(); - s2.prov(45); - - let closure = |x: u32, s: &SomeTrait| { - s.Method(23); - return x + y; - }; - - let z = closure(10, &*s); -} - -pub struct blah { - used_link_args: RefCell<[&'static str; 0]>, -} - -#[macro_use] -mod macro_use_test { - macro_rules! test_rec { - (q, $src: expr) => {{ - print!("{}", $src); - test_rec!($src); - }}; - ($src: expr) => { - print!("{}", $src); - }; - } - - macro_rules! internal_vars { - ($src: ident) => {{ - let mut x = $src; - x += 100; - }}; - } -} - -fn main() { - // foo - let s = Box::new(some_fields { field1: 43 }); - hello((43, "a".to_string()), *s); - sub::sub2::hello(); - sub2::sub3::hello(); - - let h = sub2::sub3::hello; - h(); - - // utf8 chars - let ut = "Les Miséééééééérables"; - - // For some reason, this pattern of macro_rules foiled our generated code - // avoiding strategy. - macro_rules! variable_str(($name:expr) => ( - some_fields { - field1: $name, - } - )); - let vs = variable_str!(32); - - let mut candidates: RefCell> = RefCell::new(HashMap::new()); - let _ = blah { used_link_args: RefCell::new([]) }; - let s1 = nofields; - let s2 = SF { field1: 55 }; - let s3: some_fields = some_fields { field1: 55 }; - let s4: msalias::nested_struct = sub::sub2::nested_struct { field2: 55 }; - let s4: msalias::nested_struct = sub2::nested_struct { field2: 55 }; - println(&s2.field1.to_string()); - let s5: MyType = Box::new(some_fields { field1: 55 }); - let s = SameDir::SameStruct { name: "Bob".to_string() }; - let s = SubDir::SubStruct { name: "Bob".to_string() }; - let s6: SomeEnum = SomeEnum::MyTypes(Box::new(s2.clone()), s5); - let s7: SomeEnum = SomeEnum::Strings("one", "two", "three"); - matchSomeEnum(s6); - matchSomeEnum(s7); - let s8: SomeOtherEnum = SomeOtherEnum::SomeConst2; - matchSomeOtherEnum(s8); - let s9: SomeStructEnum = - SomeStructEnum::EnumStruct2 { f1: Box::new(some_fields { field1: 10 }), f2: Box::new(s2) }; - matchSomeStructEnum(s9); - - for x in &vec![1, 2, 3] { - let _y = x; - } - - let s7: SomeEnum = SomeEnum::Strings("one", "two", "three"); - if let SomeEnum::Strings(..) = s7 { - println!("hello!"); - } - - for i in 0..5 { - foo_foo(i); - } - - if let Some(x) = None { - foo_foo(x); - } - - if false { - } else if let Some(y) = None { - foo_foo(y); - } - - while let Some(z) = None { - foo_foo(z); - } - - let mut x = 4; - test_rec!(q, "Hello"); - assert_eq!(x, 4); - internal_vars!(x); -} - -fn foo_foo(_: i32) {} - -impl Iterator for nofields { - type Item = (usize, usize); - - fn next(&mut self) -> Option<(usize, usize)> { - panic!() - } - - fn size_hint(&self) -> (usize, Option) { - panic!() - } -} - -trait Pattern<'a> { - type Searcher; -} - -struct CharEqPattern; - -impl<'a> Pattern<'a> for CharEqPattern { - type Searcher = CharEqPattern; -} - -struct CharSearcher<'a>(>::Searcher); - -pub trait Error {} - -impl Error + 'static { - pub fn is(&self) -> bool { - panic!() - } -} - -impl Error + 'static + Send { - pub fn is(&self) -> bool { - ::is::(self) - } -} -extern crate rustc_serialize; -#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Default)] -struct AllDerives(i32); - -fn test_format_args() { - let x = 1; - let y = 2; - let name = "Joe Blogg"; - println!("Hello {}", name); - print!("Hello {0}", name); - print!("{0} + {} = {}", x, y); - print!("x is {}, y is {1}, name is {n}", x, y, n = name); -} - -union TestUnion { - f1: u32, -} - -struct FrameBuffer; - -struct SilenceGenerator; - -impl Iterator for SilenceGenerator { - type Item = FrameBuffer; - - fn next(&mut self) -> Option { - panic!(); - } -} - -#[doc = include_str!("extra-docs.md")] -struct StructWithDocs; - -trait Foo { - type Bar = FrameBuffer; -} diff --git a/tests/run-make-fulldeps/save-analysis/krate2.rs b/tests/run-make-fulldeps/save-analysis/krate2.rs deleted file mode 100644 index 7d787e0c9871f..0000000000000 --- a/tests/run-make-fulldeps/save-analysis/krate2.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![ crate_name = "krate2" ] -#![ crate_type = "lib" ] - -use std::io::Write; - -pub fn hello() { - std::io::stdout().write_all(b"hello world!\n"); -} diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout index 96329f31723bd..8d0155151b8df 100644 --- a/tests/rustdoc-ui/z-help.stdout +++ b/tests/rustdoc-ui/z-help.stdout @@ -146,7 +146,6 @@ -Z sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer -Z sanitizer-recover=val -- enable recovery for selected sanitizers -Z saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes) - -Z save-analysis=val -- write syntax and type analysis (in JSON format) information, in addition to normal output (default: no) -Z self-profile=val -- run the self profiler and output the raw event data -Z self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of: `wall-time` (monotonic clock, i.e. `std::time::Instant`) diff --git a/tests/ui/asm/issue-72570.rs b/tests/ui/asm/issue-72570.rs index bb13816348d78..ac589de2303f9 100644 --- a/tests/ui/asm/issue-72570.rs +++ b/tests/ui/asm/issue-72570.rs @@ -1,6 +1,4 @@ -// compile-flags: -Zsave-analysis // needs-asm-support -// Also test for #72960 use std::arch::asm; diff --git a/tests/ui/asm/issue-72570.stderr b/tests/ui/asm/issue-72570.stderr index fa5792688b252..49013a23ced2d 100644 --- a/tests/ui/asm/issue-72570.stderr +++ b/tests/ui/asm/issue-72570.stderr @@ -1,5 +1,5 @@ error: invalid register `invalid`: unknown register - --> $DIR/issue-72570.rs:9:18 + --> $DIR/issue-72570.rs:7:18 | LL | asm!("", in("invalid") "".len()); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr index f1f3a9c3de03b..82030731cc17d 100644 --- a/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr +++ b/tests/ui/const-generics/const-argument-non-static-lifetime.min.stderr @@ -1,5 +1,5 @@ error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-argument-non-static-lifetime.rs:15:17 + --> $DIR/const-argument-non-static-lifetime.rs:14:17 | LL | let _: &'a (); | ^^ diff --git a/tests/ui/const-generics/const-argument-non-static-lifetime.rs b/tests/ui/const-generics/const-argument-non-static-lifetime.rs index 36a569784adf7..0357e4ed59fda 100644 --- a/tests/ui/const-generics/const-argument-non-static-lifetime.rs +++ b/tests/ui/const-generics/const-argument-non-static-lifetime.rs @@ -2,7 +2,6 @@ // revisions: full min // regression test for #78180 -// compile-flags: -Zsave-analysis #![cfg_attr(full, feature(generic_const_exprs))] #![cfg_attr(full, allow(incomplete_features))] diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs index 781f50e61734d..b776f2017fae0 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs @@ -1,6 +1,3 @@ -// compile-flags: -Zsave-analysis -// Regression test for #69414 ^ - use std::marker::PhantomData; struct B(PhantomData<[T; N]>); diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 8e14defd65d99..9c5c97befd836 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -1,5 +1,5 @@ error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/const-param-type-depends-on-type-param-ungated.rs:6:22 + --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 | LL | struct B(PhantomData<[T; N]>); | ^ the type must not depend on the parameter `T` diff --git a/tests/ui/const-generics/issues/issue-73260.rs b/tests/ui/const-generics/issues/issue-73260.rs index d762f9c8b2620..aa7ae90a36373 100644 --- a/tests/ui/const-generics/issues/issue-73260.rs +++ b/tests/ui/const-generics/issues/issue-73260.rs @@ -1,4 +1,3 @@ -// compile-flags: -Zsave-analysis #![feature(generic_const_exprs)] #![allow(incomplete_features)] struct Arr diff --git a/tests/ui/const-generics/issues/issue-73260.stderr b/tests/ui/const-generics/issues/issue-73260.stderr index 7670032e5b758..f9ff0f28d51d2 100644 --- a/tests/ui/const-generics/issues/issue-73260.stderr +++ b/tests/ui/const-generics/issues/issue-73260.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-73260.rs:16:12 + --> $DIR/issue-73260.rs:15:12 | LL | let x: Arr<{usize::MAX}> = Arr {}; | ^^^^^^^^^^^^^^^^^ expected `false`, found `true` @@ -7,7 +7,7 @@ LL | let x: Arr<{usize::MAX}> = Arr {}; = note: expected constant `false` found constant `true` note: required by a bound in `Arr` - --> $DIR/issue-73260.rs:6:37 + --> $DIR/issue-73260.rs:5:37 | LL | struct Arr | --- required by a bound in this @@ -16,7 +16,7 @@ LL | Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` error[E0308]: mismatched types - --> $DIR/issue-73260.rs:16:32 + --> $DIR/issue-73260.rs:15:32 | LL | let x: Arr<{usize::MAX}> = Arr {}; | ^^^ expected `false`, found `true` @@ -24,7 +24,7 @@ LL | let x: Arr<{usize::MAX}> = Arr {}; = note: expected constant `false` found constant `true` note: required by a bound in `Arr` - --> $DIR/issue-73260.rs:6:37 + --> $DIR/issue-73260.rs:5:37 | LL | struct Arr | --- required by a bound in this diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs index 4e020327447ff..49fb10e602959 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -1,6 +1,3 @@ -// compile-flags: -Zsave-analysis -// This is also a regression test for #69415 and the above flag is needed. - use std::mem::ManuallyDrop; trait Tr1 { type As1: Copy; } diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 6f2919b6c0909..edbbf7db56578 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -1,5 +1,5 @@ error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:15:22 + --> $DIR/feature-gate-associated_type_bounds.rs:12:22 | LL | type A: Iterator; | ^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | type A: Iterator; = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:19:22 + --> $DIR/feature-gate-associated_type_bounds.rs:16:22 | LL | type B: Iterator; | ^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | type B: Iterator; = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:23:20 + --> $DIR/feature-gate-associated_type_bounds.rs:20:20 | LL | struct _St1> { | ^^^^^^^^ @@ -26,7 +26,7 @@ LL | struct _St1> { = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:30:18 + --> $DIR/feature-gate-associated_type_bounds.rs:27:18 | LL | enum _En1> { | ^^^^^^^^ @@ -35,7 +35,7 @@ LL | enum _En1> { = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:37:19 + --> $DIR/feature-gate-associated_type_bounds.rs:34:19 | LL | union _Un1> { | ^^^^^^^^ @@ -44,7 +44,7 @@ LL | union _Un1> { = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:44:37 + --> $DIR/feature-gate-associated_type_bounds.rs:41:37 | LL | type _TaWhere1 where T: Iterator = T; | ^^^^^^^^^^ @@ -53,7 +53,7 @@ LL | type _TaWhere1 where T: Iterator = T; = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:47:22 + --> $DIR/feature-gate-associated_type_bounds.rs:44:22 | LL | fn _apit(_: impl Tr1) {} | ^^^^^^^^^ @@ -62,7 +62,7 @@ LL | fn _apit(_: impl Tr1) {} = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:49:26 + --> $DIR/feature-gate-associated_type_bounds.rs:46:26 | LL | fn _apit_dyn(_: &dyn Tr1) {} | ^^^^^^^^^ @@ -71,7 +71,7 @@ LL | fn _apit_dyn(_: &dyn Tr1) {} = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:52:24 + --> $DIR/feature-gate-associated_type_bounds.rs:49:24 | LL | fn _rpit() -> impl Tr1 { S1 } | ^^^^^^^^^ @@ -80,7 +80,7 @@ LL | fn _rpit() -> impl Tr1 { S1 } = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:55:31 + --> $DIR/feature-gate-associated_type_bounds.rs:52:31 | LL | fn _rpit_dyn() -> Box> { Box::new(S1) } | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | fn _rpit_dyn() -> Box> { Box::new(S1) } = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:58:23 + --> $DIR/feature-gate-associated_type_bounds.rs:55:23 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^ @@ -98,7 +98,7 @@ LL | const _cdef: impl Tr1 = S1; = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:64:24 + --> $DIR/feature-gate-associated_type_bounds.rs:61:24 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | static _sdef: impl Tr1 = S1; = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0658]: associated type bounds are unstable - --> $DIR/feature-gate-associated_type_bounds.rs:71:21 + --> $DIR/feature-gate-associated_type_bounds.rs:68:21 | LL | let _: impl Tr1 = S1; | ^^^^^^^^^ @@ -116,25 +116,25 @@ LL | let _: impl Tr1 = S1; = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type - --> $DIR/feature-gate-associated_type_bounds.rs:58:14 + --> $DIR/feature-gate-associated_type_bounds.rs:55:14 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type - --> $DIR/feature-gate-associated_type_bounds.rs:64:15 + --> $DIR/feature-gate-associated_type_bounds.rs:61:15 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding - --> $DIR/feature-gate-associated_type_bounds.rs:71:12 + --> $DIR/feature-gate-associated_type_bounds.rs:68:12 | LL | let _: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `<::A as Iterator>::Item: Copy` is not satisfied - --> $DIR/feature-gate-associated_type_bounds.rs:15:28 + --> $DIR/feature-gate-associated_type_bounds.rs:12:28 | LL | type A: Iterator; | ^^^^ the trait `Copy` is not implemented for `<::A as Iterator>::Item` diff --git a/tests/ui/impl-trait/bound-normalization-pass.rs b/tests/ui/impl-trait/bound-normalization-pass.rs index 51718079d2c48..5613c1916c6cd 100644 --- a/tests/ui/impl-trait/bound-normalization-pass.rs +++ b/tests/ui/impl-trait/bound-normalization-pass.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 // revisions: default sa -//[sa] compile-flags: -Z save-analysis -//-^ To make this the regression test for #75962. #![feature(type_alias_impl_trait)] diff --git a/tests/ui/issues/issue-3763.rs b/tests/ui/issues/issue-3763.rs index 25ad6b319f96a..2e72d39cb322b 100644 --- a/tests/ui/issues/issue-3763.rs +++ b/tests/ui/issues/issue-3763.rs @@ -1,5 +1,4 @@ -// compile-flags: -Zsave-analysis -// Also regression test for #69416 +// Regression test for #3763 mod my_mod { pub struct MyStruct { diff --git a/tests/ui/issues/issue-3763.stderr b/tests/ui/issues/issue-3763.stderr index 6f4567546d00b..a09c8421bb7a1 100644 --- a/tests/ui/issues/issue-3763.stderr +++ b/tests/ui/issues/issue-3763.stderr @@ -1,17 +1,17 @@ error[E0616]: field `priv_field` of struct `MyStruct` is private - --> $DIR/issue-3763.rs:18:32 + --> $DIR/issue-3763.rs:17:32 | LL | let _woohoo = (&my_struct).priv_field; | ^^^^^^^^^^ private field error[E0616]: field `priv_field` of struct `MyStruct` is private - --> $DIR/issue-3763.rs:21:41 + --> $DIR/issue-3763.rs:20:41 | LL | let _woohoo = (Box::new(my_struct)).priv_field; | ^^^^^^^^^^ private field error[E0624]: associated function `happyfun` is private - --> $DIR/issue-3763.rs:24:18 + --> $DIR/issue-3763.rs:23:18 | LL | fn happyfun(&self) {} | ------------------ private associated function defined here @@ -20,7 +20,7 @@ LL | (&my_struct).happyfun(); | ^^^^^^^^ private associated function error[E0624]: associated function `happyfun` is private - --> $DIR/issue-3763.rs:26:27 + --> $DIR/issue-3763.rs:25:27 | LL | fn happyfun(&self) {} | ------------------ private associated function defined here @@ -29,7 +29,7 @@ LL | (Box::new(my_struct)).happyfun(); | ^^^^^^^^ private associated function error[E0616]: field `priv_field` of struct `MyStruct` is private - --> $DIR/issue-3763.rs:27:26 + --> $DIR/issue-3763.rs:26:26 | LL | let nope = my_struct.priv_field; | ^^^^^^^^^^ private field diff --git a/tests/ui/methods/assign-to-method.rs b/tests/ui/methods/assign-to-method.rs index 85beaee8df0a1..71e40759c848b 100644 --- a/tests/ui/methods/assign-to-method.rs +++ b/tests/ui/methods/assign-to-method.rs @@ -1,5 +1,4 @@ -// compile-flags: -Zsave-analysis -// Also regression test for #69409 +// Regression test for #69409 struct Cat { meows : usize, diff --git a/tests/ui/methods/assign-to-method.stderr b/tests/ui/methods/assign-to-method.stderr index cafe9abae045d..a1fc57cae2132 100644 --- a/tests/ui/methods/assign-to-method.stderr +++ b/tests/ui/methods/assign-to-method.stderr @@ -1,5 +1,5 @@ error[E0615]: attempted to take value of method `speak` on type `Cat` - --> $DIR/assign-to-method.rs:22:10 + --> $DIR/assign-to-method.rs:21:10 | LL | nyan.speak = || println!("meow"); | ^^^^^ method, not a field @@ -7,7 +7,7 @@ LL | nyan.speak = || println!("meow"); = help: methods are immutable and cannot be assigned to error[E0615]: attempted to take value of method `speak` on type `Cat` - --> $DIR/assign-to-method.rs:23:10 + --> $DIR/assign-to-method.rs:22:10 | LL | nyan.speak += || println!("meow"); | ^^^^^ method, not a field diff --git a/tests/ui/save-analysis/emit-notifications.polonius.stderr b/tests/ui/save-analysis/emit-notifications.polonius.stderr deleted file mode 100644 index a1a1b8c63dac3..0000000000000 --- a/tests/ui/save-analysis/emit-notifications.polonius.stderr +++ /dev/null @@ -1,2 +0,0 @@ -{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications.polonius/save-analysis/libemit_notifications.json","emit":"save-analysis"} -{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications.polonius/libemit_notifications.rlib","emit":"link"} diff --git a/tests/ui/save-analysis/emit-notifications.rs b/tests/ui/save-analysis/emit-notifications.rs deleted file mode 100644 index 9179944a6201d..0000000000000 --- a/tests/ui/save-analysis/emit-notifications.rs +++ /dev/null @@ -1,7 +0,0 @@ -// build-pass (FIXME(62277): could be check-pass?) -// compile-flags: -Zsave-analysis --json artifacts -// compile-flags: --crate-type rlib --error-format=json -// ignore-pass -// ^-- needed because otherwise, the .stderr file changes with --pass check - -pub fn foo() {} diff --git a/tests/ui/save-analysis/emit-notifications.stderr b/tests/ui/save-analysis/emit-notifications.stderr deleted file mode 100644 index e16f60f8b5faf..0000000000000 --- a/tests/ui/save-analysis/emit-notifications.stderr +++ /dev/null @@ -1,2 +0,0 @@ -{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications/save-analysis/libemit_notifications.json","emit":"save-analysis"} -{"artifact":"$TEST_BUILD_DIR/save-analysis/emit-notifications/libemit_notifications.rlib","emit":"link"} diff --git a/tests/ui/save-analysis/issue-26459.rs b/tests/ui/save-analysis/issue-26459.rs deleted file mode 100644 index 2ba05a0a47e01..0000000000000 --- a/tests/ui/save-analysis/issue-26459.rs +++ /dev/null @@ -1,8 +0,0 @@ -// compile-flags: -Zsave-analysis - -fn main() { - match 'a' { - char{ch} => true - //~^ ERROR expected struct, variant or union type, found builtin type `char` - }; -} diff --git a/tests/ui/save-analysis/issue-26459.stderr b/tests/ui/save-analysis/issue-26459.stderr deleted file mode 100644 index 9f594990c6de8..0000000000000 --- a/tests/ui/save-analysis/issue-26459.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found builtin type `char` - --> $DIR/issue-26459.rs:5:9 - | -LL | char{ch} => true - | ^^^^ not a struct, variant or union type - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/save-analysis/issue-37323.rs b/tests/ui/save-analysis/issue-37323.rs deleted file mode 100644 index 55f5c5a9581b1..0000000000000 --- a/tests/ui/save-analysis/issue-37323.rs +++ /dev/null @@ -1,20 +0,0 @@ -// check-pass -// compile-flags: -Zsave-analysis - -#![feature(rustc_attrs)] -#![allow(warnings)] - -#[derive(Debug)] -struct Point { -} - -struct NestedA<'a, 'b> { - x: &'a NestedB<'b> -} - -struct NestedB<'a> { - x: &'a i32, -} - -fn main() { -} diff --git a/tests/ui/save-analysis/issue-59134-0.rs b/tests/ui/save-analysis/issue-59134-0.rs deleted file mode 100644 index a0871ca18094e..0000000000000 --- a/tests/ui/save-analysis/issue-59134-0.rs +++ /dev/null @@ -1,12 +0,0 @@ -// compile-flags: -Zsave-analysis - -// Check that this doesn't ICE when processing associated const (field expr). - -pub fn f() { - trait Trait {} - impl dyn Trait { - const FLAG: u32 = bogus.field; //~ ERROR cannot find value `bogus` - } -} - -fn main() {} diff --git a/tests/ui/save-analysis/issue-59134-0.stderr b/tests/ui/save-analysis/issue-59134-0.stderr deleted file mode 100644 index 4e9b2e6fdeb4d..0000000000000 --- a/tests/ui/save-analysis/issue-59134-0.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0425]: cannot find value `bogus` in this scope - --> $DIR/issue-59134-0.rs:8:27 - | -LL | const FLAG: u32 = bogus.field; - | ^^^^^ not found in this scope - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/save-analysis/issue-59134-1.rs b/tests/ui/save-analysis/issue-59134-1.rs deleted file mode 100644 index 3cb629777a497..0000000000000 --- a/tests/ui/save-analysis/issue-59134-1.rs +++ /dev/null @@ -1,12 +0,0 @@ -// compile-flags: -Zsave-analysis - -// Check that this doesn't ICE when processing associated const (type). - -fn func() { - trait Trait { - type MyType; - const CONST: Self::MyType = bogus.field; //~ ERROR cannot find value `bogus` - } -} - -fn main() {} diff --git a/tests/ui/save-analysis/issue-59134-1.stderr b/tests/ui/save-analysis/issue-59134-1.stderr deleted file mode 100644 index bdc335eaac041..0000000000000 --- a/tests/ui/save-analysis/issue-59134-1.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0425]: cannot find value `bogus` in this scope - --> $DIR/issue-59134-1.rs:8:37 - | -LL | const CONST: Self::MyType = bogus.field; - | ^^^^^ not found in this scope - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/save-analysis/issue-63663.rs b/tests/ui/save-analysis/issue-63663.rs deleted file mode 100644 index 92e85884f664d..0000000000000 --- a/tests/ui/save-analysis/issue-63663.rs +++ /dev/null @@ -1,28 +0,0 @@ -// check-pass -// compile-flags: -Zsave-analysis - -pub trait Trait { - type Assoc; -} - -pub struct A; - -trait Generic {} -impl Generic for () {} - -// Don't ICE when resolving type paths in return type `impl Trait` -fn assoc_in_opaque_type_bounds() -> impl Generic {} - -// Check that this doesn't ICE when processing associated const in formal -// argument and return type of functions defined inside function/method scope. -pub fn func() { - fn _inner1(_: U::Assoc) {} - fn _inner2() -> U::Assoc { unimplemented!() } - - impl A { - fn _inner1(self, _: U::Assoc) {} - fn _inner2(self) -> U::Assoc { unimplemented!() } - } -} - -fn main() {} diff --git a/tests/ui/save-analysis/issue-64659.rs b/tests/ui/save-analysis/issue-64659.rs deleted file mode 100644 index a3d88a203778f..0000000000000 --- a/tests/ui/save-analysis/issue-64659.rs +++ /dev/null @@ -1,10 +0,0 @@ -// check-pass -// compile-flags: -Zsave-analysis - -trait Trait { type Assoc; } - -fn main() { - struct Data { - x: T::Assoc, - } -} diff --git a/tests/ui/save-analysis/issue-65411.rs b/tests/ui/save-analysis/issue-65411.rs deleted file mode 100644 index 9e58b8da5d271..0000000000000 --- a/tests/ui/save-analysis/issue-65411.rs +++ /dev/null @@ -1,15 +0,0 @@ -// check-pass -// compile-flags: -Zsave-analysis - -trait Trait { type Assoc; } -trait GenericTrait {} -struct Wrapper { b: B } - -fn func() { - // Processing associated path in impl block definition inside a function - // body does not ICE - impl GenericTrait for Wrapper {} -} - - -fn main() {} diff --git a/tests/ui/save-analysis/issue-65590.rs b/tests/ui/save-analysis/issue-65590.rs deleted file mode 100644 index 27874f8655e56..0000000000000 --- a/tests/ui/save-analysis/issue-65590.rs +++ /dev/null @@ -1,21 +0,0 @@ -// check-pass -// compile-flags: -Zsave-analysis -// edition:2018 - -// Async desugaring for return types in (associated) functions introduces a -// separate definition internally, which we need to take into account -// (or else we ICE). -trait Trait { type Assoc; } -struct Struct; - -async fn foobar() -> T::Assoc { - unimplemented!() -} - -impl Struct { - async fn foo(&self) -> T::Assoc { - unimplemented!() - } -} - -fn main() {} diff --git a/tests/ui/save-analysis/issue-68621.rs b/tests/ui/save-analysis/issue-68621.rs deleted file mode 100644 index 30479580f11a3..0000000000000 --- a/tests/ui/save-analysis/issue-68621.rs +++ /dev/null @@ -1,17 +0,0 @@ -// compile-flags: -Zsave-analysis - -#![feature(type_alias_impl_trait)] - -trait Trait {} - -trait Service { - type Future: Trait; -} - -struct Struct; - -impl Service for Struct { - type Future = impl Trait; //~ ERROR: unconstrained opaque type -} - -fn main() {} diff --git a/tests/ui/save-analysis/issue-68621.stderr b/tests/ui/save-analysis/issue-68621.stderr deleted file mode 100644 index 4452ee7915baa..0000000000000 --- a/tests/ui/save-analysis/issue-68621.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: unconstrained opaque type - --> $DIR/issue-68621.rs:14:19 - | -LL | type Future = impl Trait; - | ^^^^^^^^^^ - | - = note: `Future` must be used in combination with a concrete type within the same impl - -error: aborting due to previous error - diff --git a/tests/ui/save-analysis/issue-72267.rs b/tests/ui/save-analysis/issue-72267.rs deleted file mode 100644 index eea0a7fea0cef..0000000000000 --- a/tests/ui/save-analysis/issue-72267.rs +++ /dev/null @@ -1,7 +0,0 @@ -// compile-flags: -Z save-analysis - -fn main() { - let _: Box<(dyn ?Sized)>; - //~^ ERROR `?Trait` is not permitted in trait object types - //~| ERROR at least one trait is required for an object type -} diff --git a/tests/ui/save-analysis/issue-72267.stderr b/tests/ui/save-analysis/issue-72267.stderr deleted file mode 100644 index 76fc6c57cbc36..0000000000000 --- a/tests/ui/save-analysis/issue-72267.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: `?Trait` is not permitted in trait object types - --> $DIR/issue-72267.rs:4:21 - | -LL | let _: Box<(dyn ?Sized)>; - | ^^^^^^ - -error[E0224]: at least one trait is required for an object type - --> $DIR/issue-72267.rs:4:17 - | -LL | let _: Box<(dyn ?Sized)>; - | ^^^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/save-analysis/issue-73020.rs b/tests/ui/save-analysis/issue-73020.rs deleted file mode 100644 index 87ce0933681c5..0000000000000 --- a/tests/ui/save-analysis/issue-73020.rs +++ /dev/null @@ -1,5 +0,0 @@ -// compile-flags: -Zsave-analysis -use {self}; //~ ERROR E0431 - -fn main () { -} diff --git a/tests/ui/save-analysis/issue-73020.stderr b/tests/ui/save-analysis/issue-73020.stderr deleted file mode 100644 index 5bb3aae99975c..0000000000000 --- a/tests/ui/save-analysis/issue-73020.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0431]: `self` import can only appear in an import list with a non-empty prefix - --> $DIR/issue-73020.rs:2:6 - | -LL | use {self}; - | ^^^^ can only appear in an import list with a non-empty prefix - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0431`. diff --git a/tests/ui/save-analysis/issue-73022.rs b/tests/ui/save-analysis/issue-73022.rs deleted file mode 100644 index 9ad89a319ba3b..0000000000000 --- a/tests/ui/save-analysis/issue-73022.rs +++ /dev/null @@ -1,13 +0,0 @@ -// build-pass -// compile-flags: -Zsave-analysis -enum Enum2 { - Variant8 { _field: bool }, -} - -impl Enum2 { - fn new_variant8() -> Enum2 { - Self::Variant8 { _field: true } - } -} - -fn main() {} diff --git a/tests/ui/save-analysis/issue-89066.rs b/tests/ui/save-analysis/issue-89066.rs deleted file mode 100644 index c65e2d73fadec..0000000000000 --- a/tests/ui/save-analysis/issue-89066.rs +++ /dev/null @@ -1,28 +0,0 @@ -// compile-flags: -Zsave-analysis - -// Check that this does not ICE. -// Stolen from tests/ui/const-generics/generic_arg_infer/infer-arg-test.rs - -#![feature(generic_arg_infer)] - -struct All<'a, T, const N: usize> { - v: &'a T, -} - -struct BadInfer<_>; -//~^ ERROR expected identifier -//~| ERROR parameter `_` is never used - -fn all_fn<'a, T, const N: usize>() {} - -fn bad_infer_fn<_>() {} -//~^ ERROR expected identifier - - -fn main() { - let a: All<_, _, _>; - //~^ ERROR this struct takes 2 generic arguments but 3 generic arguments were supplied - all_fn(); - let v: [u8; _]; - let v: [u8; 10] = [0; _]; -} diff --git a/tests/ui/save-analysis/issue-89066.stderr b/tests/ui/save-analysis/issue-89066.stderr deleted file mode 100644 index 5ef04936ea244..0000000000000 --- a/tests/ui/save-analysis/issue-89066.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-89066.rs:12:17 - | -LL | struct BadInfer<_>; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-89066.rs:18:17 - | -LL | fn bad_infer_fn<_>() {} - | ^ expected identifier, found reserved identifier - -error[E0392]: parameter `_` is never used - --> $DIR/issue-89066.rs:12:17 - | -LL | struct BadInfer<_>; - | ^ unused parameter - | - = help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData` - = help: if you intended `_` to be a const parameter, use `const _: usize` instead - -error[E0107]: this struct takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/issue-89066.rs:23:10 - | -LL | let a: All<_, _, _>; - | ^^^ - help: remove this generic argument - | | - | expected 2 generic arguments - | -note: struct defined here, with 2 generic parameters: `T`, `N` - --> $DIR/issue-89066.rs:8:8 - | -LL | struct All<'a, T, const N: usize> { - | ^^^ - -------------- - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0107, E0392. -For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/alias/self-in-generics.rs b/tests/ui/traits/alias/self-in-generics.rs index 0bb6335f91e4b..dcb33b7a90af4 100644 --- a/tests/ui/traits/alias/self-in-generics.rs +++ b/tests/ui/traits/alias/self-in-generics.rs @@ -1,9 +1,5 @@ // astconv uses `FreshTy(0)` as a dummy `Self` type when instanciating trait objects. // This `FreshTy(0)` can leak into substs, causing ICEs in several places. -// Using `save-analysis` triggers type-checking `f` that would be normally skipped -// as `type_of` emitted an error. -// -// compile-flags: -Zsave-analysis #![feature(trait_alias)] diff --git a/tests/ui/traits/alias/self-in-generics.stderr b/tests/ui/traits/alias/self-in-generics.stderr index 110d60e6e9116..80af4e5aae336 100644 --- a/tests/ui/traits/alias/self-in-generics.stderr +++ b/tests/ui/traits/alias/self-in-generics.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait alias `SelfInput` cannot be made into an object - --> $DIR/self-in-generics.rs:12:19 + --> $DIR/self-in-generics.rs:8:19 | LL | pub fn f(_f: &dyn SelfInput) {} | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-63279.rs b/tests/ui/type-alias-impl-trait/issue-63279.rs index 97332e16d84a2..0e46745c65cd6 100644 --- a/tests/ui/type-alias-impl-trait/issue-63279.rs +++ b/tests/ui/type-alias-impl-trait/issue-63279.rs @@ -1,5 +1,3 @@ -// compile-flags: -Zsave-analysis - #![feature(type_alias_impl_trait)] type Closure = impl FnOnce(); diff --git a/tests/ui/type-alias-impl-trait/issue-63279.stderr b/tests/ui/type-alias-impl-trait/issue-63279.stderr index 110b8d1eea4d7..a4f6359b904c6 100644 --- a/tests/ui/type-alias-impl-trait/issue-63279.stderr +++ b/tests/ui/type-alias-impl-trait/issue-63279.stderr @@ -1,5 +1,5 @@ error[E0277]: expected a `FnOnce<()>` closure, found `()` - --> $DIR/issue-63279.rs:7:11 + --> $DIR/issue-63279.rs:5:11 | LL | fn c() -> Closure { | ^^^^^^^ expected an `FnOnce<()>` closure, found `()` @@ -8,7 +8,7 @@ LL | fn c() -> Closure { = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0277]: expected a `FnOnce<()>` closure, found `()` - --> $DIR/issue-63279.rs:9:11 + --> $DIR/issue-63279.rs:7:11 | LL | || -> Closure { || () } | ^^^^^^^ expected an `FnOnce<()>` closure, found `()` @@ -17,26 +17,26 @@ LL | || -> Closure { || () } = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` error[E0308]: mismatched types - --> $DIR/issue-63279.rs:9:21 + --> $DIR/issue-63279.rs:7:21 | LL | || -> Closure { || () } | ^^^^^ expected `()`, found closure | = note: expected unit type `()` - found closure `[closure@$DIR/issue-63279.rs:9:21: 9:23]` + found closure `[closure@$DIR/issue-63279.rs:7:21: 7:23]` help: use parentheses to call this closure | LL | || -> Closure { (|| ())() } | + +++ error[E0308]: mismatched types - --> $DIR/issue-63279.rs:9:5 + --> $DIR/issue-63279.rs:7:5 | LL | || -> Closure { || () } | ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure | = note: expected unit type `()` - found closure `[closure@$DIR/issue-63279.rs:9:5: 9:18]` + found closure `[closure@$DIR/issue-63279.rs:7:5: 7:18]` help: use parentheses to call this closure | LL | (|| -> Closure { || () })() diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index 72c22827f624b..b91cbce3727f6 100644 --- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -1,4 +1,3 @@ -// compile-flags: -Zsave-analysis // check-pass #![feature(type_alias_impl_trait, rustc_attrs)] From f0ab39b60ef631da86a5069935fdc9ba2e5d0def Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 16 Feb 2023 10:54:19 +0100 Subject: [PATCH 46/47] 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 b8bfb1b6e5cc3..8afb8e9823566 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -068161ea483b1a80a959476cb3e31e6619a72737 +639377ed737b25830ec44dc6acf93467c980316a From fd8947095678c61c5cbc70509e053621baca282d Mon Sep 17 00:00:00 2001 From: Kornel Date: Thu, 16 Feb 2023 14:22:01 +0000 Subject: [PATCH 47/47] Document that CStr::as_ptr returns a type alias Workaround for #15823 --- library/core/src/ffi/c_str.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index cd00fd0daf9e1..87f077325f8be 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -457,6 +457,10 @@ impl CStr { /// to a contiguous region of memory terminated with a 0 byte to represent /// the end of the string. /// + /// The type of the returned pointer is + /// [`*const c_char`][crate::ffi::c_char], and whether it's + /// an alias for `*const i8` or `*const u8` is platform-specific. + /// /// **WARNING** /// /// The returned pointer is read-only; writing to it (including passing it @@ -470,6 +474,7 @@ impl CStr { /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)] /// use std::ffi::CString; /// + /// // Do not do this: /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); /// unsafe { /// // `ptr` is dangling