diff options
| author | mark <markm@cs.wisc.edu> | 2020-08-27 22:58:48 -0500 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2020-08-30 18:45:07 +0300 |
| commit | 9e5f7d5631b8f4009ac1c693e585d4b7108d4275 (patch) | |
| tree | 158a05eb3f204a8e72939b58427d0c2787a4eade /compiler/rustc_middle/src/traits/chalk.rs | |
| parent | db534b3ac286cf45688c3bbae6aa6e77439e52d2 (diff) | |
| download | rust-9e5f7d5631b8f4009ac1c693e585d4b7108d4275.tar.gz rust-9e5f7d5631b8f4009ac1c693e585d4b7108d4275.zip | |
mv compiler to compiler/
Diffstat (limited to 'compiler/rustc_middle/src/traits/chalk.rs')
| -rw-r--r-- | compiler/rustc_middle/src/traits/chalk.rs | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs new file mode 100644 index 00000000000..405af8cb240 --- /dev/null +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -0,0 +1,362 @@ +//! Types required for Chalk-related queries +//! +//! The primary purpose of this file is defining an implementation for the +//! `chalk_ir::interner::Interner` trait. The primary purpose of this trait, as +//! its name suggest, is to provide an abstraction boundary for creating +//! interned Chalk types. + +use rustc_middle::mir::interpret::ConstValue; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; + +use rustc_hir::def_id::DefId; +use rustc_target::spec::abi::Abi; + +use smallvec::SmallVec; + +use std::cmp::Ordering; +use std::fmt; +use std::hash::{Hash, Hasher}; + +#[derive(Copy, Clone)] +pub struct RustInterner<'tcx> { + pub tcx: TyCtxt<'tcx>, +} + +/// We don't ever actually need this. It's only required for derives. +impl<'tcx> Hash for RustInterner<'tcx> { + fn hash<H: Hasher>(&self, _state: &mut H) {} +} + +/// We don't ever actually need this. It's only required for derives. +impl<'tcx> Ord for RustInterner<'tcx> { + fn cmp(&self, _other: &Self) -> Ordering { + Ordering::Equal + } +} + +/// We don't ever actually need this. It's only required for derives. +impl<'tcx> PartialOrd for RustInterner<'tcx> { + fn partial_cmp(&self, _other: &Self) -> Option<Ordering> { + None + } +} + +/// We don't ever actually need this. It's only required for derives. +impl<'tcx> PartialEq for RustInterner<'tcx> { + fn eq(&self, _other: &Self) -> bool { + false + } +} + +/// We don't ever actually need this. It's only required for derives. +impl<'tcx> Eq for RustInterner<'tcx> {} + +impl fmt::Debug for RustInterner<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "RustInterner") + } +} + +// Right now, there is no interning at all. I was running into problems with +// adding interning in `ty/context.rs` for Chalk types with +// `parallel-compiler = true`. -jackh726 +impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { + type InternedType = Box<chalk_ir::TyData<Self>>; + type InternedLifetime = Box<chalk_ir::LifetimeData<Self>>; + type InternedConst = Box<chalk_ir::ConstData<Self>>; + type InternedConcreteConst = ConstValue<'tcx>; + type InternedGenericArg = Box<chalk_ir::GenericArgData<Self>>; + type InternedGoal = Box<chalk_ir::GoalData<Self>>; + type InternedGoals = Vec<chalk_ir::Goal<Self>>; + type InternedSubstitution = Vec<chalk_ir::GenericArg<Self>>; + type InternedProgramClause = Box<chalk_ir::ProgramClauseData<Self>>; + type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>; + type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; + type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; + type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; + type DefId = DefId; + type InternedAdtId = &'tcx AdtDef; + type Identifier = (); + type FnAbi = Abi; + + fn debug_program_clause_implication( + pci: &chalk_ir::ProgramClauseImplication<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + let mut write = || { + write!(fmt, "{:?}", pci.consequence)?; + + let conditions = pci.conditions.interned(); + + let conds = conditions.len(); + if conds == 0 { + return Ok(()); + } + + write!(fmt, " :- ")?; + for cond in &conditions[..conds - 1] { + write!(fmt, "{:?}, ", cond)?; + } + write!(fmt, "{:?}", conditions[conds - 1])?; + Ok(()) + }; + Some(write()) + } + + fn debug_application_ty( + application_ty: &chalk_ir::ApplicationTy<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + let chalk_ir::ApplicationTy { name, substitution } = application_ty; + Some(write!(fmt, "{:?}{:?}", name, chalk_ir::debug::Angle(substitution.interned()))) + } + + fn debug_substitution( + substitution: &chalk_ir::Substitution<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + Some(write!(fmt, "{:?}", substitution.interned())) + } + + fn debug_separator_trait_ref( + separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + let substitution = &separator_trait_ref.trait_ref.substitution; + let parameters = substitution.interned(); + Some(write!( + fmt, + "{:?}{}{:?}{:?}", + parameters[0], + separator_trait_ref.separator, + separator_trait_ref.trait_ref.trait_id, + chalk_ir::debug::Angle(¶meters[1..]) + )) + } + + fn debug_quantified_where_clauses( + clauses: &chalk_ir::QuantifiedWhereClauses<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + Some(write!(fmt, "{:?}", clauses.interned())) + } + + fn debug_alias( + alias_ty: &chalk_ir::AliasTy<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + match alias_ty { + chalk_ir::AliasTy::Projection(projection_ty) => { + Self::debug_projection_ty(projection_ty, fmt) + } + chalk_ir::AliasTy::Opaque(opaque_ty) => Self::debug_opaque_ty(opaque_ty, fmt), + } + } + + fn debug_projection_ty( + projection_ty: &chalk_ir::ProjectionTy<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + Some(write!( + fmt, + "projection: {:?} {:?}", + projection_ty.associated_ty_id, projection_ty.substitution, + )) + } + + fn debug_opaque_ty( + opaque_ty: &chalk_ir::OpaqueTy<Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option<fmt::Result> { + Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id)) + } + + fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Self::InternedType { + Box::new(ty) + } + + fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> { + ty + } + + fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime { + Box::new(lifetime) + } + + fn lifetime_data<'a>( + &self, + lifetime: &'a Self::InternedLifetime, + ) -> &'a chalk_ir::LifetimeData<Self> { + &lifetime + } + + fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst { + Box::new(constant) + } + + fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> { + &constant + } + + fn const_eq( + &self, + _ty: &Self::InternedType, + c1: &Self::InternedConcreteConst, + c2: &Self::InternedConcreteConst, + ) -> bool { + c1 == c2 + } + + fn intern_generic_arg(&self, data: chalk_ir::GenericArgData<Self>) -> Self::InternedGenericArg { + Box::new(data) + } + + fn generic_arg_data<'a>( + &self, + data: &'a Self::InternedGenericArg, + ) -> &'a chalk_ir::GenericArgData<Self> { + &data + } + + fn intern_goal(&self, goal: chalk_ir::GoalData<Self>) -> Self::InternedGoal { + Box::new(goal) + } + + fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a chalk_ir::GoalData<Self> { + &goal + } + + fn intern_goals<E>( + &self, + data: impl IntoIterator<Item = Result<chalk_ir::Goal<Self>, E>>, + ) -> Result<Self::InternedGoals, E> { + data.into_iter().collect::<Result<Vec<_>, _>>() + } + + fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [chalk_ir::Goal<Self>] { + goals + } + + fn intern_substitution<E>( + &self, + data: impl IntoIterator<Item = Result<chalk_ir::GenericArg<Self>, E>>, + ) -> Result<Self::InternedSubstitution, E> { + data.into_iter().collect::<Result<Vec<_>, _>>() + } + + fn substitution_data<'a>( + &self, + substitution: &'a Self::InternedSubstitution, + ) -> &'a [chalk_ir::GenericArg<Self>] { + substitution + } + + fn intern_program_clause( + &self, + data: chalk_ir::ProgramClauseData<Self>, + ) -> Self::InternedProgramClause { + Box::new(data) + } + + fn program_clause_data<'a>( + &self, + clause: &'a Self::InternedProgramClause, + ) -> &'a chalk_ir::ProgramClauseData<Self> { + &clause + } + + fn intern_program_clauses<E>( + &self, + data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>, + ) -> Result<Self::InternedProgramClauses, E> { + data.into_iter().collect::<Result<Vec<_>, _>>() + } + + fn program_clauses_data<'a>( + &self, + clauses: &'a Self::InternedProgramClauses, + ) -> &'a [chalk_ir::ProgramClause<Self>] { + clauses + } + + fn intern_quantified_where_clauses<E>( + &self, + data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>, + ) -> Result<Self::InternedQuantifiedWhereClauses, E> { + data.into_iter().collect::<Result<Vec<_>, _>>() + } + + fn quantified_where_clauses_data<'a>( + &self, + clauses: &'a Self::InternedQuantifiedWhereClauses, + ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] { + clauses + } + + fn intern_generic_arg_kinds<E>( + &self, + data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>, + ) -> Result<Self::InternedVariableKinds, E> { + data.into_iter().collect::<Result<Vec<_>, _>>() + } + + fn variable_kinds_data<'a>( + &self, + parameter_kinds: &'a Self::InternedVariableKinds, + ) -> &'a [chalk_ir::VariableKind<Self>] { + parameter_kinds + } + + fn intern_canonical_var_kinds<E>( + &self, + data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>, + ) -> Result<Self::InternedCanonicalVarKinds, E> { + data.into_iter().collect::<Result<Vec<_>, _>>() + } + + fn canonical_var_kinds_data<'a>( + &self, + canonical_var_kinds: &'a Self::InternedCanonicalVarKinds, + ) -> &'a [chalk_ir::CanonicalVarKind<Self>] { + canonical_var_kinds + } +} + +impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> { + type Interner = Self; +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +pub enum ChalkEnvironmentClause<'tcx> { + /// A normal rust `ty::Predicate` in the environment. + Predicate(ty::Predicate<'tcx>), + /// A special clause in the environment that gets lowered to + /// `chalk_ir::FromEnv::Ty`. + TypeFromEnv(Ty<'tcx>), +} + +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ChalkEnvironmentClause<'tcx>> { + fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self { + let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>(); + folder.tcx().intern_chalk_environment_clause_list(&v) + } + + fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } +} +/// We have to elaborate the environment of a chalk goal *before* +/// canonicalization. This type wraps the predicate and the elaborated +/// environment. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)] +pub struct ChalkEnvironmentAndGoal<'tcx> { + pub environment: &'tcx ty::List<ChalkEnvironmentClause<'tcx>>, + pub goal: ty::Predicate<'tcx>, +} + +impl<'tcx> fmt::Display for ChalkEnvironmentAndGoal<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "environment: {:?}, goal: {}", self.environment, self.goal) + } +} |
