mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
gccrs: Refactor unify to hit a unify_site
This allows us to enforce better error handling on unify sites gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::unify_site): Add better unification function with debug calls. * typecheck/rust-autoderef.cc (AutoderefCycle::cycle): Add more debug calls and use new unify API. * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Likewise. (TypeCoercionRules::coerce_borrowed_pointer): Likewise. (TypeCoercionRules::select): Likewise. * typecheck/rust-hir-dot-operator.cc (MethodResolver::select): Likewise. * typecheck/rust-hir-trait-resolve.cc (TraitItemReference::resolve_item): Likewise. (TypeCheckBase::coercion_site): Likewise. (TypeCheckBase::cast_site): Likewise. * typecheck/rust-hir-type-check-base.h: Likewise. * typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::visit): Likewise. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelImplItem::visit): Likewise. (TypeCheckImplItem::visit): Likewise. * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Likewise. * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): Likewise. * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): Likewise. * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): Likewise. * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::resolve): Likewise. * typecheck/rust-hir-type-check-toplevel.cc (TypeCheckTopLevel::visit): Likewise. * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): Likewise. * typecheck/rust-hir-type-check.cc (TypeResolution::Resolve): Likewise. * typecheck/rust-tyctx.cc (TypeCheckContext::peek_return_type): Likewise. * typecheck/rust-tyty-call.cc (TypeCheckMethodCallExpr::visit): Likewise. * typecheck/rust-tyty-cmp.h: Likewise. * typecheck/rust-tyty-rules.h: Likewise. * typecheck/rust-tyty.cc (BaseType::mappings_str): Likewise. (BaseType::debug): Print type name more clearly. (BaseType::debug_str): Add new function to print type pointer and name. (TupleType::get_name): Improve type name fetching function. (ReferenceType::get_name): Likewise. (PointerType::get_name): Likewise. * typecheck/rust-tyty.h: Refactor definitions outside of the header. gcc/testsuite/ChangeLog: * rust/compile/issue-1152.rs: Fix dejagnu assertion. * rust/compile/tuple1.rs: Likewise. * rust/compile/type-alias1.rs: Likewise. * rust/execute/torture/operator_overload_9.rs: Likewise. * rust/execute/torture/slice1.rs: Rework test to use new parsing capability and stick to the original implementation.
This commit is contained in:
committed by
Arthur Cohen
parent
af22b54af5
commit
7ad24d802e
@@ -255,7 +255,12 @@ resolve_operator_overload_fn (
|
||||
lookup = fn->infer_substitions (Location ());
|
||||
rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
|
||||
fn = static_cast<TyTy::FnType *> (lookup);
|
||||
fn->get_self_type ()->unify (adjusted_self);
|
||||
|
||||
Location unify_locus = mappings->lookup_location (ty->get_ref ());
|
||||
TypeCheckBase::unify_site (
|
||||
ty->get_ref (), TyTy::TyWithLocation (fn->get_self_type ()),
|
||||
TyTy::TyWithLocation (adjusted_self), unify_locus);
|
||||
|
||||
lookup = fn;
|
||||
}
|
||||
}
|
||||
@@ -284,6 +289,7 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver)
|
||||
const TyTy::BaseType *r = receiver;
|
||||
while (true)
|
||||
{
|
||||
rust_debug ("autoderef try 1: {%s}", r->debug_str ().c_str ());
|
||||
if (try_autoderefed (r))
|
||||
return true;
|
||||
|
||||
@@ -292,12 +298,15 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver)
|
||||
return false;
|
||||
|
||||
// try unsize
|
||||
|
||||
Adjustment unsize = Adjuster::try_unsize_type (r);
|
||||
if (!unsize.is_error ())
|
||||
{
|
||||
adjustments.push_back (unsize);
|
||||
auto unsize_r = unsize.get_expected ();
|
||||
|
||||
rust_debug ("autoderef try unsize: {%s}",
|
||||
unsize_r->debug_str ().c_str ());
|
||||
if (try_autoderefed (unsize_r))
|
||||
return true;
|
||||
|
||||
@@ -311,6 +320,8 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver)
|
||||
auto deref_r = deref.get_expected ();
|
||||
adjustments.push_back (deref);
|
||||
|
||||
rust_debug ("autoderef try lang-item DEREF: {%s}",
|
||||
deref_r->debug_str ().c_str ());
|
||||
if (try_autoderefed (deref_r))
|
||||
return true;
|
||||
|
||||
@@ -324,6 +335,8 @@ AutoderefCycle::cycle (const TyTy::BaseType *receiver)
|
||||
auto deref_r = deref_mut.get_expected ();
|
||||
adjustments.push_back (deref_mut);
|
||||
|
||||
rust_debug ("autoderef try lang-item DEREF_MUT: {%s}",
|
||||
deref_r->debug_str ().c_str ());
|
||||
if (try_autoderefed (deref_r))
|
||||
return true;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
// along with GCC; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "rust-hir-type-check-base.h"
|
||||
#include "rust-coercion.h"
|
||||
|
||||
namespace Rust {
|
||||
@@ -53,6 +54,49 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
|
||||
// see:
|
||||
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
|
||||
|
||||
// handle never
|
||||
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
|
||||
if (receiver->get_kind () == TyTy::TypeKind::NEVER)
|
||||
{
|
||||
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
|
||||
// type variable, we want `?T` to fallback to `!` if not
|
||||
// otherwise constrained. An example where this arises:
|
||||
//
|
||||
// let _: Option<?T> = Some({ return; });
|
||||
//
|
||||
// here, we would coerce from `!` to `?T`.
|
||||
if (expected->has_subsititions_defined () && !expected->is_concrete ())
|
||||
{
|
||||
Location locus = mappings->lookup_location (receiver->get_ref ());
|
||||
TyTy::TyVar implicit_var
|
||||
= TyTy::TyVar::get_implicit_infer_var (locus);
|
||||
try_result = CoercionResult{{}, implicit_var.get_tyty ()};
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool expected_is_infer_var
|
||||
= expected->get_kind () == TyTy::TypeKind::INFER;
|
||||
bool expected_is_general_infer_var
|
||||
= expected_is_infer_var
|
||||
&& (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
|
||||
== TyTy::InferType::InferTypeKind::GENERAL);
|
||||
|
||||
// FIXME this 'expected_is_general_infer_var' case needs to eventually
|
||||
// should go away see: compile/never_type_err1.rs
|
||||
//
|
||||
// I think we need inference obligations to say that yes we have a
|
||||
// general inference variable but we add the oligation to the expected
|
||||
// type that it could default to '!'
|
||||
if (expected_is_general_infer_var)
|
||||
try_result = CoercionResult{{}, receiver};
|
||||
else
|
||||
try_result = CoercionResult{{}, expected->clone ()};
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// unsize
|
||||
bool unsafe_error = false;
|
||||
CoercionResult unsize_coercion
|
||||
@@ -163,13 +207,17 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
|
||||
switch (receiver->get_kind ())
|
||||
{
|
||||
case TyTy::TypeKind::REF: {
|
||||
TyTy::ReferenceType *ref
|
||||
TyTy::ReferenceType *from
|
||||
= static_cast<TyTy::ReferenceType *> (receiver);
|
||||
from_mutbl = ref->mutability ();
|
||||
from_mutbl = from->mutability ();
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
// FIXME
|
||||
// we might be able to replace this with a can_eq because we default
|
||||
// back to a final unity anyway
|
||||
rust_debug ("coerce_borrowed_pointer -- unify");
|
||||
TyTy::BaseType *result = receiver->unify (expected);
|
||||
return CoercionResult{{}, result};
|
||||
}
|
||||
@@ -183,7 +231,12 @@ TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
|
||||
return TypeCoercionRules::CoercionResult::get_error ();
|
||||
}
|
||||
|
||||
rust_debug ("coerce_borrowed_pointer -- autoderef cycle");
|
||||
AutoderefCycle::cycle (receiver);
|
||||
rust_debug ("coerce_borrowed_pointer -- result: [%s] with adjustments: [%zu]",
|
||||
try_result.is_error () ? "failed" : "matched",
|
||||
try_result.adjustments.size ());
|
||||
|
||||
return try_result;
|
||||
}
|
||||
|
||||
@@ -310,7 +363,10 @@ TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
|
||||
bool
|
||||
TypeCoercionRules::select (const TyTy::BaseType &autoderefed)
|
||||
{
|
||||
if (autoderefed.can_eq (expected, false))
|
||||
rust_debug (
|
||||
"autoderef type-coercion select autoderefed={%s} can_eq expected={%s}",
|
||||
autoderefed.debug_str ().c_str (), expected->debug_str ().c_str ());
|
||||
if (expected->can_eq (&autoderefed, false))
|
||||
{
|
||||
try_result = CoercionResult{adjustments, autoderefed.clone ()};
|
||||
return true;
|
||||
|
||||
@@ -171,12 +171,21 @@ MethodResolver::select (const TyTy::BaseType &receiver)
|
||||
TyTy::FnType *fntype;
|
||||
};
|
||||
|
||||
rust_debug ("inherent_impl_fns found {%lu}, trait_fns found {%lu}, "
|
||||
"predicate_items found {%lu}",
|
||||
(unsigned long) inherent_impl_fns.size (),
|
||||
(unsigned long) trait_fns.size (),
|
||||
(unsigned long) predicate_items.size ());
|
||||
|
||||
for (auto impl_item : inherent_impl_fns)
|
||||
{
|
||||
TyTy::FnType *fn = impl_item.ty;
|
||||
rust_assert (fn->is_method ());
|
||||
|
||||
TyTy::BaseType *fn_self = fn->get_self_type ();
|
||||
rust_debug ("dot-operator impl_item fn_self={%s} can_eq receiver={%s}",
|
||||
fn_self->debug_str ().c_str (),
|
||||
receiver.debug_str ().c_str ());
|
||||
if (fn_self->can_eq (&receiver, false))
|
||||
{
|
||||
PathProbeCandidate::ImplItemCandidate c{impl_item.item,
|
||||
@@ -195,6 +204,9 @@ MethodResolver::select (const TyTy::BaseType &receiver)
|
||||
rust_assert (fn->is_method ());
|
||||
|
||||
TyTy::BaseType *fn_self = fn->get_self_type ();
|
||||
rust_debug ("dot-operator trait_item fn_self={%s} can_eq receiver={%s}",
|
||||
fn_self->debug_str ().c_str (),
|
||||
receiver.debug_str ().c_str ());
|
||||
if (fn_self->can_eq (&receiver, false))
|
||||
{
|
||||
PathProbeCandidate::TraitItemCandidate c{trait_item.reference,
|
||||
@@ -214,6 +226,9 @@ MethodResolver::select (const TyTy::BaseType &receiver)
|
||||
rust_assert (fn->is_method ());
|
||||
|
||||
TyTy::BaseType *fn_self = fn->get_self_type ();
|
||||
rust_debug ("dot-operator predicate fn_self={%s} can_eq receiver={%s}",
|
||||
fn_self->debug_str ().c_str (),
|
||||
receiver.debug_str ().c_str ());
|
||||
if (fn_self->can_eq (&receiver, false))
|
||||
{
|
||||
const TraitReference *trait_ref
|
||||
|
||||
@@ -324,10 +324,18 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func)
|
||||
|
||||
auto block_expr_ty = TypeCheckExpr::Resolve (func.get_block_expr ().get ());
|
||||
|
||||
context->pop_return_type ();
|
||||
Location fn_return_locus
|
||||
= func.get_decl ().has_return_type ()
|
||||
? func.get_decl ().get_return_type ()->get_locus ()
|
||||
: func.get_locus ();
|
||||
|
||||
if (block_expr_ty->get_kind () != TyTy::NEVER)
|
||||
expected_ret_tyty->unify (block_expr_ty);
|
||||
TypeCheckBase::coercion_site (func.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (expected_ret_tyty,
|
||||
fn_return_locus),
|
||||
TyTy::TyWithLocation (block_expr_ty),
|
||||
func.get_locus ());
|
||||
|
||||
context->pop_return_type ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -457,7 +465,10 @@ AssociatedImplTrait::setup_associated_types (
|
||||
// the type correctly as our receiver may be generic and we are inferring its
|
||||
// generic arguments and this Self might be the concrete version or vice
|
||||
// versa.
|
||||
auto result = receiver->unify (impl_self_infer);
|
||||
auto result = TypeCheckBase::unify_site (
|
||||
get_impl_block ()->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (receiver), TyTy::TyWithLocation (impl_self_infer),
|
||||
impl_predicate.get_locus ());
|
||||
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
|
||||
|
||||
// unify the bounds arguments
|
||||
@@ -479,7 +490,10 @@ AssociatedImplTrait::setup_associated_types (
|
||||
TyTy::BaseType *a = impl_trait_predicate_args.at (i);
|
||||
TyTy::BaseType *b = hrtb_bound_arguments.at (i);
|
||||
|
||||
result = a->unify (b);
|
||||
result
|
||||
= TypeCheckBase::unify_site (a->get_ref (), TyTy::TyWithLocation (a),
|
||||
TyTy::TyWithLocation (b),
|
||||
impl_predicate.get_locus ());
|
||||
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -336,6 +336,30 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, Location locus)
|
||||
return repr;
|
||||
}
|
||||
|
||||
TyTy::BaseType *
|
||||
TypeCheckBase::unify_site (HirId id, TyTy::TyWithLocation lhs,
|
||||
TyTy::TyWithLocation rhs, Location unify_locus)
|
||||
{
|
||||
TyTy::BaseType *expected = lhs.get_ty ();
|
||||
TyTy::BaseType *expr = rhs.get_ty ();
|
||||
|
||||
rust_debug ("unify_site id={%u} expected={%s} expr={%s}", id,
|
||||
expected->debug_str ().c_str (), expr->debug_str ().c_str ());
|
||||
|
||||
TyTy::BaseType *unified = expected->unify (expr);
|
||||
if (unified->get_kind () == TyTy::TypeKind::ERROR)
|
||||
{
|
||||
RichLocation r (unify_locus);
|
||||
r.add_range (lhs.get_locus ());
|
||||
r.add_range (rhs.get_locus ());
|
||||
rust_error_at (r, "expected %<%s%> got %<%s%>",
|
||||
expected->get_name ().c_str (),
|
||||
expr->get_name ().c_str ());
|
||||
}
|
||||
|
||||
return unified;
|
||||
}
|
||||
|
||||
TyTy::BaseType *
|
||||
TypeCheckBase::coercion_site (HirId id, TyTy::TyWithLocation lhs,
|
||||
TyTy::TyWithLocation rhs, Location locus)
|
||||
@@ -363,7 +387,9 @@ TypeCheckBase::coercion_site (HirId id, TyTy::TyWithLocation lhs,
|
||||
|
||||
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);
|
||||
TyTy::BaseType *coerced
|
||||
= unify_site (id, lhs, TyTy::TyWithLocation (receiver, rhs.get_locus ()),
|
||||
locus);
|
||||
context->insert_autoderef_mappings (id, std::move (result.adjustments));
|
||||
return coerced;
|
||||
}
|
||||
@@ -393,7 +419,11 @@ TypeCheckBase::cast_site (HirId id, TyTy::TyWithLocation from,
|
||||
rust_debug ("cast_default_unify(a={%s}, b={%s})",
|
||||
casted_result->debug_str ().c_str (),
|
||||
to.get_ty ()->debug_str ().c_str ());
|
||||
TyTy::BaseType *casted = to.get_ty ()->unify (casted_result);
|
||||
|
||||
TyTy::BaseType *casted
|
||||
= unify_site (id, to,
|
||||
TyTy::TyWithLocation (casted_result, from.get_locus ()),
|
||||
cast_locus);
|
||||
context->insert_cast_autoderef_mappings (id, std::move (result.adjustments));
|
||||
return casted;
|
||||
}
|
||||
@@ -411,6 +441,7 @@ TypeCheckBase::resolve_generic_params (
|
||||
// FIXME: Skipping Lifetime completely until better
|
||||
// handling.
|
||||
break;
|
||||
|
||||
case HIR::GenericParam::GenericKind::CONST: {
|
||||
auto param
|
||||
= static_cast<HIR::ConstGenericParam *> (generic_param.get ());
|
||||
@@ -422,7 +453,12 @@ TypeCheckBase::resolve_generic_params (
|
||||
auto expr_type = TypeCheckExpr::Resolve (
|
||||
param->get_default_expression ().get ());
|
||||
|
||||
specified_type->unify (expr_type);
|
||||
coercion_site (
|
||||
param->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (specified_type),
|
||||
TyTy::TyWithLocation (
|
||||
expr_type, param->get_default_expression ()->get_locus ()),
|
||||
param->get_locus ());
|
||||
}
|
||||
|
||||
context->insert_type (generic_param->get_mappings (),
|
||||
|
||||
@@ -34,6 +34,10 @@ class TypeCheckBase
|
||||
public:
|
||||
virtual ~TypeCheckBase () {}
|
||||
|
||||
static TyTy::BaseType *unify_site (HirId id, TyTy::TyWithLocation lhs,
|
||||
TyTy::TyWithLocation rhs,
|
||||
Location unify_locus);
|
||||
|
||||
static TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs,
|
||||
TyTy::TyWithLocation rhs,
|
||||
Location coercion_locus);
|
||||
|
||||
@@ -100,9 +100,9 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
|
||||
= new TyTy::ISizeType (discriminant->get_mappings ().get_hirid ());
|
||||
context->insert_type (discriminant->get_mappings (), expected_ty);
|
||||
|
||||
auto unified = expected_ty->unify (capacity_type);
|
||||
if (unified->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
unify_site (item.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (expected_ty),
|
||||
TyTy::TyWithLocation (capacity_type), item.get_locus ());
|
||||
|
||||
const CanonicalPath *canonical_path = nullptr;
|
||||
bool ok = mappings->lookup_canonical_path (item.get_mappings ().get_nodeid (),
|
||||
|
||||
@@ -158,17 +158,17 @@ void
|
||||
TypeCheckExpr::visit (HIR::ReturnExpr &expr)
|
||||
{
|
||||
auto fn_return_tyty = context->peek_return_type ();
|
||||
rust_assert (fn_return_tyty != nullptr);
|
||||
|
||||
Location expr_locus = expr.has_return_expr () ? expr.get_expr ()->get_locus ()
|
||||
: expr.get_locus ();
|
||||
TyTy::BaseType *expr_ty
|
||||
= expr.has_return_expr ()
|
||||
? TypeCheckExpr::Resolve (expr.get_expr ())
|
||||
: TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
|
||||
|
||||
infered = fn_return_tyty->unify (expr_ty);
|
||||
fn_return_tyty->append_reference (expr_ty->get_ref ());
|
||||
for (auto &ref : infered->get_combined_refs ())
|
||||
fn_return_tyty->append_reference (ref);
|
||||
infered = unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (fn_return_tyty),
|
||||
TyTy::TyWithLocation (expr_ty, expr_locus),
|
||||
expr.get_locus ());
|
||||
|
||||
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
|
||||
}
|
||||
@@ -240,9 +240,12 @@ TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr)
|
||||
|
||||
// we dont care about the result of the unify from a compound assignment
|
||||
// since this is a unit-type expr
|
||||
auto result = lhs->unify (rhs);
|
||||
if (result->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
coercion_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (lhs,
|
||||
expr.get_left_expr ()->get_locus ()),
|
||||
TyTy::TyWithLocation (rhs,
|
||||
expr.get_right_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
auto lang_item_type
|
||||
= Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem (
|
||||
@@ -306,8 +309,13 @@ TypeCheckExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
infered = lhs->unify (rhs);
|
||||
default: {
|
||||
infered = unify_site (
|
||||
expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
|
||||
TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -318,9 +326,10 @@ TypeCheckExpr::visit (HIR::ComparisonExpr &expr)
|
||||
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
|
||||
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
|
||||
|
||||
auto result = lhs->unify (rhs);
|
||||
if (result == nullptr || result->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
|
||||
TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
bool ok = context->lookup_builtin ("bool", &infered);
|
||||
rust_assert (ok);
|
||||
@@ -333,17 +342,28 @@ TypeCheckExpr::visit (HIR::LazyBooleanExpr &expr)
|
||||
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
|
||||
|
||||
// we expect the lhs and rhs must be bools at this point
|
||||
TyTy::BoolType elhs (expr.get_mappings ().get_hirid ());
|
||||
lhs = elhs.unify (lhs);
|
||||
if (lhs->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
TyTy::BaseType *boolean_node = nullptr;
|
||||
bool ok = context->lookup_builtin ("bool", &boolean_node);
|
||||
rust_assert (ok);
|
||||
|
||||
TyTy::BoolType rlhs (expr.get_mappings ().get_hirid ());
|
||||
rhs = elhs.unify (rhs);
|
||||
if (lhs->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
// verify the lhs and rhs before unifying together
|
||||
lhs = unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (boolean_node,
|
||||
expr.get_lhs ()->get_locus ()),
|
||||
TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
infered = lhs->unify (rhs);
|
||||
rhs = unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (boolean_node,
|
||||
expr.get_rhs ()->get_locus ()),
|
||||
TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
infered
|
||||
= unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()),
|
||||
TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -428,7 +448,15 @@ TypeCheckExpr::visit (HIR::IfExprConseqElse &expr)
|
||||
else if (else_blk_resolved->get_kind () == TyTy::NEVER)
|
||||
infered = if_blk_resolved;
|
||||
else
|
||||
infered = if_blk_resolved->unify (else_blk_resolved);
|
||||
{
|
||||
infered = unify_site (
|
||||
expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (if_blk_resolved,
|
||||
expr.get_if_block ()->get_locus ()),
|
||||
TyTy::TyWithLocation (else_blk_resolved,
|
||||
expr.get_else_block ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -443,7 +471,15 @@ TypeCheckExpr::visit (HIR::IfExprConseqIf &expr)
|
||||
else if (else_blk_resolved->get_kind () == TyTy::NEVER)
|
||||
infered = if_blk_resolved;
|
||||
else
|
||||
infered = if_blk_resolved->unify (else_blk_resolved);
|
||||
{
|
||||
infered = unify_site (
|
||||
expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (if_blk_resolved,
|
||||
expr.get_if_block ()->get_locus ()),
|
||||
TyTy::TyWithLocation (else_blk_resolved,
|
||||
expr.get_conseq_if_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -459,9 +495,10 @@ TypeCheckExpr::visit (HIR::IfLetExpr &expr)
|
||||
TyTy::BaseType *kase_arm_ty
|
||||
= TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
|
||||
|
||||
TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty);
|
||||
if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (scrutinee_tyty),
|
||||
TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
|
||||
expr.get_locus ());
|
||||
}
|
||||
|
||||
TypeCheckExpr::Resolve (expr.get_if_block ());
|
||||
@@ -502,7 +539,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
|
||||
{
|
||||
auto unit
|
||||
= TyTy::TupleType::get_unit_type (s->get_mappings ().get_hirid ());
|
||||
resolved = unit->unify (resolved);
|
||||
resolved
|
||||
= unify_site (s->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (unit),
|
||||
TyTy::TyWithLocation (resolved), s->get_locus ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +552,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
|
||||
infered
|
||||
= TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
|
||||
else
|
||||
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
|
||||
{
|
||||
// FIXME this seems wrong
|
||||
infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -552,7 +595,12 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
|
||||
TyTy::BaseType *from_ty
|
||||
= TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
|
||||
TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
|
||||
TyTy::BaseType *unified = from_ty->unify (to_ty);
|
||||
|
||||
TyTy::BaseType *unified = unify_site (
|
||||
expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()),
|
||||
TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
// substitute it in
|
||||
std::vector<TyTy::SubstitutionArg> subst_mappings;
|
||||
@@ -722,7 +770,11 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
|
||||
TyTy::BaseType *from_ty
|
||||
= TypeCheckExpr::Resolve (expr.get_from_expr ().get ());
|
||||
TyTy::BaseType *to_ty = TypeCheckExpr::Resolve (expr.get_to_expr ().get ());
|
||||
TyTy::BaseType *unified = from_ty->unify (to_ty);
|
||||
TyTy::BaseType *unified = unify_site (
|
||||
expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (from_ty, expr.get_from_expr ()->get_locus ()),
|
||||
TyTy::TyWithLocation (to_ty, expr.get_to_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
// substitute it in
|
||||
std::vector<TyTy::SubstitutionArg> subst_mappings;
|
||||
@@ -763,9 +815,11 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
|
||||
if (maybe_simple_array_access
|
||||
&& direct_array_expr_ty->get_kind () == TyTy::TypeKind::ARRAY)
|
||||
{
|
||||
auto resolved_index_expr = size_ty->unify (index_expr_ty);
|
||||
if (resolved_index_expr->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
unify_site (expr.get_index_expr ()->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (size_ty),
|
||||
TyTy::TyWithLocation (index_expr_ty,
|
||||
expr.get_index_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
TyTy::ArrayType *array_type
|
||||
= static_cast<TyTy::ArrayType *> (direct_array_expr_ty);
|
||||
@@ -821,9 +875,11 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
|
||||
context->insert_type (elems.get_num_copies_expr ()->get_mappings (),
|
||||
expected_ty);
|
||||
|
||||
auto unified = expected_ty->unify (capacity_type);
|
||||
if (unified->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
unify_site (
|
||||
expr.get_mappings ().get_hirid (), TyTy::TyWithLocation (expected_ty),
|
||||
TyTy::TyWithLocation (capacity_type,
|
||||
elems.get_num_copies_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
|
||||
capacity_expr = elems.get_num_copies_expr ();
|
||||
}
|
||||
@@ -839,11 +895,16 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
|
||||
types.push_back (TypeCheckExpr::Resolve (elem.get ()));
|
||||
}
|
||||
|
||||
// this is a LUB
|
||||
element_type
|
||||
= TyTy::TyVar::get_implicit_infer_var (expr.get_locus ()).get_tyty ();
|
||||
for (auto &type : types)
|
||||
{
|
||||
element_type = element_type->unify (type);
|
||||
element_type
|
||||
= unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (element_type),
|
||||
TyTy::TyWithLocation (type, type->get_locus ()),
|
||||
expr.get_locus ());
|
||||
}
|
||||
|
||||
auto crate_num = mappings->get_current_crate ();
|
||||
@@ -1165,7 +1226,12 @@ TypeCheckExpr::visit (HIR::BreakExpr &expr)
|
||||
return;
|
||||
}
|
||||
|
||||
TyTy::BaseType *unified_ty = loop_context->unify (break_expr_tyty);
|
||||
TyTy::BaseType *unified_ty
|
||||
= unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (loop_context),
|
||||
TyTy::TyWithLocation (break_expr_tyty,
|
||||
expr.get_expr ()->get_locus ()),
|
||||
expr.get_locus ());
|
||||
context->swap_head_loop_context (unified_ty);
|
||||
}
|
||||
|
||||
@@ -1290,7 +1356,12 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
|
||||
TyTy::BaseType *kase_arm_ty
|
||||
= TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty);
|
||||
|
||||
TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty);
|
||||
TyTy::BaseType *checked_kase = unify_site (
|
||||
expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (scrutinee_tyty,
|
||||
expr.get_scrutinee_expr ()->get_locus ()),
|
||||
TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
|
||||
expr.get_locus ());
|
||||
if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
}
|
||||
@@ -1308,13 +1379,14 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
|
||||
return;
|
||||
}
|
||||
|
||||
// this is a LUB
|
||||
infered = kase_block_tys.at (0);
|
||||
for (size_t i = 1; i < kase_block_tys.size (); i++)
|
||||
{
|
||||
TyTy::BaseType *kase_ty = kase_block_tys.at (i);
|
||||
infered = infered->unify (kase_ty);
|
||||
if (infered->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
infered = unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (infered),
|
||||
TyTy::TyWithLocation (kase_ty), expr.get_locus ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1470,7 +1542,11 @@ TypeCheckExpr::resolve_operator_overload (
|
||||
TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup);
|
||||
rust_assert (type->num_params () > 0);
|
||||
auto fnparam = type->param_at (0);
|
||||
fnparam.second->unify (adjusted_self); // typecheck the self
|
||||
|
||||
// typecheck the self
|
||||
unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (fnparam.second),
|
||||
TyTy::TyWithLocation (adjusted_self), expr.get_locus ());
|
||||
if (rhs == nullptr)
|
||||
{
|
||||
rust_assert (type->num_params () == 1);
|
||||
@@ -1479,7 +1555,9 @@ TypeCheckExpr::resolve_operator_overload (
|
||||
{
|
||||
rust_assert (type->num_params () == 2);
|
||||
auto fnparam = type->param_at (1);
|
||||
fnparam.second->unify (rhs); // typecheck the rhs
|
||||
unify_site (expr.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (fnparam.second),
|
||||
TyTy::TyWithLocation (rhs), expr.get_locus ());
|
||||
}
|
||||
|
||||
rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
|
||||
|
||||
@@ -179,7 +179,12 @@ TypeCheckTopLevelImplItem::visit (HIR::ConstantItem &constant)
|
||||
TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
|
||||
TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
|
||||
|
||||
context->insert_type (constant.get_mappings (), type->unify (expr_type));
|
||||
TyTy::BaseType *unified = unify_site (
|
||||
constant.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
|
||||
TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
|
||||
constant.get_locus ());
|
||||
context->insert_type (constant.get_mappings (), unified);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -365,8 +370,16 @@ TypeCheckImplItem::visit (HIR::Function &function)
|
||||
auto block_expr_ty
|
||||
= TypeCheckExpr::Resolve (function.get_definition ().get ());
|
||||
|
||||
Location fn_return_locus = function.has_function_return_type ()
|
||||
? function.get_return_type ()->get_locus ()
|
||||
: function.get_locus ();
|
||||
|
||||
coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
|
||||
TyTy::TyWithLocation (block_expr_ty),
|
||||
function.get_definition ()->get_locus ());
|
||||
|
||||
context->pop_return_type ();
|
||||
expected_ret_tyty->unify (block_expr_ty);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -214,10 +214,15 @@ TypeCheckItem::visit (HIR::Function &function)
|
||||
auto block_expr_ty
|
||||
= TypeCheckExpr::Resolve (function.get_definition ().get ());
|
||||
|
||||
context->pop_return_type ();
|
||||
Location fn_return_locus = function.has_function_return_type ()
|
||||
? function.get_return_type ()->get_locus ()
|
||||
: function.get_locus ();
|
||||
coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
|
||||
TyTy::TyWithLocation (block_expr_ty),
|
||||
function.get_definition ()->get_locus ());
|
||||
|
||||
if (block_expr_ty->get_kind () != TyTy::NEVER)
|
||||
expected_ret_tyty->unify (block_expr_ty);
|
||||
context->pop_return_type ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -390,7 +390,10 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
|
||||
impl_block_ty
|
||||
= SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
|
||||
|
||||
prev_segment = prev_segment->unify (impl_block_ty);
|
||||
prev_segment = unify_site (seg.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (prev_segment),
|
||||
TyTy::TyWithLocation (impl_block_ty),
|
||||
seg.get_locus ());
|
||||
}
|
||||
|
||||
if (tyseg->needs_generic_substitutions ())
|
||||
|
||||
@@ -375,7 +375,9 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
|
||||
break;
|
||||
}
|
||||
|
||||
infered = upper->unify (lower);
|
||||
infered = unify_site (pattern.get_pattern_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (upper),
|
||||
TyTy::TyWithLocation (lower), pattern.get_locus ());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -68,7 +68,11 @@ TypeCheckStmt::visit (HIR::ConstantItem &constant)
|
||||
TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
|
||||
TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
|
||||
|
||||
infered = type->unify (expr_type);
|
||||
infered = unify_site (
|
||||
constant.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
|
||||
TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
|
||||
constant.get_locus ());
|
||||
context->insert_type (constant.get_mappings (), infered);
|
||||
}
|
||||
|
||||
@@ -498,8 +502,13 @@ TypeCheckStmt::visit (HIR::Function &function)
|
||||
|
||||
context->pop_return_type ();
|
||||
|
||||
if (block_expr_ty->get_kind () != TyTy::NEVER)
|
||||
expected_ret_tyty->unify (block_expr_ty);
|
||||
Location fn_return_locus = function.has_function_return_type ()
|
||||
? function.get_return_type ()->get_locus ()
|
||||
: function.get_locus ();
|
||||
coercion_site (function.get_definition ()->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (expected_ret_tyty, fn_return_locus),
|
||||
TyTy::TyWithLocation (block_expr_ty),
|
||||
function.get_definition ()->get_locus ());
|
||||
|
||||
infered = fnType;
|
||||
}
|
||||
|
||||
@@ -57,14 +57,20 @@ 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->unify (base_resolved));
|
||||
if (struct_def == nullptr)
|
||||
TyTy::BaseType *base_unify = unify_site (
|
||||
struct_expr.struct_base->base_struct->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (struct_path_resolved),
|
||||
TyTy::TyWithLocation (base_resolved),
|
||||
struct_expr.struct_base->base_struct->get_locus ());
|
||||
|
||||
if (base_unify->get_kind () != struct_path_ty->get_kind ())
|
||||
{
|
||||
rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
|
||||
"incompatible types for base struct reference");
|
||||
return;
|
||||
}
|
||||
|
||||
struct_def = static_cast<TyTy::ADTType *> (base_unify);
|
||||
}
|
||||
|
||||
// figure out the variant
|
||||
|
||||
@@ -260,7 +260,13 @@ TypeCheckTopLevel::visit (HIR::StaticItem &var)
|
||||
TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
|
||||
TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
|
||||
|
||||
context->insert_type (var.get_mappings (), type->unify (expr_type));
|
||||
TyTy::BaseType *unified
|
||||
= unify_site (var.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (type, var.get_type ()->get_locus ()),
|
||||
TyTy::TyWithLocation (expr_type,
|
||||
var.get_expr ()->get_locus ()),
|
||||
var.get_locus ());
|
||||
context->insert_type (var.get_mappings (), unified);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -269,7 +275,12 @@ TypeCheckTopLevel::visit (HIR::ConstantItem &constant)
|
||||
TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
|
||||
TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
|
||||
|
||||
context->insert_type (constant.get_mappings (), type->unify (expr_type));
|
||||
TyTy::BaseType *unified = unify_site (
|
||||
constant.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (type, constant.get_type ()->get_locus ()),
|
||||
TyTy::TyWithLocation (expr_type, constant.get_expr ()->get_locus ()),
|
||||
constant.get_locus ());
|
||||
context->insert_type (constant.get_mappings (), unified);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -623,9 +623,11 @@ TypeCheckType::visit (HIR::ArrayType &type)
|
||||
rust_assert (ok);
|
||||
context->insert_type (type.get_size_expr ()->get_mappings (), expected_ty);
|
||||
|
||||
auto unified = expected_ty->unify (capacity_type);
|
||||
if (unified->get_kind () == TyTy::TypeKind::ERROR)
|
||||
return;
|
||||
unify_site (type.get_size_expr ()->get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (expected_ty),
|
||||
TyTy::TyWithLocation (capacity_type,
|
||||
type.get_size_expr ()->get_locus ()),
|
||||
type.get_size_expr ()->get_locus ());
|
||||
|
||||
TyTy::BaseType *base = TypeCheckType::Resolve (type.get_element_type ());
|
||||
translated = new TyTy::ArrayType (type.get_mappings ().get_hirid (),
|
||||
|
||||
@@ -70,7 +70,12 @@ TypeResolution::Resolve (HIR::Crate &crate)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto result = ty->unify (default_type);
|
||||
auto result
|
||||
= TypeCheckBase::unify_site (id, TyTy::TyWithLocation (ty),
|
||||
TyTy::TyWithLocation (default_type),
|
||||
Location ());
|
||||
rust_assert (result);
|
||||
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
|
||||
result->set_ref (id);
|
||||
context->insert_type (
|
||||
Analysis::NodeMapping (mappings->get_current_crate (), 0, id,
|
||||
@@ -144,7 +149,10 @@ TraitItemReference::get_type_from_constant (
|
||||
TyTy::BaseType *expr
|
||||
= TypeCheckExpr::Resolve (constant.get_expr ().get ());
|
||||
|
||||
return type->unify (expr);
|
||||
return TypeCheckBase::unify_site (constant.get_mappings ().get_hirid (),
|
||||
TyTy::TyWithLocation (type),
|
||||
TyTy::TyWithLocation (expr),
|
||||
constant.get_locus ());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@ TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
|
||||
TyTy::BaseType *
|
||||
TypeCheckContext::peek_return_type ()
|
||||
{
|
||||
rust_assert (!return_type_stack.empty ());
|
||||
return return_type_stack.back ().second;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,10 @@ TypeCheckCallExpr::visit (FnPtr &type)
|
||||
void
|
||||
TypeCheckMethodCallExpr::visit (FnType &type)
|
||||
{
|
||||
type.get_self_type ()->unify (adjusted_self);
|
||||
Resolver::TypeCheckBase::unify_site (
|
||||
call.get_mappings ().get_hirid (), TyWithLocation (type.get_self_type ()),
|
||||
TyWithLocation (adjusted_self, call.get_receiver ()->get_locus ()),
|
||||
call.get_locus ());
|
||||
|
||||
// +1 for the receiver self
|
||||
size_t num_args_to_call = call.num_params () + 1;
|
||||
|
||||
@@ -1243,8 +1243,8 @@ public:
|
||||
auto base_type = base->get_base ();
|
||||
auto other_base_type = type.get_base ();
|
||||
|
||||
bool mutability_match = base->is_mutable () == type.is_mutable ();
|
||||
if (!mutability_match)
|
||||
bool mutability_ok = base->is_mutable () ? type.is_mutable () : true;
|
||||
if (!mutability_ok)
|
||||
{
|
||||
BaseCmp::visit (type);
|
||||
return;
|
||||
|
||||
@@ -123,269 +123,53 @@ public:
|
||||
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 (TupleType &type) override {}
|
||||
|
||||
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 (ADTType &type) override {}
|
||||
|
||||
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 (InferType &type) override {}
|
||||
|
||||
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 (FnType &type) override {}
|
||||
|
||||
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 (FnPtr &type) override {}
|
||||
|
||||
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 (ArrayType &type) override {}
|
||||
|
||||
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 (SliceType &type) override {}
|
||||
|
||||
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 (BoolType &type) override {}
|
||||
|
||||
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 (IntType &type) override {}
|
||||
|
||||
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 (UintType &type) override {}
|
||||
|
||||
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 (USizeType &type) override {}
|
||||
|
||||
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 (ISizeType &type) override {}
|
||||
|
||||
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 (FloatType &type) override {}
|
||||
|
||||
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 (ErrorType &type) override {}
|
||||
|
||||
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 (CharType &type) override {}
|
||||
|
||||
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 (ReferenceType &type) override {}
|
||||
|
||||
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 (PointerType &type) override {}
|
||||
|
||||
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 (ParamType &type) override {}
|
||||
|
||||
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 (StrType &type) override {}
|
||||
|
||||
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 (NeverType &type) override {}
|
||||
|
||||
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 (PlaceholderType &type) override {}
|
||||
|
||||
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 (ProjectionType &type) override {}
|
||||
|
||||
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 (DynamicObjectType &type) override {}
|
||||
|
||||
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 ());
|
||||
}
|
||||
virtual void visit (ClosureType &type) override {}
|
||||
|
||||
protected:
|
||||
BaseRules (BaseType *base)
|
||||
|
||||
@@ -296,6 +296,33 @@ BaseType::destructure () const
|
||||
return x;
|
||||
}
|
||||
|
||||
std::string
|
||||
BaseType::mappings_str () const
|
||||
{
|
||||
std::string buffer = "Ref: " + std::to_string (get_ref ())
|
||||
+ " TyRef: " + std::to_string (get_ty_ref ());
|
||||
buffer += "[";
|
||||
for (auto &ref : combined)
|
||||
buffer += std::to_string (ref) + ",";
|
||||
buffer += "]";
|
||||
return "(" + buffer + ")";
|
||||
}
|
||||
|
||||
std::string
|
||||
BaseType::debug_str () const
|
||||
{
|
||||
// return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
|
||||
// + mappings_str () + ":" + bounds_as_string ();
|
||||
return get_name ();
|
||||
}
|
||||
|
||||
void
|
||||
BaseType::debug () const
|
||||
{
|
||||
rust_debug ("[%p] %s", static_cast<const void *> (this),
|
||||
debug_str ().c_str ());
|
||||
}
|
||||
|
||||
TyVar::TyVar (HirId ref) : ref (ref)
|
||||
{
|
||||
// ensure this reference is defined within the context
|
||||
@@ -1159,11 +1186,29 @@ TupleType::accept_vis (TyConstVisitor &vis) const
|
||||
std::string
|
||||
TupleType::as_string () const
|
||||
{
|
||||
size_t i = 0;
|
||||
std::string fields_buffer;
|
||||
for (const TyVar &field : get_fields ())
|
||||
{
|
||||
fields_buffer += field.get_tyty ()->as_string ();
|
||||
fields_buffer += ", ";
|
||||
bool has_next = (i + 1) < get_fields ().size ();
|
||||
fields_buffer += has_next ? ", " : "";
|
||||
i++;
|
||||
}
|
||||
return "(" + fields_buffer + ")";
|
||||
}
|
||||
|
||||
std::string
|
||||
TupleType::get_name () const
|
||||
{
|
||||
size_t i = 0;
|
||||
std::string fields_buffer;
|
||||
for (const TyVar &field : get_fields ())
|
||||
{
|
||||
fields_buffer += field.get_tyty ()->as_string ();
|
||||
bool has_next = (i + 1) < get_fields ().size ();
|
||||
fields_buffer += has_next ? ", " : "";
|
||||
i++;
|
||||
}
|
||||
return "(" + fields_buffer + ")";
|
||||
}
|
||||
@@ -2194,6 +2239,13 @@ ReferenceType::as_string () const
|
||||
+ get_base ()->as_string ();
|
||||
}
|
||||
|
||||
std::string
|
||||
ReferenceType::get_name () const
|
||||
{
|
||||
return std::string ("&") + (is_mutable () ? "mut" : "") + " "
|
||||
+ get_base ()->get_name ();
|
||||
}
|
||||
|
||||
BaseType *
|
||||
ReferenceType::unify (BaseType *other)
|
||||
{
|
||||
@@ -2277,6 +2329,13 @@ PointerType::as_string () const
|
||||
+ get_base ()->as_string ();
|
||||
}
|
||||
|
||||
std::string
|
||||
PointerType::get_name () const
|
||||
{
|
||||
return std::string ("* ") + (is_mutable () ? "mut" : "const") + " "
|
||||
+ get_base ()->get_name ();
|
||||
}
|
||||
|
||||
BaseType *
|
||||
PointerType::unify (BaseType *other)
|
||||
{
|
||||
|
||||
@@ -230,28 +230,11 @@ public:
|
||||
|
||||
bool contains_type_parameters () const { return !is_concrete (); }
|
||||
|
||||
std::string mappings_str () const
|
||||
{
|
||||
std::string buffer = "Ref: " + std::to_string (get_ref ())
|
||||
+ " TyRef: " + std::to_string (get_ty_ref ());
|
||||
buffer += "[";
|
||||
for (auto &ref : combined)
|
||||
buffer += std::to_string (ref) + ",";
|
||||
buffer += "]";
|
||||
return "(" + buffer + ")";
|
||||
}
|
||||
std::string mappings_str () const;
|
||||
|
||||
std::string debug_str () const
|
||||
{
|
||||
return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
|
||||
+ mappings_str () + ":" + bounds_as_string ();
|
||||
}
|
||||
std::string debug_str () const;
|
||||
|
||||
void debug () const
|
||||
{
|
||||
rust_debug ("[%p] %s", static_cast<const void *> (this),
|
||||
debug_str ().c_str ());
|
||||
}
|
||||
void debug () const;
|
||||
|
||||
// FIXME this will eventually go away
|
||||
const BaseType *get_root () const;
|
||||
@@ -560,7 +543,7 @@ public:
|
||||
|
||||
const std::vector<TyVar> &get_fields () const { return fields; }
|
||||
|
||||
std::string get_name () const override final { return as_string (); }
|
||||
std::string get_name () const override final;
|
||||
|
||||
TupleType *handle_substitions (SubstitutionArgumentMappings mappings);
|
||||
|
||||
@@ -2164,10 +2147,7 @@ public:
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
std::string get_name () const override final
|
||||
{
|
||||
return "&" + get_base ()->get_name ();
|
||||
}
|
||||
std::string get_name () const override final;
|
||||
|
||||
BaseType *unify (BaseType *other) override;
|
||||
bool can_eq (const BaseType *other, bool emit_errors) const override final;
|
||||
@@ -2249,11 +2229,7 @@ public:
|
||||
void accept_vis (TyConstVisitor &vis) const override;
|
||||
|
||||
std::string as_string () const override;
|
||||
|
||||
std::string get_name () const override final
|
||||
{
|
||||
return "*" + get_base ()->get_name ();
|
||||
}
|
||||
std::string get_name () const override final;
|
||||
|
||||
BaseType *unify (BaseType *other) override;
|
||||
bool can_eq (const BaseType *other, bool emit_errors) const override final;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
fn test() {
|
||||
let f = [0; -4_isize];
|
||||
// { dg-error "expected .usize. got .isize." "" { target *-*-* } .-1 }
|
||||
// { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
|
||||
let f = [0_usize; -1_isize];
|
||||
// { dg-error "expected .usize. got .isize." "" { target *-*-* } .-1 }
|
||||
// { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fn main() {
|
||||
let a: (i32, bool) = (123, 123); // { dg-error "expected .bool. got .<integer>." }
|
||||
let a: (i32, bool) = (123, 123); // { dg-error "expected" }
|
||||
let b;
|
||||
b = (456, 5f32);
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ type TypeAlias = (i32, u32);
|
||||
|
||||
fn main() {
|
||||
let a: TypeAlias;
|
||||
a = (123, 456f32); // { dg-error "expected .u32. got .f32." }
|
||||
a = (123, 456f32); // { dg-error "expected" }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* { dg-output "mut_deref\n123\n" } */
|
||||
/* { dg-output "imm_deref\n123\n" } */
|
||||
extern "C" {
|
||||
fn printf(s: *const i8, ...);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,10 @@ union Repr<T> {
|
||||
|
||||
const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
|
||||
unsafe {
|
||||
let a = FatPtr { data, len };
|
||||
let b = Repr { raw: a };
|
||||
b.rust
|
||||
Repr {
|
||||
raw: FatPtr { data, len },
|
||||
}
|
||||
.rust
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user