diff --git a/sway-core/src/language/ty/expression/expression.rs b/sway-core/src/language/ty/expression/expression.rs index 3f4a31b4119..880d3ae17a7 100644 --- a/sway-core/src/language/ty/expression/expression.rs +++ b/sway-core/src/language/ty/expression/expression.rs @@ -110,17 +110,49 @@ impl TypeCheckAnalysis for TyExpression { handler: &Handler, ctx: &mut TypeCheckAnalysisContext, ) -> Result<(), ErrorEmitted> { - // Check literal "fits" into assigned typed. - if let TyExpressionVariant::Literal(Literal::Numeric(literal_value)) = &self.expression { - let t = ctx.engines.te().get(self.return_type); - if let TypeInfo::UnsignedInteger(bits) = &*t { - if bits.would_overflow(*literal_value) { - handler.emit_err(CompileError::TypeError(TypeError::ConstrainedNumeric { - expected: format!("{:?}", ctx.engines.help_out(t)), - span: self.span.clone(), - })); + match &self.expression { + // Check literal "fits" into assigned typed. + TyExpressionVariant::Literal(Literal::Numeric(literal_value)) => { + let t = ctx.engines.te().get(self.return_type); + if let TypeInfo::UnsignedInteger(bits) = &*t { + if bits.would_overflow(*literal_value) { + handler.emit_err(CompileError::TypeError(TypeError::ConstrainedNumeric { + expected: format!("{:?}", ctx.engines.help_out(t)), + span: self.span.clone(), + })); + } } } + // Check all array items are the same + TyExpressionVariant::Array { + elem_type, + contents, + } => { + let eqctx = PartialEqWithEnginesContext::new(ctx.engines); + let array_elem_type = ctx.engines.te().get(*elem_type); + + // If the array element is never, we do not need to check + if !matches!(&*array_elem_type, TypeInfo::Never) { + for element in contents { + let elem_type = ctx.engines.te().get(element.return_type); + + // If the element is never, we do not need to check + if !matches!(&*array_elem_type, TypeInfo::Never) { + continue; + } + + if !array_elem_type.eq(&*elem_type, &eqctx) { + handler.emit_err(CompileError::TypeError(TypeError::MismatchedType { + expected: format!("{:?}", ctx.engines.help_out(&array_elem_type)), + received: format!("{:?}", ctx.engines.help_out(elem_type)), + help_text: String::new(), + span: element.span.clone(), + })); + } + } + } + } + _ => {} } self.expression.type_check_analyze(handler, ctx) } diff --git a/sway-core/src/type_system/mod.rs b/sway-core/src/type_system/mod.rs index 7a3a50d35fe..85407de3a4e 100644 --- a/sway-core/src/type_system/mod.rs +++ b/sway-core/src/type_system/mod.rs @@ -4,7 +4,7 @@ mod id; mod info; mod priv_prelude; mod substitute; -mod unify; +pub(crate) mod unify; #[allow(unused)] use std::ops::Deref; diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/numeric_constraints/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/numeric_constraints/src/main.sw index 11db245bc60..3286688e0b9 100644 --- a/test/src/e2e_vm_tests/test_programs/should_fail/numeric_constraints/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_fail/numeric_constraints/src/main.sw @@ -12,4 +12,7 @@ fn main() { // u32 let _a = 0x100000000; Vec::::new().push(_a); -} \ No newline at end of file + + // Array + let a = [1, 2, "hello"]; +}