@@ -116,7 +116,6 @@ GRS_OBJS = \
rust/rust-tyty-bounds.o \
rust/rust-hir-type-check-util.o \
rust/rust-hir-trait-resolve.o \
- rust/rust-hir-type-check-toplevel.o \
rust/rust-hir-type-check-item.o \
rust/rust-hir-type-check-type.o \
rust/rust-hir-type-check-struct.o \
@@ -126,6 +125,7 @@ GRS_OBJS = \
rust/rust-hir-type-check-enumitem.o \
rust/rust-hir-type-check-implitem.o \
rust/rust-hir-dot-operator.o \
+ rust/rust-hir-path-probe.o \
rust/rust-coercion.o \
rust/rust-casts.o \
rust/rust-hir-type-check-base.o \
@@ -25,8 +25,7 @@ namespace Resolver {
MethodResolver::MethodResolver (bool autoderef_flag,
const HIR::PathIdentSegment &segment_name)
- : AutoderefCycle (autoderef_flag), mappings (Analysis::Mappings::get ()),
- context (TypeCheckContext::get ()), segment_name (segment_name),
+ : AutoderefCycle (autoderef_flag), segment_name (segment_name),
try_result (MethodCandidate::get_error ())
{}
@@ -80,8 +79,9 @@ MethodResolver::select (const TyTy::BaseType &receiver)
return true;
TyTy::BaseType *ty = nullptr;
- if (!context->lookup_type (func->get_mappings ().get_hirid (), &ty))
+ if (!query_type (func->get_mappings ().get_hirid (), &ty))
return true;
+ rust_assert (ty != nullptr);
if (ty->get_kind () == TyTy::TypeKind::ERROR)
return true;
@@ -127,7 +127,7 @@ MethodResolver::select (const TyTy::BaseType &receiver)
continue;
TyTy::BaseType *ty = nullptr;
- if (!context->lookup_type (func->get_mappings ().get_hirid (), &ty))
+ if (!query_type (func->get_mappings ().get_hirid (), &ty))
continue;
if (ty->get_kind () == TyTy::TypeKind::ERROR)
continue;
@@ -37,7 +37,7 @@ struct MethodCandidate
bool is_error () const { return candidate.is_error (); }
};
-class MethodResolver : protected AutoderefCycle
+class MethodResolver : private TypeCheckBase, protected AutoderefCycle
{
public:
struct predicate_candidate
@@ -63,10 +63,6 @@ protected:
bool select (const TyTy::BaseType &receiver) override;
private:
- // context info
- Analysis::Mappings *mappings;
- TypeCheckContext *context;
-
// search
const HIR::PathIdentSegment &segment_name;
std::vector<MethodResolver::predicate_candidate> predicate_items;
new file mode 100644
@@ -0,0 +1,46 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-hir-path-probe.h"
+#include "rust-hir-type-check-item.h"
+
+namespace Rust {
+namespace Resolver {
+
+void
+PathProbeType::process_impl_item_candidate (HirId id, HIR::ImplItem *item,
+ HIR::ImplBlock *impl)
+{
+ current_impl = impl;
+ HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+ TyTy::BaseType *impl_block_ty = nullptr;
+ if (!query_type (impl_ty_id, &impl_block_ty))
+ return;
+
+ if (!receiver->can_eq (impl_block_ty, false))
+ {
+ if (!impl_block_ty->can_eq (receiver, false))
+ return;
+ }
+
+ // lets visit the impl_item
+ item->accept_vis (*this);
+}
+
+} // namespace Resolver
+} // namespace Rust
@@ -195,7 +195,7 @@ public:
{
HirId tyid = alias.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
- bool ok = context->lookup_type (tyid, &ty);
+ bool ok = query_type (tyid, &ty);
rust_assert (ok);
PathProbeCandidate::ImplItemCandidate impl_item_candidate{&alias,
@@ -214,7 +214,7 @@ public:
{
HirId tyid = constant.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
- bool ok = context->lookup_type (tyid, &ty);
+ bool ok = query_type (tyid, &ty);
rust_assert (ok);
PathProbeCandidate::ImplItemCandidate impl_item_candidate{&constant,
@@ -233,7 +233,7 @@ public:
{
HirId tyid = function.get_mappings ().get_hirid ();
TyTy::BaseType *ty = nullptr;
- bool ok = context->lookup_type (tyid, &ty);
+ bool ok = query_type (tyid, &ty);
rust_assert (ok);
PathProbeCandidate::ImplItemCandidate impl_item_candidate{&function,
@@ -272,23 +272,7 @@ protected:
}
void process_impl_item_candidate (HirId id, HIR::ImplItem *item,
- HIR::ImplBlock *impl)
- {
- current_impl = impl;
- HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
- TyTy::BaseType *impl_block_ty = nullptr;
- if (!context->lookup_type (impl_ty_id, &impl_block_ty))
- return;
-
- if (!receiver->can_eq (impl_block_ty, false))
- {
- if (!impl_block_ty->can_eq (receiver, false))
- return;
- }
-
- // lets visit the impl_item
- item->accept_vis (*this);
- }
+ HIR::ImplBlock *impl);
void
process_associated_trait_for_candidates (const TraitReference *trait_ref,
@@ -17,8 +17,10 @@
// <http://www.gnu.org/licenses/>.
#include "rust-hir-type-check-base.h"
+#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-expr.h"
+#include "rust-hir-type-check-implitem.h"
#include "rust-coercion.h"
#include "rust-casts.h"
@@ -37,6 +39,13 @@ TypeCheckBase::check_for_unconstrained (
const TyTy::SubstitutionArgumentMappings &constraint_b,
const TyTy::BaseType *reference)
{
+ bool check_result = false;
+ bool check_completed
+ = context->have_checked_for_unconstrained (reference->get_ref (),
+ &check_result);
+ if (check_completed)
+ return check_result;
+
std::set<HirId> symbols_to_constrain;
std::map<HirId, Location> symbol_to_location;
for (const auto &p : params_to_constrain)
@@ -86,6 +95,10 @@ TypeCheckBase::check_for_unconstrained (
unconstrained = true;
}
}
+
+ context->insert_unconstrained_check_marker (reference->get_ref (),
+ unconstrained);
+
return unconstrained;
}
@@ -479,5 +492,68 @@ TypeCheckBase::resolve_generic_params (
}
}
+bool
+TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
+{
+ if (context->lookup_type (reference, result))
+ return true;
+
+ HIR::Item *item = mappings->lookup_hir_item (reference);
+ if (item != nullptr)
+ {
+ rust_debug_loc (item->get_locus (), "resolved item {%u} to", reference);
+ *result = TypeCheckItem::Resolve (*item);
+ return true;
+ }
+
+ HirId parent_impl_id = UNKNOWN_HIRID;
+ HIR::ImplItem *impl_item
+ = mappings->lookup_hir_implitem (reference, &parent_impl_id);
+ if (impl_item != nullptr)
+ {
+ HIR::ImplBlock *impl_block
+ = mappings->lookup_hir_impl_block (parent_impl_id);
+ rust_assert (impl_block != nullptr);
+
+ // found an impl item
+ rust_debug_loc (impl_item->get_locus (), "resolved impl-item {%u} to",
+ reference);
+
+ *result = TypeCheckItem::ResolveImplItem (*impl_block, *impl_item);
+ return true;
+ }
+
+ // is it an impl_type?
+ HIR::ImplBlock *impl_block_by_type = nullptr;
+ bool found_impl_block_type
+ = mappings->lookup_impl_block_type (reference, &impl_block_by_type);
+ if (found_impl_block_type)
+ {
+ *result = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type);
+ return true;
+ }
+
+ // is it an extern item?
+ HirId parent_extern_block_id = UNKNOWN_HIRID;
+ HIR::ExternalItem *extern_item
+ = mappings->lookup_hir_extern_item (reference, &parent_extern_block_id);
+ if (extern_item != nullptr)
+ {
+ HIR::ExternBlock *block
+ = mappings->lookup_hir_extern_block (parent_extern_block_id);
+ rust_assert (block != nullptr);
+
+ *result = TypeCheckTopLevelExternItem::Resolve (extern_item, *block);
+ return true;
+ }
+
+ // more?
+ Location possible_locus = mappings->lookup_location (reference);
+ rust_debug_loc (possible_locus, "query system failed to resolve: [%u]",
+ reference);
+
+ return false;
+}
+
} // namespace Resolver
} // namespace Rust
@@ -69,6 +69,8 @@ protected:
const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
std::vector<TyTy::SubstitutionParamMapping> &substitutions);
+ bool query_type (HirId reference, TyTy::BaseType **result);
+
Analysis::Mappings *mappings;
Resolver *resolver;
TypeCheckContext *context;
@@ -188,6 +188,9 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
return;
}
+ rust_debug_loc (expr.get_locus (), "resolved_call_expr to: {%s}",
+ function_tyty->get_name ().c_str ());
+
TyTy::VariantDef &variant = TyTy::VariantDef::get_error_node ();
if (function_tyty->get_kind () == TyTy::TypeKind::ADT)
{
@@ -32,12 +32,21 @@ TypeCheckTopLevelExternItem::TypeCheckTopLevelExternItem (
: TypeCheckBase (), parent (parent)
{}
-void
+TyTy::BaseType *
TypeCheckTopLevelExternItem::Resolve (HIR::ExternalItem *item,
const HIR::ExternBlock &parent)
{
+ // is it already resolved?
+ auto context = TypeCheckContext::get ();
+ TyTy::BaseType *resolved = nullptr;
+ bool already_resolved
+ = context->lookup_type (item->get_mappings ().get_hirid (), &resolved);
+ if (already_resolved)
+ return resolved;
+
TypeCheckTopLevelExternItem resolver (parent);
item->accept_vis (resolver);
+ return resolver.resolved;
}
void
@@ -47,6 +56,7 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalStaticItem &item)
= TypeCheckType::Resolve (item.get_item_type ().get ());
context->insert_type (item.get_mappings (), actual_type);
+ resolved = actual_type;
}
void
@@ -142,79 +152,40 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
ret_type, std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
+ resolved = fnType;
}
-TypeCheckTopLevelImplItem::TypeCheckTopLevelImplItem (
- TyTy::BaseType *self,
+TypeCheckImplItem::TypeCheckImplItem (
+ HIR::ImplBlock *parent, TyTy::BaseType *self,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
- : TypeCheckBase (), self (self), substitutions (substitutions)
+ : TypeCheckBase (), parent (parent), self (self),
+ substitutions (substitutions)
{}
-void
-TypeCheckTopLevelImplItem::Resolve (
- HIR::ImplItem *item, TyTy::BaseType *self,
+TyTy::BaseType *
+TypeCheckImplItem::Resolve (
+ HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
{
- TypeCheckTopLevelImplItem resolver (self, substitutions);
+ // is it already resolved?
+ auto context = TypeCheckContext::get ();
+ TyTy::BaseType *resolved = nullptr;
+ bool already_resolved
+ = context->lookup_type (item->get_impl_mappings ().get_hirid (), &resolved);
+ if (already_resolved)
+ return resolved;
+
+ // resolve
+ TypeCheckImplItem resolver (parent, self, substitutions);
item->accept_vis (resolver);
+ return resolver.result;
}
void
-TypeCheckTopLevelImplItem::visit (HIR::TypeAlias &alias)
-{
- TyTy::BaseType *actual_type
- = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
-
- context->insert_type (alias.get_mappings (), actual_type);
-
- for (auto &where_clause_item : alias.get_where_clause ().get_items ())
- {
- ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
- }
-}
-
-void
-TypeCheckTopLevelImplItem::visit (HIR::ConstantItem &constant)
-{
- TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
- TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
-
- 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
-TypeCheckTopLevelImplItem::visit (HIR::Function &function)
+TypeCheckImplItem::visit (HIR::Function &function)
{
if (function.has_generics ())
- {
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
- }
+ resolve_generic_params (function.get_generic_params (), substitutions);
for (auto &where_clause_item : function.get_where_clause ().get_items ())
{
@@ -328,41 +299,10 @@ TypeCheckTopLevelImplItem::visit (HIR::Function &function)
std::move (substitutions));
context->insert_type (function.get_mappings (), fnType);
-}
-
-TypeCheckImplItem::TypeCheckImplItem (HIR::ImplBlock *parent,
- TyTy::BaseType *self)
- : TypeCheckBase (), parent (parent), self (self)
-{}
-
-void
-TypeCheckImplItem::Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item,
- TyTy::BaseType *self)
-{
- TypeCheckImplItem resolver (parent, self);
- item->accept_vis (resolver);
-}
-
-void
-TypeCheckImplItem::visit (HIR::Function &function)
-{
- TyTy::BaseType *lookup;
- if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
- {
- rust_error_at (function.get_locus (), "failed to lookup function type");
- return;
- }
-
- if (lookup->get_kind () != TyTy::TypeKind::FNDEF)
- {
- rust_error_at (function.get_locus (),
- "found invalid type for function [%s]",
- lookup->as_string ().c_str ());
- return;
- }
+ result = fnType;
// need to get the return type from this
- TyTy::FnType *resolve_fn_type = static_cast<TyTy::FnType *> (lookup);
+ TyTy::FnType *resolve_fn_type = fnType;
auto expected_ret_tyty = resolve_fn_type->get_return_type ();
context->push_return_type (TypeCheckContextItem (parent, &function),
expected_ret_tyty);
@@ -383,20 +323,41 @@ TypeCheckImplItem::visit (HIR::Function &function)
}
void
-TypeCheckImplItem::visit (HIR::ConstantItem &const_item)
-{}
+TypeCheckImplItem::visit (HIR::ConstantItem &constant)
+{
+ TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
+
+ 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);
+ result = unified;
+}
void
-TypeCheckImplItem::visit (HIR::TypeAlias &type_alias)
-{}
+TypeCheckImplItem::visit (HIR::TypeAlias &alias)
+{
+ TyTy::BaseType *actual_type
+ = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+
+ context->insert_type (alias.get_mappings (), actual_type);
+ result = actual_type;
+ for (auto &where_clause_item : alias.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+}
TypeCheckImplItemWithTrait::TypeCheckImplItemWithTrait (
HIR::ImplBlock *parent, TyTy::BaseType *self,
TyTy::TypeBoundPredicate &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
- : TypeCheckImplItem (parent, self), trait_reference (trait_reference),
+ : TypeCheckBase (), trait_reference (trait_reference),
resolved_trait_item (TyTy::TypeBoundPredicateItem::error ()),
- substitutions (substitutions)
+ parent (parent), self (self), substitutions (substitutions)
{
rust_assert (is_trait_impl_block ());
}
@@ -417,10 +378,8 @@ void
TypeCheckImplItemWithTrait::visit (HIR::ConstantItem &constant)
{
// normal resolution of the item
- TypeCheckImplItem::visit (constant);
- TyTy::BaseType *lookup;
- if (!context->lookup_type (constant.get_mappings ().get_hirid (), &lookup))
- return;
+ TyTy::BaseType *lookup
+ = TypeCheckImplItem::Resolve (parent, &constant, self, substitutions);
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
@@ -468,10 +427,8 @@ void
TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
{
// normal resolution of the item
- TypeCheckImplItem::visit (type);
- TyTy::BaseType *lookup;
- if (!context->lookup_type (type.get_mappings ().get_hirid (), &lookup))
- return;
+ TyTy::BaseType *lookup
+ = TypeCheckImplItem::Resolve (parent, &type, self, substitutions);
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
@@ -528,11 +485,9 @@ TypeCheckImplItemWithTrait::visit (HIR::TypeAlias &type)
void
TypeCheckImplItemWithTrait::visit (HIR::Function &function)
{
- // we get the error checking from the base method here
- TypeCheckImplItem::visit (function);
- TyTy::BaseType *lookup;
- if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
- return;
+ // normal resolution of the item
+ TyTy::BaseType *lookup
+ = TypeCheckImplItem::Resolve (parent, &function, self, substitutions);
// map the impl item to the associated trait item
const auto tref = trait_reference.get ();
@@ -28,7 +28,8 @@ class TypeCheckTopLevelExternItem : public TypeCheckBase,
public HIR::HIRExternalItemVisitor
{
public:
- static void Resolve (HIR::ExternalItem *item, const HIR::ExternBlock &parent);
+ static TyTy::BaseType *Resolve (HIR::ExternalItem *item,
+ const HIR::ExternBlock &parent);
void visit (HIR::ExternalStaticItem &item) override;
void visit (HIR::ExternalFunctionItem &function) override;
@@ -37,47 +38,33 @@ private:
TypeCheckTopLevelExternItem (const HIR::ExternBlock &parent);
const HIR::ExternBlock &parent;
-};
-
-class TypeCheckTopLevelImplItem : public TypeCheckBase,
- public HIR::HIRImplVisitor
-{
-public:
- static void
- Resolve (HIR::ImplItem *item, TyTy::BaseType *self,
- std::vector<TyTy::SubstitutionParamMapping> substitutions);
-
- void visit (HIR::TypeAlias &alias) override;
- void visit (HIR::ConstantItem &constant) override;
- void visit (HIR::Function &function) override;
-
-private:
- TypeCheckTopLevelImplItem (
- TyTy::BaseType *self,
- std::vector<TyTy::SubstitutionParamMapping> substitutions);
-
- TyTy::BaseType *self;
- std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ TyTy::BaseType *resolved;
};
class TypeCheckImplItem : public TypeCheckBase, public HIR::HIRImplVisitor
{
public:
- static void Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item,
- TyTy::BaseType *self);
+ static TyTy::BaseType *
+ Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> substitutions);
void visit (HIR::Function &function) override;
void visit (HIR::ConstantItem &const_item) override;
void visit (HIR::TypeAlias &type_alias) override;
protected:
- TypeCheckImplItem (HIR::ImplBlock *parent, TyTy::BaseType *self);
+ TypeCheckImplItem (HIR::ImplBlock *parent, TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> substitutions);
HIR::ImplBlock *parent;
TyTy::BaseType *self;
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+
+ TyTy::BaseType *result;
};
-class TypeCheckImplItemWithTrait : public TypeCheckImplItem
+class TypeCheckImplItemWithTrait : public TypeCheckBase,
+ public HIR::HIRImplVisitor
{
public:
static TyTy::TypeBoundPredicateItem
@@ -105,6 +92,9 @@ private:
TyTy::TypeBoundPredicate &trait_reference;
TyTy::TypeBoundPredicateItem resolved_trait_item;
+
+ HIR::ImplBlock *parent;
+ TyTy::BaseType *self;
std::vector<TyTy::SubstitutionParamMapping> substitutions;
};
@@ -16,59 +16,466 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include "rust-hir-type-check-item.h"
#include "rust-hir-full.h"
+#include "rust-hir-type-check-item.h"
+#include "rust-hir-type-check-enumitem.h"
#include "rust-hir-type-check-implitem.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-stmt.h"
#include "rust-hir-type-check-expr.h"
+#include "rust-hir-type-check-pattern.h"
#include "rust-hir-trait-resolve.h"
namespace Rust {
namespace Resolver {
-TypeCheckItem::TypeCheckItem () : TypeCheckBase () {}
+TypeCheckItem::TypeCheckItem () : TypeCheckBase (), infered (nullptr) {}
-void
+TyTy::BaseType *
TypeCheckItem::Resolve (HIR::Item &item)
{
+ // is it already resolved?
+ auto context = TypeCheckContext::get ();
+ TyTy::BaseType *resolved = nullptr;
+ bool already_resolved
+ = context->lookup_type (item.get_mappings ().get_hirid (), &resolved);
+ if (already_resolved)
+ return resolved;
+
rust_assert (item.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM);
HIR::VisItem &vis_item = static_cast<HIR::VisItem &> (item);
TypeCheckItem resolver;
vis_item.accept_vis (resolver);
+ return resolver.infered;
+}
+
+TyTy::BaseType *
+TypeCheckItem::ResolveImplItem (HIR::ImplBlock &impl_block, HIR::ImplItem &item)
+{
+ TypeCheckItem resolver;
+ return resolver.resolve_impl_item (impl_block, item);
+}
+
+TyTy::BaseType *
+TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
+{
+ TypeCheckItem resolver;
+
+ bool failed_flag = false;
+ std::vector<TyTy::SubstitutionParamMapping> substitutions
+ = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
+ if (failed_flag)
+ {
+ return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
+ }
+
+ return resolver.resolve_impl_block_self (impl_block);
+}
+
+void
+TypeCheckItem::visit (HIR::TypeAlias &alias)
+{
+ TyTy::BaseType *actual_type
+ = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+
+ context->insert_type (alias.get_mappings (), actual_type);
+
+ for (auto &where_clause_item : alias.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+ infered = actual_type;
+}
+
+void
+TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
+{
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (struct_decl.has_generics ())
+ resolve_generic_params (struct_decl.get_generic_params (), substitutions);
+
+ for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
+ std::vector<TyTy::StructFieldType *> fields;
+ size_t idx = 0;
+ for (auto &field : struct_decl.get_fields ())
+ {
+ TyTy::BaseType *field_type
+ = TypeCheckType::Resolve (field.get_field_type ().get ());
+ TyTy::StructFieldType *ty_field
+ = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
+ std::to_string (idx), field_type,
+ field.get_locus ());
+ fields.push_back (ty_field);
+ context->insert_type (field.get_mappings (), ty_field->get_field_type ());
+ idx++;
+ }
+
+ // get the path
+ const CanonicalPath *canonical_path = nullptr;
+ bool ok = mappings->lookup_canonical_path (
+ struct_decl.get_mappings ().get_nodeid (), &canonical_path);
+ rust_assert (ok);
+ RustIdent ident{*canonical_path, struct_decl.get_locus ()};
+
+ // its a single variant ADT
+ std::vector<TyTy::VariantDef *> variants;
+ variants.push_back (new TyTy::VariantDef (
+ struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
+ ident, TyTy::VariantDef::VariantType::TUPLE, nullptr, std::move (fields)));
+
+ // Process #[repr(X)] attribute, if any
+ const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
+ TyTy::ADTType::ReprOptions repr
+ = parse_repr_options (attrs, struct_decl.get_locus ());
+
+ TyTy::BaseType *type
+ = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
+ mappings->get_next_hir_id (),
+ struct_decl.get_identifier (), ident,
+ TyTy::ADTType::ADTKind::TUPLE_STRUCT,
+ std::move (variants), std::move (substitutions), repr);
+
+ context->insert_type (struct_decl.get_mappings (), type);
+ infered = type;
+}
+
+void
+TypeCheckItem::visit (HIR::StructStruct &struct_decl)
+{
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (struct_decl.has_generics ())
+ resolve_generic_params (struct_decl.get_generic_params (), substitutions);
+
+ for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
+ std::vector<TyTy::StructFieldType *> fields;
+ for (auto &field : struct_decl.get_fields ())
+ {
+ TyTy::BaseType *field_type
+ = TypeCheckType::Resolve (field.get_field_type ().get ());
+ TyTy::StructFieldType *ty_field
+ = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
+ field.get_field_name (), field_type,
+ field.get_locus ());
+ fields.push_back (ty_field);
+ context->insert_type (field.get_mappings (), ty_field->get_field_type ());
+ }
+
+ // get the path
+ const CanonicalPath *canonical_path = nullptr;
+ bool ok = mappings->lookup_canonical_path (
+ struct_decl.get_mappings ().get_nodeid (), &canonical_path);
+ rust_assert (ok);
+ RustIdent ident{*canonical_path, struct_decl.get_locus ()};
+
+ // its a single variant ADT
+ std::vector<TyTy::VariantDef *> variants;
+ variants.push_back (new TyTy::VariantDef (
+ struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
+ ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
+
+ // Process #[repr(X)] attribute, if any
+ const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
+ TyTy::ADTType::ReprOptions repr
+ = parse_repr_options (attrs, struct_decl.get_locus ());
+
+ TyTy::BaseType *type
+ = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
+ mappings->get_next_hir_id (),
+ struct_decl.get_identifier (), ident,
+ TyTy::ADTType::ADTKind::STRUCT_STRUCT,
+ std::move (variants), std::move (substitutions), repr);
+
+ context->insert_type (struct_decl.get_mappings (), type);
+ infered = type;
+}
+
+void
+TypeCheckItem::visit (HIR::Enum &enum_decl)
+{
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (enum_decl.has_generics ())
+ resolve_generic_params (enum_decl.get_generic_params (), substitutions);
+
+ std::vector<TyTy::VariantDef *> variants;
+ int64_t discriminant_value = 0;
+ for (auto &variant : enum_decl.get_variants ())
+ {
+ TyTy::VariantDef *field_type
+ = TypeCheckEnumItem::Resolve (variant.get (), discriminant_value);
+
+ discriminant_value++;
+ variants.push_back (field_type);
+ }
+
+ // get the path
+ const CanonicalPath *canonical_path = nullptr;
+ bool ok
+ = mappings->lookup_canonical_path (enum_decl.get_mappings ().get_nodeid (),
+ &canonical_path);
+ rust_assert (ok);
+ RustIdent ident{*canonical_path, enum_decl.get_locus ()};
+
+ // multi variant ADT
+ TyTy::BaseType *type
+ = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
+ mappings->get_next_hir_id (),
+ enum_decl.get_identifier (), ident,
+ TyTy::ADTType::ADTKind::ENUM, std::move (variants),
+ std::move (substitutions));
+
+ context->insert_type (enum_decl.get_mappings (), type);
+ infered = type;
+}
+
+void
+TypeCheckItem::visit (HIR::Union &union_decl)
+{
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (union_decl.has_generics ())
+ resolve_generic_params (union_decl.get_generic_params (), substitutions);
+
+ for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
+ std::vector<TyTy::StructFieldType *> fields;
+ for (auto &variant : union_decl.get_variants ())
+ {
+ TyTy::BaseType *variant_type
+ = TypeCheckType::Resolve (variant.get_field_type ().get ());
+ TyTy::StructFieldType *ty_variant
+ = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
+ variant.get_field_name (), variant_type,
+ variant.get_locus ());
+ fields.push_back (ty_variant);
+ context->insert_type (variant.get_mappings (),
+ ty_variant->get_field_type ());
+ }
+
+ // get the path
+ const CanonicalPath *canonical_path = nullptr;
+ bool ok
+ = mappings->lookup_canonical_path (union_decl.get_mappings ().get_nodeid (),
+ &canonical_path);
+ rust_assert (ok);
+ RustIdent ident{*canonical_path, union_decl.get_locus ()};
+
+ // there is only a single variant
+ std::vector<TyTy::VariantDef *> variants;
+ variants.push_back (new TyTy::VariantDef (
+ union_decl.get_mappings ().get_hirid (), union_decl.get_identifier (),
+ ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
+
+ TyTy::BaseType *type
+ = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
+ mappings->get_next_hir_id (),
+ union_decl.get_identifier (), ident,
+ TyTy::ADTType::ADTKind::UNION, std::move (variants),
+ std::move (substitutions));
+
+ context->insert_type (union_decl.get_mappings (), type);
+ infered = type;
+}
+
+void
+TypeCheckItem::visit (HIR::StaticItem &var)
+{
+ TyTy::BaseType *type = TypeCheckType::Resolve (var.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (var.get_expr ());
+
+ TyTy::BaseType *unified
+ = coercion_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);
+ infered = unified;
+}
+
+void
+TypeCheckItem::visit (HIR::ConstantItem &constant)
+{
+ TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
+ TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
+
+ 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);
+ infered = unified;
}
void
TypeCheckItem::visit (HIR::ImplBlock &impl_block)
+{
+ bool failed_flag = false;
+ std::vector<TyTy::SubstitutionParamMapping> substitutions
+ = resolve_impl_block_substitutions (impl_block, failed_flag);
+ if (failed_flag)
+ {
+ infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
+ return;
+ }
+
+ TyTy::BaseType *self = resolve_impl_block_self (impl_block);
+
+ // resolve each impl_item
+ for (auto &impl_item : impl_block.get_impl_items ())
+ {
+ TypeCheckImplItem::Resolve (&impl_block, impl_item.get (), self,
+ substitutions);
+ }
+
+ // validate the impl items
+ validate_trait_impl_block (impl_block, self, substitutions);
+}
+
+TyTy::BaseType *
+TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
+ HIR::ImplItem &item)
+{
+ bool failed_flag = false;
+ std::vector<TyTy::SubstitutionParamMapping> substitutions
+ = resolve_impl_block_substitutions (impl_block, failed_flag);
+ if (failed_flag)
+ {
+ return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
+ }
+
+ TyTy::BaseType *self = resolve_impl_block_self (impl_block);
+
+ return TypeCheckImplItem::Resolve (&impl_block, &item, self, substitutions);
+}
+
+void
+TypeCheckItem::visit (HIR::Function &function)
{
std::vector<TyTy::SubstitutionParamMapping> substitutions;
- if (impl_block.has_generics ())
+ if (function.has_generics ())
+ resolve_generic_params (function.get_generic_params (), substitutions);
+
+ for (auto &where_clause_item : function.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+ }
+
+ TyTy::BaseType *ret_type = nullptr;
+ if (!function.has_function_return_type ())
+ ret_type
+ = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid ());
+ else
{
- for (auto &generic_param : impl_block.get_generic_params ())
+ auto resolved
+ = TypeCheckType::Resolve (function.get_return_type ().get ());
+ if (resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- TyTy::BaseType *l = nullptr;
- bool ok = context->lookup_type (
- generic_param->get_mappings ().get_hirid (), &l);
- if (ok && l->get_kind () == TyTy::TypeKind::PARAM)
- {
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param),
- static_cast<TyTy::ParamType *> (l)));
- }
- }
- break;
- }
+ rust_error_at (function.get_locus (),
+ "failed to resolve return type");
+ return;
}
+
+ ret_type = resolved->clone ();
+ ret_type->set_ref (
+ function.get_return_type ()->get_mappings ().get_hirid ());
+ }
+
+ std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *>> params;
+ for (auto ¶m : function.get_function_params ())
+ {
+ // get the name as well required for later on
+ auto param_tyty = TypeCheckType::Resolve (param.get_type ());
+ params.push_back (
+ std::pair<HIR::Pattern *, TyTy::BaseType *> (param.get_param_name (),
+ param_tyty));
+
+ context->insert_type (param.get_mappings (), param_tyty);
+ TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
+ }
+
+ const CanonicalPath *canonical_path = nullptr;
+ bool ok
+ = mappings->lookup_canonical_path (function.get_mappings ().get_nodeid (),
+ &canonical_path);
+ rust_assert (ok);
+
+ RustIdent ident{*canonical_path, function.get_locus ()};
+ auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ function.get_mappings ().get_defid (),
+ function.get_function_name (), ident,
+ TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST,
+ std::move (params), ret_type,
+ std::move (substitutions));
+
+ context->insert_type (function.get_mappings (), fnType);
+
+ // need to get the return type from this
+ TyTy::FnType *resolved_fn_type = fnType;
+ auto expected_ret_tyty = resolved_fn_type->get_return_type ();
+ context->push_return_type (TypeCheckContextItem (&function),
+ expected_ret_tyty);
+
+ 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 ();
+
+ infered = fnType;
+}
+
+void
+TypeCheckItem::visit (HIR::Module &module)
+{
+ for (auto &item : module.get_items ())
+ TypeCheckItem::Resolve (*item.get ());
+}
+
+void
+TypeCheckItem::visit (HIR::Trait &trait)
+{
+ TraitResolver::Resolve (trait);
+}
+
+void
+TypeCheckItem::visit (HIR::ExternBlock &extern_block)
+{
+ for (auto &item : extern_block.get_extern_items ())
+ {
+ TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block);
+ }
+}
+
+std::vector<TyTy::SubstitutionParamMapping>
+TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
+ bool &failure_flag)
+{
+ std::vector<TyTy::SubstitutionParamMapping> substitutions;
+ if (impl_block.has_generics ())
+ resolve_generic_params (impl_block.get_generic_params (), substitutions);
+
+ for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
+ {
+ ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
}
auto specified_bound = TyTy::TypeBoundPredicate::error ();
@@ -84,14 +491,7 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
specified_bound = get_predicate_from_bound (*ref.get ());
}
- TyTy::BaseType *self = nullptr;
- if (!context->lookup_type (
- impl_block.get_type ()->get_mappings ().get_hirid (), &self))
- {
- rust_error_at (impl_block.get_locus (),
- "failed to resolve Self for ImplBlock");
- return;
- }
+ TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ());
// inherit the bounds
if (!specified_bound.is_error ())
@@ -103,20 +503,35 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
const TyTy::SubstitutionArgumentMappings impl_constraints
= GetUsedSubstArgs::From (self);
- bool impl_block_has_unconstrained_typarams
- = check_for_unconstrained (substitutions, trait_constraints,
- impl_constraints, self);
- if (impl_block_has_unconstrained_typarams)
- return;
+ failure_flag = check_for_unconstrained (substitutions, trait_constraints,
+ impl_constraints, self);
+
+ return substitutions;
+}
+
+void
+TypeCheckItem::validate_trait_impl_block (
+ HIR::ImplBlock &impl_block, TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions)
+{
+ auto specified_bound = TyTy::TypeBoundPredicate::error ();
+ TraitReference *trait_reference = &TraitReference::error_node ();
+ if (impl_block.has_trait_ref ())
+ {
+ std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
+ trait_reference = TraitResolver::Resolve (*ref.get ());
+ rust_assert (!trait_reference->is_error ());
+
+ // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
+ // for example
+ specified_bound = get_predicate_from_bound (*ref.get ());
+ }
- // validate the impl items
bool is_trait_impl_block = !trait_reference->is_error ();
std::vector<const TraitItemReference *> trait_item_refs;
for (auto &impl_item : impl_block.get_impl_items ())
{
- if (!is_trait_impl_block)
- TypeCheckImplItem::Resolve (&impl_block, impl_item.get (), self);
- else
+ if (!specified_bound.is_error ())
{
auto trait_item_ref
= TypeCheckImplItemWithTrait::Resolve (&impl_block,
@@ -128,7 +543,7 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
}
bool impl_block_missing_trait_items
- = is_trait_impl_block
+ = !specified_bound.is_error ()
&& trait_reference->size () != trait_item_refs.size ();
if (impl_block_missing_trait_items)
{
@@ -187,55 +602,10 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
}
}
-void
-TypeCheckItem::visit (HIR::Function &function)
+TyTy::BaseType *
+TypeCheckItem::resolve_impl_block_self (HIR::ImplBlock &impl_block)
{
- TyTy::BaseType *lookup;
- if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
- {
- rust_error_at (function.get_locus (), "failed to lookup function type");
- return;
- }
-
- if (lookup->get_kind () != TyTy::TypeKind::FNDEF)
- {
- rust_error_at (function.get_locus (),
- "found invalid type for function [%s]",
- lookup->as_string ().c_str ());
- return;
- }
-
- // need to get the return type from this
- TyTy::FnType *resolved_fn_type = static_cast<TyTy::FnType *> (lookup);
- auto expected_ret_tyty = resolved_fn_type->get_return_type ();
- context->push_return_type (TypeCheckContextItem (&function),
- expected_ret_tyty);
-
- 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 ();
-}
-
-void
-TypeCheckItem::visit (HIR::Module &module)
-{
- for (auto &item : module.get_items ())
- TypeCheckItem::Resolve (*item.get ());
-}
-
-void
-TypeCheckItem::visit (HIR::Trait &trait)
-{
- TraitResolver::Resolve (trait);
+ return TypeCheckType::Resolve (impl_block.get_type ().get ());
}
} // namespace Resolver
@@ -27,29 +27,48 @@ namespace Resolver {
class TypeCheckItem : private TypeCheckBase, private HIR::HIRVisItemVisitor
{
public:
- static void Resolve (HIR::Item &item);
+ static TyTy::BaseType *Resolve (HIR::Item &item);
+
+ static TyTy::BaseType *ResolveImplItem (HIR::ImplBlock &impl_block,
+ HIR::ImplItem &item);
+
+ static TyTy::BaseType *ResolveImplBlockSelf (HIR::ImplBlock &impl_block);
- void visit (HIR::ImplBlock &impl_block) override;
- void visit (HIR::Function &function) override;
void visit (HIR::Module &module) override;
- void visit (HIR::Trait &trait) override;
-
- // FIXME - get rid of toplevel pass
- void visit (HIR::TypeAlias &alias) override{};
- void visit (HIR::TupleStruct &struct_decl) override{};
- void visit (HIR::StructStruct &struct_decl) override{};
- void visit (HIR::Enum &enum_decl) override{};
- void visit (HIR::Union &union_decl) override{};
- void visit (HIR::StaticItem &var) override{};
- void visit (HIR::ConstantItem &constant) override{};
- void visit (HIR::ExternBlock &extern_block) override{};
+ void visit (HIR::Function &function) override;
+ void visit (HIR::TypeAlias &alias) override;
+ void visit (HIR::TupleStruct &struct_decl) override;
+ void visit (HIR::StructStruct &struct_decl) override;
+ void visit (HIR::Enum &enum_decl) override;
+ void visit (HIR::Union &union_decl) override;
+ void visit (HIR::StaticItem &var) override;
+ void visit (HIR::ConstantItem &constant) override;
+ void visit (HIR::ImplBlock &impl_block) override;
+ void visit (HIR::ExternBlock &extern_block) override;
+ void visit (HIR::Trait &trait_block) override;
// nothing to do
void visit (HIR::ExternCrate &crate) override {}
void visit (HIR::UseDeclaration &use_decl) override {}
+protected:
+ std::vector<TyTy::SubstitutionParamMapping>
+ resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
+ bool &failure_flag);
+
+ void validate_trait_impl_block (
+ HIR::ImplBlock &impl_block, TyTy::BaseType *self,
+ std::vector<TyTy::SubstitutionParamMapping> &substitutions);
+
+ TyTy::BaseType *resolve_impl_item (HIR::ImplBlock &impl_block,
+ HIR::ImplItem &item);
+
+ TyTy::BaseType *resolve_impl_block_self (HIR::ImplBlock &impl_block);
+
private:
TypeCheckItem ();
+
+ TyTy::BaseType *infered;
};
} // namespace Resolver
@@ -235,7 +235,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
}
TyTy::BaseType *lookup = nullptr;
- if (!context->lookup_type (ref, &lookup))
+ if (!query_type (ref, &lookup))
{
if (is_root)
{
@@ -383,7 +383,7 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
HirId impl_ty_id
= associated_impl_block->get_type ()->get_mappings ().get_hirid ();
TyTy::BaseType *impl_block_ty = nullptr;
- bool ok = context->lookup_type (impl_ty_id, &impl_block_ty);
+ bool ok = query_type (impl_ty_id, &impl_block_ty);
rust_assert (ok);
if (impl_block_ty->needs_generic_substitutions ())
@@ -22,6 +22,7 @@
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-enumitem.h"
#include "rust-hir-type-check-implitem.h"
+#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check-pattern.h"
namespace Rust {
@@ -139,378 +140,74 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt)
}
void
-TypeCheckStmt::visit (HIR::TupleStruct &struct_decl)
+TypeCheckStmt::visit (HIR::TypePath &path)
{
- std::vector<TyTy::SubstitutionParamMapping> substitutions;
- if (struct_decl.has_generics ())
- {
- for (auto &generic_param : struct_decl.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
- }
-
- std::vector<TyTy::StructFieldType *> fields;
- size_t idx = 0;
- for (auto &field : struct_decl.get_fields ())
- {
- TyTy::BaseType *field_type
- = TypeCheckType::Resolve (field.get_field_type ().get ());
- TyTy::StructFieldType *ty_field
- = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
- std::to_string (idx), field_type,
- field.get_locus ());
- fields.push_back (ty_field);
- context->insert_type (field.get_mappings (), ty_field->get_field_type ());
- idx++;
- }
-
- // get the path
- const CanonicalPath *canonical_path = nullptr;
- bool ok = mappings->lookup_canonical_path (
- struct_decl.get_mappings ().get_nodeid (), &canonical_path);
- rust_assert (ok);
- RustIdent ident{*canonical_path, struct_decl.get_locus ()};
-
- // there is only a single variant
- std::vector<TyTy::VariantDef *> variants;
- variants.push_back (new TyTy::VariantDef (
- struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
- ident, TyTy::VariantDef::VariantType::TUPLE, nullptr, std::move (fields)));
-
- // Process #[repr(...)] attribute, if any
- const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
- TyTy::ADTType::ReprOptions repr
- = parse_repr_options (attrs, struct_decl.get_locus ());
-
- TyTy::BaseType *type
- = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- mappings->get_next_hir_id (),
- struct_decl.get_identifier (), ident,
- TyTy::ADTType::ADTKind::TUPLE_STRUCT,
- std::move (variants), std::move (substitutions), repr);
+ infered = TypeCheckType::Resolve (&path);
+}
+void
+TypeCheckStmt::visit (HIR::QualifiedPathInType &path)
+{
+ infered = TypeCheckType::Resolve (&path);
+}
- context->insert_type (struct_decl.get_mappings (), type);
- infered = type;
+void
+TypeCheckStmt::visit (HIR::TupleStruct &struct_decl)
+{
+ infered = TypeCheckItem::Resolve (struct_decl);
}
void
TypeCheckStmt::visit (HIR::Enum &enum_decl)
{
- std::vector<TyTy::SubstitutionParamMapping> substitutions;
- if (enum_decl.has_generics ())
- {
- for (auto &generic_param : enum_decl.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
- }
-
- std::vector<TyTy::VariantDef *> variants;
- int64_t discriminant_value = 0;
- for (auto &variant : enum_decl.get_variants ())
- {
- TyTy::VariantDef *field_type
- = TypeCheckEnumItem::Resolve (variant.get (), discriminant_value);
-
- discriminant_value++;
- variants.push_back (field_type);
- }
-
- // get the path
- const CanonicalPath *canonical_path = nullptr;
- bool ok
- = mappings->lookup_canonical_path (enum_decl.get_mappings ().get_nodeid (),
- &canonical_path);
- rust_assert (ok);
- RustIdent ident{*canonical_path, enum_decl.get_locus ()};
-
- TyTy::BaseType *type
- = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
- mappings->get_next_hir_id (),
- enum_decl.get_identifier (), ident,
- TyTy::ADTType::ADTKind::ENUM, std::move (variants),
- std::move (substitutions));
-
- context->insert_type (enum_decl.get_mappings (), type);
- infered = type;
+ infered = TypeCheckItem::Resolve (enum_decl);
}
void
TypeCheckStmt::visit (HIR::StructStruct &struct_decl)
{
- std::vector<TyTy::SubstitutionParamMapping> substitutions;
- if (struct_decl.has_generics ())
- {
- for (auto &generic_param : struct_decl.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
- }
-
- std::vector<TyTy::StructFieldType *> fields;
- for (auto &field : struct_decl.get_fields ())
- {
- TyTy::BaseType *field_type
- = TypeCheckType::Resolve (field.get_field_type ().get ());
- TyTy::StructFieldType *ty_field
- = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
- field.get_field_name (), field_type,
- field.get_locus ());
- fields.push_back (ty_field);
- context->insert_type (field.get_mappings (), ty_field->get_field_type ());
- }
-
- // get the path
- const CanonicalPath *canonical_path = nullptr;
- bool ok = mappings->lookup_canonical_path (
- struct_decl.get_mappings ().get_nodeid (), &canonical_path);
- rust_assert (ok);
- RustIdent ident{*canonical_path, struct_decl.get_locus ()};
-
- // there is only a single variant
- std::vector<TyTy::VariantDef *> variants;
- variants.push_back (new TyTy::VariantDef (
- struct_decl.get_mappings ().get_hirid (), struct_decl.get_identifier (),
- ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
-
- // Process #[repr(...)] attribute, if any
- const AST::AttrVec &attrs = struct_decl.get_outer_attrs ();
- TyTy::ADTType::ReprOptions repr
- = parse_repr_options (attrs, struct_decl.get_locus ());
-
- TyTy::BaseType *type
- = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- mappings->get_next_hir_id (),
- struct_decl.get_identifier (), ident,
- TyTy::ADTType::ADTKind::STRUCT_STRUCT,
- std::move (variants), std::move (substitutions), repr);
-
- context->insert_type (struct_decl.get_mappings (), type);
- infered = type;
+ infered = TypeCheckItem::Resolve (struct_decl);
}
void
TypeCheckStmt::visit (HIR::Union &union_decl)
{
- std::vector<TyTy::SubstitutionParamMapping> substitutions;
- if (union_decl.has_generics ())
- {
- for (auto &generic_param : union_decl.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
- }
-
- std::vector<TyTy::StructFieldType *> fields;
- for (auto &variant : union_decl.get_variants ())
- {
- TyTy::BaseType *variant_type
- = TypeCheckType::Resolve (variant.get_field_type ().get ());
- TyTy::StructFieldType *ty_variant
- = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
- variant.get_field_name (), variant_type,
- variant.get_locus ());
- fields.push_back (ty_variant);
- context->insert_type (variant.get_mappings (),
- ty_variant->get_field_type ());
- }
-
- // get the path
- const CanonicalPath *canonical_path = nullptr;
- bool ok
- = mappings->lookup_canonical_path (union_decl.get_mappings ().get_nodeid (),
- &canonical_path);
- rust_assert (ok);
- RustIdent ident{*canonical_path, union_decl.get_locus ()};
-
- // there is only a single variant
- std::vector<TyTy::VariantDef *> variants;
- variants.push_back (new TyTy::VariantDef (
- union_decl.get_mappings ().get_hirid (), union_decl.get_identifier (),
- ident, TyTy::VariantDef::VariantType::STRUCT, nullptr, std::move (fields)));
-
- TyTy::BaseType *type
- = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
- mappings->get_next_hir_id (),
- union_decl.get_identifier (), ident,
- TyTy::ADTType::ADTKind::UNION, std::move (variants),
- std::move (substitutions));
-
- context->insert_type (union_decl.get_mappings (), type);
- infered = type;
+ infered = TypeCheckItem::Resolve (union_decl);
}
void
TypeCheckStmt::visit (HIR::Function &function)
{
- std::vector<TyTy::SubstitutionParamMapping> substitutions;
- if (function.has_generics ())
- {
- for (auto &generic_param : function.get_generic_params ())
- {
- switch (generic_param.get ()->get_kind ())
- {
- case HIR::GenericParam::GenericKind::LIFETIME:
- case HIR::GenericParam::GenericKind::CONST:
- // FIXME: Skipping Lifetime and Const completely until better
- // handling.
- break;
-
- case HIR::GenericParam::GenericKind::TYPE: {
- auto param_type
- = TypeResolveGenericParam::Resolve (generic_param.get ());
- context->insert_type (generic_param->get_mappings (),
- param_type);
-
- substitutions.push_back (TyTy::SubstitutionParamMapping (
- static_cast<HIR::TypeParam &> (*generic_param), param_type));
- }
- break;
- }
- }
- }
-
- TyTy::BaseType *ret_type = nullptr;
- if (!function.has_function_return_type ())
- ret_type
- = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid ());
- else
- {
- auto resolved
- = TypeCheckType::Resolve (function.get_return_type ().get ());
- if (resolved == nullptr)
- {
- rust_error_at (function.get_locus (),
- "failed to resolve return type");
- return;
- }
-
- ret_type = resolved->clone ();
- ret_type->set_ref (
- function.get_return_type ()->get_mappings ().get_hirid ());
- }
-
- std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
- for (auto ¶m : function.get_function_params ())
- {
- // get the name as well required for later on
- auto param_tyty = TypeCheckType::Resolve (param.get_type ());
- params.push_back (
- std::pair<HIR::Pattern *, TyTy::BaseType *> (param.get_param_name (),
- param_tyty));
-
- context->insert_type (param.get_mappings (), param_tyty);
- TypeCheckPattern::Resolve (param.get_param_name (), param_tyty);
- }
-
- // get the path
- const CanonicalPath *canonical_path = nullptr;
- bool ok
- = mappings->lookup_canonical_path (function.get_mappings ().get_nodeid (),
- &canonical_path);
- rust_assert (ok);
-
- RustIdent ident{*canonical_path, function.get_locus ()};
- auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
- function.get_mappings ().get_defid (),
- function.get_function_name (), ident,
- TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST,
- std::move (params), ret_type,
- std::move (substitutions));
- context->insert_type (function.get_mappings (), fnType);
+ infered = TypeCheckItem::Resolve (function);
+}
- TyTy::FnType *resolved_fn_type = fnType;
- auto expected_ret_tyty = resolved_fn_type->get_return_type ();
- context->push_return_type (TypeCheckContextItem (&function),
- expected_ret_tyty);
+void
+TypeCheckStmt::visit (HIR::Module &module)
+{
+ infered = TypeCheckItem::Resolve (module);
+}
- auto block_expr_ty
- = TypeCheckExpr::Resolve (function.get_definition ().get ());
+void
+TypeCheckStmt::visit (HIR::TypeAlias &type_alias)
+{
+ infered = TypeCheckItem::Resolve (type_alias);
+}
- context->pop_return_type ();
+void
+TypeCheckStmt::visit (HIR::StaticItem &static_item)
+{
+ infered = TypeCheckItem::Resolve (static_item);
+}
- 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 ());
+void
+TypeCheckStmt::visit (HIR::Trait &trait)
+{
+ infered = TypeCheckItem::Resolve (trait);
+}
- infered = fnType;
+void
+TypeCheckStmt::visit (HIR::ImplBlock &impl)
+{
+ infered = TypeCheckItem::Resolve (impl);
}
} // namespace Resolver
@@ -40,50 +40,32 @@ public:
void visit (HIR::StructStruct &struct_decl) override;
void visit (HIR::Union &union_decl) override;
void visit (HIR::Function &function) override;
+ void visit (HIR::Module &module) override;
+ void visit (HIR::TypeAlias &type_alias) override;
+ void visit (HIR::StaticItem &static_item) override;
+ void visit (HIR::Trait &trait) override;
+ void visit (HIR::ImplBlock &impl) override;
+ void visit (HIR::TypePath &path) override;
+ void visit (HIR::QualifiedPathInType &path) override;
- void visit (HIR::EnumItemTuple &) override
- { /* TODO? */
- }
- void visit (HIR::EnumItemStruct &) override
- { /* TODO? */
- }
- void visit (HIR::EnumItem &item) override
- { /* TODO? */
- }
- void visit (HIR::EnumItemDiscriminant &) override
- { /* TODO? */
- }
+ // FIXME
+ // this seems like it should not be part of this visitor
void visit (HIR::TypePathSegmentFunction &segment) override
- { /* TODO? */
- }
- void visit (HIR::TypePath &path) override
- { /* TODO? */
- }
- void visit (HIR::QualifiedPathInType &path) override
- { /* TODO? */
- }
- void visit (HIR::Module &module) override
- { /* TODO? */
- }
- void visit (HIR::ExternCrate &crate) override
- { /* TODO? */
- }
- void visit (HIR::UseDeclaration &use_decl) override
- { /* TODO? */
- }
- void visit (HIR::TypeAlias &type_alias) override
- { /* TODO? */
- }
- void visit (HIR::StaticItem &static_item) override
- { /* TODO? */
- }
- void visit (HIR::Trait &trait) override
- { /* TODO? */
- }
- void visit (HIR::ImplBlock &impl) override
- { /* TODO? */
+ {
+ gcc_unreachable ();
}
+ // nothing to do for these
+ void visit (HIR::ExternCrate &crate) override {}
+ void visit (HIR::UseDeclaration &use_decl) override {}
+
+ // nothing to do for these as they are taken care of by the
+ // hir-type-check-enumitem.h
+ void visit (HIR::EnumItemTuple &) override {}
+ void visit (HIR::EnumItemStruct &) override {}
+ void visit (HIR::EnumItem &) override {}
+ void visit (HIR::EnumItemDiscriminant &) override {}
+
private:
TypeCheckStmt () : TypeCheckBase (), infered (nullptr) {}
@@ -48,6 +48,14 @@ TypeCheckResolveGenericArguments::visit (HIR::TypePathSegmentGeneric &generic)
TyTy::BaseType *
TypeCheckType::Resolve (HIR::Type *type)
{
+ // is it already resolved?
+ auto context = TypeCheckContext::get ();
+ TyTy::BaseType *resolved = nullptr;
+ bool already_resolved
+ = context->lookup_type (type->get_mappings ().get_hirid (), &resolved);
+ if (already_resolved)
+ return resolved;
+
TypeCheckType resolver (type->get_mappings ().get_hirid ());
type->accept_vis (resolver);
rust_assert (resolver.translated != nullptr);
@@ -103,77 +111,29 @@ TypeCheckType::visit (HIR::TupleType &tuple)
void
TypeCheckType::visit (HIR::TypePath &path)
{
- // lookup the Node this resolves to
- NodeId ref;
- auto nid = path.get_mappings ().get_nodeid ();
- bool is_fully_resolved = resolver->lookup_resolved_type (nid, &ref);
-
- TyTy::BaseType *lookup = nullptr;
- if (!is_fully_resolved)
- {
- // this can happen so we need to look up the root then resolve the
- // remaining segments if possible
- size_t offset = 0;
- NodeId resolved_node_id = UNKNOWN_NODEID;
- TyTy::BaseType *root
- = resolve_root_path (path, &offset, &resolved_node_id);
-
- rust_assert (root != nullptr);
- if (root->get_kind () == TyTy::TypeKind::ERROR)
- return;
-
- translated
- = resolve_segments (resolved_node_id, path.get_mappings ().get_hirid (),
- path.get_segments (), offset, root,
- path.get_mappings (), path.get_locus ());
- return;
- }
-
- HirId hir_lookup;
- if (!context->lookup_type_by_node_id (ref, &hir_lookup))
- {
- rust_error_at (path.get_locus (), "failed to lookup HIR %d for node '%s'",
- ref, path.as_string ().c_str ());
- return;
- }
-
- if (!context->lookup_type (hir_lookup, &lookup))
- {
- rust_error_at (path.get_locus (), "failed to lookup HIR TyTy");
- return;
- }
+ // this can happen so we need to look up the root then resolve the
+ // remaining segments if possible
+ size_t offset = 0;
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ TyTy::BaseType *root = resolve_root_path (path, &offset, &resolved_node_id);
+ if (root->get_kind () == TyTy::TypeKind::ERROR)
+ return;
- TyTy::BaseType *path_type = lookup->clone ();
+ TyTy::BaseType *path_type = root->clone ();
path_type->set_ref (path.get_mappings ().get_hirid ());
+ context->insert_implicit_type (path.get_mappings ().get_hirid (), path_type);
- HIR::TypePathSegment *final_seg = path.get_final_segment ().get ();
- HIR::GenericArgs args = TypeCheckResolveGenericArguments::resolve (final_seg);
-
- bool is_big_self = final_seg->is_ident_only ()
- && (final_seg->as_string ().compare ("Self") == 0);
-
- if (path_type->needs_generic_substitutions ())
- {
- if (is_big_self)
- {
- translated = path_type;
- return;
- }
-
- translated = SubstMapper::Resolve (path_type, path.get_locus (), &args);
- }
- else if (!args.is_empty ())
- {
- rust_error_at (path.get_locus (),
- "TypePath %s declares generic arguments but "
- "the type %s does not have any",
- path.as_string ().c_str (),
- path_type->as_string ().c_str ());
- }
- else
+ bool fully_resolved = offset >= path.get_segments ().size ();
+ if (fully_resolved)
{
translated = path_type;
+ return;
}
+
+ translated
+ = resolve_segments (resolved_node_id, path.get_mappings ().get_hirid (),
+ path.get_segments (), offset, path_type,
+ path.get_mappings (), path.get_locus ());
}
void
@@ -389,7 +349,7 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
}
TyTy::BaseType *lookup = nullptr;
- if (!context->lookup_type (ref, &lookup))
+ if (!query_type (ref, &lookup))
{
if (is_root)
{
@@ -428,14 +388,22 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
if (!lookup->can_substitute ())
{
- rust_error_at (seg->get_locus (),
- "substitutions not supported for %s",
+ rust_error_at (path.get_locus (),
+ "TypePath %s declares generic arguments but the "
+ "type %s does not have any",
+ path.as_string ().c_str (),
lookup->as_string ().c_str ());
return new TyTy::ErrorType (lookup->get_ref ());
}
lookup = SubstMapper::Resolve (lookup, path.get_locus (),
&generic_segment->get_generic_args ());
}
+ else if (lookup->needs_generic_substitutions ())
+ {
+ HIR::GenericArgs empty
+ = HIR::GenericArgs::create_empty (path.get_locus ());
+ lookup = SubstMapper::Resolve (lookup, path.get_locus (), &empty);
+ }
*root_resolved_node_id = ref_node_id;
*offset = *offset + 1;
@@ -531,7 +499,7 @@ TypeCheckType::resolve_segments (
context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
if (tyseg->needs_generic_substitutions ())
{
- Location locus = segments.back ()->get_locus ();
+ // Location locus = segments.back ()->get_locus ();
if (!prev_segment->needs_generic_substitutions ())
{
auto used_args_in_prev_segment
@@ -540,10 +508,6 @@ TypeCheckType::resolve_segments (
tyseg
= SubstMapperInternal::Resolve (tyseg, used_args_in_prev_segment);
}
- else
- {
- tyseg = SubstMapper::InferSubst (tyseg, locus);
- }
if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr_id);
@@ -18,7 +18,6 @@
#include "rust-hir-type-check.h"
#include "rust-hir-full.h"
-#include "rust-hir-type-check-toplevel.h"
#include "rust-hir-type-check-item.h"
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-pattern.h"
@@ -35,7 +34,7 @@ void
TypeResolution::Resolve (HIR::Crate &crate)
{
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
- TypeCheckTopLevel::Resolve (*it->get ());
+ TypeCheckItem::Resolve (*it->get ());
if (saw_errors ())
return;
@@ -44,12 +43,6 @@ TypeResolution::Resolve (HIR::Crate &crate)
if (saw_errors ())
return;
- for (auto it = crate.items.begin (); it != crate.items.end (); it++)
- TypeCheckItem::Resolve (*it->get ());
-
- if (saw_errors ())
- return;
-
auto mappings = Analysis::Mappings::get ();
auto context = TypeCheckContext::get ();
@@ -337,6 +337,41 @@ public:
return true;
}
+ void insert_unconstrained_check_marker (HirId id, bool status)
+ {
+ unconstrained[id] = status;
+ }
+
+ bool have_checked_for_unconstrained (HirId id, bool *result)
+ {
+ auto it = unconstrained.find (id);
+ bool found = it != unconstrained.end ();
+ if (!found)
+ return false;
+
+ *result = it->second;
+ return true;
+ }
+
+ void insert_resolved_predicate (HirId id, TyTy::TypeBoundPredicate predicate)
+ {
+ auto it = predicates.find (id);
+ rust_assert (it == predicates.end ());
+
+ predicates.insert ({id, predicate});
+ }
+
+ bool lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result)
+ {
+ auto it = predicates.find (id);
+ bool found = it != predicates.end ();
+ if (!found)
+ return false;
+
+ *result = it->second;
+ return true;
+ }
+
private:
TypeCheckContext ();
@@ -365,6 +400,12 @@ private:
// variants
std::map<HirId, HirId> variants;
+
+ // unconstrained type-params check
+ std::map<HirId, bool> unconstrained;
+
+ // predicates
+ std::map<HirId, TyTy::TypeBoundPredicate> predicates;
};
class TypeResolution
@@ -102,7 +102,7 @@ public:
if (!have_generic_args ())
{
TyTy::BaseType *substs = type.infer_substitions (locus);
- rust_assert (substs->get_kind () == TyTy::TypeKind::ADT);
+ rust_assert (substs->get_kind () == TyTy::TypeKind::PROJECTION);
concrete = static_cast<TyTy::ProjectionType *> (substs);
}
else
@@ -18,6 +18,7 @@
#include "rust-hir-type-bounds.h"
#include "rust-hir-trait-resolve.h"
+#include "rust-hir-type-check-item.h"
namespace Rust {
namespace Resolver {
@@ -33,11 +34,8 @@ TypeBoundsProbe::scan ()
if (!impl->has_trait_ref ())
return true;
- TyTy::BaseType *impl_type = nullptr;
- bool ok
- = context->lookup_type (impl->get_type ()->get_mappings ().get_hirid (),
- &impl_type);
- if (!ok)
+ TyTy::BaseType *impl_type = TypeCheckItem::ResolveImplBlockSelf (*impl);
+ if (impl_type->get_kind () == TyTy::TypeKind::ERROR)
return true;
if (!receiver->can_eq (impl_type, false))
@@ -69,6 +67,13 @@ TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
TyTy::TypeBoundPredicate
TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path)
{
+ TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
+ bool already_resolved
+ = context->lookup_predicate (type_path.get_mappings ().get_hirid (),
+ &lookup);
+ if (already_resolved)
+ return lookup;
+
TraitReference *trait = resolve_trait_path (type_path);
if (trait->is_error ())
return TyTy::TypeBoundPredicate::error ();
@@ -94,6 +99,8 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path)
predicate.apply_generic_arguments (&args);
}
+ context->insert_resolved_predicate (type_path.get_mappings ().get_hirid (),
+ predicate);
return predicate;
}
@@ -470,6 +477,13 @@ TypeBoundsMappings::raw_bounds_as_name () const
void
TypeBoundsMappings::add_bound (TypeBoundPredicate predicate)
{
+ for (auto &bound : specified_bounds)
+ {
+ bool same_trait_ref_p = bound.get_id () == predicate.get_id ();
+ if (same_trait_ref_p)
+ return;
+ }
+
specified_bounds.push_back (predicate);
}
@@ -1358,6 +1358,8 @@ public:
// generic arguments
void visit (const ParamType &) override { ok = true; }
+ void visit (const TupleType &) override { ok = true; }
+
void visit (const InferType &) override { ok = true; }
void visit (const FnType &) override { ok = true; }
@@ -208,9 +208,6 @@ void
BaseType::inherit_bounds (
const std::vector<TyTy::TypeBoundPredicate> &specified_bounds)
{
- // FIXME
- // 1. This needs to union the bounds
- // 2. Do some checking for trait polarity to ensure compatibility
for (auto &bound : specified_bounds)
{
add_bound (bound);
@@ -754,6 +751,40 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
return SubstitutionArgumentMappings (mappings, args.get_locus ());
}
+BaseType *
+SubstitutionRef::infer_substitions (Location locus)
+{
+ std::vector<SubstitutionArg> args;
+ std::map<std::string, BaseType *> argument_mappings;
+ for (auto &p : get_substs ())
+ {
+ if (p.needs_substitution ())
+ {
+ const std::string &symbol = p.get_param_ty ()->get_symbol ();
+ auto it = argument_mappings.find (symbol);
+ bool have_mapping = it != argument_mappings.end ();
+
+ if (have_mapping)
+ {
+ args.push_back (SubstitutionArg (&p, it->second));
+ }
+ else
+ {
+ TyVar infer_var = TyVar::get_implicit_infer_var (locus);
+ args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
+ argument_mappings[symbol] = infer_var.get_tyty ();
+ }
+ }
+ else
+ {
+ args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
+ }
+ }
+
+ SubstitutionArgumentMappings infer_arguments (std::move (args), locus);
+ return handle_substitions (std::move (infer_arguments));
+}
+
SubstitutionArgumentMappings
SubstitutionRef::adjust_mappings_for_this (
SubstitutionArgumentMappings &mappings)
@@ -2479,7 +2510,13 @@ ParamType::resolve () const
break;
TyVar v (rr->get_ty_ref ());
- r = v.get_tyty ();
+ BaseType *n = v.get_tyty ();
+
+ // fix infinite loop
+ if (r == n)
+ break;
+
+ r = n;
}
if (r->get_kind () == TypeKind::PARAM && (r->get_ref () == r->get_ty_ref ()))
@@ -960,37 +960,7 @@ public:
solve_missing_mappings_from_this (SubstitutionRef &ref, SubstitutionRef &to);
// TODO comment
- BaseType *infer_substitions (Location locus)
- {
- std::vector<SubstitutionArg> args;
- std::map<std::string, BaseType *> argument_mappings;
- for (auto &p : get_substs ())
- {
- if (p.needs_substitution ())
- {
- const std::string &symbol = p.get_param_ty ()->get_symbol ();
- auto it = argument_mappings.find (symbol);
- if (it == argument_mappings.end ())
- {
- TyVar infer_var = TyVar::get_implicit_infer_var (locus);
- args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
- argument_mappings[symbol] = infer_var.get_tyty ();
- }
- else
- {
- args.push_back (SubstitutionArg (&p, it->second));
- }
- }
- else
- {
- args.push_back (
- SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
- }
- }
-
- SubstitutionArgumentMappings infer_arguments (std::move (args), locus);
- return handle_substitions (std::move (infer_arguments));
- }
+ BaseType *infer_substitions (Location locus);
// TODO comment
bool monomorphize ();
@@ -1059,6 +1029,8 @@ public:
bool contains_associated_types () const;
+ DefId get_id () const { return reference; }
+
private:
DefId reference;
Location locus;
@@ -419,7 +419,9 @@ Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
auto id = item->get_mappings ().get_hirid ();
rust_assert (lookup_hir_impl_block (id) == nullptr);
+ HirId impl_type_id = item->get_type ()->get_mappings ().get_hirid ();
hirImplBlockMappings[id] = item;
+ hirImplBlockTypeMappings[impl_type_id] = item;
insert_node_to_hir (item->get_mappings ().get_nodeid (), id);
}
@@ -433,6 +435,17 @@ Mappings::lookup_hir_impl_block (HirId id)
return it->second;
}
+bool
+Mappings::lookup_impl_block_type (HirId id, HIR::ImplBlock **impl_block)
+{
+ auto it = hirImplBlockTypeMappings.find (id);
+ if (it == hirImplBlockTypeMappings.end ())
+ return false;
+
+ *impl_block = it->second;
+ return true;
+}
+
void
Mappings::insert_module (HIR::Module *module)
{
@@ -123,6 +123,7 @@ public:
void insert_hir_impl_block (HIR::ImplBlock *item);
HIR::ImplBlock *lookup_hir_impl_block (HirId id);
+ bool lookup_impl_block_type (HirId id, HIR::ImplBlock **impl_block);
void insert_module (HIR::Module *module);
HIR::Module *lookup_module (HirId id);
@@ -314,6 +315,7 @@ private:
std::map<HirId, HIR::SelfParam *> hirSelfParamMappings;
std::map<HirId, HIR::ImplBlock *> hirImplItemsToImplMappings;
std::map<HirId, HIR::ImplBlock *> hirImplBlockMappings;
+ std::map<HirId, HIR::ImplBlock *> hirImplBlockTypeMappings;
std::map<HirId, HIR::TraitItem *> hirTraitItemMappings;
std::map<HirId, HIR::ExternBlock *> hirExternBlockMappings;
std::map<HirId, std::pair<HIR::ExternalItem *, HirId>> hirExternItemMappings;
@@ -1,12 +1,15 @@
+// bogus errors but shows the type checking system needs to support const
+// generics with defaults
+
struct Foo<const N: usize = { 14 }>;
const M: usize = 15;
-type N = Foo<3>;
+type N = Foo<3>; // { dg-error "TypePath Foo<> declares generic arguments but the type Foo{Foo {}} does not have any" }
fn main() {
- let _: Foo<15> = Foo;
- let _: Foo<{ M }> = Foo;
- let _: Foo<M> = Foo;
- // bogus error, but it means the above const generic gets disambiguated properly
+ let _: Foo<15> = Foo; // { dg-error "TypePath Foo<> declares generic arguments but the type Foo{Foo {}} does not have any" }
+ let _: Foo<{ M }> = Foo; // { dg-error "TypePath Foo<> declares generic arguments but the type Foo{Foo {}} does not have any" }
+ let _: Foo<M> = Foo; // { dg-error "TypePath Foo<> declares generic arguments but the type Foo{Foo {}} does not have any" }
+
let _: Foo<N> = Foo; // { dg-error "TypePath Foo<N> declares generic arguments but the type Foo{Foo {}} does not have any" }
}
@@ -9,4 +9,6 @@ impl<X, Y> Foo<X> {
fn main() {
let a = Foo::test();
+ // { dg-error "Failed to resolve expression of function call" "" { target *-*-* } .-1 }
+ // { dg-error "failed to type resolve expression" "" { target *-*-* } .-2 }
}