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