From 7a5ba86f9ea3509d2ddf278bce8054ea3d44fd9f Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 19 Dec 2024 16:43:49 +0000 Subject: [PATCH] gccrs: add support for lang_item eq and PartialEq trait TODO Fixes Rust-GCC#3302 gcc/rust/ChangeLog: * backend/rust-compile-expr.cc (CompileExpr::visit): * backend/rust-compile-expr.h: * hir/tree/rust-hir-expr.cc (OperatorExprMeta::OperatorExprMeta): * hir/tree/rust-hir-expr.h: * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): (TypeCheckExpr::resolve_operator_overload): * typecheck/rust-hir-type-check-expr.h: * util/rust-lang-item.cc (LangItem::ComparisonToLangItem): (LangItem::ComparisonToSegment): * util/rust-lang-item.h: Signed-off-by: Philip Herron --- gcc/rust/backend/rust-compile-expr.cc | 28 +++++++++++++-- gcc/rust/backend/rust-compile-expr.h | 4 ++- gcc/rust/hir/tree/rust-hir-expr.cc | 6 ++++ gcc/rust/hir/tree/rust-hir-expr.h | 2 ++ .../typecheck/rust-hir-type-check-expr.cc | 27 +++++++++++--- gcc/rust/typecheck/rust-hir-type-check-expr.h | 4 ++- gcc/rust/util/rust-lang-item.cc | 36 +++++++++++++++++++ gcc/rust/util/rust-lang-item.h | 4 +++ 8 files changed, 102 insertions(+), 9 deletions(-) diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 7323413bfce2..46b9b0adccfd 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -279,6 +279,26 @@ CompileExpr::visit (HIR::ComparisonExpr &expr) auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx); auto location = expr.get_locus (); + // this might be an operator overload situation lets check + TyTy::FnType *fntype; + bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload ( + expr.get_mappings ().get_hirid (), &fntype); + if (is_op_overload) + { + auto seg_name = LangItem::ComparisonToSegment (expr.get_expr_type ()); + auto segment = HIR::PathIdentSegment (seg_name); + auto lang_item_type + = LangItem::ComparisonToLangItem (expr.get_expr_type ()); + + rhs = address_expression (rhs, EXPR_LOCATION (rhs)); + + translated = resolve_operator_overload ( + lang_item_type, expr, lhs, rhs, expr.get_lhs (), + tl::optional> (expr.get_rhs ()), + segment); + return; + } + translated = Backend::comparison_expression (op, lhs, rhs, location); } @@ -1478,7 +1498,8 @@ CompileExpr::get_receiver_from_dyn (const TyTy::DynamicObjectType *dyn, tree CompileExpr::resolve_operator_overload ( LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr, tree lhs, tree rhs, - HIR::Expr &lhs_expr, tl::optional> rhs_expr) + HIR::Expr &lhs_expr, tl::optional> rhs_expr, + HIR::PathIdentSegment specified_segment) { TyTy::FnType *fntype; bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload ( @@ -1499,7 +1520,10 @@ CompileExpr::resolve_operator_overload ( } // lookup compiled functions since it may have already been compiled - HIR::PathIdentSegment segment_name (LangItem::ToString (lang_item_type)); + HIR::PathIdentSegment segment_name + = specified_segment.is_error () + ? HIR::PathIdentSegment (LangItem::ToString (lang_item_type)) + : specified_segment; tree fn_expr = resolve_method_address (fntype, receiver, expr.get_locus ()); // lookup the autoderef mappings diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 9e7af42c64f2..45e0d3c350d0 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -99,7 +99,9 @@ class CompileExpr : private HIRCompileBase, protected HIR::HIRExpressionVisitor tree resolve_operator_overload ( LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr, tree lhs, tree rhs, HIR::Expr &lhs_expr, - tl::optional> rhs_expr); + tl::optional> rhs_expr, + HIR::PathIdentSegment specified_segment + = HIR::PathIdentSegment::create_error ()); tree compile_bool_literal (const HIR::LiteralExpr &expr, const TyTy::BaseType *tyty); diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc index 6c9a7a475e71..95df23d834a4 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.cc +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -1298,6 +1298,12 @@ OperatorExprMeta::OperatorExprMeta (HIR::ArrayIndexExpr &expr) locus (expr.get_locus ()) {} +OperatorExprMeta::OperatorExprMeta (HIR::ComparisonExpr &expr) + : node_mappings (expr.get_mappings ()), + lvalue_mappings (expr.get_expr ().get_mappings ()), + locus (expr.get_locus ()) +{} + AnonConst::AnonConst (NodeId id, std::unique_ptr expr) : id (id), expr (std::move (expr)) { diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index e956108dc53f..46039270f729 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -2816,6 +2816,8 @@ class OperatorExprMeta OperatorExprMeta (HIR::ArrayIndexExpr &expr); + OperatorExprMeta (HIR::ComparisonExpr &expr); + const Analysis::NodeMapping &get_mappings () const { return node_mappings; } const Analysis::NodeMapping &get_lvalue_mappings () const diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 7daa27195db6..1cfd855de0c0 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -344,6 +344,21 @@ TypeCheckExpr::visit (HIR::ComparisonExpr &expr) auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ()); auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); + auto borrwed_rhs + = new TyTy::ReferenceType (mappings.get_next_hir_id (), + TyTy::TyVar (rhs->get_ref ()), Mutability::Imm); + context->insert_implicit_type (borrwed_rhs->get_ref (), borrwed_rhs); + + auto seg_name = LangItem::ComparisonToSegment (expr.get_expr_type ()); + auto segment = HIR::PathIdentSegment (seg_name); + auto lang_item_type = LangItem::ComparisonToLangItem (expr.get_expr_type ()); + + bool operator_overloaded + = resolve_operator_overload (lang_item_type, expr, lhs, borrwed_rhs, + segment); + if (operator_overloaded) + return; + unify_site (expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (lhs, expr.get_lhs ().get_locus ()), TyTy::TyWithLocation (rhs, expr.get_rhs ().get_locus ()), @@ -1638,10 +1653,10 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr) } bool -TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type, - HIR::OperatorExprMeta expr, - TyTy::BaseType *lhs, - TyTy::BaseType *rhs) +TypeCheckExpr::resolve_operator_overload ( + LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr, + TyTy::BaseType *lhs, TyTy::BaseType *rhs, + HIR::PathIdentSegment specified_segment) { // look up lang item for arithmetic type std::string associated_item_name = LangItem::ToString (lang_item_type); @@ -1659,7 +1674,9 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind lang_item_type, current_context = context->peek_context (); } - auto segment = HIR::PathIdentSegment (associated_item_name); + auto segment = specified_segment.is_error () + ? HIR::PathIdentSegment (associated_item_name) + : specified_segment; auto candidates = MethodResolver::Probe (lhs, segment); // remove any recursive candidates diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 51fdd934da5d..3ceef7a521e7 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -97,7 +97,9 @@ class TypeCheckExpr : private TypeCheckBase, private HIR::HIRExpressionVisitor protected: bool resolve_operator_overload (LangItem::Kind lang_item_type, HIR::OperatorExprMeta expr, - TyTy::BaseType *lhs, TyTy::BaseType *rhs); + TyTy::BaseType *lhs, TyTy::BaseType *rhs, + HIR::PathIdentSegment specified_segment + = HIR::PathIdentSegment::create_error ()); bool resolve_fn_trait_call (HIR::CallExpr &expr, TyTy::BaseType *function_tyty, diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc index 0d8a98077d1e..648f6ae2677b 100644 --- a/gcc/rust/util/rust-lang-item.cc +++ b/gcc/rust/util/rust-lang-item.cc @@ -91,6 +91,7 @@ const BiMap Rust::LangItem::lang_items = {{ {"str", Kind::STR}, {"f32_runtime", Kind::F32_RUNTIME}, {"f64_runtime", Kind::F64_RUNTIME}, + {"eq", Kind::EQ}, }}; tl::optional @@ -138,6 +139,41 @@ LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op) rust_unreachable (); } +LangItem::Kind +LangItem::ComparisonToLangItem (ComparisonOperator op) +{ + switch (op) + { + case ComparisonOperator::NOT_EQUAL: + case ComparisonOperator::EQUAL: + return LangItem::Kind::EQ; + + default: + break; + } + + rust_unreachable (); +} + +std::string +LangItem::ComparisonToSegment (ComparisonOperator op) +{ + switch (op) + { + case ComparisonOperator::NOT_EQUAL: + return "ne"; + + case ComparisonOperator::EQUAL: + return "eq"; + + default: + break; + } + + rust_unreachable (); + return std::string (); +} + LangItem::Kind LangItem::CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op) { diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h index bcf41df559e5..c28f92ee81a0 100644 --- a/gcc/rust/util/rust-lang-item.h +++ b/gcc/rust/util/rust-lang-item.h @@ -42,6 +42,7 @@ class LangItem NEGATION, NOT, + EQ, ADD_ASSIGN, SUB_ASSIGN, @@ -126,6 +127,9 @@ class LangItem static Kind CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op); static Kind NegationOperatorToLangItem (NegationOperator op); + static Kind ComparisonToLangItem (ComparisonOperator op); + + static std::string ComparisonToSegment (ComparisonOperator op); }; } // namespace Rust