Skip to content

Commit

Permalink
gccrs: add support for lang_item eq and PartialEq trait
Browse files Browse the repository at this point in the history
TODO

Fixes #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 <[email protected]>
  • Loading branch information
philberty committed Dec 19, 2024
1 parent daa2977 commit 7a5ba86
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 9 deletions.
28 changes: 26 additions & 2 deletions gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::reference_wrapper<HIR::Expr>> (expr.get_rhs ()),
segment);
return;
}

translated = Backend::comparison_expression (op, lhs, rhs, location);
}

Expand Down Expand Up @@ -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<std::reference_wrapper<HIR::Expr>> rhs_expr)
HIR::Expr &lhs_expr, tl::optional<std::reference_wrapper<HIR::Expr>> rhs_expr,
HIR::PathIdentSegment specified_segment)
{
TyTy::FnType *fntype;
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion gcc/rust/backend/rust-compile-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::reference_wrapper<HIR::Expr>> rhs_expr);
tl::optional<std::reference_wrapper<HIR::Expr>> rhs_expr,
HIR::PathIdentSegment specified_segment
= HIR::PathIdentSegment::create_error ());

tree compile_bool_literal (const HIR::LiteralExpr &expr,
const TyTy::BaseType *tyty);
Expand Down
6 changes: 6 additions & 0 deletions gcc/rust/hir/tree/rust-hir-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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> expr)
: id (id), expr (std::move (expr))
{
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/hir/tree/rust-hir-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 22 additions & 5 deletions gcc/rust/typecheck/rust-hir-type-check-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()),
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion gcc/rust/typecheck/rust-hir-type-check-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
36 changes: 36 additions & 0 deletions gcc/rust/util/rust-lang-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{
{"str", Kind::STR},
{"f32_runtime", Kind::F32_RUNTIME},
{"f64_runtime", Kind::F64_RUNTIME},
{"eq", Kind::EQ},
}};

tl::optional<LangItem::Kind>
Expand Down Expand Up @@ -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)
{
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/util/rust-lang-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class LangItem

NEGATION,
NOT,
EQ,

ADD_ASSIGN,
SUB_ASSIGN,
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 7a5ba86

Please sign in to comment.