From 04e7a10af68e6174e42e9ce4a6e81f97722a6032 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 4 Feb 2025 15:15:28 +0100 Subject: intrinsics: unify rint, roundeven, nearbyint in a single round_ties_even intrinsic --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 43d6ccfcb4a..464a6ce434d 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -126,15 +126,14 @@ fn get_simple_intrinsic<'ll>( sym::truncf64 => "llvm.trunc.f64", sym::truncf128 => "llvm.trunc.f128", - sym::rintf16 => "llvm.rint.f16", - sym::rintf32 => "llvm.rint.f32", - sym::rintf64 => "llvm.rint.f64", - sym::rintf128 => "llvm.rint.f128", - - sym::nearbyintf16 => "llvm.nearbyint.f16", - sym::nearbyintf32 => "llvm.nearbyint.f32", - sym::nearbyintf64 => "llvm.nearbyint.f64", - sym::nearbyintf128 => "llvm.nearbyint.f128", + // We could use any of `rint`, `nearbyint`, or `roundeven` + // for this -- they are all identical in semantics when + // assuming the default FP environment. + // `rint` is what we used for $forever. + sym::round_ties_even_f16 => "llvm.rint.f16", + sym::round_ties_even_f32 => "llvm.rint.f32", + sym::round_ties_even_f64 => "llvm.rint.f64", + sym::round_ties_even_f128 => "llvm.rint.f128", sym::roundf16 => "llvm.round.f16", sym::roundf32 => "llvm.round.f32", @@ -143,11 +142,6 @@ fn get_simple_intrinsic<'ll>( sym::ptr_mask => "llvm.ptrmask", - sym::roundevenf16 => "llvm.roundeven.f16", - sym::roundevenf32 => "llvm.roundeven.f32", - sym::roundevenf64 => "llvm.roundeven.f64", - sym::roundevenf128 => "llvm.roundeven.f128", - _ => return None, }; Some(cx.get_intrinsic(llvm_name)) -- cgit 1.4.1-3-g733a5 From 4cf21866e8f18449ea0c41ee1ba031c05419d94c Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 15 Feb 2025 15:18:19 -0500 Subject: Move hashes from rustc_data_structure to rustc_hashes so they can be shared with rust-analyzer --- Cargo.lock | 21 +++ compiler/rustc_abi/Cargo.toml | 1 + compiler/rustc_abi/src/layout.rs | 2 +- compiler/rustc_abi/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/Cargo.toml | 1 + compiler/rustc_codegen_llvm/src/common.rs | 3 +- compiler/rustc_codegen_ssa/Cargo.toml | 1 + .../rustc_codegen_ssa/src/debuginfo/type_names.rs | 3 +- compiler/rustc_data_structures/Cargo.toml | 1 + compiler/rustc_data_structures/src/fingerprint.rs | 5 +- compiler/rustc_data_structures/src/hashes.rs | 152 --------------------- compiler/rustc_data_structures/src/lib.rs | 1 - .../rustc_data_structures/src/stable_hasher.rs | 3 +- .../rustc_data_structures/src/tagged_ptr/tests.rs | 3 +- compiler/rustc_errors/Cargo.toml | 1 + compiler/rustc_errors/src/lib.rs | 3 +- compiler/rustc_hashes/Cargo.toml | 9 ++ compiler/rustc_hashes/src/lib.rs | 131 ++++++++++++++++++ compiler/rustc_hir/Cargo.toml | 1 + compiler/rustc_hir/src/def_path_hash_map.rs | 2 +- compiler/rustc_hir/src/definitions.rs | 3 +- compiler/rustc_hir/src/tests.rs | 2 +- compiler/rustc_middle/Cargo.toml | 1 + compiler/rustc_middle/src/mir/mono.rs | 3 +- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 3 +- compiler/rustc_query_impl/Cargo.toml | 1 + compiler/rustc_query_impl/src/plumbing.rs | 3 +- compiler/rustc_query_system/Cargo.toml | 1 + compiler/rustc_query_system/src/query/mod.rs | 2 +- compiler/rustc_serialize/Cargo.toml | 1 + compiler/rustc_serialize/src/serialize.rs | 29 ++++ compiler/rustc_session/Cargo.toml | 1 + compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_span/Cargo.toml | 1 + compiler/rustc_span/src/def_id.rs | 5 +- compiler/rustc_span/src/hygiene.rs | 3 +- compiler/rustc_span/src/lib.rs | 3 +- compiler/rustc_symbol_mangling/Cargo.toml | 1 + compiler/rustc_symbol_mangling/src/hashed.rs | 3 +- compiler/rustc_symbol_mangling/src/legacy.rs | 3 +- compiler/rustc_ty_utils/Cargo.toml | 1 + compiler/rustc_ty_utils/src/layout.rs | 2 +- compiler/rustc_type_ir/src/ty_kind.rs | 1 + .../rust-analyzer/crates/hir-def/src/data/adt.rs | 3 +- src/tools/rust-analyzer/crates/hir-def/src/lib.rs | 6 + .../rust-analyzer/crates/hir-ty/src/layout.rs | 9 +- src/tools/rust-analyzer/crates/hir-ty/src/lib.rs | 6 + tests/run-make/rustc-crates-on-stable/rmake.rs | 2 + .../ui-fulldeps/missing-rustc-driver-error.stderr | 8 ++ 51 files changed, 272 insertions(+), 187 deletions(-) delete mode 100644 compiler/rustc_data_structures/src/hashes.rs create mode 100644 compiler/rustc_hashes/Cargo.toml create mode 100644 compiler/rustc_hashes/src/lib.rs (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/Cargo.lock b/Cargo.lock index d31ef9c4b17..10492c0a4f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3317,6 +3317,7 @@ dependencies = [ "rand 0.8.5", "rand_xoshiro", "rustc_data_structures", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3544,6 +3545,7 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_llvm", @@ -3586,6 +3588,7 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_hir_pretty", "rustc_incremental", @@ -3658,6 +3661,7 @@ dependencies = [ "rustc-stable-hash", "rustc_arena", "rustc_graphviz", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3768,6 +3772,7 @@ dependencies = [ "rustc_error_codes", "rustc_error_messages", "rustc_fluent_macro", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_lexer", @@ -3840,6 +3845,13 @@ version = "0.0.0" name = "rustc_graphviz" version = "0.0.0" +[[package]] +name = "rustc_hashes" +version = "0.0.0" +dependencies = [ + "rustc-stable-hash", +] + [[package]] name = "rustc_hir" version = "0.0.0" @@ -3849,6 +3861,7 @@ dependencies = [ "rustc_arena", "rustc_ast", "rustc_data_structures", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -4169,6 +4182,7 @@ dependencies = [ "rustc_feature", "rustc_fluent_macro", "rustc_graphviz", + "rustc_hashes", "rustc_hir", "rustc_hir_pretty", "rustc_index", @@ -4405,6 +4419,7 @@ dependencies = [ "measureme", "rustc_data_structures", "rustc_errors", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_middle", @@ -4428,6 +4443,7 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_fluent_macro", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_macros", @@ -4488,6 +4504,7 @@ name = "rustc_serialize" version = "0.0.0" dependencies = [ "indexmap", + "rustc_hashes", "rustc_macros", "smallvec", "tempfile", @@ -4508,6 +4525,7 @@ dependencies = [ "rustc_feature", "rustc_fluent_macro", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_lint_defs", "rustc_macros", @@ -4549,6 +4567,7 @@ dependencies = [ "md-5", "rustc_arena", "rustc_data_structures", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -4568,6 +4587,7 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_errors", + "rustc_hashes", "rustc_hir", "rustc_middle", "rustc_session", @@ -4663,6 +4683,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_infer", diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 1013f1d3958..3d6f4a6a109 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -9,6 +9,7 @@ bitflags = "2.4.1" rand = { version = "0.8.4", default-features = false, optional = true } rand_xoshiro = { version = "0.6.0", optional = true } rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 9e33824afe2..45cd0b517f6 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Write}; use std::ops::{Bound, Deref}; use std::{cmp, iter}; -use rustc_data_structures::stable_hasher::Hash64; +use rustc_hashes::Hash64; use rustc_index::Idx; use tracing::debug; diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index d3847e5f272..dbb4bed5cdd 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -48,9 +48,9 @@ use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub}; use std::str::FromStr; use bitflags::bitflags; -use rustc_data_structures::stable_hasher::Hash64; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; +use rustc_hashes::Hash64; use rustc_index::{Idx, IndexSlice, IndexVec}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_Generic, Encodable_Generic, HashStable_Generic}; diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 94f21ac5f57..a8172270548 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -25,6 +25,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_llvm = { path = "../rustc_llvm" } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 78b3a7f8541..f17d98fa242 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -7,7 +7,8 @@ use rustc_abi::{AddressSpace, HasDataLayout}; use rustc_ast::Mutability; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash128; use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 2afc1efc1b3..963d9258be6 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -25,6 +25,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_incremental = { path = "../rustc_incremental" } diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 53953b089c6..84703a0a156 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -15,7 +15,8 @@ use std::fmt::Write; use rustc_abi::Integer; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash64; use rustc_hir::def_id::DefId; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index a8f83ca13e2..1705af1e210 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -18,6 +18,7 @@ rustc-rayon = { version = "0.5.1", features = ["indexmap"] } rustc-stable-hash = { version = "0.1.0", features = ["nightly"] } rustc_arena = { path = "../rustc_arena" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index", package = "rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index 16c66824c5b..c7c0d0ab072 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,10 +1,9 @@ use std::hash::{Hash, Hasher}; +use rustc_hashes::Hash64; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use crate::stable_hasher::{ - FromStableHash, Hash64, StableHasherHash, impl_stable_traits_for_trivial_type, -}; +use crate::stable_hasher::{FromStableHash, StableHasherHash, impl_stable_traits_for_trivial_type}; #[cfg(test)] mod tests; diff --git a/compiler/rustc_data_structures/src/hashes.rs b/compiler/rustc_data_structures/src/hashes.rs deleted file mode 100644 index b25758048bd..00000000000 --- a/compiler/rustc_data_structures/src/hashes.rs +++ /dev/null @@ -1,152 +0,0 @@ -//! rustc encodes a lot of hashes. If hashes are stored as `u64` or `u128`, a `derive(Encodable)` -//! will apply varint encoding to the hashes, which is less efficient than directly encoding the 8 -//! or 16 bytes of the hash. -//! -//! The types in this module represent 64-bit or 128-bit hashes produced by a `StableHasher`. -//! `Hash64` and `Hash128` expose some utility functions to encourage users to not extract the inner -//! hash value as an integer type and accidentally apply varint encoding to it. -//! -//! In contrast with `Fingerprint`, users of these types cannot and should not attempt to construct -//! and decompose these types into constituent pieces. The point of these types is only to -//! connect the fact that they can only be produced by a `StableHasher` to their -//! `Encode`/`Decode` impls. - -use std::fmt; -use std::ops::BitXorAssign; - -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; - -use crate::stable_hasher::{FromStableHash, StableHasherHash}; - -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] -pub struct Hash64 { - inner: u64, -} - -impl Hash64 { - pub const ZERO: Hash64 = Hash64 { inner: 0 }; - - #[inline] - pub fn new(n: u64) -> Self { - Self { inner: n } - } - - #[inline] - pub fn as_u64(self) -> u64 { - self.inner - } - - #[inline] - pub fn wrapping_add(self, other: Self) -> Self { - Self { inner: self.inner.wrapping_add(other.inner) } - } -} - -impl BitXorAssign for Hash64 { - #[inline] - fn bitxor_assign(&mut self, rhs: u64) { - self.inner ^= rhs; - } -} - -impl Encodable for Hash64 { - #[inline] - fn encode(&self, s: &mut S) { - s.emit_raw_bytes(&self.inner.to_le_bytes()); - } -} - -impl Decodable for Hash64 { - #[inline] - fn decode(d: &mut D) -> Self { - Self { inner: u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap()) } - } -} - -impl FromStableHash for Hash64 { - type Hash = StableHasherHash; - - #[inline] - fn from(StableHasherHash([_0, __1]): Self::Hash) -> Self { - Self { inner: _0 } - } -} - -impl fmt::Debug for Hash64 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.inner.fmt(f) - } -} - -impl fmt::LowerHex for Hash64 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::LowerHex::fmt(&self.inner, f) - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct Hash128 { - inner: u128, -} - -// We expect Hash128 to be well mixed. So there's no point in hashing both parts. -// -// This also allows using Hash128-containing types in UnHash-based hashmaps, which would otherwise -// debug_assert! that we're hashing more than a single u64. -impl std::hash::Hash for Hash128 { - fn hash(&self, h: &mut H) { - h.write_u64(self.truncate().as_u64()); - } -} - -impl Hash128 { - #[inline] - pub fn truncate(self) -> Hash64 { - Hash64 { inner: self.inner as u64 } - } - - #[inline] - pub fn wrapping_add(self, other: Self) -> Self { - Self { inner: self.inner.wrapping_add(other.inner) } - } - - #[inline] - pub fn as_u128(self) -> u128 { - self.inner - } -} - -impl Encodable for Hash128 { - #[inline] - fn encode(&self, s: &mut S) { - s.emit_raw_bytes(&self.inner.to_le_bytes()); - } -} - -impl Decodable for Hash128 { - #[inline] - fn decode(d: &mut D) -> Self { - Self { inner: u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap()) } - } -} - -impl FromStableHash for Hash128 { - type Hash = StableHasherHash; - - #[inline] - fn from(StableHasherHash([_0, _1]): Self::Hash) -> Self { - Self { inner: u128::from(_0) | (u128::from(_1) << 64) } - } -} - -impl fmt::Debug for Hash128 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.inner.fmt(f) - } -} - -impl fmt::LowerHex for Hash128 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::LowerHex::fmt(&self.inner, f) - } -} diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 6ef73debadd..66d3834d857 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -84,7 +84,6 @@ pub mod vec_cache; pub mod work_queue; mod atomic_ref; -mod hashes; /// This calls the passed function while ensuring it won't be inlined into the caller. #[inline(never)] diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 9cd0cc499ca..ffbe54d6206 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -10,12 +10,11 @@ use smallvec::SmallVec; #[cfg(test)] mod tests; +use rustc_hashes::{Hash64, Hash128}; pub use rustc_stable_hash::{ FromStableHash, SipHasher128Hash as StableHasherHash, StableSipHasher128 as StableHasher, }; -pub use crate::hashes::{Hash64, Hash128}; - /// Something that implements `HashStable` can be hashed in a way that is /// stable across multiple compilation sessions. /// diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index b1bdee18d6d..9c1e4cefa69 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs @@ -1,7 +1,8 @@ use std::ptr; +use rustc_hashes::Hash128; + use super::*; -use crate::hashes::Hash128; use crate::stable_hasher::{HashStable, StableHasher}; /// A tag type used in [`TaggedRef`] tests. diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index fbb6a1cc475..434f8c1c767 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -14,6 +14,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_codes = { path = "../rustc_error_codes" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8ff5dc12596..6fce1fade26 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -58,12 +58,13 @@ pub use emitter::ColorConfig; use emitter::{DynEmitter, Emitter, is_case_difference, is_different}; use rustc_data_structures::AtomicRef; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{DynSend, Lock}; pub use rustc_error_messages::{ DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, fallback_fluent_bundle, fluent_bundle, }; +use rustc_hashes::Hash128; use rustc_lint_defs::LintExpectationId; pub use rustc_lint_defs::{Applicability, listify, pluralize}; use rustc_macros::{Decodable, Encodable}; diff --git a/compiler/rustc_hashes/Cargo.toml b/compiler/rustc_hashes/Cargo.toml new file mode 100644 index 00000000000..c2bae2fe8cb --- /dev/null +++ b/compiler/rustc_hashes/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rustc_hashes" +version = "0.0.0" +edition = "2021" + +[dependencies] +# tidy-alphabetical-start +rustc-stable-hash = { version = "0.1.0" } +# tidy-alphabetical-end diff --git a/compiler/rustc_hashes/src/lib.rs b/compiler/rustc_hashes/src/lib.rs new file mode 100644 index 00000000000..3755caaaa29 --- /dev/null +++ b/compiler/rustc_hashes/src/lib.rs @@ -0,0 +1,131 @@ +//! rustc encodes a lot of hashes. If hashes are stored as `u64` or `u128`, a `derive(Encodable)` +//! will apply varint encoding to the hashes, which is less efficient than directly encoding the 8 +//! or 16 bytes of the hash. And if that hash depends on the `StableCrateHash` (which most in rustc +//! do), the varint encoding will make the number of bytes encoded fluctuate between compiler +//! versions. +//! +//! The types in this module represent 64-bit or 128-bit hashes produced by a `StableHasher`. +//! `Hash64` and `Hash128` expose some utility functions to encourage users to not extract the inner +//! hash value as an integer type and accidentally apply varint encoding to it. +//! +//! In contrast with `Fingerprint`, users of these types cannot and should not attempt to construct +//! and decompose these types into constituent pieces. The point of these types is only to +//! connect the fact that they can only be produced by a `StableHasher` to their +//! `Encode`/`Decode` impls. + +use std::fmt; +use std::ops::BitXorAssign; + +use rustc_stable_hash::{FromStableHash, SipHasher128Hash as StableHasherHash}; + +/// A `u64` but encoded with a fixed size; for hashes this encoding is more compact than `u64`. +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] +pub struct Hash64 { + inner: u64, +} + +impl Hash64 { + pub const ZERO: Hash64 = Hash64 { inner: 0 }; + + #[inline] + pub fn new(n: u64) -> Self { + Self { inner: n } + } + + #[inline] + pub fn as_u64(self) -> u64 { + self.inner + } + + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self { inner: self.inner.wrapping_add(other.inner) } + } +} + +impl BitXorAssign for Hash64 { + #[inline] + fn bitxor_assign(&mut self, rhs: u64) { + self.inner ^= rhs; + } +} + +impl FromStableHash for Hash64 { + type Hash = StableHasherHash; + + #[inline] + fn from(StableHasherHash([_0, __1]): Self::Hash) -> Self { + Self { inner: _0 } + } +} + +impl fmt::Debug for Hash64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.inner.fmt(f) + } +} + +impl fmt::LowerHex for Hash64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.inner, f) + } +} + +/// A `u128` but encoded with a fixed size; for hashes this encoding is more compact than `u128`. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] +pub struct Hash128 { + inner: u128, +} + +// We expect Hash128 to be well mixed. So there's no point in hashing both parts. +// +// This also allows using Hash128-containing types in UnHash-based hashmaps, which would otherwise +// debug_assert! that we're hashing more than a single u64. +impl std::hash::Hash for Hash128 { + fn hash(&self, h: &mut H) { + h.write_u64(self.truncate().as_u64()); + } +} + +impl Hash128 { + #[inline] + pub fn new(n: u128) -> Self { + Self { inner: n } + } + + #[inline] + pub fn truncate(self) -> Hash64 { + Hash64 { inner: self.inner as u64 } + } + + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self { inner: self.inner.wrapping_add(other.inner) } + } + + #[inline] + pub fn as_u128(self) -> u128 { + self.inner + } +} + +impl FromStableHash for Hash128 { + type Hash = StableHasherHash; + + #[inline] + fn from(StableHasherHash([_0, _1]): Self::Hash) -> Self { + Self { inner: u128::from(_0) | (u128::from(_1) << 64) } + } +} + +impl fmt::Debug for Hash128 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.inner.fmt(f) + } +} + +impl fmt::LowerHex for Hash128 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.inner, f) + } +} diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 5bfc4756ec6..b1516e53173 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -10,6 +10,7 @@ rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_hir/src/def_path_hash_map.rs b/compiler/rustc_hir/src/def_path_hash_map.rs index 9a6dee1e511..35c6e57b877 100644 --- a/compiler/rustc_hir/src/def_path_hash_map.rs +++ b/compiler/rustc_hir/src/def_path_hash_map.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::stable_hasher::Hash64; +use rustc_hashes::Hash64; use rustc_span::def_id::DefIndex; #[derive(Clone, Default)] diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index dc527240f74..08a0a5225e7 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -7,8 +7,9 @@ use std::fmt::{self, Write}; use std::hash::Hash; -use rustc_data_structures::stable_hasher::{Hash64, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::Hash64; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_span::{Symbol, kw, sym}; diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs index e0e63d183c6..0837444ffdb 100644 --- a/compiler/rustc_hir/src/tests.rs +++ b/compiler/rustc_hir/src/tests.rs @@ -1,6 +1,6 @@ #![allow(rustc::symbol_intern_string_literal)] -use rustc_data_structures::stable_hasher::Hash64; +use rustc_hashes::Hash64; use rustc_span::def_id::{DefPathHash, StableCrateId}; use rustc_span::edition::Edition; use rustc_span::{Symbol, create_session_globals_then}; diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index de722e62043..1b6a174c093 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -22,6 +22,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index d4a9aac3733..4a21b6ad237 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -6,8 +6,9 @@ use rustc_attr_parsing::InlineAttr; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::Hash128; use rustc_hir::ItemId; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE}; use rustc_index::Idx; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 2e90e5251e2..bbb8a9fa671 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -7,11 +7,11 @@ use rustc_abi::{ PointeeInfo, PointerKind, Primitive, ReprOptions, Scalar, Size, TagEncoding, TargetDataLayout, TyAbiInterface, VariantIdx, Variants, }; -use rustc_data_structures::stable_hasher::Hash64; use rustc_error_messages::DiagMessage; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, }; +use rustc_hashes::Hash64; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 94bd359f6eb..88d57498542 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -5,9 +5,10 @@ use std::{fmt, iter}; use rustc_abi::{ExternAbi, Float, Integer, IntegerType, Size}; use rustc_apfloat::Float as _; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; +use rustc_hashes::Hash128; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 8b0cc9d726b..fd1d21b6a89 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" measureme = "11" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index e95c186f6b6..f98d6421307 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -4,10 +4,11 @@ use std::num::NonZero; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_data_structures::unord::UnordMap; use rustc_errors::DiagInner; +use rustc_hashes::Hash64; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::dep_graph::{ diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index a42329b4614..d9560f3eb0f 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -13,6 +13,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 82c51193a19..7490a3f3503 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -11,9 +11,9 @@ mod caches; pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; mod config; -use rustc_data_structures::stable_hasher::Hash64; use rustc_data_structures::sync::Lock; use rustc_errors::DiagInner; +use rustc_hashes::Hash64; use rustc_hir::def::DefKind; use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 8bf98c16361..a6815c7a447 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start indexmap = "2.0.0" +rustc_hashes = { path = "../rustc_hashes" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" # tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index db8555edd0f..1eefd76f92b 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -10,6 +10,7 @@ use std::path; use std::rc::Rc; use std::sync::Arc; +use rustc_hashes::{Hash64, Hash128}; use smallvec::{Array, SmallVec}; use thin_vec::ThinVec; @@ -716,3 +717,31 @@ impl> Decodable for Arc<[T]> { vec.into() } } + +impl Encodable for Hash64 { + #[inline] + fn encode(&self, s: &mut S) { + s.emit_raw_bytes(&self.as_u64().to_le_bytes()); + } +} + +impl Encodable for Hash128 { + #[inline] + fn encode(&self, s: &mut S) { + s.emit_raw_bytes(&self.as_u128().to_le_bytes()); + } +} + +impl Decodable for Hash64 { + #[inline] + fn decode(d: &mut D) -> Self { + Self::new(u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap())) + } +} + +impl Decodable for Hash128 { + #[inline] + fn decode(d: &mut D) -> Self { + Self::new(u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap())) + } +} diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index b9c535df4bd..31892c13438 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -14,6 +14,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7d473b86ff5..85ef69ea2b7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2934,9 +2934,9 @@ pub(crate) mod dep_tracking { use rustc_abi::Align; use rustc_data_structures::fx::FxIndexMap; - use rustc_data_structures::stable_hasher::Hash64; use rustc_errors::LanguageIdentifier; use rustc_feature::UnstableFeatures; + use rustc_hashes::Hash64; use rustc_span::RealFileName; use rustc_span::edition::Edition; use rustc_target::spec::{ diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 35819f896c5..351dad3f3e4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -7,9 +7,9 @@ use std::str; use rustc_abi::Align; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::TimePassesFormat; -use rustc_data_structures::stable_hasher::Hash64; use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl}; use rustc_feature::UnstableFeatures; +use rustc_hashes::Hash64; use rustc_macros::{Decodable, Encodable}; use rustc_span::edition::Edition; use rustc_span::{RealFileName, SourceFileHashAlgorithm}; diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 781fe6a11fe..991c75cc98d 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -12,6 +12,7 @@ itoa = "1.0" md5 = { package = "md-5", version = "0.10.0" } rustc_arena = { path = "../rustc_arena" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index f61ce37131e..641bac88ad0 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -3,10 +3,9 @@ use std::hash::{BuildHasherDefault, Hash, Hasher}; use rustc_data_structures::AtomicRef; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::{ - Hash64, HashStable, StableHasher, StableOrd, ToStableHashKey, -}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; use rustc_data_structures::unhash::Unhasher; +use rustc_hashes::Hash64; use rustc_index::Idx; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 2910bcdf51d..9bf1d305e54 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -33,9 +33,10 @@ use std::sync::Arc; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, HashingControls, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; use rustc_data_structures::sync::{Lock, WorkerLocal}; use rustc_data_structures::unhash::UnhashMap; +use rustc_hashes::Hash64; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 0e146baef37..695edc956cd 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -87,9 +87,10 @@ use std::sync::Arc; use std::{fmt, iter}; use md5::{Digest, Md5}; -use rustc_data_structures::stable_hasher::{Hash64, Hash128, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock}; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::{Hash64, Hash128}; use sha1::Sha1; use sha2::Sha256; diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 1fb647cab5b..4c51c908f54 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -11,6 +11,7 @@ rustc-demangle = "0.1.21" rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_symbol_mangling/src/hashed.rs b/compiler/rustc_symbol_mangling/src/hashed.rs index 07c5f544792..e965e6a7d53 100644 --- a/compiler/rustc_symbol_mangling/src/hashed.rs +++ b/compiler/rustc_symbol_mangling/src/hashed.rs @@ -1,6 +1,7 @@ use std::fmt::Write; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash64; use rustc_hir::def_id::CrateNum; use rustc_middle::ty::{Instance, TyCtxt}; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 8ae35572d01..88754f1f15b 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -1,7 +1,8 @@ use std::fmt::{self, Write}; use std::mem::{self, discriminant}; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash64; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::bug; diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 40356e0c978..f88f8c38d50 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -11,6 +11,7 @@ rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 6a67009fe90..8429e68b600 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -9,7 +9,7 @@ use rustc_abi::{ HasDataLayout, Layout, LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, }; -use rustc_data_structures::stable_hasher::Hash64; +use rustc_hashes::Hash64; use rustc_index::bit_set::DenseBitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::bug; diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 52e4fa19cb0..83631f7fe34 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -14,6 +14,7 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use self::TyKind::*; pub use self::closure::*; use crate::inherent::*; +#[cfg(feature = "nightly")] use crate::visit::TypeVisitable; use crate::{self as ty, DebruijnIndex, Interner}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 8fc19854033..5d1834a8642 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -9,6 +9,7 @@ use hir_expand::name::Name; use intern::sym; use la_arena::Arena; use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions}; +use rustc_hashes::Hash64; use triomphe::Arc; use tt::iter::TtElement; @@ -172,7 +173,7 @@ fn parse_repr_tt(tt: &TopSubtree) -> Option { } } - Some(ReprOptions { int, align: max_align, pack: min_pack, flags, field_shuffle_seed: 0 }) + Some(ReprOptions { int, align: max_align, pack: min_pack, flags, field_shuffle_seed: Hash64::ZERO }) } impl StructData { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index c8efd904320..9c947df35e9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -18,9 +18,15 @@ extern crate ra_ap_rustc_parse_format as rustc_parse_format; #[cfg(feature = "in-rust-tree")] extern crate rustc_abi; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_hashes; + #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; +#[cfg(not(feature = "in-rust-tree"))] +extern crate ra_ap_rustc_hashes as rustc_hashes; + pub mod db; pub mod attr; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 108171586ea..b6f7c44c2ae 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -15,6 +15,7 @@ use hir_def::{ use la_arena::{Idx, RawIdx}; use rustc_abi::AddressSpace; use rustc_index::{IndexSlice, IndexVec}; +use rustc_hashes::Hash64; use triomphe::Arc; @@ -197,7 +198,7 @@ fn layout_of_simd_ty( align, max_repr_align: None, unadjusted_abi_align: align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, })) } @@ -314,7 +315,7 @@ pub fn layout_of_ty_query( size, max_repr_align: None, unadjusted_abi_align: element.align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, } } TyKind::Slice(element) => { @@ -328,7 +329,7 @@ pub fn layout_of_ty_query( size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: element.align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, } } TyKind::Str => Layout { @@ -340,7 +341,7 @@ pub fn layout_of_ty_query( size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, }, // Potentially-wide pointers. TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 55d81875a2b..daddcf0b242 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -12,6 +12,9 @@ extern crate ra_ap_rustc_index as rustc_index; #[cfg(feature = "in-rust-tree")] extern crate rustc_abi; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_hashes; + #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; @@ -21,6 +24,9 @@ extern crate rustc_pattern_analysis; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; +#[cfg(not(feature = "in-rust-tree"))] +extern crate ra_ap_rustc_hashes as rustc_hashes; + mod builder; mod chalk_db; mod chalk_ext; diff --git a/tests/run-make/rustc-crates-on-stable/rmake.rs b/tests/run-make/rustc-crates-on-stable/rmake.rs index 9fbc675cc9a..cbc1f24b8c1 100644 --- a/tests/run-make/rustc-crates-on-stable/rmake.rs +++ b/tests/run-make/rustc-crates-on-stable/rmake.rs @@ -35,6 +35,8 @@ fn main() { "rustc_abi", "-p", "rustc_parse_format", + "-p", + "rustc_hashes", ]) .run(); } diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.stderr b/tests/ui-fulldeps/missing-rustc-driver-error.stderr index d7bf27d6349..faad6264522 100644 --- a/tests/ui-fulldeps/missing-rustc-driver-error.stderr +++ b/tests/ui-fulldeps/missing-rustc-driver-error.stderr @@ -2,5 +2,13 @@ error: crate `rustc_serialize` required to be available in rlib format, but was | = help: try adding `extern crate rustc_driver;` at the top level of this crate +error: crate `rustc_hashes` required to be available in rlib format, but was not found in this form + | + = help: try adding `extern crate rustc_driver;` at the top level of this crate + +error: crate `rustc_stable_hash` required to be available in rlib format, but was not found in this form + | + = help: try adding `extern crate rustc_driver;` at the top level of this crate + error: aborting due to NUMBER previous errors -- cgit 1.4.1-3-g733a5 From 7bb5f4dd78a7a45729ab503805ba1b3065cb0de9 Mon Sep 17 00:00:00 2001 From: Jiri Bobek Date: Wed, 4 Dec 2024 12:30:42 +0100 Subject: improve cold_path() --- compiler/rustc_codegen_llvm/src/builder.rs | 48 ++++++++++++- compiler/rustc_codegen_ssa/src/mir/block.rs | 33 +++++++-- compiler/rustc_codegen_ssa/src/mir/mod.rs | 27 +++++--- compiler/rustc_codegen_ssa/src/traits/builder.rs | 14 ++++ tests/codegen/intrinsics/cold_path2.rs | 36 ++++++++++ tests/codegen/intrinsics/cold_path3.rs | 87 ++++++++++++++++++++++++ 6 files changed, 230 insertions(+), 15 deletions(-) create mode 100644 tests/codegen/intrinsics/cold_path2.rs create mode 100644 tests/codegen/intrinsics/cold_path3.rs (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 2d007416263..b63c8f8caef 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -4,7 +4,7 @@ use std::{iter, ptr}; pub(crate) mod autodiff; -use libc::{c_char, c_uint}; +use libc::{c_char, c_uint, size_t}; use rustc_abi as abi; use rustc_abi::{Align, Size, WrappingRange}; use rustc_codegen_ssa::MemFlags; @@ -32,7 +32,7 @@ use crate::abi::FnAbiLlvmExt; use crate::attributes; use crate::common::Funclet; use crate::context::{CodegenCx, SimpleCx}; -use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True}; +use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, Metadata, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; @@ -333,6 +333,50 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + fn switch_with_weights( + &mut self, + v: Self::Value, + else_llbb: Self::BasicBlock, + else_is_cold: bool, + cases: impl ExactSizeIterator, + ) { + if self.cx.sess().opts.optimize == rustc_session::config::OptLevel::No { + self.switch(v, else_llbb, cases.map(|(val, dest, _)| (val, dest))); + return; + } + + let id_str = "branch_weights"; + let id = unsafe { + llvm::LLVMMDStringInContext2(self.cx.llcx, id_str.as_ptr().cast(), id_str.len()) + }; + + // For switch instructions with 2 targets, the `llvm.expect` intrinsic is used. + // This function handles switch instructions with more than 2 targets and it needs to + // emit branch weights metadata instead of using the intrinsic. + // The values 1 and 2000 are the same as the values used by the `llvm.expect` intrinsic. + let cold_weight = unsafe { llvm::LLVMValueAsMetadata(self.cx.const_u32(1)) }; + let hot_weight = unsafe { llvm::LLVMValueAsMetadata(self.cx.const_u32(2000)) }; + let weight = + |is_cold: bool| -> &Metadata { if is_cold { cold_weight } else { hot_weight } }; + + let mut md: SmallVec<[&Metadata; 16]> = SmallVec::with_capacity(cases.len() + 2); + md.push(id); + md.push(weight(else_is_cold)); + + let switch = + unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) }; + for (on_val, dest, is_cold) in cases { + let on_val = self.const_uint_big(self.val_ty(v), on_val); + unsafe { llvm::LLVMAddCase(switch, on_val, dest) } + md.push(weight(is_cold)); + } + + unsafe { + let md_node = llvm::LLVMMDNodeInContext2(self.cx.llcx, md.as_ptr(), md.len() as size_t); + self.cx.set_metadata(switch, llvm::MD_prof, md_node); + } + } + fn invoke( &mut self, llty: &'ll Type, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 4be363ca9a2..66008a47650 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -429,11 +429,34 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let cmp = bx.icmp(IntPredicate::IntEQ, discr_value, llval); bx.cond_br(cmp, ll1, ll2); } else { - bx.switch( - discr_value, - helper.llbb_with_cleanup(self, targets.otherwise()), - target_iter.map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))), - ); + let otherwise = targets.otherwise(); + let otherwise_cold = self.cold_blocks[otherwise]; + let otherwise_unreachable = self.mir[otherwise].is_empty_unreachable(); + let cold_count = targets.iter().filter(|(_, target)| self.cold_blocks[*target]).count(); + let none_cold = cold_count == 0; + let all_cold = cold_count == targets.iter().len(); + if (none_cold && (!otherwise_cold || otherwise_unreachable)) + || (all_cold && (otherwise_cold || otherwise_unreachable)) + { + // All targets have the same weight, + // or `otherwise` is unreachable and it's the only target with a different weight. + bx.switch( + discr_value, + helper.llbb_with_cleanup(self, targets.otherwise()), + target_iter + .map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))), + ); + } else { + // Targets have different weights + bx.switch_with_weights( + discr_value, + helper.llbb_with_cleanup(self, targets.otherwise()), + otherwise_cold, + target_iter.map(|(value, target)| { + (value, helper.llbb_with_cleanup(self, target), self.cold_blocks[target]) + }), + ); + } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 3a896071bc6..ba28720afec 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -502,14 +502,25 @@ fn find_cold_blocks<'tcx>( for (bb, bb_data) in traversal::postorder(mir) { let terminator = bb_data.terminator(); - // If a BB ends with a call to a cold function, mark it as cold. - if let mir::TerminatorKind::Call { ref func, .. } = terminator.kind - && let ty::FnDef(def_id, ..) = *func.ty(local_decls, tcx).kind() - && let attrs = tcx.codegen_fn_attrs(def_id) - && attrs.flags.contains(CodegenFnAttrFlags::COLD) - { - cold_blocks[bb] = true; - continue; + match terminator.kind { + // If a BB ends with a call to a cold function, mark it as cold. + mir::TerminatorKind::Call { ref func, .. } + | mir::TerminatorKind::TailCall { ref func, .. } + if let ty::FnDef(def_id, ..) = *func.ty(local_decls, tcx).kind() + && let attrs = tcx.codegen_fn_attrs(def_id) + && attrs.flags.contains(CodegenFnAttrFlags::COLD) => + { + cold_blocks[bb] = true; + continue; + } + + // If a BB ends with an `unreachable`, also mark it as cold. + mir::TerminatorKind::Unreachable => { + cold_blocks[bb] = true; + continue; + } + + _ => {} } // If all successors of a BB are cold and there's at least one of them, mark this BB as cold diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index bbf87a59942..cbe0f2e8059 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -110,6 +110,20 @@ pub trait BuilderMethods<'a, 'tcx>: else_llbb: Self::BasicBlock, cases: impl ExactSizeIterator, ); + + // This is like `switch()`, but every case has a bool flag indicating whether it's cold. + // + // Default implementation throws away the cold flags and calls `switch()`. + fn switch_with_weights( + &mut self, + v: Self::Value, + else_llbb: Self::BasicBlock, + _else_is_cold: bool, + cases: impl ExactSizeIterator, + ) { + self.switch(v, else_llbb, cases.map(|(val, bb, _)| (val, bb))) + } + fn invoke( &mut self, llty: Self::Type, diff --git a/tests/codegen/intrinsics/cold_path2.rs b/tests/codegen/intrinsics/cold_path2.rs new file mode 100644 index 00000000000..1e7e0478f4f --- /dev/null +++ b/tests/codegen/intrinsics/cold_path2.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -O +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::cold_path; + +#[inline(never)] +#[no_mangle] +pub fn path_a() { + println!("path a"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_b() { + println!("path b"); +} + +#[no_mangle] +pub fn test(x: Option) { + if let Some(_) = x { + path_a(); + } else { + cold_path(); + path_b(); + } + + // CHECK-LABEL: @test( + // CHECK: br i1 %1, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] + // CHECK: bb1: + // CHECK: path_a + // CHECK: bb2: + // CHECK: path_b +} + +// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 1, i32 2000} diff --git a/tests/codegen/intrinsics/cold_path3.rs b/tests/codegen/intrinsics/cold_path3.rs new file mode 100644 index 00000000000..bf3347de665 --- /dev/null +++ b/tests/codegen/intrinsics/cold_path3.rs @@ -0,0 +1,87 @@ +//@ compile-flags: -O +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::cold_path; + +#[inline(never)] +#[no_mangle] +pub fn path_a() { + println!("path a"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_b() { + println!("path b"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_c() { + println!("path c"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_d() { + println!("path d"); +} + +#[no_mangle] +pub fn test(x: Option) { + match x { + Some(0) => path_a(), + Some(1) => { + cold_path(); + path_b() + } + Some(2) => path_c(), + Some(3) => { + cold_path(); + path_d() + } + _ => path_a(), + } + + // CHECK-LABEL: @test( + // CHECK: switch i32 %1, label %bb1 [ + // CHECK: i32 0, label %bb6 + // CHECK: i32 1, label %bb5 + // CHECK: i32 2, label %bb4 + // CHECK: i32 3, label %bb3 + // CHECK: ], !prof ![[NUM1:[0-9]+]] +} + +#[no_mangle] +pub fn test2(x: Option) { + match x { + Some(10) => path_a(), + Some(11) => { + cold_path(); + path_b() + } + Some(12) => { + unsafe { core::intrinsics::unreachable() }; + path_c() + } + Some(13) => { + cold_path(); + path_d() + } + _ => { + cold_path(); + path_a() + } + } + + // CHECK-LABEL: @test2( + // CHECK: switch i32 %1, label %bb1 [ + // CHECK: i32 10, label %bb5 + // CHECK: i32 11, label %bb4 + // CHECK: i32 13, label %bb3 + // CHECK: ], !prof ![[NUM2:[0-9]+]] +} + +// CHECK: ![[NUM1]] = !{!"branch_weights", i32 2000, i32 2000, i32 1, i32 2000, i32 1} +// CHECK: ![[NUM2]] = !{!"branch_weights", i32 1, i32 2000, i32 1, i32 1} -- cgit 1.4.1-3-g733a5 From fd7b4bf4e19b19ebf9b536790ec1668a3e50fe6f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 17 Feb 2025 14:17:57 +1100 Subject: Move methods from `Map` to `TyCtxt`, part 2. Continuing the work started in #136466. Every method gains a `hir_` prefix, though for the ones that already have a `par_` or `try_par_` prefix I added the `hir_` after that. --- .../src/diagnostics/conflict_errors.rs | 16 +- .../rustc_borrowck/src/diagnostics/move_errors.rs | 6 +- .../src/diagnostics/mutability_errors.rs | 23 ++- .../src/diagnostics/region_errors.rs | 3 +- .../rustc_borrowck/src/diagnostics/region_name.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_borrowck/src/universal_regions.rs | 2 +- compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs | 2 +- compiler/rustc_const_eval/src/check_consts/mod.rs | 2 +- compiler/rustc_driver_impl/src/pretty.rs | 7 +- compiler/rustc_hir/src/intravisit.rs | 6 +- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- .../src/check/compare_impl_item.rs | 5 +- compiler/rustc_hir_analysis/src/check/region.rs | 6 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_hir_analysis/src/check_unused.rs | 4 +- .../src/coherence/inherent_impls.rs | 2 +- .../src/collect/predicates_of.rs | 4 +- .../src/collect/resolve_bound_vars.rs | 4 +- .../src/collect/type_of/opaque.rs | 2 +- .../src/hir_ty_lowering/generics.rs | 2 +- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 10 +- compiler/rustc_hir_analysis/src/hir_wf_check.rs | 4 +- compiler/rustc_hir_analysis/src/lib.rs | 6 +- compiler/rustc_hir_typeck/src/_match.rs | 4 +- compiler/rustc_hir_typeck/src/callee.rs | 2 +- compiler/rustc_hir_typeck/src/check.rs | 6 +- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- compiler/rustc_hir_typeck/src/demand.rs | 4 +- compiler/rustc_hir_typeck/src/expr.rs | 6 +- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 5 +- compiler/rustc_hir_typeck/src/fallback.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 13 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 6 +- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 8 +- compiler/rustc_incremental/src/assert_dep_graph.rs | 2 +- .../rustc_incremental/src/persist/dirty_clean.rs | 2 +- compiler/rustc_interface/src/limits.rs | 8 +- compiler/rustc_interface/src/passes.rs | 18 +-- .../rustc_lint/src/for_loops_over_fallibles.rs | 2 +- compiler/rustc_lint/src/late.rs | 6 +- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 +- compiler/rustc_middle/src/hir/map.rs | 171 ++++++++++----------- compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 8 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/trait_def.rs | 2 +- compiler/rustc_mir_build/src/builder/mod.rs | 7 +- compiler/rustc_mir_build/src/check_unsafety.rs | 4 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 7 +- .../src/thir/pattern/const_to_pat.rs | 2 +- compiler/rustc_mir_transform/src/check_inline.rs | 2 +- .../rustc_mir_transform/src/ffi_unwind_calls.rs | 2 +- compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_mir_transform/src/instsimplify.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 8 +- compiler/rustc_passes/src/check_attr.rs | 6 +- compiler/rustc_passes/src/dead.rs | 4 +- compiler/rustc_passes/src/hir_id_validator.rs | 4 +- compiler/rustc_passes/src/input_stats.rs | 4 +- compiler/rustc_passes/src/lib_features.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 7 +- compiler/rustc_passes/src/loops.rs | 2 +- compiler/rustc_passes/src/stability.rs | 8 +- compiler/rustc_passes/src/upvars.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 8 +- .../src/error_reporting/infer/need_type_info.rs | 2 +- .../infer/nice_region_error/static_impl_trait.rs | 4 +- .../nice_region_error/trait_impl_difference.rs | 3 +- .../infer/nice_region_error/util.rs | 6 +- .../src/error_reporting/infer/suggest.rs | 2 +- .../src/error_reporting/traits/ambiguity.rs | 2 +- .../error_reporting/traits/fulfillment_errors.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 15 +- compiler/rustc_ty_utils/src/opaque_types.rs | 2 +- src/librustdoc/clean/types.rs | 4 +- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/core.rs | 7 +- src/librustdoc/doctest/rust.rs | 2 +- src/librustdoc/html/render/span_map.rs | 10 +- src/librustdoc/json/conversions.rs | 2 +- src/librustdoc/scrape_examples.rs | 5 +- .../clippy_lints/src/default_numeric_fallback.rs | 3 +- src/tools/clippy/clippy_lints/src/enum_clike.rs | 2 +- .../src/functions/impl_trait_in_params.rs | 4 +- .../src/functions/renamed_function_params.rs | 2 +- .../clippy_lints/src/manual_float_methods.rs | 2 +- .../src/methods/option_map_unwrap_or.rs | 3 +- .../src/needless_borrows_for_generic_args.rs | 4 +- .../clippy_lints/src/needless_pass_by_ref_mut.rs | 2 +- .../src/operators/arithmetic_side_effects.rs | 8 +- .../src/operators/numeric_arithmetic.rs | 8 +- .../clippy/clippy_lints/src/redundant_locals.rs | 2 +- src/tools/clippy/clippy_lints/src/shadow.rs | 8 +- .../clippy/clippy_lints/src/single_call_fn.rs | 3 +- .../src/transmute/missing_transmute_annotations.rs | 4 +- .../clippy_lints/src/unconditional_recursion.rs | 4 +- src/tools/clippy/clippy_lints/src/utils/author.rs | 3 +- .../utils/internal_lints/lint_without_lint_pass.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 10 +- src/tools/clippy/clippy_utils/src/mir/mod.rs | 4 +- src/tools/clippy/clippy_utils/src/ty/mod.rs | 4 +- 108 files changed, 314 insertions(+), 346 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 59c76cb7f2b..e778340cb65 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -386,8 +386,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { hir::intravisit::walk_pat(self, p); } } + let tcx = self.infcx.tcx; let hir = self.infcx.tcx.hir(); - if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) { + if let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) { let expr = body.value; let place = &self.move_data.move_paths[mpi].place; let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span); @@ -396,7 +397,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { expr: None, pat: None, parent_pat: None, - tcx: self.infcx.tcx, + tcx, }; finder.visit_expr(expr); if let Some(span) = span @@ -782,9 +783,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. - let map = self.infcx.tcx.hir(); - let body = map.body_owned_by(self.mir_def_id()); - let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] }; + let tcx = self.infcx.tcx; + let body = tcx.hir_body_owned_by(self.mir_def_id()); + let mut visitor = ConditionVisitor { tcx, spans, name, errors: vec![] }; visitor.visit_body(&body); let spans = visitor.spans; @@ -2443,7 +2444,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) { let &UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; let tcx = self.infcx.tcx; - let hir = tcx.hir(); // Get the type of the local that we are trying to borrow let local = borrowed_place.local; @@ -2522,7 +2522,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Find the first argument with a matching type, get its name let Some((_, this_name)) = - params.iter().zip(hir.body_param_names(closure.body)).find(|(param_ty, name)| { + params.iter().zip(tcx.hir_body_param_names(closure.body)).find(|(param_ty, name)| { // FIXME: also support deref for stuff like `Rc` arguments param_ty.peel_refs() == local_ty && name != &Ident::empty() }) @@ -4178,7 +4178,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); let is_closure = self.infcx.tcx.is_closure_like(did.to_def_id()); let fn_hir_id = self.infcx.tcx.local_def_id_to_hir_id(did); - let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(fn_hir_id)?; + let fn_decl = self.infcx.tcx.hir_fn_decl_by_hir_id(fn_hir_id)?; // We need to work out which arguments to highlight. We do this by looking // at the return type, where there are three cases: diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 38f22473edf..ddf6187a662 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -777,12 +777,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } let Some(pat_span) = pat_span else { return }; - let hir = self.infcx.tcx.hir(); - let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) else { return }; + let tcx = self.infcx.tcx; + let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) else { return }; let typeck_results = self.infcx.tcx.typeck(self.mir_def_id()); let mut finder = BindingFinder { typeck_results, - tcx: self.infcx.tcx, + tcx, pat_span, binding_spans, found_pat: false, diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fc782ce6424..be83e61f75d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -648,10 +648,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let Some(local_def_id) = def_id.as_local() else { return }; - let Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return }; + let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) else { return }; let mut v = SuggestIndexOperatorAlternativeVisitor { assign_span: span, @@ -749,7 +748,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` let def_id = self.body.source.def_id(); if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { @@ -856,7 +855,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { use hir::ExprKind::{AddrOf, Block, Call, MethodCall}; use hir::{BorrowKind, Expr}; - let hir_map = self.infcx.tcx.hir(); + let tcx = self.infcx.tcx; struct Finder { span: Span, } @@ -871,7 +870,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id()) + if let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) && let Block(block, _) = body.value.kind { // `span` corresponds to the expression being iterated, find the `for`-loop desugared @@ -884,17 +883,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { MethodCall(path_segment, _, _, span) => { // We have `for _ in iter.read_only_iter()`, try to // suggest `for _ in iter.mutable_iter()` instead. - let opt_suggestions = self - .infcx - .tcx + let opt_suggestions = tcx .typeck(path_segment.hir_id.owner.def_id) .type_dependent_def_id(expr.hir_id) - .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) - .map(|def_id| self.infcx.tcx.associated_items(def_id)) + .and_then(|def_id| tcx.impl_of_method(def_id)) + .map(|def_id| tcx.associated_items(def_id)) .map(|assoc_items| { assoc_items .in_definition_order() - .map(|assoc_item_def| assoc_item_def.ident(self.infcx.tcx)) + .map(|assoc_item_def| assoc_item_def.ident(tcx)) .filter(|&ident| { let original_method_ident = path_segment.ident; original_method_ident != ident @@ -942,7 +939,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let closure_span = tcx.def_span(self.mir_def_id()); let fn_call_id = tcx.parent_hir_id(closure_id); let node = tcx.hir_node(fn_call_id); - let def_id = hir.enclosing_body_owner(fn_call_id); + let def_id = tcx.hir_enclosing_body_owner(fn_call_id); let mut look_at_return = true; // If the HIR node is a function or method call gets the def ID @@ -1275,7 +1272,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }) => { let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) { BindingFinder { span: err_label_span }.visit_body(&body).break_value() } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index d3c91cbdee9..55b6367f35f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1169,8 +1169,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { #[allow(rustc::diagnostic_outside_of_impl)] fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) { - let map = self.infcx.tcx.hir(); - let body = map.body_owned_by(self.mir_def_id()); + let body = self.infcx.tcx.hir_body_owned_by(self.mir_def_id()); let expr = &body.value.peel_blocks(); let mut closure_span = None::; match expr.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index ccd13badad7..b036e6e950b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -424,7 +424,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { &self, argument_index: usize, ) -> Option<&hir::Ty<'tcx>> { - let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(self.mir_hir_id())?; + let fn_decl = self.infcx.tcx.hir_fn_decl_by_hir_id(self.mir_hir_id())?; let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?; match argument_hir_ty.kind { // This indicates a variable with no type annotation, like diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 53cf4f34ae7..22ce0fd1ea7 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -188,7 +188,7 @@ fn do_mir_borrowck<'tcx>( .iterate_to_fixpoint(tcx, body, Some("borrowck")) .into_results_cursor(body); - let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure(); + let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure(); let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data); // Compute non-lexical lifetimes. diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index eb0079a3883..4e6f82ac849 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -576,7 +576,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); - match tcx.hir().body_owner_kind(self.mir_def) { + match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { let defining_ty = tcx.type_of(self.mir_def).instantiate_identity(); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 54c5d445f66..4ffe551df09 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -87,7 +87,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = - attr::contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); + attr::contains_name(cx.tcx.hir_krate_attrs(), sym::omit_gdb_pretty_printer_section); // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create // ODR violations at link time, this section will not be emitted for rlibs since diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index bfa0a0319c3..52e000858b4 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -31,7 +31,7 @@ pub struct ConstCx<'mir, 'tcx> { impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self { let typing_env = body.typing_env(tcx); - let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local()); + let const_kind = tcx.hir_body_const_context(body.source.def_id().expect_local()); ConstCx { body, tcx, typing_env, const_kind } } diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 093ee659bb4..828a14e707c 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -164,8 +164,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { if let pprust_hir::AnnNode::Expr(expr) = node { let typeck_results = self.maybe_typeck_results.get().or_else(|| { self.tcx - .hir() - .maybe_body_owned_by(expr.hir_id.owner.def_id) + .hir_maybe_body_owned_by(expr.hir_id.owner.def_id) .map(|body_id| self.tcx.typeck_body(body_id.id())) }); @@ -317,7 +316,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { rustc_hir_analysis::check_crate(tcx); tcx.dcx().abort_if_errors(); debug!("pretty printing THIR tree"); - for did in tcx.hir().body_owners() { + for did in tcx.hir_body_owners() { let _ = writeln!(out, "{:?}:\n{}\n", did, thir_tree(tcx, did)); } out @@ -328,7 +327,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { rustc_hir_analysis::check_crate(tcx); tcx.dcx().abort_if_errors(); debug!("pretty printing THIR flat"); - for did in tcx.hir().body_owners() { + for did in tcx.hir_body_owners() { let _ = writeln!(out, "{:?}:\n{}\n", did, thir_flat(tcx, did)); } out diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 949f8daa4dc..bd96fe9ee32 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -19,7 +19,7 @@ //! - Example: Examine each expression to look for its type and do some check or other. //! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to //! `nested_filter::OnlyBodies` (and implement `maybe_tcx`), and use -//! `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your +//! `tcx.hir_visit_all_item_likes_in_crate(&mut visitor)`. Within your //! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke //! `intravisit::walk_expr()` to keep walking the subparts). //! - Pro: Visitor methods for any kind of HIR node, not just item-like things. @@ -31,7 +31,7 @@ //! impl into scope while visiting the impl-items, and then back out again. //! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to //! `nested_filter::All` (and implement `maybe_tcx`). Walk your crate with -//! `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`. +//! `tcx.hir_walk_toplevel_module(visitor)`. //! - Pro: Visitor methods for any kind of HIR node, not just item-like things. //! - Pro: Preserves nesting information //! - Con: Does not integrate well into dependency tracking. @@ -193,7 +193,7 @@ use nested_filter::NestedFilter; /// (this is why the module is called `intravisit`, to distinguish it /// from the AST's `visit` module, which acts differently). If you /// simply want to visit all items in the crate in some order, you -/// should call `tcx.hir().visit_all_item_likes_in_crate`. Otherwise, see the comment +/// should call `tcx.hir_visit_all_item_likes_in_crate`. Otherwise, see the comment /// on `visit_nested_item` for details on how to visit nested items. /// /// If you want to ensure that your code handles every variant diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index bc0fd4b705d..516ecbcfe0e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -484,7 +484,7 @@ fn best_definition_site_of_opaque<'tcx>( hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { let scope = tcx.hir().get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id)); let found = if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator) + tcx.hir_walk_toplevel_module(&mut locator) } else { match tcx.hir_node(scope) { Node::Item(it) => locator.visit_item(it), 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 84d5ec4a1e5..0dd8296e66c 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -501,7 +501,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id); - let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); + let return_span = tcx.hir_fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); let cause = ObligationCause::new( return_span, impl_m_def_id, @@ -1033,8 +1033,7 @@ fn report_trait_method_mismatch<'tcx>( // argument pattern and type. let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let span = tcx - .hir() - .body_param_names(body) + .hir_body_param_names(body) .zip(sig.decl.inputs.iter()) .map(|(param, ty)| param.span.to(ty.span)) .next() diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 88dd40ba289..255f5fee52a 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -844,7 +844,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { fn visit_body(&mut self, body: &hir::Body<'tcx>) { let body_id = body.id(); - let owner_id = self.tcx.hir().body_owner_def_id(body_id); + let owner_id = self.tcx.hir_body_owner_def_id(body_id); debug!( "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})", @@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { ); self.enter_body(body.value.hir_id, |this| { - if this.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() { + if this.tcx.hir_body_owner_kind(owner_id).is_fn_or_closure() { // The arguments and `self` are parented to the fn. this.cx.var_parent = this.cx.parent.take(); for param in body.params { @@ -924,7 +924,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id.expect_local()) { let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 01b4a5649f1..edfa897860b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1710,7 +1710,7 @@ fn check_sized_if_body<'tcx>( maybe_span: Option, ) { let tcx = wfcx.tcx(); - if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) { + if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let span = maybe_span.unwrap_or(body.value.span); wfcx.register_bound( diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 68b7b44c36d..750c09887a1 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -13,11 +13,11 @@ pub(crate) fn provide(providers: &mut Providers) { fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { let mut used_trait_imports = UnordSet::::default(); - // FIXME: Use `tcx.hir().par_body_owners()` when we implement creating `DefId`s + // FIXME: Use `tcx.hir_par_body_owners()` when we implement creating `DefId`s // for anon constants during their parents' typeck. // Doing so at current will produce queries cycle errors because it may typeck // on anon constants directly. - for item_def_id in tcx.hir().body_owners() { + for item_def_id in tcx.hir_body_owners() { let imports = tcx.used_trait_imports(item_def_id); debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports); used_trait_imports.extend_unord(imports.items().copied()); diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 1805e2438af..c9a9180c5c9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -113,7 +113,7 @@ impl<'tcx> InherentCollect<'tcx> { ty: Ty<'tcx>, ) -> Result<(), ErrorGuaranteed> { let items = self.tcx.associated_item_def_ids(impl_def_id); - if !self.tcx.hir().rustc_coherence_is_core() { + if !self.tcx.hir_rustc_coherence_is_core() { if self.tcx.features().rustc_attrs() { for &impl_item in items { if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 70e7451a5fb..7b1fff157b5 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -435,7 +435,7 @@ fn const_evaluatable_predicates_of<'tcx>( self_ty.instantiate_identity().visit_with(&mut collector); } - if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) { + if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) { debug!("visit fn sig"); let fn_sig = tcx.fn_sig(def_id); let fn_sig = fn_sig.instantiate_identity(); @@ -825,7 +825,7 @@ pub(super) fn type_param_predicates<'tcx>( // `where T: Foo`. let param_id = tcx.local_def_id_to_hir_id(def_id); - let param_owner = tcx.hir().ty_param_owner(def_id); + let param_owner = tcx.hir_ty_param_owner(def_id); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 5a8a2f1fe28..759c981a8f7 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1340,7 +1340,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }; def = ResolvedArg::Error(guar); } else if let Some(body_id) = outermost_body { - let fn_id = self.tcx.hir().body_owner(body_id); + let fn_id = self.tcx.hir_body_owner(body_id); match self.tcx.hir_node(fn_id) { Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn { .. }, .. }) | Node::TraitItem(hir::TraitItem { @@ -2265,7 +2265,7 @@ fn is_late_bound_map( tcx: TyCtxt<'_>, owner_id: hir::OwnerId, ) -> Option<&FxIndexSet> { - let sig = tcx.hir().fn_sig_by_hir_id(owner_id.into())?; + let sig = tcx.hir_fn_sig_by_hir_id(owner_id.into())?; let generics = tcx.hir_get_generics(owner_id.def_id)?; let mut late_bound = FxIndexSet::default(); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 88d4acbdd8d..0c36888f363 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -89,7 +89,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local debug!(?scope); if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator); + tcx.hir_walk_toplevel_module(&mut locator); } else { trace!("scope={:#?}", tcx.hir_node(scope)); match tcx.hir_node(scope) { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index cc28b8780c6..17de64db629 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -70,7 +70,7 @@ fn generic_arg_mismatch_err( } Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { - let param_name = tcx.hir().ty_param_name(param_local_id); + let param_name = tcx.hir_ty_param_name(param_local_id); let param_type = tcx.type_of(param.def_id).instantiate_identity(); if param_type.is_suggestable(tcx, false) { err.span_suggestion( diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 7dce8b9b60f..ec8343bb2bf 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -217,7 +217,7 @@ impl AssocItemQSelf { fn to_string(&self, tcx: TyCtxt<'_>) -> String { match *self { Self::Trait(def_id) => tcx.def_path_str(def_id), - Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(), + Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(), Self::SelfTyAlias => kw::SelfUpper.to_string(), } } @@ -342,8 +342,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } rbv::ResolvedArg::EarlyBound(def_id) => { - let name = tcx.hir().ty_param_name(def_id); - let item_def_id = tcx.hir().ty_param_owner(def_id); + let name = tcx.hir_ty_param_name(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name }) @@ -2070,10 +2070,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ty::new_bound(tcx, debruijn, br) } Some(rbv::ResolvedArg::EarlyBound(def_id)) => { - let item_def_id = tcx.hir().ty_param_owner(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)) + Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id)) } Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar), arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index f5abcd23440..0b1be8e4f7a 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -22,8 +22,6 @@ fn diagnostic_hir_wf_check<'tcx>( tcx: TyCtxt<'tcx>, (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc), ) -> Option> { - let hir = tcx.hir(); - let def_id = match loc { WellFormedLoc::Ty(def_id) => def_id, WellFormedLoc::Param { function, param_idx: _ } => function, @@ -187,7 +185,7 @@ fn diagnostic_hir_wf_check<'tcx>( ref node => bug!("Unexpected node {:?}", node), }, WellFormedLoc::Param { function: _, param_idx } => { - let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap(); + let fn_decl = tcx.hir_fn_decl_by_hir_id(hir_id).unwrap(); // Get return type if param_idx as usize == fn_decl.inputs.len() { match fn_decl.output { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 886360dfb6c..66d7c9377ed 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -183,7 +183,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // what we are intending to discard, to help future type-based refactoring. type R = Result<(), ErrorGuaranteed>; - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { let _: R = tcx.ensure_ok().check_mod_type_wf(module); }); @@ -208,7 +208,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // Make sure we evaluate all static and (non-associated) const items, even if unused. // If any of these fail to evaluate, we do not want this crate to pass compilation. - tcx.hir().par_body_owners(|item_def_id| { + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id), @@ -226,7 +226,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // for anon constants during their parents' typeck. // Typeck all body owners in parallel will produce queries // cycle errors because it may typeck on anon constants directly. - tcx.hir().par_body_owners(|item_def_id| { + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); if !matches!(def_kind, DefKind::AnonConst) { tcx.ensure_ok().typeck(item_def_id); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 3d40c5ee804..38319862334 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -213,10 +213,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arm_ty: Ty<'tcx>, prior_arm: Option<(Option, Ty<'tcx>, Span)>, ) { - let hir = self.tcx.hir(); - // First, check that we're actually in the tail of a function. - let Some(body) = hir.maybe_body_owned_by(self.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(self.body_id) else { return; }; let hir::ExprKind::Block(block, _) = body.value.kind else { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index bccde782264..49ea2181b07 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -860,7 +860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - let host = match self.tcx.hir().body_const_context(self.body_id) { + let host = match self.tcx.hir_body_const_context(self.body_id) { Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => { ty::BoundConstness::Const } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 6fb5f6af091..dabae7b1d09 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -35,12 +35,8 @@ pub(super) fn check_fn<'a, 'tcx>( params_can_be_unsized: bool, ) -> Option> { let fn_id = fcx.tcx.local_def_id_to_hir_id(fn_def_id); - let tcx = fcx.tcx; - let hir = tcx.hir(); - let declared_ret_ty = fn_sig.output(); - let ret_ty = fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars( declared_ret_ty, @@ -69,7 +65,7 @@ pub(super) fn check_fn<'a, 'tcx>( }); // Add formal parameters. - let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); + let inputs_hir = tcx.hir_fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); let inputs_fn = fn_sig.inputs().iter().copied(); for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() { // We checked the root's signature during wfcheck, but not the child. diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index c8433d0cb5b..cf11bccae0a 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1943,7 +1943,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if due_to_block && let Some(expr) = expression && let Some(parent_fn_decl) = - fcx.tcx.hir().fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) + fcx.tcx.hir_fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) { fcx.suggest_missing_break_or_return_expr( &mut err, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 2f7f9148023..4dc736f72cf 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -293,8 +293,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, source: TypeMismatchSource<'tcx>, ) -> bool { - let hir = self.tcx.hir(); - let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; }; @@ -334,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() }; - let body = hir.body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_id); expr_finder.visit_expr(body.value); // Replaces all of the variables in the given type with a fresh inference variable. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a41ad94f95e..b46d7c49063 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1150,13 +1150,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We are inside a function body, so reporting "return statement // outside of function body" needs an explanation. - let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id); + let encl_body_owner_id = self.tcx.hir_enclosing_body_owner(expr.hir_id); // If this didn't hold, we would not have to report an error in // the first place. assert_ne!(encl_item_id.def_id, encl_body_owner_id); - let encl_body = self.tcx.hir().body_owned_by(encl_body_owner_id); + let encl_body = self.tcx.hir_body_owned_by(encl_body_owner_id); err.encl_body_span = Some(encl_body.value.span); err.encl_fn_span = Some(*encl_fn_span); @@ -3229,7 +3229,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => return, }; let param_span = self.tcx.hir().span(param_hir_id); - let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local()); + let param_name = self.tcx.hir_ty_param_name(param_def_id.expect_local()); err.span_label(param_span, format!("type parameter '{param_name}' declared here")); } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 860e619be71..9b85b2aeec6 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1001,11 +1001,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let closure_def_id = closure_expr.def_id; // For purposes of this function, coroutine and closures are equivalent. let body_owner_is_closure = matches!( - tcx.hir().body_owner_kind(self.cx.body_owner_def_id()), + tcx.hir_body_owner_kind(self.cx.body_owner_def_id()), hir::BodyOwnerKind::Closure ); - // If we have a nested closure, we want to include the fake reads present in the nested closure. + // If we have a nested closure, we want to include the fake reads present in the nested + // closure. if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) { for (fake_read, cause, hir_id) in fake_reads.iter() { match fake_read.base { diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index ce6f7420e5b..e051fc7ac6c 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -573,7 +573,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { coercions: &VecGraph, ) -> errors::SuggestAnnotations { let body = - self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner"); + self.tcx.hir_maybe_body_owned_by(self.body_id).expect("body id must have an owner"); // For each diverging var, look through the HIR for a place to give it // a type annotation. We do this per var because we only really need one // suggestion to influence a var to be `()`. @@ -764,7 +764,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, body_id: LocalDefId, ) -> UnordMap { - let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = fcx.tcx.hir_maybe_body_owned_by(body_id).expect("body id must have an owner"); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index c0af5ea7bbf..7ca44d23e3e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -100,7 +100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut deferred_asm_checks = self.deferred_asm_checks.borrow_mut(); debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { - let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id); + let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id); let get_operand_ty = |expr| { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index b77e6de52ff..42236ac6d80 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -290,7 +290,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { _: Ident, ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { let tcx = self.tcx; - let item_def_id = tcx.hir().ty_param_owner(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; // HACK(eddyb) should get the original `Span`. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 05c76b3c568..347a6557c2a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1811,7 +1811,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead" ), ); - let owner = self.tcx.hir().enclosing_body_owner(expr.hir_id); + let owner = self.tcx.hir_enclosing_body_owner(expr.hir_id); if let ty::Param(param) = expected_ty.kind() && let Some(generics) = self.tcx.hir_get_generics(owner) { @@ -2094,9 +2094,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'tcx>, expected: Ty<'tcx>, ) -> bool { - let hir = self.tcx.hir(); + let tcx = self.tcx; + let hir = tcx.hir(); let enclosing_scope = - hir.get_enclosing_scope(expr.hir_id).map(|hir_id| self.tcx.hir_node(hir_id)); + hir.get_enclosing_scope(expr.hir_id).map(|hir_id| tcx.hir_node(hir_id)); // Get tail expr of the enclosing block or body let tail_expr = if let Some(Node::Block(hir::Block { expr, .. })) = enclosing_scope @@ -2104,8 +2105,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { *expr } else { - let body_def_id = hir.enclosing_body_owner(expr.hir_id); - let body = hir.body_owned_by(body_def_id); + let body_def_id = tcx.hir_enclosing_body_owner(expr.hir_id); + let body = tcx.hir_body_owned_by(body_def_id); // Get tail expr of the body match body.value.kind { @@ -2147,7 +2148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ("consider returning a value here", format!("`{expected}` value")) }; - let src_map = self.tcx.sess.source_map(); + let src_map = tcx.sess.source_map(); let suggestion = if src_map.is_multiline(expr.span) { let indentation = src_map.indentation_before(span).unwrap_or_else(String::new); format!("\n{indentation}/* {suggestion} */") diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1ca8b59db22..780ab8c1833 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::def::Res::Local(recv_id) = path.res && let Some(segment) = path.segments.first() { - let body = self.tcx.hir().body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_id); if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) { let mut let_visitor = LetVisitor { @@ -2599,7 +2599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { seg1.ident.span, StashKey::CallAssocMethod, |err| { - let body = self.tcx.hir().body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_id); struct LetVisitor { ident_name: Symbol, } @@ -3336,7 +3336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let accessible_sugg = sugg(accessible_candidates, true); let inaccessible_sugg = sugg(inaccessible_candidates, false); - let (module, _, _) = self.tcx.hir().get_module(scope); + let (module, _, _) = self.tcx.hir_get_module(scope); let span = module.spans.inject_use_span; handle_candidates(accessible_sugg, inaccessible_sugg, span); } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 871d08137b3..762d04fdedd 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -196,7 +196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let args = self.resolve_vars_if_possible(args); let closure_def_id = closure_def_id.expect_local(); - assert_eq!(self.tcx.hir().body_owner_def_id(body.id()), closure_def_id); + assert_eq!(self.tcx.hir_body_owner_def_id(body.id()), closure_def_id); let mut delegate = InferBorrowKind { closure_def_id, capture_information: Default::default(), diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index dbcf9915790..8c50cc59c1d 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, body: &'tcx hir::Body<'tcx>, ) -> &'tcx ty::TypeckResults<'tcx> { - let item_def_id = self.tcx.hir().body_owner_def_id(body.id()); + let item_def_id = self.tcx.hir_body_owner_def_id(body.id()); // This attribute causes us to dump some writeback information // in the form of errors, which is used for unit tests. @@ -49,7 +49,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.visit_node_id(param.pat.span, param.hir_id); } // Type only exists for constants and statics, not functions. - match self.tcx.hir().body_owner_kind(item_def_id) { + match self.tcx.hir_body_owner_kind(item_def_id) { hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) => { let item_hir_id = self.tcx.local_def_id_to_hir_id(item_def_id); wbcx.visit_node_id(body.value.span, item_hir_id); @@ -790,7 +790,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { self.fcx .err_ctxt() .emit_inference_failure_err( - self.fcx.tcx.hir().body_owner_def_id(self.body.id()), + self.fcx.tcx.hir_body_owner_def_id(self.body.id()), self.span.to_span(self.fcx.tcx), p.into(), TypeAnnotationNeeded::E0282, @@ -814,7 +814,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { // expect that types that show up in the typeck are fully // normalized. let mut value = if self.should_normalize { - let body_id = tcx.hir().body_owner_def_id(self.body.id()); + let body_id = tcx.hir_body_owner_def_id(self.body.id()); let cause = ObligationCause::misc(self.span.to_span(tcx), body_id); let at = self.fcx.at(&cause, self.fcx.param_env); let universes = vec![None; outer_exclusive_binder(value).as_usize()]; diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index c2f9ebc5262..d4407559202 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -76,7 +76,7 @@ pub(crate) fn assert_dep_graph(tcx: TyCtxt<'_>) { let mut visitor = IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] }; visitor.process_attrs(CRATE_DEF_ID); - tcx.hir().visit_all_item_likes_in_crate(&mut visitor); + tcx.hir_visit_all_item_likes_in_crate(&mut visitor); (visitor.if_this_changed, visitor.then_this_would_need) }; diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index a95599e7a86..118a6fed036 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -166,7 +166,7 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { } let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] }; - tcx.hir().walk_attributes(&mut all_attrs); + tcx.hir_walk_attributes(&mut all_attrs); // Note that we cannot use the existing "unused attribute"-infrastructure // here, since that is running before codegen. This is also the reason why diff --git a/compiler/rustc_interface/src/limits.rs b/compiler/rustc_interface/src/limits.rs index 3de513797e3..8f01edec09f 100644 --- a/compiler/rustc_interface/src/limits.rs +++ b/compiler/rustc_interface/src/limits.rs @@ -20,21 +20,21 @@ use crate::errors::LimitInvalid; pub(crate) fn provide(providers: &mut Providers) { providers.limits = |tcx, ()| Limits { - recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess), + recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess), move_size_limit: get_limit( - tcx.hir().krate_attrs(), + tcx.hir_krate_attrs(), tcx.sess, sym::move_size_limit, Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0)), ), type_length_limit: get_limit( - tcx.hir().krate_attrs(), + tcx.hir_krate_attrs(), tcx.sess, sym::type_length_limit, Limit::new(2usize.pow(24)), ), pattern_complexity_limit: get_limit( - tcx.hir().krate_attrs(), + tcx.hir_krate_attrs(), tcx.sess, sym::pattern_complexity_limit, Limit::unlimited(), diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d7d183e17ed..d70d9d344b9 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -846,7 +846,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { CStore::from_tcx(tcx).report_unused_deps(tcx); }, { - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_loops(module); tcx.ensure_ok().check_mod_attrs(module); tcx.ensure_ok().check_mod_naked_functions(module); @@ -871,7 +871,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { rustc_hir_analysis::check_crate(tcx); sess.time("MIR_coroutine_by_move_body", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) { tcx.ensure_done().coroutine_by_move_body_def_id(def_id); } @@ -885,7 +885,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.untracked().definitions.freeze(); sess.time("MIR_borrow_checking", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { // Run unsafety check because it's responsible for stealing and // deallocating THIR. tcx.ensure_ok().check_unsafety(def_id); @@ -893,21 +893,21 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { }); }); sess.time("MIR_effect_checking", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { tcx.ensure_ok().has_ffi_unwind_calls(def_id); // If we need to codegen, ensure that we emit all errors from // `mir_drops_elaborated_and_const_checked` now, to avoid discovering // them later during codegen. if tcx.sess.opts.output_types.should_codegen() - || tcx.hir().body_const_context(def_id).is_some() + || tcx.hir_body_const_context(def_id).is_some() { tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id); } }); }); sess.time("coroutine_obligations", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { if tcx.is_coroutine(def_id.to_def_id()) { tcx.ensure_ok().mir_coroutine_witnesses(def_id); tcx.ensure_ok().check_coroutine_obligations( @@ -931,7 +931,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // that requires the optimized/ctfe MIR, coroutine bodies, or evaluating consts. if tcx.sess.opts.unstable_opts.validate_mir { sess.time("ensuring_final_MIR_is_computable", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { tcx.instance_mir(ty::InstanceKind::Item(def_id.into())); }); }); @@ -967,7 +967,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { tcx.ensure_ok().check_private_in_public(()); }, { - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_deathness(module) }); }, @@ -983,7 +983,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { }, { sess.time("privacy_checking_modules", || { - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_privacy(module); }); }); diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index 59390b7e420..757fc1f58bd 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -166,7 +166,7 @@ fn suggest_question_mark<'tcx>( let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env()); let ocx = ObligationCtxt::new(&infcx); - let body_def_id = cx.tcx.hir().body_owner_def_id(body_id); + let body_def_id = cx.tcx.hir_body_owner_def_id(body_id); let cause = ObligationCause::new(span, body_def_id, rustc_infer::traits::ObligationCauseCode::Misc); diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index f17570e4a81..d22515d62d6 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -379,7 +379,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( ) { let mut cx = LateContextAndPass { context, pass }; - let (module, _span, hir_id) = tcx.hir().get_module(module_def_id); + let (module, _span, hir_id) = tcx.hir_get_module(module_def_id); cx.with_lint_attrs(hir_id, |cx| { // There is no module lint that will have the crate itself as an item, so check it here. @@ -445,7 +445,7 @@ fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>( // Since the root module isn't visited as an item (because it isn't an // item), warn for it here. lint_callback!(cx, check_crate,); - tcx.hir().walk_toplevel_module(cx); + tcx.hir_walk_toplevel_module(cx); lint_callback!(cx, check_crate_post,); }) } @@ -462,7 +462,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { || { tcx.sess.time("module_lints", || { // Run per-module lints - tcx.hir().par_for_each_module(|module| tcx.ensure_ok().lint_mod(module)); + tcx.par_hir_for_each_module(|module| tcx.ensure_ok().lint_mod(module)); }); }, ); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 7e13205bbf1..4ede9b44087 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -144,7 +144,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { let mut visitor = LintLevelMaximum { tcx, dont_need_to_run }; visitor.process_opts(); - tcx.hir().walk_attributes(&mut visitor); + tcx.hir_walk_attributes(&mut visitor); visitor.dont_need_to_run } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 1ac2f6e81e5..88a88847e6b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -696,7 +696,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers()); let root = stat!("final", || { - let attrs = tcx.hir().krate_attrs(); + let attrs = tcx.hir_krate_attrs(); self.lazy(CrateRoot { header: CrateHeader { name: tcx.crate_name(LOCAL_CRATE), @@ -1763,7 +1763,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); - let body = tcx.hir().maybe_body_owned_by(def_id); + let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(self.tcx, &body, def_id); record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index b44f14315d7..3436c2f372f 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -229,64 +229,62 @@ impl<'tcx> TyCtxt<'tcx> { pub fn hir_body(self, id: BodyId) -> &'tcx Body<'tcx> { self.hir_owner_nodes(id.hir_id.owner).bodies[&id.hir_id.local_id] } -} -impl<'hir> Map<'hir> { #[track_caller] - pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> { - self.tcx.hir_node(hir_id).fn_decl() + pub fn hir_fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'tcx FnDecl<'tcx>> { + self.hir_node(hir_id).fn_decl() } #[track_caller] - pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> { - self.tcx.hir_node(hir_id).fn_sig() + pub fn hir_fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'tcx FnSig<'tcx>> { + self.hir_node(hir_id).fn_sig() } #[track_caller] - pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { - for (_, node) in self.parent_iter(hir_id) { + pub fn hir_enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { + for (_, node) in self.hir().parent_iter(hir_id) { if let Some((def_id, _)) = node.associated_body() { return def_id; } } - bug!("no `enclosing_body_owner` for hir_id `{}`", hir_id); + bug!("no `hir_enclosing_body_owner` for hir_id `{}`", hir_id); } /// Returns the `HirId` that corresponds to the definition of /// which this is the body of, i.e., a `fn`, `const` or `static` /// item (possibly associated), a closure, or a `hir::AnonConst`. - pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId { - let parent = self.tcx.parent_hir_id(hir_id); - assert_eq!(self.tcx.hir_node(parent).body_id().unwrap().hir_id, hir_id, "{hir_id:?}"); + pub fn hir_body_owner(self, BodyId { hir_id }: BodyId) -> HirId { + let parent = self.parent_hir_id(hir_id); + assert_eq!(self.hir_node(parent).body_id().unwrap().hir_id, hir_id, "{hir_id:?}"); parent } - pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { - self.tcx.parent_hir_node(hir_id).associated_body().unwrap().0 + pub fn hir_body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { + self.parent_hir_node(hir_id).associated_body().unwrap().0 } /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. - pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<&'hir Body<'hir>> { - Some(self.tcx.hir_body(self.tcx.hir_node_by_def_id(id).body_id()?)) + pub fn hir_maybe_body_owned_by(self, id: LocalDefId) -> Option<&'tcx Body<'tcx>> { + Some(self.hir_body(self.hir_node_by_def_id(id).body_id()?)) } /// Given a body owner's id, returns the `BodyId` associated with it. #[track_caller] - pub fn body_owned_by(self, id: LocalDefId) -> &'hir Body<'hir> { - self.maybe_body_owned_by(id).unwrap_or_else(|| { - let hir_id = self.tcx.local_def_id_to_hir_id(id); + pub fn hir_body_owned_by(self, id: LocalDefId) -> &'tcx Body<'tcx> { + self.hir_maybe_body_owned_by(id).unwrap_or_else(|| { + let hir_id = self.local_def_id_to_hir_id(id); span_bug!( - self.span(hir_id), + self.hir().span(hir_id), "body_owned_by: {} has no associated body", - self.node_to_string(hir_id) + self.hir().node_to_string(hir_id) ); }) } - pub fn body_param_names(self, id: BodyId) -> impl Iterator + 'hir { - self.tcx.hir_body(id).params.iter().map(|arg| match arg.pat.kind { + pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator + 'tcx { + self.hir_body(id).params.iter().map(|arg| match arg.pat.kind { PatKind::Binding(_, _, ident, _) => ident, _ => Ident::empty(), }) @@ -295,9 +293,9 @@ impl<'hir> Map<'hir> { /// Returns the `BodyOwnerKind` of this `LocalDefId`. /// /// Panics if `LocalDefId` does not have an associated body. - pub fn body_owner_kind(self, def_id: impl Into) -> BodyOwnerKind { + pub fn hir_body_owner_kind(self, def_id: impl Into) -> BodyOwnerKind { let def_id = def_id.into(); - match self.tcx.def_kind(def_id) { + match self.def_kind(def_id) { DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { BodyOwnerKind::Const { inline: false } } @@ -318,17 +316,17 @@ impl<'hir> Map<'hir> { /// This should only be used for determining the context of a body, a return /// value of `Some` does not always suggest that the owner of the body is `const`, /// just that it has to be checked as if it were. - pub fn body_const_context(self, def_id: impl Into) -> Option { + pub fn hir_body_const_context(self, def_id: impl Into) -> Option { let def_id = def_id.into(); - let ccx = match self.body_owner_kind(def_id) { + let ccx = match self.hir_body_owner_kind(def_id) { BodyOwnerKind::Const { inline } => ConstContext::Const { inline }, BodyOwnerKind::Static(mutability) => ConstContext::Static(mutability), - BodyOwnerKind::Fn if self.tcx.is_constructor(def_id) => return None, - BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn(def_id) => { + BodyOwnerKind::Fn if self.is_constructor(def_id) => return None, + BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.is_const_fn(def_id) => { ConstContext::ConstFn } - BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id) => ConstContext::ConstFn, + BodyOwnerKind::Fn if self.is_const_default_method(def_id) => ConstContext::ConstFn, BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None, }; @@ -339,55 +337,55 @@ impl<'hir> Map<'hir> { /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir().krate().body_ids.iter()`. #[inline] - pub fn body_owners(self) -> impl Iterator + 'hir { - self.tcx.hir_crate_items(()).body_owners.iter().copied() + pub fn hir_body_owners(self) -> impl Iterator + 'tcx { + self.hir_crate_items(()).body_owners.iter().copied() } #[inline] - pub fn par_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) { - par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id)); + pub fn par_hir_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) { + par_for_each_in(&self.hir_crate_items(()).body_owners[..], |&def_id| f(def_id)); } - pub fn ty_param_owner(self, def_id: LocalDefId) -> LocalDefId { - let def_kind = self.tcx.def_kind(def_id); + pub fn hir_ty_param_owner(self, def_id: LocalDefId) -> LocalDefId { + let def_kind = self.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => def_id, DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { - self.tcx.local_parent(def_id) + self.local_parent(def_id) } _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind), } } - pub fn ty_param_name(self, def_id: LocalDefId) -> Symbol { - let def_kind = self.tcx.def_kind(def_id); + pub fn hir_ty_param_name(self, def_id: LocalDefId) -> Symbol { + let def_kind = self.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper, DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { - self.tcx.item_name(def_id.to_def_id()) + self.item_name(def_id.to_def_id()) } _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind), } } - pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { - self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) + pub fn hir_trait_impls(self, trait_did: DefId) -> &'tcx [LocalDefId] { + self.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. - pub fn krate_attrs(self) -> &'hir [Attribute] { - self.attrs(CRATE_HIR_ID) + pub fn hir_krate_attrs(self) -> &'tcx [Attribute] { + self.hir().attrs(CRATE_HIR_ID) } - pub fn rustc_coherence_is_core(self) -> bool { - self.krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + pub fn hir_rustc_coherence_is_core(self) -> bool { + self.hir_krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) } - pub fn get_module(self, module: LocalModDefId) -> (&'hir Mod<'hir>, Span, HirId) { + pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { let hir_id = HirId::make_owner(module.to_local_def_id()); - match self.tcx.hir_owner_node(hir_id.owner) { + match self.hir_owner_node(hir_id.owner) { OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. }) => (m, span, hir_id), OwnerNode::Crate(item) => (item, item.spans.inner_span, hir_id), node => panic!("not a module: {node:?}"), @@ -395,20 +393,20 @@ impl<'hir> Map<'hir> { } /// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`. - pub fn walk_toplevel_module(self, visitor: &mut V) -> V::Result + pub fn hir_walk_toplevel_module(self, visitor: &mut V) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let (top_mod, span, hir_id) = self.get_module(LocalModDefId::CRATE_DEF_ID); + let (top_mod, span, hir_id) = self.hir_get_module(LocalModDefId::CRATE_DEF_ID); visitor.visit_mod(top_mod, span, hir_id) } /// Walks the attributes in a crate. - pub fn walk_attributes(self, visitor: &mut V) -> V::Result + pub fn hir_walk_attributes(self, visitor: &mut V) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let krate = self.tcx.hir_crate(()); + let krate = self.hir_crate(()); for info in krate.owners.iter() { if let MaybeOwner::Owner(info) = info { for attrs in info.attrs.map.values() { @@ -422,89 +420,87 @@ impl<'hir> Map<'hir> { /// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you /// need to process every item-like, and don't care about visiting nested items in a particular /// order then this method is the best choice. If you do care about this nesting, you should - /// use the `tcx.hir().walk_toplevel_module`. + /// use the `tcx.hir_walk_toplevel_module`. /// /// Note that this function will access HIR for all the item-likes in the crate. If you only /// need to access some of them, it is usually better to manually loop on the iterators /// provided by `tcx.hir_crate_items(())`. /// /// Please see the notes in `intravisit.rs` for more information. - pub fn visit_all_item_likes_in_crate(self, visitor: &mut V) -> V::Result + pub fn hir_visit_all_item_likes_in_crate(self, visitor: &mut V) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let krate = self.tcx.hir_crate_items(()); - walk_list!(visitor, visit_item, krate.free_items().map(|id| self.tcx.hir_item(id))); + let krate = self.hir_crate_items(()); + walk_list!(visitor, visit_item, krate.free_items().map(|id| self.hir_item(id))); walk_list!( visitor, visit_trait_item, - krate.trait_items().map(|id| self.tcx.hir_trait_item(id)) - ); - walk_list!( - visitor, - visit_impl_item, - krate.impl_items().map(|id| self.tcx.hir_impl_item(id)) + krate.trait_items().map(|id| self.hir_trait_item(id)) ); + walk_list!(visitor, visit_impl_item, krate.impl_items().map(|id| self.hir_impl_item(id))); walk_list!( visitor, visit_foreign_item, - krate.foreign_items().map(|id| self.tcx.hir_foreign_item(id)) + krate.foreign_items().map(|id| self.hir_foreign_item(id)) ); V::Result::output() } /// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to /// item-likes in a single module. - pub fn visit_item_likes_in_module(self, module: LocalModDefId, visitor: &mut V) -> V::Result + pub fn hir_visit_item_likes_in_module( + self, + module: LocalModDefId, + visitor: &mut V, + ) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let module = self.tcx.hir_module_items(module); - walk_list!(visitor, visit_item, module.free_items().map(|id| self.tcx.hir_item(id))); + let module = self.hir_module_items(module); + walk_list!(visitor, visit_item, module.free_items().map(|id| self.hir_item(id))); walk_list!( visitor, visit_trait_item, - module.trait_items().map(|id| self.tcx.hir_trait_item(id)) - ); - walk_list!( - visitor, - visit_impl_item, - module.impl_items().map(|id| self.tcx.hir_impl_item(id)) + module.trait_items().map(|id| self.hir_trait_item(id)) ); + walk_list!(visitor, visit_impl_item, module.impl_items().map(|id| self.hir_impl_item(id))); walk_list!( visitor, visit_foreign_item, - module.foreign_items().map(|id| self.tcx.hir_foreign_item(id)) + module.foreign_items().map(|id| self.hir_foreign_item(id)) ); V::Result::output() } - pub fn for_each_module(self, mut f: impl FnMut(LocalModDefId)) { - let crate_items = self.tcx.hir_crate_items(()); + pub fn hir_for_each_module(self, mut f: impl FnMut(LocalModDefId)) { + let crate_items = self.hir_crate_items(()); for module in crate_items.submodules.iter() { f(LocalModDefId::new_unchecked(module.def_id)) } } #[inline] - pub fn par_for_each_module(self, f: impl Fn(LocalModDefId) + DynSend + DynSync) { - let crate_items = self.tcx.hir_crate_items(()); + pub fn par_hir_for_each_module(self, f: impl Fn(LocalModDefId) + DynSend + DynSync) { + let crate_items = self.hir_crate_items(()); par_for_each_in(&crate_items.submodules[..], |module| { f(LocalModDefId::new_unchecked(module.def_id)) }) } #[inline] - pub fn try_par_for_each_module( + pub fn try_par_hir_for_each_module( self, f: impl Fn(LocalModDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { - let crate_items = self.tcx.hir_crate_items(()); + let crate_items = self.hir_crate_items(()); try_par_for_each_in(&crate_items.submodules[..], |module| { f(LocalModDefId::new_unchecked(module.def_id)) }) } +} +impl<'hir> Map<'hir> { /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] @@ -540,7 +536,7 @@ impl<'hir> Map<'hir> { /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. /// Used exclusively for diagnostics, to avoid suggestion function calls. pub fn is_inside_const_context(self, hir_id: HirId) -> bool { - self.body_const_context(self.enclosing_body_owner(hir_id)).is_some() + self.tcx.hir_body_const_context(self.tcx.hir_enclosing_body_owner(hir_id)).is_some() } /// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is @@ -566,7 +562,8 @@ impl<'hir> Map<'hir> { /// } /// ``` pub fn get_fn_id_for_return_block(self, id: HirId) -> Option { - let enclosing_body_owner = self.tcx.local_def_id_to_hir_id(self.enclosing_body_owner(id)); + let enclosing_body_owner = + self.tcx.local_def_id_to_hir_id(self.tcx.hir_enclosing_body_owner(id)); // Return `None` if the `id` expression is not the returned value of the enclosing body let mut iter = [id].into_iter().chain(self.parent_id_iter(id)).peekable(); @@ -1249,7 +1246,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems { let mut collector = ItemCollector::new(tcx, false); - let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id); + let (hir_mod, span, hir_id) = tcx.hir_get_module(module_id); collector.visit_mod(hir_mod, span, hir_id); let ItemCollector { @@ -1282,7 +1279,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { // module item (the former starts at the crate root) but only // the former needs to collect it. ItemCollector does not do this for us. collector.submodules.push(CRATE_OWNER_ID); - tcx.hir().walk_toplevel_module(&mut collector); + tcx.hir_walk_toplevel_module(&mut collector); let ItemCollector { submodules, diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 0d2acf96d08..2a201e23015 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -213,7 +213,7 @@ pub fn provide(providers: &mut Providers) { providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() { - tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) + tcx.arena.alloc_from_iter(tcx.hir_body_param_names(body_id)) } else if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), .. diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index b0df6c71014..1e3b8d029e1 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1588,7 +1588,7 @@ pub fn write_allocations<'tcx>( Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => { write!(w, " (static: {}", tcx.def_path_str(did))?; if body.phase <= MirPhase::Runtime(RuntimePhase::PostCleanup) - && tcx.hir().body_const_context(body.source.def_id()).is_some() + && tcx.hir_body_const_context(body.source.def_id()).is_some() { // Statics may be cyclic and evaluating them too early // in the MIR pipeline may cause cycle errors even though diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cd81890598e..693823b4af4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -163,7 +163,7 @@ rustc_queries! { /// The items in a module. /// - /// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`. + /// This can be conveniently accessed by `tcx.hir_visit_item_likes_in_module`. /// Avoid calling this query directly. query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache @@ -771,7 +771,7 @@ rustc_queries! { query type_param_predicates( key: (LocalDefId, LocalDefId, rustc_span::Ident) ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir().ty_param_name(key.1) } + desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) } } query trait_def(key: DefId) -> &'tcx ty::TraitDef { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ea2b610a727..35893ad953d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2079,7 +2079,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Vec<&'tcx hir::Ty<'tcx>> { let hir_id = self.local_def_id_to_hir_id(scope_def_id); let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = - self.hir().fn_decl_by_hir_id(hir_id) + self.hir_fn_decl_by_hir_id(hir_id) else { return vec![]; }; @@ -2099,7 +2099,7 @@ impl<'tcx> TyCtxt<'tcx> { let hir_id = self.local_def_id_to_hir_id(scope_def_id); let mut v = TraitObjectVisitor(vec![], self.hir()); // when the return type is a type alias - if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) + if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id) && let hir::TyKind::Path(hir::QPath::Resolved( None, hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind @@ -3297,9 +3297,9 @@ pub fn provide(providers: &mut Providers) { providers.extern_mod_stmt_cnum = |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); providers.is_panic_runtime = - |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::panic_runtime); + |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime); providers.is_compiler_builtins = - |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins); + |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins); providers.has_panic_handler = |tcx, LocalCrate| { // We want to check if the panic handler was defined in this crate tcx.lang_items().panic_impl().is_some_and(|did| did.is_local()) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7beb6d84044..c52e774c8b7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1470,7 +1470,7 @@ pub enum ImplTraitInTraitData { impl<'tcx> TyCtxt<'tcx> { pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> { - self.typeck(self.hir().body_owner_def_id(body)) + self.typeck(self.hir_body_owner_def_id(body)) } pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator { diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index b84cc57234f..17e90c15d41 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -235,7 +235,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait } } - for &impl_def_id in tcx.hir().trait_impls(trait_id) { + for &impl_def_id in tcx.hir_trait_impls(trait_id) { let impl_def_id = impl_def_id.to_def_id(); let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index e04c70b5883..fb0aa354913 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -465,11 +465,10 @@ fn construct_fn<'tcx>( assert_eq!(expr.as_usize(), thir.exprs.len() - 1); // Figure out what primary body this item has. - let body = tcx.hir().body_owned_by(fn_def); + let body = tcx.hir_body_owned_by(fn_def); let span_with_body = tcx.hir().span_with_body(fn_id); let return_ty_span = tcx - .hir() - .fn_decl_by_hir_id(fn_id) + .hir_fn_decl_by_hir_id(fn_id) .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def)) .output .span(); @@ -758,7 +757,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { check_overflow |= tcx.sess.overflow_checks(); // Constants always need overflow checks. check_overflow |= matches!( - tcx.hir().body_owner_kind(def), + tcx.hir_body_owner_kind(def), hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) ); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8b6fcec3837..84f58f1968d 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -927,7 +927,7 @@ impl UnsafeOpKind { && let hir::BlockCheckMode::UnsafeBlock(_) = block.rules { true - } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) + } else if let Some(sig) = tcx.hir_fn_sig_by_hir_id(*id) && matches!(sig.header.safety, hir::HeaderSafety::Normal(hir::Safety::Unsafe)) { true @@ -1145,7 +1145,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { let thir = &thir.steal(); let hir_id = tcx.local_def_id_to_hir_id(def); - let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { + let safety_context = tcx.hir_fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { match fn_sig.header.safety { // We typeck the body as safe, but otherwise treat it as unsafe everywhere else. // Call sites to other SafeTargetFeatures functions are checked explicitly and don't need diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index a01609012b8..7a9f6e46304 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -22,8 +22,7 @@ pub(crate) fn thir_body( tcx: TyCtxt<'_>, owner_def: LocalDefId, ) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { - let hir = tcx.hir(); - let body = hir.body_owned_by(owner_def); + let body = tcx.hir_body_owned_by(owner_def); let mut cx = ThirBuildCx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); @@ -31,7 +30,7 @@ pub(crate) fn thir_body( let expr = cx.mirror_expr(body.value); let owner_id = tcx.local_def_id_to_hir_id(owner_def); - if let Some(fn_decl) = hir.fn_decl_by_hir_id(owner_id) { + if let Some(fn_decl) = tcx.hir_fn_decl_by_hir_id(owner_id) { let closure_env_param = cx.closure_env_param(owner_def, owner_id); let explicit_params = cx.explicit_params(owner_id, fn_decl, &body); cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect(); @@ -77,7 +76,7 @@ impl<'tcx> ThirBuildCx<'tcx> { let hir = tcx.hir(); let hir_id = tcx.local_def_id_to_hir_id(def); - let body_type = if hir.body_owner_kind(def).is_fn_or_closure() { + let body_type = if tcx.hir_body_owner_kind(def).is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id]) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 551ec5cf4e9..667d59d858e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -148,7 +148,7 @@ impl<'tcx> ConstToPat<'tcx> { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Param(param_ty) = ty.kind() { - let def_id = self.tcx.hir().enclosing_body_owner(self.id); + let def_id = self.tcx.hir_enclosing_body_owner(self.id); let generics = self.tcx.generics_of(def_id); let param = generics.type_param(*param_ty, self.tcx); let span = self.tcx.def_span(param.def_id); diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index 497f4a660ea..83c3cda5a50 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -16,7 +16,7 @@ pub(super) struct CheckForceInline; impl<'tcx> MirLint<'tcx> for CheckForceInline { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let def_id = body.source.def_id(); - if !tcx.hir().body_owner_kind(def_id).is_fn_or_closure() || !def_id.is_local() { + if !tcx.hir_body_owner_kind(def_id).is_fn_or_closure() || !def_id.is_local() { return; } let InlineAttr::Force { attr_span, .. } = tcx.codegen_fn_attrs(def_id).inline else { diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 9a6a153c7ba..5d21d687a35 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -113,7 +113,7 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> b let def_id = body.source.def_id(); // Only do inlining into fn bodies. - if !tcx.hir().body_owner_kind(def_id).is_fn_or_closure() { + if !tcx.hir_body_owner_kind(def_id).is_fn_or_closure() { return false; } diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 3dc4edaaa5a..da346dfc48c 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -36,7 +36,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { typing_env: body.typing_env(tcx), }; let preserve_ub_checks = - attr::contains_name(tcx.hir().krate_attrs(), sym::rustc_preserve_ub_checks); + attr::contains_name(tcx.hir_krate_attrs(), sym::rustc_preserve_ub_checks); for block in body.basic_blocks.as_mut() { for statement in block.statements.iter_mut() { match statement.kind { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 46abdcb2a87..04c9375b831 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -314,11 +314,11 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// MIR associated with them. fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // All body-owners have MIR associated with them. - let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect(); + let mut set: FxIndexSet<_> = tcx.hir_body_owners().collect(); // Coroutine-closures (e.g. async closures) have an additional by-move MIR // body that isn't in the HIR. - for body_owner in tcx.hir().body_owners() { + for body_owner in tcx.hir_body_owners() { if let DefKind::Closure = tcx.def_kind(body_owner) && tcx.needs_coroutine_by_move_body_def_id(body_owner.to_def_id()) { @@ -470,7 +470,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { } let body = tcx.mir_drops_elaborated_and_const_checked(def); - let body = match tcx.hir().body_const_context(def) { + let body = match tcx.hir_body_const_context(def) { // consts and statics do not have `optimized_mir`, so we can steal the body instead of // cloning it. Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => body.steal(), @@ -729,7 +729,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { return shim::build_adt_ctor(tcx, did.to_def_id()); } - match tcx.hir().body_const_context(did) { + match tcx.hir_body_const_context(did) { // Run the `mir_for_ctfe` query, which depends on `mir_drops_elaborated_and_const_checked` // which we are going to steal below. Thus we need to run `mir_for_ctfe` first, so it // computes and caches its result. diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 396a0cbc889..5111a025f94 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2461,7 +2461,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) { let mut diag = tcx.dcx().create_err(errors::ProcMacroBadSig { span, kind }); - let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id); + let hir_sig = tcx.hir_fn_sig_by_hir_id(hir_id); if let Some(hir_sig) = hir_sig { #[allow(rustc::diagnostic_outside_of_impl)] // FIXME match terr { @@ -2791,10 +2791,10 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let check_attr_visitor = &mut CheckAttrVisitor { tcx, abort: Cell::new(false) }; - tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor); + tcx.hir_visit_item_likes_in_module(module_def_id, check_attr_visitor); if module_def_id.to_local_def_id().is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None); - check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs()); + check_invalid_crate_level_attr(tcx, tcx.hir_krate_attrs()); } if check_attr_visitor.abort.get() { tcx.dcx().abort_if_errors() diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 696cc79bfeb..7b4fecf2ed1 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -358,7 +358,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let Some(local_impl_of) = impl_of.as_local() && let Some(local_def_id) = def_id.as_local() && let Some(fn_sig) = - self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) + self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None) && let TyKind::Path(hir::QPath::Resolved(_, path)) = self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind @@ -779,7 +779,7 @@ fn check_item<'tcx>( // check the function may construct Self let mut may_construct_self = false; if let Some(fn_sig) = - tcx.hir().fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id)) + tcx.hir_fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id)) { may_construct_self = matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None); diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 43f2f892e77..509c2f54775 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -9,11 +9,11 @@ use rustc_middle::ty::TyCtxt; pub fn check_crate(tcx: TyCtxt<'_>) { let errors = Lock::new(Vec::new()); - tcx.hir().par_for_each_module(|module_id| { + tcx.par_hir_for_each_module(|module_id| { let mut v = HirIdValidator { tcx, owner: None, hir_ids_seen: Default::default(), errors: &errors }; - tcx.hir().visit_item_likes_in_module(module_id, &mut v); + tcx.hir_visit_item_likes_in_module(module_id, &mut v); }); let errors = errors.into_inner(); diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index e60dcc807c9..92ea49f18e5 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -63,8 +63,8 @@ struct StatCollector<'k> { pub fn print_hir_stats(tcx: TyCtxt<'_>) { let mut collector = StatCollector { tcx: Some(tcx), nodes: FxHashMap::default(), seen: FxHashSet::default() }; - tcx.hir().walk_toplevel_module(&mut collector); - tcx.hir().walk_attributes(&mut collector); + tcx.hir_walk_toplevel_module(&mut collector); + tcx.hir_walk_attributes(&mut collector); collector.print("HIR STATS", "hir-stats"); } diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 09d59e1f717..e123fbac1be 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -148,7 +148,7 @@ fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures { } let mut collector = LibFeatureCollector::new(tcx); - tcx.hir().walk_attributes(&mut collector); + tcx.hir_walk_attributes(&mut collector); collector.lib_features } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 60f7616a5fb..a7bca67e4e4 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -152,8 +152,8 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let mut maps = IrMaps::new(tcx); - let body = tcx.hir().body_owned_by(def_id); - let hir_id = tcx.hir().body_owner(body.id()); + let body = tcx.hir_body_owned_by(def_id); + let hir_id = tcx.hir_body_owner(body.id()); if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { @@ -1522,8 +1522,7 @@ impl<'tcx> Liveness<'_, 'tcx> { } fn warn_about_unused_args(&self, body: &hir::Body<'_>, entry_ln: LiveNode) { - if let Some(intrinsic) = - self.ir.tcx.intrinsic(self.ir.tcx.hir().body_owner_def_id(body.id())) + if let Some(intrinsic) = self.ir.tcx.intrinsic(self.ir.tcx.hir_body_owner_def_id(body.id())) { if intrinsic.must_be_overridden { return; diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 0fd980af0b5..8e59c0b3251 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -76,7 +76,7 @@ struct CheckLoopVisitor<'tcx> { fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let mut check = CheckLoopVisitor { tcx, cx_stack: vec![Normal], block_breaks: Default::default() }; - tcx.hir().visit_item_likes_in_module(module_def_id, &mut check); + tcx.hir_visit_item_likes_in_module(module_def_id, &mut check); check.report_outside_loop_error(); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index d045e61d1d4..a6585946656 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -721,7 +721,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { InheritDeprecation::Yes, InheritConstStability::No, InheritStability::No, - |v| tcx.hir().walk_toplevel_module(v), + |v| tcx.hir_walk_toplevel_module(v), ); } index @@ -730,7 +730,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { - tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); + tcx.hir_visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); } pub(crate) fn provide(providers: &mut Providers) { @@ -1059,8 +1059,8 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let effective_visibilities = &tcx.effective_visibilities(()); let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities }; missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID)); - tcx.hir().walk_toplevel_module(&mut missing); - tcx.hir().visit_all_item_likes_in_crate(&mut missing); + tcx.hir_walk_toplevel_module(&mut missing); + tcx.hir_visit_all_item_likes_in_crate(&mut missing); } let enabled_lang_features = tcx.features().enabled_lang_features(); diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 0544d08f5b1..fae88fbba36 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -16,7 +16,7 @@ pub(crate) fn provide(providers: &mut Providers) { } let local_def_id = def_id.expect_local(); - let body = tcx.hir().maybe_body_owned_by(local_def_id)?; + let body = tcx.hir_maybe_body_owned_by(local_def_id)?; let mut local_collector = LocalCollector::default(); local_collector.visit_body(&body); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index b8490da26f4..6faa2c1a00d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1771,7 +1771,7 @@ pub fn provide(providers: &mut Providers) { fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_results: None }; - tcx.hir().visit_item_likes_in_module(module_def_id, &mut visitor); + tcx.hir_visit_item_likes_in_module(module_def_id, &mut visitor); // Check privacy of explicitly written types and traits as well as // inferred types of expressions and patterns. @@ -1782,7 +1782,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { for def_id in module.definitions() { rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor); - if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id) { + if let Some(body_id) = tcx.hir_maybe_body_owned_by(def_id) { visitor.visit_nested_body(body_id.id()); } } @@ -1863,7 +1863,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { } loop { - tcx.hir().visit_all_item_likes_in_crate(&mut visitor); + tcx.hir_visit_all_item_likes_in_crate(&mut visitor); if visitor.changed { visitor.changed = false; } else { @@ -1875,7 +1875,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { let mut check_visitor = TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities }; check_visitor.effective_visibility_diagnostic(CRATE_DEF_ID); - tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor); + tcx.hir_visit_all_item_likes_in_crate(&mut check_visitor); tcx.arena.alloc(visitor.effective_visibilities) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 55eb3f777d6..2bb38f3ed14 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -489,7 +489,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); - if let Some(body) = self.tcx.hir().maybe_body_owned_by( + if let Some(body) = self.tcx.hir_maybe_body_owned_by( self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), ) { let expr = body.value; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 35fd4e588ef..5b8d48e3ca9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -147,7 +147,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { | ObligationCauseCode::BlockTailExpression(hir_id, ..) = cause.code() { let parent_id = tcx.hir().get_parent_item(*hir_id); - if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) { + if let Some(fn_decl) = tcx.hir_fn_decl_by_hir_id(parent_id.into()) { let mut span: MultiSpan = fn_decl.output.span().into(); let mut spans = Vec::new(); let mut add_label = true; @@ -490,7 +490,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // obligation comes from the `impl`. Find that `impl` so that we can point // at it in the suggestion. let trait_did = trait_id.to_def_id(); - tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { + tcx.hir_trait_impls(trait_did).iter().find_map(|&impl_did| { if let Node::Item(Item { kind: ItemKind::Impl(hir::Impl { self_ty, .. }), .. }) = tcx.hir_node_by_def_id(impl_did) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs index 0695cc57978..cc2ab1c3432 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs @@ -99,11 +99,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] }; match assoc_item.kind { ty::AssocKind::Fn => { - let hir = self.tcx().hir(); if let Some(hir_id) = assoc_item.def_id.as_local().map(|id| self.tcx().local_def_id_to_hir_id(id)) { - if let Some(decl) = hir.fn_decl_by_hir_id(hir_id) { + if let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id) { visitor.visit_fn_decl(decl); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index 445937ad169..245764c94ab 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -64,10 +64,10 @@ pub fn find_param_with_region<'tcx>( _ => {} } - let body = hir.maybe_body_owned_by(def_id)?; + let body = tcx.hir_maybe_body_owned_by(def_id)?; - let owner_id = hir.body_owner(body.id()); - let fn_decl = hir.fn_decl_by_hir_id(owner_id)?; + let owner_id = tcx.hir_body_owner(body.id()); + let fn_decl = tcx.hir_fn_decl_by_hir_id(owner_id)?; let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index bb25c5e8bd1..628888c8d45 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -624,7 +624,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body| { + self.tcx.hir_maybe_body_owned_by(cause.body_id).and_then(|body| { IfVisitor { err_span: span, found_if: false } .visit_body(&body) .is_break() diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 6beb108bc3a..f15f1b78b52 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -316,7 +316,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) - && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + && let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(&body.value); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index ecfffb65fbc..a8ee4d61e65 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -367,7 +367,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (span.shrink_to_lo(), format!("(")), (span.shrink_to_hi(), format!(" as {})", cand.self_ty())), ] - } else if let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { + } else if let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); if let Some(expr) = expr_finder.result && diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ac1ced2ed3c..3d89b6ed2f0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -876,7 +876,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.remove_mark(); } let mut expr_finder = FindExprBySpan::new(span, self.tcx); - let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { return; }; expr_finder.visit_expr(body.value); @@ -1347,8 +1347,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Issue #104961, we need to add parentheses properly for compound expressions // for example, `x.starts_with("hi".to_string() + "you")` // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body) = - self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { return false; }; @@ -1447,7 +1446,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.remove_mark(); } let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); - let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { return false; }; expr_finder.visit_expr(body.value); @@ -1766,7 +1765,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.children.clear(); let span = obligation.cause.span; - let body = self.tcx.hir().body_owned_by(obligation.cause.body_id); + let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default(); visitor.visit_body(&body); @@ -2300,7 +2299,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); let coroutine_body = - coroutine_did.as_local().and_then(|def_id| hir.maybe_body_owned_by(def_id)); + coroutine_did.as_local().and_then(|def_id| self.tcx.hir_maybe_body_owned_by(def_id)); let mut visitor = AwaitsVisitor::default(); if let Some(body) = coroutine_body { visitor.visit_body(&body); @@ -4130,7 +4129,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; suggest_restriction( tcx, - hir.body_owner_def_id(body_id), + tcx.hir_body_owner_def_id(body_id), generics, &format!("type parameter `{ty}`"), err, @@ -4352,7 +4351,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term: ty.into(), }), )); - let body_def_id = self.tcx.hir().enclosing_body_owner(body_id); + let body_def_id = self.tcx.hir_enclosing_body_owner(body_id); // Add `::Item = _` obligation. ocx.register_obligation(Obligation::misc( self.tcx, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 32d9469c296..7ce72c76e5c 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -109,7 +109,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { - let body = self.tcx.hir().body_owned_by(self.item).value; + let body = self.tcx.hir_body_owned_by(self.item).value; struct TaitInBodyFinder<'a, 'tcx> { collector: &'a mut OpaqueTypeCollector<'tcx>, } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8b424499724..fc7c4b42047 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2121,7 +2121,7 @@ impl Discriminant { /// simplified pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option { self.expr - .map(|body| rendered_const(tcx, tcx.hir_body(body), tcx.hir().body_owner_def_id(body))) + .map(|body| rendered_const(tcx, tcx.hir_body(body), tcx.hir_body_owner_def_id(body))) } pub(crate) fn value(&self, tcx: TyCtxt<'_>, with_underscores: bool) -> String { print_evaluated_const(tcx, self.value, with_underscores, false).unwrap() @@ -2417,7 +2417,7 @@ impl ConstantKind { ConstantKind::Path { ref path } => path.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { - rendered_const(tcx, tcx.hir_body(body), tcx.hir().body_owner_def_id(body)) + rendered_const(tcx, tcx.hir_body(body), tcx.hir_body_owner_def_id(body)) } ConstantKind::Infer { .. } => "_".to_string(), } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8a7d140bb1a..6b1d1a2fcdd 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -336,7 +336,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { let s = if let Some(def) = def.as_local() { - rendered_const(cx.tcx, cx.tcx.hir().body_owned_by(def), def) + rendered_const(cx.tcx, cx.tcx.hir_body_owned_by(def), def) } else { inline::print_inlined_const(cx.tcx, def) }; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1ead87fd69d..757a2a6e0dd 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -304,8 +304,7 @@ pub(crate) fn create_config( return tcx.typeck(typeck_root_def_id); } - let hir = tcx.hir(); - let body = hir.body_owned_by(def_id); + let body = tcx.hir_body_owned_by(def_id); debug!("visiting body for {def_id:?}"); EmitIgnoredResolutionErrors::new(tcx).visit_body(body); (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id) @@ -335,14 +334,14 @@ pub(crate) fn run_global_ctxt( // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes. let _ = tcx.sess.time("wf_checking", || { - tcx.hir().try_par_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module)) + tcx.try_par_hir_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module)) }); tcx.dcx().abort_if_errors(); tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx)); tcx.sess.time("check_mod_attrs", || { - tcx.hir().for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module)) + tcx.hir_for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module)) }); rustc_passes::stability::check_unused_or_stable_features(tcx); diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 0d52e21419f..1ac3c040b59 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -81,7 +81,7 @@ impl<'tcx> HirCollector<'tcx> { pub fn collect_crate(mut self) -> Vec { let tcx = self.tcx; self.visit_testable("".to_string(), CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| { - tcx.hir().walk_toplevel_module(this) + tcx.hir_walk_toplevel_module(this) }); self.collector.tests } diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index fa2465c1926..658d5965b3d 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -51,7 +51,7 @@ pub(crate) fn collect_spans_and_sources( let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() }; if generate_link_to_definition { - tcx.hir().walk_toplevel_module(&mut visitor); + tcx.hir_walk_toplevel_module(&mut visitor); } let sources = sources::collect_local_sources(tcx, src_root, krate); (sources, visitor.matches) @@ -173,18 +173,18 @@ impl SpanMapVisitor<'_> { } fn infer_id(&mut self, hir_id: HirId, expr_hir_id: Option, span: Span) { - let hir = self.tcx.hir(); - let body_id = hir.enclosing_body_owner(hir_id); + let tcx = self.tcx; + let body_id = tcx.hir_enclosing_body_owner(hir_id); // FIXME: this is showing error messages for parts of the code that are not // compiled (because of cfg)! // // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 - let typeck_results = self.tcx.typeck_body(hir.body_owned_by(body_id).id()); + let typeck_results = tcx.typeck_body(tcx.hir_body_owned_by(body_id).id()); // Interestingly enough, for method calls, we need the whole expression whereas for static // method/function calls, we need the call expression specifically. if let Some(def_id) = typeck_results.type_dependent_def_id(expr_hir_id.unwrap_or(hir_id)) { let link = if def_id.as_local().is_some() { - LinkFromSrc::Local(rustc_span(def_id, self.tcx)) + LinkFromSrc::Local(rustc_span(def_id, tcx)) } else { LinkFromSrc::External(def_id) }; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bef59469179..9606ba76991 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -846,7 +846,7 @@ fn convert_static( is_unsafe: safety.is_unsafe(), expr: stat .expr - .map(|e| rendered_const(tcx, tcx.hir_body(e), tcx.hir().body_owner_def_id(e))) + .map(|e| rendered_const(tcx, tcx.hir_body(e), tcx.hir_body_owner_def_id(e))) .unwrap_or_default(), } } diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index dd9dbd7170e..a36dcb0d30e 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -135,8 +135,7 @@ where // If we visit an item that contains an expression outside a function body, // then we need to exit before calling typeck (which will panic). See // test/run-make/rustdoc-scrape-examples-invalid-expr for an example. - let hir = tcx.hir(); - if hir.maybe_body_owned_by(ex.hir_id.owner.def_id).is_none() { + if tcx.hir_maybe_body_owned_by(ex.hir_id.owner.def_id).is_none() { return; } @@ -302,7 +301,7 @@ pub(crate) fn run( // Run call-finder on all items let mut calls = FxIndexMap::default(); let mut finder = FindCalls { calls: &mut calls, cx, target_crates, bin_crate }; - tcx.hir().visit_all_item_likes_in_crate(&mut finder); + tcx.hir_visit_all_item_likes_in_crate(&mut finder); // The visitor might have found a type error, which we need to // promote to a fatal error diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index 772268e7899..784214c29af 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -52,11 +52,10 @@ declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { - let hir = cx.tcx.hir(); // NOTE: this is different from `clippy_utils::is_inside_always_const_context`. // Inline const supports type inference. let is_parent_const = matches!( - hir.body_const_context(hir.body_owner_def_id(body.id())), + cx.tcx.hir_body_const_context(cx.tcx.hir_body_owner_def_id(body.id())), Some(ConstContext::Const { inline: false } | ConstContext::Static(_)) ); let mut visitor = NumericFallbackVisitor::new(cx, is_parent_const); diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index a090a987d4f..2e1f8ac615a 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { if let ItemKind::Enum(def, _) = &item.kind { for var in def.variants { if let Some(anon_const) = &var.disr_expr { - let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body); + let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body); let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity(); let constant = cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs index 6d1c55d0693..cb83b1395d2 100644 --- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs @@ -39,7 +39,7 @@ fn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) { if let FnKind::ItemFn(_, generics, _) = kind - && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() + && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, hir_id) { for param in generics.params { @@ -57,7 +57,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { && let hir::Impl { of_trait, .. } = *impl_ && of_trait.is_none() && let body = cx.tcx.hir_body(body_id) - && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() + && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, impl_item.hir_id()) { for param in impl_item.generics.params { diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs index ac2e866e4ff..5ad83f886e2 100644 --- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs @@ -22,7 +22,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored && let Some(did) = trait_item_def_id_of_impl(items, item.owner_id) && !is_from_ignored_trait(trait_ref, ignored_traits) { - let mut param_idents_iter = cx.tcx.hir().body_param_names(body_id); + let mut param_idents_iter = cx.tcx.hir_body_param_names(body_id); let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied(); let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter); diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs index 052e6502da9..2a5aa12d126 100644 --- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs +++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { && exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2 && !expr.span.in_external_macro(cx.sess().source_map()) && ( - is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into()) + is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into()) || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY) ) && let [first, second, const_1, const_2] = exprs diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index 4a8a221e8c3..b1107d8cc72 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -58,8 +58,7 @@ pub(super) fn check<'tcx>( unwrap_or_span: unwrap_arg.span, }; - let map = cx.tcx.hir(); - let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id)); + let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); // Visit the body, and return if we've found a reference if reference_visitor.visit_body(body).is_break() { diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 7f91e555054..ea1d7e5d438 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { if self .possible_borrowers .last() - .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir().body_owner_def_id(body.id())) + .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir_body_owner_def_id(body.id())) { self.possible_borrowers.pop(); } @@ -359,7 +359,7 @@ fn referent_used_exactly_once<'tcx>( && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind && !place.is_indirect_first_projection() { - let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id); + let body_owner_local_def_id = cx.tcx.hir_enclosing_body_owner(reference.hir_id); if possible_borrowers .last() .is_none_or(|&(local_def_id, _)| local_def_id != body_owner_local_def_id) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 6a1dc5e41a0..5e85d23718a 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -352,7 +352,7 @@ impl MutablyUsedVariablesCtxt<'_> { fn is_in_unsafe_block(&self, item: HirId) -> bool { let hir = self.tcx.hir(); for (parent, node) in hir.parent_iter(item) { - if let Some(fn_sig) = hir.fn_sig_by_hir_id(parent) { + if let Some(fn_sig) = self.tcx.hir_fn_sig_by_hir_id(parent) { return fn_sig.header.is_unsafe(); } else if let Node::Block(block) = node { if matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) { diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index 9d07a14718d..594101427f5 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -349,10 +349,10 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); - let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); + let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id()); - let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id); + let body_owner_kind = cx.tcx.hir_body_owner_kind(body_owner_def_id); if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind { let body_span = cx.tcx.hir().span_with_body(body_owner); if let Some(span) = self.const_span @@ -365,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); let body_span = cx.tcx.hir().span(body_owner); if let Some(span) = self.const_span && span.contains(body_span) diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs index 2083f2bf628..cda99a362dc 100644 --- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs @@ -68,10 +68,10 @@ impl Context { } pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); - let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); + let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id()); - match cx.tcx.hir().body_owner_kind(body_owner_def_id) { + match cx.tcx.hir_body_owner_kind(body_owner_def_id) { hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const { .. } => { let body_span = cx.tcx.hir().span_with_body(body_owner); @@ -87,7 +87,7 @@ impl Context { } pub fn body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); let body_span = cx.tcx.hir().span_with_body(body_owner); if let Some(span) = self.const_span { diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs index ebe3e7c2019..e15e1262920 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals { /// assert_static(closure); /// ``` fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool { - let closure_def_id = cx.tcx.hir().enclosing_body_owner(redefinition); + let closure_def_id = cx.tcx.hir_enclosing_body_owner(redefinition); cx.tcx.is_closure_like(closure_def_id.to_def_id()) && cx.tcx.closure_captures(closure_def_id).iter().any(|c| { diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 83199ba0f70..a931e39bac9 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -149,17 +149,15 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { } fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { - let hir = cx.tcx.hir(); - let owner_id = hir.body_owner_def_id(body.id()); - if !matches!(hir.body_owner_kind(owner_id), BodyOwnerKind::Closure) { + let owner_id = cx.tcx.hir_body_owner_def_id(body.id()); + if !matches!(cx.tcx.hir_body_owner_kind(owner_id), BodyOwnerKind::Closure) { self.bindings.push((FxHashMap::default(), owner_id)); } } fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { - let hir = cx.tcx.hir(); if !matches!( - hir.body_owner_kind(hir.body_owner_def_id(body.id())), + cx.tcx.hir_body_owner_kind(cx.tcx.hir_body_owner_def_id(body.id())), BodyOwnerKind::Closure ) { self.bindings.pop(); diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs index fdbccbaa8a5..1a2fb77acc1 100644 --- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs +++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs @@ -90,8 +90,7 @@ impl SingleCallFn { || fn_span.in_external_macro(cx.sess().source_map()) || cx .tcx - .hir() - .maybe_body_owned_by(fn_def_id) + .hir_maybe_body_owned_by(fn_def_id) .is_none_or(|body| is_in_test_function(cx.tcx, body.value.hir_id)) || match cx.tcx.hir_node(fn_hir_id) { Node::Item(item) => is_from_proc_macro(cx, item), diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs index 4961dd6b280..0b5d83ef58c 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -28,8 +28,8 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) } fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { - let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); - if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) { + let def_id = cx.tcx.hir_enclosing_body_owner(expr_hir_id); + if let Some(body) = cx.tcx.hir_maybe_body_owned_by(def_id) { return body.value.peel_blocks().hir_id == expr_hir_id; } false diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 529f85be372..76a0b927df4 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -331,8 +331,8 @@ impl UnconditionalRecursion { && let [return_expr] = get_return_calls_in_body(body).as_slice() && let ExprKind::Call(call_expr, _) = return_expr.kind // We need to use typeck here to infer the actual function being called. - && let body_def_id = cx.tcx.hir().enclosing_body_owner(call_expr.hir_id) - && let Some(body_owner) = cx.tcx.hir().maybe_body_owned_by(body_def_id) + && let body_def_id = cx.tcx.hir_enclosing_body_owner(call_expr.hir_id) + && let Some(body_owner) = cx.tcx.hir_maybe_body_owned_by(body_def_id) && let typeck = cx.tcx.typeck_body(body_owner.id()) && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id) { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index ce489054e16..5fc166438e8 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -132,8 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_item(cx: &LateContext<'_>, hir_id: HirId) { - let hir = cx.tcx.hir(); - if let Some(body) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { + if let Some(body) = cx.tcx.hir_maybe_body_owned_by(hir_id.expect_owner().def_id) { check_node(cx, hir_id, |v| { v.expr(&v.bind("expr", body.value)); }); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index e31da9e9f61..d6f10f1e4b8 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { output: &mut self.registered_lints, cx, }; - let body = cx.tcx.hir().body_owned_by( + let body = cx.tcx.hir_body_owned_by( impl_item_refs .iter() .find(|iiref| iiref.ident.as_str() == "lint_vec") diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index ccf32f42a47..15e395731ad 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -237,8 +237,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool { debug_assert!(cx.enclosing_body.is_some(), "`LateContext` has no enclosing body"); cx.enclosing_body.is_some_and(|id| { cx.tcx - .hir() - .body_const_context(cx.tcx.hir().body_owner_def_id(id)) + .hir_body_const_context(cx.tcx.hir_body_owner_def_id(id)) .is_some() }) } @@ -251,8 +250,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool { /// * associated constants pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { use ConstContext::{Const, ConstFn, Static}; - let hir = tcx.hir(); - let Some(ctx) = hir.body_const_context(hir.enclosing_body_owner(hir_id)) else { + let Some(ctx) = tcx.hir_body_const_context(tcx.hir_enclosing_body_owner(hir_id)) else { return false; }; match ctx { @@ -1648,7 +1646,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool if is_integer_literal(e, value) { return true; } - let enclosing_body = cx.tcx.hir().enclosing_body_owner(e.hir_id); + let enclosing_body = cx.tcx.hir_enclosing_body_owner(e.hir_id); if let Some(Constant::Int(v)) = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e) { @@ -2762,7 +2760,7 @@ impl<'tcx> ExprUseCtxt<'tcx> { Node::Expr(use_expr) => match use_expr.kind { ExprKind::Ret(_) => ExprUseNode::Return(OwnerId { - def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), + def_id: cx.tcx.hir_body_owner_def_id(cx.enclosing_body.unwrap()), }), ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }), diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index 85250f81dc4..637c0bafd96 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -136,8 +136,8 @@ pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option { /// Returns the `mir::Body` containing the node associated with `hir_id`. #[allow(clippy::module_name_repetitions)] pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&Body<'_>> { - let body_owner_local_def_id = tcx.hir().enclosing_body_owner(hir_id); - if tcx.hir().body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { + let body_owner_local_def_id = tcx.hir_enclosing_body_owner(hir_id); + if tcx.hir_body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { Some(tcx.optimized_mir(body_owner_local_def_id.to_def_id())) } else { None diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index a5374f6904e..8eef6a7f57e 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -267,7 +267,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( // through calling `body_owner_kind`, which would panic if the callee // does not have a body. if let Some(callee_id) = callee_id { - let _ = tcx.hir().body_owner_kind(callee_id); + let _ = tcx.hir_body_owner_kind(callee_id); } let ty = tcx.erase_regions(ty); @@ -705,7 +705,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option { let decl = id .as_local() - .and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); + .and_then(|id| cx.tcx.hir_fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); Some(ExprFnSig::Closure(decl, subs.as_closure().sig())) }, ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), -- cgit 1.4.1-3-g733a5 From 2d2de181668bbfc50b3396f470da64cd46443c39 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 18 Feb 2025 00:12:26 -0800 Subject: compiler: Stop reexporting stuff in cg_llvm::abi The reexports confuse tooling like rustdoc into thinking cg_llvm is the source of key types that originate in rustc_target. --- compiler/rustc_codegen_llvm/src/abi.rs | 19 ++++++++----------- compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 18 ++++++++++-------- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_llvm/src/declare.rs | 3 ++- compiler/rustc_codegen_llvm/src/intrinsic.rs | 12 ++++++------ 5 files changed, 27 insertions(+), 27 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 28f423efc21..8c75125e009 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -2,19 +2,18 @@ use std::borrow::Borrow; use std::cmp; use libc::c_uint; -use rustc_abi as abi; -pub(crate) use rustc_abi::ExternAbi; -use rustc_abi::{HasDataLayout, Primitive, Reg, RegKind, Size}; +use rustc_abi::{BackendRepr, HasDataLayout, Primitive, Reg, RegKind, Size}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; -pub(crate) use rustc_middle::ty::layout::{WIDE_PTR_ADDR, WIDE_PTR_EXTRA}; use rustc_middle::{bug, ty}; use rustc_session::config; -pub(crate) use rustc_target::callconv::*; +use rustc_target::callconv::{ + ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, Conv, FnAbi, PassMode, +}; use rustc_target::spec::SanitizerSet; use smallvec::SmallVec; @@ -458,7 +457,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { match &self.ret.mode { PassMode::Direct(attrs) => { attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn); - if let abi::BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr { + if let BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr { apply_range_attr(llvm::AttributePlace::ReturnValue, scalar); } } @@ -499,7 +498,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } PassMode::Direct(attrs) => { let i = apply(attrs); - if let abi::BackendRepr::Scalar(scalar) = arg.layout.backend_repr { + if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr { apply_range_attr(llvm::AttributePlace::Argument(i), scalar); } } @@ -514,9 +513,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Pair(a, b) => { let i = apply(a); let ii = apply(b); - if let abi::BackendRepr::ScalarPair(scalar_a, scalar_b) = - arg.layout.backend_repr - { + if let BackendRepr::ScalarPair(scalar_a, scalar_b) = arg.layout.backend_repr { apply_range_attr(llvm::AttributePlace::Argument(i), scalar_a); apply_range_attr(llvm::AttributePlace::Argument(ii), scalar_b); } @@ -576,7 +573,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } if bx.cx.sess().opts.optimize != config::OptLevel::No && llvm_util::get_version() < (19, 0, 0) - && let abi::BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr + && let BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr && matches!(scalar.primitive(), Primitive::Int(..)) // If the value is a boolean, the range is 0..2 and that ultimately // become 0..0 when the type becomes i1, which would be rejected diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 59c3fe635d0..98d59f5a8ae 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -11,7 +11,9 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; -use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{ + HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA, +}; use rustc_middle::ty::{ self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, }; @@ -34,12 +36,12 @@ use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::dwarf_const; use crate::debuginfo::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind}; +use crate::llvm; use crate::llvm::debuginfo::{ DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind, DebugNameTableKind, }; use crate::value::Value; -use crate::{abi, llvm}; impl PartialEq for llvm::Metadata { fn eq(&self, other: &Self) -> bool { @@ -211,16 +213,16 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( }; let layout = cx.layout_of(layout_type); - let addr_field = layout.field(cx, abi::WIDE_PTR_ADDR); - let extra_field = layout.field(cx, abi::WIDE_PTR_EXTRA); + let addr_field = layout.field(cx, WIDE_PTR_ADDR); + let extra_field = layout.field(cx, WIDE_PTR_EXTRA); let (addr_field_name, extra_field_name) = match wide_pointer_kind { WidePtrKind::Dyn => ("pointer", "vtable"), WidePtrKind::Slice => ("data_ptr", "length"), }; - assert_eq!(abi::WIDE_PTR_ADDR, 0); - assert_eq!(abi::WIDE_PTR_EXTRA, 1); + assert_eq!(WIDE_PTR_ADDR, 0); + assert_eq!(WIDE_PTR_EXTRA, 1); // The data pointer type is a regular, thin pointer, regardless of whether this // is a slice or a trait object. @@ -242,7 +244,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( owner, addr_field_name, (addr_field.size, addr_field.align.abi), - layout.fields.offset(abi::WIDE_PTR_ADDR), + layout.fields.offset(WIDE_PTR_ADDR), DIFlags::FlagZero, data_ptr_type_di_node, None, @@ -252,7 +254,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( owner, extra_field_name, (extra_field.size, extra_field.align.abi), - layout.fields.offset(abi::WIDE_PTR_EXTRA), + layout.fields.offset(WIDE_PTR_EXTRA), DIFlags::FlagZero, type_di_node(cx, extra_field.ty), None, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 17f2d5f4e73..10819a53b1d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -22,6 +22,7 @@ use rustc_session::config::{self, DebugInfo}; use rustc_span::{ BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, Symbol, }; +use rustc_target::callconv::FnAbi; use rustc_target::spec::DebuginfoKind; use smallvec::SmallVec; use tracing::debug; @@ -29,7 +30,6 @@ use tracing::debug; use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node}; use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; -use crate::abi::FnAbi; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; use crate::llvm; diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index cebceef1b93..e79662ebc64 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -16,10 +16,11 @@ use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods; use rustc_data_structures::fx::FxIndexSet; use rustc_middle::ty::{Instance, Ty}; use rustc_sanitizers::{cfi, kcfi}; +use rustc_target::callconv::FnAbi; use smallvec::SmallVec; use tracing::debug; -use crate::abi::{FnAbi, FnAbiLlvmExt}; +use crate::abi::FnAbiLlvmExt; use crate::common::AsCCharPtr; use crate::context::{CodegenCx, SimpleCx}; use crate::llvm::AttributePlace::Function; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 8b976885904..7e1a9d361e6 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1,7 +1,7 @@ use std::assert_matches::assert_matches; use std::cmp::Ordering; -use rustc_abi::{self as abi, Align, Float, HasDataLayout, Primitive, Size}; +use rustc_abi::{Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size}; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization}; @@ -14,10 +14,11 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; +use rustc_target::callconv::{FnAbi, PassMode}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use tracing::debug; -use crate::abi::{ExternAbi, FnAbi, FnAbiLlvmExt, LlvmType, PassMode}; +use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::builder::Builder; use crate::context::CodegenCx; use crate::llvm::{self, Metadata}; @@ -257,7 +258,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::va_arg => { match fn_abi.ret.layout.backend_repr { - abi::BackendRepr::Scalar(scalar) => { + BackendRepr::Scalar(scalar) => { match scalar.primitive() { Primitive::Int(..) => { if self.cx().size_of(ret_ty).bytes() < 4 { @@ -470,7 +471,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::raw_eq => { - use abi::BackendRepr::*; + use BackendRepr::*; let tp_ty = fn_args.type_at(0); let layout = self.layout_of(tp_ty).layout; let use_integer_compare = match layout.backend_repr() { @@ -582,8 +583,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } let llret_ty = if ret_ty.is_simd() - && let abi::BackendRepr::Memory { .. } = - self.layout_of(ret_ty).layout.backend_repr + && let BackendRepr::Memory { .. } = self.layout_of(ret_ty).layout.backend_repr { let (size, elem_ty) = ret_ty.simd_size_and_type(self.tcx()); let elem_ll_ty = match elem_ty.kind() { -- cgit 1.4.1-3-g733a5 From 5e9d8a7d55fbf1771d1b83ff2f15bdc75c9216d8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 19 Feb 2025 10:55:36 +0100 Subject: Switch to the LLVMBuildGEPWithNoWrapFlags API This API allows us to set the nuw flag as well. --- compiler/rustc_codegen_llvm/src/builder.rs | 8 +++++--- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 22 +++++++++++++--------- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index e10a4d63407..5e130854b78 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -32,7 +32,7 @@ use crate::abi::FnAbiLlvmExt; use crate::attributes; use crate::common::Funclet; use crate::context::{CodegenCx, SimpleCx}; -use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, Metadata, True}; +use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; @@ -908,13 +908,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn gep(&mut self, ty: &'ll Type, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value { unsafe { - llvm::LLVMBuildGEP2( + llvm::LLVMBuildGEPWithNoWrapFlags( self.llbuilder, ty, ptr, indices.as_ptr(), indices.len() as c_uint, UNNAMED, + GEPNoWrapFlags::default(), ) } } @@ -926,13 +927,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { indices: &[&'ll Value], ) -> &'ll Value { unsafe { - llvm::LLVMBuildInBoundsGEP2( + llvm::LLVMBuildGEPWithNoWrapFlags( self.llbuilder, ty, ptr, indices.as_ptr(), indices.len() as c_uint, UNNAMED, + GEPNoWrapFlags::InBounds, ) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3b0187b9d37..da91e6edbcf 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -954,6 +954,17 @@ bitflags! { } } +// These values **must** match with LLVMGEPNoWrapFlags +bitflags! { + #[repr(transparent)] + #[derive(Default)] + pub struct GEPNoWrapFlags : c_uint { + const InBounds = 1 << 0; + const NUSW = 1 << 1; + const NUW = 1 << 2; + } +} + unsafe extern "C" { pub type ModuleBuffer; } @@ -1454,21 +1465,14 @@ unsafe extern "C" { pub(crate) fn LLVMBuildStore<'a>(B: &Builder<'a>, Val: &'a Value, Ptr: &'a Value) -> &'a Value; - pub(crate) fn LLVMBuildGEP2<'a>( - B: &Builder<'a>, - Ty: &'a Type, - Pointer: &'a Value, - Indices: *const &'a Value, - NumIndices: c_uint, - Name: *const c_char, - ) -> &'a Value; - pub(crate) fn LLVMBuildInBoundsGEP2<'a>( + pub(crate) fn LLVMBuildGEPWithNoWrapFlags<'a>( B: &Builder<'a>, Ty: &'a Type, Pointer: &'a Value, Indices: *const &'a Value, NumIndices: c_uint, Name: *const c_char, + Flags: GEPNoWrapFlags, ) -> &'a Value; // Casts diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index b8cef6a7e25..aea2a8dd097 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1767,6 +1767,24 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS))); } +#if LLVM_VERSION_LT(19, 0) +enum { + LLVMGEPFlagInBounds = (1 << 0), + LLVMGEPFlagNUSW = (1 << 1), + LLVMGEPFlagNUW = (1 << 2), +}; +extern "C" LLVMValueRef +LLVMBuildGEPWithNoWrapFlags(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Pointer, LLVMValueRef *Indices, + unsigned NumIndices, const char *Name, + unsigned NoWrapFlags) { + if (NoWrapFlags & LLVMGEPFlagInBounds) + return LLVMBuildInBoundsGEP2(B, Ty, Pointer, Indices, NumIndices, Name); + else + return LLVMBuildGEP2(B, Ty, Pointer, Indices, NumIndices, Name); +} +#endif + // Transfers ownership of DiagnosticHandler unique_ptr to the caller. extern "C" DiagnosticHandler * LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) { -- cgit 1.4.1-3-g733a5 From 31cc4c074d9df22110daa59d8f5486ae02bac3bd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 19 Feb 2025 11:06:11 +0100 Subject: Emit getelementptr inbounds nuw for pointer::add() --- compiler/rustc_codegen_llvm/src/builder.rs | 23 ++++++++++++++++++- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 29 ++++++++++++++++-------- compiler/rustc_codegen_ssa/src/traits/builder.rs | 8 +++++++ tests/codegen/gep-index.rs | 4 ++-- tests/codegen/intrinsics/offset.rs | 2 +- tests/codegen/intrinsics/ptr_metadata.rs | 2 +- tests/codegen/ptr-arithmetic.rs | 2 +- 7 files changed, 55 insertions(+), 15 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 5e130854b78..7e428f010ef 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -32,7 +32,9 @@ use crate::abi::FnAbiLlvmExt; use crate::attributes; use crate::common::Funclet; use crate::context::{CodegenCx, SimpleCx}; -use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True}; +use crate::llvm::{ + self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True, +}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; @@ -939,6 +941,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + fn inbounds_nuw_gep( + &mut self, + ty: &'ll Type, + ptr: &'ll Value, + indices: &[&'ll Value], + ) -> &'ll Value { + unsafe { + llvm::LLVMBuildGEPWithNoWrapFlags( + self.llbuilder, + ty, + ptr, + indices.as_ptr(), + indices.len() as c_uint, + UNNAMED, + GEPNoWrapFlags::InBounds | GEPNoWrapFlags::NUW, + ) + } + } + /* Casts */ fn trunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 4c5b183cfe9..6ba38b7186d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -664,9 +664,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { lhs.layout.ty, ), - (OperandValue::Immediate(lhs_val), OperandValue::Immediate(rhs_val)) => { - self.codegen_scalar_binop(bx, op, lhs_val, rhs_val, lhs.layout.ty) - } + (OperandValue::Immediate(lhs_val), OperandValue::Immediate(rhs_val)) => self + .codegen_scalar_binop( + bx, + op, + lhs_val, + rhs_val, + lhs.layout.ty, + rhs.layout.ty, + ), _ => bug!(), }; @@ -887,10 +893,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { op: mir::BinOp, lhs: Bx::Value, rhs: Bx::Value, - input_ty: Ty<'tcx>, + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>, ) -> Bx::Value { - let is_float = input_ty.is_floating_point(); - let is_signed = input_ty.is_signed(); + let is_float = lhs_ty.is_floating_point(); + let is_signed = lhs_ty.is_signed(); match op { mir::BinOp::Add => { if is_float { @@ -956,9 +963,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::BinOp::BitAnd => bx.and(lhs, rhs), mir::BinOp::BitXor => bx.xor(lhs, rhs), mir::BinOp::Offset => { - let pointee_type = input_ty + let pointee_type = lhs_ty .builtin_deref(true) - .unwrap_or_else(|| bug!("deref of non-pointer {:?}", input_ty)); + .unwrap_or_else(|| bug!("deref of non-pointer {:?}", lhs_ty)); let pointee_layout = bx.cx().layout_of(pointee_type); if pointee_layout.is_zst() { // `Offset` works in terms of the size of pointee, @@ -966,7 +973,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { lhs } else { let llty = bx.cx().backend_type(pointee_layout); - bx.inbounds_gep(llty, lhs, &[rhs]) + if !rhs_ty.is_signed() { + bx.inbounds_nuw_gep(llty, lhs, &[rhs]) + } else { + bx.inbounds_gep(llty, lhs, &[rhs]) + } } } mir::BinOp::Shl | mir::BinOp::ShlUnchecked => { diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 48ae000f2c6..868bd4f9039 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -332,6 +332,14 @@ pub trait BuilderMethods<'a, 'tcx>: ptr: Self::Value, indices: &[Self::Value], ) -> Self::Value; + fn inbounds_nuw_gep( + &mut self, + ty: Self::Type, + ptr: Self::Value, + indices: &[Self::Value], + ) -> Self::Value { + self.inbounds_gep(ty, ptr, indices) + } fn ptradd(&mut self, ptr: Self::Value, offset: Self::Value) -> Self::Value { self.gep(self.cx().type_i8(), ptr, &[offset]) } diff --git a/tests/codegen/gep-index.rs b/tests/codegen/gep-index.rs index 1f5e8855910..6b45692bea1 100644 --- a/tests/codegen/gep-index.rs +++ b/tests/codegen/gep-index.rs @@ -18,7 +18,7 @@ fn index_on_struct(a: &[Foo], index: usize) -> &Foo { // CHECK-LABEL: @offset_on_struct( #[no_mangle] fn offset_on_struct(a: *const Foo, index: usize) -> *const Foo { - // CHECK: getelementptr inbounds %Foo, ptr %a, {{i64|i32}} %index + // CHECK: getelementptr inbounds{{( nuw)?}} %Foo, ptr %a, {{i64|i32}} %index unsafe { a.add(index) } } @@ -32,6 +32,6 @@ fn index_on_i32(a: &[i32], index: usize) -> &i32 { // CHECK-LABEL: @offset_on_i32( #[no_mangle] fn offset_on_i32(a: *const i32, index: usize) -> *const i32 { - // CHECK: getelementptr inbounds i32, ptr %a, {{i64|i32}} %index + // CHECK: getelementptr inbounds{{( nuw)?}} i32, ptr %a, {{i64|i32}} %index unsafe { a.add(index) } } diff --git a/tests/codegen/intrinsics/offset.rs b/tests/codegen/intrinsics/offset.rs index d76d3e705ab..cf0c7c7ac7d 100644 --- a/tests/codegen/intrinsics/offset.rs +++ b/tests/codegen/intrinsics/offset.rs @@ -27,7 +27,7 @@ pub unsafe fn offset_isize(p: *const u32, d: isize) -> *const u32 { // CHECK-SAME: (ptr noundef %p, [[SIZE]] noundef %d) #[no_mangle] pub unsafe fn offset_usize(p: *const u64, d: usize) -> *const u64 { - // CHECK: %[[R:.*]] = getelementptr inbounds i64, ptr %p, [[SIZE]] %d + // CHECK: %[[R:.*]] = getelementptr inbounds{{( nuw)?}} i64, ptr %p, [[SIZE]] %d // CHECK-NEXT: ret ptr %[[R]] offset(p, d) } diff --git a/tests/codegen/intrinsics/ptr_metadata.rs b/tests/codegen/intrinsics/ptr_metadata.rs index 87a32fa3d24..044dbc20486 100644 --- a/tests/codegen/intrinsics/ptr_metadata.rs +++ b/tests/codegen/intrinsics/ptr_metadata.rs @@ -28,7 +28,7 @@ pub unsafe fn dyn_byte_offset( p: *const dyn std::fmt::Debug, n: usize, ) -> *const dyn std::fmt::Debug { - // CHECK: %[[Q:.+]] = getelementptr inbounds i8, ptr %p.0, i64 %n + // CHECK: %[[Q:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %p.0, i64 %n // CHECK: %[[TEMP1:.+]] = insertvalue { ptr, ptr } poison, ptr %[[Q]], 0 // CHECK: %[[TEMP2:.+]] = insertvalue { ptr, ptr } %[[TEMP1]], ptr %p.1, 1 // CHECK: ret { ptr, ptr } %[[TEMP2]] diff --git a/tests/codegen/ptr-arithmetic.rs b/tests/codegen/ptr-arithmetic.rs index ecb44b30f5c..fc4441ef448 100644 --- a/tests/codegen/ptr-arithmetic.rs +++ b/tests/codegen/ptr-arithmetic.rs @@ -6,7 +6,7 @@ // CHECK-SAME: [[WORD:i[0-9]+]] noundef %n) #[no_mangle] pub unsafe fn i32_add(p: *const i32, n: usize) -> *const i32 { - // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %n + // CHECK: %[[TEMP:.+]] = getelementptr inbounds{{( nuw)?}} i32, ptr %p, [[WORD]] %n // CHECK: ret ptr %[[TEMP]] p.add(n) } -- cgit 1.4.1-3-g733a5 From 511bf307f03d7045f54a376d389ebdf9786e7a24 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 14 Feb 2025 20:25:43 -0800 Subject: Emit `trunc nuw` for unchecked shifts and `to_immediate_scalar` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - For shifts this shrinks the IR by no longer needing an `assume` while still providing the UB information - Having this on the `i8`→`i1` truncations will hopefully help with some places that have to load `i8`s or pass those in LLVM structs without range information --- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_llvm/src/builder.rs | 28 +++++++++++- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_ssa/src/base.rs | 10 +--- compiler/rustc_codegen_ssa/src/traits/builder.rs | 11 +++++ tests/codegen/intrinsics/transmute-niched.rs | 2 +- tests/codegen/intrinsics/transmute.rs | 11 +++-- tests/codegen/transmute-scalar.rs | 2 +- tests/codegen/unchecked_shifts.rs | 58 +++++++++++------------- tests/codegen/union-abi.rs | 2 +- 10 files changed, 77 insertions(+), 50 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index b8e37b60480..76846692459 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1694,7 +1694,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value { if scalar.is_bool() { - return self.trunc(val, self.cx().type_i1()); + return self.unchecked_utrunc(val, self.cx().type_i1()); } val } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index e10a4d63407..18bb6a609aa 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -29,13 +29,13 @@ use smallvec::SmallVec; use tracing::{debug, instrument}; use crate::abi::FnAbiLlvmExt; -use crate::attributes; use crate::common::Funclet; use crate::context::{CodegenCx, SimpleCx}; use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, Metadata, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; +use crate::{attributes, llvm_util}; #[must_use] pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow>> { @@ -606,7 +606,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value { if scalar.is_bool() { - return self.trunc(val, self.cx().type_i1()); + return self.unchecked_utrunc(val, self.cx().type_i1()); } val } @@ -942,6 +942,30 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) } } + fn unchecked_utrunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + let trunc = self.trunc(val, dest_ty); + if llvm_util::get_version() >= (19, 0, 0) { + unsafe { + if llvm::LLVMIsATruncInst(trunc).is_some() { + llvm::LLVMSetNUW(trunc, True); + } + } + } + trunc + } + + fn unchecked_strunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + let trunc = self.trunc(val, dest_ty); + if llvm_util::get_version() >= (19, 0, 0) { + unsafe { + if llvm::LLVMIsATruncInst(trunc).is_some() { + llvm::LLVMSetNSW(trunc, True); + } + } + } + trunc + } + fn sext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3b0187b9d37..1e105e86189 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1165,6 +1165,7 @@ unsafe extern "C" { // Operations on instructions pub(crate) fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>; + pub(crate) fn LLVMIsATruncInst(Val: &Value) -> Option<&Value>; pub(crate) fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; pub(crate) fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index e800492dad0..a989e9c64c0 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -24,7 +24,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::Session; -use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; +use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; use rustc_span::{DUMMY_SP, Symbol, sym}; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; @@ -364,13 +364,7 @@ pub(crate) fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let rhs_sz = bx.cx().int_width(rhs_llty); let lhs_sz = bx.cx().int_width(lhs_llty); if lhs_sz < rhs_sz { - if is_unchecked && bx.sess().opts.optimize != OptLevel::No { - // FIXME: Use `trunc nuw` once that's available - let inrange = bx.icmp(IntPredicate::IntULE, rhs, mask); - bx.assume(inrange); - } - - bx.trunc(rhs, lhs_llty) + if is_unchecked { bx.unchecked_utrunc(rhs, lhs_llty) } else { bx.trunc(rhs, lhs_llty) } } else if lhs_sz > rhs_sz { // We zero-extend even if the RHS is signed. So e.g. `(x: i32) << -1i8` will zero-extend the // RHS to `255i32`. But then we mask the shift amount to be within the size of the LHS diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 48ae000f2c6..345db313022 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -340,6 +340,17 @@ pub trait BuilderMethods<'a, 'tcx>: } fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; + /// Produces the same value as [`Self::trunc`] (and defaults to that), + /// but is UB unless the *zero*-extending the result can reproduce `val`. + fn unchecked_utrunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value { + self.trunc(val, dest_ty) + } + /// Produces the same value as [`Self::trunc`] (and defaults to that), + /// but is UB unless the *sign*-extending the result can reproduce `val`. + fn unchecked_strunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value { + self.trunc(val, dest_ty) + } + fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs index 5ded0e192fa..8ff5cc8ee4f 100644 --- a/tests/codegen/intrinsics/transmute-niched.rs +++ b/tests/codegen/intrinsics/transmute-niched.rs @@ -170,7 +170,7 @@ pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool { // OPT: call void @llvm.assume(i1 %2) // CHECK-NOT: icmp // CHECK-NOT: assume - // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1 // CHECK: ret i1 %[[R]] transmute(x) diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 5b40a6a12c0..ff297b27065 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -11,6 +11,9 @@ use std::intrinsics::mir::*; use std::intrinsics::{transmute, transmute_unchecked}; use std::mem::MaybeUninit; +// FIXME(LLVM18REMOVED): `trunc nuw` doesn't exist in LLVM 18, so once we no +// longer support it the optional flag checks can be changed to required. + pub enum ZstNever {} #[repr(align(2))] @@ -153,7 +156,7 @@ pub unsafe fn check_from_newtype(x: Scalar64) -> u64 { pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool { // CHECK: %x = alloca [1 x i8], align 1 // CHECK: %[[BYTE:.+]] = load i8, ptr %x, align 1 - // CHECK: %[[BOOL:.+]] = trunc i8 %[[BYTE]] to i1 + // CHECK: %[[BOOL:.+]] = trunc{{( nuw)?}} i8 %[[BYTE]] to i1 // CHECK: ret i1 %[[BOOL]] transmute(x) } @@ -171,7 +174,7 @@ pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 { #[no_mangle] pub unsafe fn check_byte_to_bool(x: u8) -> bool { // CHECK-NOT: alloca - // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1 // CHECK: ret i1 %[[R]] transmute(x) } @@ -284,7 +287,7 @@ pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] { #[no_mangle] pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) { // CHECK-NOT: alloca - // CHECK: trunc i8 %x.0 to i1 + // CHECK: trunc{{( nuw)?}} i8 %x.0 to i1 // CHECK: zext i1 %x.1 to i8 transmute(x) } @@ -338,7 +341,7 @@ pub unsafe fn check_heterogeneous_integer_pair(x: (i32, bool)) -> (bool, u32) { // CHECK: store i8 %[[WIDER]] // CHECK: %[[BYTE:.+]] = load i8 - // CHECK: trunc i8 %[[BYTE:.+]] to i1 + // CHECK: trunc{{( nuw)?}} i8 %[[BYTE:.+]] to i1 // CHECK: load i32 transmute(x) } diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs index 43da7c1781e..c080259a917 100644 --- a/tests/codegen/transmute-scalar.rs +++ b/tests/codegen/transmute-scalar.rs @@ -26,7 +26,7 @@ pub fn bool_to_byte(b: bool) -> u8 { } // CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8{{.*}} %byte) -// CHECK: %_0 = trunc i8 %byte to i1 +// CHECK: %_0 = trunc{{( nuw)?}} i8 %byte to i1 // CHECK-NEXT: ret i1 %_0 #[no_mangle] pub unsafe fn byte_to_bool(byte: u8) -> bool { diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs index b27eb73c0cc..a0d8990d29f 100644 --- a/tests/codegen/unchecked_shifts.rs +++ b/tests/codegen/unchecked_shifts.rs @@ -1,4 +1,10 @@ -//@ compile-flags: -Copt-level=3 +//@ revisions: LLVM18 LLVM19PLUS +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes +//@[LLVM18] exact-llvm-major-version: 18 +//@[LLVM19PLUS] min-llvm-version: 19 + +// This runs mir-opts to inline the standard library call, but doesn't run LLVM +// optimizations so it doesn't need to worry about them adding more flags. #![crate_type = "lib"] #![feature(unchecked_shifts)] @@ -17,12 +23,9 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 { // CHECK-LABEL: @unchecked_shl_unsigned_smaller #[no_mangle] pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16 + // CHECK-NOT: assume + // LLVM18-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16 + // LLVM19PLUS-DAG: %[[TRUNC:.+]] = trunc nuw i32 %b to i16 // CHECK-DAG: shl i16 %a, %[[TRUNC]] a.unchecked_shl(b) } @@ -31,7 +34,7 @@ pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { #[no_mangle] pub unsafe fn unchecked_shl_unsigned_bigger(a: u64, b: u32) -> u64 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64 + // CHECK: %[[EXT:.+]] = zext i32 %b to i64 // CHECK: shl i64 %a, %[[EXT]] a.unchecked_shl(b) } @@ -49,13 +52,10 @@ pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 { // CHECK-LABEL: @unchecked_shr_signed_smaller #[no_mangle] pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16 - // CHECK-DAG: ashr i16 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16 + // CHECK: ashr i16 %a, %[[TRUNC]] a.unchecked_shr(b) } @@ -63,7 +63,7 @@ pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 { #[no_mangle] pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64 + // CHECK: %[[EXT:.+]] = zext i32 %b to i64 // CHECK: ashr i64 %a, %[[EXT]] a.unchecked_shr(b) } @@ -72,7 +72,7 @@ pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 { #[no_mangle] pub unsafe fn unchecked_shr_u128_i8(a: u128, b: i8) -> u128 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128 + // CHECK: %[[EXT:.+]] = zext i8 %b to i128 // CHECK: lshr i128 %a, %[[EXT]] std::intrinsics::unchecked_shr(a, b) } @@ -81,7 +81,7 @@ pub unsafe fn unchecked_shr_u128_i8(a: u128, b: i8) -> u128 { #[no_mangle] pub unsafe fn unchecked_shl_i128_u8(a: i128, b: u8) -> i128 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128 + // CHECK: %[[EXT:.+]] = zext i8 %b to i128 // CHECK: shl i128 %a, %[[EXT]] std::intrinsics::unchecked_shl(a, b) } @@ -89,25 +89,19 @@ pub unsafe fn unchecked_shl_i128_u8(a: i128, b: u8) -> i128 { // CHECK-LABEL: @unchecked_shl_u8_i128 #[no_mangle] pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8 - // CHECK-DAG: shl i8 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8 + // CHECK: shl i8 %a, %[[TRUNC]] std::intrinsics::unchecked_shl(a, b) } // CHECK-LABEL: @unchecked_shr_i8_u128 #[no_mangle] pub unsafe fn unchecked_shr_i8_u128(a: i8, b: u128) -> i8 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8 - // CHECK-DAG: ashr i8 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8 + // CHECK: ashr i8 %a, %[[TRUNC]] std::intrinsics::unchecked_shr(a, b) } diff --git a/tests/codegen/union-abi.rs b/tests/codegen/union-abi.rs index 16022fad8af..28acc4de2f3 100644 --- a/tests/codegen/union-abi.rs +++ b/tests/codegen/union-abi.rs @@ -142,4 +142,4 @@ pub union UnionBool { pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } } -// CHECK: %_0 = trunc i8 %b to i1 +// CHECK: %_0 = trunc{{( nuw)?}} i8 %b to i1 -- cgit 1.4.1-3-g733a5 From 642a705f714eaa73875b9bc9e7848568efc4b890 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 15 Feb 2025 10:24:24 -0800 Subject: PR feedback --- compiler/rustc_codegen_llvm/src/builder.rs | 4 ++-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 - tests/codegen/unchecked_shifts.rs | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 18bb6a609aa..5d1a133e808 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -946,7 +946,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let trunc = self.trunc(val, dest_ty); if llvm_util::get_version() >= (19, 0, 0) { unsafe { - if llvm::LLVMIsATruncInst(trunc).is_some() { + if llvm::LLVMIsAInstruction(trunc).is_some() { llvm::LLVMSetNUW(trunc, True); } } @@ -958,7 +958,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let trunc = self.trunc(val, dest_ty); if llvm_util::get_version() >= (19, 0, 0) { unsafe { - if llvm::LLVMIsATruncInst(trunc).is_some() { + if llvm::LLVMIsAInstruction(trunc).is_some() { llvm::LLVMSetNSW(trunc, True); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 1e105e86189..3b0187b9d37 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1165,7 +1165,6 @@ unsafe extern "C" { // Operations on instructions pub(crate) fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>; - pub(crate) fn LLVMIsATruncInst(Val: &Value) -> Option<&Value>; pub(crate) fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; pub(crate) fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>; diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs index a0d8990d29f..9fccaf2252e 100644 --- a/tests/codegen/unchecked_shifts.rs +++ b/tests/codegen/unchecked_shifts.rs @@ -24,9 +24,9 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 { #[no_mangle] pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { // CHECK-NOT: assume - // LLVM18-DAG: %[[TRUNC:.+]] = trunc i32 %b to i16 - // LLVM19PLUS-DAG: %[[TRUNC:.+]] = trunc nuw i32 %b to i16 - // CHECK-DAG: shl i16 %a, %[[TRUNC]] + // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16 + // CHECK: shl i16 %a, %[[TRUNC]] a.unchecked_shl(b) } -- cgit 1.4.1-3-g733a5 From 6f9cfd694d67ad24af6c7e2235a2da5d22918df0 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 15 Feb 2025 16:07:18 -0800 Subject: Rework `OperandRef::extract_field` to stop calling `to_immediate_scalar` on things which are already immediates That means it stops trying to truncate things that are already `i1`s. --- compiler/rustc_codegen_gcc/src/builder.rs | 12 +- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 11 +- compiler/rustc_codegen_llvm/src/builder.rs | 10 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 10 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 131 +++++++++++----------- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 4 +- compiler/rustc_codegen_ssa/src/traits/builder.rs | 9 +- tests/codegen/simd/project-to-simd-array-field.rs | 31 +++++ tests/crashes/project-to-simd-array-field.rs | 33 ++++++ 9 files changed, 164 insertions(+), 87 deletions(-) create mode 100644 tests/codegen/simd/project-to-simd-array-field.rs create mode 100644 tests/crashes/project-to-simd-array-field.rs (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 76846692459..c8b7616e645 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -989,10 +989,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.val) } else if place.layout.is_gcc_immediate() { let load = self.load(place.layout.gcc_type(self), place.val.llval, place.val.align); - if let abi::BackendRepr::Scalar(ref scalar) = place.layout.backend_repr { - scalar_load_metadata(self, load, scalar); - } - OperandValue::Immediate(self.to_immediate(load, place.layout)) + OperandValue::Immediate( + if let abi::BackendRepr::Scalar(ref scalar) = place.layout.backend_repr { + scalar_load_metadata(self, load, scalar); + self.to_immediate_scalar(load, *scalar) + } else { + load + }, + ) } else if let abi::BackendRepr::ScalarPair(ref a, ref b) = place.layout.backend_repr { let b_offset = a.size(self).align_to(b.align(self).abi); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index a1123fafe2f..5322b731d8b 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -9,7 +9,7 @@ use gccjit::FunctionType; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; -use rustc_abi::HasDataLayout; +use rustc_abi::{BackendRepr, HasDataLayout}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; @@ -181,14 +181,19 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); + let layout = self.layout_of(tp_ty); let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode { let gcc_ty = ty.gcc_type(self); self.volatile_load(gcc_ty, ptr) } else { - self.volatile_load(self.layout_of(tp_ty).gcc_type(self), ptr) + self.volatile_load(layout.gcc_type(self), ptr) }; // TODO(antoyo): set alignment. - self.to_immediate(load, self.layout_of(tp_ty)) + if let BackendRepr::Scalar(scalar) = layout.backend_repr { + self.to_immediate_scalar(load, scalar) + } else { + load + } } sym::volatile_store => { let dst = args[0].deref(self.cx()); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 5d1a133e808..e1609e31c07 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -746,10 +746,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let load = self.load(llty, place.val.llval, place.val.align); if let abi::BackendRepr::Scalar(scalar) = place.layout.backend_repr { scalar_load_metadata(self, load, scalar, place.layout, Size::ZERO); + self.to_immediate_scalar(load, scalar) + } else { + load } - load }); - OperandValue::Immediate(self.to_immediate(llval, place.layout)) + OperandValue::Immediate(llval) } else if let abi::BackendRepr::ScalarPair(a, b) = place.layout.backend_repr { let b_offset = a.size(self).align_to(b.align(self).abi); @@ -943,6 +945,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn unchecked_utrunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + debug_assert_ne!(self.val_ty(val), dest_ty); + let trunc = self.trunc(val, dest_ty); if llvm_util::get_version() >= (19, 0, 0) { unsafe { @@ -955,6 +959,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn unchecked_strunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + debug_assert_ne!(self.val_ty(val), dest_ty); + let trunc = self.trunc(val, dest_ty); if llvm_util::get_version() >= (19, 0, 0) { unsafe { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 616d748a299..0620f08fc73 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1040,7 +1040,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", ); - op = op.extract_field(bx, idx); + op = op.extract_field(self, bx, idx); } // Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its @@ -1072,7 +1072,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", ); - op = op.extract_field(bx, idx); + op = op.extract_field(self, bx, idx); } // Make sure that we've actually unwrapped the rcvr down @@ -1572,9 +1572,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if scalar.is_bool() { bx.range_metadata(llval, WrappingRange { start: 0, end: 1 }); } + // We store bools as `i8` so we need to truncate to `i1`. + llval = bx.to_immediate_scalar(llval, scalar); } - // We store bools as `i8` so we need to truncate to `i1`. - llval = bx.to_immediate(llval, arg.layout); } } @@ -1604,7 +1604,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { // If the tuple is immediate, the elements are as well. for i in 0..tuple.layout.fields.count() { - let op = tuple.extract_field(bx, i); + let op = tuple.extract_field(self, bx, i); self.codegen_argument(bx, op, llargs, &args[i]); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 9ca7d4f8f00..958a52a2cb1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -1,15 +1,14 @@ -use std::assert_matches::assert_matches; use std::fmt; use arrayvec::ArrayVec; use either::Either; use rustc_abi as abi; use rustc_abi::{Align, BackendRepr, Size}; -use rustc_middle::bug; use rustc_middle::mir::interpret::{Pointer, Scalar, alloc_range}; use rustc_middle::mir::{self, ConstValue}; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::{bug, span_bug}; use tracing::debug; use super::place::{PlaceRef, PlaceValue}; @@ -352,79 +351,83 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub(crate) fn extract_field>( &self, + fx: &mut FunctionCx<'a, 'tcx, Bx>, bx: &mut Bx, i: usize, ) -> Self { let field = self.layout.field(bx.cx(), i); let offset = self.layout.fields.offset(i); - let mut val = match (self.val, self.layout.backend_repr) { - // If the field is ZST, it has no data. - _ if field.is_zst() => OperandValue::ZeroSized, - - // Newtype of a scalar, scalar pair or vector. - (OperandValue::Immediate(_) | OperandValue::Pair(..), _) - if field.size == self.layout.size => - { - assert_eq!(offset.bytes(), 0); - self.val + let val = if field.is_zst() { + OperandValue::ZeroSized + } else if field.size == self.layout.size { + assert_eq!(offset.bytes(), 0); + if let Some(field_val) = fx.codegen_transmute_operand(bx, *self, field) { + field_val + } else { + // we have to go through memory for things like + // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); + let place = PlaceRef::alloca(bx, field); + self.val.store(bx, place.val.with_type(self.layout)); + bx.load_operand(place).val } - - // Extract a scalar component from a pair. - (OperandValue::Pair(a_llval, b_llval), BackendRepr::ScalarPair(a, b)) => { - if offset.bytes() == 0 { - assert_eq!(field.size, a.size(bx.cx())); - OperandValue::Immediate(a_llval) - } else { - assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi)); - assert_eq!(field.size, b.size(bx.cx())); - OperandValue::Immediate(b_llval) + } else { + let (in_scalar, imm) = match (self.val, self.layout.backend_repr) { + // Extract a scalar component from a pair. + (OperandValue::Pair(a_llval, b_llval), BackendRepr::ScalarPair(a, b)) => { + if offset.bytes() == 0 { + assert_eq!(field.size, a.size(bx.cx())); + (Some(a), a_llval) + } else { + assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi)); + assert_eq!(field.size, b.size(bx.cx())); + (Some(b), b_llval) + } } - } - // `#[repr(simd)]` types are also immediate. - (OperandValue::Immediate(llval), BackendRepr::Vector { .. }) => { - OperandValue::Immediate(bx.extract_element(llval, bx.cx().const_usize(i as u64))) - } + // `#[repr(simd)]` types are also immediate. + (OperandValue::Immediate(llval), BackendRepr::Vector { .. }) => { + (None, bx.extract_element(llval, bx.cx().const_usize(i as u64))) + } - _ => bug!("OperandRef::extract_field({:?}): not applicable", self), + _ => { + span_bug!(fx.mir.span, "OperandRef::extract_field({:?}): not applicable", self) + } + }; + OperandValue::Immediate(match field.backend_repr { + BackendRepr::Vector { .. } => imm, + BackendRepr::Scalar(out_scalar) => { + let Some(in_scalar) = in_scalar else { + span_bug!( + fx.mir.span, + "OperandRef::extract_field({:?}): missing input scalar for output scalar", + self + ) + }; + if in_scalar != out_scalar { + // If the backend and backend_immediate types might differ, + // flip back to the backend type then to the new immediate. + // This avoids nop truncations, but still handles things like + // Bools in union fields needs to be truncated. + let backend = bx.from_immediate(imm); + bx.to_immediate_scalar(backend, out_scalar) + } else { + imm + } + } + BackendRepr::Memory { sized: true } => { + span_bug!( + fx.mir.span, + "Projecting into a simd type with padding doesn't work; \ + See ", + ); + } + BackendRepr::Uninhabited + | BackendRepr::ScalarPair(_, _) + | BackendRepr::Memory { sized: false } => bug!(), + }) }; - match (&mut val, field.backend_repr) { - (OperandValue::ZeroSized, _) => {} - ( - OperandValue::Immediate(llval), - BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. }, - ) => { - // Bools in union fields needs to be truncated. - *llval = bx.to_immediate(*llval, field); - } - (OperandValue::Pair(a, b), BackendRepr::ScalarPair(a_abi, b_abi)) => { - // Bools in union fields needs to be truncated. - *a = bx.to_immediate_scalar(*a, a_abi); - *b = bx.to_immediate_scalar(*b, b_abi); - } - // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); - (OperandValue::Immediate(llval), BackendRepr::Memory { sized: true }) => { - assert_matches!(self.layout.backend_repr, BackendRepr::Vector { .. }); - - let llfield_ty = bx.cx().backend_type(field); - - // Can't bitcast an aggregate, so round trip through memory. - let llptr = bx.alloca(field.size, field.align.abi); - bx.store(*llval, llptr, field.align.abi); - *llval = bx.load(llfield_ty, llptr, field.align.abi); - } - ( - OperandValue::Immediate(_), - BackendRepr::Uninhabited | BackendRepr::Memory { sized: false }, - ) => { - bug!() - } - (OperandValue::Pair(..), _) => bug!(), - (OperandValue::Ref(..), _) => bug!(), - } - OperandRef { val, layout: field } } } @@ -587,7 +590,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \ but tried to access field {f:?} of pointer {o:?}", ); - o = o.extract_field(bx, f.index()); + o = o.extract_field(self, bx, f.index()); } mir::ProjectionElem::Index(_) | mir::ProjectionElem::ConstantIndex { .. } => { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 4c5b183cfe9..daa4fa90ed7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// /// Returns `None` for cases that can't work in that framework, such as for /// `Immediate`->`Ref` that needs an `alloc` to get the location. - fn codegen_transmute_operand( + pub(crate) fn codegen_transmute_operand( &mut self, bx: &mut Bx, operand: OperandRef<'tcx, Bx::Value>, @@ -260,6 +260,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(source_place_val) => { assert_eq!(source_place_val.llextra, None); assert_matches!(operand_kind, OperandValueKind::Ref); + // The existing alignment is part of `source_place_val`, + // so that alignment will be used, not `cast`'s. Some(bx.load_operand(source_place_val.with_type(cast)).val) } OperandValue::ZeroSized => { diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 345db313022..2b00ba01946 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -1,7 +1,7 @@ use std::assert_matches::assert_matches; use std::ops::Deref; -use rustc_abi::{Align, BackendRepr, Scalar, Size, WrappingRange}; +use rustc_abi::{Align, Scalar, Size, WrappingRange}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; use rustc_middle::ty::{Instance, Ty}; @@ -223,13 +223,6 @@ pub trait BuilderMethods<'a, 'tcx>: ) -> (Self::Value, Self::Value); fn from_immediate(&mut self, val: Self::Value) -> Self::Value; - fn to_immediate(&mut self, val: Self::Value, layout: TyAndLayout<'_>) -> Self::Value { - if let BackendRepr::Scalar(scalar) = layout.backend_repr { - self.to_immediate_scalar(val, scalar) - } else { - val - } - } fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, size: Size, align: Align) -> Self::Value; diff --git a/tests/codegen/simd/project-to-simd-array-field.rs b/tests/codegen/simd/project-to-simd-array-field.rs new file mode 100644 index 00000000000..29fab640633 --- /dev/null +++ b/tests/codegen/simd/project-to-simd-array-field.rs @@ -0,0 +1,31 @@ +//@compile-flags: -Copt-level=3 + +#![crate_type = "lib"] +#![feature(repr_simd, core_intrinsics)] + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(simd)] +struct i32x4([i32; 4]); + +#[inline(always)] +fn to_array4(a: i32x4) -> [i32; 4] { + a.0 +} + +// CHECK-LABEL: simd_add_self_then_return_array( +// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]], +// CHECK-SAME: ptr{{.+}}%a) +#[no_mangle] +pub fn simd_add_self_then_return_array(a: &i32x4) -> [i32; 4] { + // It would be nice to just ban `.0` into simd types, + // but until we do this has to keep working. + // See also + + // CHECK: %[[T1:.+]] = load <4 x i32>, ptr %a + // CHECK: %[[T2:.+]] = shl <4 x i32> %[[T1]], {{splat \(i32 1\)|}} + // CHECK: store <4 x i32> %[[T2]], ptr %[[RET]] + let a = *a; + let b = unsafe { core::intrinsics::simd::simd_add(a, a) }; + to_array4(b) +} diff --git a/tests/crashes/project-to-simd-array-field.rs b/tests/crashes/project-to-simd-array-field.rs new file mode 100644 index 00000000000..6dc916c41db --- /dev/null +++ b/tests/crashes/project-to-simd-array-field.rs @@ -0,0 +1,33 @@ +//@ known-bug: #137108 +//@compile-flags: -Copt-level=3 + +// If you fix this, put it in the corresponding codegen test, +// not in a UI test like the readme says. + +#![crate_type = "lib"] + +#![feature(repr_simd, core_intrinsics)] + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(simd)] +struct i32x3([i32; 3]); + +const _: () = { assert!(size_of::() == 16) }; + +#[inline(always)] +fn to_array3(a: i32x3) -> [i32; 3] { + a.0 +} + +// CHECK-LABEL: simd_add_self_then_return_array_packed( +// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]], +// CHECK-SAME: ptr{{.+}}%a) +#[no_mangle] +pub fn simd_add_self_then_return_array_packed(a: i32x3) -> [i32; 3] { + // CHECK: %[[T1:.+]] = load <3 x i32>, ptr %a + // CHECK: %[[T2:.+]] = shl <3 x i32> %[[T1]], + // CHECK: store <3 x i32> %[[T2]], ptr %[[RET]] + let b = unsafe { core::intrinsics::simd::simd_add(a, a) }; + to_array3(b) +} -- cgit 1.4.1-3-g733a5 From ea7180813b4dface2bc02a9095ce1ebb8c64d4de Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Feb 2025 17:27:49 +0000 Subject: Create safe helper for LLVMSetDLLStorageClass --- compiler/rustc_codegen_llvm/src/callee.rs | 6 ++---- compiler/rustc_codegen_llvm/src/consts.rs | 8 ++------ compiler/rustc_codegen_llvm/src/llvm/mod.rs | 6 ++++++ 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index aa9a0f34f55..90075e1c105 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -66,9 +66,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t // LLVM will prefix the name with `__imp_`. Ideally, we'd like the // existing logic below to set the Storage Class, but it has an // exemption for MinGW for backwards compatibility. - unsafe { - llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); - } + llvm::set_dllimport_storage_class(llfn); llfn } else { cx.declare_fn(sym, fn_abi, Some(instance)) @@ -150,7 +148,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t && library.kind.is_dllimport() && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc") { - llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); + llvm::set_dllimport_storage_class(llfn); } if cx.should_assume_dso_local(llfn, true) { diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 4a5491ec7a1..5ab437d27c2 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -375,9 +375,7 @@ impl<'ll> CodegenCx<'ll, '_> { // is actually present in the current crate. We can find out via the // is_codegened_item query. if !self.tcx.is_codegened_item(def_id) { - unsafe { - llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); - } + llvm::set_dllimport_storage_class(g); } } } @@ -387,9 +385,7 @@ impl<'ll> CodegenCx<'ll, '_> { && library.kind.is_dllimport() { // For foreign (native) libs we know the exact storage type to use. - unsafe { - llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); - } + llvm::set_dllimport_storage_class(g); } self.instances.borrow_mut().insert(instance, g); diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index efc9cf2ef69..7f57e640637 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -403,3 +403,9 @@ pub(crate) fn add_module_flag_str( ); } } + +pub(crate) fn set_dllimport_storage_class<'ll>(v: &'ll Value) { + unsafe { + LLVMSetDLLStorageClass(v, DLLStorageClass::DllImport); + } +} -- cgit 1.4.1-3-g733a5 From ce7f58bd91548fd8674aaceb670f827de26d4216 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 14 Feb 2025 17:27:49 +0000 Subject: Merge two operations that were always performed together --- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/callee.rs | 102 +++++++++++++-------------- compiler/rustc_codegen_llvm/src/consts.rs | 11 +-- compiler/rustc_codegen_llvm/src/llvm/mod.rs | 6 ++ compiler/rustc_codegen_llvm/src/mono_item.rs | 25 ++++--- 5 files changed, 70 insertions(+), 76 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 7262fce4911..3e25b94961b 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -362,8 +362,8 @@ fn fat_lto( ptr as *const *const libc::c_char, symbols_below_threshold.len() as libc::size_t, ); - save_temp_bitcode(cgcx, &module, "lto.after-restriction"); } + save_temp_bitcode(cgcx, &module, "lto.after-restriction"); } Ok(LtoModuleCodegen::Fat(module)) diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 90075e1c105..ea9ab5c02bd 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -97,65 +97,61 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t // has been applied to the definition (wherever that definition may be). llvm::set_linkage(llfn, llvm::Linkage::ExternalLinkage); - unsafe { - let is_generic = instance.args.non_erasable_generics().next().is_some(); - - let is_hidden = if is_generic { - // This is a monomorphization of a generic function. - if !(cx.tcx.sess.opts.share_generics() - || tcx.codegen_fn_attrs(instance_def_id).inline - == rustc_attr_parsing::InlineAttr::Never) - { - // When not sharing generics, all instances are in the same - // crate and have hidden visibility. - true - } else { - if let Some(instance_def_id) = instance_def_id.as_local() { - // This is a monomorphization of a generic function - // defined in the current crate. It is hidden if: - // - the definition is unreachable for downstream - // crates, or - // - the current crate does not re-export generics - // (because the crate is a C library or executable) - cx.tcx.is_unreachable_local_definition(instance_def_id) - || !cx.tcx.local_crate_exports_generics() - } else { - // This is a monomorphization of a generic function - // defined in an upstream crate. It is hidden if: - // - it is instantiated in this crate, and - // - the current crate does not re-export generics - instance.upstream_monomorphization(tcx).is_none() - && !cx.tcx.local_crate_exports_generics() - } - } - } else { - // This is a non-generic function. It is hidden if: - // - it is instantiated in the local crate, and - // - it is defined an upstream crate (non-local), or - // - it is not reachable - cx.tcx.is_codegened_item(instance_def_id) - && (!instance_def_id.is_local() - || !cx.tcx.is_reachable_non_generic(instance_def_id)) - }; - if is_hidden { - llvm::set_visibility(llfn, llvm::Visibility::Hidden); - } + let is_generic = instance.args.non_erasable_generics().next().is_some(); - // MinGW: For backward compatibility we rely on the linker to decide whether it - // should use dllimport for functions. - if cx.use_dll_storage_attrs - && let Some(library) = tcx.native_library(instance_def_id) - && library.kind.is_dllimport() - && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc") + let is_hidden = if is_generic { + // This is a monomorphization of a generic function. + if !(cx.tcx.sess.opts.share_generics() + || tcx.codegen_fn_attrs(instance_def_id).inline + == rustc_attr_parsing::InlineAttr::Never) { - llvm::set_dllimport_storage_class(llfn); + // When not sharing generics, all instances are in the same + // crate and have hidden visibility. + true + } else { + if let Some(instance_def_id) = instance_def_id.as_local() { + // This is a monomorphization of a generic function + // defined in the current crate. It is hidden if: + // - the definition is unreachable for downstream + // crates, or + // - the current crate does not re-export generics + // (because the crate is a C library or executable) + cx.tcx.is_unreachable_local_definition(instance_def_id) + || !cx.tcx.local_crate_exports_generics() + } else { + // This is a monomorphization of a generic function + // defined in an upstream crate. It is hidden if: + // - it is instantiated in this crate, and + // - the current crate does not re-export generics + instance.upstream_monomorphization(tcx).is_none() + && !cx.tcx.local_crate_exports_generics() + } } + } else { + // This is a non-generic function. It is hidden if: + // - it is instantiated in the local crate, and + // - it is defined an upstream crate (non-local), or + // - it is not reachable + cx.tcx.is_codegened_item(instance_def_id) + && (!instance_def_id.is_local() + || !cx.tcx.is_reachable_non_generic(instance_def_id)) + }; + if is_hidden { + llvm::set_visibility(llfn, llvm::Visibility::Hidden); + } - if cx.should_assume_dso_local(llfn, true) { - llvm::LLVMRustSetDSOLocal(llfn, true); - } + // MinGW: For backward compatibility we rely on the linker to decide whether it + // should use dllimport for functions. + if cx.use_dll_storage_attrs + && let Some(library) = tcx.native_library(instance_def_id) + && library.kind.is_dllimport() + && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc") + { + llvm::set_dllimport_storage_class(llfn); } + cx.assume_dso_local(llfn, true); + llfn }; diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 5ab437d27c2..330e8a8f406 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -336,12 +336,7 @@ impl<'ll> CodegenCx<'ll, '_> { llvm::set_thread_local_mode(g, self.tls_model); } - let dso_local = self.should_assume_dso_local(g, true); - if dso_local { - unsafe { - llvm::LLVMRustSetDSOLocal(g, true); - } - } + let dso_local = self.assume_dso_local(g, true); if !def_id.is_local() { let needs_dll_storage_attr = self.use_dll_storage_attrs @@ -456,9 +451,7 @@ impl<'ll> CodegenCx<'ll, '_> { set_global_alignment(self, g, alloc.align); llvm::set_initializer(g, v); - if self.should_assume_dso_local(g, true) { - llvm::LLVMRustSetDSOLocal(g, true); - } + self.assume_dso_local(g, true); // Forward the allocation's mutability (picked by the const interner) to LLVM. if alloc.mutability.is_not() { diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 7f57e640637..5ec93424131 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -409,3 +409,9 @@ pub(crate) fn set_dllimport_storage_class<'ll>(v: &'ll Value) { LLVMSetDLLStorageClass(v, DLLStorageClass::DllImport); } } + +pub(crate) fn set_dso_local<'ll>(v: &'ll Value) { + unsafe { + LLVMRustSetDSOLocal(v, true); + } +} diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 70edee21bd6..a64627eaf59 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -38,11 +38,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::set_linkage(g, base::linkage_to_llvm(linkage)); llvm::set_visibility(g, base::visibility_to_llvm(visibility)); - unsafe { - if self.should_assume_dso_local(g, false) { - llvm::LLVMRustSetDSOLocal(g, true); - } - } + self.assume_dso_local(g, false); self.instances.borrow_mut().insert(instance, g); } @@ -79,9 +75,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { debug!("predefine_fn: instance = {:?}", instance); - if self.should_assume_dso_local(lldecl, false) { - unsafe { llvm::LLVMRustSetDSOLocal(lldecl, true) }; - } + self.assume_dso_local(lldecl, false); self.instances.borrow_mut().insert(instance, lldecl); } @@ -90,11 +84,16 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { impl CodegenCx<'_, '_> { /// Whether a definition or declaration can be assumed to be local to a group of /// libraries that form a single DSO or executable. - pub(crate) fn should_assume_dso_local( - &self, - llval: &llvm::Value, - is_declaration: bool, - ) -> bool { + /// Marks the local as DSO if so. + pub(crate) fn assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { + let assume = self.should_assume_dso_local(llval, is_declaration); + if assume { + llvm::set_dso_local(llval); + } + assume + } + + fn should_assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { let linkage = llvm::get_linkage(llval); let visibility = llvm::get_visibility(llval); -- cgit 1.4.1-3-g733a5 From 7ba3d7b54e7688f6f1a0fd22fe274ee7b06fea3e Mon Sep 17 00:00:00 2001 From: Zachary S Date: Sat, 25 Jan 2025 20:15:24 -0600 Subject: Remove `BackendRepr::Uninhabited`, replaced with an `uninhabited: bool` field in `LayoutData`. Also update comments that refered to BackendRepr::Uninhabited. --- compiler/rustc_abi/src/callconv.rs | 2 -- compiler/rustc_abi/src/layout.rs | 23 +++++++------- compiler/rustc_abi/src/lib.rs | 35 ++++++++++------------ .../rustc_codegen_cranelift/src/value_and_place.rs | 4 +-- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 13 ++++---- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 13 ++++---- compiler/rustc_codegen_ssa/src/mir/operand.rs | 4 +-- compiler/rustc_const_eval/src/interpret/operand.rs | 2 +- .../rustc_const_eval/src/interpret/validity.rs | 8 ++--- .../src/util/check_validity_requirement.rs | 16 +++++----- compiler/rustc_middle/src/ty/layout.rs | 3 +- compiler/rustc_mir_transform/src/gvn.rs | 5 +++- compiler/rustc_smir/src/rustc_smir/convert/abi.rs | 1 - compiler/rustc_target/src/callconv/loongarch.rs | 2 +- compiler/rustc_target/src/callconv/mod.rs | 3 +- compiler/rustc_target/src/callconv/riscv.rs | 2 +- compiler/rustc_target/src/callconv/x86.rs | 4 +-- compiler/rustc_target/src/callconv/x86_64.rs | 2 -- compiler/rustc_target/src/callconv/x86_win64.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 4 +-- compiler/rustc_ty_utils/src/layout.rs | 21 ++++++------- compiler/rustc_ty_utils/src/layout/invariant.rs | 15 ++++++---- compiler/stable_mir/src/abi.rs | 6 +--- .../rust-analyzer/crates/hir-ty/src/layout.rs | 12 ++++---- 26 files changed, 93 insertions(+), 113 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 9fb70b80c9e..4529ab8058e 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -65,8 +65,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty: TyAbiInterface<'a, C> + Copy, { match self.backend_repr { - BackendRepr::Uninhabited => Err(Heterogeneous), - // The primitive for this algorithm. BackendRepr::Scalar(scalar) => { let kind = match scalar.primitive() { diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 45cd0b517f6..53243266f99 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -130,6 +130,7 @@ impl LayoutCalculator { }, backend_repr: BackendRepr::ScalarPair(a, b), largest_niche, + uninhabited: false, align, size, max_repr_align: None, @@ -221,8 +222,9 @@ impl LayoutCalculator { LayoutData { variants: Variants::Empty, fields: FieldsShape::Primitive, - backend_repr: BackendRepr::Uninhabited, + backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, + uninhabited: true, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, @@ -400,6 +402,7 @@ impl LayoutCalculator { fields: FieldsShape::Union(union_field_count), backend_repr: abi, largest_niche: None, + uninhabited: false, align, size: size.align_to(align.abi), max_repr_align, @@ -447,7 +450,6 @@ impl LayoutCalculator { Scalar::Union { .. } => {} }; match &mut st.backend_repr { - BackendRepr::Uninhabited => {} BackendRepr::Scalar(scalar) => hide_niches(scalar), BackendRepr::ScalarPair(a, b) => { hide_niches(a); @@ -639,9 +641,8 @@ impl LayoutCalculator { let same_size = size == variant_layouts[largest_variant_index].size; let same_align = align == variant_layouts[largest_variant_index].align; - let abi = if variant_layouts.iter().all(|v| v.is_uninhabited()) { - BackendRepr::Uninhabited - } else if same_size && same_align && others_zst { + let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); + let abi = if same_size && same_align && others_zst { match variant_layouts[largest_variant_index].backend_repr { // When the total alignment and size match, we can use the // same ABI as the scalar variant with the reserved niche. @@ -683,6 +684,7 @@ impl LayoutCalculator { }, backend_repr: abi, largest_niche, + uninhabited, size, align, max_repr_align, @@ -853,9 +855,8 @@ impl LayoutCalculator { }; let mut abi = BackendRepr::Memory { sized: true }; - if layout_variants.iter().all(|v| v.is_uninhabited()) { - abi = BackendRepr::Uninhabited; - } else if tag.size(dl) == size { + let uninhabited = layout_variants.iter().all(|v| v.is_uninhabited()); + if tag.size(dl) == size { // Make sure we only use scalar layout when the enum is entirely its // own tag (i.e. it has no padding nor any non-ZST variant fields). abi = BackendRepr::Scalar(tag); @@ -995,6 +996,7 @@ impl LayoutCalculator { memory_index: [0].into(), }, largest_niche, + uninhabited, backend_repr: abi, align, size, @@ -1355,9 +1357,7 @@ impl LayoutCalculator { _ => {} } } - if fields.iter().any(|f| f.is_uninhabited()) { - abi = BackendRepr::Uninhabited; - } + let uninhabited = fields.iter().any(|f| f.is_uninhabited()); let unadjusted_abi_align = if repr.transparent() { match layout_of_single_non_zst_field { @@ -1378,6 +1378,7 @@ impl LayoutCalculator { fields: FieldsShape::Arbitrary { offsets, memory_index }, backend_repr: abi, largest_niche, + uninhabited, align, size, max_repr_align, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index dbb4bed5cdd..14a8a579200 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1404,7 +1404,6 @@ impl AddressSpace { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] pub enum BackendRepr { - Uninhabited, Scalar(Scalar), ScalarPair(Scalar, Scalar), Vector { @@ -1423,10 +1422,9 @@ impl BackendRepr { #[inline] pub fn is_unsized(&self) -> bool { match *self { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::ScalarPair(..) - | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { + false + } BackendRepr::Memory { sized } => !sized, } } @@ -1445,12 +1443,6 @@ impl BackendRepr { } } - /// Returns `true` if this is an uninhabited type - #[inline] - pub fn is_uninhabited(&self) -> bool { - matches!(*self, BackendRepr::Uninhabited) - } - /// Returns `true` if this is a scalar type #[inline] pub fn is_scalar(&self) -> bool { @@ -1471,7 +1463,7 @@ impl BackendRepr { BackendRepr::Vector { element, count } => { cx.data_layout().vector_align(element.size(cx) * count) } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None, + BackendRepr::Memory { .. } => return None, }) } @@ -1492,7 +1484,7 @@ impl BackendRepr { // to make the size a multiple of align (e.g. for vectors of size 3). (element.size(cx) * count).align_to(self.inherent_align(cx)?.abi) } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None, + BackendRepr::Memory { .. } => return None, }) } @@ -1506,9 +1498,7 @@ impl BackendRepr { BackendRepr::Vector { element, count } => { BackendRepr::Vector { element: element.to_union(), count } } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - BackendRepr::Memory { sized: true } - } + BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, } } @@ -1704,6 +1694,11 @@ pub struct LayoutData { /// The leaf scalar with the largest number of invalid values /// (i.e. outside of its `valid_range`), if it exists. pub largest_niche: Option, + /// Is this type known to be uninhabted? + /// + /// This is separate from BackendRepr, because an uninhabited return type may require special + /// consideration based on its size or other attributes. + pub uninhabited: bool, pub align: AbiAndPrefAlign, pub size: Size, @@ -1735,14 +1730,14 @@ impl LayoutData { /// Returns `true` if this is an aggregate type (including a ScalarPair!) pub fn is_aggregate(&self) -> bool { match self.backend_repr { - BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true, } } /// Returns `true` if this is an uninhabited type pub fn is_uninhabited(&self) -> bool { - self.backend_repr.is_uninhabited() + self.uninhabited } pub fn scalar(cx: &C, scalar: Scalar) -> Self { @@ -1778,6 +1773,7 @@ impl LayoutData { fields: FieldsShape::Primitive, backend_repr: BackendRepr::Scalar(scalar), largest_niche, + uninhabited: false, size, align, max_repr_align: None, @@ -1802,6 +1798,7 @@ where backend_repr, fields, largest_niche, + uninhabited, variants, max_repr_align, unadjusted_abi_align, @@ -1813,6 +1810,7 @@ where .field("abi", backend_repr) .field("fields", fields) .field("largest_niche", largest_niche) + .field("uninhabited", uninhabited) .field("variants", variants) .field("max_repr_align", max_repr_align) .field("unadjusted_abi_align", unadjusted_abi_align) @@ -1877,7 +1875,6 @@ impl LayoutData { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { false } - BackendRepr::Uninhabited => self.size.bytes() == 0, BackendRepr::Memory { sized } => sized && self.size.bytes() == 0, } } diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index a9b8e1bd393..1b3f86c8405 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -638,9 +638,7 @@ impl<'tcx> CPlace<'tcx> { } CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self), CPlaceInner::Addr(to_ptr, None) => { - if dst_layout.size == Size::ZERO - || dst_layout.backend_repr == BackendRepr::Uninhabited - { + if dst_layout.size == Size::ZERO { return; } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 5322b731d8b..433868e238a 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -315,7 +315,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 8b8b54753e7..bac4fc51300 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( false, ); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} + BackendRepr::Memory { .. } => {} } let name = match *layout.ty.kind() { @@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_gcc_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7e1a9d361e6..f68365f6c69 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -476,7 +476,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let layout = self.layout_of(tp_ty).layout; let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index b0b6da869da..ba01fbff385 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} + BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} } let name = match layout.ty.kind() { @@ -172,19 +172,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_llvm_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 958a52a2cb1..faf1300e473 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -422,9 +422,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { See ", ); } - BackendRepr::Uninhabited - | BackendRepr::ScalarPair(_, _) - | BackendRepr::Memory { sized: false } => bug!(), + BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { sized: false } => bug!(), }) }; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 5d905cff1f2..36da9037e43 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -385,7 +385,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { (Immediate::Uninit, _) => Immediate::Uninit, // If the field is uninhabited, we can forget the data (can happen in ConstProp). // `enum S { A(!), B, C }` is an example of an enum with Scalar layout that - // has an `Uninhabited` variant, which means this case is possible. + // has an uninhabited variant, which means this case is possible. _ if layout.is_uninhabited() => Immediate::Uninit, // the field contains no information, can be left uninit // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 0ac34f4633b..3667cc84d70 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1274,11 +1274,11 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, // FIXME: We could avoid some redundant checks here. For newtypes wrapping // scalars, we do the same check on every "level" (e.g., first we check // MyNewtype and then the scalar in there). + if val.layout.is_uninhabited() { + let ty = val.layout.ty; + throw_validation_failure!(self.path, UninhabitedVal { ty }); + } match val.layout.backend_repr { - BackendRepr::Uninhabited => { - let ty = val.layout.ty; - throw_validation_failure!(self.path, UninhabitedVal { ty }); - } BackendRepr::Scalar(scalar_layout) => { if !scalar_layout.is_uninit_valid() { // There is something to check here. diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 79baf91c3ce..6426bca2332 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -111,13 +111,15 @@ fn check_validity_requirement_lax<'tcx>( }; // Check the ABI. - let valid = match this.backend_repr { - BackendRepr::Uninhabited => false, // definitely UB - BackendRepr::Scalar(s) => scalar_allows_raw_init(s), - BackendRepr::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2), - BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), - BackendRepr::Memory { .. } => true, // Fields are checked below. - }; + let valid = !this.is_uninhabited() // definitely UB if uninhabited + && match this.backend_repr { + BackendRepr::Scalar(s) => scalar_allows_raw_init(s), + BackendRepr::ScalarPair(s1, s2) => { + scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2) + } + BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), + BackendRepr::Memory { .. } => true, // Fields are checked below. + }; if !valid { // This is definitely not okay. return Ok(false); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 19fa8323574..eb14ed20fba 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -794,8 +794,9 @@ where Some(fields) => FieldsShape::Union(fields), None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() }, }, - backend_repr: BackendRepr::Uninhabited, + backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, + uninhabited: true, align: tcx.data_layout.i8_align, size: Size::ZERO, max_repr_align: None, diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 77a3854ebde..2f8a3050199 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1558,8 +1558,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return true; }; + if layout.uninhabited { + return true; + } + match layout.backend_repr { - BackendRepr::Uninhabited => true, BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx), BackendRepr::ScalarPair(a, b) => { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index fb2e838cdc9..a627e0e69b6 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -202,7 +202,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { match *self { - rustc_abi::BackendRepr::Uninhabited => ValueAbi::Uninhabited, rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)), rustc_abi::BackendRepr::ScalarPair(first, second) => { ValueAbi::ScalarPair(first.stable(tables), second.stable(tables)) diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index 47566bde6b4..3fa67c624a7 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -80,7 +80,7 @@ where } } }, - BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv), + BackendRepr::Vector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index c2a176facdf..e5f986269dd 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -38,7 +38,7 @@ mod xtensa; pub enum PassMode { /// Ignore the argument. /// - /// The argument is either uninhabited or a ZST. + /// The argument is a ZST. Ignore, /// Pass the argument directly. /// @@ -350,7 +350,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> { scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, Scalar, Size) -> ArgAttributes, ) -> Self { let mode = match layout.backend_repr { - BackendRepr::Uninhabited => PassMode::Ignore, BackendRepr::Scalar(scalar) => { PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO)) } diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index 265ae20f991..785175229b0 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -86,7 +86,7 @@ where } } }, - BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv), + BackendRepr::Vector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 5f4f4cd57f6..7e5aab0201b 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -108,9 +108,7 @@ where Ty: TyAbiInterface<'a, C> + Copy, { match layout.backend_repr { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::ScalarPair(..) => false, + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false, BackendRepr::Vector { .. } => true, BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index b15d82c26da..ab306e20239 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -51,8 +51,6 @@ where } let mut c = match layout.backend_repr { - BackendRepr::Uninhabited => return Ok(()), - BackendRepr::Scalar(scalar) => match scalar.primitive() { Primitive::Int(..) | Primitive::Pointer(_) => Class::Int, Primitive::Float(_) => Class::Sse, diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 2ef5127de04..4d99a9f9ba0 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -8,7 +8,7 @@ use crate::spec::{HasTargetSpec, RustcAbi}; pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| { match a.layout.backend_repr { - BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {} + BackendRepr::Memory { sized: false } => {} BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => { match a.layout.size.bits() { 8 => a.cast_to(Reg::i8()), diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index c5d2d0afbfa..2d20ef3d690 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -472,9 +472,7 @@ fn fn_abi_sanity_check<'tcx>( // `layout.backend_repr` and ignore everything else. We should just reject //`Aggregate` entirely here, but some targets need to be fixed first. match arg.layout.backend_repr { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } => {} + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => {} BackendRepr::ScalarPair(..) => { panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty) } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 556512e0236..b6a14d147ca 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -348,19 +348,17 @@ fn layout_of_uncached<'tcx>( .checked_mul(count, dl) .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; - let abi = if count != 0 && ty.is_privately_uninhabited(tcx, cx.typing_env) { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let abi = BackendRepr::Memory { sized: true }; let largest_niche = if count != 0 { element.largest_niche } else { None }; + let uninhabited = if count != 0 { element.uninhabited } else { false }; tcx.mk_layout(LayoutData { variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr: abi, largest_niche, + uninhabited, align: element.align, size, max_repr_align: None, @@ -375,6 +373,7 @@ fn layout_of_uncached<'tcx>( fields: FieldsShape::Array { stride: element.size, count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: element.align, size: Size::ZERO, max_repr_align: None, @@ -390,6 +389,7 @@ fn layout_of_uncached<'tcx>( fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, @@ -555,6 +555,7 @@ fn layout_of_uncached<'tcx>( fields, backend_repr: abi, largest_niche: e_ly.largest_niche, + uninhabited: false, size, align, max_repr_align: None, @@ -1014,13 +1015,8 @@ fn coroutine_layout<'tcx>( size = size.align_to(align.abi); - let abi = if prefix.backend_repr.is_uninhabited() - || variants.iter().all(|v| v.backend_repr.is_uninhabited()) - { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited()); + let abi = BackendRepr::Memory { sized: true }; // this is similar to how ReprOptions populates its field_shuffle_seed let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash(); @@ -1041,6 +1037,7 @@ fn coroutine_layout<'tcx>( // See , . // FIXME: Remove when is implemented and aliased coroutine fields are wrapped in `UnsafePinned`. largest_niche: None, + uninhabited, size, align, max_repr_align: None, diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 8d5403ed324..5ea6716c5ca 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -10,7 +10,11 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou // Type-level uninhabitedness should always imply ABI uninhabitedness. if layout.ty.is_privately_uninhabited(tcx, cx.typing_env) { - assert!(layout.is_uninhabited()); + assert!( + layout.is_uninhabited(), + "{:?} is type-level uninhabited but not ABI-uninhabited?", + layout.ty + ); } if layout.size.bytes() % layout.align.abi.bytes() != 0 { @@ -71,7 +75,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou let Some((align, size)) = align.zip(size) else { assert_matches!( layout.layout.backend_repr(), - BackendRepr::Uninhabited | BackendRepr::Memory { .. }, + BackendRepr::Memory { .. }, "ABI unexpectedly missing alignment and/or size in {layout:#?}" ); return; @@ -235,7 +239,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`. // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair. } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} // Nothing to check. + BackendRepr::Memory { .. } => {} // Nothing to check. } } @@ -291,8 +295,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou || variant.is_uninhabited() { // These are never actually accessed anyway, so we can skip the coherence check - // for them. They also fail that check, since they have - // `Aggregate`/`Uninhabited` ABI even when the main type is + // for them. They also fail that check, since they may have + // a different ABI even when the main type is // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size // 0, and sometimes, variants without fields have non-0 size.) continue; @@ -306,7 +310,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou (BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => { scalar_coherent(a1, a2) && scalar_coherent(b1, b2) } - (BackendRepr::Uninhabited, _) => true, (BackendRepr::Memory { .. }, _) => true, _ => false, }; diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs index 861b6692b53..091f3e1a95e 100644 --- a/compiler/stable_mir/src/abi.rs +++ b/compiler/stable_mir/src/abi.rs @@ -227,7 +227,6 @@ pub enum TagEncoding { /// in terms of categories of C types there are ABI rules for. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum ValueAbi { - Uninhabited, Scalar(Scalar), ScalarPair(Scalar, Scalar), Vector { @@ -244,10 +243,7 @@ impl ValueAbi { /// Returns `true` if the layout corresponds to an unsized type. pub fn is_unsized(&self) -> bool { match *self { - ValueAbi::Uninhabited - | ValueAbi::Scalar(_) - | ValueAbi::ScalarPair(..) - | ValueAbi::Vector { .. } => false, + ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false, ValueAbi::Aggregate { sized } => !sized, } } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index b6f7c44c2ae..f5a7b658123 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -194,6 +194,7 @@ fn layout_of_simd_ty( fields, backend_repr: BackendRepr::Vector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, + uninhabited: false, size, align, max_repr_align: None, @@ -297,20 +298,17 @@ pub fn layout_of_ty_query( .checked_mul(count, dl) .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?; - let backend_repr = - if count != 0 && matches!(element.backend_repr, BackendRepr::Uninhabited) { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let backend_repr = BackendRepr::Memory { sized: true }; let largest_niche = if count != 0 { element.largest_niche } else { None }; + let uninhabited = if count != 0 { element.uninhabited } else { false }; Layout { variants: Variants::Single { index: struct_variant_idx() }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr, largest_niche, + uninhabited, align: element.align, size, max_repr_align: None, @@ -325,6 +323,7 @@ pub fn layout_of_ty_query( fields: FieldsShape::Array { stride: element.size, count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: element.align, size: Size::ZERO, max_repr_align: None, @@ -337,6 +336,7 @@ pub fn layout_of_ty_query( fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, -- cgit 1.4.1-3-g733a5 From e1819a889a2606b79dc9cc790205da1497d617b7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Feb 2025 18:28:42 +0000 Subject: Fix overcapturing, unsafe extern blocks, and new unsafe ops --- compiler/rustc/src/main.rs | 2 +- compiler/rustc_borrowck/src/universal_regions.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 4 ++-- compiler/rustc_data_structures/src/graph/scc/mod.rs | 2 +- compiler/rustc_expand/src/proc_macro.rs | 2 +- compiler/rustc_interface/src/passes.rs | 20 ++++++++++++-------- compiler/rustc_llvm/build.rs | 8 ++++++-- 7 files changed, 24 insertions(+), 16 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index a55a63a7bf1..ca1bb59e59d 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -65,7 +65,7 @@ fn main() { // linking, so we need to explicitly depend on the function. #[cfg(target_os = "macos")] { - extern "C" { + unsafe extern "C" { fn _rjem_je_zone_register(); } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 9a68eeb3326..c578eb4dc45 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -308,7 +308,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// Returns an iterator over all the RegionVids corresponding to /// universally quantified free regions. - pub(crate) fn universal_regions_iter(&self) -> impl Iterator { + pub(crate) fn universal_regions_iter(&self) -> impl Iterator + use<> { (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) } diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 39bac13a968..9c740ab9868 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -7,7 +7,7 @@ use super::ffi::{BasicBlock, Metadata, Module, Type, Value}; use crate::llvm::Bool; #[link(name = "llvm-wrapper", kind = "static")] -extern "C" { +unsafe extern "C" { // Enzyme pub(crate) fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool; pub(crate) fn LLVMRustEraseInstUntilInclusive(BB: &BasicBlock, I: &Value); @@ -18,7 +18,7 @@ extern "C" { pub(crate) fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool; } -extern "C" { +unsafe extern "C" { // Enzyme pub(crate) fn LLVMDumpModule(M: &Module); pub(crate) fn LLVMDumpValue(V: &Value); diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 93f6192b10b..2241b538738 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -133,7 +133,7 @@ impl Sccs { /// meaning that if `S1 -> S2`, we will visit `S2` first and `S1` after. /// This is convenient when the edges represent dependencies: when you visit /// `S1`, the value for `S2` will already have been computed. - pub fn all_sccs(&self) -> impl Iterator { + pub fn all_sccs(&self) -> impl Iterator + use { (0..self.scc_data.len()).map(S::new) } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index dca0516f9f3..814d2b04d8d 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -31,7 +31,7 @@ impl pm::bridge::server::MessagePipe for MessagePipe { } } -fn exec_strategy(ecx: &ExtCtxt<'_>) -> impl pm::bridge::server::ExecutionStrategy { +fn exec_strategy(ecx: &ExtCtxt<'_>) -> impl pm::bridge::server::ExecutionStrategy + use<> { pm::bridge::server::MaybeCrossThread::>::new( ecx.sess.opts.unstable_opts.proc_macro_execution_strategy == ProcMacroExecutionStrategy::CrossThread, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d70d9d344b9..2d3c7f834e9 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -171,13 +171,15 @@ fn configure_and_expand( new_path.push(path); } } - env::set_var( - "PATH", - &env::join_paths( - new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()), - ) - .unwrap(), - ); + unsafe { + env::set_var( + "PATH", + &env::join_paths( + new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()), + ) + .unwrap(), + ); + } } // Create the config for macro expansion @@ -216,7 +218,9 @@ fn configure_and_expand( } if cfg!(windows) { - env::set_var("PATH", &old_path); + unsafe { + env::set_var("PATH", &old_path); + } } krate diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 48806888b43..3d1f3b2cd4d 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -51,9 +51,13 @@ fn detect_llvm_link() -> (&'static str, &'static str) { fn restore_library_path() { let key = tracked_env_var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); if let Some(env) = tracked_env_var_os("REAL_LIBRARY_PATH") { - env::set_var(&key, env); + unsafe { + env::set_var(&key, env); + } } else { - env::remove_var(&key); + unsafe { + env::remove_var(&key); + } } } -- cgit 1.4.1-3-g733a5 From f4e2218b131b82097c720d28c1c2ea10922b0d47 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 21 Feb 2025 21:47:48 -0500 Subject: clean up autodiff code/comments --- compiler/rustc_ast/src/expand/autodiff_attrs.rs | 1 - compiler/rustc_codegen_llvm/src/back/write.rs | 15 +++++---------- compiler/rustc_monomorphize/src/partitioning/autodiff.rs | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs index 70222f4acab..c8ec185ee5e 100644 --- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -17,7 +17,6 @@ use crate::{Ty, TyKind}; /// functions. The proper solution is to recognize and resolve this DAG of autodiff invocations, /// as it's already done in the C++ and Julia frontend of Enzyme. /// -/// (FIXME) remove *First variants. /// Documentation for using [reverse](https://enzyme.mit.edu/rust/rev.html) and /// [forward](https://enzyme.mit.edu/rust/fwd.html) mode is available online. #[derive(Clone, Copy, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 9fa10e96068..b67890c0465 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -564,19 +564,16 @@ pub(crate) unsafe fn llvm_optimize( // FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting // differentiated. + let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); + let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; let unroll_loops; let vectorize_slp; let vectorize_loop; - let run_enzyme = cfg!(llvm_enzyme) && autodiff_stage == AutodiffStage::DuringAD; // When we build rustc with enzyme/autodiff support, we want to postpone size-increasing // optimizations until after differentiation. Our pipeline is thus: (opt + enzyme), (full opt). // We therefore have two calls to llvm_optimize, if autodiff is used. - // - // FIXME(ZuseZ4): Before shipping on nightly, - // we should make this more granular, or at least check that the user has at least one autodiff - // call in their code, to justify altering the compilation pipeline. - if cfg!(llvm_enzyme) && autodiff_stage != AutodiffStage::PostAD { + if consider_ad && autodiff_stage != AutodiffStage::PostAD { unroll_loops = false; vectorize_slp = false; vectorize_loop = false; @@ -706,10 +703,8 @@ pub(crate) unsafe fn optimize( // If we know that we will later run AD, then we disable vectorization and loop unrolling. // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD). - // FIXME(ZuseZ4): Make this more granular, only set PreAD if we actually have autodiff - // usages, not just if we build rustc with autodiff support. - let autodiff_stage = - if cfg!(llvm_enzyme) { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; + let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); + let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; return unsafe { llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, autodiff_stage) }; diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs index bce31bf0748..0c855508434 100644 --- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -66,7 +66,7 @@ pub(crate) fn find_autodiff_source_functions<'tcx>( let mut autodiff_items: Vec = vec![]; for (item, instance) in autodiff_mono_items { let target_id = instance.def_id(); - let cg_fn_attr = tcx.codegen_fn_attrs(target_id).autodiff_item.clone(); + let cg_fn_attr = &tcx.codegen_fn_attrs(target_id).autodiff_item; let Some(target_attrs) = cg_fn_attr else { continue; }; -- cgit 1.4.1-3-g733a5 From e2d250c3f63d14e068e92ab3048817af6e1770c2 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 21 Feb 2025 21:51:20 -0500 Subject: update autodiff flags --- compiler/rustc_codegen_llvm/messages.ftl | 1 + compiler/rustc_codegen_llvm/src/back/lto.rs | 85 +++++++++++++------ .../rustc_codegen_llvm/src/builder/autodiff.rs | 13 ++- compiler/rustc_codegen_llvm/src/errors.rs | 5 +- compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 94 ++++++++++++++++++++++ compiler/rustc_codegen_ssa/src/back/write.rs | 3 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 25 +++--- compiler/rustc_session/src/options.rs | 39 ++++----- .../unstable-book/src/compiler-flags/autodiff.md | 9 +-- tests/codegen/autodiff.rs | 2 +- 11 files changed, 203 insertions(+), 75 deletions(-) (limited to 'compiler/rustc_codegen_llvm/src') diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 399d7ffea8e..17f2e7ca9f7 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,3 +1,4 @@ +codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires using fat-lto codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err} diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 3e25b94961b..99906ea7bce 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -586,6 +586,42 @@ fn thin_lto( } } +fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen) { + for &val in ad { + match val { + config::AutoDiff::PrintModBefore => { + unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) }; + } + config::AutoDiff::PrintPerf => { + llvm::set_print_perf(true); + } + config::AutoDiff::PrintAA => { + llvm::set_print_activity(true); + } + config::AutoDiff::PrintTA => { + llvm::set_print_type(true); + } + config::AutoDiff::Inline => { + llvm::set_inline(true); + } + config::AutoDiff::LooseTypes => { + llvm::set_loose_types(false); + } + config::AutoDiff::PrintSteps => { + llvm::set_print(true); + } + // We handle this below + config::AutoDiff::PrintModAfter => {} + // This is required and already checked + config::AutoDiff::Enable => {} + } + } + // This helps with handling enums for now. + llvm::set_strict_aliasing(false); + // FIXME(ZuseZ4): Test this, since it was added a long time ago. + llvm::set_rust_rules(true); +} + pub(crate) fn run_pass_manager( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, @@ -604,34 +640,37 @@ pub(crate) fn run_pass_manager( let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO }; let opt_level = config.opt_level.unwrap_or(config::OptLevel::No); - // If this rustc version was build with enzyme/autodiff enabled, and if users applied the - // `#[autodiff]` macro at least once, then we will later call llvm_optimize a second time. - debug!("running llvm pm opt pipeline"); + // The PostAD behavior is the same that we would have if no autodiff was used. + // It will run the default optimization pipeline. If AD is enabled we select + // the DuringAD stage, which will disable vectorization and loop unrolling, and + // schedule two autodiff optimization + differentiation passes. + // We then run the llvm_optimize function a second time, to optimize the code which we generated + // in the enzyme differentiation pass. + let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable); + let stage = + if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD }; + + if enable_ad { + enable_autodiff_settings(&config.autodiff, module); + } + unsafe { - write::llvm_optimize( - cgcx, - dcx, - module, - config, - opt_level, - opt_stage, - write::AutodiffStage::DuringAD, - )?; + write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, stage)?; } - // FIXME(ZuseZ4): Make this more granular - if cfg!(llvm_enzyme) && !thin { + + if cfg!(llvm_enzyme) && enable_ad { + let opt_stage = llvm::OptStage::FatLTO; + let stage = write::AutodiffStage::PostAD; unsafe { - write::llvm_optimize( - cgcx, - dcx, - module, - config, - opt_level, - llvm::OptStage::FatLTO, - write::AutodiffStage::PostAD, - )?; + write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, stage)?; + } + + // This is the final IR, so people should be able to inspect the optimized autodiff output. + if config.autodiff.contains(&config::AutoDiff::PrintModAfter) { + unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) }; } } + debug!("lto done"); Ok(()) } diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index b2c1088e3fc..2c7899975e3 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -10,7 +10,7 @@ use crate::back::write::llvm_err; use crate::builder::SBuilder; use crate::context::SimpleCx; use crate::declare::declare_simple_fn; -use crate::errors::LlvmError; +use crate::errors::{AutoDiffWithoutEnable, LlvmError}; use crate::llvm::AttributePlace::Function; use crate::llvm::{Metadata, True}; use crate::value::Value; @@ -46,9 +46,6 @@ fn generate_enzyme_call<'ll>( let output = attrs.ret_activity; // We have to pick the name depending on whether we want forward or reverse mode autodiff. - // FIXME(ZuseZ4): The new pass based approach should not need the {Forward/Reverse}First method anymore, since - // it will handle higher-order derivatives correctly automatically (in theory). Currently - // higher-order derivatives fail, so we should debug that before adjusting this code. let mut ad_name: String = match attrs.mode { DiffMode::Forward => "__enzyme_fwddiff", DiffMode::Reverse => "__enzyme_autodiff", @@ -291,6 +288,14 @@ pub(crate) fn differentiate<'ll>( let diag_handler = cgcx.create_dcx(); let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx }; + // First of all, did the user try to use autodiff without using the -Zautodiff=Enable flag? + if !diff_items.is_empty() + && !cgcx.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) + { + let dcx = cgcx.create_dcx(); + return Err(dcx.handle().emit_almost_fatal(AutoDiffWithoutEnable)); + } + // Before dumping the module, we want all the TypeTrees to become part of the module. for item in diff_items.iter() { let name = item.source.clone(); diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 97f49256165..4c5a78ca74f 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -92,9 +92,12 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] -#[note] pub(crate) struct AutoDiffWithoutLTO; +#[derive(Diagnostic)] +#[diag(codegen_llvm_autodiff_without_enable)] +pub(crate) struct AutoDiffWithoutEnable; + #[derive(Diagnostic)] #[diag(codegen_llvm_lto_disallowed)] pub(crate) struct LtoDisallowed; diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 39bac13a968..daa6696e963 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -35,3 +35,97 @@ pub enum LLVMRustVerifierFailureAction { LLVMPrintMessageAction = 1, LLVMReturnStatusAction = 2, } + +#[cfg(llvm_enzyme)] +pub use self::Enzyme_AD::*; + +#[cfg(llvm_enzyme)] +pub mod Enzyme_AD { + use libc::c_void; + extern "C" { + pub fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); + } + extern "C" { + static mut EnzymePrintPerf: c_void; + static mut EnzymePrintActivity: c_void; + static mut EnzymePrintType: c_void; + static mut EnzymePrint: c_void; + static mut EnzymeStrictAliasing: c_void; + static mut looseTypeAnalysis: c_void; + static mut EnzymeInline: c_void; + static mut RustTypeRules: c_void; + } + pub fn set_print_perf(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8); + } + } + pub fn set_print_activity(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8); + } + } + pub fn set_print_type(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8); + } + } + pub fn set_print(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8); + } + } + pub fn set_strict_aliasing(strict: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8); + } + } + pub fn set_loose_types(loose: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8); + } + } + pub fn set_inline(val: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8); + } + } + pub fn set_rust_rules(val: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8); + } + } +} + +#[cfg(not(llvm_enzyme))] +pub use self::Fallback_AD::*; + +#[cfg(not(llvm_enzyme))] +pub mod Fallback_AD { + #![allow(unused_variables)] + + pub fn set_inline(val: bool) { + unimplemented!() + } + pub fn set_print_perf(print: bool) { + unimplemented!() + } + pub fn set_print_activity(print: bool) { + unimplemented!() + } + pub fn set_print_type(print: bool) { + unimplemented!() + } + pub fn set_print(print: bool) { + unimplemented!() + } + pub fn set_strict_aliasing(strict: bool) { + unimplemented!() + } + pub fn set_loose_types(loose: bool) { + unimplemented!() + } + pub fn set_rust_rules(val: bool) { + unimplemented!() + } +} diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index f029c08a808..d2548deb8c7 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -405,7 +405,8 @@ fn generate_lto_work( B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise()); if cgcx.lto == Lto::Fat && !autodiff.is_empty() { let config = cgcx.config(ModuleKind::Regular); - module = unsafe { module.autodiff(cgcx, autodiff, config).unwrap() }; + module = + unsafe { module.autodiff(cgcx, autodiff, config).unwrap_or_else(|e| e.raise()) }; } // We are adding a single work item, so the cost doesn't matter. vec![(WorkItem::LTO(module), 0)] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 233bfcb5297..aabd235bcab 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -759,7 +759,7 @@ fn test_unstable_options_tracking_hash() { tracked!(allow_features, Some(vec![String::from("lang_items")])); tracked!(always_encode_mir, true); tracked!(assume_incomplete_release, true); - tracked!(autodiff, vec![AutoDiff::Print]); + tracked!(autodiff, vec![AutoDiff::Enable]); tracked!(binary_dep_depinfo, true); tracked!(box_noalias, false); tracked!( diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 85ef69ea2b7..4f44eaf6437 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -198,33 +198,26 @@ pub enum CoverageLevel { /// The different settings that the `-Z autodiff` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum AutoDiff { + /// Enable the autodiff opt pipeline + Enable, + /// Print TypeAnalysis information PrintTA, /// Print ActivityAnalysis Information PrintAA, /// Print Performance Warnings from Enzyme PrintPerf, - /// Combines the three print flags above. - Print, + /// Print intermediate IR generation steps + PrintSteps, /// Print the whole module, before running opts. PrintModBefore, - /// Print the whole module just before we pass it to Enzyme. - /// For Debug purpose, prefer the OPT flag below - PrintModAfterOpts, /// Print the module after Enzyme differentiated everything. - PrintModAfterEnzyme, + PrintModAfter, - /// Enzyme's loose type debug helper (can cause incorrect gradients) + /// Enzyme's loose type debug helper (can cause incorrect gradients!!) + /// Usable in cases where Enzyme errors with `can not deduce type of X`. LooseTypes, - - /// More flags - NoModOptAfter, - /// Tell Enzyme to run LLVM Opts on each function it generated. By default off, - /// since we already optimize the whole module after Enzyme is done. - EnableFncOpt, - NoVecUnroll, - RuntimeActivity, - /// Runs Enzyme specific Inlining + /// Runs Enzyme's aggressive inlining Inline, } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 351dad3f3e4..0b94b4f122c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -707,7 +707,7 @@ mod desc { pub(crate) const parse_list: &str = "a space-separated list of strings"; pub(crate) const parse_list_with_polarity: &str = "a comma-separated list of strings, with elements beginning with + or -"; - pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Print`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfterOpts`, `PrintModAfterEnzyme`, `LooseTypes`, `NoModOptAfter`, `EnableFncOpt`, `NoVecUnroll`, `Inline`"; + pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `LooseTypes`, `Inline`"; pub(crate) const parse_comma_list: &str = "a comma-separated list of strings"; pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_number: &str = "a number"; @@ -1348,17 +1348,14 @@ pub mod parse { v.sort_unstable(); for &val in v.iter() { let variant = match val { + "Enable" => AutoDiff::Enable, "PrintTA" => AutoDiff::PrintTA, "PrintAA" => AutoDiff::PrintAA, "PrintPerf" => AutoDiff::PrintPerf, - "Print" => AutoDiff::Print, + "PrintSteps" => AutoDiff::PrintSteps, "PrintModBefore" => AutoDiff::PrintModBefore, - "PrintModAfterOpts" => AutoDiff::PrintModAfterOpts, - "PrintModAfterEnzyme" => AutoDiff::PrintModAfterEnzyme, + "PrintModAfter" => AutoDiff::PrintModAfter, "LooseTypes" => AutoDiff::LooseTypes, - "NoModOptAfter" => AutoDiff::NoModOptAfter, - "EnableFncOpt" => AutoDiff::EnableFncOpt, - "NoVecUnroll" => AutoDiff::NoVecUnroll, "Inline" => AutoDiff::Inline, _ => { // FIXME(ZuseZ4): print an error saying which value is not recognized @@ -2081,21 +2078,19 @@ options! { assume_incomplete_release: bool = (false, parse_bool, [TRACKED], "make cfg(version) treat the current version as incomplete (default: no)"), autodiff: Vec = (Vec::new(), parse_autodiff, [TRACKED], - "a list of optional autodiff flags to enable - Optional extra settings: - `=PrintTA` - `=PrintAA` - `=PrintPerf` - `=Print` - `=PrintModBefore` - `=PrintModAfterOpts` - `=PrintModAfterEnzyme` - `=LooseTypes` - `=NoModOptAfter` - `=EnableFncOpt` - `=NoVecUnroll` - `=Inline` - Multiple options can be combined with commas."), + "a list of autodiff flags to enable + Mandatory setting: + `=Enable` + Optional extra settings: + `=PrintTA` + `=PrintAA` + `=PrintPerf` + `=PrintSteps` + `=PrintModBefore` + `=PrintModAfter` + `=LooseTypes` + `=Inline` + Multiple options can be combined with commas."), #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")] binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ diff --git a/src/doc/unstable-book/src/compiler-flags/autodiff.md b/src/doc/unstable-book/src/compiler-flags/autodiff.md index 4e55be0ad95..95c188d1f3b 100644 --- a/src/doc/unstable-book/src/compiler-flags/autodiff.md +++ b/src/doc/unstable-book/src/compiler-flags/autodiff.md @@ -8,16 +8,13 @@ This feature allows you to differentiate functions using automatic differentiati Set the `-Zautodiff=` compiler flag to adjust the behaviour of the autodiff feature. Multiple options can be separated with a comma. Valid options are: +`Enable` - Required flag to enable autodiff `PrintTA` - print Type Analysis Information `PrintAA` - print Activity Analysis Information `PrintPerf` - print Performance Warnings from Enzyme -`Print` - prints all intermediate transformations +`PrintSteps` - prints all intermediate transformations `PrintModBefore` - print the whole module, before running opts -`PrintModAfterOpts` - print the whole module just before we pass it to Enzyme -`PrintModAfterEnzyme` - print the module after Enzyme differentiated everything +`PrintModAfter` - print the module after Enzyme differentiated everything `LooseTypes` - Enzyme's loose type debug helper (can cause incorrect gradients) `Inline` - runs Enzyme specific Inlining -`NoModOptAfter` - do not optimize the module after Enzyme is done -`EnableFncOpt` - tell Enzyme to run LLVM Opts on each function it generated -`NoVecUnroll` - do not unroll vectorized loops `RuntimeActivity` - allow specifying activity at runtime diff --git a/tests/codegen/autodiff.rs b/tests/codegen/autodiff.rs index abf7fcf3e4b..cace0edb2b5 100644 --- a/tests/codegen/autodiff.rs +++ b/tests/codegen/autodiff.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -C opt-level=3 -Clto=fat +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme #![feature(autodiff)] -- cgit 1.4.1-3-g733a5