From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/traits/chalk.rs | 403 ++++++++++++++++++++++++++++++ 1 file changed, 403 insertions(+) create mode 100644 compiler/rustc_middle/src/traits/chalk.rs (limited to 'compiler/rustc_middle/src/traits/chalk.rs') diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs new file mode 100644 index 000000000..6d4af8bea --- /dev/null +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -0,0 +1,403 @@ +//! 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::ty::{self, AdtDef, TyCtxt}; + +use rustc_hir::def_id::DefId; +use rustc_target::spec::abi::Abi; + +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(&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 { + 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>; + type InternedLifetime = Box>; + type InternedConst = Box>; + type InternedConcreteConst = ty::ValTree<'tcx>; + type InternedGenericArg = Box>; + type InternedGoal = Box>; + type InternedGoals = Vec>; + type InternedSubstitution = Vec>; + type InternedProgramClause = Box>; + type InternedProgramClauses = Vec>; + type InternedQuantifiedWhereClauses = Vec>; + type InternedVariableKinds = Vec>; + type InternedCanonicalVarKinds = Vec>; + type InternedVariances = Vec; + type InternedConstraints = Vec>>; + type DefId = DefId; + type InternedAdtId = AdtDef<'tcx>; + type Identifier = (); + type FnAbi = Abi; + + fn debug_program_clause_implication( + pci: &chalk_ir::ProgramClauseImplication, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + let mut write = || { + write!(fmt, "{:?}", pci.consequence)?; + + let conditions = pci.conditions.interned(); + let constraints = pci.constraints.interned(); + + let conds = conditions.len(); + let consts = constraints.len(); + if conds == 0 && consts == 0 { + return Ok(()); + } + + write!(fmt, " :- ")?; + + if conds != 0 { + for cond in &conditions[..conds - 1] { + write!(fmt, "{:?}, ", cond)?; + } + write!(fmt, "{:?}", conditions[conds - 1])?; + } + + if conds != 0 && consts != 0 { + write!(fmt, " ; ")?; + } + + if consts != 0 { + for constraint in &constraints[..consts - 1] { + write!(fmt, "{:?}, ", constraint)?; + } + write!(fmt, "{:?}", constraints[consts - 1])?; + } + + Ok(()) + }; + Some(write()) + } + + fn debug_substitution( + substitution: &chalk_ir::Substitution, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + Some(write!(fmt, "{:?}", substitution.interned())) + } + + fn debug_separator_trait_ref( + separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Self>, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + 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, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + Some(write!(fmt, "{:?}", clauses.interned())) + } + + fn debug_ty(ty: &chalk_ir::Ty, fmt: &mut fmt::Formatter<'_>) -> Option { + match &ty.interned().kind { + chalk_ir::TyKind::Ref(chalk_ir::Mutability::Not, lifetime, ty) => { + Some(write!(fmt, "(&{:?} {:?})", lifetime, ty)) + } + chalk_ir::TyKind::Ref(chalk_ir::Mutability::Mut, lifetime, ty) => { + Some(write!(fmt, "(&{:?} mut {:?})", lifetime, ty)) + } + chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)), + chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)), + chalk_ir::TyKind::Tuple(len, substs) => Some((|| { + write!(fmt, "(")?; + for (idx, substitution) in substs.interned().iter().enumerate() { + if idx == *len && *len != 1 { + // Don't add a trailing comma if the tuple has more than one element + write!(fmt, "{:?}", substitution)?; + } else { + write!(fmt, "{:?},", substitution)?; + } + } + write!(fmt, ")") + })()), + _ => None, + } + } + + fn debug_alias( + alias_ty: &chalk_ir::AliasTy, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + 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, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + Some(write!( + fmt, + "projection: {:?} {:?}", + projection_ty.associated_ty_id, projection_ty.substitution, + )) + } + + fn debug_opaque_ty( + opaque_ty: &chalk_ir::OpaqueTy, + fmt: &mut fmt::Formatter<'_>, + ) -> Option { + Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id)) + } + + fn intern_ty(self, ty: chalk_ir::TyKind) -> Self::InternedType { + let flags = ty.compute_flags(self); + Box::new(chalk_ir::TyData { kind: ty, flags: flags }) + } + + fn ty_data<'a>(self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData { + ty + } + + fn intern_lifetime(self, lifetime: chalk_ir::LifetimeData) -> Self::InternedLifetime { + Box::new(lifetime) + } + + fn lifetime_data<'a>( + self, + lifetime: &'a Self::InternedLifetime, + ) -> &'a chalk_ir::LifetimeData { + &lifetime + } + + fn intern_const(self, constant: chalk_ir::ConstData) -> Self::InternedConst { + Box::new(constant) + } + + fn const_data<'a>(self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData { + &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::InternedGenericArg { + Box::new(data) + } + + fn generic_arg_data<'a>( + self, + data: &'a Self::InternedGenericArg, + ) -> &'a chalk_ir::GenericArgData { + &data + } + + fn intern_goal(self, goal: chalk_ir::GoalData) -> Self::InternedGoal { + Box::new(goal) + } + + fn goal_data<'a>(self, goal: &'a Self::InternedGoal) -> &'a chalk_ir::GoalData { + &goal + } + + fn intern_goals( + self, + data: impl IntoIterator, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn goals_data<'a>(self, goals: &'a Self::InternedGoals) -> &'a [chalk_ir::Goal] { + goals + } + + fn intern_substitution( + self, + data: impl IntoIterator, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn substitution_data<'a>( + self, + substitution: &'a Self::InternedSubstitution, + ) -> &'a [chalk_ir::GenericArg] { + substitution + } + + fn intern_program_clause( + self, + data: chalk_ir::ProgramClauseData, + ) -> Self::InternedProgramClause { + Box::new(data) + } + + fn program_clause_data<'a>( + self, + clause: &'a Self::InternedProgramClause, + ) -> &'a chalk_ir::ProgramClauseData { + &clause + } + + fn intern_program_clauses( + self, + data: impl IntoIterator, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn program_clauses_data<'a>( + self, + clauses: &'a Self::InternedProgramClauses, + ) -> &'a [chalk_ir::ProgramClause] { + clauses + } + + fn intern_quantified_where_clauses( + self, + data: impl IntoIterator, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn quantified_where_clauses_data<'a>( + self, + clauses: &'a Self::InternedQuantifiedWhereClauses, + ) -> &'a [chalk_ir::QuantifiedWhereClause] { + clauses + } + + fn intern_generic_arg_kinds( + self, + data: impl IntoIterator, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn variable_kinds_data<'a>( + self, + parameter_kinds: &'a Self::InternedVariableKinds, + ) -> &'a [chalk_ir::VariableKind] { + parameter_kinds + } + + fn intern_canonical_var_kinds( + self, + data: impl IntoIterator, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn canonical_var_kinds_data<'a>( + self, + canonical_var_kinds: &'a Self::InternedCanonicalVarKinds, + ) -> &'a [chalk_ir::CanonicalVarKind] { + canonical_var_kinds + } + + fn intern_constraints( + self, + data: impl IntoIterator>, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn constraints_data<'a>( + self, + constraints: &'a Self::InternedConstraints, + ) -> &'a [chalk_ir::InEnvironment>] { + constraints + } + + fn intern_variances( + self, + data: impl IntoIterator>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn variances_data<'a>( + self, + variances: &'a Self::InternedVariances, + ) -> &'a [chalk_ir::Variance] { + variances + } +} + +impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> { + type Interner = Self; +} + +/// A chalk environment and goal. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, TypeVisitable)] +pub struct ChalkEnvironmentAndGoal<'tcx> { + pub environment: &'tcx ty::List>, + 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) + } +} -- cgit v1.2.3