From 7ec3b66f7a3ac0a33cf435bc3596fdac542fc52a Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 20 Mar 2021 11:23:59 +0100 Subject: Turn Obligation into something similar to chalk_ir::DomainGoal This includes starting to make use of Chalk's `Cast` trait. --- crates/hir_ty/src/chalk_cast.rs | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 crates/hir_ty/src/chalk_cast.rs (limited to 'crates/hir_ty/src/chalk_cast.rs') diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs new file mode 100644 index 000000000..bf884ae15 --- /dev/null +++ b/crates/hir_ty/src/chalk_cast.rs @@ -0,0 +1,53 @@ +//! 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); -- cgit v1.2.3