sway_core/language/ty/declaration/
enum.rs1use crate::{
2 decl_engine::MaterializeConstGenerics,
3 engine_threading::*,
4 has_changes,
5 language::{parsed::EnumDeclaration, ty::TyDeclParsedType, CallPath, Visibility},
6 transform,
7 type_system::*,
8};
9use monomorphization::MonomorphizeHelper;
10use serde::{Deserialize, Serialize};
11use std::{
12 cmp::Ordering,
13 hash::{Hash, Hasher},
14};
15use sway_error::{
16 error::CompileError,
17 handler::{ErrorEmitted, Handler},
18};
19use sway_types::{Ident, Named, Span, Spanned};
20
21#[derive(Clone, Debug, Serialize, Deserialize)]
22pub struct TyEnumDecl {
23 pub call_path: CallPath,
24 pub type_parameters: Vec<TypeParameter>,
25 pub attributes: transform::AttributesMap,
26 pub variants: Vec<TyEnumVariant>,
27 pub span: Span,
28 pub visibility: Visibility,
29}
30
31impl TyDeclParsedType for TyEnumDecl {
32 type ParsedType = EnumDeclaration;
33}
34
35impl Named for TyEnumDecl {
36 fn name(&self) -> &Ident {
37 &self.call_path.suffix
38 }
39}
40
41impl EqWithEngines for TyEnumDecl {}
42impl PartialEqWithEngines for TyEnumDecl {
43 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
44 self.call_path == other.call_path
45 && self.type_parameters.eq(&other.type_parameters, ctx)
46 && self.variants.eq(&other.variants, ctx)
47 && self.visibility == other.visibility
48 }
49}
50
51impl HashWithEngines for TyEnumDecl {
52 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
53 let TyEnumDecl {
54 call_path,
55 type_parameters,
56 variants,
57 visibility,
58 span: _,
61 attributes: _,
62 } = self;
63 call_path.hash(state);
64 variants.hash(state, engines);
65 type_parameters.hash(state, engines);
66 visibility.hash(state);
67 }
68}
69
70impl SubstTypes for TyEnumDecl {
71 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
72 has_changes! {
73 self.variants.subst(ctx);
74 self.type_parameters.subst(ctx);
75 }
76 }
77}
78
79impl Spanned for TyEnumDecl {
80 fn span(&self) -> Span {
81 self.span.clone()
82 }
83}
84
85impl IsConcrete for TyEnumDecl {
86 fn is_concrete(&self, engines: &Engines) -> bool {
87 self.type_parameters
88 .iter()
89 .all(|tp| tp.is_concrete(engines))
90 }
91}
92
93impl MonomorphizeHelper for TyEnumDecl {
94 fn type_parameters(&self) -> &[TypeParameter] {
95 &self.type_parameters
96 }
97
98 fn name(&self) -> &Ident {
99 &self.call_path.suffix
100 }
101
102 fn has_self_type_param(&self) -> bool {
103 false
104 }
105}
106
107impl MaterializeConstGenerics for TyEnumDecl {
108 fn materialize_const_generics(
109 &mut self,
110 _engines: &Engines,
111 _handler: &Handler,
112 _name: &str,
113 _value: &crate::language::ty::TyExpression,
114 ) -> Result<(), ErrorEmitted> {
115 Ok(())
116 }
117}
118
119impl TyEnumDecl {
120 pub(crate) fn expect_variant_from_name(
121 &self,
122 handler: &Handler,
123 variant_name: &Ident,
124 ) -> Result<&TyEnumVariant, ErrorEmitted> {
125 match self
126 .variants
127 .iter()
128 .find(|x| x.name.as_str() == variant_name.as_str())
129 {
130 Some(variant) => Ok(variant),
131 None => Err(handler.emit_err(CompileError::UnknownEnumVariant {
132 enum_name: self.call_path.suffix.clone(),
133 variant_name: variant_name.clone(),
134 span: variant_name.span(),
135 })),
136 }
137 }
138}
139
140impl Spanned for TyEnumVariant {
141 fn span(&self) -> Span {
142 self.span.clone()
143 }
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct TyEnumVariant {
148 pub name: Ident,
149 pub type_argument: TypeArgument,
150 pub(crate) tag: usize,
151 pub span: Span,
152 pub attributes: transform::AttributesMap,
153}
154
155impl HashWithEngines for TyEnumVariant {
156 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
157 self.name.hash(state);
158 self.type_argument.hash(state, engines);
159 self.tag.hash(state);
160 }
161}
162
163impl EqWithEngines for TyEnumVariant {}
164impl PartialEqWithEngines for TyEnumVariant {
165 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
166 self.name == other.name
167 && self.type_argument.eq(&other.type_argument, ctx)
168 && self.tag == other.tag
169 }
170}
171
172impl OrdWithEngines for TyEnumVariant {
173 fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> Ordering {
174 let TyEnumVariant {
175 name: ln,
176 type_argument: lta,
177 tag: lt,
178 span: _,
181 attributes: _,
182 } = self;
183 let TyEnumVariant {
184 name: rn,
185 type_argument: rta,
186 tag: rt,
187 span: _,
190 attributes: _,
191 } = other;
192 ln.cmp(rn)
193 .then_with(|| lta.cmp(rta, ctx))
194 .then_with(|| lt.cmp(rt))
195 }
196}
197
198impl SubstTypes for TyEnumVariant {
199 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
200 self.type_argument.subst_inner(ctx)
201 }
202}