summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-03 12:08:29 +0800
committerJohn Hodge <tpg@mutabah.net>2016-07-03 12:08:29 +0800
commite6fa6b6369935d3f9aca3d608d1e5669d0e59574 (patch)
treed8926dff29f00f334c040bc1be2027ff5da9c09c
parent1d4f1e5081cbd6ed17f3ebfe5766f2c5834e95e7 (diff)
downloadmrust-e6fa6b6369935d3f9aca3d608d1e5669d0e59574.tar.gz
HIR Typecheck CS - Almost ready to invoke
-rw-r--r--src/hir_typeck/expr_cs.cpp232
1 files changed, 217 insertions, 15 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index a241790b..d96bbf76 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -41,6 +41,8 @@ struct Context
};
const ::HIR::Crate& m_crate;
+ const ::HIR::GenericParams* m_impl_params;
+ const ::HIR::GenericParams* m_item_params;
::std::vector<Binding> m_bindings;
HMTypeInferrence m_ivars;
@@ -50,9 +52,12 @@ struct Context
/// Nodes that need revisiting (e.g. method calls when the receiver isn't known)
::std::vector< ::HIR::ExprNode*> to_visit;
- Context(const ::HIR::Crate& crate):
- m_crate(crate)
- {}
+ Context(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params):
+ m_crate(crate),
+ m_impl_params( impl_params ),
+ m_item_params( item_params )
+ {
+ }
void add_ivars(::HIR::TypeRef& ty);
// - Equate two types, with no possibility of coercion
@@ -91,9 +96,10 @@ class ExprVisitor_Enum:
// TEMP: List of in-scope traits for buildup
::HIR::t_trait_list m_traits;
public:
- ExprVisitor_Enum(Context& context, const ::HIR::TypeRef& ret_type):
+ ExprVisitor_Enum(Context& context, ::HIR::t_trait_list base_traits, const ::HIR::TypeRef& ret_type):
context(context),
- ret_type(ret_type)
+ ret_type(ret_type),
+ m_traits( mv$(base_traits) )
{
}
@@ -609,6 +615,7 @@ private:
TODO(sp, "Hit a UfcsUnknown (" << path << ") - Is this an error?");
),
(UfcsInherent,
+ // TODO: What if this types has ivars?
// - Locate function (and impl block)
const ::HIR::TypeImpl* impl_ptr = nullptr;
this->context.m_crate.find_type_impls(*e.type, [&](const auto& ty)->const auto& {
@@ -1030,16 +1037,6 @@ private:
};
-void Typecheck_Code_CS(Context context, const ::HIR::TypeRef& result_type, ::HIR::ExprPtr& expr)
-{
- ExprVisitor_Enum visitor(context, result_type);
- expr->visit(visitor);
-
- context.equate_types(expr->span(), result_type, expr->m_res_type);
-
- // TODO: Run
-}
-
void Context::add_ivars(::HIR::TypeRef& ty) {
TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e),
(Infer,
@@ -1550,3 +1547,208 @@ void fix_param_count(const Span& sp, Context& context, const ::HIR::Path& path,
void fix_param_count(const Span& sp, Context& context, const ::HIR::GenericPath& path, const ::HIR::GenericParams& param_defs, ::HIR::PathParams& params) {
fix_param_count_(sp, context, path, param_defs, params);
}
+
+namespace {
+ struct ModuleState
+ {
+ ::HIR::Crate& m_crate;
+
+ ::HIR::GenericParams* m_impl_generics;
+ ::HIR::GenericParams* m_item_generics;
+
+ ::std::vector< ::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > m_traits;
+
+ ModuleState(::HIR::Crate& crate):
+ m_crate(crate),
+ m_impl_generics(nullptr),
+ m_item_generics(nullptr)
+ {}
+
+ template<typename T>
+ class NullOnDrop {
+ T*& ptr;
+ public:
+ NullOnDrop(T*& ptr):
+ ptr(ptr)
+ {}
+ ~NullOnDrop() {
+ ptr = nullptr;
+ }
+ };
+ NullOnDrop< ::HIR::GenericParams> set_impl_generics(::HIR::GenericParams& gps) {
+ assert( !m_impl_generics );
+ m_impl_generics = &gps;
+ return NullOnDrop< ::HIR::GenericParams>(m_impl_generics);
+ }
+ NullOnDrop< ::HIR::GenericParams> set_item_generics(::HIR::GenericParams& gps) {
+ assert( !m_item_generics );
+ m_item_generics = &gps;
+ return NullOnDrop< ::HIR::GenericParams>(m_item_generics);
+ }
+
+ void push_traits(const ::HIR::Module& mod) {
+ auto sp = Span();
+ DEBUG("Module has " << mod.m_traits.size() << " in-scope traits");
+ // - Push a NULL entry to prevent parent module import lists being searched
+ m_traits.push_back( ::std::make_pair(nullptr, nullptr) );
+ for( const auto& trait_path : mod.m_traits ) {
+ DEBUG("Push " << trait_path);
+ m_traits.push_back( ::std::make_pair( &trait_path, &this->m_crate.get_trait_by_path(sp, trait_path) ) );
+ }
+ }
+ void pop_traits(const ::HIR::Module& mod) {
+ DEBUG("Module has " << mod.m_traits.size() << " in-scope traits");
+ for(unsigned int i = 0; i < mod.m_traits.size(); i ++ )
+ m_traits.pop_back();
+ m_traits.pop_back();
+ }
+ };
+}
+
+
+typedef ::std::vector< ::std::pair<::HIR::Pattern, ::HIR::TypeRef> > t_args;
+void Typecheck_Code_CS(const ModuleState& ms, t_args& args, const ::HIR::TypeRef& result_type, ::HIR::ExprPtr& expr)
+{
+ Context context { ms.m_crate, ms.m_impl_generics, ms.m_item_generics };
+
+ for( auto& arg : args ) {
+ context.add_binding( Span(), arg.first, arg.second );
+ }
+
+ ExprVisitor_Enum visitor(context, ms.m_traits, result_type);
+ expr->visit(visitor);
+
+ context.equate_types(expr->span(), result_type, expr->m_res_type);
+
+ // TODO: Run
+}
+
+
+namespace {
+
+ class OuterVisitor:
+ public ::HIR::Visitor
+ {
+ ModuleState m_ms;
+ public:
+ OuterVisitor(::HIR::Crate& crate):
+ m_ms(crate)
+ {
+ }
+
+
+ public:
+ void visit_module(::HIR::PathChain p, ::HIR::Module& mod) override
+ {
+ m_ms.push_traits(mod);
+ ::HIR::Visitor::visit_module(p, mod);
+ m_ms.pop_traits(mod);
+ }
+
+ // NOTE: This is left here to ensure that any expressions that aren't handled by higher code cause a failure
+ void visit_expr(::HIR::ExprPtr& exp) {
+ TODO(Span(), "visit_expr");
+ }
+
+ void visit_trait(::HIR::PathChain p, ::HIR::Trait& item) override
+ {
+ auto _ = this->m_ms.set_impl_generics(item.m_params);
+ ::HIR::Visitor::visit_trait(p, item);
+ }
+
+ void visit_type_impl(::HIR::TypeImpl& impl) override
+ {
+ TRACE_FUNCTION_F("impl " << impl.m_type);
+ auto _ = this->m_ms.set_impl_generics(impl.m_params);
+
+ const auto& mod = this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module);
+ m_ms.push_traits(mod);
+ ::HIR::Visitor::visit_type_impl(impl);
+ m_ms.pop_traits(mod);
+ }
+ void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
+ {
+ TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type);
+ auto _ = this->m_ms.set_impl_generics(impl.m_params);
+
+ const auto& mod = this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module);
+ m_ms.push_traits(mod);
+ ::HIR::Visitor::visit_trait_impl(trait_path, impl);
+ m_ms.pop_traits(mod);
+ }
+ void visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl) override
+ {
+ TRACE_FUNCTION_F("impl " << trait_path << " for " << impl.m_type << " { }");
+ auto _ = this->m_ms.set_impl_generics(impl.m_params);
+
+ const auto& mod = this->m_ms.m_crate.get_mod_by_path(Span(), impl.m_src_module);
+ m_ms.push_traits(mod);
+ ::HIR::Visitor::visit_marker_impl(trait_path, impl);
+ m_ms.pop_traits(mod);
+ }
+
+ void visit_type(::HIR::TypeRef& ty) override
+ {
+ TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,
+ this->visit_type( *e.inner );
+ DEBUG("Array size " << ty);
+ t_args tmp;
+ Typecheck_Code_CS( m_ms, tmp, ::HIR::TypeRef(::HIR::CoreType::Usize), e.size );
+ )
+ else {
+ ::HIR::Visitor::visit_type(ty);
+ }
+ }
+ // ------
+ // Code-containing items
+ // ------
+ void visit_function(::HIR::PathChain p, ::HIR::Function& item) override {
+ auto _ = this->m_ms.set_item_generics(item.m_params);
+ if( item.m_code )
+ {
+ DEBUG("Function code " << p);
+ Typecheck_Code_CS( m_ms, item.m_args, item.m_return, item.m_code );
+ }
+ }
+ void visit_static(::HIR::PathChain p, ::HIR::Static& item) override {
+ //auto _ = this->m_ms.set_item_generics(item.m_params);
+ if( item.m_value )
+ {
+ DEBUG("Static value " << p);
+ t_args tmp;
+ Typecheck_Code_CS(m_ms, tmp, item.m_type, item.m_value);
+ }
+ }
+ void visit_constant(::HIR::PathChain p, ::HIR::Constant& item) override {
+ auto _ = this->m_ms.set_item_generics(item.m_params);
+ if( item.m_value )
+ {
+ DEBUG("Const value " << p);
+ t_args tmp;
+ Typecheck_Code_CS(m_ms, tmp, item.m_type, item.m_value);
+ }
+ }
+ void visit_enum(::HIR::PathChain p, ::HIR::Enum& item) override {
+ auto _ = this->m_ms.set_item_generics(item.m_params);
+
+ // TODO: Use a different type depding on repr()
+ auto enum_type = ::HIR::TypeRef(::HIR::CoreType::Usize);
+
+ // TODO: Check types too?
+ for(auto& var : item.m_variants)
+ {
+ TU_IFLET(::HIR::Enum::Variant, var.second, Value, e,
+ DEBUG("Enum value " << p << " - " << var.first);
+ t_args tmp;
+ Typecheck_Code_CS(m_ms, tmp, enum_type, e);
+ )
+ }
+ }
+ };
+}
+
+//void Typecheck_Expressions(::HIR::Crate& crate)
+//{
+// OuterVisitor visitor { crate };
+// visitor.visit_crate( crate );
+//}