diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/arena.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/solve.rs | 67 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 8 |
3 files changed, 72 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 6a1a2a061dd..a149a61ec13 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -121,6 +121,7 @@ macro_rules! arena_types { >, [] bit_set_u32: rustc_index::bit_set::BitSet<u32>, [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>, + [] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>, [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap, [] closure_kind_origin: (rustc_span::Span, rustc_middle::hir::place::Place<'tcx>), [] mod_child: rustc_middle::metadata::ModChild, diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index 1511c906d1e..2c5b64a59cd 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -5,13 +5,13 @@ use rustc_query_system::cache::Cache; use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints}; use crate::traits::query::NoSolution; -use crate::traits::Canonical; +use crate::traits::{Canonical, DefiningAnchor}; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, }; -pub type EvaluationCache<'tcx> = Cache<CanonicalGoal<'tcx>, QueryResult<'tcx>>; +pub type EvaluationCache<'tcx> = Cache<CanonicalInput<'tcx>, QueryResult<'tcx>>; /// A goal is a statement, i.e. `predicate`, we want to prove /// given some assumptions, i.e. `param_env`. @@ -96,7 +96,31 @@ pub enum MaybeCause { Overflow, } -pub type CanonicalGoal<'tcx, T = ty::Predicate<'tcx>> = Canonical<'tcx, Goal<'tcx, T>>; +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)] +pub struct QueryInput<'tcx, T> { + pub goal: Goal<'tcx, T>, + pub anchor: DefiningAnchor, + pub predefined_opaques_in_body: PredefinedOpaques<'tcx>, +} + +/// Additional constraints returned on success. +#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)] +pub struct PredefinedOpaquesData<'tcx> { + pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>, +} + +#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] +pub struct PredefinedOpaques<'tcx>(pub(crate) Interned<'tcx, PredefinedOpaquesData<'tcx>>); + +impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> { + type Target = PredefinedOpaquesData<'tcx>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub type CanonicalInput<'tcx, T = ty::Predicate<'tcx>> = Canonical<'tcx, QueryInput<'tcx, T>>; pub type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>; @@ -165,3 +189,40 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { ControlFlow::Continue(()) } } + +// FIXME: Having to clone `region_constraints` for folding feels bad and +// probably isn't great wrt performance. +// +// Not sure how to fix this, maybe we should also intern `opaque_types` and +// `region_constraints` here or something. +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + Ok(FallibleTypeFolder::interner(folder).mk_predefined_opaques_in_body( + PredefinedOpaquesData { + opaque_types: self + .opaque_types + .iter() + .map(|opaque| opaque.try_fold_with(folder)) + .collect::<Result<_, F::Error>>()?, + }, + )) + } + + fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self { + TypeFolder::interner(folder).mk_predefined_opaques_in_body(PredefinedOpaquesData { + opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), + }) + } +} + +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut V, + ) -> std::ops::ControlFlow<V::BreakTy> { + self.opaque_types.visit_with(visitor) + } +} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6c931a24462..2bde55bc4fd 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -21,7 +21,9 @@ use crate::query::{IntoQueryParam, TyCtxtAt}; use crate::thir::Thir; use crate::traits; use crate::traits::solve; -use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData}; +use crate::traits::solve::{ + ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData, +}; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, @@ -140,6 +142,7 @@ pub struct CtxtInterners<'tcx> { layout: InternedSet<'tcx, LayoutS>, adt_def: InternedSet<'tcx, AdtDefData>, external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, + predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, fields: InternedSet<'tcx, List<FieldIdx>>, } @@ -164,6 +167,7 @@ impl<'tcx> CtxtInterners<'tcx> { layout: Default::default(), adt_def: Default::default(), external_constraints: Default::default(), + predefined_opaques_in_body: Default::default(), fields: Default::default(), } } @@ -1520,6 +1524,8 @@ direct_interners! { adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>, + predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>): + PredefinedOpaques -> PredefinedOpaques<'tcx>, } macro_rules! slice_interners { |
