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:
Philip Herron
2022-08-26 15:09:55 +01:00
committed by Arthur Cohen
parent af22b54af5
commit 7ad24d802e
28 changed files with 460 additions and 363 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 (),

View File

@@ -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);

View File

@@ -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 (),

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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 ())

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 (),

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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 }
}

View File

@@ -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);
}

View File

@@ -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" }
}

View File

@@ -1,4 +1,4 @@
/* { dg-output "mut_deref\n123\n" } */
/* { dg-output "imm_deref\n123\n" } */
extern "C" {
fn printf(s: *const i8, ...);
}

View File

@@ -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
}
}