1use crate::{
2 decl_engine::*,
3 engine_threading::*,
4 language::{parsed::Declaration, ty::*, Visibility},
5 type_system::*,
6 types::*,
7};
8use serde::{Deserialize, Serialize};
9use std::{
10 fmt,
11 hash::{Hash, Hasher},
12};
13
14use sway_error::{
15 error::CompileError,
16 handler::{ErrorEmitted, Handler},
17};
18use sway_types::{BaseIdent, Ident, Named, Span, Spanned};
19
20#[derive(Clone, Debug, Serialize, Deserialize)]
21pub enum TyDecl {
22 VariableDecl(Box<TyVariableDecl>),
23 ConstantDecl(ConstantDecl),
24 ConfigurableDecl(ConfigurableDecl),
25 ConstGenericDecl(ConstGenericDecl),
26 TraitTypeDecl(TraitTypeDecl),
27 FunctionDecl(FunctionDecl),
28 TraitDecl(TraitDecl),
29 StructDecl(StructDecl),
30 EnumDecl(EnumDecl),
31 EnumVariantDecl(EnumVariantDecl),
32 ImplSelfOrTrait(ImplSelfOrTrait),
33 AbiDecl(AbiDecl),
34 GenericTypeForFunctionScope(GenericTypeForFunctionScope),
37 ErrorRecovery(Span, #[serde(skip)] ErrorEmitted),
38 StorageDecl(StorageDecl),
39 TypeAliasDecl(TypeAliasDecl),
40}
41
42pub trait TyDeclParsedType {
47 type ParsedType;
48}
49
50#[derive(Clone, Debug, Serialize, Deserialize)]
51pub struct ConstGenericDecl {
52 pub decl_id: DeclId<TyConstGenericDecl>,
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize)]
56pub struct ConstantDecl {
57 pub decl_id: DeclId<TyConstantDecl>,
58}
59
60#[derive(Clone, Debug, Serialize, Deserialize)]
61pub struct ConfigurableDecl {
62 pub decl_id: DeclId<TyConfigurableDecl>,
63}
64
65#[derive(Clone, Debug, Serialize, Deserialize)]
66pub struct TraitTypeDecl {
67 pub decl_id: DeclId<TyTraitType>,
68}
69
70#[derive(Clone, Debug, Serialize, Deserialize)]
71pub struct FunctionDecl {
72 pub decl_id: DeclId<TyFunctionDecl>,
73}
74
75#[derive(Clone, Debug, Serialize, Deserialize)]
76pub struct TraitDecl {
77 pub decl_id: DeclId<TyTraitDecl>,
78}
79
80#[derive(Clone, Debug, Serialize, Deserialize)]
81pub struct StructDecl {
82 pub decl_id: DeclId<TyStructDecl>,
83}
84
85#[derive(Clone, Debug, Serialize, Deserialize)]
86pub struct EnumDecl {
87 pub decl_id: DeclId<TyEnumDecl>,
88}
89
90#[derive(Clone, Debug, Serialize, Deserialize)]
91pub struct EnumVariantDecl {
92 pub enum_ref: DeclRefEnum,
93 pub variant_name: Ident,
94 pub variant_decl_span: Span,
95}
96
97#[derive(Clone, Debug, Serialize, Deserialize)]
98pub struct ImplSelfOrTrait {
99 pub decl_id: DeclId<TyImplSelfOrTrait>,
100}
101
102#[derive(Clone, Debug, Serialize, Deserialize)]
103pub struct AbiDecl {
104 pub decl_id: DeclId<TyAbiDecl>,
105}
106
107#[derive(Clone, Debug, Serialize, Deserialize)]
108pub struct GenericTypeForFunctionScope {
109 pub name: Ident,
110 pub type_id: TypeId,
111}
112
113#[derive(Clone, Debug, Serialize, Deserialize)]
114pub struct StorageDecl {
115 pub decl_id: DeclId<TyStorageDecl>,
116}
117
118#[derive(Clone, Debug, Serialize, Deserialize)]
119pub struct TypeAliasDecl {
120 pub decl_id: DeclId<TyTypeAliasDecl>,
121}
122
123impl EqWithEngines for TyDecl {}
124impl PartialEqWithEngines for TyDecl {
125 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
126 let decl_engine = ctx.engines().de();
127 let type_engine = ctx.engines().te();
128 match (self, other) {
129 (TyDecl::VariableDecl(x), TyDecl::VariableDecl(y)) => x.eq(y, ctx),
130 (
131 TyDecl::ConstantDecl(ConstantDecl { decl_id: lid, .. }),
132 TyDecl::ConstantDecl(ConstantDecl { decl_id: rid, .. }),
133 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
134 (
135 TyDecl::FunctionDecl(FunctionDecl { decl_id: lid, .. }),
136 TyDecl::FunctionDecl(FunctionDecl { decl_id: rid, .. }),
137 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
138 (
139 TyDecl::TraitDecl(TraitDecl { decl_id: lid, .. }),
140 TyDecl::TraitDecl(TraitDecl { decl_id: rid, .. }),
141 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
142 (
143 TyDecl::StructDecl(StructDecl { decl_id: lid, .. }),
144 TyDecl::StructDecl(StructDecl { decl_id: rid, .. }),
145 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
146 (
147 TyDecl::EnumDecl(EnumDecl { decl_id: lid, .. }),
148 TyDecl::EnumDecl(EnumDecl { decl_id: rid, .. }),
149 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
150 (
151 TyDecl::EnumVariantDecl(EnumVariantDecl {
152 enum_ref: l_enum,
153 variant_name: ln,
154 ..
155 }),
156 TyDecl::EnumVariantDecl(EnumVariantDecl {
157 enum_ref: r_enum,
158 variant_name: rn,
159 ..
160 }),
161 ) => {
162 ln == rn
163 && decl_engine
164 .get_enum(l_enum)
165 .eq(&decl_engine.get_enum(r_enum), ctx)
166 }
167 (
168 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id: lid, .. }),
169 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id: rid, .. }),
170 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
171 (
172 TyDecl::AbiDecl(AbiDecl { decl_id: lid, .. }),
173 TyDecl::AbiDecl(AbiDecl { decl_id: rid, .. }),
174 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
175 (
176 TyDecl::StorageDecl(StorageDecl { decl_id: lid, .. }),
177 TyDecl::StorageDecl(StorageDecl { decl_id: rid, .. }),
178 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
179 (
180 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id: lid, .. }),
181 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id: rid, .. }),
182 ) => decl_engine.get(lid).eq(&decl_engine.get(rid), ctx),
183 (
184 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
185 name: xn,
186 type_id: xti,
187 }),
188 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
189 name: yn,
190 type_id: yti,
191 }),
192 ) => xn == yn && type_engine.get(*xti).eq(&type_engine.get(*yti), ctx),
193 (TyDecl::ErrorRecovery(x, _), TyDecl::ErrorRecovery(y, _)) => x == y,
194 _ => false,
195 }
196 }
197}
198
199impl HashWithEngines for TyDecl {
200 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
201 let decl_engine = engines.de();
202 let type_engine = engines.te();
203 std::mem::discriminant(self).hash(state);
204 match self {
205 TyDecl::VariableDecl(decl) => {
206 decl.hash(state, engines);
207 }
208 TyDecl::ConstantDecl(ConstantDecl { decl_id, .. }) => {
209 decl_engine.get(decl_id).hash(state, engines);
210 }
211 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id, .. }) => {
212 decl_engine.get(decl_id).hash(state, engines);
213 }
214 TyDecl::ConstGenericDecl(ConstGenericDecl { decl_id }) => {
215 decl_engine.get(decl_id).hash(state, engines);
216 }
217 TyDecl::TraitTypeDecl(TraitTypeDecl { decl_id, .. }) => {
218 decl_engine.get(decl_id).hash(state, engines);
219 }
220 TyDecl::FunctionDecl(FunctionDecl { decl_id, .. }) => {
221 decl_engine.get(decl_id).hash(state, engines);
222 }
223 TyDecl::TraitDecl(TraitDecl { decl_id, .. }) => {
224 decl_engine.get(decl_id).hash(state, engines);
225 }
226 TyDecl::StructDecl(StructDecl { decl_id, .. }) => {
227 decl_engine.get(decl_id).hash(state, engines);
228 }
229 TyDecl::EnumDecl(EnumDecl { decl_id, .. }) => {
230 decl_engine.get(decl_id).hash(state, engines);
231 }
232 TyDecl::EnumVariantDecl(EnumVariantDecl {
233 enum_ref,
234 variant_name,
235 ..
236 }) => {
237 enum_ref.hash(state, engines);
238 variant_name.hash(state);
239 }
240 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id, .. }) => {
241 decl_engine.get(decl_id).hash(state, engines);
242 }
243 TyDecl::AbiDecl(AbiDecl { decl_id, .. }) => {
244 decl_engine.get(decl_id).hash(state, engines);
245 }
246 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
247 decl_engine.get(decl_id).hash(state, engines);
248 }
249 TyDecl::StorageDecl(StorageDecl { decl_id, .. }) => {
250 decl_engine.get(decl_id).hash(state, engines);
251 }
252 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope { name, type_id }) => {
253 name.hash(state);
254 type_engine.get(*type_id).hash(state, engines);
255 }
256 TyDecl::ErrorRecovery(..) => {}
257 }
258 }
259}
260
261impl SubstTypes for TyDecl {
262 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
263 match self {
264 TyDecl::VariableDecl(ref mut var_decl) => var_decl.subst(ctx),
265 TyDecl::FunctionDecl(FunctionDecl {
266 ref mut decl_id, ..
267 }) => decl_id.subst(ctx),
268 TyDecl::TraitDecl(TraitDecl {
269 ref mut decl_id, ..
270 }) => decl_id.subst(ctx),
271 TyDecl::StructDecl(StructDecl {
272 ref mut decl_id, ..
273 }) => decl_id.subst(ctx),
274 TyDecl::EnumDecl(EnumDecl {
275 ref mut decl_id, ..
276 }) => decl_id.subst(ctx),
277 TyDecl::EnumVariantDecl(EnumVariantDecl {
278 ref mut enum_ref, ..
279 }) => enum_ref.subst(ctx),
280 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait {
281 ref mut decl_id, ..
282 }) => decl_id.subst(ctx),
283 TyDecl::TypeAliasDecl(TypeAliasDecl {
284 ref mut decl_id, ..
285 }) => decl_id.subst(ctx),
286 TyDecl::TraitTypeDecl(TraitTypeDecl {
287 ref mut decl_id, ..
288 }) => decl_id.subst(ctx),
289 TyDecl::ConstantDecl(ConstantDecl { decl_id }) => decl_id.subst(ctx),
290 TyDecl::AbiDecl(_)
292 | TyDecl::ConfigurableDecl(_)
293 | TyDecl::StorageDecl(_)
294 | TyDecl::GenericTypeForFunctionScope(_)
295 | TyDecl::ErrorRecovery(..) => HasChanges::No,
296 TyDecl::ConstGenericDecl(_) => HasChanges::No,
297 }
298 }
299}
300
301impl SpannedWithEngines for TyDecl {
302 fn span(&self, engines: &Engines) -> Span {
303 match self {
304 TyDecl::ConstantDecl(ConstantDecl { decl_id, .. }) => {
305 let decl = engines.de().get(decl_id);
306 decl.span.clone()
307 }
308 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id, .. }) => {
309 let decl = engines.de().get(decl_id);
310 decl.span.clone()
311 }
312 TyDecl::ConstGenericDecl(ConstGenericDecl { decl_id }) => {
313 let decl = engines.de().get(decl_id);
314 decl.span.clone()
315 }
316 TyDecl::TraitTypeDecl(TraitTypeDecl { decl_id }) => {
317 engines.de().get_type(decl_id).span.clone()
318 }
319 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
320 engines.de().get_function(decl_id).span.clone()
321 }
322 TyDecl::TraitDecl(TraitDecl { decl_id }) => {
323 engines.de().get_trait(decl_id).span.clone()
324 }
325 TyDecl::StructDecl(StructDecl { decl_id }) => {
326 engines.de().get_struct(decl_id).span.clone()
327 }
328 TyDecl::EnumDecl(EnumDecl { decl_id }) => engines.de().get_enum(decl_id).span.clone(),
329 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id }) => {
330 engines.de().get_impl_self_or_trait(decl_id).span.clone()
331 }
332 TyDecl::AbiDecl(AbiDecl { decl_id }) => engines.de().get_abi(decl_id).span.clone(),
333 TyDecl::VariableDecl(decl) => decl.name.span(),
334 TyDecl::StorageDecl(StorageDecl { decl_id }) => engines.de().get(decl_id).span.clone(),
335 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id }) => {
336 engines.de().get(decl_id).span.clone()
337 }
338 TyDecl::EnumVariantDecl(EnumVariantDecl {
339 variant_decl_span, ..
340 }) => variant_decl_span.clone(),
341 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope { name, .. }) => {
342 name.span()
343 }
344 TyDecl::ErrorRecovery(span, _) => span.clone(),
345 }
346 }
347}
348
349impl DisplayWithEngines for TyDecl {
350 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
351 let type_engine = engines.te();
352 write!(
353 f,
354 "{} declaration ({})",
355 self.friendly_type_name(),
356 match self {
357 TyDecl::VariableDecl(decl) => {
358 let TyVariableDecl {
359 mutability,
360 name,
361 type_ascription,
362 body,
363 ..
364 } = &**decl;
365 let mut builder = String::new();
366 match mutability {
367 VariableMutability::Mutable => builder.push_str("mut"),
368 VariableMutability::RefMutable => builder.push_str("ref mut"),
369 VariableMutability::Immutable => {}
370 }
371 builder.push_str(name.as_str());
372 builder.push_str(": ");
373 builder.push_str(
374 &engines
375 .help_out(&*type_engine.get(type_ascription.type_id))
376 .to_string(),
377 );
378 builder.push_str(" = ");
379 builder.push_str(&engines.help_out(body).to_string());
380 builder
381 }
382 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
383 engines.de().get(decl_id).name.as_str().into()
384 }
385 TyDecl::TraitDecl(TraitDecl { decl_id }) => {
386 engines.de().get(decl_id).name.as_str().into()
387 }
388 TyDecl::StructDecl(StructDecl { decl_id }) => {
389 engines.de().get(decl_id).name().as_str().into()
390 }
391 TyDecl::EnumDecl(EnumDecl { decl_id }) => {
392 engines.de().get(decl_id).name().as_str().into()
393 }
394 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id }) => {
395 engines.de().get(decl_id).name().as_str().into()
396 }
397 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id }) =>
398 engines.de().get(decl_id).name().as_str().into(),
399 _ => String::new(),
400 }
401 )
402 }
403}
404
405impl DebugWithEngines for TyDecl {
406 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> std::fmt::Result {
407 let type_engine = engines.te();
408 write!(
409 f,
410 "{} declaration ({})",
411 self.friendly_type_name(),
412 match self {
413 TyDecl::VariableDecl(decl) => {
414 let TyVariableDecl {
415 mutability,
416 name,
417 type_ascription,
418 body,
419 ..
420 } = &**decl;
421 let mut builder = String::new();
422 match mutability {
423 VariableMutability::Mutable => builder.push_str("mut"),
424 VariableMutability::RefMutable => builder.push_str("ref mut"),
425 VariableMutability::Immutable => {}
426 }
427 builder.push_str(name.as_str());
428 builder.push_str(": ");
429 builder.push_str(
430 &engines
431 .help_out(&*type_engine.get(type_ascription.type_id))
432 .to_string(),
433 );
434 builder.push_str(" = ");
435 builder.push_str(&engines.help_out(body).to_string());
436 builder
437 }
438 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
439 engines.de().get(decl_id).name.as_str().into()
440 }
441 TyDecl::TraitDecl(TraitDecl { decl_id }) => {
442 engines.de().get(decl_id).name.as_str().into()
443 }
444 TyDecl::StructDecl(StructDecl { decl_id }) => {
445 engines.de().get(decl_id).name().as_str().into()
446 }
447 TyDecl::EnumDecl(EnumDecl { decl_id }) => {
448 engines.de().get(decl_id).name().as_str().into()
449 }
450 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id }) => {
451 let decl = engines.de().get(decl_id);
452 return DebugWithEngines::fmt(&*decl, f, engines);
453 }
454 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id }) =>
455 engines.de().get(decl_id).name().as_str().into(),
456 _ => String::new(),
457 }
458 )
459 }
460}
461
462impl CollectTypesMetadata for TyDecl {
463 fn collect_types_metadata(
465 &self,
466 handler: &Handler,
467 ctx: &mut CollectTypesMetadataContext,
468 ) -> Result<Vec<TypeMetadata>, ErrorEmitted> {
469 let decl_engine = ctx.engines.de();
470 let metadata = match self {
471 TyDecl::VariableDecl(decl) => {
472 let mut body = decl.body.collect_types_metadata(handler, ctx)?;
473 body.append(
474 &mut decl
475 .type_ascription
476 .type_id
477 .collect_types_metadata(handler, ctx)?,
478 );
479 body
480 }
481 TyDecl::FunctionDecl(FunctionDecl { decl_id, .. }) => {
482 let decl = decl_engine.get_function(decl_id);
483 decl.collect_types_metadata(handler, ctx)?
484 }
485 TyDecl::ConstantDecl(ConstantDecl { decl_id, .. }) => {
486 let decl = decl_engine.get_constant(decl_id);
487 let TyConstantDecl { value, .. } = &*decl;
488 if let Some(value) = value {
489 value.collect_types_metadata(handler, ctx)?
490 } else {
491 vec![]
492 }
493 }
494 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id, .. }) => {
495 let decl = decl_engine.get_configurable(decl_id);
496 let TyConfigurableDecl { value, .. } = &*decl;
497 if let Some(value) = value {
498 value.collect_types_metadata(handler, ctx)?
499 } else {
500 return Ok(vec![]);
501 }
502 }
503 TyDecl::ErrorRecovery(..)
504 | TyDecl::StorageDecl(_)
505 | TyDecl::TraitDecl(_)
506 | TyDecl::StructDecl(_)
507 | TyDecl::EnumDecl(_)
508 | TyDecl::EnumVariantDecl(_)
509 | TyDecl::ImplSelfOrTrait(_)
510 | TyDecl::AbiDecl(_)
511 | TyDecl::TypeAliasDecl(_)
512 | TyDecl::TraitTypeDecl(_)
513 | TyDecl::GenericTypeForFunctionScope(_)
514 | TyDecl::ConstGenericDecl(_) => vec![],
515 };
516 Ok(metadata)
517 }
518}
519
520impl GetDeclIdent for TyDecl {
521 fn get_decl_ident(&self, engines: &Engines) -> Option<Ident> {
522 match self {
523 TyDecl::ConstantDecl(ConstantDecl { decl_id }) => {
524 Some(engines.de().get_constant(decl_id).name().clone())
525 }
526 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id }) => {
527 Some(engines.de().get_configurable(decl_id).name().clone())
528 }
529 TyDecl::ConstGenericDecl(ConstGenericDecl { decl_id }) => {
530 Some(engines.de().get_const_generic(decl_id).name().clone())
531 }
532 TyDecl::TraitTypeDecl(TraitTypeDecl { decl_id }) => {
533 Some(engines.de().get_type(decl_id).name().clone())
534 }
535 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
536 Some(engines.de().get(decl_id).name.clone())
537 }
538 TyDecl::TraitDecl(TraitDecl { decl_id }) => {
539 Some(engines.de().get(decl_id).name.clone())
540 }
541 TyDecl::StructDecl(StructDecl { decl_id }) => {
542 Some(engines.de().get(decl_id).name().clone())
543 }
544 TyDecl::EnumDecl(EnumDecl { decl_id }) => {
545 Some(engines.de().get(decl_id).name().clone())
546 }
547 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id }) => {
548 Some(engines.de().get(decl_id).name().clone())
549 }
550 TyDecl::AbiDecl(AbiDecl { decl_id }) => Some(engines.de().get(decl_id).name().clone()),
551 TyDecl::VariableDecl(decl) => Some(decl.name.clone()),
552 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id }) => {
553 Some(engines.de().get(decl_id).name().clone())
554 }
555 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope { name, .. }) => {
556 Some(name.clone())
557 }
558 TyDecl::EnumVariantDecl(EnumVariantDecl { variant_name, .. }) => {
559 Some(variant_name.clone())
560 }
561 TyDecl::ErrorRecovery(..) => None,
562 TyDecl::StorageDecl(_) => None,
563 }
564 }
565}
566
567impl TyDecl {
568 pub(crate) fn get_parsed_decl(&self, decl_engine: &DeclEngine) -> Option<Declaration> {
569 match self {
570 TyDecl::VariableDecl(_decl) => None,
571 TyDecl::ConstantDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
572 TyDecl::ConfigurableDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
573 TyDecl::ConstGenericDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
574 TyDecl::TraitTypeDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
575 TyDecl::FunctionDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
576 TyDecl::TraitDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
577 TyDecl::StructDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
578 TyDecl::EnumDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
579 TyDecl::EnumVariantDecl(decl) => decl_engine.get_parsed_decl(decl.enum_ref.id()),
580 TyDecl::ImplSelfOrTrait(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
581 TyDecl::AbiDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
582 TyDecl::GenericTypeForFunctionScope(_data) => None,
583 TyDecl::StorageDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
584 TyDecl::TypeAliasDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
585 TyDecl::ErrorRecovery(_, _) => None,
586 }
587 }
588
589 pub(crate) fn to_enum_id(
593 &self,
594 handler: &Handler,
595 engines: &Engines,
596 ) -> Result<DeclId<TyEnumDecl>, ErrorEmitted> {
597 match self {
598 TyDecl::EnumDecl(EnumDecl { decl_id }) => Ok(*decl_id),
599 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
600 let alias_decl = engines.de().get_type_alias(decl_id);
601 let TyTypeAliasDecl { ty, span, .. } = &*alias_decl;
602 engines
603 .te()
604 .get(ty.type_id)
605 .expect_enum(handler, engines, "", span)
606 }
607 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
609 type_id, ..
610 }) => match &*engines.te().get(*type_id) {
611 TypeInfo::Enum(r) => Ok(*r),
612 _ => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
613 actually: self.friendly_type_name().to_string(),
614 span: self.span(engines),
615 })),
616 },
617 TyDecl::ErrorRecovery(_, err) => Err(*err),
618 decl => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
619 actually: decl.friendly_type_name().to_string(),
620 span: decl.span(engines),
621 })),
622 }
623 }
624
625 pub(crate) fn to_struct_decl(
629 &self,
630 handler: &Handler,
631 engines: &Engines,
632 ) -> Result<DeclId<TyStructDecl>, ErrorEmitted> {
633 match self {
634 TyDecl::StructDecl(StructDecl { decl_id }) => Ok(*decl_id),
635 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
636 let alias_decl = engines.de().get_type_alias(decl_id);
637 let TyTypeAliasDecl { ty, span, .. } = &*alias_decl;
638 engines
639 .te()
640 .get(ty.type_id)
641 .expect_struct(handler, engines, span)
642 }
643 TyDecl::ErrorRecovery(_, err) => Err(*err),
644 decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct {
645 actually: decl.friendly_type_name().to_string(),
646 span: decl.span(engines),
647 })),
648 }
649 }
650
651 pub(crate) fn to_fn_ref(
655 &self,
656 handler: &Handler,
657 engines: &Engines,
658 ) -> Result<DeclRefFunction, ErrorEmitted> {
659 match self {
660 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
661 let decl = engines.de().get(decl_id);
662 Ok(DeclRef::new(decl.name.clone(), *decl_id, decl.span.clone()))
663 }
664 TyDecl::ErrorRecovery(_, err) => Err(*err),
665 decl => Err(handler.emit_err(CompileError::DeclIsNotAFunction {
666 actually: decl.friendly_type_name().to_string(),
667 span: decl.span(engines),
668 })),
669 }
670 }
671
672 pub(crate) fn expect_variable(
676 &self,
677 handler: &Handler,
678 engines: &Engines,
679 ) -> Result<&TyVariableDecl, ErrorEmitted> {
680 match self {
681 TyDecl::VariableDecl(decl) => Ok(decl),
682 TyDecl::ErrorRecovery(_, err) => Err(*err),
683 decl => Err(handler.emit_err(CompileError::DeclIsNotAVariable {
684 actually: decl.friendly_type_name().to_string(),
685 span: decl.span(engines),
686 })),
687 }
688 }
689
690 pub(crate) fn to_abi_ref(
694 &self,
695 handler: &Handler,
696 engines: &Engines,
697 ) -> Result<DeclRef<DeclId<TyAbiDecl>>, ErrorEmitted> {
698 match self {
699 TyDecl::AbiDecl(AbiDecl { decl_id }) => {
700 let abi_decl = engines.de().get_abi(decl_id);
701 Ok(DeclRef::new(
702 abi_decl.name().clone(),
703 *decl_id,
704 abi_decl.span.clone(),
705 ))
706 }
707 TyDecl::ErrorRecovery(_, err) => Err(*err),
708 decl => Err(handler.emit_err(CompileError::DeclIsNotAnAbi {
709 actually: decl.friendly_type_name().to_string(),
710 span: decl.span(engines),
711 })),
712 }
713 }
714
715 pub(crate) fn to_const_ref(
719 &self,
720 handler: &Handler,
721 engines: &Engines,
722 ) -> Result<DeclRef<DeclId<TyConstantDecl>>, ErrorEmitted> {
723 match self {
724 TyDecl::ConstantDecl(ConstantDecl { decl_id }) => {
725 let const_decl = engines.de().get_constant(decl_id);
726 Ok(DeclRef::new(
727 const_decl.name().clone(),
728 *decl_id,
729 const_decl.span.clone(),
730 ))
731 }
732 TyDecl::ErrorRecovery(_, err) => Err(*err),
733 decl => Err(handler.emit_err(CompileError::DeclIsNotAConstant {
734 actually: decl.friendly_type_name().to_string(),
735 span: decl.span(engines),
736 })),
737 }
738 }
739
740 pub fn get_name(&self, engines: &Engines) -> BaseIdent {
741 match self {
742 TyDecl::VariableDecl(ty_variable_decl) => ty_variable_decl.name.clone(),
743 TyDecl::ConstantDecl(constant_decl) => engines
744 .de()
745 .get_constant(&constant_decl.decl_id)
746 .call_path
747 .suffix
748 .clone(),
749 TyDecl::ConfigurableDecl(configurable_decl) => engines
750 .de()
751 .get_configurable(&configurable_decl.decl_id)
752 .call_path
753 .suffix
754 .clone(),
755 TyDecl::ConstGenericDecl(const_generic_decl) => engines
756 .de()
757 .get_const_generic(&const_generic_decl.decl_id)
758 .call_path
759 .suffix
760 .clone(),
761 TyDecl::TraitTypeDecl(trait_type_decl) => {
762 engines.de().get_type(&trait_type_decl.decl_id).name.clone()
763 }
764 TyDecl::FunctionDecl(function_decl) => engines
765 .de()
766 .get_function(&function_decl.decl_id)
767 .name
768 .clone(),
769 TyDecl::TraitDecl(trait_decl) => {
770 engines.de().get_trait(&trait_decl.decl_id).name.clone()
771 }
772 TyDecl::StructDecl(struct_decl) => engines
773 .de()
774 .get_struct(&struct_decl.decl_id)
775 .call_path
776 .suffix
777 .clone(),
778 TyDecl::EnumDecl(enum_decl) => engines
779 .de()
780 .get_enum(&enum_decl.decl_id)
781 .call_path
782 .suffix
783 .clone(),
784 TyDecl::EnumVariantDecl(_enum_variant_decl) => {
785 unreachable!()
786 }
787 TyDecl::ImplSelfOrTrait(impl_self_or_trait) => engines
788 .de()
789 .get_impl_self_or_trait(&impl_self_or_trait.decl_id)
790 .trait_name
791 .suffix
792 .clone(),
793 TyDecl::AbiDecl(abi_decl) => engines.de().get_abi(&abi_decl.decl_id).name.clone(),
794 TyDecl::GenericTypeForFunctionScope(_generic_type_for_function_scope) => unreachable!(),
795 TyDecl::ErrorRecovery(_span, _error_emitted) => unreachable!(),
796 TyDecl::StorageDecl(_storage_decl) => unreachable!(),
797 TyDecl::TypeAliasDecl(type_alias_decl) => engines
798 .de()
799 .get_type_alias(&type_alias_decl.decl_id)
800 .call_path
801 .suffix
802 .clone(),
803 }
804 }
805
806 pub fn friendly_name(&self, engines: &Engines) -> String {
809 let decl_engine = engines.de();
810 let type_engine = engines.te();
811 match self {
812 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id, .. }) => {
813 let decl = decl_engine.get_impl_self_or_trait(decl_id);
814 let implementing_for_type_id_arc = type_engine.get(decl.implementing_for.type_id);
815 let implementing_for_type_id = &*implementing_for_type_id_arc;
816 format!(
817 "{} for {:?}",
818 self.get_decl_ident(engines)
819 .map_or(String::from(""), |f| f.as_str().to_string()),
820 engines.help_out(implementing_for_type_id)
821 )
822 }
823 _ => self
824 .get_decl_ident(engines)
825 .map_or(String::from(""), |f| f.as_str().to_string()),
826 }
827 }
828
829 pub fn friendly_type_name(&self) -> &'static str {
838 use TyDecl::*;
839 match self {
840 VariableDecl(_) => "variable",
841 ConstantDecl(_) => "constant",
842 ConfigurableDecl(_) => "configurable",
843 ConstGenericDecl(_) => "const generic",
844 TraitTypeDecl(_) => "type",
845 FunctionDecl(_) => "function",
846 TraitDecl(_) => "trait",
847 StructDecl(_) => "struct",
848 EnumDecl(_) => "enum",
849 EnumVariantDecl(_) => "enum variant",
850 ImplSelfOrTrait(_) => "impl trait",
851 AbiDecl(_) => "abi",
852 GenericTypeForFunctionScope(_) => "generic type parameter",
853 ErrorRecovery(_, _) => "error",
854 StorageDecl(_) => "contract storage",
855 TypeAliasDecl(_) => "type alias",
856 }
857 }
858
859 pub fn friendly_type_name_with_acronym(&self) -> &'static str {
860 match self.friendly_type_name() {
861 "abi" => "ABI",
862 friendly_name => friendly_name,
863 }
864 }
865
866 pub(crate) fn return_type(
867 &self,
868 handler: &Handler,
869 engines: &Engines,
870 ) -> Result<TypeId, ErrorEmitted> {
871 let type_engine = engines.te();
872 let decl_engine = engines.de();
873 let type_id = match self {
874 TyDecl::VariableDecl(decl) => decl.return_type,
875 TyDecl::FunctionDecl(FunctionDecl { decl_id, .. }) => {
876 let decl = decl_engine.get_function(decl_id);
877 decl.return_type.type_id
878 }
879 TyDecl::StructDecl(StructDecl { decl_id }) => {
880 type_engine.insert_struct(engines, *decl_id)
881 }
882 TyDecl::EnumDecl(EnumDecl { decl_id }) => type_engine.insert_enum(engines, *decl_id),
883 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
884 let decl = decl_engine.get_type_alias(decl_id);
885 decl.create_type_id(engines)
886 }
887 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
888 type_id, ..
889 }) => *type_id,
890 decl => {
891 return Err(handler.emit_err(CompileError::NotAType {
892 span: decl.span(engines),
893 name: engines.help_out(decl).to_string(),
894 actually_is: decl.friendly_type_name(),
895 }));
896 }
897 };
898 Ok(type_id)
899 }
900
901 pub(crate) fn visibility(&self, decl_engine: &DeclEngine) -> Visibility {
902 match self {
903 TyDecl::TraitDecl(TraitDecl { decl_id, .. }) => {
904 decl_engine.get_trait(decl_id).visibility
905 }
906 TyDecl::ConstantDecl(ConstantDecl { decl_id, .. }) => {
907 decl_engine.get_constant(decl_id).visibility
908 }
909 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id, .. }) => {
910 decl_engine.get_configurable(decl_id).visibility
911 }
912 TyDecl::ConstGenericDecl(_) => {
913 unreachable!("Const generics do not have visibility");
914 }
915 TyDecl::StructDecl(StructDecl { decl_id, .. }) => {
916 decl_engine.get_struct(decl_id).visibility
917 }
918 TyDecl::EnumDecl(EnumDecl { decl_id, .. }) => decl_engine.get_enum(decl_id).visibility,
919 TyDecl::EnumVariantDecl(EnumVariantDecl { enum_ref, .. }) => {
920 decl_engine.get_enum(enum_ref.id()).visibility
921 }
922 TyDecl::FunctionDecl(FunctionDecl { decl_id, .. }) => {
923 decl_engine.get_function(decl_id).visibility
924 }
925 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
926 decl_engine.get_type_alias(decl_id).visibility
927 }
928 TyDecl::GenericTypeForFunctionScope(_)
929 | TyDecl::ImplSelfOrTrait(_)
930 | TyDecl::StorageDecl(_)
931 | TyDecl::AbiDecl(_)
932 | TyDecl::TraitTypeDecl(_)
933 | TyDecl::ErrorRecovery(_, _) => Visibility::Public,
934 TyDecl::VariableDecl(decl) => decl.mutability.visibility(),
935 }
936 }
937}
938
939impl From<DeclRef<DeclId<TyTraitType>>> for TyDecl {
940 fn from(decl_ref: DeclRef<DeclId<TyTraitType>>) -> Self {
941 TyDecl::TraitTypeDecl(TraitTypeDecl {
942 decl_id: *decl_ref.id(),
943 })
944 }
945}
946
947impl From<DeclRef<DeclId<TyConstantDecl>>> for TyDecl {
948 fn from(decl_ref: DeclRef<DeclId<TyConstantDecl>>) -> Self {
949 TyDecl::ConstantDecl(ConstantDecl {
950 decl_id: *decl_ref.id(),
951 })
952 }
953}
954
955impl From<DeclRef<DeclId<TyConfigurableDecl>>> for TyDecl {
956 fn from(decl_ref: DeclRef<DeclId<TyConfigurableDecl>>) -> Self {
957 TyDecl::ConfigurableDecl(ConfigurableDecl {
958 decl_id: *decl_ref.id(),
959 })
960 }
961}
962
963impl From<DeclRef<DeclId<TyEnumDecl>>> for TyDecl {
964 fn from(decl_ref: DeclRef<DeclId<TyEnumDecl>>) -> Self {
965 TyDecl::EnumDecl(EnumDecl {
966 decl_id: *decl_ref.id(),
967 })
968 }
969}
970
971impl From<DeclRef<DeclId<TyFunctionDecl>>> for TyDecl {
972 fn from(decl_ref: DeclRef<DeclId<TyFunctionDecl>>) -> Self {
973 TyDecl::FunctionDecl(FunctionDecl {
974 decl_id: *decl_ref.id(),
975 })
976 }
977}
978
979impl From<DeclRef<DeclId<TyTraitDecl>>> for TyDecl {
980 fn from(decl_ref: DeclRef<DeclId<TyTraitDecl>>) -> Self {
981 TyDecl::TraitDecl(TraitDecl {
982 decl_id: *decl_ref.id(),
983 })
984 }
985}
986
987impl From<DeclRef<DeclId<TyImplSelfOrTrait>>> for TyDecl {
988 fn from(decl_ref: DeclRef<DeclId<TyImplSelfOrTrait>>) -> Self {
989 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait {
990 decl_id: *decl_ref.id(),
991 })
992 }
993}
994
995impl From<DeclRef<DeclId<TyStructDecl>>> for TyDecl {
996 fn from(decl_ref: DeclRef<DeclId<TyStructDecl>>) -> Self {
997 TyDecl::StructDecl(StructDecl {
998 decl_id: *decl_ref.id(),
999 })
1000 }
1001}
1002
1003impl From<DeclRef<DeclId<TyAbiDecl>>> for TyDecl {
1004 fn from(decl_ref: DeclRef<DeclId<TyAbiDecl>>) -> Self {
1005 TyDecl::AbiDecl(AbiDecl {
1006 decl_id: *decl_ref.id(),
1007 })
1008 }
1009}
1010
1011impl From<DeclRef<DeclId<TyStorageDecl>>> for TyDecl {
1012 fn from(decl_ref: DeclRef<DeclId<TyStorageDecl>>) -> Self {
1013 TyDecl::StorageDecl(StorageDecl {
1014 decl_id: *decl_ref.id(),
1015 })
1016 }
1017}
1018impl From<DeclRef<DeclId<TyTypeAliasDecl>>> for TyDecl {
1019 fn from(decl_ref: DeclRef<DeclId<TyTypeAliasDecl>>) -> Self {
1020 TyDecl::TypeAliasDecl(TypeAliasDecl {
1021 decl_id: *decl_ref.id(),
1022 })
1023 }
1024}