Skip to content

Commit 2160a48

Browse files
committed
Add snapshot tests for generic enums
1 parent da974a8 commit 2160a48

File tree

15 files changed

+1349
-0
lines changed

15 files changed

+1349
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
use enumcapsulate::AsVariant;
2+
trait HasAssoc {
3+
type Assoc: Sized;
4+
}
5+
pub struct VariantA;
6+
#[automatically_derived]
7+
impl ::core::clone::Clone for VariantA {
8+
#[inline]
9+
fn clone(&self) -> VariantA {
10+
VariantA
11+
}
12+
}
13+
pub struct VariantB;
14+
#[automatically_derived]
15+
impl ::core::clone::Clone for VariantB {
16+
#[inline]
17+
fn clone(&self) -> VariantB {
18+
VariantB
19+
}
20+
}
21+
pub struct VariantC<'l>(&'l ());
22+
#[automatically_derived]
23+
impl<'l> ::core::clone::Clone for VariantC<'l> {
24+
#[inline]
25+
fn clone(&self) -> VariantC<'l> {
26+
VariantC(::core::clone::Clone::clone(&self.0))
27+
}
28+
}
29+
pub struct VariantD<const N: usize>([(); N]);
30+
#[automatically_derived]
31+
impl<const N: usize> ::core::clone::Clone for VariantD<N> {
32+
#[inline]
33+
fn clone(&self) -> VariantD<N> {
34+
VariantD(::core::clone::Clone::clone(&self.0))
35+
}
36+
}
37+
pub struct VariantE<T>(T);
38+
#[automatically_derived]
39+
impl<T: ::core::clone::Clone> ::core::clone::Clone for VariantE<T> {
40+
#[inline]
41+
fn clone(&self) -> VariantE<T> {
42+
VariantE(::core::clone::Clone::clone(&self.0))
43+
}
44+
}
45+
pub struct VariantF<'l, const N: usize, T>(&'l [T; N]);
46+
#[automatically_derived]
47+
impl<'l, const N: usize, T: ::core::clone::Clone> ::core::clone::Clone
48+
for VariantF<'l, N, T> {
49+
#[inline]
50+
fn clone(&self) -> VariantF<'l, N, T> {
51+
VariantF(::core::clone::Clone::clone(&self.0))
52+
}
53+
}
54+
pub struct VariantT;
55+
#[automatically_derived]
56+
impl ::core::clone::Clone for VariantT {
57+
#[inline]
58+
fn clone(&self) -> VariantT {
59+
VariantT
60+
}
61+
}
62+
impl HasAssoc for VariantT {
63+
type Assoc = ();
64+
}
65+
pub struct VariantU;
66+
#[automatically_derived]
67+
impl ::core::clone::Clone for VariantU {
68+
#[inline]
69+
fn clone(&self) -> VariantU {
70+
VariantU
71+
}
72+
}
73+
trait HasT {
74+
type T: Sized;
75+
}
76+
impl HasT for VariantU {
77+
type T = ();
78+
}
79+
pub enum Enum<'l, const N: usize, T>
80+
where
81+
T: HasAssoc,
82+
{
83+
Unit,
84+
OwnedSpecificType(VariantA),
85+
BorrowedSpecificType(&'l VariantB),
86+
OwnedWithGenericLifetime(VariantC<'l>),
87+
OwnedGenericTypeWithConstParam(VariantD<N>),
88+
OwnedGenericTypeWithTypeParam(VariantE<T>),
89+
OwnedGenericTypeWithMixedParams(VariantF<'l, N, T>),
90+
OwnedGenericParam(T),
91+
BorrowedGenericParam(&'l T),
92+
OwnedAssocTypeOfGenericParam(T::Assoc),
93+
OwnedAssocTypeOfGenericParamBehindCast(<T as HasAssoc>::Assoc),
94+
OwnedAssocTypeOfSpecificTypeBehindCast(<VariantU as HasT>::T),
95+
}
96+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariant<VariantA> for Enum<'l, N, T>
97+
where
98+
T: HasAssoc,
99+
VariantA: Clone,
100+
{
101+
fn as_variant(&self) -> Option<VariantA> {
102+
match self {
103+
Enum::OwnedSpecificType(inner, ..) => Some(inner.clone()),
104+
_ => None,
105+
}
106+
}
107+
}
108+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariant<&'l VariantB> for Enum<'l, N, T>
109+
where
110+
T: HasAssoc,
111+
&'l VariantB: Clone,
112+
{
113+
fn as_variant(&self) -> Option<&'l VariantB> {
114+
match self {
115+
Enum::BorrowedSpecificType(inner, ..) => Some(inner.clone()),
116+
_ => None,
117+
}
118+
}
119+
}
120+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariant<VariantC<'l>> for Enum<'l, N, T>
121+
where
122+
T: HasAssoc,
123+
VariantC<'l>: Clone,
124+
{
125+
fn as_variant(&self) -> Option<VariantC<'l>> {
126+
match self {
127+
Enum::OwnedWithGenericLifetime(inner, ..) => Some(inner.clone()),
128+
_ => None,
129+
}
130+
}
131+
}
132+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariant<<VariantU as HasT>::T>
133+
for Enum<'l, N, T>
134+
where
135+
T: HasAssoc,
136+
<VariantU as HasT>::T: Clone,
137+
{
138+
fn as_variant(&self) -> Option<<VariantU as HasT>::T> {
139+
match self {
140+
Enum::OwnedAssocTypeOfSpecificTypeBehindCast(inner, ..) => {
141+
Some(inner.clone())
142+
}
143+
_ => None,
144+
}
145+
}
146+
}
147+
fn main() {
148+
type Subject<'x> = Enum<'x, 42, VariantT>;
149+
let mut subject = Subject::Unit;
150+
let _: Option<VariantA> = subject.as_variant();
151+
let _: Option<&VariantB> = subject.as_variant();
152+
let _: Option<VariantC<'_>> = subject.as_variant();
153+
let _: Option<VariantC<'_>> = subject.as_variant();
154+
let _: Option<<VariantU as HasT>::T> = subject.as_variant();
155+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use enumcapsulate::AsVariant;
2+
3+
trait HasAssoc {
4+
type Assoc: Sized;
5+
}
6+
7+
#[derive(Clone)]
8+
pub struct VariantA;
9+
#[derive(Clone)]
10+
pub struct VariantB;
11+
#[derive(Clone)]
12+
pub struct VariantC<'l>(&'l ());
13+
#[derive(Clone)]
14+
pub struct VariantD<const N: usize>([(); N]);
15+
#[derive(Clone)]
16+
pub struct VariantE<T>(T);
17+
#[derive(Clone)]
18+
pub struct VariantF<'l, const N: usize, T>(&'l [T; N]);
19+
20+
#[derive(Clone)]
21+
pub struct VariantT;
22+
23+
impl HasAssoc for VariantT {
24+
type Assoc = ();
25+
}
26+
27+
#[derive(Clone)]
28+
pub struct VariantU;
29+
30+
trait HasT {
31+
// This associated type intentionally has the same name
32+
// as the generic type param of the enum subject.
33+
//
34+
// The point of this is to detect false positives
35+
// from the generic param detection, which should falsely
36+
// detect `VariantU::T` as a use of the type param `T`:
37+
type T: Sized;
38+
}
39+
40+
impl HasT for VariantU {
41+
type T = ();
42+
}
43+
44+
#[derive(AsVariant)]
45+
pub enum Enum<'l, const N: usize, T>
46+
where
47+
T: HasAssoc,
48+
{
49+
Unit,
50+
// We expect this variant to get derived:
51+
OwnedSpecificType(VariantA),
52+
// We expect this variant to get derived:
53+
BorrowedSpecificType(&'l VariantB),
54+
// We expect this variant to get derived:
55+
OwnedWithGenericLifetime(VariantC<'l>),
56+
// We expect this variant to NOT get derived (due to its use of a const param):
57+
OwnedGenericTypeWithConstParam(VariantD<N>),
58+
// We expect this variant to NOT get derived (due to its use of a type param):
59+
OwnedGenericTypeWithTypeParam(VariantE<T>),
60+
// We expect this variant to NOT get derived (due to its use of const and type params):
61+
OwnedGenericTypeWithMixedParams(VariantF<'l, N, T>),
62+
// We expect this variant to NOT get derived (due to its use of a type param):
63+
OwnedGenericParam(T),
64+
// We expect this variant to NOT get derived (due to its use of a type param):
65+
BorrowedGenericParam(&'l T),
66+
// We expect this variant to NOT get derived (due to its use of a type param):
67+
OwnedAssocTypeOfGenericParam(T::Assoc),
68+
// We expect this variant to NOT get derived (due to its use of a type param):
69+
OwnedAssocTypeOfGenericParamBehindCast(<T as HasAssoc>::Assoc),
70+
// We expect this variant to get derived:
71+
OwnedAssocTypeOfSpecificTypeBehindCast(<VariantU as HasT>::T),
72+
}
73+
74+
fn main() {
75+
type Subject<'x> = Enum<'x, 42, VariantT>;
76+
77+
let mut subject = Subject::Unit;
78+
79+
let _: Option<VariantA> = subject.as_variant();
80+
let _: Option<&VariantB> = subject.as_variant();
81+
let _: Option<VariantC<'_>> = subject.as_variant();
82+
let _: Option<VariantC<'_>> = subject.as_variant();
83+
let _: Option<<VariantU as HasT>::T> = subject.as_variant();
84+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use enumcapsulate::AsVariantMut;
2+
trait HasAssoc {
3+
type Assoc: Sized;
4+
}
5+
pub struct VariantA;
6+
pub struct VariantB;
7+
pub struct VariantC<'l>(&'l ());
8+
pub struct VariantD<const N: usize>([(); N]);
9+
pub struct VariantE<T>(T);
10+
pub struct VariantF<'l, const N: usize, T>(&'l [T; N]);
11+
pub struct VariantT;
12+
impl HasAssoc for VariantT {
13+
type Assoc = ();
14+
}
15+
pub struct VariantU;
16+
trait HasT {
17+
type T: Sized;
18+
}
19+
impl HasT for VariantU {
20+
type T = ();
21+
}
22+
pub enum Enum<'l, const N: usize, T>
23+
where
24+
T: HasAssoc,
25+
{
26+
Unit,
27+
OwnedSpecificType(VariantA),
28+
BorrowedSpecificType(&'l VariantB),
29+
OwnedWithGenericLifetime(VariantC<'l>),
30+
OwnedGenericTypeWithConstParam(VariantD<N>),
31+
OwnedGenericTypeWithTypeParam(VariantE<T>),
32+
OwnedGenericTypeWithMixedParams(VariantF<'l, N, T>),
33+
OwnedGenericParam(T),
34+
BorrowedGenericParam(&'l T),
35+
OwnedAssocTypeOfGenericParam(T::Assoc),
36+
OwnedAssocTypeOfGenericParamBehindCast(<T as HasAssoc>::Assoc),
37+
OwnedAssocTypeOfSpecificTypeBehindCast(<VariantU as HasT>::T),
38+
}
39+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariantMut<VariantA> for Enum<'l, N, T>
40+
where
41+
T: HasAssoc,
42+
{
43+
fn as_variant_mut(&mut self) -> Option<&mut VariantA> {
44+
match self {
45+
Enum::OwnedSpecificType(inner, ..) => Some(inner),
46+
_ => None,
47+
}
48+
}
49+
}
50+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariantMut<&'l VariantB>
51+
for Enum<'l, N, T>
52+
where
53+
T: HasAssoc,
54+
{
55+
fn as_variant_mut(&mut self) -> Option<&mut &'l VariantB> {
56+
match self {
57+
Enum::BorrowedSpecificType(inner, ..) => Some(inner),
58+
_ => None,
59+
}
60+
}
61+
}
62+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariantMut<VariantC<'l>>
63+
for Enum<'l, N, T>
64+
where
65+
T: HasAssoc,
66+
{
67+
fn as_variant_mut(&mut self) -> Option<&mut VariantC<'l>> {
68+
match self {
69+
Enum::OwnedWithGenericLifetime(inner, ..) => Some(inner),
70+
_ => None,
71+
}
72+
}
73+
}
74+
impl<'l, const N: usize, T> ::enumcapsulate::AsVariantMut<<VariantU as HasT>::T>
75+
for Enum<'l, N, T>
76+
where
77+
T: HasAssoc,
78+
{
79+
fn as_variant_mut(&mut self) -> Option<&mut <VariantU as HasT>::T> {
80+
match self {
81+
Enum::OwnedAssocTypeOfSpecificTypeBehindCast(inner, ..) => Some(inner),
82+
_ => None,
83+
}
84+
}
85+
}
86+
fn main() {
87+
type Subject<'x> = Enum<'x, 42, VariantT>;
88+
let mut subject = Subject::Unit;
89+
{
90+
let _: Option<&mut VariantA> = subject.as_variant_mut();
91+
}
92+
{
93+
let _: Option<&mut &VariantB> = subject.as_variant_mut();
94+
}
95+
{
96+
let _: Option<&mut VariantC<'_>> = subject.as_variant_mut();
97+
}
98+
{
99+
let _: Option<&mut VariantC<'_>> = subject.as_variant_mut();
100+
}
101+
{
102+
let _: Option<&mut <VariantU as HasT>::T> = subject.as_variant_mut();
103+
}
104+
}

0 commit comments

Comments
 (0)