//! Implementations of the Chalk `Cast` trait for our types. use chalk_ir::{ cast::{Cast, CastTo}, interner::HasInterner, }; use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause}; macro_rules! has_interner { ($t:ty) => { impl HasInterner for $t { type Interner = crate::Interner; } }; } has_interner!(WhereClause); has_interner!(DomainGoal); impl CastTo for TraitRef { fn cast_to(self, _interner: &Interner) -> WhereClause { WhereClause::Implemented(self) } } impl CastTo for AliasEq { fn cast_to(self, _interner: &Interner) -> WhereClause { WhereClause::AliasEq(self) } } impl CastTo for WhereClause { fn cast_to(self, _interner: &Interner) -> DomainGoal { DomainGoal::Holds(self) } } macro_rules! transitive_impl { ($a:ty, $b:ty, $c:ty) => { impl CastTo<$c> for $a { fn cast_to(self, interner: &Interner) -> $c { self.cast::<$b>(interner).cast(interner) } } }; } // In Chalk, these can be done as blanket impls, but that doesn't work here // because of coherence transitive_impl!(TraitRef, WhereClause, DomainGoal); transitive_impl!(AliasEq, WhereClause, DomainGoal);