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