diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-19 21:06:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-19 21:06:50 +0000 |
commit | 0f4ec11e8c2399ca20f80b4006e294794f9b2e0f (patch) | |
tree | 9631c8dd4a6aeaa85ed2248faae9af02ba370023 | |
parent | abfd358d756b409ce657761d320b04b9383cbfd8 (diff) | |
parent | fdbf789c2bb93baebd449744309d7c42bf2b36b8 (diff) | |
download | gcc-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>
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 7 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 40 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-autoderef.cc | 12 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-autoderef.h | 27 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-coercion.cc | 306 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-coercion.h | 31 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.cc | 19 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-struct.cc | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.cc | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-coercion.h | 1601 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 172 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 50 |
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; |