X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=compiler%2Frustc_middle%2Fsrc%2Fty%2Fcontext.rs;h=c3df9a66fe7186881df6ab4c29b8501ef23e98ed;hb=923072b8013b17b229df96598af0b6e0f8f869eb;hp=1616b753433a83c0e47415865ca3e67836870677;hpb=04454e1e9e4605f1f24bb172ca3209acbad7a83d;p=rustc.git diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1616b75343..c3df9a66fe 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -6,9 +6,9 @@ use crate::hir::place::Place as HirPlace; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource}; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; -use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath}; +use crate::middle::resolve_lifetime; use crate::middle::stability; -use crate::mir::interpret::{self, Allocation, ConstAllocation, ConstValue, Scalar}; +use crate::mir::interpret::{self, Allocation, ConstAllocation}; use crate::mir::{ Body, BorrowCheckResult, Field, Local, Place, PlaceElem, ProjectionKind, Promoted, }; @@ -16,7 +16,6 @@ use crate::thir::Thir; use crate::traits; use crate::ty::query::{self, TyCtxtAt}; use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts}; -use crate::ty::TyKind::*; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, @@ -50,7 +49,8 @@ use rustc_macros::HashStable; use rustc_middle::mir::FakeReadCause; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; -use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames}; +use rustc_session::config::{CrateType, OutputFilenames}; +use rustc_session::cstore::CrateStoreDyn; use rustc_session::lint::{Level, Lint}; use rustc_session::Limit; use rustc_session::Session; @@ -60,9 +60,9 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; +use rustc_type_ir::sty::TyKind::*; +use rustc_type_ir::{InternAs, InternIteratorElement, Interner, TypeFlags}; -use rustc_type_ir::TypeFlags; -use smallvec::SmallVec; use std::any::Any; use std::borrow::Borrow; use std::cmp::Ordering; @@ -74,6 +74,8 @@ use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; +use super::{ImplPolarity, RvalueScopes}; + pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// Creates a new `OnDiskCache` instance from the serialized data in `data`. fn new(sess: &'tcx Session, data: Mmap, start_pos: usize) -> Self @@ -86,7 +88,38 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { fn drop_serialized_data(&self, tcx: TyCtxt<'tcx>); - fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: &mut FileEncoder) -> FileEncodeResult; + fn serialize(&self, tcx: TyCtxt<'tcx>, encoder: FileEncoder) -> FileEncodeResult; +} + +#[allow(rustc::usage_of_ty_tykind)] +impl<'tcx> Interner for TyCtxt<'tcx> { + type AdtDef = ty::AdtDef<'tcx>; + type SubstsRef = ty::SubstsRef<'tcx>; + type DefId = DefId; + type Ty = Ty<'tcx>; + type Const = ty::Const<'tcx>; + type Region = Region<'tcx>; + type TypeAndMut = TypeAndMut<'tcx>; + type Mutability = hir::Mutability; + type Movability = hir::Movability; + type PolyFnSig = PolyFnSig<'tcx>; + type ListBinderExistentialPredicate = &'tcx List>>; + type BinderListTy = Binder<'tcx, &'tcx List>>; + type ListTy = &'tcx List>; + type ProjectionTy = ty::ProjectionTy<'tcx>; + type ParamTy = ParamTy; + type BoundTy = ty::BoundTy; + type PlaceholderType = ty::PlaceholderType; + type InferTy = InferTy; + type DelaySpanBugEmitted = DelaySpanBugEmitted; + type PredicateKind = ty::PredicateKind<'tcx>; + type AllocId = crate::mir::interpret::AllocId; + + type EarlyBoundRegion = ty::EarlyBoundRegion; + type BoundRegion = ty::BoundRegion; + type FreeRegion = ty::FreeRegion; + type RegionVid = ty::RegionVid; + type PlaceholderRegion = ty::PlaceholderRegion; } /// A type that is not publicly constructable. This prevents people from making [`TyKind::Error`]s @@ -109,7 +142,7 @@ pub struct CtxtInterners<'tcx> { type_: InternedSet<'tcx, WithStableHash>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, canonical_var_infos: InternedSet<'tcx, List>>, - region: InternedSet<'tcx, RegionKind>, + region: InternedSet<'tcx, RegionKind<'tcx>>, poly_existential_predicates: InternedSet<'tcx, List>>>, predicate: InternedSet<'tcx, PredicateS<'tcx>>, @@ -151,7 +184,9 @@ impl<'tcx> CtxtInterners<'tcx> { &self, kind: TyKind<'tcx>, sess: &Session, - resolutions: &ty::ResolverOutputs, + definitions: &rustc_hir::definitions::Definitions, + cstore: &CrateStoreDyn, + source_span: &IndexVec, ) -> Ty<'tcx> { Ty(Interned::new_unchecked( self.type_ @@ -168,8 +203,9 @@ impl<'tcx> CtxtInterners<'tcx> { let mut hasher = StableHasher::new(); let mut hcx = StableHashingContext::ignore_spans( sess, - &resolutions.definitions, - &*resolutions.cstore, + definitions, + cstore, + source_span, ); kind.hash_stable(&mut hcx, &mut hasher); hasher.finish() @@ -535,6 +571,11 @@ pub struct TypeckResults<'tcx> { /// issue by fake reading `t`. pub closure_fake_reads: FxHashMap, FakeReadCause, hir::HirId)>>, + /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions + /// by applying extended parameter rules. + /// Details may be find in `rustc_typeck::check::rvalue_scopes`. + pub rvalue_scopes: RvalueScopes, + /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). pub generator_interior_types: ty::Binder<'tcx, Vec>>, @@ -572,6 +613,7 @@ impl<'tcx> TypeckResults<'tcx> { concrete_opaque_types: Default::default(), closure_min_captures: Default::default(), closure_fake_reads: Default::default(), + rvalue_scopes: Default::default(), generator_interior_types: ty::Binder::dummy(Default::default()), treat_byte_string_as_slice: Default::default(), closure_size_eval: Default::default(), @@ -870,7 +912,7 @@ impl<'tcx> CanonicalUserType<'tcx> { _ => false, }, - GenericArgKind::Const(ct) => match ct.val() { + GenericArgKind::Const(ct) => match ct.kind() { ty::ConstKind::Bound(debruijn, b) => { // We only allow a `ty::INNERMOST` index in substitutions. assert_eq!(debruijn, ty::INNERMOST); @@ -902,9 +944,11 @@ impl<'tcx> CommonTypes<'tcx> { fn new( interners: &CtxtInterners<'tcx>, sess: &Session, - resolutions: &ty::ResolverOutputs, + definitions: &rustc_hir::definitions::Definitions, + cstore: &CrateStoreDyn, + source_span: &IndexVec, ) -> CommonTypes<'tcx> { - let mk = |ty| interners.intern_ty(ty, sess, resolutions); + let mk = |ty| interners.intern_ty(ty, sess, definitions, cstore, source_span); CommonTypes { unit: mk(Tuple(List::empty())), @@ -959,7 +1003,7 @@ impl<'tcx> CommonConsts<'tcx> { CommonConsts { unit: mk_const(ty::ConstS { - val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::ZST)), + kind: ty::ConstKind::Value(ty::ValTree::zst()), ty: types.unit, }), } @@ -1025,6 +1069,9 @@ pub struct GlobalCtxt<'tcx> { /// Common consts, pre-interned for your convenience. pub consts: CommonConsts<'tcx>, + definitions: rustc_hir::definitions::Definitions, + cstore: Box, + /// Output of the resolver. pub(crate) untracked_resolutions: ty::ResolverOutputs, @@ -1186,7 +1233,9 @@ impl<'tcx> TyCtxt<'tcx> { s: &'tcx Session, lint_store: Lrc, arena: &'tcx WorkerLocal>, - resolutions: ty::ResolverOutputs, + definitions: rustc_hir::definitions::Definitions, + cstore: Box, + untracked_resolutions: ty::ResolverOutputs, krate: &'tcx hir::Crate<'tcx>, dep_graph: DepGraph, on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>, @@ -1199,7 +1248,14 @@ impl<'tcx> TyCtxt<'tcx> { s.fatal(&err); }); let interners = CtxtInterners::new(arena); - let common_types = CommonTypes::new(&interners, s, &resolutions); + let common_types = CommonTypes::new( + &interners, + s, + &definitions, + &*cstore, + // This is only used to create a stable hashing context. + &untracked_resolutions.source_span, + ); let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -1209,7 +1265,9 @@ impl<'tcx> TyCtxt<'tcx> { arena, interners, dep_graph, - untracked_resolutions: resolutions, + definitions, + cstore, + untracked_resolutions, prof: s.prof.clone(), types: common_types, lifetimes: common_lifetimes, @@ -1230,7 +1288,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - crate fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct { + pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct { &self.query_kinds[k as usize] } @@ -1268,7 +1326,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Const<'tcx> { let reported = self.sess.delay_span_bug(span, msg); self.mk_const(ty::ConstS { - val: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }), + kind: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }), ty, }) } @@ -1310,9 +1368,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { // Accessing the DefKey is ok, since it is part of DefPathHash. if let Some(id) = id.as_local() { - self.untracked_resolutions.definitions.def_key(id) + self.definitions.def_key(id) } else { - self.untracked_resolutions.cstore.def_key(id) + self.cstore.def_key(id) } } @@ -1324,9 +1382,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath { // Accessing the DefPath is ok, since it is part of DefPathHash. if let Some(id) = id.as_local() { - self.untracked_resolutions.definitions.def_path(id) + self.definitions.def_path(id) } else { - self.untracked_resolutions.cstore.def_path(id) + self.cstore.def_path(id) } } @@ -1334,9 +1392,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash { // Accessing the DefPathHash is ok, it is incr. comp. stable. if let Some(def_id) = def_id.as_local() { - self.untracked_resolutions.definitions.def_path_hash(def_id) + self.definitions.def_path_hash(def_id) } else { - self.untracked_resolutions.cstore.def_path_hash(def_id) + self.cstore.def_path_hash(def_id) } } @@ -1345,7 +1403,7 @@ impl<'tcx> TyCtxt<'tcx> { if crate_num == LOCAL_CRATE { self.sess.local_stable_crate_id() } else { - self.untracked_resolutions.cstore.stable_crate_id(crate_num) + self.cstore.stable_crate_id(crate_num) } } @@ -1356,7 +1414,7 @@ impl<'tcx> TyCtxt<'tcx> { if stable_crate_id == self.sess.local_stable_crate_id() { LOCAL_CRATE } else { - self.untracked_resolutions.cstore.stable_crate_id_to_crate_num(stable_crate_id) + self.cstore.stable_crate_id_to_crate_num(stable_crate_id) } } @@ -1371,16 +1429,12 @@ impl<'tcx> TyCtxt<'tcx> { // If this is a DefPathHash from the local crate, we can look up the // DefId in the tcx's `Definitions`. if stable_crate_id == self.sess.local_stable_crate_id() { - self.untracked_resolutions - .definitions - .local_def_path_hash_to_def_id(hash, err) - .to_def_id() + self.definitions.local_def_path_hash_to_def_id(hash, err).to_def_id() } else { // If this is a DefPathHash from an upstream crate, let the CrateStore map // it to a DefId. - let cstore = &self.untracked_resolutions.cstore; - let cnum = cstore.stable_crate_id_to_crate_num(stable_crate_id); - cstore.def_path_hash_to_def_id(cnum, hash) + let cnum = self.cstore.stable_crate_id_to_crate_num(stable_crate_id); + self.cstore.def_path_hash_to_def_id(cnum, hash) } } @@ -1392,7 +1446,7 @@ impl<'tcx> TyCtxt<'tcx> { let (crate_name, stable_crate_id) = if def_id.is_local() { (self.crate_name, self.sess.local_stable_crate_id()) } else { - let cstore = &self.untracked_resolutions.cstore; + let cstore = &self.cstore; (cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate)) }; @@ -1408,72 +1462,45 @@ impl<'tcx> TyCtxt<'tcx> { /// Note that this is *untracked* and should only be used within the query /// system if the result is otherwise tracked through queries - pub fn cstore_untracked(self) -> &'tcx ty::CrateStoreDyn { - &*self.untracked_resolutions.cstore + pub fn cstore_untracked(self) -> &'tcx CrateStoreDyn { + &*self.cstore } /// Note that this is *untracked* and should only be used within the query /// system if the result is otherwise tracked through queries pub fn definitions_untracked(self) -> &'tcx hir::definitions::Definitions { - &self.untracked_resolutions.definitions + &self.definitions + } + + /// Note that this is *untracked* and should only be used within the query + /// system if the result is otherwise tracked through queries + #[inline] + pub fn source_span_untracked(self, def_id: LocalDefId) -> Span { + self.untracked_resolutions.source_span.get(def_id).copied().unwrap_or(DUMMY_SP) } #[inline(always)] pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> { - let resolutions = &self.gcx.untracked_resolutions; - StableHashingContext::new(self.sess, &resolutions.definitions, &*resolutions.cstore) + StableHashingContext::new( + self.sess, + &self.definitions, + &*self.cstore, + &self.untracked_resolutions.source_span, + ) } #[inline(always)] pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> { - let resolutions = &self.gcx.untracked_resolutions; StableHashingContext::ignore_spans( self.sess, - &resolutions.definitions, - &*resolutions.cstore, + &self.definitions, + &*self.cstore, + &self.untracked_resolutions.source_span, ) } - pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult { - self.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder)) - } - - /// If `true`, we should use the MIR-based borrowck, but also - /// fall back on the AST borrowck if the MIR-based one errors. - pub fn migrate_borrowck(self) -> bool { - self.borrowck_mode().migrate() - } - - /// What mode(s) of borrowck should we run? AST? MIR? both? - /// (Also considers the `#![feature(nll)]` setting.) - pub fn borrowck_mode(self) -> BorrowckMode { - // Here are the main constraints we need to deal with: - // - // 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is - // synonymous with no `-Z borrowck=...` flag at all. - // - // 2. We want to allow developers on the Nightly channel - // to opt back into the "hard error" mode for NLL, - // (which they can do via specifying `#![feature(nll)]` - // explicitly in their crate). - // - // So, this precedence list is how pnkfelix chose to work with - // the above constraints: - // - // * `#![feature(nll)]` *always* means use NLL with hard - // errors. (To simplify the code here, it now even overrides - // a user's attempt to specify `-Z borrowck=compare`, which - // we arguably do not need anymore and should remove.) - // - // * Otherwise, if no `-Z borrowck=...` then use migrate mode - // - // * Otherwise, use the behavior requested via `-Z borrowck=...` - - if self.features().nll { - return BorrowckMode::Mir; - } - - self.sess.opts.borrowck_mode + pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult { + self.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder)) } /// If `true`, we should use lazy normalization for constants, otherwise @@ -1556,7 +1583,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {} Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {} Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {} - Node::Expr(&hir::Expr { kind: ExprKind::Closure(..), .. }) => {} + Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {} _ => return None, } @@ -1669,7 +1696,7 @@ macro_rules! nop_lift { impl<'a, 'tcx> Lift<'tcx> for $ty { type Lifted = $lifted; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option { - if tcx.interners.$set.contains_pointer_to(&InternedInSet(self.0.0)) { + if tcx.interners.$set.contains_pointer_to(&InternedInSet(&*self.0.0)) { // SAFETY: `self` is interned and therefore valid // for the entire lifetime of the `TyCtxt`. Some(unsafe { mem::transmute(self) }) @@ -2154,7 +2181,7 @@ macro_rules! direct_interners { } direct_interners! { - region: mk_region(RegionKind): Region -> Region<'tcx>, + region: mk_region(RegionKind<'tcx>): Region -> Region<'tcx>, const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>, const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, layout: intern_layout(LayoutS<'tcx>): Layout -> Layout<'tcx>, @@ -2203,6 +2230,20 @@ impl<'tcx> TyCtxt<'tcx> { }) } + /// Given a `ty`, return whether it's an `impl Future<...>`. + pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { + let ty::Opaque(def_id, _) = ty.kind() else { return false }; + let future_trait = self.lang_items().future_trait().unwrap(); + + self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { + let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { + return false; + }; + trait_predicate.trait_ref.def_id == future_trait + && trait_predicate.polarity == ImplPolarity::Positive + }) + } + /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used /// to identify which traits may define a given associated type to help avoid cycle errors. @@ -2253,14 +2294,21 @@ impl<'tcx> TyCtxt<'tcx> { /// Same a `self.mk_region(kind)`, but avoids accessing the interners if /// `*r == kind`. #[inline] - pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind) -> Region<'tcx> { + pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { if *r == kind { r } else { self.mk_region(kind) } } #[allow(rustc::usage_of_ty_tykind)] #[inline] pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> { - self.interners.intern_ty(st, self.sess, &self.gcx.untracked_resolutions) + self.interners.intern_ty( + st, + self.sess, + &self.definitions, + &*self.cstore, + // This is only used to create a stable hashing context. + &self.untracked_resolutions.source_span, + ) } #[inline] @@ -2473,7 +2521,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { - self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(InferConst::Var(v)), ty }) + self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(InferConst::Var(v)), ty }) } #[inline] @@ -2493,7 +2541,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> { - self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(ic), ty }) + self.mk_const(ty::ConstS { kind: ty::ConstKind::Infer(ic), ty }) } #[inline] @@ -2503,7 +2551,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> { - self.mk_const(ty::ConstS { val: ty::ConstKind::Param(ParamConst { index, name }), ty }) + self.mk_const(ty::ConstS { kind: ty::ConstKind::Param(ParamConst { index, name }), ty }) } pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { @@ -2771,6 +2819,13 @@ impl<'tcx> TyCtxt<'tcx> { self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned()) } + pub fn is_late_bound(self, id: HirId) -> bool { + self.is_late_bound_map(id.owner).map_or(false, |set| { + let def_id = self.hir().local_def_id(id); + set.contains(&def_id) + }) + } + pub fn late_bound_vars(self, id: HirId) -> &'tcx List { self.mk_bound_variable_kinds( self.late_bound_vars_map(id.owner) @@ -2782,16 +2837,12 @@ impl<'tcx> TyCtxt<'tcx> { ) } - pub fn lifetime_scope(self, id: HirId) -> Option<&'tcx LifetimeScopeForPath> { - self.lifetime_scope_map(id.owner).as_ref().and_then(|map| map.get(&id.local_id)) - } - /// Whether the `def_id` counts as const fn in the current crate, considering all active /// feature gates pub fn is_const_fn(self, def_id: DefId) -> bool { if self.is_const_fn_raw(def_id) { match self.lookup_const_stability(def_id) { - Some(stability) if stability.level.is_unstable() => { + Some(stability) if stability.is_const_unstable() => { // has a `rustc_const_unstable` attribute, check whether the user enabled the // corresponding feature gate. self.features() @@ -2808,6 +2859,21 @@ impl<'tcx> TyCtxt<'tcx> { false } } + + /// Whether the trait impl is marked const. This does not consider stability or feature gates. + pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { + let Some(local_def_id) = def_id.as_local() else { return false }; + let hir_id = self.local_def_id_to_hir_id(local_def_id); + let node = self.hir().get(hir_id); + + matches!( + node, + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), + .. + }) + ) + } } impl<'tcx> TyCtxtAt<'tcx> { @@ -2825,108 +2891,6 @@ impl<'tcx> TyCtxtAt<'tcx> { } } -pub trait InternAs { - type Output; - fn intern_with(self, f: F) -> Self::Output - where - F: FnOnce(&T) -> R; -} - -impl InternAs<[T], R> for I -where - E: InternIteratorElement, - I: Iterator, -{ - type Output = E::Output; - fn intern_with(self, f: F) -> Self::Output - where - F: FnOnce(&[T]) -> R, - { - E::intern_with(self, f) - } -} - -pub trait InternIteratorElement: Sized { - type Output; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output; -} - -impl InternIteratorElement for T { - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>( - mut iter: I, - f: F, - ) -> Self::Output { - // This code is hot enough that it's worth specializing for the most - // common length lists, to avoid the overhead of `SmallVec` creation. - // Lengths 0, 1, and 2 typically account for ~95% of cases. If - // `size_hint` is incorrect a panic will occur via an `unwrap` or an - // `assert`. - match iter.size_hint() { - (0, Some(0)) => { - assert!(iter.next().is_none()); - f(&[]) - } - (1, Some(1)) => { - let t0 = iter.next().unwrap(); - assert!(iter.next().is_none()); - f(&[t0]) - } - (2, Some(2)) => { - let t0 = iter.next().unwrap(); - let t1 = iter.next().unwrap(); - assert!(iter.next().is_none()); - f(&[t0, t1]) - } - _ => f(&iter.collect::>()), - } - } -} - -impl<'a, T, R> InternIteratorElement for &'a T -where - T: Clone + 'a, -{ - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { - // This code isn't hot. - f(&iter.cloned().collect::>()) - } -} - -impl InternIteratorElement for Result { - type Output = Result; - fn intern_with, F: FnOnce(&[T]) -> R>( - mut iter: I, - f: F, - ) -> Self::Output { - // This code is hot enough that it's worth specializing for the most - // common length lists, to avoid the overhead of `SmallVec` creation. - // Lengths 0, 1, and 2 typically account for ~95% of cases. If - // `size_hint` is incorrect a panic will occur via an `unwrap` or an - // `assert`, unless a failure happens first, in which case the result - // will be an error anyway. - Ok(match iter.size_hint() { - (0, Some(0)) => { - assert!(iter.next().is_none()); - f(&[]) - } - (1, Some(1)) => { - let t0 = iter.next().unwrap()?; - assert!(iter.next().is_none()); - f(&[t0]) - } - (2, Some(2)) => { - let t0 = iter.next().unwrap()?; - let t1 = iter.next().unwrap()?; - assert!(iter.next().is_none()); - f(&[t0, t1]) - } - _ => f(&iter.collect::, _>>()?), - }) - } -} - // We are comparing types with different invariant lifetimes, so `ptr::eq` // won't work for us. fn ptr_eq(t: *const T, u: *const U) -> bool { @@ -2941,8 +2905,8 @@ pub fn provide(providers: &mut ty::query::Providers) { assert_eq!(id, LOCAL_CRATE); tcx.crate_name }; - providers.maybe_unused_trait_import = - |tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id); + providers.maybe_unused_trait_imports = + |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; providers.maybe_unused_extern_crates = |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..]; providers.names_imported_by_glob_use = |tcx, id| {