1 //! Upcasts, to avoid writing out wrapper types. 2 3 use crate::*; 4 use std::marker::PhantomData; 5 6 /// The `Cast` trait is used to make annoying upcasts between 7 /// logically equivalent types that imply wrappers. For example, one 8 /// could convert a `DomainGoal` into a `Goal` by doing: 9 /// 10 /// ```ignore 11 /// let goal: Goal = domain_goal.cast(); 12 /// ``` 13 /// 14 /// This is equivalent to the more explicit: 15 /// 16 /// ```ignore 17 /// let goal: Goal = Goal::DomainGoal(domain_goal) 18 /// ``` 19 /// 20 /// Another useful trick is the `casted()` iterator adapter, which 21 /// casts each element in the iterator as it is produced (you must 22 /// have the `Caster` trait in scope for that). 23 /// 24 /// # Invariant 25 /// 26 /// `Cast` imposes a key invariant. You can only implement `T: 27 /// Cast<U>` if both `T` and `U` have the same semantic meaning. Also, 28 /// as part of this, they should always use the same set of free 29 /// variables (the `Canonical` implementation, for example, relies on 30 /// that). 31 /// 32 /// # Iterators 33 /// 34 /// If you import the `Caster` trait, you can also write `.casted()` on an 35 /// iterator chain to cast every instance within. 36 /// 37 /// # Implementing Cast 38 /// 39 /// Do not implement `Cast` directly. Instead, implement `CastTo`. 40 /// This split setup allows us to write `foo.cast::<T>()` to mean 41 /// "cast to T". 42 pub trait Cast: Sized { 43 /// Cast a value to type `U` using `CastTo`. cast<U>(self, interner: &U::Interner) -> U where Self: CastTo<U>, U: HasInterner,44 fn cast<U>(self, interner: &U::Interner) -> U 45 where 46 Self: CastTo<U>, 47 U: HasInterner, 48 { 49 self.cast_to(interner) 50 } 51 } 52 53 impl<T> Cast for T {} 54 55 /// The "helper" trait for `cast` that actually implements the 56 /// transformations. You can also use this if you want to have 57 /// functions that take (e.g.) an `impl CastTo<Goal<_>>` or something 58 /// like that. 59 pub trait CastTo<T: HasInterner>: Sized { 60 /// Cast a value to type `T`. cast_to(self, interner: &T::Interner) -> T61 fn cast_to(self, interner: &T::Interner) -> T; 62 } 63 64 macro_rules! reflexive_impl { 65 (for($($t:tt)*) $u:ty) => { 66 impl<$($t)*> CastTo<$u> for $u { 67 fn cast_to(self, _interner: &<$u as HasInterner>::Interner) -> $u { 68 self 69 } 70 } 71 }; 72 ($u:ty) => { 73 impl CastTo<$u> for $u { 74 fn cast_to(self, interner: &<$u as HasInterner>::Interner) -> $u { 75 self 76 } 77 } 78 }; 79 } 80 81 reflexive_impl!(for(I: Interner) TyKind<I>); 82 reflexive_impl!(for(I: Interner) LifetimeData<I>); 83 reflexive_impl!(for(I: Interner) ConstData<I>); 84 reflexive_impl!(for(I: Interner) TraitRef<I>); 85 reflexive_impl!(for(I: Interner) DomainGoal<I>); 86 reflexive_impl!(for(I: Interner) Goal<I>); 87 reflexive_impl!(for(I: Interner) WhereClause<I>); 88 reflexive_impl!(for(I: Interner) ProgramClause<I>); 89 reflexive_impl!(for(I: Interner) QuantifiedWhereClause<I>); 90 reflexive_impl!(for(I: Interner) VariableKind<I>); 91 reflexive_impl!(for(I: Interner) VariableKinds<I>); 92 reflexive_impl!(for(I: Interner) CanonicalVarKind<I>); 93 reflexive_impl!(for(I: Interner) CanonicalVarKinds<I>); 94 reflexive_impl!(for(I: Interner) Constraint<I>); 95 96 impl<I: Interner> CastTo<WhereClause<I>> for TraitRef<I> { cast_to(self, _interner: &I) -> WhereClause<I>97 fn cast_to(self, _interner: &I) -> WhereClause<I> { 98 WhereClause::Implemented(self) 99 } 100 } 101 102 impl<I: Interner> CastTo<WhereClause<I>> for AliasEq<I> { cast_to(self, _interner: &I) -> WhereClause<I>103 fn cast_to(self, _interner: &I) -> WhereClause<I> { 104 WhereClause::AliasEq(self) 105 } 106 } 107 108 impl<I: Interner> CastTo<WhereClause<I>> for LifetimeOutlives<I> { cast_to(self, _interner: &I) -> WhereClause<I>109 fn cast_to(self, _interner: &I) -> WhereClause<I> { 110 WhereClause::LifetimeOutlives(self) 111 } 112 } 113 114 impl<I: Interner> CastTo<WhereClause<I>> for TypeOutlives<I> { cast_to(self, _interner: &I) -> WhereClause<I>115 fn cast_to(self, _interner: &I) -> WhereClause<I> { 116 WhereClause::TypeOutlives(self) 117 } 118 } 119 120 impl<T, I> CastTo<DomainGoal<I>> for T 121 where 122 T: CastTo<WhereClause<I>>, 123 I: Interner, 124 { cast_to(self, interner: &I) -> DomainGoal<I>125 fn cast_to(self, interner: &I) -> DomainGoal<I> { 126 DomainGoal::Holds(self.cast(interner)) 127 } 128 } 129 130 impl<T, I: Interner> CastTo<Goal<I>> for T 131 where 132 T: CastTo<DomainGoal<I>>, 133 { cast_to(self, interner: &I) -> Goal<I>134 fn cast_to(self, interner: &I) -> Goal<I> { 135 GoalData::DomainGoal(self.cast(interner)).intern(interner) 136 } 137 } 138 139 impl<I: Interner> CastTo<DomainGoal<I>> for Normalize<I> { cast_to(self, _interner: &I) -> DomainGoal<I>140 fn cast_to(self, _interner: &I) -> DomainGoal<I> { 141 DomainGoal::Normalize(self) 142 } 143 } 144 145 impl<I: Interner> CastTo<DomainGoal<I>> for WellFormed<I> { cast_to(self, _interner: &I) -> DomainGoal<I>146 fn cast_to(self, _interner: &I) -> DomainGoal<I> { 147 DomainGoal::WellFormed(self) 148 } 149 } 150 151 impl<I: Interner> CastTo<DomainGoal<I>> for FromEnv<I> { cast_to(self, _interner: &I) -> DomainGoal<I>152 fn cast_to(self, _interner: &I) -> DomainGoal<I> { 153 DomainGoal::FromEnv(self) 154 } 155 } 156 157 impl<I: Interner> CastTo<Goal<I>> for EqGoal<I> { cast_to(self, interner: &I) -> Goal<I>158 fn cast_to(self, interner: &I) -> Goal<I> { 159 GoalData::EqGoal(self).intern(interner) 160 } 161 } 162 163 impl<I: Interner> CastTo<Goal<I>> for SubtypeGoal<I> { cast_to(self, interner: &I) -> Goal<I>164 fn cast_to(self, interner: &I) -> Goal<I> { 165 GoalData::SubtypeGoal(self).intern(interner) 166 } 167 } 168 169 impl<I: Interner, T: HasInterner<Interner = I> + CastTo<Goal<I>>> CastTo<Goal<I>> for Binders<T> { cast_to(self, interner: &I) -> Goal<I>170 fn cast_to(self, interner: &I) -> Goal<I> { 171 GoalData::Quantified( 172 QuantifierKind::ForAll, 173 self.map(|bound| bound.cast(interner)), 174 ) 175 .intern(interner) 176 } 177 } 178 179 impl<I: Interner> CastTo<TyKind<I>> for AliasTy<I> { cast_to(self, _interner: &I) -> TyKind<I>180 fn cast_to(self, _interner: &I) -> TyKind<I> { 181 TyKind::Alias(self) 182 } 183 } 184 185 impl<I: Interner> CastTo<GenericArg<I>> for Ty<I> { cast_to(self, interner: &I) -> GenericArg<I>186 fn cast_to(self, interner: &I) -> GenericArg<I> { 187 GenericArg::new(interner, GenericArgData::Ty(self)) 188 } 189 } 190 191 impl<I: Interner> CastTo<GenericArg<I>> for Lifetime<I> { cast_to(self, interner: &I) -> GenericArg<I>192 fn cast_to(self, interner: &I) -> GenericArg<I> { 193 GenericArg::new(interner, GenericArgData::Lifetime(self)) 194 } 195 } 196 197 impl<I: Interner> CastTo<GenericArg<I>> for Const<I> { cast_to(self, interner: &I) -> GenericArg<I>198 fn cast_to(self, interner: &I) -> GenericArg<I> { 199 GenericArg::new(interner, GenericArgData::Const(self)) 200 } 201 } 202 203 impl<I: Interner> CastTo<GenericArg<I>> for GenericArg<I> { cast_to(self, _interner: &I) -> GenericArg<I>204 fn cast_to(self, _interner: &I) -> GenericArg<I> { 205 self 206 } 207 } 208 209 impl<T, I> CastTo<ProgramClause<I>> for T 210 where 211 T: CastTo<DomainGoal<I>>, 212 I: Interner, 213 { cast_to(self, interner: &I) -> ProgramClause<I>214 fn cast_to(self, interner: &I) -> ProgramClause<I> { 215 let implication = ProgramClauseImplication { 216 consequence: self.cast(interner), 217 conditions: Goals::empty(interner), 218 constraints: Constraints::empty(interner), 219 priority: ClausePriority::High, 220 }; 221 222 ProgramClauseData(Binders::empty(interner, implication.shifted_in(interner))) 223 .intern(interner) 224 } 225 } 226 227 impl<I, T> CastTo<ProgramClause<I>> for Binders<T> 228 where 229 I: Interner, 230 T: HasInterner<Interner = I> + CastTo<DomainGoal<I>>, 231 { cast_to(self, interner: &I) -> ProgramClause<I>232 fn cast_to(self, interner: &I) -> ProgramClause<I> { 233 ProgramClauseData(self.map(|bound| ProgramClauseImplication { 234 consequence: bound.cast(interner), 235 conditions: Goals::empty(interner), 236 constraints: Constraints::empty(interner), 237 priority: ClausePriority::High, 238 })) 239 .intern(interner) 240 } 241 } 242 243 impl<T, U> CastTo<Option<U>> for Option<T> 244 where 245 T: CastTo<U>, 246 U: HasInterner, 247 { cast_to(self, interner: &U::Interner) -> Option<U>248 fn cast_to(self, interner: &U::Interner) -> Option<U> { 249 self.map(|v| v.cast(interner)) 250 } 251 } 252 253 impl<T, U, I> CastTo<InEnvironment<U>> for InEnvironment<T> 254 where 255 T: HasInterner<Interner = I> + CastTo<U>, 256 U: HasInterner<Interner = I>, 257 I: Interner, 258 { cast_to(self, interner: &U::Interner) -> InEnvironment<U>259 fn cast_to(self, interner: &U::Interner) -> InEnvironment<U> { 260 self.map(|v| v.cast(interner)) 261 } 262 } 263 264 impl<T, U, E> CastTo<Result<U, E>> for Result<T, E> 265 where 266 T: CastTo<U>, 267 U: HasInterner, 268 { cast_to(self, interner: &U::Interner) -> Result<U, E>269 fn cast_to(self, interner: &U::Interner) -> Result<U, E> { 270 self.map(|v| v.cast(interner)) 271 } 272 } 273 274 impl<T> HasInterner for Option<T> 275 where 276 T: HasInterner, 277 { 278 type Interner = T::Interner; 279 } 280 281 impl<T, E> HasInterner for Result<T, E> 282 where 283 T: HasInterner, 284 { 285 type Interner = T::Interner; 286 } 287 288 impl<T, U> CastTo<Canonical<U>> for Canonical<T> 289 where 290 T: CastTo<U> + HasInterner, 291 U: HasInterner<Interner = T::Interner>, 292 { cast_to(self, interner: &T::Interner) -> Canonical<U>293 fn cast_to(self, interner: &T::Interner) -> Canonical<U> { 294 // Subtle point: It should be ok to re-use the binders here, 295 // because `cast()` never introduces new inference variables, 296 // nor changes the "substance" of the type we are working 297 // with. It just introduces new wrapper types. 298 Canonical { 299 value: self.value.cast(interner), 300 binders: self.binders.cast(interner), 301 } 302 } 303 } 304 305 impl<T, U> CastTo<Vec<U>> for Vec<T> 306 where 307 T: CastTo<U> + HasInterner, 308 U: HasInterner, 309 { cast_to(self, interner: &U::Interner) -> Vec<U>310 fn cast_to(self, interner: &U::Interner) -> Vec<U> { 311 self.into_iter().casted(interner).collect() 312 } 313 } 314 315 impl<T> CastTo<T> for &T 316 where 317 T: Clone + HasInterner, 318 { cast_to(self, _interner: &T::Interner) -> T319 fn cast_to(self, _interner: &T::Interner) -> T { 320 self.clone() 321 } 322 } 323 324 /// An iterator that casts each element to some other type. 325 pub struct Casted<'i, IT, U: HasInterner> { 326 interner: &'i U::Interner, 327 iterator: IT, 328 _cast: PhantomData<U>, 329 } 330 331 impl<IT: Iterator, U> Iterator for Casted<'_, IT, U> 332 where 333 IT::Item: CastTo<U>, 334 U: HasInterner, 335 { 336 type Item = U; 337 next(&mut self) -> Option<Self::Item>338 fn next(&mut self) -> Option<Self::Item> { 339 self.iterator.next().map(|item| item.cast_to(self.interner)) 340 } 341 size_hint(&self) -> (usize, Option<usize>)342 fn size_hint(&self) -> (usize, Option<usize>) { 343 self.iterator.size_hint() 344 } 345 } 346 347 /// An iterator adapter that casts each element we are iterating over 348 /// to some other type. 349 pub trait Caster: Iterator + Sized { 350 /// Cast each element in this iterator. casted<U>(self, interner: &U::Interner) -> Casted<'_, Self, U> where Self::Item: CastTo<U>, U: HasInterner,351 fn casted<U>(self, interner: &U::Interner) -> Casted<'_, Self, U> 352 where 353 Self::Item: CastTo<U>, 354 U: HasInterner, 355 { 356 Casted { 357 interner, 358 iterator: self, 359 _cast: PhantomData, 360 } 361 } 362 } 363 364 impl<I> Caster for I where I: Iterator {} 365