1use crate::{
2 decl_engine::*,
3 engine_threading::*,
4 language::{parsed::Declaration, ty::*, CallPath, Visibility},
5 semantic_analysis::TypeCheckContext,
6 type_system::*,
7 types::*,
8};
9use serde::{Deserialize, Serialize};
10use std::{
11 collections::HashMap,
12 fmt,
13 hash::{Hash, Hasher},
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::EnumDecl(_)
526 | TyDecl::EnumVariantDecl(_)
527 | TyDecl::ImplSelfOrTrait(_)
528 | TyDecl::TypeAliasDecl(_)
529 | TyDecl::TraitTypeDecl(_)
530 | TyDecl::GenericTypeForFunctionScope(_)
531 | TyDecl::AbiDecl(_)
532 | TyDecl::StructDecl(_)
533 | TyDecl::ConstGenericDecl(_) => vec![],
534 };
535 Ok(metadata)
536 }
537}
538
539pub fn generate_is_decode_trivial_table(
540 ctx: &mut TypeCheckContext<'_>,
541 types: impl IntoIterator<Item = TypeId>,
542) -> HashMap<String, TyExpression> {
543 let mut map = HashMap::new();
544
545 for tid in types {
546 for tid in tid.extract_inner_types(ctx.engines, IncludeSelf::Yes) {
547 let fullname = ctx.engines.help_out(tid).to_string();
548 let handler = Handler::default();
549 let expr = TyExpression::type_check_function_application(
550 &handler,
551 ctx.by_ref(),
552 TypeBinding {
553 inner: CallPath {
554 prefixes: vec![
555 BaseIdent::new_no_span("std".into()),
556 BaseIdent::new_no_span("codec".into()),
557 ],
558 suffix: BaseIdent::new_no_span("is_decode_trivial".into()),
559 callpath_type: crate::language::CallPathType::Ambiguous,
560 },
561 type_arguments: TypeArgs::Regular(vec![GenericArgument::Type(
562 GenericTypeArgument {
563 type_id: tid,
564 initial_type_id: tid,
565 span: Span::dummy(),
566 call_path_tree: None,
567 },
568 )]),
569 span: Span::dummy(),
570 },
571 &[],
572 Span::dummy(),
573 );
574
575 if let Ok(expr) = expr {
576 map.insert(fullname, expr);
577 }
578 }
579 }
580
581 map
582}
583
584impl GetDeclIdent for TyDecl {
585 fn get_decl_ident(&self, engines: &Engines) -> Option<Ident> {
586 match self {
587 TyDecl::ConstantDecl(ConstantDecl { decl_id }) => {
588 Some(engines.de().get_constant(decl_id).name().clone())
589 }
590 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id }) => {
591 Some(engines.de().get_configurable(decl_id).name().clone())
592 }
593 TyDecl::ConstGenericDecl(ConstGenericDecl { decl_id }) => {
594 Some(engines.de().get_const_generic(decl_id).name().clone())
595 }
596 TyDecl::TraitTypeDecl(TraitTypeDecl { decl_id }) => {
597 Some(engines.de().get_type(decl_id).name().clone())
598 }
599 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
600 Some(engines.de().get(decl_id).name.clone())
601 }
602 TyDecl::TraitDecl(TraitDecl { decl_id }) => {
603 Some(engines.de().get(decl_id).name.clone())
604 }
605 TyDecl::StructDecl(StructDecl { decl_id }) => {
606 Some(engines.de().get(decl_id).name().clone())
607 }
608 TyDecl::EnumDecl(EnumDecl { decl_id }) => {
609 Some(engines.de().get(decl_id).name().clone())
610 }
611 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id }) => {
612 Some(engines.de().get(decl_id).name().clone())
613 }
614 TyDecl::AbiDecl(AbiDecl { decl_id }) => Some(engines.de().get(decl_id).name().clone()),
615 TyDecl::VariableDecl(decl) => Some(decl.name.clone()),
616 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id }) => {
617 Some(engines.de().get(decl_id).name().clone())
618 }
619 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope { name, .. }) => {
620 Some(name.clone())
621 }
622 TyDecl::EnumVariantDecl(EnumVariantDecl { variant_name, .. }) => {
623 Some(variant_name.clone())
624 }
625 TyDecl::ErrorRecovery(..) => None,
626 TyDecl::StorageDecl(_) => None,
627 }
628 }
629}
630
631impl TyDecl {
632 pub(crate) fn get_parsed_decl(&self, decl_engine: &DeclEngine) -> Option<Declaration> {
633 match self {
634 TyDecl::VariableDecl(_decl) => None,
635 TyDecl::ConstantDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
636 TyDecl::ConfigurableDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
637 TyDecl::ConstGenericDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
638 TyDecl::TraitTypeDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
639 TyDecl::FunctionDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
640 TyDecl::TraitDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
641 TyDecl::StructDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
642 TyDecl::EnumDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
643 TyDecl::EnumVariantDecl(decl) => decl_engine.get_parsed_decl(decl.enum_ref.id()),
644 TyDecl::ImplSelfOrTrait(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
645 TyDecl::AbiDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
646 TyDecl::GenericTypeForFunctionScope(_data) => None,
647 TyDecl::StorageDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
648 TyDecl::TypeAliasDecl(decl) => decl_engine.get_parsed_decl(&decl.decl_id),
649 TyDecl::ErrorRecovery(_, _) => None,
650 }
651 }
652
653 pub(crate) fn to_enum_id(
657 &self,
658 handler: &Handler,
659 engines: &Engines,
660 ) -> Result<DeclId<TyEnumDecl>, ErrorEmitted> {
661 match self {
662 TyDecl::EnumDecl(EnumDecl { decl_id }) => Ok(*decl_id),
663 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
664 let alias_decl = engines.de().get_type_alias(decl_id);
665 let TyTypeAliasDecl { ty, span, .. } = &*alias_decl;
666 engines
667 .te()
668 .get(ty.type_id)
669 .expect_enum(handler, engines, "", span)
670 }
671 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
673 type_id, ..
674 }) => match &*engines.te().get(*type_id) {
675 TypeInfo::Enum(r) => Ok(*r),
676 _ => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
677 actually: self.friendly_type_name().to_string(),
678 span: self.span(engines),
679 })),
680 },
681 TyDecl::ErrorRecovery(_, err) => Err(*err),
682 decl => Err(handler.emit_err(CompileError::DeclIsNotAnEnum {
683 actually: decl.friendly_type_name().to_string(),
684 span: decl.span(engines),
685 })),
686 }
687 }
688
689 pub(crate) fn to_struct_decl(
693 &self,
694 handler: &Handler,
695 engines: &Engines,
696 ) -> Result<DeclId<TyStructDecl>, ErrorEmitted> {
697 match self {
698 TyDecl::StructDecl(StructDecl { decl_id }) => Ok(*decl_id),
699 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
700 let alias_decl = engines.de().get_type_alias(decl_id);
701 let TyTypeAliasDecl { ty, span, .. } = &*alias_decl;
702 engines
703 .te()
704 .get(ty.type_id)
705 .expect_struct(handler, engines, span)
706 }
707 TyDecl::ErrorRecovery(_, err) => Err(*err),
708 decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct {
709 actually: decl.friendly_type_name().to_string(),
710 span: decl.span(engines),
711 })),
712 }
713 }
714
715 pub(crate) fn to_fn_ref(
719 &self,
720 handler: &Handler,
721 engines: &Engines,
722 ) -> Result<DeclRefFunction, ErrorEmitted> {
723 match self {
724 TyDecl::FunctionDecl(FunctionDecl { decl_id }) => {
725 let decl = engines.de().get(decl_id);
726 Ok(DeclRef::new(decl.name.clone(), *decl_id, decl.span.clone()))
727 }
728 TyDecl::ErrorRecovery(_, err) => Err(*err),
729 decl => Err(handler.emit_err(CompileError::DeclIsNotAFunction {
730 actually: decl.friendly_type_name().to_string(),
731 span: decl.span(engines),
732 })),
733 }
734 }
735
736 pub(crate) fn expect_variable(
740 &self,
741 handler: &Handler,
742 engines: &Engines,
743 ) -> Result<&TyVariableDecl, ErrorEmitted> {
744 match self {
745 TyDecl::VariableDecl(decl) => Ok(decl),
746 TyDecl::ErrorRecovery(_, err) => Err(*err),
747 decl => Err(handler.emit_err(CompileError::DeclIsNotAVariable {
748 actually: decl.friendly_type_name().to_string(),
749 span: decl.span(engines),
750 })),
751 }
752 }
753
754 pub(crate) fn to_abi_ref(
758 &self,
759 handler: &Handler,
760 engines: &Engines,
761 ) -> Result<DeclRef<DeclId<TyAbiDecl>>, ErrorEmitted> {
762 match self {
763 TyDecl::AbiDecl(AbiDecl { decl_id }) => {
764 let abi_decl = engines.de().get_abi(decl_id);
765 Ok(DeclRef::new(
766 abi_decl.name().clone(),
767 *decl_id,
768 abi_decl.span.clone(),
769 ))
770 }
771 TyDecl::ErrorRecovery(_, err) => Err(*err),
772 decl => Err(handler.emit_err(CompileError::DeclIsNotAnAbi {
773 actually: decl.friendly_type_name().to_string(),
774 span: decl.span(engines),
775 })),
776 }
777 }
778
779 pub(crate) fn to_const_ref(
783 &self,
784 handler: &Handler,
785 engines: &Engines,
786 ) -> Result<DeclRef<DeclId<TyConstantDecl>>, ErrorEmitted> {
787 match self {
788 TyDecl::ConstantDecl(ConstantDecl { decl_id }) => {
789 let const_decl = engines.de().get_constant(decl_id);
790 Ok(DeclRef::new(
791 const_decl.name().clone(),
792 *decl_id,
793 const_decl.span.clone(),
794 ))
795 }
796 TyDecl::ErrorRecovery(_, err) => Err(*err),
797 decl => Err(handler.emit_err(CompileError::DeclIsNotAConstant {
798 actually: decl.friendly_type_name().to_string(),
799 span: decl.span(engines),
800 })),
801 }
802 }
803
804 pub fn get_name(&self, engines: &Engines) -> BaseIdent {
805 match self {
806 TyDecl::VariableDecl(ty_variable_decl) => ty_variable_decl.name.clone(),
807 TyDecl::ConstantDecl(constant_decl) => engines
808 .de()
809 .get_constant(&constant_decl.decl_id)
810 .call_path
811 .suffix
812 .clone(),
813 TyDecl::ConfigurableDecl(configurable_decl) => engines
814 .de()
815 .get_configurable(&configurable_decl.decl_id)
816 .call_path
817 .suffix
818 .clone(),
819 TyDecl::ConstGenericDecl(const_generic_decl) => engines
820 .de()
821 .get_const_generic(&const_generic_decl.decl_id)
822 .call_path
823 .suffix
824 .clone(),
825 TyDecl::TraitTypeDecl(trait_type_decl) => {
826 engines.de().get_type(&trait_type_decl.decl_id).name.clone()
827 }
828 TyDecl::FunctionDecl(function_decl) => engines
829 .de()
830 .get_function(&function_decl.decl_id)
831 .name
832 .clone(),
833 TyDecl::TraitDecl(trait_decl) => {
834 engines.de().get_trait(&trait_decl.decl_id).name.clone()
835 }
836 TyDecl::StructDecl(struct_decl) => engines
837 .de()
838 .get_struct(&struct_decl.decl_id)
839 .call_path
840 .suffix
841 .clone(),
842 TyDecl::EnumDecl(enum_decl) => engines
843 .de()
844 .get_enum(&enum_decl.decl_id)
845 .call_path
846 .suffix
847 .clone(),
848 TyDecl::EnumVariantDecl(_enum_variant_decl) => {
849 unreachable!()
850 }
851 TyDecl::ImplSelfOrTrait(impl_self_or_trait) => engines
852 .de()
853 .get_impl_self_or_trait(&impl_self_or_trait.decl_id)
854 .trait_name
855 .suffix
856 .clone(),
857 TyDecl::AbiDecl(abi_decl) => engines.de().get_abi(&abi_decl.decl_id).name.clone(),
858 TyDecl::GenericTypeForFunctionScope(_generic_type_for_function_scope) => unreachable!(),
859 TyDecl::ErrorRecovery(_span, _error_emitted) => unreachable!(),
860 TyDecl::StorageDecl(_storage_decl) => unreachable!(),
861 TyDecl::TypeAliasDecl(type_alias_decl) => engines
862 .de()
863 .get_type_alias(&type_alias_decl.decl_id)
864 .call_path
865 .suffix
866 .clone(),
867 }
868 }
869
870 pub fn friendly_name(&self, engines: &Engines) -> String {
873 let decl_engine = engines.de();
874 let type_engine = engines.te();
875 match self {
876 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait { decl_id, .. }) => {
877 let decl = decl_engine.get_impl_self_or_trait(decl_id);
878 let implementing_for_type_id_arc = type_engine.get(decl.implementing_for.type_id);
879 let implementing_for_type_id = &*implementing_for_type_id_arc;
880 format!(
881 "{} for {:?}",
882 self.get_decl_ident(engines)
883 .map_or(String::from(""), |f| f.as_str().to_string()),
884 engines.help_out(implementing_for_type_id)
885 )
886 }
887 _ => self
888 .get_decl_ident(engines)
889 .map_or(String::from(""), |f| f.as_str().to_string()),
890 }
891 }
892
893 pub fn friendly_type_name(&self) -> &'static str {
902 use TyDecl::*;
903 match self {
904 VariableDecl(_) => "variable",
905 ConstantDecl(_) => "constant",
906 ConfigurableDecl(_) => "configurable",
907 ConstGenericDecl(_) => "const generic",
908 TraitTypeDecl(_) => "type",
909 FunctionDecl(_) => "function",
910 TraitDecl(_) => "trait",
911 StructDecl(_) => "struct",
912 EnumDecl(_) => "enum",
913 EnumVariantDecl(_) => "enum variant",
914 ImplSelfOrTrait(_) => "impl trait",
915 AbiDecl(_) => "abi",
916 GenericTypeForFunctionScope(_) => "generic type parameter",
917 ErrorRecovery(_, _) => "error",
918 StorageDecl(_) => "contract storage",
919 TypeAliasDecl(_) => "type alias",
920 }
921 }
922
923 pub fn friendly_type_name_with_acronym(&self) -> &'static str {
924 match self.friendly_type_name() {
925 "abi" => "ABI",
926 friendly_name => friendly_name,
927 }
928 }
929
930 pub(crate) fn return_type(
931 &self,
932 handler: &Handler,
933 engines: &Engines,
934 ) -> Result<TypeId, ErrorEmitted> {
935 let type_engine = engines.te();
936 let decl_engine = engines.de();
937 let type_id = match self {
938 TyDecl::VariableDecl(decl) => decl.return_type,
939 TyDecl::FunctionDecl(FunctionDecl { decl_id, .. }) => {
940 let decl = decl_engine.get_function(decl_id);
941 decl.return_type.type_id
942 }
943 TyDecl::StructDecl(StructDecl { decl_id }) => {
944 type_engine.insert_struct(engines, *decl_id)
945 }
946 TyDecl::EnumDecl(EnumDecl { decl_id }) => type_engine.insert_enum(engines, *decl_id),
947 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
948 let decl = decl_engine.get_type_alias(decl_id);
949 decl.create_type_id(engines)
950 }
951 TyDecl::GenericTypeForFunctionScope(GenericTypeForFunctionScope {
952 type_id, ..
953 }) => *type_id,
954 decl => {
955 return Err(handler.emit_err(CompileError::NotAType {
956 span: decl.span(engines),
957 name: engines.help_out(decl).to_string(),
958 actually_is: decl.friendly_type_name(),
959 }));
960 }
961 };
962 Ok(type_id)
963 }
964
965 pub(crate) fn visibility(&self, decl_engine: &DeclEngine) -> Visibility {
966 match self {
967 TyDecl::TraitDecl(TraitDecl { decl_id, .. }) => {
968 decl_engine.get_trait(decl_id).visibility
969 }
970 TyDecl::ConstantDecl(ConstantDecl { decl_id, .. }) => {
971 decl_engine.get_constant(decl_id).visibility
972 }
973 TyDecl::ConfigurableDecl(ConfigurableDecl { decl_id, .. }) => {
974 decl_engine.get_configurable(decl_id).visibility
975 }
976 TyDecl::ConstGenericDecl(_) => {
977 unreachable!("Const generics do not have visibility");
978 }
979 TyDecl::StructDecl(StructDecl { decl_id, .. }) => {
980 decl_engine.get_struct(decl_id).visibility
981 }
982 TyDecl::EnumDecl(EnumDecl { decl_id, .. }) => decl_engine.get_enum(decl_id).visibility,
983 TyDecl::EnumVariantDecl(EnumVariantDecl { enum_ref, .. }) => {
984 decl_engine.get_enum(enum_ref.id()).visibility
985 }
986 TyDecl::FunctionDecl(FunctionDecl { decl_id, .. }) => {
987 decl_engine.get_function(decl_id).visibility
988 }
989 TyDecl::TypeAliasDecl(TypeAliasDecl { decl_id, .. }) => {
990 decl_engine.get_type_alias(decl_id).visibility
991 }
992 TyDecl::GenericTypeForFunctionScope(_)
993 | TyDecl::ImplSelfOrTrait(_)
994 | TyDecl::StorageDecl(_)
995 | TyDecl::AbiDecl(_)
996 | TyDecl::TraitTypeDecl(_)
997 | TyDecl::ErrorRecovery(_, _) => Visibility::Public,
998 TyDecl::VariableDecl(decl) => decl.mutability.visibility(),
999 }
1000 }
1001}
1002
1003impl From<DeclRef<DeclId<TyTraitType>>> for TyDecl {
1004 fn from(decl_ref: DeclRef<DeclId<TyTraitType>>) -> Self {
1005 TyDecl::TraitTypeDecl(TraitTypeDecl {
1006 decl_id: *decl_ref.id(),
1007 })
1008 }
1009}
1010
1011impl From<DeclRef<DeclId<TyConstantDecl>>> for TyDecl {
1012 fn from(decl_ref: DeclRef<DeclId<TyConstantDecl>>) -> Self {
1013 TyDecl::ConstantDecl(ConstantDecl {
1014 decl_id: *decl_ref.id(),
1015 })
1016 }
1017}
1018
1019impl From<DeclRef<DeclId<TyConfigurableDecl>>> for TyDecl {
1020 fn from(decl_ref: DeclRef<DeclId<TyConfigurableDecl>>) -> Self {
1021 TyDecl::ConfigurableDecl(ConfigurableDecl {
1022 decl_id: *decl_ref.id(),
1023 })
1024 }
1025}
1026
1027impl From<DeclRef<DeclId<TyEnumDecl>>> for TyDecl {
1028 fn from(decl_ref: DeclRef<DeclId<TyEnumDecl>>) -> Self {
1029 TyDecl::EnumDecl(EnumDecl {
1030 decl_id: *decl_ref.id(),
1031 })
1032 }
1033}
1034
1035impl From<DeclRef<DeclId<TyFunctionDecl>>> for TyDecl {
1036 fn from(decl_ref: DeclRef<DeclId<TyFunctionDecl>>) -> Self {
1037 TyDecl::FunctionDecl(FunctionDecl {
1038 decl_id: *decl_ref.id(),
1039 })
1040 }
1041}
1042
1043impl From<DeclRef<DeclId<TyTraitDecl>>> for TyDecl {
1044 fn from(decl_ref: DeclRef<DeclId<TyTraitDecl>>) -> Self {
1045 TyDecl::TraitDecl(TraitDecl {
1046 decl_id: *decl_ref.id(),
1047 })
1048 }
1049}
1050
1051impl From<DeclRef<DeclId<TyImplSelfOrTrait>>> for TyDecl {
1052 fn from(decl_ref: DeclRef<DeclId<TyImplSelfOrTrait>>) -> Self {
1053 TyDecl::ImplSelfOrTrait(ImplSelfOrTrait {
1054 decl_id: *decl_ref.id(),
1055 })
1056 }
1057}
1058
1059impl From<DeclRef<DeclId<TyStructDecl>>> for TyDecl {
1060 fn from(decl_ref: DeclRef<DeclId<TyStructDecl>>) -> Self {
1061 TyDecl::StructDecl(StructDecl {
1062 decl_id: *decl_ref.id(),
1063 })
1064 }
1065}
1066
1067impl From<DeclRef<DeclId<TyAbiDecl>>> for TyDecl {
1068 fn from(decl_ref: DeclRef<DeclId<TyAbiDecl>>) -> Self {
1069 TyDecl::AbiDecl(AbiDecl {
1070 decl_id: *decl_ref.id(),
1071 })
1072 }
1073}
1074
1075impl From<DeclRef<DeclId<TyStorageDecl>>> for TyDecl {
1076 fn from(decl_ref: DeclRef<DeclId<TyStorageDecl>>) -> Self {
1077 TyDecl::StorageDecl(StorageDecl {
1078 decl_id: *decl_ref.id(),
1079 })
1080 }
1081}
1082impl From<DeclRef<DeclId<TyTypeAliasDecl>>> for TyDecl {
1083 fn from(decl_ref: DeclRef<DeclId<TyTypeAliasDecl>>) -> Self {
1084 TyDecl::TypeAliasDecl(TypeAliasDecl {
1085 decl_id: *decl_ref.id(),
1086 })
1087 }
1088}