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