From 00c24dd8cec6c57ccbfb376c4a2f47b5f6e39401 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 1 Mar 2022 14:51:08 +0000 Subject: [PATCH 1/5] Move stable hash from TyS into a datastructure that can be shared with other interned types. --- compiler/rustc_data_structures/src/intern.rs | 73 ++++++++++++++++++++ compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 17 +++-- compiler/rustc_middle/src/ty/mod.rs | 45 +++--------- compiler/rustc_middle/src/ty/print/pretty.rs | 49 +++++++++---- compiler/rustc_middle/src/ty/subst.rs | 6 +- compiler/rustc_middle/src/ty/util.rs | 4 +- compiler/rustc_query_system/src/ich/hcx.rs | 8 +++ 8 files changed, 140 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index 7a320b10b6030..1b187cd306e93 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -4,6 +4,8 @@ use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::ptr; +use crate::fingerprint::Fingerprint; + mod private { #[derive(Clone, Copy, Debug)] pub struct PrivateZst; @@ -108,5 +110,76 @@ where } } +/// A helper trait so that `Interned` things can cache stable hashes reproducibly. +pub trait InternedHashingContext { + fn with_def_path_and_no_spans(&mut self, f: impl FnOnce(&mut Self)); +} + +#[derive(Copy, Clone)] +pub struct InTy { + pub internee: T, + pub stable_hash: Fingerprint, +} + +impl PartialEq for InTy { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.internee.eq(&other.internee) + } +} + +impl Eq for InTy {} + +impl PartialOrd for InTy { + fn partial_cmp(&self, other: &InTy) -> Option { + Some(self.internee.cmp(&other.internee)) + } +} + +impl Ord for InTy { + fn cmp(&self, other: &InTy) -> Ordering { + self.internee.cmp(&other.internee) + } +} + +impl Deref for InTy { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.internee + } +} + +impl Hash for InTy { + #[inline] + fn hash(&self, s: &mut H) { + self.internee.hash(s) + } +} + +impl, CTX: InternedHashingContext> HashStable for InTy { + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + let stable_hash = self.stable_hash; + + if stable_hash == Fingerprint::ZERO { + // No cached hash available. This can only mean that incremental is disabled. + // We don't cache stable hashes in non-incremental mode, because they are used + // so rarely that the performance actually suffers. + + // We need to build the hash as if we cached it and then hash that hash, as + // otherwise the hashes will differ between cached and non-cached mode. + let stable_hash: Fingerprint = { + let mut hasher = StableHasher::new(); + hcx.with_def_path_and_no_spans(|hcx| self.internee.hash_stable(hcx, &mut hasher)); + hasher.finish() + }; + stable_hash.hash_stable(hcx, hasher); + } else { + stable_hash.hash_stable(hcx, hasher); + } + } +} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 170dd113f6dfe..5141d5beb7d45 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -87,7 +87,7 @@ macro_rules! arena_types { [] hir_id_set: rustc_hir::HirIdSet, // Interned types - [] tys: rustc_middle::ty::TyS<'tcx>, + [] tys: rustc_data_structures::intern::InTy>, [] predicates: rustc_middle::ty::PredicateS<'tcx>, [] consts: rustc_middle::ty::ConstS<'tcx>, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ac9f04ee05575..bc077a673f362 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -26,7 +26,7 @@ use crate::ty::{ use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::Interned; +use rustc_data_structures::intern::{InTy, Interned}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -105,7 +105,7 @@ pub struct CtxtInterners<'tcx> { // Specifically use a speedy hash algorithm for these hash sets, since // they're accessed quite often. - type_: InternedSet<'tcx, TyS<'tcx>>, + type_: InternedSet<'tcx, InTy>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, canonical_var_infos: InternedSet<'tcx, List>>, region: InternedSet<'tcx, RegionKind>, @@ -178,10 +178,9 @@ impl<'tcx> CtxtInterners<'tcx> { kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, - stable_hash, }; - InternedInSet(self.arena.alloc(ty_struct)) + InternedInSet(self.arena.alloc(InTy { internee: ty_struct, stable_hash })) }) .0, )) @@ -2048,23 +2047,23 @@ impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> { } #[allow(rustc::usage_of_ty_tykind)] -impl<'tcx> Borrow> for InternedInSet<'tcx, TyS<'tcx>> { +impl<'tcx> Borrow> for InternedInSet<'tcx, InTy>> { fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> { &self.0.kind } } -impl<'tcx> PartialEq for InternedInSet<'tcx, TyS<'tcx>> { - fn eq(&self, other: &InternedInSet<'tcx, TyS<'tcx>>) -> bool { +impl<'tcx> PartialEq for InternedInSet<'tcx, InTy>> { + fn eq(&self, other: &InternedInSet<'tcx, InTy>>) -> bool { // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals // `x == y`. self.0.kind == other.0.kind } } -impl<'tcx> Eq for InternedInSet<'tcx, TyS<'tcx>> {} +impl<'tcx> Eq for InternedInSet<'tcx, InTy>> {} -impl<'tcx> Hash for InternedInSet<'tcx, TyS<'tcx>> { +impl<'tcx> Hash for InternedInSet<'tcx, InTy>> { fn hash(&self, s: &mut H) { // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`. self.0.kind.hash(s) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 653b4908ab560..39acf252698de 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -31,8 +31,8 @@ use crate::ty::util::Discr; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_data_structures::intern::Interned; -use rustc_data_structures::stable_hasher::{HashStable, NodeIdHashingMode, StableHasher}; +use rustc_data_structures::intern::{InTy, Interned}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -433,32 +433,28 @@ crate struct TyS<'tcx> { /// De Bruijn indices within the type are contained within `0..D` /// (exclusive). outer_exclusive_binder: ty::DebruijnIndex, - - /// The stable hash of the type. This way hashing of types will not have to work - /// on the address of the type anymore, but can instead just read this field - stable_hash: Fingerprint, } // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -static_assert_size!(TyS<'_>, 56); +static_assert_size!(TyS<'_>, 40); /// Use this rather than `TyS`, whenever possible. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] #[rustc_diagnostic_item = "Ty"] #[rustc_pass_by_value] -pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>); +pub struct Ty<'tcx>(Interned<'tcx, InTy>>); // Statics only used for internal testing. -pub static BOOL_TY: Ty<'static> = Ty(Interned::new_unchecked(&BOOL_TYS)); -static BOOL_TYS: TyS<'static> = TyS { +pub static BOOL_TY: Ty<'static> = + Ty(Interned::new_unchecked(&InTy { internee: BOOL_TYS, stable_hash: Fingerprint::ZERO })); +const BOOL_TYS: TyS<'static> = TyS { kind: ty::Bool, flags: TypeFlags::empty(), outer_exclusive_binder: DebruijnIndex::from_usize(0), - stable_hash: Fingerprint::ZERO, }; -impl<'a, 'tcx> HashStable> for Ty<'tcx> { +impl<'a, 'tcx> HashStable> for TyS<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let TyS { kind, @@ -468,28 +464,9 @@ impl<'a, 'tcx> HashStable> for Ty<'tcx> { flags: _, outer_exclusive_binder: _, + } = self; - stable_hash, - } = self.0.0; - - if *stable_hash == Fingerprint::ZERO { - // No cached hash available. This can only mean that incremental is disabled. - // We don't cache stable hashes in non-incremental mode, because they are used - // so rarely that the performance actually suffers. - - let stable_hash: Fingerprint = { - let mut hasher = StableHasher::new(); - hcx.while_hashing_spans(false, |hcx| { - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - kind.hash_stable(hcx, &mut hasher) - }) - }); - hasher.finish() - }; - stable_hash.hash_stable(hcx, hasher); - } else { - stable_hash.hash_stable(hcx, hasher); - } + kind.hash_stable(hcx, hasher) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 9a9c529f24552..7e0b0ace8c0a8 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3,7 +3,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::intern::Interned; +use rustc_data_structures::intern::{InTy, Interned}; use rustc_data_structures::sso::SsoHashSet; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; @@ -1266,18 +1266,29 @@ pub trait PrettyPrinter<'tcx>: ty::Ref( _, Ty(Interned( - ty::TyS { - kind: - ty::Array( - Ty(Interned(ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, _)), - ty::Const(Interned( - ty::ConstS { - val: ty::ConstKind::Value(ConstValue::Scalar(int)), - .. - }, - _, - )), - ), + InTy { + internee: + ty::TyS { + kind: + ty::Array( + Ty(Interned( + InTy { + internee: + ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, + .. + }, + _, + )), + ty::Const(Interned( + ty::ConstS { + val: ty::ConstKind::Value(ConstValue::Scalar(int)), + .. + }, + _, + )), + ), + .. + }, .. }, _, @@ -1439,7 +1450,11 @@ pub trait PrettyPrinter<'tcx>: // Byte/string slices, printed as (byte) string literals. ( ConstValue::Slice { data, start, end }, - ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Slice(t), .. }, _)), _), + ty::Ref( + _, + Ty(Interned(InTy { internee: ty::TyS { kind: ty::Slice(t), .. }, .. }, _)), + _, + ), ) if *t == u8_type => { // The `inspect` here is okay since we checked the bounds, and there are // no relocations (we have an active slice reference here). We don't use @@ -1450,7 +1465,11 @@ pub trait PrettyPrinter<'tcx>: } ( ConstValue::Slice { data, start, end }, - ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Str, .. }, _)), _), + ty::Ref( + _, + Ty(Interned(InTy { internee: ty::TyS { kind: ty::Str, .. }, .. }, _)), + _, + ), ) => { // The `inspect` here is okay since we checked the bounds, and there are no // relocations (we have an active `str` reference here). We don't use this diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 0a6cb276f7578..50357877c0afc 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -6,7 +6,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor} use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; -use rustc_data_structures::intern::Interned; +use rustc_data_structures::intern::{InTy, Interned}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_serialize::{self, Decodable, Encodable}; @@ -85,7 +85,7 @@ impl<'tcx> GenericArgKind<'tcx> { GenericArgKind::Type(ty) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(ty.0.0) & TAG_MASK, 0); - (TYPE_TAG, ty.0.0 as *const ty::TyS<'tcx> as usize) + (TYPE_TAG, ty.0.0 as *const InTy> as usize) } GenericArgKind::Const(ct) => { // Ensure we can use the tag bits. @@ -154,7 +154,7 @@ impl<'tcx> GenericArg<'tcx> { &*((ptr & !TAG_MASK) as *const ty::RegionKind), ))), TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked( - &*((ptr & !TAG_MASK) as *const ty::TyS<'tcx>), + &*((ptr & !TAG_MASK) as *const InTy>), ))), CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked( &*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>), diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 7d9a917d04c76..a5cc730813fef 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -13,7 +13,7 @@ use rustc_apfloat::Float as _; use rustc_ast as ast; use rustc_attr::{self as attr, SignedInt, UnsignedInt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::Interned; +use rustc_data_structures::intern::{InTy, Interned}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -427,7 +427,7 @@ impl<'tcx> TyCtxt<'tcx> { !impl_generics.region_param(ebr, self).pure_wrt_drop } GenericArgKind::Type(Ty(Interned( - ty::TyS { kind: ty::Param(ref pt), .. }, + InTy { internee: ty::TyS { kind: ty::Param(ref pt), .. }, .. }, _, ))) => !impl_generics.type_param(pt, self).pure_wrt_drop, GenericArgKind::Const(Const(Interned( diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 76e21be17bc68..a073bf7105775 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -231,4 +231,12 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { } } +impl<'a> rustc_data_structures::intern::InternedHashingContext for StableHashingContext<'a> { + fn with_def_path_and_no_spans(&mut self, f: impl FnOnce(&mut Self)) { + self.while_hashing_spans(false, |hcx| { + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| f(hcx)) + }); + } +} + impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {} From 33d0ce95a947d1311af01ad6d3e39b1075c50417 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 7 Mar 2022 11:00:27 +0000 Subject: [PATCH 2/5] inline a trivial function --- compiler/rustc_middle/src/ty/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 39acf252698de..482460c0fe9f8 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -455,6 +455,7 @@ const BOOL_TYS: TyS<'static> = TyS { }; impl<'a, 'tcx> HashStable> for TyS<'tcx> { + #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let TyS { kind, From 6ffd654683900a81adda24b3a86e4c30fee31214 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 7 Mar 2022 13:31:49 +0000 Subject: [PATCH 3/5] Check that the cached stable hash is the right one if debug assertions are enabled --- compiler/rustc_data_structures/src/intern.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index 1b187cd306e93..bd62f30372ef7 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -160,9 +160,7 @@ impl Hash for InTy { impl, CTX: InternedHashingContext> HashStable for InTy { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - let stable_hash = self.stable_hash; - - if stable_hash == Fingerprint::ZERO { + if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) { // No cached hash available. This can only mean that incremental is disabled. // We don't cache stable hashes in non-incremental mode, because they are used // so rarely that the performance actually suffers. @@ -174,9 +172,15 @@ impl, CTX: InternedHashingContext> HashStable for InTy Date: Tue, 5 Apr 2022 16:42:47 +0000 Subject: [PATCH 4/5] Document and rename the new wrapper type --- compiler/rustc_data_structures/src/intern.rs | 27 ++++++++++++-------- compiler/rustc_middle/src/arena.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 18 +++++++------ compiler/rustc_middle/src/ty/mod.rs | 15 ++++++++--- compiler/rustc_middle/src/ty/print/pretty.rs | 13 ++++++---- compiler/rustc_middle/src/ty/subst.rs | 6 ++--- compiler/rustc_middle/src/ty/util.rs | 6 +++-- 7 files changed, 54 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index bd62f30372ef7..009b5d5340afe 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -115,34 +115,41 @@ pub trait InternedHashingContext { fn with_def_path_and_no_spans(&mut self, f: impl FnOnce(&mut Self)); } +/// A helper type that you can wrap round your own type in order to automatically +/// cache the stable hash on creation and not recompute it whenever the stable hash +/// of the type is computed. +/// This is only done in incremental mode. You can also opt out of caching by using +/// StableHash::ZERO for the hash, in which case the hash gets computed each time. +/// This is useful if you have values that you intern but never (can?) use for stable +/// hashing. #[derive(Copy, Clone)] -pub struct InTy { +pub struct WithStableHash { pub internee: T, pub stable_hash: Fingerprint, } -impl PartialEq for InTy { +impl PartialEq for WithStableHash { #[inline] fn eq(&self, other: &Self) -> bool { self.internee.eq(&other.internee) } } -impl Eq for InTy {} +impl Eq for WithStableHash {} -impl PartialOrd for InTy { - fn partial_cmp(&self, other: &InTy) -> Option { +impl PartialOrd for WithStableHash { + fn partial_cmp(&self, other: &WithStableHash) -> Option { Some(self.internee.cmp(&other.internee)) } } -impl Ord for InTy { - fn cmp(&self, other: &InTy) -> Ordering { +impl Ord for WithStableHash { + fn cmp(&self, other: &WithStableHash) -> Ordering { self.internee.cmp(&other.internee) } } -impl Deref for InTy { +impl Deref for WithStableHash { type Target = T; #[inline] @@ -151,14 +158,14 @@ impl Deref for InTy { } } -impl Hash for InTy { +impl Hash for WithStableHash { #[inline] fn hash(&self, s: &mut H) { self.internee.hash(s) } } -impl, CTX: InternedHashingContext> HashStable for InTy { +impl, CTX: InternedHashingContext> HashStable for WithStableHash { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) { // No cached hash available. This can only mean that incremental is disabled. diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 5141d5beb7d45..7c90cbb9092b8 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -87,7 +87,7 @@ macro_rules! arena_types { [] hir_id_set: rustc_hir::HirIdSet, // Interned types - [] tys: rustc_data_structures::intern::InTy>, + [] tys: rustc_data_structures::intern::WithStableHash>, [] predicates: rustc_middle::ty::PredicateS<'tcx>, [] consts: rustc_middle::ty::ConstS<'tcx>, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bc077a673f362..acca24a79f4d8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -26,7 +26,7 @@ use crate::ty::{ use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::{InTy, Interned}; +use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -105,7 +105,7 @@ pub struct CtxtInterners<'tcx> { // Specifically use a speedy hash algorithm for these hash sets, since // they're accessed quite often. - type_: InternedSet<'tcx, InTy>>, + type_: InternedSet<'tcx, WithStableHash>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, canonical_var_infos: InternedSet<'tcx, List>>, region: InternedSet<'tcx, RegionKind>, @@ -180,7 +180,9 @@ impl<'tcx> CtxtInterners<'tcx> { outer_exclusive_binder: flags.outer_exclusive_binder, }; - InternedInSet(self.arena.alloc(InTy { internee: ty_struct, stable_hash })) + InternedInSet( + self.arena.alloc(WithStableHash { internee: ty_struct, stable_hash }), + ) }) .0, )) @@ -2047,23 +2049,23 @@ impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> { } #[allow(rustc::usage_of_ty_tykind)] -impl<'tcx> Borrow> for InternedInSet<'tcx, InTy>> { +impl<'tcx> Borrow> for InternedInSet<'tcx, WithStableHash>> { fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> { &self.0.kind } } -impl<'tcx> PartialEq for InternedInSet<'tcx, InTy>> { - fn eq(&self, other: &InternedInSet<'tcx, InTy>>) -> bool { +impl<'tcx> PartialEq for InternedInSet<'tcx, WithStableHash>> { + fn eq(&self, other: &InternedInSet<'tcx, WithStableHash>>) -> bool { // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals // `x == y`. self.0.kind == other.0.kind } } -impl<'tcx> Eq for InternedInSet<'tcx, InTy>> {} +impl<'tcx> Eq for InternedInSet<'tcx, WithStableHash>> {} -impl<'tcx> Hash for InternedInSet<'tcx, InTy>> { +impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash>> { fn hash(&self, s: &mut H) { // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`. self.0.kind.hash(s) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 482460c0fe9f8..a4a9fef4515c0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -31,7 +31,7 @@ use crate::ty::util::Discr; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_data_structures::intern::{InTy, Interned}; +use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_hir as hir; @@ -439,15 +439,22 @@ crate struct TyS<'tcx> { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(TyS<'_>, 40); +// We are actually storing a stable hash cache next to the type, so let's +// also check the full size +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +static_assert_size!(WithStableHash>, 56); + /// Use this rather than `TyS`, whenever possible. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] #[rustc_diagnostic_item = "Ty"] #[rustc_pass_by_value] -pub struct Ty<'tcx>(Interned<'tcx, InTy>>); +pub struct Ty<'tcx>(Interned<'tcx, WithStableHash>>); // Statics only used for internal testing. -pub static BOOL_TY: Ty<'static> = - Ty(Interned::new_unchecked(&InTy { internee: BOOL_TYS, stable_hash: Fingerprint::ZERO })); +pub static BOOL_TY: Ty<'static> = Ty(Interned::new_unchecked(&WithStableHash { + internee: BOOL_TYS, + stable_hash: Fingerprint::ZERO, +})); const BOOL_TYS: TyS<'static> = TyS { kind: ty::Bool, flags: TypeFlags::empty(), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7e0b0ace8c0a8..1a843a4732309 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3,7 +3,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::intern::{InTy, Interned}; +use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::sso::SsoHashSet; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; @@ -1266,13 +1266,13 @@ pub trait PrettyPrinter<'tcx>: ty::Ref( _, Ty(Interned( - InTy { + WithStableHash { internee: ty::TyS { kind: ty::Array( Ty(Interned( - InTy { + WithStableHash { internee: ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, .. @@ -1452,7 +1452,10 @@ pub trait PrettyPrinter<'tcx>: ConstValue::Slice { data, start, end }, ty::Ref( _, - Ty(Interned(InTy { internee: ty::TyS { kind: ty::Slice(t), .. }, .. }, _)), + Ty(Interned( + WithStableHash { internee: ty::TyS { kind: ty::Slice(t), .. }, .. }, + _, + )), _, ), ) if *t == u8_type => { @@ -1467,7 +1470,7 @@ pub trait PrettyPrinter<'tcx>: ConstValue::Slice { data, start, end }, ty::Ref( _, - Ty(Interned(InTy { internee: ty::TyS { kind: ty::Str, .. }, .. }, _)), + Ty(Interned(WithStableHash { internee: ty::TyS { kind: ty::Str, .. }, .. }, _)), _, ), ) => { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 50357877c0afc..46b938ea93baa 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -6,7 +6,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor} use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; -use rustc_data_structures::intern::{InTy, Interned}; +use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_serialize::{self, Decodable, Encodable}; @@ -85,7 +85,7 @@ impl<'tcx> GenericArgKind<'tcx> { GenericArgKind::Type(ty) => { // Ensure we can use the tag bits. assert_eq!(mem::align_of_val(ty.0.0) & TAG_MASK, 0); - (TYPE_TAG, ty.0.0 as *const InTy> as usize) + (TYPE_TAG, ty.0.0 as *const WithStableHash> as usize) } GenericArgKind::Const(ct) => { // Ensure we can use the tag bits. @@ -154,7 +154,7 @@ impl<'tcx> GenericArg<'tcx> { &*((ptr & !TAG_MASK) as *const ty::RegionKind), ))), TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked( - &*((ptr & !TAG_MASK) as *const InTy>), + &*((ptr & !TAG_MASK) as *const WithStableHash>), ))), CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked( &*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>), diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index a5cc730813fef..29a388538792c 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -13,7 +13,7 @@ use rustc_apfloat::Float as _; use rustc_ast as ast; use rustc_attr::{self as attr, SignedInt, UnsignedInt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::{InTy, Interned}; +use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -427,7 +427,9 @@ impl<'tcx> TyCtxt<'tcx> { !impl_generics.region_param(ebr, self).pure_wrt_drop } GenericArgKind::Type(Ty(Interned( - InTy { internee: ty::TyS { kind: ty::Param(ref pt), .. }, .. }, + WithStableHash { + internee: ty::TyS { kind: ty::Param(ref pt), .. }, .. + }, _, ))) => !impl_generics.type_param(pt, self).pure_wrt_drop, GenericArgKind::Const(Const(Interned( From 25d6f8e0f647f865775158f35408724278145c50 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 8 Apr 2022 15:57:44 +0000 Subject: [PATCH 5/5] Avoid looking at the internals of Interned directly --- .../rustc_infer/src/infer/outlives/env.rs | 35 ++-- compiler/rustc_middle/src/ty/layout.rs | 68 +++---- compiler/rustc_middle/src/ty/print/pretty.rs | 178 ++++++++---------- compiler/rustc_middle/src/ty/util.rs | 43 ++--- .../src/traits/const_evaluatable.rs | 15 +- compiler/rustc_typeck/src/check/place_op.rs | 5 +- ...se_sensitive_file_extension_comparisons.rs | 5 +- 7 files changed, 150 insertions(+), 199 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 97e219ab61de9..c8236ce79c098 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -2,7 +2,6 @@ use crate::infer::free_regions::FreeRegionMap; use crate::infer::{GenericKind, InferCtxt}; use crate::traits::query::OutlivesBound; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::intern::Interned; use rustc_hir as hir; use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region}; @@ -164,12 +163,6 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> { for outlives_bound in outlives_bounds { debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound); match outlives_bound { - OutlivesBound::RegionSubRegion( - r_a @ (Region(Interned(ReEarlyBound(_), _)) | Region(Interned(ReFree(_), _))), - Region(Interned(ReVar(vid_b), _)), - ) => { - infcx.expect("no infcx provided but region vars found").add_given(r_a, *vid_b); - } OutlivesBound::RegionSubParam(r_a, param_b) => { self.region_bound_pairs_accum.push((r_a, GenericKind::Param(param_b))); } @@ -178,17 +171,23 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> { .push((r_a, GenericKind::Projection(projection_b))); } OutlivesBound::RegionSubRegion(r_a, r_b) => { - // In principle, we could record (and take - // advantage of) every relationship here, but - // we are also free not to -- it simply means - // strictly less that we can successfully type - // check. Right now we only look for things - // relationships between free regions. (It may - // also be that we should revise our inference - // system to be more general and to make use - // of *every* relationship that arises here, - // but presently we do not.) - self.free_region_map.relate_regions(r_a, r_b); + if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) { + infcx + .expect("no infcx provided but region vars found") + .add_given(r_a, vid_b); + } else { + // In principle, we could record (and take + // advantage of) every relationship here, but + // we are also free not to -- it simply means + // strictly less that we can successfully type + // check. Right now we only look for things + // relationships between free regions. (It may + // also be that we should revise our inference + // system to be more general and to make use + // of *every* relationship that arises here, + // but presently we do not.) + self.free_region_map.relate_regions(r_a, r_b); + } } } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 0c1ab67cc4ac7..e265bc0fcd2a0 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -5,7 +5,6 @@ use crate::ty::subst::Subst; use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; use rustc_ast as ast; use rustc_attr as attr; -use rustc_data_structures::intern::Interned; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::BitSet; @@ -503,42 +502,34 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } // Two non-ZST fields, and they're both scalars. - ( - Some(( - i, - &TyAndLayout { - layout: Layout(Interned(&LayoutS { abi: Abi::Scalar(a), .. }, _)), - .. - }, - )), - Some(( - j, - &TyAndLayout { - layout: Layout(Interned(&LayoutS { abi: Abi::Scalar(b), .. }, _)), - .. - }, - )), - None, - ) => { - // Order by the memory placement, not source order. - let ((i, a), (j, b)) = - if offsets[i] < offsets[j] { ((i, a), (j, b)) } else { ((j, b), (i, a)) }; - let pair = self.scalar_pair(a, b); - let pair_offsets = match pair.fields { - FieldsShape::Arbitrary { ref offsets, ref memory_index } => { - assert_eq!(memory_index, &[0, 1]); - offsets + (Some((i, a)), Some((j, b)), None) => { + match (a.abi, b.abi) { + (Abi::Scalar(a), Abi::Scalar(b)) => { + // Order by the memory placement, not source order. + let ((i, a), (j, b)) = if offsets[i] < offsets[j] { + ((i, a), (j, b)) + } else { + ((j, b), (i, a)) + }; + let pair = self.scalar_pair(a, b); + let pair_offsets = match pair.fields { + FieldsShape::Arbitrary { ref offsets, ref memory_index } => { + assert_eq!(memory_index, &[0, 1]); + offsets + } + _ => bug!(), + }; + if offsets[i] == pair_offsets[0] + && offsets[j] == pair_offsets[1] + && align == pair.align + && size == pair.size + { + // We can use `ScalarPair` only when it matches our + // already computed layout (including `#[repr(C)]`). + abi = pair.abi; + } } - _ => bug!(), - }; - if offsets[i] == pair_offsets[0] - && offsets[j] == pair_offsets[1] - && align == pair.align - && size == pair.size - { - // We can use `ScalarPair` only when it matches our - // already computed layout (including `#[repr(C)]`). - abi = pair.abi; + _ => {} } } @@ -788,10 +779,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } // Extract the number of elements from the layout of the array field: - let Ok(TyAndLayout { - layout: Layout(Interned(LayoutS { fields: FieldsShape::Array { count, .. }, .. }, _)), - .. - }) = self.layout_of(f0_ty) else { + let FieldsShape::Array { count, .. } = self.layout_of(f0_ty)?.layout.fields() else { return Err(LayoutError::Unknown(ty)); }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1a843a4732309..4379adb604e1f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3,7 +3,6 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::sso::SsoHashSet; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; @@ -1263,71 +1262,52 @@ pub trait PrettyPrinter<'tcx>: let (alloc_id, offset) = ptr.into_parts(); match ty.kind() { // Byte strings (&[u8; N]) - ty::Ref( - _, - Ty(Interned( - WithStableHash { - internee: - ty::TyS { - kind: - ty::Array( - Ty(Interned( - WithStableHash { - internee: - ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, - .. - }, - _, - )), - ty::Const(Interned( - ty::ConstS { - val: ty::ConstKind::Value(ConstValue::Scalar(int)), - .. - }, - _, - )), - ), - .. - }, - .. - }, - _, - )), - _, - ) => match self.tcx().get_global_alloc(alloc_id) { - Some(GlobalAlloc::Memory(alloc)) => { - let len = int.assert_bits(self.tcx().data_layout.pointer_size); - let range = AllocRange { start: offset, size: Size::from_bytes(len) }; - if let Ok(byte_str) = alloc.inner().get_bytes(&self.tcx(), range) { - p!(pretty_print_byte_str(byte_str)) - } else { - p!("") + ty::Ref(_, inner, _) => { + if let ty::Array(elem, len) = inner.kind() { + if let ty::Uint(ty::UintTy::U8) = elem.kind() { + if let ty::ConstKind::Value(ConstValue::Scalar(int)) = len.val() { + match self.tcx().get_global_alloc(alloc_id) { + Some(GlobalAlloc::Memory(alloc)) => { + let len = int.assert_bits(self.tcx().data_layout.pointer_size); + let range = + AllocRange { start: offset, size: Size::from_bytes(len) }; + if let Ok(byte_str) = + alloc.inner().get_bytes(&self.tcx(), range) + { + p!(pretty_print_byte_str(byte_str)) + } else { + p!("") + } + } + // FIXME: for statics and functions, we could in principle print more detail. + Some(GlobalAlloc::Static(def_id)) => { + p!(write("", def_id)) + } + Some(GlobalAlloc::Function(_)) => p!(""), + None => p!(""), + } + return Ok(self); + } } } - // FIXME: for statics and functions, we could in principle print more detail. - Some(GlobalAlloc::Static(def_id)) => p!(write("", def_id)), - Some(GlobalAlloc::Function(_)) => p!(""), - None => p!(""), - }, + } ty::FnPtr(_) => { // FIXME: We should probably have a helper method to share code with the "Byte strings" // printing above (which also has to handle pointers to all sorts of things). - match self.tcx().get_global_alloc(alloc_id) { - Some(GlobalAlloc::Function(instance)) => { - self = self.typed_value( - |this| this.print_value_path(instance.def_id(), instance.substs), - |this| this.print_type(ty), - " as ", - )?; - } - _ => self = self.pretty_print_const_pointer(ptr, ty, print_ty)?, + if let Some(GlobalAlloc::Function(instance)) = self.tcx().get_global_alloc(alloc_id) + { + self = self.typed_value( + |this| this.print_value_path(instance.def_id(), instance.substs), + |this| this.print_type(ty), + " as ", + )?; + return Ok(self); } } - // Any pointer values not covered by a branch above - _ => { - self = self.pretty_print_const_pointer(ptr, ty, print_ty)?; - } + _ => {} } + // Any pointer values not covered by a branch above + self = self.pretty_print_const_pointer(ptr, ty, print_ty)?; Ok(self) } @@ -1448,39 +1428,31 @@ pub trait PrettyPrinter<'tcx>: match (ct, ty.kind()) { // Byte/string slices, printed as (byte) string literals. - ( - ConstValue::Slice { data, start, end }, - ty::Ref( - _, - Ty(Interned( - WithStableHash { internee: ty::TyS { kind: ty::Slice(t), .. }, .. }, - _, - )), - _, - ), - ) if *t == u8_type => { - // The `inspect` here is okay since we checked the bounds, and there are - // no relocations (we have an active slice reference here). We don't use - // this result to affect interpreter execution. - let byte_str = - data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end); - self.pretty_print_byte_str(byte_str) - } - ( - ConstValue::Slice { data, start, end }, - ty::Ref( - _, - Ty(Interned(WithStableHash { internee: ty::TyS { kind: ty::Str, .. }, .. }, _)), - _, - ), - ) => { - // The `inspect` here is okay since we checked the bounds, and there are no - // relocations (we have an active `str` reference here). We don't use this - // result to affect interpreter execution. - let slice = - data.inner().inspect_with_uninit_and_ptr_outside_interpreter(start..end); - p!(write("{:?}", String::from_utf8_lossy(slice))); - Ok(self) + (ConstValue::Slice { data, start, end }, ty::Ref(_, inner, _)) => { + match inner.kind() { + ty::Slice(t) => { + if *t == u8_type { + // The `inspect` here is okay since we checked the bounds, and there are + // no relocations (we have an active slice reference here). We don't use + // this result to affect interpreter execution. + let byte_str = data + .inner() + .inspect_with_uninit_and_ptr_outside_interpreter(start..end); + return self.pretty_print_byte_str(byte_str); + } + } + ty::Str => { + // The `inspect` here is okay since we checked the bounds, and there are no + // relocations (we have an active `str` reference here). We don't use this + // result to affect interpreter execution. + let slice = data + .inner() + .inspect_with_uninit_and_ptr_outside_interpreter(start..end); + p!(write("{:?}", String::from_utf8_lossy(slice))); + return Ok(self); + } + _ => {} + } } (ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => { let n = n.val().try_to_bits(self.tcx().data_layout.pointer_size).unwrap(); @@ -1490,7 +1462,7 @@ pub trait PrettyPrinter<'tcx>: let byte_str = alloc.inner().get_bytes(&self.tcx(), range).unwrap(); p!("*"); p!(pretty_print_byte_str(byte_str)); - Ok(self) + return Ok(self); } // Aggregates, printed as array/tuple/struct/variant construction syntax. @@ -1567,22 +1539,24 @@ pub trait PrettyPrinter<'tcx>: _ => unreachable!(), } - Ok(self) + return Ok(self); } - (ConstValue::Scalar(scalar), _) => self.pretty_print_const_scalar(scalar, ty, print_ty), + (ConstValue::Scalar(scalar), _) => { + return self.pretty_print_const_scalar(scalar, ty, print_ty); + } // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading // their fields instead of just dumping the memory. - _ => { - // fallback - p!(write("{:?}", ct)); - if print_ty { - p!(": ", print(ty)); - } - Ok(self) - } + _ => {} } + + // fallback + p!(write("{:?}", ct)); + if print_ty { + p!(": ", print(ty)); + } + Ok(self) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 29a388538792c..a9749716ce892 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -6,14 +6,12 @@ use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; use crate::ty::{ - self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Region, Ty, TyCtxt, TyKind::*, - TypeFoldable, + self, Const, DebruijnIndex, DefIdTree, List, ReEarlyBound, Ty, TyCtxt, TyKind::*, TypeFoldable, }; use rustc_apfloat::Float as _; use rustc_ast as ast; use rustc_attr::{self as attr, SignedInt, UnsignedInt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::intern::{Interned, WithStableHash}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -423,26 +421,25 @@ impl<'tcx> TyCtxt<'tcx> { let result = iter::zip(item_substs, impl_substs) .filter(|&(_, k)| { match k.unpack() { - GenericArgKind::Lifetime(Region(Interned(ReEarlyBound(ref ebr), _))) => { - !impl_generics.region_param(ebr, self).pure_wrt_drop - } - GenericArgKind::Type(Ty(Interned( - WithStableHash { - internee: ty::TyS { kind: ty::Param(ref pt), .. }, .. - }, - _, - ))) => !impl_generics.type_param(pt, self).pure_wrt_drop, - GenericArgKind::Const(Const(Interned( - ty::ConstS { val: ty::ConstKind::Param(ref pc), .. }, - _, - ))) => !impl_generics.const_param(pc, self).pure_wrt_drop, - GenericArgKind::Lifetime(_) - | GenericArgKind::Type(_) - | GenericArgKind::Const(_) => { - // Not a type, const or region param: this should be reported - // as an error. - false - } + GenericArgKind::Lifetime(region) => match region.kind() { + ReEarlyBound(ref ebr) => { + !impl_generics.region_param(ebr, self).pure_wrt_drop + } + // Error: not a region param + _ => false, + }, + GenericArgKind::Type(ty) => match ty.kind() { + ty::Param(ref pt) => !impl_generics.type_param(pt, self).pure_wrt_drop, + // Error: not a type param + _ => false, + }, + GenericArgKind::Const(ct) => match ct.val() { + ty::ConstKind::Param(ref pc) => { + !impl_generics.const_param(pc, self).pure_wrt_drop + } + // Error: not a const param + _ => false, + }, } }) .map(|(item_param, _)| item_param) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 2b9cc75f1b753..302b8b791566d 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -8,7 +8,6 @@ //! In this case we try to build an abstract representation of this constant using //! `thir_abstract_const` which can then be checked for structural equality with other //! generic constants mentioned in the `caller_bounds` of the current environment. -use rustc_data_structures::intern::Interned; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_index::vec::IndexVec; @@ -414,14 +413,12 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.recurse_build(self.body_id)?; for n in self.nodes.iter() { - if let Node::Leaf(ty::Const(Interned( - ty::ConstS { val: ty::ConstKind::Unevaluated(ct), ty: _ }, - _, - ))) = n - { - // `AbstractConst`s should not contain any promoteds as they require references which - // are not allowed. - assert_eq!(ct.promoted, None); + if let Node::Leaf(ct) = n { + if let ty::ConstKind::Unevaluated(ct) = ct.val() { + // `AbstractConst`s should not contain any promoteds as they require references which + // are not allowed. + assert_eq!(ct.promoted, None); + } } } diff --git a/compiler/rustc_typeck/src/check/place_op.rs b/compiler/rustc_typeck/src/check/place_op.rs index 42eec1776495e..5dab0bb7a1375 100644 --- a/compiler/rustc_typeck/src/check/place_op.rs +++ b/compiler/rustc_typeck/src/check/place_op.rs @@ -1,7 +1,6 @@ use crate::check::method::MethodCallee; use crate::check::{has_expected_num_generic_args, FnCtxt, PlaceOp}; use rustc_ast as ast; -use rustc_data_structures::intern::Interned; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -126,9 +125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) = index_expr.kind { match adjusted_ty.kind() { - ty::Adt(ty::AdtDef(Interned(ty::AdtDefData { did, .. }, _)), _) - if self.tcx.is_diagnostic_item(sym::Vec, *did) => - { + ty::Adt(def, _) if self.tcx.is_diagnostic_item(sym::Vec, def.did()) => { return self.negative_index(adjusted_ty, index_expr.span, base_expr); } ty::Slice(_) | ty::Array(_, _) => { diff --git a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs index df780747a0c75..a8f9c189adec8 100644 --- a/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/case_sensitive_file_extension_comparisons.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_help; use if_chain::if_chain; use rustc_ast::ast::LitKind; -use rustc_data_structures::intern::Interned; use rustc_hir::{Expr, ExprKind, PathSegment}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; @@ -56,8 +55,8 @@ fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: & ty::Str => { return Some(span); }, - ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) => { - if ctx.tcx.is_diagnostic_item(sym::String, did) { + ty::Adt(def, _) => { + if ctx.tcx.is_diagnostic_item(sym::String, def.did()) { return Some(span); } },