1use crate::{
2 decl_engine::*,
3 engine_threading::*,
4 has_changes,
5 language::{ty::*, Literal},
6 semantic_analysis::{
7 TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization,
8 TypeCheckFinalizationContext,
9 },
10 transform::{AllowDeprecatedState, Attributes},
11 type_system::*,
12 types::*,
13};
14use serde::{Deserialize, Serialize};
15use std::{fmt, hash::Hasher};
16use sway_error::{
17 error::CompileError,
18 handler::{ErrorEmitted, Handler},
19 type_error::TypeError,
20 warning::{CompileWarning, DeprecatedElement, Warning},
21};
22use sway_types::{Span, Spanned};
23
24#[derive(Clone, Debug, Serialize, Deserialize)]
25pub struct TyExpression {
26 pub expression: TyExpressionVariant,
27 pub return_type: TypeId,
28 pub span: Span,
29}
30
31impl EqWithEngines for TyExpression {}
32impl PartialEqWithEngines for TyExpression {
33 fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool {
34 let type_engine = ctx.engines().te();
35 self.expression.eq(&other.expression, ctx)
36 && type_engine
37 .get(self.return_type)
38 .eq(&type_engine.get(other.return_type), ctx)
39 }
40}
41
42impl HashWithEngines for TyExpression {
43 fn hash<H: Hasher>(&self, state: &mut H, engines: &Engines) {
44 let TyExpression {
45 expression,
46 return_type,
47 span: _,
50 } = self;
51 let type_engine = engines.te();
52 expression.hash(state, engines);
53 type_engine.get(*return_type).hash(state, engines);
54 }
55}
56
57impl SubstTypes for TyExpression {
58 fn subst_inner(&mut self, ctx: &SubstTypesContext) -> HasChanges {
59 has_changes! {
60 self.return_type.subst(ctx);
61 self.expression.subst(ctx);
62 }
63 }
64}
65
66impl ReplaceDecls for TyExpression {
67 fn replace_decls_inner(
68 &mut self,
69 decl_mapping: &DeclMapping,
70 handler: &Handler,
71 ctx: &mut TypeCheckContext,
72 ) -> Result<bool, ErrorEmitted> {
73 self.expression.replace_decls(decl_mapping, handler, ctx)
74 }
75}
76
77impl UpdateConstantExpression for TyExpression {
78 fn update_constant_expression(&mut self, engines: &Engines, implementing_type: &TyDecl) {
79 self.expression
80 .update_constant_expression(engines, implementing_type)
81 }
82}
83
84impl DisplayWithEngines for TyExpression {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
86 write!(
87 f,
88 "{} ({})",
89 engines.help_out(&self.expression),
90 engines.help_out(self.return_type)
91 )
92 }
93}
94
95impl DebugWithEngines for TyExpression {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>, engines: &Engines) -> fmt::Result {
97 write!(
98 f,
99 "{:?} ({:?})",
100 engines.help_out(&self.expression),
101 engines.help_out(self.return_type)
102 )
103 }
104}
105
106impl TypeCheckAnalysis for TyExpression {
107 fn type_check_analyze(
108 &self,
109 handler: &Handler,
110 ctx: &mut TypeCheckAnalysisContext,
111 ) -> Result<(), ErrorEmitted> {
112 match &self.expression {
113 TyExpressionVariant::Literal(Literal::Numeric(literal_value)) => {
115 let t = ctx.engines.te().get(self.return_type);
116 if let TypeInfo::UnsignedInteger(bits) = &*t {
117 if bits.would_overflow(*literal_value) {
118 handler.emit_err(CompileError::TypeError(TypeError::LiteralOverflow {
119 expected: format!("{:?}", ctx.engines.help_out(t)),
120 span: self.span.clone(),
121 }));
122 }
123 }
124 }
125 TyExpressionVariant::ArrayExplicit { .. } => {
126 self.as_array_unify_elements(handler, ctx.engines);
127 }
128 _ => {}
129 }
130 self.expression.type_check_analyze(handler, ctx)
131 }
132}
133
134impl TypeCheckFinalization for TyExpression {
135 fn type_check_finalize(
136 &mut self,
137 handler: &Handler,
138 ctx: &mut TypeCheckFinalizationContext,
139 ) -> Result<(), ErrorEmitted> {
140 let res = self.expression.type_check_finalize(handler, ctx);
141 if let TyExpressionVariant::FunctionApplication { fn_ref, .. } = &self.expression {
142 let method = ctx.engines.de().get_function(fn_ref);
143 self.return_type = method.return_type.type_id();
144 }
145 res
146 }
147}
148
149impl CollectTypesMetadata for TyExpression {
150 fn collect_types_metadata(
151 &self,
152 handler: &Handler,
153 ctx: &mut CollectTypesMetadataContext,
154 ) -> Result<Vec<TypeMetadata>, ErrorEmitted> {
155 use TyExpressionVariant::*;
156 let decl_engine = ctx.engines.de();
157 let mut res = self.return_type.collect_types_metadata(handler, ctx)?;
158 match &self.expression {
159 FunctionApplication {
160 arguments,
161 fn_ref,
162 call_path,
163 type_binding,
164 ..
165 } => {
166 for arg in arguments.iter() {
167 res.append(&mut arg.1.collect_types_metadata(handler, ctx)?);
168 }
169 let function_decl = decl_engine.get_function(fn_ref);
170
171 ctx.call_site_push();
172 for (idx, p) in function_decl
173 .type_parameters
174 .iter()
175 .filter_map(|x| x.as_type_parameter())
176 .enumerate()
177 {
178 ctx.call_site_insert(p.type_id, call_path.span());
179
180 res.extend(
182 p.type_id
183 .collect_types_metadata(handler, ctx)?
184 .into_iter()
185 .map(|x| match x {
187 TypeMetadata::UnresolvedType(ident, original_span) => {
188 let span = type_binding
189 .as_ref()
190 .and_then(|type_binding| {
191 type_binding.type_arguments.as_slice().get(idx)
192 })
193 .map(|type_argument| Some(type_argument.span()))
194 .unwrap_or(original_span);
195 TypeMetadata::UnresolvedType(ident, span)
196 }
197 x => x,
198 }),
199 );
200 }
201
202 for content in function_decl.body.contents.iter() {
203 res.append(&mut content.collect_types_metadata(handler, ctx)?);
204 }
205 ctx.call_site_pop();
206 }
207 Tuple { fields } => {
208 for field in fields.iter() {
209 res.append(&mut field.collect_types_metadata(handler, ctx)?);
210 }
211 }
212 AsmExpression { registers, .. } => {
213 for register in registers.iter() {
214 if let Some(init) = register.initializer.as_ref() {
215 res.append(&mut init.collect_types_metadata(handler, ctx)?);
216 }
217 }
218 }
219 StructExpression {
220 fields,
221 instantiation_span,
222 struct_id,
223 ..
224 } => {
225 let struct_decl = decl_engine.get_struct(struct_id);
226 for p in &struct_decl.generic_parameters {
227 match p {
228 TypeParameter::Type(p) => {
229 ctx.call_site_insert(p.type_id, instantiation_span.clone());
230 }
231 TypeParameter::Const(_) => {}
232 }
233 }
234 if let TypeInfo::Struct(decl_ref) = &*ctx.engines.te().get(self.return_type) {
235 let decl = decl_engine.get_struct(decl_ref);
236 for p in &decl.generic_parameters {
237 match p {
238 TypeParameter::Type(p) => {
239 ctx.call_site_insert(p.type_id, instantiation_span.clone());
240 }
241 TypeParameter::Const(_) => {}
242 }
243 }
244 }
245 for field in fields.iter() {
246 res.append(&mut field.value.collect_types_metadata(handler, ctx)?);
247 }
248 }
249 LazyOperator { lhs, rhs, .. } => {
250 res.append(&mut lhs.collect_types_metadata(handler, ctx)?);
251 res.append(&mut rhs.collect_types_metadata(handler, ctx)?);
252 }
253 ArrayExplicit {
254 elem_type: _,
255 contents,
256 } => {
257 for content in contents.iter() {
258 res.append(&mut content.collect_types_metadata(handler, ctx)?);
259 }
260 }
261 ArrayRepeat {
262 elem_type: _,
263 value,
264 length,
265 } => {
266 res.append(&mut value.collect_types_metadata(handler, ctx)?);
267 res.append(&mut length.collect_types_metadata(handler, ctx)?);
268 }
269 ArrayIndex { prefix, index } => {
270 res.append(&mut (**prefix).collect_types_metadata(handler, ctx)?);
271 res.append(&mut (**index).collect_types_metadata(handler, ctx)?);
272 }
273 CodeBlock(block) => {
274 for content in block.contents.iter() {
275 res.append(&mut content.collect_types_metadata(handler, ctx)?);
276 }
277 }
278 MatchExp { desugared, .. } => {
279 res.append(&mut desugared.collect_types_metadata(handler, ctx)?)
280 }
281 IfExp {
282 condition,
283 then,
284 r#else,
285 } => {
286 res.append(&mut condition.collect_types_metadata(handler, ctx)?);
287 res.append(&mut then.collect_types_metadata(handler, ctx)?);
288 if let Some(r#else) = r#else {
289 res.append(&mut r#else.collect_types_metadata(handler, ctx)?);
290 }
291 }
292 StructFieldAccess {
293 prefix,
294 resolved_type_of_parent,
295 ..
296 } => {
297 res.append(&mut prefix.collect_types_metadata(handler, ctx)?);
298 res.append(&mut resolved_type_of_parent.collect_types_metadata(handler, ctx)?);
299 }
300 TupleElemAccess {
301 prefix,
302 resolved_type_of_parent,
303 ..
304 } => {
305 res.append(&mut prefix.collect_types_metadata(handler, ctx)?);
306 res.append(&mut resolved_type_of_parent.collect_types_metadata(handler, ctx)?);
307 }
308 EnumInstantiation {
309 enum_ref,
310 contents,
311 call_path_binding,
312 ..
313 } => {
314 let enum_decl = decl_engine.get_enum(enum_ref);
315 for p in enum_decl.generic_parameters.iter() {
316 match p {
317 TypeParameter::Type(p) => {
318 ctx.call_site_insert(p.type_id, call_path_binding.inner.suffix.span())
319 }
320 TypeParameter::Const(_) => {}
321 }
322 }
323 if let Some(contents) = contents {
324 res.append(&mut contents.collect_types_metadata(handler, ctx)?);
325 }
326 for variant in enum_decl.variants.iter() {
327 res.append(
328 &mut variant
329 .type_argument
330 .type_id()
331 .collect_types_metadata(handler, ctx)?,
332 );
333 }
334 for p in enum_decl.generic_parameters.iter() {
335 match p {
336 TypeParameter::Type(p) => {
337 res.append(&mut p.type_id.collect_types_metadata(handler, ctx)?);
338 }
339 TypeParameter::Const(_) => {}
340 }
341 }
342 }
343 AbiCast { address, .. } => {
344 res.append(&mut address.collect_types_metadata(handler, ctx)?);
345 }
346 IntrinsicFunction(kind) => {
347 res.append(&mut kind.collect_types_metadata(handler, ctx)?);
348 }
349 EnumTag { exp } => {
350 res.append(&mut exp.collect_types_metadata(handler, ctx)?);
351 }
352 UnsafeDowncast {
353 exp,
354 variant,
355 call_path_decl: _,
356 } => {
357 res.append(&mut exp.collect_types_metadata(handler, ctx)?);
358 res.append(
359 &mut variant
360 .type_argument
361 .type_id()
362 .collect_types_metadata(handler, ctx)?,
363 );
364 }
365 WhileLoop { condition, body } => {
366 res.append(&mut condition.collect_types_metadata(handler, ctx)?);
367 for content in body.contents.iter() {
368 res.append(&mut content.collect_types_metadata(handler, ctx)?);
369 }
370 }
371 ForLoop { desugared } => {
372 res.append(&mut desugared.collect_types_metadata(handler, ctx)?);
373 }
374 ImplicitReturn(exp) | Return(exp) => {
375 res.append(&mut exp.collect_types_metadata(handler, ctx)?)
376 }
377 Panic(exp) => {
378 let logged_type_id =
380 TypeMetadata::get_logged_type_id(exp, ctx.experimental.new_encoding)
381 .map_err(|err| handler.emit_err(err))?;
382 res.push(TypeMetadata::new_logged_type(
383 ctx.engines,
384 logged_type_id,
385 ctx.program_name.clone(),
386 ));
387
388 res.append(&mut exp.collect_types_metadata(handler, ctx)?)
391 }
392 Ref(exp) | Deref(exp) => res.append(&mut exp.collect_types_metadata(handler, ctx)?),
393 VariableExpression { .. }
397 | ConstantExpression { .. }
398 | ConfigurableExpression { .. }
399 | ConstGenericExpression { .. }
400 | StorageAccess { .. }
401 | Literal(_)
402 | AbiName(_)
403 | Break
404 | Continue
405 | FunctionParameter => {}
406 Reassignment(reassignment) => {
407 res.append(&mut reassignment.rhs.collect_types_metadata(handler, ctx)?);
408 }
409 }
410 Ok(res)
411 }
412}
413
414impl MaterializeConstGenerics for TyExpression {
415 fn materialize_const_generics(
416 &mut self,
417 engines: &Engines,
418 handler: &Handler,
419 name: &str,
420 value: &TyExpression,
421 ) -> Result<(), ErrorEmitted> {
422 self.return_type
423 .materialize_const_generics(engines, handler, name, value)?;
424 match &mut self.expression {
425 TyExpressionVariant::CodeBlock(block) => {
426 for node in block.contents.iter_mut() {
427 node.materialize_const_generics(engines, handler, name, value)?;
428 }
429 Ok(())
430 }
431 TyExpressionVariant::ConstGenericExpression { decl, .. } => {
432 decl.materialize_const_generics(engines, handler, name, value)
433 }
434 TyExpressionVariant::ImplicitReturn(expr) => {
435 expr.materialize_const_generics(engines, handler, name, value)
436 }
437 TyExpressionVariant::FunctionApplication { arguments, .. } => {
438 for (_, expr) in arguments {
439 expr.materialize_const_generics(engines, handler, name, value)?;
440 }
441 Ok(())
442 }
443 TyExpressionVariant::IntrinsicFunction(TyIntrinsicFunctionKind {
444 arguments, ..
445 }) => {
446 for expr in arguments {
447 expr.materialize_const_generics(engines, handler, name, value)?;
448 }
449 Ok(())
450 }
451 TyExpressionVariant::Return(expr) => {
452 expr.materialize_const_generics(engines, handler, name, value)
453 }
454 TyExpressionVariant::IfExp {
455 condition,
456 then,
457 r#else,
458 } => {
459 condition.materialize_const_generics(engines, handler, name, value)?;
460 then.materialize_const_generics(engines, handler, name, value)?;
461 if let Some(e) = r#else.as_mut() {
462 e.materialize_const_generics(engines, handler, name, value)?;
463 }
464 Ok(())
465 }
466 TyExpressionVariant::WhileLoop { condition, body } => {
467 condition.materialize_const_generics(engines, handler, name, value)?;
468 body.materialize_const_generics(engines, handler, name, value)
469 }
470 TyExpressionVariant::Reassignment(expr) => expr
471 .rhs
472 .materialize_const_generics(engines, handler, name, value),
473 TyExpressionVariant::ArrayIndex { prefix, index } => {
474 prefix.materialize_const_generics(engines, handler, name, value)?;
475 index.materialize_const_generics(engines, handler, name, value)
476 }
477 TyExpressionVariant::Literal(_) | TyExpressionVariant::VariableExpression { .. } => {
478 Ok(())
479 }
480 TyExpressionVariant::ArrayRepeat {
481 elem_type,
482 value: elem_value,
483 length,
484 } => {
485 elem_type.materialize_const_generics(engines, handler, name, value)?;
486 elem_value.materialize_const_generics(engines, handler, name, value)?;
487 length.materialize_const_generics(engines, handler, name, value)
488 }
489 TyExpressionVariant::Ref(r) => {
490 r.materialize_const_generics(engines, handler, name, value)
491 }
492 TyExpressionVariant::Deref(r) => {
493 r.materialize_const_generics(engines, handler, name, value)
494 }
495 TyExpressionVariant::MatchExp { desugared, .. } => {
496 desugared.materialize_const_generics(engines, handler, name, value)
497 }
498 TyExpressionVariant::EnumInstantiation { contents, .. } => {
499 if let Some(contents) = contents.as_mut() {
500 contents.materialize_const_generics(engines, handler, name, value)?;
501 }
502 Ok(())
503 }
504 TyExpressionVariant::EnumTag { exp } => {
505 exp.materialize_const_generics(engines, handler, name, value)
506 }
507 TyExpressionVariant::Tuple { fields } => {
508 for f in fields {
509 f.materialize_const_generics(engines, handler, name, value)?;
510 }
511 Ok(())
512 }
513 TyExpressionVariant::TupleElemAccess {
514 prefix,
515 resolved_type_of_parent,
516 ..
517 } => {
518 prefix.materialize_const_generics(engines, handler, name, value)?;
519 resolved_type_of_parent
520 .materialize_const_generics(engines, handler, name, value)?;
521 Ok(())
522 }
523 TyExpressionVariant::LazyOperator { lhs, rhs, .. } => {
524 lhs.materialize_const_generics(engines, handler, name, value)?;
525 rhs.materialize_const_generics(engines, handler, name, value)
526 }
527 TyExpressionVariant::AsmExpression { registers, .. } => {
528 for r in registers.iter_mut() {
529 if let Some(init) = r.initializer.as_mut() {
530 init.materialize_const_generics(engines, handler, name, value)?;
531 }
532 }
533 Ok(())
534 }
535 TyExpressionVariant::ConstantExpression { .. } => Ok(()),
536 TyExpressionVariant::StructExpression { fields, .. } => {
537 for f in fields {
538 f.value
539 .materialize_const_generics(engines, handler, name, value)?;
540 }
541 Ok(())
542 }
543 TyExpressionVariant::StructFieldAccess {
544 prefix,
545 resolved_type_of_parent,
546 ..
547 } => {
548 prefix.materialize_const_generics(engines, handler, name, value)?;
549 resolved_type_of_parent.materialize_const_generics(engines, handler, name, value)
550 }
551 TyExpressionVariant::UnsafeDowncast { exp, .. } => {
552 exp.materialize_const_generics(engines, handler, name, value)
553 }
554 _ => Err(handler.emit_err(
555 sway_error::error::CompileError::ConstGenericNotSupportedHere {
556 span: self.span.clone(),
557 },
558 )),
559 }
560 }
561}
562
563impl TyExpression {
564 pub(crate) fn error(err: ErrorEmitted, span: Span, engines: &Engines) -> TyExpression {
565 let type_engine = engines.te();
566 TyExpression {
567 expression: TyExpressionVariant::Tuple { fields: vec![] },
568 return_type: type_engine.id_of_error_recovery(err),
569 span,
570 }
571 }
572
573 pub(crate) fn gather_mutability(&self) -> VariableMutability {
575 match &self.expression {
576 TyExpressionVariant::VariableExpression { mutability, .. } => *mutability,
577 _ => VariableMutability::Immutable,
578 }
579 }
580
581 pub(crate) fn extract_literal_value(&self) -> Option<Literal> {
583 self.expression.extract_literal_value()
584 }
585
586 pub(crate) fn check_deprecated(
590 &self,
591 engines: &Engines,
592 handler: &Handler,
593 allow_deprecated: &mut AllowDeprecatedState,
594 ) {
595 fn emit_warning_if_deprecated(
596 attributes: &Attributes,
597 span: &Span,
598 handler: &Handler,
599 deprecated_element: DeprecatedElement,
600 deprecated_element_name: &str,
601 allow_deprecated: &mut AllowDeprecatedState,
602 ) {
603 if allow_deprecated.is_allowed() {
604 return;
605 }
606
607 let Some(deprecated_attr) = attributes.deprecated() else {
608 return;
609 };
610
611 let help = deprecated_attr
612 .args
613 .iter()
614 .rfind(|arg| arg.is_deprecated_note())
616 .and_then(|note_arg| match note_arg.get_string_opt(handler) {
617 Ok(note) => note.cloned(),
618 Err(_) => None,
621 });
622
623 handler.emit_warn(CompileWarning {
624 span: span.clone(),
625 warning_content: Warning::UsingDeprecated {
626 deprecated_element,
627 deprecated_element_name: deprecated_element_name.to_string(),
628 help,
629 },
630 })
631 }
632
633 match &self.expression {
634 TyExpressionVariant::Literal(..) => {}
635 TyExpressionVariant::FunctionApplication {
636 call_path,
637 fn_ref,
638 arguments,
639 ..
640 } => {
641 for (_, expr) in arguments {
642 expr.check_deprecated(engines, handler, allow_deprecated);
643 }
644
645 let fn_ty = engines.de().get(fn_ref);
646 if let Some(TyDecl::ImplSelfOrTrait(t)) = &fn_ty.implementing_type {
647 let t = &engines.de().get(&t.decl_id).implementing_for;
648 if let TypeInfo::Struct(struct_id) = &*engines.te().get(t.type_id()) {
649 let s = engines.de().get(struct_id);
650 emit_warning_if_deprecated(
651 &s.attributes,
652 &call_path.span(),
653 handler,
654 DeprecatedElement::Struct,
655 s.call_path.suffix.as_str(),
656 allow_deprecated,
657 );
658 }
659 }
660
661 emit_warning_if_deprecated(
662 &fn_ty.attributes,
663 &call_path.span(),
664 handler,
665 DeprecatedElement::Function,
666 fn_ty.call_path.suffix.as_str(),
667 allow_deprecated,
668 );
669 }
670 TyExpressionVariant::LazyOperator { lhs, rhs, .. } => {
671 lhs.check_deprecated(engines, handler, allow_deprecated);
672 rhs.check_deprecated(engines, handler, allow_deprecated);
673 }
674 TyExpressionVariant::ConstantExpression { span, decl, .. } => {
675 emit_warning_if_deprecated(
676 &decl.attributes,
677 span,
678 handler,
679 DeprecatedElement::Const,
680 decl.call_path.suffix.as_str(),
681 allow_deprecated,
682 );
683 }
684 TyExpressionVariant::ConfigurableExpression { span, decl, .. } => {
685 emit_warning_if_deprecated(
686 &decl.attributes,
687 span,
688 handler,
689 DeprecatedElement::Configurable,
690 decl.call_path.suffix.as_str(),
691 allow_deprecated,
692 );
693 }
694 TyExpressionVariant::ConstGenericExpression { .. } => {}
696 TyExpressionVariant::VariableExpression { .. } => {}
697 TyExpressionVariant::Tuple { fields } => {
698 for e in fields {
699 e.check_deprecated(engines, handler, allow_deprecated);
700 }
701 }
702 TyExpressionVariant::ArrayExplicit { contents, .. } => {
703 for e in contents {
704 e.check_deprecated(engines, handler, allow_deprecated);
705 }
706 }
707 TyExpressionVariant::ArrayRepeat { value, length, .. } => {
708 value.check_deprecated(engines, handler, allow_deprecated);
709 length.check_deprecated(engines, handler, allow_deprecated);
710 }
711 TyExpressionVariant::ArrayIndex { prefix, index } => {
712 prefix.check_deprecated(engines, handler, allow_deprecated);
713 index.check_deprecated(engines, handler, allow_deprecated);
714 }
715 TyExpressionVariant::StructExpression {
716 struct_id,
717 instantiation_span,
718 ..
719 } => {
720 let struct_decl = engines.de().get(struct_id);
721 emit_warning_if_deprecated(
722 &struct_decl.attributes,
723 instantiation_span,
724 handler,
725 DeprecatedElement::Struct,
726 struct_decl.call_path.suffix.as_str(),
727 allow_deprecated,
728 );
729 }
730 TyExpressionVariant::CodeBlock(block) => {
731 block.check_deprecated(engines, handler, allow_deprecated);
732 }
733 TyExpressionVariant::FunctionParameter => {}
734 TyExpressionVariant::MatchExp {
735 desugared,
736 ..
739 } => {
740 desugared.check_deprecated(engines, handler, allow_deprecated);
741 }
742 TyExpressionVariant::IfExp {
743 condition,
744 then,
745 r#else,
746 } => {
747 condition.check_deprecated(engines, handler, allow_deprecated);
748 then.check_deprecated(engines, handler, allow_deprecated);
749 if let Some(e) = r#else {
750 e.check_deprecated(engines, handler, allow_deprecated);
751 }
752 }
753 TyExpressionVariant::AsmExpression { .. } => {}
754 TyExpressionVariant::StructFieldAccess {
755 prefix,
756 field_to_access,
757 field_instantiation_span,
758 ..
759 } => {
760 prefix.check_deprecated(engines, handler, allow_deprecated);
761 emit_warning_if_deprecated(
762 &field_to_access.attributes,
763 field_instantiation_span,
764 handler,
765 DeprecatedElement::StructField,
766 field_to_access.name.as_str(),
767 allow_deprecated,
768 );
769 }
770 TyExpressionVariant::TupleElemAccess { prefix, .. } => {
771 prefix.check_deprecated(engines, handler, allow_deprecated);
772 }
773 TyExpressionVariant::EnumInstantiation {
774 enum_ref,
775 tag,
776 contents,
777 variant_instantiation_span,
778 call_path_binding,
779 ..
780 } => {
781 let enum_ty = engines.de().get(enum_ref);
782 emit_warning_if_deprecated(
783 &enum_ty.attributes,
784 &call_path_binding.span,
786 handler,
787 DeprecatedElement::Enum,
788 enum_ty.call_path.suffix.as_str(),
789 allow_deprecated,
790 );
791 if let Some(variant_decl) = enum_ty.variants.get(*tag) {
792 emit_warning_if_deprecated(
793 &variant_decl.attributes,
794 variant_instantiation_span,
795 handler,
796 DeprecatedElement::EnumVariant,
797 variant_decl.name.as_str(),
798 allow_deprecated,
799 );
800 }
801 if let Some(expr) = contents {
802 expr.check_deprecated(engines, handler, allow_deprecated);
803 }
804 }
805 TyExpressionVariant::AbiCast { address, .. } => {
806 address.check_deprecated(engines, handler, allow_deprecated);
809 }
810 TyExpressionVariant::StorageAccess(access) => {
811 if let Some(expr) = &access.key_expression {
814 expr.check_deprecated(engines, handler, allow_deprecated);
815 }
816 }
817 TyExpressionVariant::IntrinsicFunction(kind) => {
818 for arg in kind.arguments.iter() {
819 arg.check_deprecated(engines, handler, allow_deprecated);
820 }
821 }
822 TyExpressionVariant::AbiName(..) => {}
823 TyExpressionVariant::EnumTag { exp } => {
824 exp.check_deprecated(engines, handler, allow_deprecated);
825 }
826 TyExpressionVariant::UnsafeDowncast {
827 exp,
828 ..
831 } => {
832 exp.check_deprecated(engines, handler, allow_deprecated);
833 }
834 TyExpressionVariant::WhileLoop { condition, body } => {
835 condition.check_deprecated(engines, handler, allow_deprecated);
836 body.check_deprecated(engines, handler, allow_deprecated);
837 }
838 TyExpressionVariant::ForLoop { desugared } => {
839 desugared.check_deprecated(engines, handler, allow_deprecated);
840 }
841 TyExpressionVariant::Break => {}
842 TyExpressionVariant::Continue => {}
843 TyExpressionVariant::Reassignment(reass) => {
844 if let TyReassignmentTarget::DerefAccess { exp, indices } = &reass.lhs {
845 exp.check_deprecated(engines, handler, allow_deprecated);
846 for indice in indices {
847 match indice {
848 ProjectionKind::StructField {
849 name: idx_name,
850 field_to_access,
851 } => {
852 if let Some(field_to_access) = field_to_access {
853 emit_warning_if_deprecated(
854 &field_to_access.attributes,
855 &idx_name.span(),
856 handler,
857 DeprecatedElement::StructField,
858 idx_name.as_str(),
859 allow_deprecated,
860 );
861 }
862 }
863 ProjectionKind::TupleField {
864 index: _,
865 index_span: _,
866 } => {}
867 ProjectionKind::ArrayIndex {
868 index,
869 index_span: _,
870 } => index.check_deprecated(engines, handler, allow_deprecated),
871 }
872 }
873 }
874 reass
877 .rhs
878 .check_deprecated(engines, handler, allow_deprecated);
879 }
880 TyExpressionVariant::ImplicitReturn(expr) => {
881 expr.check_deprecated(engines, handler, allow_deprecated);
882 }
883 TyExpressionVariant::Return(expr) => {
884 expr.check_deprecated(engines, handler, allow_deprecated);
885 }
886 TyExpressionVariant::Panic(expr) => {
887 expr.check_deprecated(engines, handler, allow_deprecated);
888 }
889 TyExpressionVariant::Ref(expr) => {
890 expr.check_deprecated(engines, handler, allow_deprecated);
891 }
892 TyExpressionVariant::Deref(expr) => {
893 expr.check_deprecated(engines, handler, allow_deprecated);
894 }
895 }
896 }
897
898 pub fn as_array(&self) -> Option<(&TypeId, &[TyExpression])> {
899 match &self.expression {
900 TyExpressionVariant::ArrayExplicit {
901 elem_type,
902 contents,
903 } => Some((elem_type, contents)),
904 _ => None,
905 }
906 }
907
908 pub fn as_intrinsic(&self) -> Option<&TyIntrinsicFunctionKind> {
909 match &self.expression {
910 TyExpressionVariant::IntrinsicFunction(v) => Some(v),
911 _ => None,
912 }
913 }
914
915 pub fn as_array_unify_elements(&self, handler: &Handler, engines: &Engines) {
918 let TyExpressionVariant::ArrayExplicit {
919 elem_type,
920 contents,
921 } = &self.expression
922 else {
923 unreachable!("Should only be called on Arrays")
924 };
925
926 let array_elem_type = engines.te().get(*elem_type);
927 if !matches!(&*array_elem_type, TypeInfo::Never) {
928 let unify = crate::type_system::unify::unifier::Unifier::new(
929 engines,
930 "",
931 unify::unifier::UnifyKind::Default,
932 );
933 for element in contents {
934 let element_type = engines.te().get(element.return_type);
935
936 if matches!(&*element_type, TypeInfo::Never) {
938 continue;
939 }
940
941 let h = Handler::default();
942 unify.unify(&h, element.return_type, *elem_type, &element.span, true);
943
944 if h.has_errors() {
947 handler.emit_err(CompileError::TypeError(TypeError::MismatchedType {
948 expected: format!("{:?}", engines.help_out(&array_elem_type)),
949 received: format!("{:?}", engines.help_out(element_type)),
950 help_text: String::new(),
951 span: element.span.clone(),
952 }));
953 }
954 }
955 }
956 }
957}