From 89f624877de5431ff4229b5078d56f3cd548a5dd Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Sun, 17 May 2020 17:55:36 +0100 Subject: Initial type comparison code for error: E0308 --- gcc/rust/analysis/rust-resolution.cc | 75 +++++++++++++++++++++++++++++++++--- gcc/rust/analysis/rust-resolution.h | 3 ++ 2 files changed, 73 insertions(+), 5 deletions(-) (limited to 'gcc/rust/analysis') diff --git a/gcc/rust/analysis/rust-resolution.cc b/gcc/rust/analysis/rust-resolution.cc index cb96ef0..0b53d34 100644 --- a/gcc/rust/analysis/rust-resolution.cc +++ b/gcc/rust/analysis/rust-resolution.cc @@ -65,6 +65,14 @@ TypeResolution::go () return true; } +bool +TypeResolution::typesAreCompatible (std::string &lhs, std::string &rhs) const +{ + // FIXME this needs to handle the cases of an i8 going into an i32 which is + // compatible + return lhs.compare (rhs) == 0; +} + void TypeResolution::visit (AST::Token &tok) {} @@ -124,18 +132,21 @@ TypeResolution::visit (AST::TypePathSegmentFunction &segment) void TypeResolution::visit (AST::TypePath &path) { - printf ("TypePath: %s\n", path.as_string ().c_str ()); + // this may not be robust enough for type comparisons but lets try it for now + typeComparisonBuffer.push_back (path.as_string ()); } void TypeResolution::visit (AST::QualifiedPathInExpression &path) { - printf ("QualifiedPathInExpression: %s\n", path.as_string ().c_str ()); + typeComparisonBuffer.push_back (path.as_string ()); } void TypeResolution::visit (AST::QualifiedPathInType &path) -{} +{ + typeComparisonBuffer.push_back (path.as_string ()); +} // rust-expr.h void @@ -245,7 +256,34 @@ TypeResolution::visit (AST::ArithmeticOrLogicalExpr &expr) // scope will require knowledge of the type // do the lhsType and the rhsType match - // TODO + before = typeComparisonBuffer.size (); + lhsType->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (expr.locus, "Failed to unwrap type for lhs"); + return; + } + + before = typeComparisonBuffer.size (); + rhsType->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (expr.locus, "Failed to unwrap type for rhs"); + return; + } + + auto rhsTypeStr = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + auto lhsTypeStr = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + + if (!typesAreCompatible (lhsTypeStr, rhsTypeStr)) + { + rust_error_at (expr.right_expr->get_locus_slow (), + "E0308: expected: %s, found %s", lhsTypeStr.c_str (), + rhsTypeStr.c_str ()); + return; + } } void @@ -288,7 +326,34 @@ TypeResolution::visit (AST::AssignmentExpr &expr) // scope will require knowledge of the type // do the lhsType and the rhsType match - // TODO + before = typeComparisonBuffer.size (); + lhsType->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (expr.locus, "Failed to unwrap type for lhs"); + return; + } + + before = typeComparisonBuffer.size (); + rhsType->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (expr.locus, "Failed to unwrap type for rhs"); + return; + } + + auto rhsTypeStr = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + auto lhsTypeStr = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + + if (!typesAreCompatible (lhsTypeStr, rhsTypeStr)) + { + rust_error_at (expr.right_expr->get_locus_slow (), + "E0308: expected: %s, found %s", lhsTypeStr.c_str (), + rhsTypeStr.c_str ()); + return; + } } void diff --git a/gcc/rust/analysis/rust-resolution.h b/gcc/rust/analysis/rust-resolution.h index cd8eb91..c71871e 100644 --- a/gcc/rust/analysis/rust-resolution.h +++ b/gcc/rust/analysis/rust-resolution.h @@ -225,12 +225,15 @@ private: bool go (); + bool typesAreCompatible (std::string &lhs, std::string &rhs) const; + Scope scope; Scope typeScope; AST::Crate &crate; std::vector letPatternBuffer; std::vector typeBuffer; + std::vector typeComparisonBuffer; }; } // namespace Analysis -- cgit v1.1