From 168e10562e746d8e3a721e2ad9286e7940636443 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Thu, 17 Aug 2023 08:44:00 -0500 Subject: [PATCH] Fix 'expected T, found T' error on tuple assignment --- .../src/hir/type_check/errors.rs | 26 +++++++-------- .../noirc_frontend/src/hir/type_check/expr.rs | 32 +++++++++---------- .../noirc_frontend/src/hir/type_check/mod.rs | 4 +-- .../noirc_frontend/src/hir/type_check/stmt.rs | 26 +++++++++------ 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/crates/noirc_frontend/src/hir/type_check/errors.rs b/crates/noirc_frontend/src/hir/type_check/errors.rs index 30f65fcbc5c..cd8d87435c9 100644 --- a/crates/noirc_frontend/src/hir/type_check/errors.rs +++ b/crates/noirc_frontend/src/hir/type_check/errors.rs @@ -39,8 +39,8 @@ pub enum TypeCheckError { TypeCannotBeUsed { typ: Type, place: &'static str, span: Span }, #[error("Expected type {expected_typ:?} is not the same as {expr_typ:?}")] TypeMismatch { expected_typ: String, expr_typ: String, expr_span: Span }, - #[error("Expected type {lhs} is not the same as {rhs}")] - TypeMismatchWithSource { lhs: Type, rhs: Type, span: Span, source: Source }, + #[error("Expected type {expected} is not the same as {actual}")] + TypeMismatchWithSource { expected: Type, actual: Type, span: Span, source: Source }, #[error("Expected {expected:?} found {found:?}")] ArityMisMatch { expected: u16, found: u16, span: Span }, #[error("Return type in a function cannot be public")] @@ -193,29 +193,29 @@ impl From for Diagnostic { span, ), TypeCheckError::ResolverError(error) => error.into(), - TypeCheckError::TypeMismatchWithSource { lhs, rhs, span, source } => { + TypeCheckError::TypeMismatchWithSource { expected, actual, span, source } => { let message = match source { - Source::Binary => format!("Types in a binary operation should match, but found {lhs} and {rhs}"), + Source::Binary => format!("Types in a binary operation should match, but found {expected} and {actual}"), Source::Assignment => { - format!("Cannot assign an expression of type {lhs} to a value of type {rhs}") + format!("Cannot assign an expression of type {actual} to a value of type {expected}") } - Source::ArrayElements => format!("Cannot compare {lhs} and {rhs}, the array element types differ"), - Source::ArrayLen => format!("Can only compare arrays of the same length. Here LHS is of length {lhs}, and RHS is {rhs}"), - Source::StringLen => format!("Can only compare strings of the same length. Here LHS is of length {lhs}, and RHS is {rhs}"), - Source::Comparison => format!("Unsupported types for comparison: {lhs} and {rhs}"), - Source::BinOp => format!("Unsupported types for binary operation: {lhs} and {rhs}"), + Source::ArrayElements => format!("Cannot compare {expected} and {actual}, the array element types differ"), + Source::ArrayLen => format!("Can only compare arrays of the same length. Here LHS is of length {expected}, and RHS is {actual}"), + Source::StringLen => format!("Can only compare strings of the same length. Here LHS is of length {expected}, and RHS is {actual}"), + Source::Comparison => format!("Unsupported types for comparison: {expected} and {actual}"), + Source::BinOp => format!("Unsupported types for binary operation: {expected} and {actual}"), Source::Return(ret_ty, expr_span) => { let ret_ty_span = match ret_ty { FunctionReturnType::Default(span) | FunctionReturnType::Ty(_, span) => span }; - let mut diagnostic = Diagnostic::simple_error(format!("expected type {lhs}, found type {rhs}"), format!("expected {lhs} because of return type"), ret_ty_span); + let mut diagnostic = Diagnostic::simple_error(format!("expected type {expected}, found type {actual}"), format!("expected {expected} because of return type"), ret_ty_span); if let FunctionReturnType::Default(_) = ret_ty { - diagnostic.add_note(format!("help: try adding a return type: `-> {rhs}`")); + diagnostic.add_note(format!("help: try adding a return type: `-> {actual}`")); } - diagnostic.add_secondary(format!("{rhs} returned here"), expr_span); + diagnostic.add_secondary(format!("{actual} returned here"), expr_span); return diagnostic }, diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/crates/noirc_frontend/src/hir/type_check/expr.rs index 0f9beed660c..20ecbaa3108 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/crates/noirc_frontend/src/hir/type_check/expr.rs @@ -686,8 +686,8 @@ impl<'interner> TypeChecker<'interner> { Ok(Bool) } else { Err(TypeCheckError::TypeMismatchWithSource { - lhs: lhs_type.clone(), - rhs: rhs_type.clone(), + expected: lhs_type.clone(), + actual: rhs_type.clone(), span, source: Source::Binary, }) @@ -732,15 +732,15 @@ impl<'interner> TypeChecker<'interner> { if matches!(op.kind, Equal | NotEqual) => { self.unify(x_type, y_type, || TypeCheckError::TypeMismatchWithSource { - lhs: lhs_type.clone(), - rhs: rhs_type.clone(), + expected: lhs_type.clone(), + actual: rhs_type.clone(), source: Source::ArrayElements, span: op.location.span, }); self.unify(x_size, y_size, || TypeCheckError::TypeMismatchWithSource { - lhs: lhs_type.clone(), - rhs: rhs_type.clone(), + expected: lhs_type.clone(), + actual: rhs_type.clone(), source: Source::ArrayLen, span: op.location.span, }); @@ -752,16 +752,16 @@ impl<'interner> TypeChecker<'interner> { return Ok(Bool); } Err(TypeCheckError::TypeMismatchWithSource { - lhs: lhs.clone(), - rhs: rhs.clone(), + expected: lhs.clone(), + actual: rhs.clone(), source: Source::Comparison, span, }) } (String(x_size), String(y_size)) => { self.unify(x_size, y_size, || TypeCheckError::TypeMismatchWithSource { - rhs: *x_size.clone(), - lhs: *y_size.clone(), + expected: *x_size.clone(), + actual: *y_size.clone(), span: op.location.span, source: Source::StringLen, }); @@ -769,8 +769,8 @@ impl<'interner> TypeChecker<'interner> { Ok(Bool) } (lhs, rhs) => Err(TypeCheckError::TypeMismatchWithSource { - lhs: lhs.clone(), - rhs: rhs.clone(), + expected: lhs.clone(), + actual: rhs.clone(), source: Source::Comparison, span, }), @@ -936,8 +936,8 @@ impl<'interner> TypeChecker<'interner> { Ok(other.clone()) } else { Err(TypeCheckError::TypeMismatchWithSource { - rhs: lhs_type.clone(), - lhs: rhs_type.clone(), + expected: lhs_type.clone(), + actual: rhs_type.clone(), source: Source::Binary, span, }) @@ -996,8 +996,8 @@ impl<'interner> TypeChecker<'interner> { (Bool, Bool) => Ok(Bool), (lhs, rhs) => Err(TypeCheckError::TypeMismatchWithSource { - rhs: lhs.clone(), - lhs: rhs.clone(), + expected: lhs.clone(), + actual: rhs.clone(), source: Source::BinOp, span, }), diff --git a/crates/noirc_frontend/src/hir/type_check/mod.rs b/crates/noirc_frontend/src/hir/type_check/mod.rs index 4a09139c99c..608dacbbcc7 100644 --- a/crates/noirc_frontend/src/hir/type_check/mod.rs +++ b/crates/noirc_frontend/src/hir/type_check/mod.rs @@ -74,8 +74,8 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec TypeChecker<'interner> { } Type::Error => (), other => { - self.errors.push(TypeCheckError::TypeMismatch { - expected_typ: other.to_string(), - expr_typ: other.to_string(), - expr_span: *span, + let expected = + Type::Tuple(vecmap(fields, |_| self.interner.next_type_variable())); + + self.errors.push(TypeCheckError::TypeMismatchWithSource { + expected, + actual: other, + span: *span, + source: Source::Assignment, }); } }, HirPattern::Struct(struct_type, fields, span) => { - self.unify(struct_type, &typ, || TypeCheckError::TypeMismatch { - expected_typ: typ.to_string(), - expr_typ: struct_type.to_string(), - expr_span: *span, + self.unify(struct_type, &typ, || TypeCheckError::TypeMismatchWithSource { + expected: struct_type.clone(), + actual: typ.clone(), + span: *span, + source: Source::Assignment, }); if let Type::Struct(struct_type, generics) = struct_type { @@ -109,8 +115,8 @@ impl<'interner> TypeChecker<'interner> { let span = self.interner.expr_span(&assign_stmt.expression); self.unify_with_coercions(&expr_type, &lvalue_type, assign_stmt.expression, || { TypeCheckError::TypeMismatchWithSource { - rhs: expr_type.clone(), - lhs: lvalue_type.clone(), + actual: lvalue_type.clone(), + expected: expr_type.clone(), span, source: Source::Assignment, }