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;
}
}
const TyTy::BaseType *r = receiver;
while (true)
{
+ rust_debug ("autoderef try 1: {%s}", r->debug_str ().c_str ());
if (try_autoderefed (r))
return true;
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;
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;
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;
// 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 {
// 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
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};
}
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;
}
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;
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,
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,
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
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 ();
+
+ TypeCheckBase::coercion_site (func.get_mappings ().get_hirid (),
+ TyTy::TyWithLocation (expected_ret_tyty,
+ fn_return_locus),
+ TyTy::TyWithLocation (block_expr_ty),
+ func.get_locus ());
- if (block_expr_ty->get_kind () != TyTy::NEVER)
- expected_ret_tyty->unify (block_expr_ty);
+ context->pop_return_type ();
}
void
// 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
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);
}
}
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)
{
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;
}
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;
}
// FIXME: Skipping Lifetime completely until better
// handling.
break;
+
case HIR::GenericParam::GenericKind::CONST: {
auto param
= static_cast<HIR::ConstGenericParam *> (generic_param.get ());
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 (),
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);
= 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 (),
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 ());
}
// 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 (
}
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;
}
}
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);
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
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
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
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 ());
{
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 ());
}
}
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
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;
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;
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);
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 ();
}
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 ();
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);
}
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;
}
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 ());
}
}
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);
{
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);
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
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
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
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 ())
break;
}
- infered = upper->unify (lower);
+ infered = unify_site (pattern.get_pattern_mappings ().get_hirid (),
+ TyTy::TyWithLocation (upper),
+ TyTy::TyWithLocation (lower), pattern.get_locus ());
}
void
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);
}
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;
}
{
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
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
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
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 (),
}
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,
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;
}
TyTy::BaseType *
TypeCheckContext::peek_return_type ()
{
+ rust_assert (!return_type_stack.empty ());
return return_type_stack.back ().second;
}
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;
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;
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)
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
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 ();
+ 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 ();
- fields_buffer += ", ";
+ bool has_next = (i + 1) < get_fields ().size ();
+ fields_buffer += has_next ? ", " : "";
+ i++;
}
return "(" + fields_buffer + ")";
}
+ 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)
{
+ 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)
{
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;
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);
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;
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;
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 }
}
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);
}
fn main() {
let a: TypeAlias;
- a = (123, 456f32); // { dg-error "expected .u32. got .f32." }
+ a = (123, 456f32); // { dg-error "expected" }
}
-/* { dg-output "mut_deref\n123\n" } */
+/* { dg-output "imm_deref\n123\n" } */
extern "C" {
fn printf(s: *const i8, ...);
}
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
}
}