Skip to content

Commit 101b59c

Browse files
committed
TEMP COMMIT
1 parent af0d872 commit 101b59c

5 files changed

Lines changed: 89 additions & 34 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ strum = { version = "0.24.1", features = ["derive"], default-features = false }
2525

2626
[dependencies]
2727
quote = "1.0.23"
28-
syn = { version = "1.0.107", features = ["full", "extra-traits"] }
28+
syn = "1.0.107"
2929
proc-macro2 = "1.0.51"
3030
heck = "0.4.1"
3131

src/enum.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl Enum {
3737
.type_params()
3838
.map(|param| {
3939
(
40-
Param::Ident(param.ident.clone()),
40+
Param::Type(param.ident.clone()),
4141
param.bounds.iter().cloned().collect(),
4242
)
4343
})
@@ -64,9 +64,9 @@ impl Enum {
6464
// We need to treat this as a bound on both `T` and on `U`.
6565
let bounds: Vec<TypeParamBound> = ty.bounds.iter().cloned().collect();
6666
ty.bounded_ty
67-
.extract_idents()
67+
.extract_types()
6868
.into_iter()
69-
.map(move |ident| (Param::Ident(ident), bounds.clone()))
69+
.map(move |ident| (Param::Type(ident), bounds.clone()))
7070
.boxed()
7171
}
7272
syn::WherePredicate::Lifetime(lt) => [(

src/extractor.rs

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ use crate::{iter::BoxedIter, param::Param};
77

88
pub trait Extractor {
99
fn extract_lifetimes(&self) -> Vec<Lifetime>;
10-
fn extract_idents(&self) -> Vec<Ident>;
10+
fn extract_types(&self) -> Vec<Ident>;
11+
fn extract_consts(&self) -> Vec<Ident>;
1112
fn extract_params(&self) -> Box<dyn Iterator<Item = Param>> {
1213
self.extract_lifetimes()
1314
.into_iter()
1415
.map(Param::Lifetime)
15-
.chain(self.extract_idents().into_iter().map(Param::Ident))
16+
.chain(self.extract_types().into_iter().map(Param::Type))
17+
.chain(self.extract_consts().into_iter().map(Param::Const))
1618
.boxed()
1719
}
1820
}
@@ -63,11 +65,11 @@ impl Extractor for Type {
6365
}
6466
}
6567

66-
fn extract_idents(&self) -> Vec<Ident> {
68+
fn extract_types(&self) -> Vec<Ident> {
6769
match self {
68-
Type::Array(a) => a.elem.extract_idents(),
70+
Type::Array(a) => a.elem.extract_types(),
6971
Type::BareFn(_) => Vec::new(),
70-
Type::Group(g) => g.elem.extract_idents(),
72+
Type::Group(g) => g.elem.extract_types(),
7173
Type::ImplTrait(it) => it
7274
.bounds
7375
.iter()
@@ -80,18 +82,54 @@ impl Extractor for Type {
8082
Type::Infer(_) => Vec::new(),
8183
Type::Macro(_) => Vec::new(),
8284
Type::Never(_) => Vec::new(),
83-
Type::Paren(p) => p.elem.extract_idents(),
85+
Type::Paren(p) => p.elem.extract_types(),
8486
Type::Path(p) => p
8587
.path
8688
.get_ident()
8789
.map(ToOwned::to_owned)
8890
.into_iter()
8991
.collect(),
90-
Type::Ptr(p) => p.elem.extract_idents(),
91-
Type::Reference(r) => r.elem.extract_idents(),
92-
Type::Slice(s) => s.elem.extract_idents(),
92+
Type::Ptr(p) => p.elem.extract_types(),
93+
Type::Reference(r) => r.elem.extract_types(),
94+
Type::Slice(s) => s.elem.extract_types(),
9395
Type::TraitObject(_) => Vec::new(),
94-
Type::Tuple(t) => t.elems.iter().flat_map(Self::extract_idents).collect(),
96+
Type::Tuple(t) => t.elems.iter().flat_map(Self::extract_types).collect(),
97+
Type::Verbatim(_) => Vec::new(),
98+
#[allow(unknown_lints)]
99+
#[cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
100+
_ => Vec::new(),
101+
}
102+
}
103+
104+
fn extract_consts(&self) -> Vec<Ident> {
105+
match self {
106+
Type::Array(a) => a.elem.extract_types(),
107+
Type::BareFn(_) => Vec::new(),
108+
Type::Group(g) => g.elem.extract_types(),
109+
Type::ImplTrait(it) => it
110+
.bounds
111+
.iter()
112+
.cloned()
113+
.filter_map(|b| match b {
114+
TypeParamBound::Trait(t) => t.path.get_ident().map(ToOwned::to_owned),
115+
TypeParamBound::Lifetime(_) => None,
116+
})
117+
.collect(),
118+
Type::Infer(_) => Vec::new(),
119+
Type::Macro(_) => Vec::new(),
120+
Type::Never(_) => Vec::new(),
121+
Type::Paren(p) => p.elem.extract_types(),
122+
Type::Path(p) => p
123+
.path
124+
.get_ident()
125+
.map(ToOwned::to_owned)
126+
.into_iter()
127+
.collect(),
128+
Type::Ptr(p) => p.elem.extract_types(),
129+
Type::Reference(r) => r.elem.extract_types(),
130+
Type::Slice(s) => s.elem.extract_types(),
131+
Type::TraitObject(_) => Vec::new(),
132+
Type::Tuple(t) => t.elems.iter().flat_map(Self::extract_types).collect(),
95133
Type::Verbatim(_) => Vec::new(),
96134
#[allow(unknown_lints)]
97135
#[cfg_attr(test, deny(non_exhaustive_omitted_patterns))]

src/param.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,8 @@ use crate::extractor::Extractor;
1010
#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
1111
pub enum Param {
1212
Lifetime(Lifetime),
13-
Ident(Ident),
14-
}
15-
16-
impl From<Ident> for Param {
17-
fn from(value: Ident) -> Self {
18-
Param::Ident(value)
19-
}
20-
}
21-
22-
impl From<Lifetime> for Param {
23-
fn from(value: Lifetime) -> Self {
24-
Param::Lifetime(value)
25-
}
13+
Type(Ident),
14+
Const(Ident),
2615
}
2716

2817
impl Param {
@@ -34,7 +23,8 @@ impl Param {
3423
) -> (Option<&'b GenericParam>, Option<&'b WherePredicate>) {
3524
match self {
3625
Param::Lifetime(lt) => find_lt(lt, generics),
37-
Param::Ident(ty) => find_ident(ty, generics),
26+
Param::Type(ty) => find_ident(ty, generics),
27+
Param::Const(c) => find_const(c, generics),
3828
}
3929
}
4030

@@ -54,11 +44,11 @@ impl Param {
5444
.get_ident()
5545
.into_iter()
5646
.cloned()
57-
.flat_map(|ident| Param::from(ident).find_relevant(bound_map))
47+
.flat_map(|ident| Param::Type(ident).find_relevant(bound_map))
5848
.collect()
5949
}
6050
TypeParamBound::Lifetime(lifetime) => {
61-
Param::from(lifetime.clone()).find_relevant(bound_map)
51+
Param::Lifetime(lifetime.clone()).find_relevant(bound_map)
6252
}
6353
})
6454
.chain([self.clone()])
@@ -67,6 +57,7 @@ impl Param {
6757
}
6858
}
6959
}
60+
7061
fn find_lt<'a>(
7162
lt: &Lifetime,
7263
generics: &'a Generics,
@@ -104,11 +95,23 @@ fn find_ident<'a>(
10495
.find(|pred| match pred {
10596
WherePredicate::Type(pred_ty) => pred_ty
10697
.bounded_ty
107-
.extract_idents()
98+
.extract_types()
10899
.iter()
109100
.any(|id| id == ident),
110101
_ => false,
111102
});
112103

113104
(generic_param, predicate)
114105
}
106+
107+
fn find_const<'a>(
108+
con: &Ident,
109+
generics: &'a Generics,
110+
) -> (Option<&'a GenericParam>, Option<&'a WherePredicate>) {
111+
let generic_param = generics.params.iter().find(|p| match p {
112+
GenericParam::Const(const_param) => &const_param.ident == con,
113+
_ => false,
114+
});
115+
116+
(generic_param, None)
117+
}

tests/it.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use subenum::subenum;
22

3+
// Test tuple variants, struct variants, and repeated types.
34
#[subenum(Bar)]
45
#[derive(Clone, Debug, PartialEq, Eq)]
56
enum Foo {
@@ -14,6 +15,7 @@ enum Foo {
1415
},
1516
}
1617

18+
// Test lifetimes, generics, as well as unused lifetimes/generics.
1719
#[subenum(Both, Str, Tee, Neither)]
1820
#[derive(Clone, Debug)]
1921
enum Pippy<'a, T> {
@@ -31,6 +33,7 @@ enum Pippy<'a, T> {
3133
F { a: u32 },
3234
}
3335

