diff options
| author | The Miri Cronjob Bot <miri@cron.bot> | 2024-06-19 05:02:35 +0000 |
|---|---|---|
| committer | The Miri Cronjob Bot <miri@cron.bot> | 2024-06-19 05:02:35 +0000 |
| commit | 3e93254d5e2efb3d2dd738833142de9274c7b191 (patch) | |
| tree | 6ad18502b12564bac17108d771d900947abbefcb /compiler/rustc_middle/src | |
| parent | d9f1d557860138da64d52c0f536db395a99b9a4a (diff) | |
| parent | 2a6a42329f79d3c2a42f23ca9fb68aba511a2bc1 (diff) | |
Merge from rustc
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/arena.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/macros.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/stability.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/allocation.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/solve.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/solve/cache.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/adt.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/consts.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 370 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/generic_args.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/generics.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/predicate.rs | 42 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 36 |
16 files changed, 464 insertions, 113 deletions
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 3d4e5caa9b2..e3d7dff3c66 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -111,7 +111,7 @@ macro_rules! arena_types { rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>> >, [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>, - [] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>, + [] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<rustc_middle::ty::TyCtxt<'tcx>>, [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap, [] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem, [] mod_child: rustc_middle::metadata::ModChild, diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 817ac594627..fcea1ea81a7 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -4,10 +4,10 @@ /// /// If you have a span available, you should use [`span_bug`] instead. /// -/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxt::span_delayed_bug`] +/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`] /// may be useful. /// -/// [`DiagCtxt::span_delayed_bug`]: rustc_errors::DiagCtxt::span_delayed_bug +/// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug /// [`span_bug`]: crate::span_bug #[macro_export] macro_rules! bug { @@ -30,10 +30,10 @@ macro_rules! bug { /// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger /// ICEs. /// -/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxt::span_delayed_bug`] +/// If the bug should only be emitted when compilation didn't fail, [`DiagCtxtHandle::span_delayed_bug`] /// may be useful. /// -/// [`DiagCtxt::span_delayed_bug`]: rustc_errors::DiagCtxt::span_delayed_bug +/// [`DiagCtxtHandle::span_delayed_bug`]: rustc_errors::DiagCtxtHandle::span_delayed_bug #[macro_export] macro_rules! span_bug { ($span:expr, $msg:expr) => ( diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 8cf1bedf0da..d1ccd158cf9 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -176,7 +176,7 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate diag.arg("has_note", false); } if let Some(sub) = self.sub { - diag.subdiagnostic(diag.dcx, sub); + diag.subdiagnostic(sub); } } } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index b0f8a047b82..2fc466c0e7e 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -52,7 +52,7 @@ impl AllocBytes for Box<[u8]> { } fn zeroed(size: Size, _align: Align) -> Option<Self> { - let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes_usize()).ok()?; + let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes().try_into().ok()?).ok()?; // SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]> let bytes = unsafe { bytes.assume_init() }; Some(bytes) @@ -323,7 +323,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> { /// first call this function and then call write_scalar to fill in the right data. pub fn uninit(size: Size, align: Align) -> Self { match Self::uninit_inner(size, align, || { - panic!("Allocation::uninit called with panic_on_fail had allocation failure"); + panic!( + "interpreter ran out of memory: cannot create allocation of {} bytes", + size.bytes() + ); }) { Ok(x) => x, Err(x) => x, diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 9e979620a44..90f80f90767 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -5,12 +5,12 @@ use rustc_type_ir as ir; pub use rustc_type_ir::solve::*; use crate::ty::{ - self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, + self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, }; mod cache; -pub use cache::{CacheData, EvaluationCache}; +pub use cache::EvaluationCache; pub type Goal<'tcx, P> = ir::solve::Goal<TyCtxt<'tcx>, P>; pub type QueryInput<'tcx, P> = ir::solve::QueryInput<TyCtxt<'tcx>, P>; @@ -19,17 +19,11 @@ pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>; pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>; pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>; -/// Additional constraints returned on success. -#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default)] -pub struct PredefinedOpaquesData<'tcx> { - pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>, -} - #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)] -pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<'tcx>>); +pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>); impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> { - type Target = PredefinedOpaquesData<'tcx>; + type Target = PredefinedOpaquesData<TyCtxt<'tcx>>; fn deref(&self) -> &Self::Target { &self.0 diff --git a/compiler/rustc_middle/src/traits/solve/cache.rs b/compiler/rustc_middle/src/traits/solve/cache.rs index dc31114b2c4..72a8d4eb405 100644 --- a/compiler/rustc_middle/src/traits/solve/cache.rs +++ b/compiler/rustc_middle/src/traits/solve/cache.rs @@ -5,6 +5,8 @@ use rustc_data_structures::sync::Lock; use rustc_query_system::cache::WithDepNode; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_session::Limit; +use rustc_type_ir::solve::CacheData; + /// The trait solver cache used by `-Znext-solver`. /// /// FIXME(@lcnr): link to some official documentation of how @@ -14,17 +16,9 @@ pub struct EvaluationCache<'tcx> { map: Lock<FxHashMap<CanonicalInput<'tcx>, CacheEntry<'tcx>>>, } -#[derive(Debug, PartialEq, Eq)] -pub struct CacheData<'tcx> { - pub result: QueryResult<'tcx>, - pub proof_tree: Option<&'tcx inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>>, - pub additional_depth: usize, - pub encountered_overflow: bool, -} - -impl<'tcx> EvaluationCache<'tcx> { +impl<'tcx> rustc_type_ir::inherent::EvaluationCache<TyCtxt<'tcx>> for &'tcx EvaluationCache<'tcx> { /// Insert a final result into the global cache. - pub fn insert( + fn insert( &self, tcx: TyCtxt<'tcx>, key: CanonicalInput<'tcx>, @@ -48,7 +42,7 @@ impl<'tcx> EvaluationCache<'tcx> { if cfg!(debug_assertions) { drop(map); let expected = CacheData { result, proof_tree, additional_depth, encountered_overflow }; - let actual = self.get(tcx, key, [], Limit(additional_depth)); + let actual = self.get(tcx, key, [], additional_depth); if !actual.as_ref().is_some_and(|actual| expected == *actual) { bug!("failed to lookup inserted element for {key:?}: {expected:?} != {actual:?}"); } @@ -59,13 +53,13 @@ impl<'tcx> EvaluationCache<'tcx> { /// and handling root goals of coinductive cycles. /// /// If this returns `Some` the cache result can be used. - pub fn get( + fn get( &self, tcx: TyCtxt<'tcx>, key: CanonicalInput<'tcx>, stack_entries: impl IntoIterator<Item = CanonicalInput<'tcx>>, - available_depth: Limit, - ) -> Option<CacheData<'tcx>> { + available_depth: usize, + ) -> Option<CacheData<TyCtxt<'tcx>>> { let map = self.map.borrow(); let entry = map.get(&key)?; @@ -76,7 +70,7 @@ impl<'tcx> EvaluationCache<'tcx> { } if let Some(ref success) = entry.success { - if available_depth.value_within_limit(success.additional_depth) { + if Limit(available_depth).value_within_limit(success.additional_depth) { let QueryData { result, proof_tree } = success.data.get(tcx); return Some(CacheData { result, @@ -87,12 +81,12 @@ impl<'tcx> EvaluationCache<'tcx> { } } - entry.with_overflow.get(&available_depth.0).map(|e| { + entry.with_overflow.get(&available_depth).map(|e| { let QueryData { result, proof_tree } = e.get(tcx); CacheData { result, proof_tree, - additional_depth: available_depth.0, + additional_depth: available_depth, encountered_overflow: true, } }) diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 684b3233cfd..8e221cdc603 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -205,6 +205,14 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> { self.did() } + fn is_struct(self) -> bool { + self.is_struct() + } + + fn struct_tail_ty(self, interner: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + Some(interner.type_of(self.non_enum_variant().tail_opt()?.did)) + } + fn is_phantom_data(self) -> bool { self.is_phantom_data() } @@ -212,7 +220,7 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> { fn all_field_tys( self, tcx: TyCtxt<'tcx>, - ) -> ty::EarlyBinder<'tcx, impl Iterator<Item = Ty<'tcx>>> { + ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = Ty<'tcx>>> { ty::EarlyBinder::bind( self.all_fields().map(move |field| tcx.type_of(field.did).skip_binder()), ) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 12f0c38b054..32d01d07c17 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -16,8 +16,8 @@ mod valtree; pub use int::*; pub use kind::*; -use rustc_span::Span; use rustc_span::DUMMY_SP; +use rustc_span::{ErrorGuaranteed, Span}; pub use valtree::*; pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>; @@ -176,6 +176,10 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> { fn new_expr(interner: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Self { Const::new_expr(interner, expr) } + + fn new_error(interner: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { + Const::new_error(interner, guar) + } } impl<'tcx> Const<'tcx> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e2f15dac019..6d64c1d50ae 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -47,7 +47,9 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work #[cfg(parallel_compiler)] use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan}; +use rustc_errors::{ + Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; @@ -71,6 +73,7 @@ use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx} use rustc_target::spec::abi; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SolverMode; use rustc_type_ir::TyKind::*; use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo}; use tracing::{debug, instrument}; @@ -89,46 +92,65 @@ use std::ops::{Bound, Deref}; impl<'tcx> Interner for TyCtxt<'tcx> { type DefId = DefId; type LocalDefId = LocalDefId; - type AdtDef = ty::AdtDef<'tcx>; - type GenericArgs = ty::GenericArgsRef<'tcx>; + type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>]; type GenericArg = ty::GenericArg<'tcx>; type Term = ty::Term<'tcx>; - type BoundVarKinds = &'tcx List<ty::BoundVariableKind>; - type BoundVarKind = ty::BoundVariableKind; - type CanonicalVars = CanonicalVarInfos<'tcx>; + type BoundVarKind = ty::BoundVariableKind; type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; + + fn mk_predefined_opaques_in_body( + self, + data: PredefinedOpaquesData<Self>, + ) -> Self::PredefinedOpaques { + self.mk_predefined_opaques_in_body(data) + } type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>; - type ExternalConstraints = ExternalConstraints<'tcx>; type CanonicalGoalEvaluationStepRef = &'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>; + type CanonicalVars = CanonicalVarInfos<'tcx>; + fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars { + self.mk_canonical_var_infos(infos) + } + type ExternalConstraints = ExternalConstraints<'tcx>; + fn mk_external_constraints( + self, + data: ExternalConstraintsData<Self>, + ) -> ExternalConstraints<'tcx> { + self.mk_external_constraints(data) + } + type DepNodeIndex = DepNodeIndex; + fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) { + self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task) + } type Ty = Ty<'tcx>; type Tys = &'tcx List<Ty<'tcx>>; + type FnInputTys = &'tcx [Ty<'tcx>]; type ParamTy = ParamTy; type BoundTy = ty::BoundTy; - type PlaceholderTy = ty::PlaceholderType; + type PlaceholderTy = ty::PlaceholderType; type ErrorGuaranteed = ErrorGuaranteed; type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>; - type AllocId = crate::mir::interpret::AllocId; + type AllocId = crate::mir::interpret::AllocId; type Pat = Pattern<'tcx>; type Safety = hir::Safety; type Abi = abi::Abi; - type Const = ty::Const<'tcx>; type PlaceholderConst = ty::PlaceholderConst; + type ParamConst = ty::ParamConst; type BoundConst = ty::BoundVar; type ValueConst = ty::ValTree<'tcx>; type ExprConst = ty::Expr<'tcx>; - type Region = Region<'tcx>; + type EarlyParamRegion = ty::EarlyParamRegion; type LateParamRegion = ty::LateParamRegion; type BoundRegion = ty::BoundRegion; @@ -136,15 +158,21 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ParamEnv = ty::ParamEnv<'tcx>; type Predicate = Predicate<'tcx>; + type Clause = Clause<'tcx>; type Clauses = ty::Clauses<'tcx>; - fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T { - self.expand_abstract_consts(t) + type EvaluationCache = &'tcx solve::EvaluationCache<'tcx>; + + fn evaluation_cache(self, mode: SolverMode) -> &'tcx solve::EvaluationCache<'tcx> { + match mode { + SolverMode::Normal => &self.new_solver_evaluation_cache, + SolverMode::Coherence => &self.new_solver_coherence_evaluation_cache, + } } - fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars { - self.mk_canonical_var_infos(infos) + fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T { + self.expand_abstract_consts(t) } type GenericsOf = &'tcx ty::Generics; @@ -163,6 +191,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.type_of(def_id) } + type AdtDef = ty::AdtDef<'tcx>; + fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef { + self.adt_def(adt_def_id) + } + fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind { match self.def_kind(alias.def_id) { DefKind::AssocTy => { @@ -200,8 +233,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn trait_ref_and_own_args_for_alias( self, def_id: DefId, - args: Self::GenericArgs, - ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) { + args: ty::GenericArgsRef<'tcx>, + ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst); let trait_def_id = self.parent(def_id); assert_matches!(self.def_kind(trait_def_id), DefKind::Trait); @@ -212,18 +245,22 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) } - fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs { + fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> { self.mk_args(args) } fn mk_args_from_iter<I, T>(self, args: I) -> T::Output where I: Iterator<Item = T>, - T: CollectAndApply<Self::GenericArg, Self::GenericArgs>, + T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>, { self.mk_args_from_iter(args) } + fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool { + self.check_args_compatible(def_id, args) + } + fn check_and_mk_args( self, def_id: DefId, @@ -242,7 +279,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output where I: Iterator<Item = T>, - T: CollectAndApply<Self::Ty, Self::Tys>, + T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>, { self.mk_type_list_from_iter(args) } @@ -291,6 +328,24 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.item_bounds(def_id).map_bound(IntoIterator::into_iter) } + fn predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> { + ty::EarlyBinder::bind( + self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(), + ) + } + + fn own_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> { + ty::EarlyBinder::bind( + self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause), + ) + } + fn super_predicates_of( self, def_id: DefId, @@ -305,15 +360,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId { - self.require_lang_item( - match lang_item { - TraitSolverLangItem::Future => hir::LangItem::Future, - TraitSolverLangItem::FutureOutput => hir::LangItem::FutureOutput, - TraitSolverLangItem::AsyncFnKindHelper => hir::LangItem::AsyncFnKindHelper, - TraitSolverLangItem::AsyncFnKindUpvars => hir::LangItem::AsyncFnKindUpvars, - }, - None, - ) + self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None) + } + + fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool { + self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item)) } fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> { @@ -322,6 +373,257 @@ impl<'tcx> Interner for TyCtxt<'tcx> { .filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type)) .map(|assoc_item| assoc_item.def_id) } + + fn args_may_unify_deep( + self, + obligation_args: ty::GenericArgsRef<'tcx>, + impl_args: ty::GenericArgsRef<'tcx>, + ) -> bool { + ty::fast_reject::DeepRejectCtxt { + treat_obligation_params: ty::fast_reject::TreatParams::ForLookup, + } + .args_may_unify(obligation_args, impl_args) + } + + // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`, + // since we want to skip over blanket impls for non-rigid aliases, and also we + // only want to consider types that *actually* unify with float/int vars. + fn for_each_relevant_impl( + self, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + mut f: impl FnMut(DefId), + ) { + let tcx = self; + let trait_impls = tcx.trait_impls_of(trait_def_id); + let mut consider_impls_for_simplified_type = |simp| { + if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) { + for &impl_def_id in impls_for_type { + f(impl_def_id); + } + } + }; + + match self_ty.kind() { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Pat(_, _) + | ty::Slice(_) + | ty::RawPtr(_, _) + | ty::Ref(_, _, _) + | ty::FnDef(_, _) + | ty::FnPtr(_) + | ty::Dynamic(_, _, _) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(_, _) + | ty::Never + | ty::Tuple(_) => { + let simp = ty::fast_reject::simplify_type( + tcx, + self_ty, + ty::fast_reject::TreatParams::ForLookup, + ) + .unwrap(); + consider_impls_for_simplified_type(simp); + } + + // HACK: For integer and float variables we have to manually look at all impls + // which have some integer or float as a self type. + ty::Infer(ty::IntVar(_)) => { + use ty::IntTy::*; + use ty::UintTy::*; + // This causes a compiler error if any new integer kinds are added. + let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy; + let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy; + let possible_integers = [ + // signed integers + ty::SimplifiedType::Int(I8), + ty::SimplifiedType::Int(I16), + ty::SimplifiedType::Int(I32), + ty::SimplifiedType::Int(I64), + ty::SimplifiedType::Int(I128), + ty::SimplifiedType::Int(Isize), + // unsigned integers + ty::SimplifiedType::Uint(U8), + ty::SimplifiedType::Uint(U16), + ty::SimplifiedType::Uint(U32), + ty::SimplifiedType::Uint(U64), + ty::SimplifiedType::Uint(U128), + ty::SimplifiedType::Uint(Usize), + ]; + for simp in possible_integers { + consider_impls_for_simplified_type(simp); + } + } + + ty::Infer(ty::FloatVar(_)) => { + // This causes a compiler error if any new float kinds are added. + let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128); + let possible_floats = [ + ty::SimplifiedType::Float(ty::FloatTy::F16), + ty::SimplifiedType::Float(ty::FloatTy::F32), + ty::SimplifiedType::Float(ty::FloatTy::F64), + ty::SimplifiedType::Float(ty::FloatTy::F128), + ]; + + for simp in possible_floats { + consider_impls_for_simplified_type(simp); + } + } + + // The only traits applying to aliases and placeholders are blanket impls. + // + // Impls which apply to an alias after normalization are handled by + // `assemble_candidates_after_normalizing_self_ty`. + ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (), + + // FIXME: These should ideally not exist as a self type. It would be nice for + // the builtin auto trait impls of coroutines to instead directly recurse + // into the witness. + ty::CoroutineWitness(..) => (), + + // These variants should not exist as a self type. + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + | ty::Param(_) + | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"), + } + + let trait_impls = tcx.trait_impls_of(trait_def_id); + for &impl_def_id in trait_impls.blanket_impls() { + f(impl_def_id); + } + } + + fn has_item_definition(self, def_id: DefId) -> bool { + self.defaultness(def_id).has_value() + } + + fn impl_is_default(self, impl_def_id: DefId) -> bool { + self.defaultness(impl_def_id).is_default() + } + + fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { + self.impl_trait_ref(impl_def_id).unwrap() + } + + fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity { + self.impl_polarity(impl_def_id) + } + + fn trait_is_auto(self, trait_def_id: DefId) -> bool { + self.trait_is_auto(trait_def_id) + } + + fn trait_is_alias(self, trait_def_id: DefId) -> bool { + self.trait_is_alias(trait_def_id) + } + + fn trait_is_object_safe(self, trait_def_id: DefId) -> bool { + self.is_object_safe(trait_def_id) + } + + fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool { + self.trait_def(trait_def_id).implement_via_object + } + + fn fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> { + self.fn_trait_kind_from_def_id(trait_def_id) + } + + fn async_fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> { + self.async_fn_trait_kind_from_def_id(trait_def_id) + } + + fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> { + self.supertrait_def_ids(trait_def_id) + } + + fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed { + self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) + } + + fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool { + self.is_general_coroutine(coroutine_def_id) + } + + fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool { + self.coroutine_is_async(coroutine_def_id) + } + + fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool { + self.coroutine_is_gen(coroutine_def_id) + } + + fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool { + self.coroutine_is_async_gen(coroutine_def_id) + } + + fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { + self.layout_of(self.erase_regions(param_env.and(ty))) + .is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout)) + } + + type UnsizingParams = &'tcx rustc_index::bit_set::BitSet<u32>; + fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams { + self.unsizing_params_for_adt(adt_def_id) + } + + fn find_const_ty_from_env( + self, + param_env: ty::ParamEnv<'tcx>, + placeholder: Self::PlaceholderConst, + ) -> Ty<'tcx> { + placeholder.find_const_ty_from_env(param_env) + } +} + +fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { + match lang_item { + TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct, + TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper, + TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars, + TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput, + TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator, + TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture, + TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture, + TraitSolverLangItem::Clone => LangItem::Clone, + TraitSolverLangItem::Copy => LangItem::Copy, + TraitSolverLangItem::Coroutine => LangItem::Coroutine, + TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn, + TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield, + TraitSolverLangItem::Destruct => LangItem::Destruct, + TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, + TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, + TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, + TraitSolverLangItem::FusedIterator => LangItem::FusedIterator, + TraitSolverLangItem::Future => LangItem::Future, + TraitSolverLangItem::FutureOutput => LangItem::FutureOutput, + TraitSolverLangItem::Iterator => LangItem::Iterator, + TraitSolverLangItem::Metadata => LangItem::Metadata, + TraitSolverLangItem::Option => LangItem::Option, + TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait, + TraitSolverLangItem::PointerLike => LangItem::PointerLike, + TraitSolverLangItem::Poll => LangItem::Poll, + TraitSolverLangItem::Sized => LangItem::Sized, + TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait, + TraitSolverLangItem::Tuple => LangItem::Tuple, + TraitSolverLangItem::Unpin => LangItem::Unpin, + TraitSolverLangItem::Unsize => LangItem::Unsize, + } +} + +impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId { + fn as_local(self) -> Option<LocalDefId> { + self.as_local() + } } impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi { @@ -356,6 +658,10 @@ impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_featu fn coroutine_clone(self) -> bool { self.coroutine_clone } + + fn associated_const_equality(self) -> bool { + self.associated_const_equality + } } type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>; @@ -384,7 +690,7 @@ pub struct CtxtInterners<'tcx> { layout: InternedSet<'tcx, LayoutS<FieldIdx, VariantIdx>>, adt_def: InternedSet<'tcx, AdtDefData>, external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>, - predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, + predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<TyCtxt<'tcx>>>, fields: InternedSet<'tcx, List<FieldIdx>>, local_def_ids: InternedSet<'tcx, List<LocalDefId>>, captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>, @@ -1415,7 +1721,7 @@ impl<'tcx> TyCtxt<'tcx> { ) } - pub fn dcx(self) -> &'tcx DiagCtxt { + pub fn dcx(self) -> DiagCtxtHandle<'tcx> { self.sess.dcx() } } @@ -2096,7 +2402,7 @@ direct_interners! { adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>): ExternalConstraints -> ExternalConstraints<'tcx>, - predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>): + predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<TyCtxt<'tcx>>): PredefinedOpaques -> PredefinedOpaques<'tcx>, } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 54c88e48614..83d45ca78d9 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -44,10 +44,27 @@ pub struct GenericArg<'tcx> { impl<'tcx> rustc_type_ir::inherent::GenericArg<TyCtxt<'tcx>> for GenericArg<'tcx> {} impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> { + fn rebase_onto( + self, + tcx: TyCtxt<'tcx>, + source_ancestor: DefId, + target_args: GenericArgsRef<'tcx>, + ) -> GenericArgsRef<'tcx> { + self.rebase_onto(tcx, source_ancestor, target_args) + } + fn type_at(self, i: usize) -> Ty<'tcx> { self.type_at(i) } + fn region_at(self, i: usize) -> ty::Region<'tcx> { + self.region_at(i) + } + + fn const_at(self, i: usize) -> ty::Const<'tcx> { + self.const_at(i) + } + fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> { GenericArgs::identity_for_item(tcx, def_id) } @@ -281,6 +298,7 @@ impl<'tcx> GenericArg<'tcx> { pub fn is_non_region_infer(self) -> bool { match self.unpack() { GenericArgKind::Lifetime(_) => false, + // FIXME: This shouldn't return numerical/float. GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(), GenericArgKind::Const(ct) => ct.is_ct_infer(), } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 185dbe44735..6467689a8aa 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -392,6 +392,10 @@ impl<'tcx> GenericPredicates<'tcx> { EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) } + pub fn instantiate_own_identity(&self) -> impl Iterator<Item = (Clause<'tcx>, Span)> { + EarlyBinder::bind(self.predicates).instantiate_identity_iter_copied() + } + #[instrument(level = "debug", skip(self, tcx))] fn instantiate_into( &self, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index cf7610bb4f6..3d397b6b37e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -5,7 +5,7 @@ use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt}; use rustc_error_messages::DiagMessage; use rustc_errors::{ - Diag, DiagArgValue, DiagCtxt, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, + Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -1256,7 +1256,7 @@ pub enum FnAbiError<'tcx> { } impl<'a, 'b, G: EmissionGuarantee> Diagnostic<'a, G> for FnAbiError<'b> { - fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { match self { Self::Layout(e) => e.into_diagnostic().into_diag(dcx, level), Self::AdjustForForeignAbi(call::AdjustForForeignAbiError::Unsupported { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d07541bad93..9c2bfc12a18 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -990,6 +990,16 @@ pub struct ParamEnv<'tcx> { packed: CopyTaggedPtr<Clauses<'tcx>, ParamTag, true>, } +impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> { + fn reveal(self) -> Reveal { + self.reveal() + } + + fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> { + self.caller_bounds() + } +} + #[derive(Copy, Clone)] struct ParamTag { reveal: traits::Reveal, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index ae36f2624ca..e9b37503bb3 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -175,6 +175,14 @@ pub struct Clause<'tcx>( impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {} +impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> { + type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>; + + fn kind(self) -> Self::Kind { + self.kind() + } +} + impl<'tcx> Clause<'tcx> { pub fn as_predicate(self) -> Predicate<'tcx> { Predicate(self.0) @@ -251,6 +259,28 @@ impl<'tcx> ExistentialPredicate<'tcx> { pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>; +impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>> + for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> +{ + fn principal_def_id(self) -> Option<DefId> { + self.principal_def_id() + } + + fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> { + self.principal() + } + + fn auto_traits(self) -> impl IntoIterator<Item = DefId> { + self.auto_traits() + } + + fn projection_bounds( + self, + ) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> { + self.projection_bounds() + } +} + impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> { /// Returns the "principal `DefId`" of this set of existential predicates. /// @@ -481,12 +511,6 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> { } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for TraitPredicate<'tcx> { - fn upcast_from(from: TraitRef<'tcx>, _tcx: TyCtxt<'tcx>) -> Self { - TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive } - } -} - impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> { fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self { let p: Predicate<'tcx> = from.upcast(tcx); @@ -543,6 +567,12 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> { } } +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: RegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { + ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx) + } +} + impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predicate<'tcx> { fn upcast_from(from: PolyRegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8308e537e5e..9c8a3484aa5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -930,6 +930,22 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> { fn new_pat(interner: TyCtxt<'tcx>, ty: Self, pat: ty::Pattern<'tcx>) -> Self { Ty::new_pat(interner, ty, pat) } + + fn new_unit(interner: TyCtxt<'tcx>) -> Self { + interner.types.unit + } + + fn new_usize(interner: TyCtxt<'tcx>) -> Self { + interner.types.usize + } + + fn discriminant_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> { + self.discriminant_ty(interner) + } + + fn async_destructor_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> { + self.async_destructor_ty(interner) + } } /// Type utilities diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 52a0e72e17e..b079ed521d3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -565,42 +565,6 @@ impl<'tcx> TyCtxt<'tcx> { Ok(()) } - /// Checks whether each generic argument is simply a unique generic placeholder. - /// - /// This is used in the new solver, which canonicalizes params to placeholders - /// for better caching. - pub fn uses_unique_placeholders_ignoring_regions( - self, - args: GenericArgsRef<'tcx>, - ) -> Result<(), NotUniqueParam<'tcx>> { - let mut seen = GrowableBitSet::default(); - for arg in args { - match arg.unpack() { - // Ignore regions, since we can't resolve those in a canonicalized - // query in the trait solver. - GenericArgKind::Lifetime(_) => {} - GenericArgKind::Type(t) => match t.kind() { - ty::Placeholder(p) => { - if !seen.insert(p.bound.var) { - return Err(NotUniqueParam::DuplicateParam(t.into())); - } - } - _ => return Err(NotUniqueParam::NotParam(t.into())), - }, - GenericArgKind::Const(c) => match c.kind() { - ty::ConstKind::Placeholder(p) => { - if !seen.insert(p.bound) { - return Err(NotUniqueParam::DuplicateParam(c.into())); - } - } - _ => return Err(NotUniqueParam::NotParam(c.into())), - }, - } - } - - Ok(()) - } - /// Returns `true` if `def_id` refers to a closure, coroutine, or coroutine-closure /// (i.e. an async closure). These are all represented by `hir::Closure`, and all /// have the same `DefKind`. |
