Skip to content

Commit 6d671d2

Browse files
committed
regularize up/down cast
1 parent 63e792b commit 6d671d2

File tree

2 files changed

+46
-54
lines changed

2 files changed

+46
-54
lines changed

crates/formality-core/src/cast.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -271,34 +271,6 @@ where
271271
}
272272
}
273273

274-
impl<A, As, B, Bs, Z> UpcastFrom<(A, B)> for Vec<Z>
275-
where
276-
A: IntoIterator<Item = As> + Clone,
277-
As: Upcast<Z>,
278-
B: IntoIterator<Item = Bs> + Clone,
279-
Bs: Upcast<Z>,
280-
{
281-
fn upcast_from(term: (A, B)) -> Self {
282-
let (a, b) = term;
283-
let mut v: Self = vec![];
284-
v.extend(a.into_iter().map(|a| a.upcast()));
285-
v.extend(b.into_iter().map(|b| b.upcast()));
286-
v
287-
}
288-
}
289-
290-
impl<A, B, C, Z> UpcastFrom<(A, B, C)> for Vec<Z>
291-
where
292-
A: Upcast<Z>,
293-
B: Upcast<Z>,
294-
C: Upcast<Z>,
295-
{
296-
fn upcast_from(term: (A, B, C)) -> Self {
297-
let (a, b, c) = term;
298-
vec![a.upcast(), b.upcast(), c.upcast()]
299-
}
300-
}
301-
302274
#[macro_export]
303275
macro_rules! cast_impl {
304276
($e:ident :: $v:ident ($u:ty)) => {

crates/formality-core/src/collections.rs

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use std::collections::{BTreeMap, BTreeSet};
55

6-
use crate::cast::{Downcast, DowncastFrom, DowncastTo, Upcast, UpcastFrom};
6+
use crate::cast::{DowncastTo, Upcast, UpcastFrom, Upcasted};
77

88
pub type Map<K, V> = BTreeMap<K, V>;
99
pub type Set<E> = BTreeSet<E>;
@@ -58,6 +58,17 @@ macro_rules! seq {
5858

5959
}
6060

61+
pub trait VecExt<T>: Sized {
62+
fn with_pushed(self, other: T) -> Self;
63+
}
64+
65+
impl<T: Ord + Clone> VecExt<T> for Vec<T> {
66+
fn with_pushed(mut self, other: T) -> Self {
67+
self.push(other);
68+
self
69+
}
70+
}
71+
6172
pub trait SetExt<T>: Sized {
6273
fn split_first(self) -> Option<(T, Self)>;
6374

@@ -69,7 +80,9 @@ pub trait SetExt<T>: Sized {
6980
impl<T: Ord + Clone> SetExt<T> for Set<T> {
7081
fn split_first(self) -> Option<(T, Set<T>)> {
7182
let mut iter = self.into_iter();
72-
iter.next().map(|e| (e, iter.collect()))
83+
let e = iter.next()?;
84+
let c = iter.collect();
85+
Some((e, c))
7386
}
7487

7588
fn union_with(mut self, other: Self) -> Self {
@@ -106,60 +119,67 @@ impl<T> DowncastTo<()> for Vec<T> {
106119
}
107120

108121
macro_rules! tuple_upcast {
109-
($($name:ident),*) => {
122+
($coll:ident : $($name:ident),*) => {
123+
/// Upcast from a tuple of iterable things into a collection.
124+
/// Downcasting doesn't work, because how would we know how many
125+
/// things to put in each collection? But see `Cons` below.
110126
#[allow(non_snake_case)]
111-
impl<$($name,)* T> UpcastFrom<($($name,)*)> for Set<T>
127+
impl<$($name,)* T> UpcastFrom<($($name,)*)> for $coll<T>
112128
where
113-
$($name: Upcast<Set<T>>,)*
129+
$($name: IntoIterator + Clone,)*
130+
$(<$name as IntoIterator>::Item: Upcast<T>,)*
114131
T: Ord + Clone,
115132
{
116133
fn upcast_from(($($name,)*): ($($name,)*)) -> Self {
117134
let c = None.into_iter();
118135
$(
119-
let $name: Set<T> = $name.upcast();
120-
let c = c.chain($name);
136+
let c = c.chain($name.into_iter().upcasted());
121137
)*
122138
c.collect()
123139
}
124140
}
125141
}
126142
}
127143

128-
tuple_upcast!(A, B);
129-
tuple_upcast!(A, B, C);
130-
tuple_upcast!(A, B, C, D);
144+
tuple_upcast!(Set: );
145+
tuple_upcast!(Set: A, B);
146+
tuple_upcast!(Set: A, B, C);
147+
tuple_upcast!(Set: A, B, C, D);
148+
149+
tuple_upcast!(Vec: );
150+
tuple_upcast!(Vec: A, B);
151+
tuple_upcast!(Vec: A, B, C);
152+
tuple_upcast!(Vec: A, B, C, D);
131153

132-
impl<A, T> DowncastTo<(A, Set<T>)> for Set<T>
154+
/// This type exists to be used in judgment functions.
155+
/// You can downcast a `Vec` or `Set` to `Cons(head, tail)`
156+
/// where `head` will be the first item in the collection
157+
/// and tail will be a collection with the remaining items.
158+
/// Both can also be downcast to `()` which matches an empty collection.
159+
pub struct Cons<T, C>(pub T, pub C);
160+
161+
impl<T> DowncastTo<Cons<T, Set<T>>> for Set<T>
133162
where
134-
A: DowncastFrom<T>,
135163
T: Ord + Clone,
136164
{
137-
fn downcast_to(&self) -> Option<(A, Set<T>)> {
165+
fn downcast_to(&self) -> Option<Cons<T, Set<T>>> {
138166
if self.is_empty() {
139167
None
140168
} else {
141169
let r = self.clone();
142170
let (a, bs) = r.split_first().unwrap();
143-
let a: A = a.downcast()?;
144-
Some((a, bs))
171+
Some(Cons(a, bs))
145172
}
146173
}
147174
}
148175

149-
impl<A, T> DowncastTo<(A, Vec<T>)> for Vec<T>
176+
impl<T> DowncastTo<Cons<T, Vec<T>>> for Vec<T>
150177
where
151-
A: DowncastFrom<T>,
152178
T: Ord + Clone,
153179
{
154-
fn downcast_to(&self) -> Option<(A, Vec<T>)> {
155-
if self.is_empty() {
156-
None
157-
} else {
158-
let r = self.clone();
159-
let (a, bs) = r.split_first().unwrap();
160-
let a: A = a.downcast()?;
161-
Some((a, bs.to_vec()))
162-
}
180+
fn downcast_to(&self) -> Option<Cons<T, Vec<T>>> {
181+
let (a, bs) = self.split_first()?;
182+
Some(Cons(a.clone(), bs.to_vec()))
163183
}
164184
}
165185

0 commit comments

Comments
 (0)