36+
// Test where clause
3437
#[subenum(Flip, Flop)]
3538
#[derive(Clone, Debug, PartialEq, Eq)]
3639
enum Flippy<T, U>
@@ -43,6 +46,7 @@ where
4346
B(U),
4447
}
4548

49+
// Test conversion.
4650
#[subenum(Floop)]
4751
#[derive(Clone, Debug, PartialEq)]
4852
enum Snoo<T> {
@@ -65,10 +69,20 @@ enum Boo<'a> {
6569
A(&'a str),
6670
}
6771

72+
// Test lifetime relationships.
73+
#[subenum(Dop, Mop)]
74+
enum Dip<'a: 'b, 'b, 'c, T, U> {
75+
#[subenum(Dop, Mop)]
76+
A(&'a T),
77+
#[subenum(Dop)]
78+
B(&'b [&'c [U; 7]]),
79+
}
80+
81+
// Test generic consts.
6882
#[subenum(Phew)]
69-
enum Whew<'a: 'b, 'b, 'c, T, U> {
83+
enum Whew<const N: usize> {
7084
#[subenum(Phew)]
71-
A(&'a T),
85+
A,
7286
#[subenum(Phew)]
73-
B(&'b [&'c [U; 7]]),
87+
B([u8; N]),
7488
}

0 commit comments

Comments
 (0)