aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-19 21:06:50 +0000
committerGitHub <noreply@github.com>2022-08-19 21:06:50 +0000
commit0f4ec11e8c2399ca20f80b4006e294794f9b2e0f (patch)
tree9631c8dd4a6aeaa85ed2248faae9af02ba370023 /gcc
parentabfd358d756b409ce657761d320b04b9383cbfd8 (diff)
parentfdbf789c2bb93baebd449744309d7c42bf2b36b8 (diff)
downloadgcc-0f4ec11e8c2399ca20f80b4006e294794f9b2e0f.zip
gcc-0f4ec11e8c2399ca20f80b4006e294794f9b2e0f.tar.gz
gcc-0f4ec11e8c2399ca20f80b4006e294794f9b2e0f.tar.bz2
Merge #1492
1492: Redo coercion site code r=philberty a=philberty 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. Co-authored-by: Philip Herron <philip.herron@embecosm.com>
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 9a8b779..412ca09 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2514,6 +2514,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);
@@ -2542,6 +2563,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 6913144..0ccb98d 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -161,13 +161,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
@@ -182,7 +175,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);
}
@@ -192,7 +185,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;