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, AttributeKind, AttributesMap},
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, 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, type_parameter) in function_decl.type_parameters.iter().enumerate() {
173 ctx.call_site_insert(type_parameter.type_id, call_path.span());
174
175 res.extend(
177 type_parameter
178 .type_id
179 .collect_types_metadata(handler, ctx)?
180 .into_iter()
181 .map(|x| match x {
183 TypeMetadata::UnresolvedType(ident, original_span) => {
184 let span = type_binding
185 .as_ref()
186 .and_then(|type_binding| {
187 type_binding.type_arguments.as_slice().get(idx)
188 })
189 .map(|type_argument| Some(type_argument.span.clone()))
190 .unwrap_or(original_span);
191 TypeMetadata::UnresolvedType(ident, span)
192 }
193 x => x,
194 }),
195 );
196 }
197
198 for content in function_decl.body.contents.iter() {
199 res.append(&mut content.collect_types_metadata(handler, ctx)?);
200 }
201 ctx.call_site_pop();
202 }
203 Tuple { fields } => {
204 for field in fields.iter() {
205 res.append(&mut field.collect_types_metadata(handler, ctx)?);
206 }
207 }
208 AsmExpression { registers, .. } => {
209 for register in registers.iter() {
210 if let Some(init) = register.initializer.as_ref() {
211 res.append(&mut init.collect_types_metadata(handler, ctx)?);
212 }
213 }
214 }
215 StructExpression {
216 fields,
217 instantiation_span,
218 struct_id,
219 ..
220 } => {
221 let struct_decl = decl_engine.get_struct(struct_id);
222 for type_parameter in &struct_decl.type_parameters {
223 ctx.call_site_insert(type_parameter.type_id, instantiation_span.clone());
224 }
225 if let TypeInfo::Struct(decl_ref) = &*ctx.engines.te().get(self.return_type) {
226 let decl = decl_engine.get_struct(decl_ref);
227 for type_parameter in &decl.type_parameters {
228 ctx.call_site_insert(type_parameter.type_id, instantiation_span.clone());
229 }
230 }
231 for field in fields.iter() {
232 res.append(&mut field.value.collect_types_metadata(handler, ctx)?);
233 }
234 }
235 LazyOperator { lhs, rhs, .. } => {
236 res.append(&mut lhs.collect_types_metadata(handler, ctx)?);
237 res.append(&mut rhs.collect_types_metadata(handler, ctx)?);
238 }
239 ArrayExplicit {
240 elem_type: _,
241 contents,
242 } => {
243 for content in contents.iter() {
244 res.append(&mut content.collect_types_metadata(handler, ctx)?);
245 }
246 }
247 ArrayRepeat {
248 elem_type: _,
249 value,
250 length,
251 } => {
252 res.append(&mut value.collect_types_metadata(handler, ctx)?);
253 res.append(&mut length.collect_types_metadata(handler, ctx)?);
254 }
255 ArrayIndex { prefix, index } => {
256 res.append(&mut (**prefix).collect_types_metadata(handler, ctx)?);
257 res.append(&mut (**index).collect_types_metadata(handler, ctx)?);
258 }
259 CodeBlock(block) => {
260 for content in block.contents.iter() {
261 res.append(&mut content.collect_types_metadata(handler, ctx)?);
262 }
263 }
264 MatchExp { desugared, .. } => {
265 res.append(&mut desugared.collect_types_metadata(handler, ctx)?)
266 }
267 IfExp {
268 condition,
269 then,
270 r#else,
271 } => {
272 res.append(&mut condition.collect_types_metadata(handler, ctx)?);
273 res.append(&mut then.collect_types_metadata(handler, ctx)?);
274 if let Some(r#else) = r#else {
275 res.append(&mut r#else.collect_types_metadata(handler, ctx)?);
276 }
277 }
278 StructFieldAccess {
279 prefix,
280 resolved_type_of_parent,
281 ..
282 } => {
283 res.append(&mut prefix.collect_types_metadata(handler, ctx)?);
284 res.append(&mut resolved_type_of_parent.collect_types_metadata(handler, ctx)?);
285 }
286 TupleElemAccess {
287 prefix,
288 resolved_type_of_parent,
289 ..
290 } => {
291 res.append(&mut prefix.collect_types_metadata(handler, ctx)?);
292 res.append(&mut resolved_type_of_parent.collect_types_metadata(handler, ctx)?);
293 }
294 EnumInstantiation {
295 enum_ref,
296 contents,
297 call_path_binding,
298 ..
299 } => {
300 let enum_decl = decl_engine.get_enum(enum_ref);
301 for type_param in enum_decl.type_parameters.iter() {
302 ctx.call_site_insert(type_param.type_id, call_path_binding.inner.suffix.span())
303 }
304 if let Some(contents) = contents {
305 res.append(&mut contents.collect_types_metadata(handler, ctx)?);
306 }
307 for variant in enum_decl.variants.iter() {
308 res.append(
309 &mut variant
310 .type_argument
311 .type_id
312 .collect_types_metadata(handler, ctx)?,
313 );
314 }
315 for type_param in enum_decl.type_parameters.iter() {
316 res.append(&mut type_param.type_id.collect_types_metadata(handler, ctx)?);
317 }
318 }
319 AbiCast { address, .. } => {
320 res.append(&mut address.collect_types_metadata(handler, ctx)?);
321 }
322 IntrinsicFunction(kind) => {
323 res.append(&mut kind.collect_types_metadata(handler, ctx)?);
324 }
325 EnumTag { exp } => {
326 res.append(&mut exp.collect_types_metadata(handler, ctx)?);
327 }
328 UnsafeDowncast {
329 exp,
330 variant,
331 call_path_decl: _,
332 } => {
333 res.append(&mut exp.collect_types_metadata(handler, ctx)?);
334 res.append(
335 &mut variant
336 .type_argument
337 .type_id
338 .collect_types_metadata(handler, ctx)?,
339 );
340 }
341 WhileLoop { condition, body } => {
342 res.append(&mut condition.collect_types_metadata(handler, ctx)?);
343 for content in body.contents.iter() {
344 res.append(&mut content.collect_types_metadata(handler, ctx)?);
345 }
346 }
347 ForLoop { desugared } => {
348 res.append(&mut desugared.collect_types_metadata(handler, ctx)?);
349 }
350 ImplicitReturn(exp) | Return(exp) => {
351 res.append(&mut exp.collect_types_metadata(handler, ctx)?)
352 }
353 Ref(exp) | Deref(exp) => res.append(&mut exp.collect_types_metadata(handler, ctx)?),
354 VariableExpression { .. }
358 | ConstantExpression { .. }
359 | ConfigurableExpression { .. }
360 | ConstGenericExpression { .. }
361 | StorageAccess { .. }
362 | Literal(_)
363 | AbiName(_)
364 | Break
365 | Continue
366 | FunctionParameter => {}
367 Reassignment(reassignment) => {
368 res.append(&mut reassignment.rhs.collect_types_metadata(handler, ctx)?);
369 }
370 }
371 Ok(res)
372 }
373}
374
375impl MaterializeConstGenerics for TyExpression {
376 fn materialize_const_generics(
377 &mut self,
378 engines: &Engines,
379 handler: &Handler,
380 name: &str,
381 value: &TyExpression,
382 ) -> Result<(), ErrorEmitted> {
383 self.return_type
384 .materialize_const_generics(engines, handler, name, value)?;
385 match &mut self.expression {
386 TyExpressionVariant::ConstGenericExpression { decl, .. } => {
387 decl.materialize_const_generics(engines, handler, name, value)
388 }
389 TyExpressionVariant::ImplicitReturn(expr) => {
390 expr.materialize_const_generics(engines, handler, name, value)
391 }
392 TyExpressionVariant::FunctionApplication { arguments, .. } => {
393 for (_, expr) in arguments {
394 expr.materialize_const_generics(engines, handler, name, value)?;
395 }
396
397 Ok(())
398 }
399 TyExpressionVariant::WhileLoop { condition, body } => {
400 condition.materialize_const_generics(engines, handler, name, value)?;
401 body.materialize_const_generics(engines, handler, name, value)
402 }
403 TyExpressionVariant::Reassignment(expr) => expr
404 .rhs
405 .materialize_const_generics(engines, handler, name, value),
406 TyExpressionVariant::ArrayIndex { prefix, index } => {
407 prefix.materialize_const_generics(engines, handler, name, value)?;
408 index.materialize_const_generics(engines, handler, name, value)
409 }
410 TyExpressionVariant::IntrinsicFunction(kind) => {
411 for expr in kind.arguments.iter_mut() {
412 expr.materialize_const_generics(engines, handler, name, value)?;
413 }
414 Ok(())
415 }
416 TyExpressionVariant::Literal(_) | TyExpressionVariant::VariableExpression { .. } => {
417 Ok(())
418 }
419 _ => Err(handler.emit_err(
420 sway_error::error::CompileError::ConstGenericNotSupportedHere {
421 span: self.span.clone(),
422 },
423 )),
424 }
425 }
426}
427
428impl TyExpression {
429 pub(crate) fn error(err: ErrorEmitted, span: Span, engines: &Engines) -> TyExpression {
430 let type_engine = engines.te();
431 TyExpression {
432 expression: TyExpressionVariant::Tuple { fields: vec![] },
433 return_type: type_engine.id_of_error_recovery(err),
434 span,
435 }
436 }
437
438 pub(crate) fn gather_mutability(&self) -> VariableMutability {
440 match &self.expression {
441 TyExpressionVariant::VariableExpression { mutability, .. } => *mutability,
442 _ => VariableMutability::Immutable,
443 }
444 }
445
446 pub(crate) fn extract_literal_value(&self) -> Option<Literal> {
448 self.expression.extract_literal_value()
449 }
450
451 pub(crate) fn check_deprecated(
454 &self,
455 engines: &Engines,
456 handler: &Handler,
457 allow_deprecated: &mut AllowDeprecatedState,
458 ) {
459 fn emit_warning_if_deprecated(
460 attributes: &AttributesMap,
461 span: &Span,
462 handler: &Handler,
463 message: &str,
464 allow_deprecated: &mut AllowDeprecatedState,
465 ) {
466 if allow_deprecated.is_allowed() {
467 return;
468 }
469
470 if let Some(v) = attributes
471 .get(&AttributeKind::Deprecated)
472 .and_then(|x| x.last())
473 {
474 let mut message = message.to_string();
475
476 if let Some(sway_ast::Literal::String(s)) = v
477 .args
478 .iter()
479 .find(|x| x.name.as_str() == "note")
480 .and_then(|x| x.value.as_ref())
481 {
482 message.push_str(": ");
483 message.push_str(s.parsed.as_str());
484 }
485
486 handler.emit_warn(CompileWarning {
487 span: span.clone(),
488 warning_content: Warning::UsingDeprecated { message },
489 })
490 }
491 }
492
493 match &self.expression {
494 TyExpressionVariant::Literal(..) => {}
495 TyExpressionVariant::FunctionApplication {
496 call_path,
497 fn_ref,
498 arguments,
499 ..
500 } => {
501 for (_, expr) in arguments.iter() {
502 expr.check_deprecated(engines, handler, allow_deprecated);
503 }
504
505 let fn_ty = engines.de().get(fn_ref);
506 if let Some(TyDecl::ImplSelfOrTrait(t)) = &fn_ty.implementing_type {
507 let t = &engines.de().get(&t.decl_id).implementing_for;
508 if let TypeInfo::Struct(struct_id) = &*engines.te().get(t.type_id) {
509 let s = engines.de().get(struct_id);
510 emit_warning_if_deprecated(
511 &s.attributes,
512 &call_path.span(),
513 handler,
514 "deprecated struct",
515 allow_deprecated,
516 );
517 }
518 }
519
520 emit_warning_if_deprecated(
521 &fn_ty.attributes,
522 &call_path.span(),
523 handler,
524 "deprecated function",
525 allow_deprecated,
526 );
527 }
528 TyExpressionVariant::LazyOperator { lhs, rhs, .. } => {
529 lhs.check_deprecated(engines, handler, allow_deprecated);
530 rhs.check_deprecated(engines, handler, allow_deprecated);
531 }
532 TyExpressionVariant::ConstantExpression { span, decl, .. } => {
533 emit_warning_if_deprecated(
534 &decl.attributes,
535 span,
536 handler,
537 "deprecated constant",
538 allow_deprecated,
539 );
540 }
541 TyExpressionVariant::ConfigurableExpression { span, decl, .. } => {
542 emit_warning_if_deprecated(
543 &decl.attributes,
544 span,
545 handler,
546 "deprecated configurable",
547 allow_deprecated,
548 );
549 }
550 TyExpressionVariant::ConstGenericExpression { span, .. } => {
551 emit_warning_if_deprecated(
554 &AttributesMap::default(),
555 span,
556 handler,
557 "deprecated configurable",
558 allow_deprecated,
559 );
560 }
561 TyExpressionVariant::VariableExpression { .. } => {}
562 TyExpressionVariant::Tuple { fields } => {
563 for e in fields.iter() {
564 e.check_deprecated(engines, handler, allow_deprecated);
565 }
566 }
567 TyExpressionVariant::ArrayExplicit { contents, .. } => {
568 for e in contents.iter() {
569 e.check_deprecated(engines, handler, allow_deprecated);
570 }
571 }
572 TyExpressionVariant::ArrayRepeat { value, length, .. } => {
573 value.check_deprecated(engines, handler, allow_deprecated);
574 length.check_deprecated(engines, handler, allow_deprecated);
575 }
576 TyExpressionVariant::ArrayIndex { prefix, index } => {
577 prefix.check_deprecated(engines, handler, allow_deprecated);
578 index.check_deprecated(engines, handler, allow_deprecated);
579 }
580 TyExpressionVariant::StructExpression {
581 struct_id,
582 instantiation_span,
583 ..
584 } => {
585 let struct_decl = engines.de().get(struct_id);
586 emit_warning_if_deprecated(
587 &struct_decl.attributes,
588 instantiation_span,
589 handler,
590 "deprecated struct",
591 allow_deprecated,
592 );
593 }
594 TyExpressionVariant::CodeBlock(block) => {
595 block.check_deprecated(engines, handler, allow_deprecated);
596 }
597 TyExpressionVariant::FunctionParameter => {}
598 TyExpressionVariant::MatchExp {
599 desugared,
600 ..
602 } => {
603 desugared.check_deprecated(engines, handler, allow_deprecated);
604 }
606 TyExpressionVariant::IfExp {
607 condition,
608 then,
609 r#else,
610 } => {
611 condition.check_deprecated(engines, handler, allow_deprecated);
612 then.check_deprecated(engines, handler, allow_deprecated);
613 if let Some(e) = r#else {
614 e.check_deprecated(engines, handler, allow_deprecated);
615 }
616 }
617 TyExpressionVariant::AsmExpression { .. } => {}
618 TyExpressionVariant::StructFieldAccess {
619 prefix,
620 field_to_access,
621 field_instantiation_span,
622 ..
623 } => {
624 prefix.check_deprecated(engines, handler, allow_deprecated);
625 emit_warning_if_deprecated(
626 &field_to_access.attributes,
627 field_instantiation_span,
628 handler,
629 "deprecated struct field",
630 allow_deprecated,
631 );
632 }
633 TyExpressionVariant::TupleElemAccess { prefix, .. } => {
634 prefix.check_deprecated(engines, handler, allow_deprecated);
635 }
636 TyExpressionVariant::EnumInstantiation {
637 enum_ref,
638 tag,
639 contents,
640 variant_instantiation_span,
641 ..
642 } => {
643 let enum_ty = engines.de().get(enum_ref);
644 emit_warning_if_deprecated(
645 &enum_ty.attributes,
646 variant_instantiation_span,
647 handler,
648 "deprecated enum",
649 allow_deprecated,
650 );
651 if let Some(variant_decl) = enum_ty.variants.get(*tag) {
652 emit_warning_if_deprecated(
653 &variant_decl.attributes,
654 variant_instantiation_span,
655 handler,
656 "deprecated enum variant",
657 allow_deprecated,
658 );
659 }
660 if let Some(expr) = contents {
661 expr.check_deprecated(engines, handler, allow_deprecated);
662 }
663 }
664 TyExpressionVariant::AbiCast { address, .. } => {
665 address.check_deprecated(engines, handler, allow_deprecated);
667 }
668 TyExpressionVariant::StorageAccess(access) => {
669 if let Some(expr) = &access.key_expression {
671 expr.check_deprecated(engines, handler, allow_deprecated);
672 }
673 }
674 TyExpressionVariant::IntrinsicFunction(kind) => {
675 for arg in kind.arguments.iter() {
676 arg.check_deprecated(engines, handler, allow_deprecated);
677 }
678 }
679 TyExpressionVariant::AbiName(..) => {}
680 TyExpressionVariant::EnumTag { exp } => {
681 exp.check_deprecated(engines, handler, allow_deprecated);
682 }
683 TyExpressionVariant::UnsafeDowncast {
684 exp,
685 ..
687 } => {
688 exp.check_deprecated(engines, handler, allow_deprecated);
689 }
691 TyExpressionVariant::WhileLoop { condition, body } => {
692 condition.check_deprecated(engines, handler, allow_deprecated);
693 body.check_deprecated(engines, handler, allow_deprecated);
694 }
695 TyExpressionVariant::ForLoop { desugared } => {
696 desugared.check_deprecated(engines, handler, allow_deprecated);
697 }
698 TyExpressionVariant::Break => {}
699 TyExpressionVariant::Continue => {}
700 TyExpressionVariant::Reassignment(reass) => {
701 if let TyReassignmentTarget::Deref(expr) = &reass.lhs {
702 expr.check_deprecated(engines, handler, allow_deprecated);
703 }
704 reass
705 .rhs
706 .check_deprecated(engines, handler, allow_deprecated);
707 }
708 TyExpressionVariant::ImplicitReturn(expr) => {
709 expr.check_deprecated(engines, handler, allow_deprecated);
710 }
711 TyExpressionVariant::Return(expr) => {
712 expr.check_deprecated(engines, handler, allow_deprecated);
713 }
714 TyExpressionVariant::Ref(expr) => {
715 expr.check_deprecated(engines, handler, allow_deprecated);
716 }
717 TyExpressionVariant::Deref(expr) => {
718 expr.check_deprecated(engines, handler, allow_deprecated);
719 }
720 }
721 }
722
723 pub fn as_array(&self) -> Option<(&TypeId, &[TyExpression])> {
724 match &self.expression {
725 TyExpressionVariant::ArrayExplicit {
726 elem_type,
727 contents,
728 } => Some((elem_type, contents)),
729 _ => None,
730 }
731 }
732
733 pub(crate) fn as_literal_u64(&self) -> Option<u64> {
734 match &self.expression {
735 TyExpressionVariant::Literal(Literal::U64(v)) => Some(*v),
736 _ => None,
737 }
738 }
739
740 pub fn as_intrinsic(&self) -> Option<&TyIntrinsicFunctionKind> {
741 match &self.expression {
742 TyExpressionVariant::IntrinsicFunction(v) => Some(v),
743 _ => None,
744 }
745 }
746
747 pub fn as_array_unify_elements(&self, handler: &Handler, engines: &Engines) {
750 let TyExpressionVariant::ArrayExplicit {
751 elem_type,
752 contents,
753 } = &self.expression
754 else {
755 unreachable!("Should only be called on Arrays")
756 };
757
758 let array_elem_type = engines.te().get(*elem_type);
759 if !matches!(&*array_elem_type, TypeInfo::Never) {
760 let unify = crate::type_system::unify::unifier::Unifier::new(
761 engines,
762 "",
763 unify::unifier::UnifyKind::Default,
764 );
765 for element in contents {
766 let element_type = engines.te().get(element.return_type);
767
768 if matches!(&*element_type, TypeInfo::Never) {
770 continue;
771 }
772
773 let h = Handler::default();
774 unify.unify(&h, element.return_type, *elem_type, &element.span, true);
775
776 if h.has_errors() {
779 handler.emit_err(CompileError::TypeError(TypeError::MismatchedType {
780 expected: format!("{:?}", engines.help_out(&array_elem_type)),
781 received: format!("{:?}", engines.help_out(element_type)),
782 help_text: String::new(),
783 span: element.span.clone(),
784 }));
785 }
786 }
787 }
788 }
789}