aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-08-18 16:28:49 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-08-19 21:59:00 +0100
commitfdbf789c2bb93baebd449744309d7c42bf2b36b8 (patch)
treecb4de70f42cb25876ff40cafa1ed7907b866eb25 /gcc
parent4f039ff9f6f18d15e32ddb54e3a6124802c45b7f (diff)
downloadgcc-fdbf789c2bb93baebd449744309d7c42bf2b36b8.zip
gcc-fdbf789c2bb93baebd449744309d7c42bf2b36b8.tar.gz
gcc-fdbf789c2bb93baebd449744309d7c42bf2b36b8.tar.bz2
Redo coercion site code
This gets rid of the old visitor method and brings us much closer to the Rustc rules which from the algo mentioned in the comment's do the checks in a very specific order which we need to match.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-base.h7
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc40
-rw-r--r--gcc/rust/backend/rust-compile.cc10
-rw-r--r--gcc/rust/typecheck/rust-autoderef.cc12
-rw-r--r--gcc/rust/typecheck/rust-autoderef.h27
-rw-r--r--gcc/rust/typecheck/rust-coercion.cc306
-rw-r--r--gcc/rust/typecheck/rust-coercion.h31
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc19
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct.cc2
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.cc6
-rw-r--r--gcc/rust/typecheck/rust-tyty-coercion.h1601
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc172
-rw-r--r--gcc/rust/typecheck/rust-tyty.h50
13 files changed, 413 insertions, 1870 deletions
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 5a0ac8f..4c20933 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -48,7 +48,6 @@ protected:
Location rvalue_locus);
tree coerce_to_dyn_object (tree compiled_ref, const TyTy::BaseType *actual,
- const TyTy::BaseType *expected,
const TyTy::DynamicObjectType *ty, Location locus);
tree compute_address_for_trait_item (
@@ -78,6 +77,12 @@ protected:
tree resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus);
+ tree resolve_unsized_slice_adjustment (Resolver::Adjustment &adjustment,
+ tree expression, Location locus);
+
+ tree resolve_unsized_dyn_adjustment (Resolver::Adjustment &adjustment,
+ tree expression, Location locus);
+
static void setup_fndecl (tree fndecl, bool is_main_entry_point,
bool is_generic_fn, HIR::Visibility &visibility,
const HIR::FunctionQualifiers &qualifiers,
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index bfaa7fc..cf82cf4 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1774,6 +1774,27 @@ tree
HIRCompileBase::resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus)
{
+ bool expect_slice
+ = adjustment.get_expected ()->get_kind () == TyTy::TypeKind::SLICE;
+ bool expect_dyn
+ = adjustment.get_expected ()->get_kind () == TyTy::TypeKind::DYNAMIC;
+
+ // assumes this is an array
+ tree expr_type = TREE_TYPE (expression);
+ if (expect_slice)
+ {
+ rust_assert (TREE_CODE (expr_type) == ARRAY_TYPE);
+ return resolve_unsized_slice_adjustment (adjustment, expression, locus);
+ }
+
+ rust_assert (expect_dyn);
+ return resolve_unsized_dyn_adjustment (adjustment, expression, locus);
+}
+
+tree
+HIRCompileBase::resolve_unsized_slice_adjustment (
+ Resolver::Adjustment &adjustment, tree expression, Location locus)
+{
// assumes this is an array
tree expr_type = TREE_TYPE (expression);
rust_assert (TREE_CODE (expr_type) == ARRAY_TYPE);
@@ -1802,6 +1823,25 @@ HIRCompileBase::resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
{data, size}, -1, locus);
}
+tree
+HIRCompileBase::resolve_unsized_dyn_adjustment (
+ Resolver::Adjustment &adjustment, tree expression, Location locus)
+{
+ tree rvalue = expression;
+ Location rvalue_locus = locus;
+
+ const TyTy::BaseType *actual = adjustment.get_actual ();
+ const TyTy::BaseType *expected = adjustment.get_expected ();
+
+ const TyTy::DynamicObjectType *dyn
+ = static_cast<const TyTy::DynamicObjectType *> (expected);
+
+ rust_debug ("resolve_unsized_dyn_adjustment actual={%s} dyn={%s}",
+ actual->debug_str ().c_str (), dyn->debug_str ().c_str ());
+
+ return coerce_to_dyn_object (rvalue, actual, dyn, rvalue_locus);
+}
+
void
CompileExpr::visit (HIR::RangeFromToExpr &expr)
{
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index c4100c4..bf34bb6 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -312,13 +312,6 @@ HIRCompileBase::coercion_site1 (tree rvalue, const TyTy::BaseType *rval,
lvalue_locus, rvalue_locus))
return error_mark_node;
}
- else if (expected->get_kind () == TyTy::TypeKind::DYNAMIC
- && actual->get_kind () != TyTy::TypeKind::DYNAMIC)
- {
- const TyTy::DynamicObjectType *dyn
- = static_cast<const TyTy::DynamicObjectType *> (expected);
- return coerce_to_dyn_object (rvalue, actual, expected, dyn, rvalue_locus);
- }
else if (expected->get_kind () == TyTy::TypeKind::SLICE)
{
// bad coercion
@@ -333,7 +326,7 @@ HIRCompileBase::coercion_site1 (tree rvalue, const TyTy::BaseType *rval,
// return an unsized coercion
Resolver::Adjustment unsize_adj (
- Resolver::Adjustment::AdjustmentType::UNSIZE, expected);
+ Resolver::Adjustment::AdjustmentType::UNSIZE, actual, expected);
return resolve_unsized_adjustment (unsize_adj, rvalue, rvalue_locus);
}
@@ -343,7 +336,6 @@ HIRCompileBase::coercion_site1 (tree rvalue, const TyTy::BaseType *rval,
tree
HIRCompileBase::coerce_to_dyn_object (tree compiled_ref,
const TyTy::BaseType *actual,
- const TyTy::BaseType *expected,
const TyTy::DynamicObjectType *ty,
Location locus)
{
diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index 0025e7e..423f8e4 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -79,7 +79,7 @@ Adjuster::try_deref_type (const TyTy::BaseType *ty,
break;
}
- return Adjustment::get_op_overload_deref_adjustment (adjustment_type,
+ return Adjustment::get_op_overload_deref_adjustment (adjustment_type, ty,
ref_base, fn, impl_item,
requires_ref_adjustment);
}
@@ -95,7 +95,7 @@ Adjuster::try_raw_deref_type (const TyTy::BaseType *ty)
= static_cast<const TyTy::ReferenceType *> (ty);
auto infered = ref_base->get_base ()->clone ();
- return Adjustment (Adjustment::AdjustmentType::INDIRECTION, infered);
+ return Adjustment (Adjustment::AdjustmentType::INDIRECTION, ty, infered);
}
Adjustment
@@ -116,7 +116,7 @@ Adjuster::try_unsize_type (const TyTy::BaseType *ty)
TyTy::TyVar (slice_elem->get_ref ()));
context->insert_implicit_type (slice);
- return Adjustment (Adjustment::AdjustmentType::UNSIZE, slice);
+ return Adjustment (Adjustment::AdjustmentType::UNSIZE, ty, slice);
}
static bool
@@ -373,7 +373,8 @@ AutoderefCycle::try_autoderefed (const TyTy::BaseType *r)
TyTy::ReferenceType *r1
= new TyTy::ReferenceType (r->get_ref (), TyTy::TyVar (r->get_ref ()),
Mutability::Imm);
- adjustments.push_back (Adjustment (Adjustment::AdjustmentType::IMM_REF, r1));
+ adjustments.push_back (
+ Adjustment (Adjustment::AdjustmentType::IMM_REF, r, r1));
if (select (*r1))
return true;
@@ -383,7 +384,8 @@ AutoderefCycle::try_autoderefed (const TyTy::BaseType *r)
TyTy::ReferenceType *r2
= new TyTy::ReferenceType (r->get_ref (), TyTy::TyVar (r->get_ref ()),
Mutability::Mut);
- adjustments.push_back (Adjustment (Adjustment::AdjustmentType::MUT_REF, r2));
+ adjustments.push_back (
+ Adjustment (Adjustment::AdjustmentType::MUT_REF, r, r2));
if (select (*r2))
return true;
diff --git a/gcc/rust/typecheck/rust-autoderef.h b/gcc/rust/typecheck/rust-autoderef.h
index 220b6f4..2f8d64b 100644
--- a/gcc/rust/typecheck/rust-autoderef.h
+++ b/gcc/rust/typecheck/rust-autoderef.h
@@ -40,21 +40,25 @@ public:
};
// ctor for all adjustments except derefs
- Adjustment (AdjustmentType type, const TyTy::BaseType *expected)
- : Adjustment (type, expected, nullptr, nullptr, AdjustmentType::ERROR)
+ Adjustment (AdjustmentType type, const TyTy::BaseType *actual,
+ const TyTy::BaseType *expected)
+ : Adjustment (type, actual, expected, nullptr, nullptr,
+ AdjustmentType::ERROR)
{}
static Adjustment get_op_overload_deref_adjustment (
- AdjustmentType type, const TyTy::BaseType *expected, TyTy::FnType *fn,
- HIR::ImplItem *deref_item,
+ AdjustmentType type, const TyTy::BaseType *actual,
+ const TyTy::BaseType *expected, TyTy::FnType *fn, HIR::ImplItem *deref_item,
Adjustment::AdjustmentType requires_ref_adjustment)
{
rust_assert (type == DEREF || type == DEREF_MUT);
- return Adjustment (type, expected, fn, deref_item, requires_ref_adjustment);
+ return Adjustment (type, actual, expected, fn, deref_item,
+ requires_ref_adjustment);
}
AdjustmentType get_type () const { return type; }
+ const TyTy::BaseType *get_actual () const { return actual; }
const TyTy::BaseType *get_expected () const { return expected; }
std::string as_string () const
@@ -86,7 +90,7 @@ public:
return "";
}
- static Adjustment get_error () { return Adjustment{ERROR, nullptr}; }
+ static Adjustment get_error () { return Adjustment{ERROR, nullptr, nullptr}; }
bool is_error () const { return type == ERROR; }
@@ -106,14 +110,17 @@ public:
HIR::ImplItem *get_deref_hir_item () const { return deref_item; }
private:
- Adjustment (AdjustmentType type, const TyTy::BaseType *expected,
- TyTy::FnType *deref_operator_fn, HIR::ImplItem *deref_item,
+ Adjustment (AdjustmentType type, const TyTy::BaseType *actual,
+ const TyTy::BaseType *expected, TyTy::FnType *deref_operator_fn,
+ HIR::ImplItem *deref_item,
Adjustment::AdjustmentType requires_ref_adjustment)
- : type (type), expected (expected), deref_operator_fn (deref_operator_fn),
- deref_item (deref_item), requires_ref_adjustment (requires_ref_adjustment)
+ : type (type), actual (actual), expected (expected),
+ deref_operator_fn (deref_operator_fn), deref_item (deref_item),
+ requires_ref_adjustment (requires_ref_adjustment)
{}
AdjustmentType type;
+ const TyTy::BaseType *actual;
const TyTy::BaseType *expected;
// - only used for deref operator_overloads
diff --git a/gcc/rust/typecheck/rust-coercion.cc b/gcc/rust/typecheck/rust-coercion.cc
index e6e82c3..b7ef677 100644
--- a/gcc/rust/typecheck/rust-coercion.cc
+++ b/gcc/rust/typecheck/rust-coercion.cc
@@ -22,15 +22,15 @@ namespace Rust {
namespace Resolver {
AutoderefTypeCoercion::CoercionResult
-AutoderefTypeCoercion::Coerce (const TyTy::BaseType *receiver,
- const TyTy::BaseType *expected, Location locus)
+AutoderefTypeCoercion::Coerce (TyTy::BaseType *receiver,
+ TyTy::BaseType *expected, Location locus)
{
AutoderefTypeCoercion resolver (expected, locus);
- bool ok = resolver.cycle (receiver);
+ bool ok = resolver.do_coercion (receiver);
return ok ? resolver.try_result : CoercionResult::get_error ();
}
-AutoderefTypeCoercion::AutoderefTypeCoercion (const TyTy::BaseType *expected,
+AutoderefTypeCoercion::AutoderefTypeCoercion (TyTy::BaseType *expected,
Location locus)
: AutoderefCycle (false), mappings (Analysis::Mappings::get ()),
context (TypeCheckContext::get ()), expected (expected), locus (locus),
@@ -38,43 +38,260 @@ AutoderefTypeCoercion::AutoderefTypeCoercion (const TyTy::BaseType *expected,
{}
bool
-AutoderefTypeCoercion::cycle (const TyTy::BaseType *receiver)
+AutoderefTypeCoercion::do_coercion (TyTy::BaseType *receiver)
{
// FIXME this is not finished and might be super simplified
// see:
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
- if (receiver->get_kind () == TyTy::TypeKind::REF
- && expected->get_kind () == TyTy::TypeKind::REF)
+ // unsize
+ bool unsafe_error = false;
+ CoercionResult unsize_coercion
+ = coerce_unsized (receiver, expected, unsafe_error);
+ bool valid_unsize_coercion = !unsize_coercion.is_error ();
+ if (valid_unsize_coercion)
{
- // if we expect to get a mutable pointer we can't get that from an
- // immutable one so we have to be careful
-
- const auto &receiver_ref
- = static_cast<const TyTy::ReferenceType &> (*receiver);
- const auto &expected_ref
- = static_cast<const TyTy::ReferenceType &> (*expected);
-
- // we can allow for mutability changes here by casting down from
- // mutability eg: mut vs const, we cant take a mutable reference from a
- // const eg: const vs mut we can take a const reference from a mutable
- // one
-
- bool mutability_ok
- = !expected_ref.is_mutable ()
- || (expected_ref.is_mutable () == receiver_ref.is_mutable ());
- if (!mutability_ok)
+ try_result = unsize_coercion;
+ return true;
+ }
+ else if (unsafe_error)
+ {
+ // Location lhs = mappings->lookup_location (receiver->get_ref ());
+ // Location rhs = mappings->lookup_location (expected->get_ref ());
+ // object_unsafe_error (locus, lhs, rhs);
+ return false;
+ }
+
+ // pointers
+ switch (expected->get_kind ())
+ {
+ case TyTy::TypeKind::POINTER: {
+ TyTy::PointerType *ptr = static_cast<TyTy::PointerType *> (expected);
+ try_result = coerce_unsafe_ptr (receiver, ptr, ptr->mutability ());
+ return !try_result.is_error ();
+ }
+
+ case TyTy::TypeKind::REF: {
+ TyTy::ReferenceType *ptr
+ = static_cast<TyTy::ReferenceType *> (expected);
+ try_result
+ = coerce_borrowed_pointer (receiver, ptr, ptr->mutability ());
+ return !try_result.is_error ();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return !try_result.is_error ();
+}
+
+AutoderefTypeCoercion::CoercionResult
+AutoderefTypeCoercion::coerce_unsafe_ptr (TyTy::BaseType *receiver,
+ TyTy::PointerType *expected,
+ Mutability to_mutbl)
+{
+ rust_debug ("coerce_unsafe_ptr(a={%s}, b={%s})",
+ receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
+
+ Mutability from_mutbl = Mutability::Imm;
+ TyTy::BaseType *element = nullptr;
+ switch (receiver->get_kind ())
+ {
+ case TyTy::TypeKind::REF: {
+ TyTy::ReferenceType *ref
+ = static_cast<TyTy::ReferenceType *> (receiver);
+ from_mutbl = ref->mutability ();
+ element = ref->get_base ();
+ }
+ break;
+
+ case TyTy::TypeKind::POINTER: {
+ TyTy::PointerType *ref = static_cast<TyTy::PointerType *> (receiver);
+ from_mutbl = ref->mutability ();
+ element = ref->get_base ();
+ }
+ break;
+
+ default: {
+ TyTy::BaseType *result = receiver->unify (expected);
+ return CoercionResult{{}, result};
+ }
+ }
+
+ if (!coerceable_mutability (from_mutbl, to_mutbl))
+ {
+ Location lhs = mappings->lookup_location (receiver->get_ref ());
+ Location rhs = mappings->lookup_location (expected->get_ref ());
+ mismatched_mutability_error (locus, lhs, rhs);
+ return AutoderefTypeCoercion::CoercionResult::get_error ();
+ }
+
+ TyTy::PointerType *result
+ = new TyTy::PointerType (receiver->get_ref (),
+ TyTy::TyVar (element->get_ref ()), to_mutbl);
+ return CoercionResult{{}, result};
+}
+
+/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
+/// To match `A` with `B`, autoderef will be performed,
+/// calling `deref`/`deref_mut` where necessary.
+AutoderefTypeCoercion::CoercionResult
+AutoderefTypeCoercion::coerce_borrowed_pointer (TyTy::BaseType *receiver,
+ TyTy::ReferenceType *expected,
+ Mutability to_mutbl)
+{
+ rust_debug ("coerce_borrowed_pointer(a={%s}, b={%s})",
+ receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
+
+ Mutability from_mutbl = Mutability::Imm;
+ switch (receiver->get_kind ())
+ {
+ case TyTy::TypeKind::REF: {
+ TyTy::ReferenceType *ref
+ = static_cast<TyTy::ReferenceType *> (receiver);
+ from_mutbl = ref->mutability ();
+ }
+ break;
+
+ default: {
+ TyTy::BaseType *result = receiver->unify (expected);
+ return CoercionResult{{}, result};
+ }
+ }
+
+ if (!coerceable_mutability (from_mutbl, to_mutbl))
+ {
+ Location lhs = mappings->lookup_location (receiver->get_ref ());
+ Location rhs = mappings->lookup_location (expected->get_ref ());
+ mismatched_mutability_error (locus, lhs, rhs);
+ return AutoderefTypeCoercion::CoercionResult::get_error ();
+ }
+
+ AutoderefCycle::cycle (receiver);
+ return try_result;
+}
+
+// &[T; n] or &mut [T; n] -> &[T]
+// or &mut [T; n] -> &mut [T]
+// or &Concrete -> &Trait, etc.
+AutoderefTypeCoercion::CoercionResult
+AutoderefTypeCoercion::coerce_unsized (TyTy::BaseType *source,
+ TyTy::BaseType *target,
+ bool &unsafe_error)
+{
+ rust_debug ("coerce_unsized(source={%s}, target={%s})",
+ source->debug_str ().c_str (), target->debug_str ().c_str ());
+
+ bool source_is_ref = source->get_kind () == TyTy::TypeKind::REF;
+ bool target_is_ref = target->get_kind () == TyTy::TypeKind::REF;
+ bool target_is_ptr = target->get_kind () == TyTy::TypeKind::POINTER;
+
+ bool needs_reborrow = false;
+ TyTy::BaseType *ty_a = source;
+ TyTy::BaseType *ty_b = target;
+ Mutability expected_mutability = Mutability::Imm;
+ if (source_is_ref && target_is_ref)
+ {
+ TyTy::ReferenceType *source_ref
+ = static_cast<TyTy::ReferenceType *> (source);
+ TyTy::ReferenceType *target_ref
+ = static_cast<TyTy::ReferenceType *> (target);
+
+ Mutability from_mutbl = source_ref->mutability ();
+ Mutability to_mutbl = target_ref->mutability ();
+ if (!coerceable_mutability (from_mutbl, to_mutbl))
+ {
+ unsafe_error = true;
+ Location lhs = mappings->lookup_location (source->get_ref ());
+ Location rhs = mappings->lookup_location (target->get_ref ());
+ mismatched_mutability_error (locus, lhs, rhs);
+ return AutoderefTypeCoercion::CoercionResult::get_error ();
+ }
+
+ ty_a = source_ref->get_base ();
+ ty_b = target_ref->get_base ();
+ needs_reborrow = true;
+ expected_mutability = to_mutbl;
+
+ adjustments.push_back (
+ Adjustment (Adjustment::AdjustmentType::INDIRECTION, source_ref, ty_a));
+ }
+ else if (source_is_ref && target_is_ptr)
+ {
+ TyTy::ReferenceType *source_ref
+ = static_cast<TyTy::ReferenceType *> (source);
+ TyTy::PointerType *target_ref = static_cast<TyTy::PointerType *> (target);
+
+ Mutability from_mutbl = source_ref->mutability ();
+ Mutability to_mutbl = target_ref->mutability ();
+ if (!coerceable_mutability (from_mutbl, to_mutbl))
+ {
+ unsafe_error = true;
+ Location lhs = mappings->lookup_location (source->get_ref ());
+ Location rhs = mappings->lookup_location (target->get_ref ());
+ mismatched_mutability_error (locus, lhs, rhs);
+ return AutoderefTypeCoercion::CoercionResult::get_error ();
+ }
+
+ ty_a = source_ref->get_base ();
+ ty_b = target_ref->get_base ();
+ needs_reborrow = true;
+ expected_mutability = to_mutbl;
+
+ adjustments.push_back (
+ Adjustment (Adjustment::AdjustmentType::INDIRECTION, source_ref, ty_a));
+ }
+
+ // FIXME
+ // there is a bunch of code to ensure something is coerce able to a dyn trait
+ // we need to support but we need to support a few more lang items for that
+ // see:
+ // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L582
+
+ const auto a = ty_a;
+ const auto b = ty_b;
+
+ bool expect_dyn = b->get_kind () == TyTy::TypeKind::DYNAMIC;
+ bool need_unsize = a->get_kind () != TyTy::TypeKind::DYNAMIC;
+
+ if (expect_dyn && need_unsize)
+ {
+ bool bounds_compatible = b->bounds_compatible (*a, locus, true);
+ if (!bounds_compatible)
+ {
+ unsafe_error = true;
+ return AutoderefTypeCoercion::CoercionResult::get_error ();
+ }
+
+ // return the unsize coercion
+ TyTy::BaseType *result = b->clone ();
+ // result->set_ref (a->get_ref ());
+
+ // append a dyn coercion adjustment
+ adjustments.push_back (Adjustment (Adjustment::UNSIZE, a, result));
+
+ // reborrow if needed
+ if (needs_reborrow)
{
- RichLocation r (locus);
- r.add_range (mappings->lookup_location (receiver_ref.get_ref ()));
- r.add_range (mappings->lookup_location (expected_ref.get_ref ()));
- rust_error_at (r, "mismatched mutability");
+ TyTy::ReferenceType *reborrow
+ = new TyTy::ReferenceType (source->get_ref (),
+ TyTy::TyVar (result->get_ref ()),
+ expected_mutability);
- return false;
+ Adjustment::AdjustmentType borrow_type
+ = expected_mutability == Mutability::Imm ? Adjustment::IMM_REF
+ : Adjustment::MUT_REF;
+ adjustments.push_back (Adjustment (borrow_type, result, reborrow));
+ result = reborrow;
}
+
+ return CoercionResult{adjustments, result};
}
- return AutoderefCycle::cycle (receiver);
+ adjustments.clear ();
+ return AutoderefTypeCoercion::CoercionResult::get_error ();
}
bool
@@ -88,5 +305,34 @@ AutoderefTypeCoercion::select (const TyTy::BaseType &autoderefed)
return false;
}
+/// Coercing a mutable reference to an immutable works, while
+/// coercing `&T` to `&mut T` should be forbidden.
+bool
+AutoderefTypeCoercion::coerceable_mutability (Mutability from_mutbl,
+ Mutability to_mutbl)
+{
+ return to_mutbl == Mutability::Imm || (from_mutbl == to_mutbl);
+}
+
+void
+AutoderefTypeCoercion::mismatched_mutability_error (Location expr_locus,
+ Location lhs, Location rhs)
+{
+ RichLocation r (expr_locus);
+ r.add_range (lhs);
+ r.add_range (rhs);
+ rust_error_at (r, "mismatched mutability");
+}
+
+void
+AutoderefTypeCoercion::object_unsafe_error (Location expr_locus, Location lhs,
+ Location rhs)
+{
+ RichLocation r (expr_locus);
+ r.add_range (lhs);
+ r.add_range (rhs);
+ rust_error_at (r, "unsafe unsize coercion");
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-coercion.h b/gcc/rust/typecheck/rust-coercion.h
index c3d5d02..f2f440a 100644
--- a/gcc/rust/typecheck/rust-coercion.h
+++ b/gcc/rust/typecheck/rust-coercion.h
@@ -41,23 +41,42 @@ public:
static CoercionResult get_error () { return CoercionResult{{}, nullptr}; }
};
- static CoercionResult Coerce (const TyTy::BaseType *receiver,
- const TyTy::BaseType *expected, Location locus);
+ static CoercionResult Coerce (TyTy::BaseType *receiver,
+ TyTy::BaseType *expected, Location locus);
-protected:
- AutoderefTypeCoercion (const TyTy::BaseType *expected, Location locus);
+ CoercionResult coerce_unsafe_ptr (TyTy::BaseType *receiver,
+ TyTy::PointerType *expected,
+ Mutability mutability);
+
+ CoercionResult coerce_borrowed_pointer (TyTy::BaseType *receiver,
+ TyTy::ReferenceType *expected,
+ Mutability mutability);
+
+ CoercionResult coerce_unsized (TyTy::BaseType *receiver,
+ TyTy::BaseType *expected, bool &unsafe_error);
+
+ static bool coerceable_mutability (Mutability from_mutbl,
+ Mutability to_mutbl);
- bool cycle (const TyTy::BaseType *receiver) override;
+ static void mismatched_mutability_error (Location expr_locus, Location lhs,
+ Location rhs);
+ static void object_unsafe_error (Location expr_locus, Location lhs,
+ Location rhs);
+
+protected:
+ AutoderefTypeCoercion (TyTy::BaseType *expected, Location locus);
bool select (const TyTy::BaseType &autoderefed) override;
+ bool do_coercion (TyTy::BaseType *receiver);
+
private:
// context info
Analysis::Mappings *mappings;
TypeCheckContext *context;
// search
- const TyTy::BaseType *expected;
+ TyTy::BaseType *expected;
Location locus;
// mutable fields
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index e263056..f7b21ea 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -334,6 +334,9 @@ TyTy::BaseType *
TypeCheckBase::coercion_site (HirId id, TyTy::BaseType *expected,
TyTy::BaseType *expr, Location locus)
{
+ rust_debug ("coercion_site id={%u} expected={%s} expr={%s}", id,
+ expected->debug_str ().c_str (), expr->debug_str ().c_str ());
+
auto context = TypeCheckContext::get ();
if (expected->get_kind () == TyTy::TypeKind::ERROR
|| expr->get_kind () == TyTy::TypeKind::ERROR)
@@ -341,14 +344,19 @@ TypeCheckBase::coercion_site (HirId id, TyTy::BaseType *expected,
// can we autoderef it?
auto result = AutoderefTypeCoercion::Coerce (expr, expected, locus);
+
+ // the result needs to be unified
+ TyTy::BaseType *receiver = expr;
if (!result.is_error ())
{
- // save any adjustments
- context->insert_autoderef_mappings (id, std::move (result.adjustments));
- return expected->coerce (result.tyty);
+ receiver = result.tyty;
}
- return expected->coerce (expr);
+ rust_debug ("coerce_default_unify(a={%s}, b={%s})",
+ receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
+ TyTy::BaseType *coerced = expected->unify (receiver);
+ context->insert_autoderef_mappings (id, std::move (result.adjustments));
+ return coerced;
}
void
@@ -374,7 +382,8 @@ TypeCheckBase::resolve_generic_params (
{
auto expr_type = TypeCheckExpr::Resolve (
param->get_default_expression ().get ());
- specified_type->coerce (expr_type);
+
+ specified_type->unify (expr_type);
}
context->insert_type (generic_param->get_mappings (),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index f22b35d..b2261e8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -58,7 +58,7 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields &struct_expr)
TyTy::BaseType *base_resolved
= TypeCheckExpr::Resolve (struct_expr.struct_base->base_struct.get ());
struct_def = static_cast<TyTy::ADTType *> (
- struct_path_resolved->coerce (base_resolved));
+ struct_path_resolved->unify (base_resolved));
if (struct_def == nullptr)
{
rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index b810bd8..1ce82c9 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -136,8 +136,6 @@ TypeCheckCallExpr::visit (FnType &type)
}
}
- context->insert_type (argument->get_mappings (), argument_expr_tyty);
-
i++;
}
@@ -189,8 +187,6 @@ TypeCheckCallExpr::visit (FnPtr &type)
return;
}
- context->insert_type (argument->get_mappings (), argument_expr_tyty);
-
i++;
}
@@ -247,8 +243,6 @@ TypeCheckMethodCallExpr::visit (FnType &type)
return;
}
- context->insert_type (argument->get_mappings (), argument_expr_tyty);
-
i++;
}
diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h
deleted file mode 100644
index ed16365..0000000
--- a/gcc/rust/typecheck/rust-tyty-coercion.h
+++ /dev/null
@@ -1,1601 +0,0 @@
-// Copyright (C) 2020-2022 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#ifndef RUST_TYTY_COERCION_RULES
-#define RUST_TYTY_COERCION_RULES
-
-#include "rust-diagnostics.h"
-#include "rust-tyty.h"
-#include "rust-tyty-visitor.h"
-#include "rust-hir-map.h"
-#include "rust-hir-type-check.h"
-#include "rust-hir-type-bounds.h"
-
-extern ::Backend *
-rust_get_backend ();
-
-namespace Rust {
-namespace TyTy {
-
-class BaseCoercionRules : public TyVisitor
-{
-public:
- virtual ~BaseCoercionRules () {}
-
- virtual BaseType *coerce (BaseType *other)
- {
- if (other->get_kind () == TypeKind::PARAM)
- {
- ParamType *p = static_cast<ParamType *> (other);
- if (p->can_resolve ())
- {
- other = p->resolve ();
- }
- }
- else if (other->get_kind () == TypeKind::PLACEHOLDER)
- {
- PlaceholderType *p = static_cast<PlaceholderType *> (other);
- if (p->can_resolve ())
- {
- other = p->resolve ();
- return get_base ()->coerce (other);
- }
- }
- else if (other->get_kind () == TypeKind::PROJECTION)
- {
- ProjectionType *p = static_cast<ProjectionType *> (other);
- other = p->get ();
- return get_base ()->coerce (other);
- }
-
- other->accept_vis (*this);
- if (resolved->get_kind () == TyTy::TypeKind::ERROR)
- return resolved;
-
- resolved->append_reference (get_base ()->get_ref ());
- resolved->append_reference (other->get_ref ());
- for (auto ref : get_base ()->get_combined_refs ())
- resolved->append_reference (ref);
- for (auto ref : other->get_combined_refs ())
- resolved->append_reference (ref);
-
- bool result_resolved = resolved->get_kind () != TyTy::TypeKind::INFER;
- bool result_is_infer_var = resolved->get_kind () == TyTy::TypeKind::INFER;
- bool results_is_non_general_infer_var
- = (result_is_infer_var
- && (static_cast<InferType *> (resolved))->get_infer_kind ()
- != TyTy::InferType::GENERAL);
- if (result_resolved || results_is_non_general_infer_var)
- {
- for (auto &ref : resolved->get_combined_refs ())
- {
- TyTy::BaseType *ref_tyty = nullptr;
- bool ok = context->lookup_type (ref, &ref_tyty);
- if (!ok)
- continue;
-
- // if any of the types are inference variables lets fix them
- if (ref_tyty->get_kind () == TyTy::TypeKind::INFER)
- {
- context->insert_type (
- Analysis::NodeMapping (mappings->get_current_crate (),
- UNKNOWN_NODEID, ref,
- UNKNOWN_LOCAL_DEFID),
- resolved->clone ());
- }
- }
- }
- return resolved;
- }
-
- virtual void visit (TupleType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ADTType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (InferType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (FnType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (FnPtr &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ArrayType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (SliceType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (BoolType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (IntType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (UintType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (USizeType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ISizeType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (FloatType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ErrorType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (CharType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ReferenceType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (PointerType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ParamType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (StrType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (NeverType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (PlaceholderType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ProjectionType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (DynamicObjectType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
- virtual void visit (ClosureType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- Location base_locus = mappings->lookup_location (get_base ()->get_ref ());
- RichLocation r (ref_locus);
- r.add_range (base_locus);
- rust_error_at (r, "expected [%s] got [%s]",
- get_base ()->as_string ().c_str (),
- type.as_string ().c_str ());
- }
-
-protected:
- BaseCoercionRules (BaseType *base)
- : mappings (Analysis::Mappings::get ()),
- context (Resolver::TypeCheckContext::get ()),
- resolved (new ErrorType (base->get_ref (), base->get_ref ()))
- {}
-
- Analysis::Mappings *mappings;
- Resolver::TypeCheckContext *context;
-
- /* Temporary storage for the result of a unification.
- We could return the result directly instead of storing it in the rule
- object, but that involves modifying the visitor pattern to accommodate
- the return value, which is too complex. */
- BaseType *resolved;
-
-private:
- /* Returns a pointer to the ty that created this rule. */
- virtual BaseType *get_base () = 0;
-};
-
-class InferCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- InferCoercionRules (InferType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (BoolType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (IntType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (UintType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (USizeType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (ISizeType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::INTEGRAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (FloatType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
- || (base->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (ArrayType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (SliceType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (ADTType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (TupleType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (InferType &type) override
- {
- switch (base->get_infer_kind ())
- {
- case InferType::InferTypeKind::GENERAL:
- resolved = type.clone ();
- return;
-
- case InferType::InferTypeKind::INTEGRAL: {
- if (type.get_infer_kind () == InferType::InferTypeKind::INTEGRAL)
- {
- resolved = type.clone ();
- return;
- }
- else if (type.get_infer_kind () == InferType::InferTypeKind::GENERAL)
- {
- resolved = base->clone ();
- return;
- }
- }
- break;
-
- case InferType::InferTypeKind::FLOAT: {
- if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
- {
- resolved = type.clone ();
- return;
- }
- else if (type.get_infer_kind () == InferType::InferTypeKind::GENERAL)
- {
- resolved = base->clone ();
- return;
- }
- }
- break;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (CharType &type) override
- {
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
- }
-
- void visit (ReferenceType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (PointerType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (ParamType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (DynamicObjectType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (ClosureType &type) override
- {
- bool is_valid
- = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL);
- if (is_valid)
- {
- resolved = type.clone ();
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- InferType *base;
-};
-
-class FnCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- FnCoercionRules (FnType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (FnType &type) override
- {
- if (base->num_params () != type.num_params ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- for (size_t i = 0; i < base->num_params (); i++)
- {
- auto a = base->param_at (i).second;
- auto b = type.param_at (i).second;
-
- auto unified_param = a->unify (b);
- if (unified_param == nullptr)
- {
- BaseCoercionRules::visit (type);
- return;
- }
- }
-
- auto unified_return
- = base->get_return_type ()->unify (type.get_return_type ());
- if (unified_return == nullptr)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- FnType *base;
-};
-
-class FnptrCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- FnptrCoercionRules (FnPtr *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (FnPtr &type) override
- {
- auto this_ret_type = base->get_return_type ();
- auto other_ret_type = type.get_return_type ();
- auto unified_result = this_ret_type->unify (other_ret_type);
- if (unified_result == nullptr
- || unified_result->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- if (base->num_params () != type.num_params ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- for (size_t i = 0; i < base->num_params (); i++)
- {
- auto this_param = base->param_at (i);
- auto other_param = type.param_at (i);
- auto unified_param = this_param->unify (other_param);
- if (unified_param == nullptr
- || unified_param->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (FnType &type) override
- {
- auto this_ret_type = base->get_return_type ();
- auto other_ret_type = type.get_return_type ();
- auto unified_result = this_ret_type->unify (other_ret_type);
- if (unified_result == nullptr
- || unified_result->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- if (base->num_params () != type.num_params ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- for (size_t i = 0; i < base->num_params (); i++)
- {
- auto this_param = base->param_at (i);
- auto other_param = type.param_at (i).second;
- auto unified_param = this_param->unify (other_param);
- if (unified_param == nullptr
- || unified_param->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- FnPtr *base;
-};
-
-class ClosureCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- ClosureCoercionRules (ClosureType *base)
- : BaseCoercionRules (base), base (base)
- {}
-
- // TODO
-
-private:
- BaseType *get_base () override { return base; }
-
- ClosureType *base;
-};
-
-class ArrayCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- ArrayCoercionRules (ArrayType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (ArrayType &type) override
- {
- // check base type
- auto base_resolved
- = base->get_element_type ()->unify (type.get_element_type ());
- if (base_resolved == nullptr)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved
- = new ArrayType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus, type.get_capacity_expr (),
- TyVar (base_resolved->get_ref ()));
- }
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- ArrayType *base;
-};
-
-class SliceCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- SliceCoercionRules (SliceType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (SliceType &type) override
- {
- // check base type
- auto base_resolved
- = base->get_element_type ()->unify (type.get_element_type ());
- if (base_resolved == nullptr)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = new SliceType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus,
- TyVar (base_resolved->get_ref ()));
- }
-
- void visit (ArrayType &type) override
- {
- // check base type
- auto base_resolved
- = base->get_element_type ()->unify (type.get_element_type ());
- if (base_resolved == nullptr)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = new SliceType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus,
- TyVar (base_resolved->get_ref ()));
- }
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- SliceType *base;
-};
-
-class BoolCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- BoolCoercionRules (BoolType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (BoolType &type) override
- {
- resolved = new BoolType (type.get_ref (), type.get_ty_ref ());
- }
-
- void visit (InferType &type) override
- {
- switch (type.get_infer_kind ())
- {
- case InferType::InferTypeKind::GENERAL:
- resolved = base->clone ();
- break;
-
- default:
- BaseCoercionRules::visit (type);
- break;
- }
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- BoolType *base;
-};
-
-class IntCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- IntCoercionRules (IntType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (InferType &type) override
- {
- // cant assign a float inference variable
- if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (IntType &type) override
- {
- if (type.get_int_kind () != base->get_int_kind ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved
- = new IntType (type.get_ref (), type.get_ty_ref (), type.get_int_kind ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- IntType *base;
-};
-
-class UintCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- UintCoercionRules (UintType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (InferType &type) override
- {
- // cant assign a float inference variable
- if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (UintType &type) override
- {
- if (type.get_uint_kind () != base->get_uint_kind ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = new UintType (type.get_ref (), type.get_ty_ref (),
- type.get_uint_kind ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- UintType *base;
-};
-
-class FloatCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- FloatCoercionRules (FloatType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () == InferType::InferTypeKind::INTEGRAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (FloatType &type) override
- {
- if (type.get_float_kind () != base->get_float_kind ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = new FloatType (type.get_ref (), type.get_ty_ref (),
- type.get_float_kind ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- FloatType *base;
-};
-
-class ADTCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- ADTCoercionRules (ADTType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (ADTType &type) override
- {
- if (base->get_adt_kind () != type.get_adt_kind ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- if (base->get_identifier ().compare (type.get_identifier ()) != 0)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- if (base->number_of_variants () != type.number_of_variants ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- for (size_t i = 0; i < type.number_of_variants (); ++i)
- {
- TyTy::VariantDef *a = base->get_variants ().at (i);
- TyTy::VariantDef *b = type.get_variants ().at (i);
-
- if (a->num_fields () != b->num_fields ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- for (size_t j = 0; j < a->num_fields (); j++)
- {
- TyTy::StructFieldType *base_field = a->get_field_at_index (j);
- TyTy::StructFieldType *other_field = b->get_field_at_index (j);
-
- TyTy::BaseType *this_field_ty = base_field->get_field_type ();
- TyTy::BaseType *other_field_ty = other_field->get_field_type ();
-
- BaseType *unified_ty = this_field_ty->unify (other_field_ty);
- if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
- return;
- }
- }
-
- // generic args for the unit-struct case
- if (type.is_unit () && base->is_unit ())
- {
- rust_assert (type.get_num_substitutions ()
- == base->get_num_substitutions ());
-
- for (size_t i = 0; i < type.get_num_substitutions (); i++)
- {
- auto &a = base->get_substs ().at (i);
- auto &b = type.get_substs ().at (i);
-
- auto pa = a.get_param_ty ();
- auto pb = b.get_param_ty ();
-
- auto res = pa->unify (pb);
- if (res->get_kind () == TyTy::TypeKind::ERROR)
- {
- return;
- }
- }
- }
-
- resolved = type.clone ();
- }
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- ADTType *base;
-};
-
-class TupleCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- TupleCoercionRules (TupleType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (TupleType &type) override
- {
- if (base->num_fields () != type.num_fields ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- std::vector<TyVar> fields;
- for (size_t i = 0; i < base->num_fields (); i++)
- {
- BaseType *bo = base->get_field (i);
- BaseType *fo = type.get_field (i);
-
- BaseType *unified_ty = bo->unify (fo);
- if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
- return;
-
- fields.push_back (TyVar (unified_ty->get_ref ()));
- }
-
- resolved = new TyTy::TupleType (type.get_ref (), type.get_ty_ref (),
- type.get_ident ().locus, fields);
- }
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- TupleType *base;
-};
-
-class USizeCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- USizeCoercionRules (USizeType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (InferType &type) override
- {
- // cant assign a float inference variable
- if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (USizeType &type) override { resolved = type.clone (); }
-
-private:
- BaseType *get_base () override { return base; }
-
- USizeType *base;
-};
-
-class ISizeCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- ISizeCoercionRules (ISizeType *base) : BaseCoercionRules (base), base (base)
- {}
-
- void visit (InferType &type) override
- {
- // cant assign a float inference variable
- if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (ISizeType &type) override { resolved = type.clone (); }
-
-private:
- BaseType *get_base () override { return base; }
-
- ISizeType *base;
-};
-
-class CharCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- CharCoercionRules (CharType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- resolved->set_ref (type.get_ref ());
- }
-
- void visit (CharType &type) override { resolved = type.clone (); }
-
-private:
- BaseType *get_base () override { return base; }
-
- CharType *base;
-};
-
-class ReferenceCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- ReferenceCoercionRules (ReferenceType *base)
- : BaseCoercionRules (base), base (base)
- {}
-
- void visit (ReferenceType &type) override
- {
- auto base_type = base->get_base ();
- auto other_base_type = type.get_base ();
-
- TyTy::BaseType *base_resolved = base_type->coerce (other_base_type);
- if (base_resolved == nullptr
- || base_resolved->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- // we can allow for mutability changes here by casting down from mutability
- // eg: mut vs const, we cant take a mutable reference from a const
- // eg: const vs mut we can take a const reference from a mutable one
- if (!base->is_mutable () || (base->is_mutable () == type.is_mutable ()))
- {
- resolved = new ReferenceType (base->get_ref (), base->get_ty_ref (),
- TyVar (base_resolved->get_ref ()),
- base->mutability ());
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- ReferenceType *base;
-};
-
-class PointerCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- PointerCoercionRules (PointerType *base)
- : BaseCoercionRules (base), base (base)
- {}
-
- void visit (ReferenceType &type) override
- {
- auto base_type = base->get_base ();
- auto other_base_type = type.get_base ();
-
- TyTy::BaseType *base_resolved = base_type->unify (other_base_type);
- if (base_resolved == nullptr
- || base_resolved->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- // we can allow for mutability changes here by casting down from mutability
- // eg: mut vs const, we cant take a mutable pointer from a const
- // eg: const vs mut we can take a const reference from a mutable one
- if (!base->is_mutable () || (base->is_mutable () == type.is_mutable ()))
- {
- resolved = new PointerType (base->get_ref (), base->get_ty_ref (),
- TyVar (base_resolved->get_ref ()),
- base->mutability ());
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
- void visit (PointerType &type) override
- {
- auto base_type = base->get_base ();
- auto other_base_type = type.get_base ();
-
- TyTy::BaseType *base_resolved = base_type->unify (other_base_type);
- if (base_resolved == nullptr
- || base_resolved->get_kind () == TypeKind::ERROR)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- // we can allow for mutability changes here by casting down from mutability
- // eg: mut vs const, we cant take a mutable pointer from a const one
- // eg: const vs mut we can take a const reference from a mutable one
- if (!base->is_mutable () || (base->is_mutable () == type.is_mutable ()))
- {
- resolved = new PointerType (base->get_ref (), base->get_ty_ref (),
- TyVar (base_resolved->get_ref ()),
- base->mutability ());
- return;
- }
-
- BaseCoercionRules::visit (type);
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- PointerType *base;
-};
-
-class ParamCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- ParamCoercionRules (ParamType *base) : BaseCoercionRules (base), base (base)
- {}
-
- // param types are a placeholder we shouldn't have cases where we unify
- // against it. eg: struct foo<T> { a: T }; When we invoke it we can do either:
- //
- // foo<i32>{ a: 123 }.
- // Then this enforces the i32 type to be referenced on the
- // field via an hirid.
- //
- // rust also allows for a = foo{a:123}; Where we can use an Inference Variable
- // to handle the typing of the struct
- BaseType *coerce (BaseType *other) override final
- {
- if (!base->can_resolve ())
- return BaseCoercionRules::coerce (other);
-
- auto lookup = base->resolve ();
- return lookup->unify (other);
- }
-
- void visit (ParamType &type) override
- {
- if (base->get_symbol ().compare (type.get_symbol ()) != 0)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = type.clone ();
- }
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- ParamType *base;
-};
-
-class StrCoercionRules : public BaseCoercionRules
-{
- // FIXME we will need a enum for the StrType like ByteBuf etc..
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- StrCoercionRules (StrType *base) : BaseCoercionRules (base), base (base) {}
-
- void visit (StrType &type) override { resolved = type.clone (); }
-
-private:
- BaseType *get_base () override { return base; }
-
- StrType *base;
-};
-
-class NeverCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- NeverCoercionRules (NeverType *base) : BaseCoercionRules (base), base (base)
- {}
-
- virtual void visit (NeverType &type) override { resolved = type.clone (); }
-
-private:
- BaseType *get_base () override { return base; }
-
- NeverType *base;
-};
-
-class PlaceholderCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- PlaceholderCoercionRules (PlaceholderType *base)
- : BaseCoercionRules (base), base (base)
- {}
-
- BaseType *coerce (BaseType *other) override final
- {
- if (!base->can_resolve ())
- return BaseCoercionRules::coerce (other);
-
- BaseType *lookup = base->resolve ();
- return lookup->unify (other);
- }
-
- void visit (PlaceholderType &type) override
- {
- if (base->get_symbol ().compare (type.get_symbol ()) != 0)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = type.clone ();
- }
-
- void visit (InferType &type) override
- {
- if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- PlaceholderType *base;
-};
-
-class DynamicCoercionRules : public BaseCoercionRules
-{
- using Rust::TyTy::BaseCoercionRules::visit;
-
-public:
- DynamicCoercionRules (DynamicObjectType *base)
- : BaseCoercionRules (base), base (base)
- {}
-
- void visit (DynamicObjectType &type) override
- {
- if (base->num_specified_bounds () != type.num_specified_bounds ())
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- if (!base->bounds_compatible (type, ref_locus, true))
- {
- BaseCoercionRules::visit (type);
- return;
- }
-
- resolved = base->clone ();
- }
-
- void visit (ADTType &type) override
- {
- Location ref_locus = mappings->lookup_location (type.get_ref ());
- bool ok = base->bounds_compatible (type, ref_locus, true);
- if (!ok)
- return;
-
- resolved = base->clone ();
- }
-
-private:
- BaseType *get_base () override { return base; }
-
- DynamicObjectType *base;
-};
-
-} // namespace TyTy
-} // namespace Rust
-
-#endif // RUST_TYTY_COERCION_RULES
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index daedfc3..24969db 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -23,7 +23,6 @@
#include "rust-hir-type-check-type.h"
#include "rust-tyty-rules.h"
#include "rust-tyty-cmp.h"
-#include "rust-tyty-coercion.h"
#include "rust-tyty-cast.h"
#include "rust-hir-map.h"
#include "rust-substitution-mapper.h"
@@ -419,13 +418,6 @@ InferType::can_eq (const BaseType *other, bool emit_errors) const
}
BaseType *
-InferType::coerce (BaseType *other)
-{
- InferCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
InferType::cast (BaseType *other)
{
InferCastRules r (this);
@@ -527,12 +519,6 @@ ErrorType::can_eq (const BaseType *other, bool emit_errors) const
}
BaseType *
-ErrorType::coerce (BaseType *other)
-{
- return this;
-}
-
-BaseType *
ErrorType::cast (BaseType *other)
{
return this;
@@ -999,13 +985,6 @@ ADTType::unify (BaseType *other)
}
BaseType *
-ADTType::coerce (BaseType *other)
-{
- ADTCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
ADTType::cast (BaseType *other)
{
ADTCastRules r (this);
@@ -1213,13 +1192,6 @@ TupleType::unify (BaseType *other)
}
BaseType *
-TupleType::coerce (BaseType *other)
-{
- TupleCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
TupleType::cast (BaseType *other)
{
TupleCastRules r (this);
@@ -1334,13 +1306,6 @@ FnType::unify (BaseType *other)
}
BaseType *
-FnType::coerce (BaseType *other)
-{
- FnCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
FnType::cast (BaseType *other)
{
FnCastRules r (this);
@@ -1579,13 +1544,6 @@ FnPtr::unify (BaseType *other)
}
BaseType *
-FnPtr::coerce (BaseType *other)
-{
- FnptrCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
FnPtr::cast (BaseType *other)
{
FnptrCastRules r (this);
@@ -1679,17 +1637,11 @@ ClosureType::can_eq (const BaseType *other, bool emit_errors) const
}
BaseType *
-ClosureType::coerce (BaseType *other)
-{
- ClosureCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
ClosureType::cast (BaseType *other)
{
- ClosureCoercionRules r (this);
- return r.coerce (other);
+ // FIXME
+ gcc_unreachable ();
+ return nullptr;
}
bool
@@ -1745,13 +1697,6 @@ ArrayType::unify (BaseType *other)
}
BaseType *
-ArrayType::coerce (BaseType *other)
-{
- ArrayCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
ArrayType::cast (BaseType *other)
{
ArrayCastRules r (this);
@@ -1842,13 +1787,6 @@ SliceType::unify (BaseType *other)
}
BaseType *
-SliceType::coerce (BaseType *other)
-{
- SliceCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
SliceType::cast (BaseType *other)
{
SliceCastRules r (this);
@@ -1939,13 +1877,6 @@ BoolType::unify (BaseType *other)
}
BaseType *
-BoolType::coerce (BaseType *other)
-{
- BoolCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
BoolType::cast (BaseType *other)
{
BoolCastRules r (this);
@@ -2011,13 +1942,6 @@ IntType::unify (BaseType *other)
}
BaseType *
-IntType::coerce (BaseType *other)
-{
- IntCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
IntType::cast (BaseType *other)
{
IntCastRules r (this);
@@ -2094,13 +2018,6 @@ UintType::unify (BaseType *other)
}
BaseType *
-UintType::coerce (BaseType *other)
-{
- UintCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
UintType::cast (BaseType *other)
{
UintCastRules r (this);
@@ -2171,13 +2088,6 @@ FloatType::unify (BaseType *other)
}
BaseType *
-FloatType::coerce (BaseType *other)
-{
- FloatCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
FloatType::cast (BaseType *other)
{
FloatCastRules r (this);
@@ -2240,13 +2150,6 @@ USizeType::unify (BaseType *other)
}
BaseType *
-USizeType::coerce (BaseType *other)
-{
- USizeCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
USizeType::cast (BaseType *other)
{
USizeCastRules r (this);
@@ -2298,13 +2201,6 @@ ISizeType::unify (BaseType *other)
}
BaseType *
-ISizeType::coerce (BaseType *other)
-{
- ISizeCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
ISizeType::cast (BaseType *other)
{
ISizeCastRules r (this);
@@ -2356,13 +2252,6 @@ CharType::unify (BaseType *other)
}
BaseType *
-CharType::coerce (BaseType *other)
-{
- CharCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
CharType::cast (BaseType *other)
{
CharCastRules r (this);
@@ -2415,13 +2304,6 @@ ReferenceType::unify (BaseType *other)
}
BaseType *
-ReferenceType::coerce (BaseType *other)
-{
- ReferenceCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
ReferenceType::cast (BaseType *other)
{
ReferenceCastRules r (this);
@@ -2512,13 +2394,6 @@ PointerType::unify (BaseType *other)
}
BaseType *
-PointerType::coerce (BaseType *other)
-{
- PointerCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
PointerType::cast (BaseType *other)
{
PointerCastRules r (this);
@@ -2623,13 +2498,6 @@ ParamType::unify (BaseType *other)
}
BaseType *
-ParamType::coerce (BaseType *other)
-{
- ParamCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
ParamType::cast (BaseType *other)
{
ParamCastRules r (this);
@@ -2769,13 +2637,6 @@ StrType::unify (BaseType *other)
}
BaseType *
-StrType::coerce (BaseType *other)
-{
- StrCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
StrType::cast (BaseType *other)
{
StrCastRules r (this);
@@ -2821,13 +2682,6 @@ NeverType::unify (BaseType *other)
}
BaseType *
-NeverType::coerce (BaseType *other)
-{
- NeverCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
NeverType::cast (BaseType *other)
{
NeverCastRules r (this);
@@ -2882,13 +2736,6 @@ PlaceholderType::unify (BaseType *other)
}
BaseType *
-PlaceholderType::coerce (BaseType *other)
-{
- PlaceholderCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
PlaceholderType::cast (BaseType *other)
{
PlaceholderCastRules r (this);
@@ -2993,12 +2840,6 @@ ProjectionType::unify (BaseType *other)
}
BaseType *
-ProjectionType::coerce (BaseType *other)
-{
- return base->coerce (other);
-}
-
-BaseType *
ProjectionType::cast (BaseType *other)
{
return base->cast (other);
@@ -3129,13 +2970,6 @@ DynamicObjectType::can_eq (const BaseType *other, bool emit_errors) const
}
BaseType *
-DynamicObjectType::coerce (BaseType *other)
-{
- DynamicCoercionRules r (this);
- return r.coerce (other);
-}
-
-BaseType *
DynamicObjectType::cast (BaseType *other)
{
DynamicCastRules r (this);
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 1a44c75..56a0e05 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -180,9 +180,6 @@ public:
// checks
virtual bool can_eq (const BaseType *other, bool emit_errors) const = 0;
- // this is the base coercion interface for types
- virtual BaseType *coerce (BaseType *other) = 0;
-
// this is the cast interface for TypeCastExpr
virtual BaseType *cast (BaseType *other) = 0;
@@ -350,7 +347,6 @@ public:
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -390,7 +386,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -434,7 +430,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -534,7 +530,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1363,7 +1359,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1500,7 +1496,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1622,7 +1618,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1696,7 +1692,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1762,7 +1758,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1812,7 +1808,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -1859,7 +1855,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -1905,7 +1901,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
IntKind get_int_kind () const { return int_kind; }
@@ -1958,7 +1954,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
UintKind get_uint_kind () const { return uint_kind; }
@@ -2009,7 +2005,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
FloatKind get_float_kind () const { return float_kind; }
@@ -2050,7 +2046,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -2084,7 +2080,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -2118,7 +2114,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -2152,7 +2148,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -2197,7 +2193,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -2285,7 +2281,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;
@@ -2374,7 +2370,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -2416,7 +2412,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -2492,7 +2488,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
BaseType *clone () const final override;
@@ -2550,7 +2546,7 @@ public:
BaseType *unify (BaseType *other) override;
bool can_eq (const BaseType *other, bool emit_errors) const override final;
- BaseType *coerce (BaseType *other) override;
+
BaseType *cast (BaseType *other) override;
bool is_equal (const BaseType &other) const override;