diff options
-rw-r--r-- | src/hir/expr.hpp | 5 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 61 |
2 files changed, 51 insertions, 15 deletions
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 36fd8bef..300414b4 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -9,6 +9,8 @@ namespace HIR { +typedef ::std::vector< ::std::pair<const ::HIR::SimplePath*,const ::HIR::Trait*> > t_trait_list; + class GenericParams; class ExprVisitor; @@ -44,7 +46,7 @@ struct ExprNode_Block: ::std::vector< ExprNodeP > m_nodes; ::HIR::SimplePath m_local_mod; - ::std::vector< ::std::pair<const ::HIR::SimplePath*,const ::HIR::Trait*> > m_traits; + t_trait_list m_traits; ExprNode_Block(Span sp): ExprNode(mv$(sp)), @@ -431,6 +433,7 @@ struct ExprNode_CallMethod: // - Set during typeck to the real path to the method ::HIR::Path m_method_path; ExprCallCache m_cache; + t_trait_list m_traits; ExprNode_CallMethod(Span sp, ::HIR::ExprNodeP val, ::std::string method_name, ::HIR::PathParams params, ::std::vector< ::HIR::ExprNodeP> args): ExprNode( mv$(sp) ), diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 7175e2dc..893a6f85 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -62,7 +62,7 @@ struct Context // - Equate two types, allowing inferrence void equate_types_coerce(const Span& sp, const ::HIR::TypeRef& l, ::HIR::ExprNodeP& node_ptr); // - Equate - void equate_types_assoc(const Span& sp, const ::HIR::TypeRef& l, const ::HIR::SimplePath& trait, const ::std::vector< ::HIR::TypeRef>& ty_args, const ::HIR::TypeRef& impl_ty, const char *name); + void equate_types_assoc(const Span& sp, const ::HIR::TypeRef& l, const ::HIR::SimplePath& trait, ::std::vector< ::HIR::TypeRef> ty_args, const ::HIR::TypeRef& impl_ty, const char *name); // - Add a pattern binding (forcing the type to match) void add_binding(const Span& sp, ::HIR::Pattern& pat, ::HIR::TypeRef& type); @@ -73,10 +73,6 @@ struct Context // - Add a revisit entry void add_revisit(::HIR::ExprNode& node); - typedef ::std::vector<::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > t_trait_list; - void push_traits(const t_trait_list& list); - void pop_traits(const t_trait_list& list); - const ::HIR::TypeRef& get_type(const ::HIR::TypeRef& ty) const { return m_ivars.get_type(ty); } private: @@ -91,6 +87,9 @@ class ExprVisitor_Enum: { Context& context; const ::HIR::TypeRef& ret_type; + + // TEMP: List of in-scope traits for buildup + ::HIR::t_trait_list m_traits; public: ExprVisitor_Enum(Context& context, const ::HIR::TypeRef& ret_type): context(context), @@ -101,7 +100,7 @@ public: void visit(::HIR::ExprNode_Block& node) override { TRACE_FUNCTION_F("{ ... }"); - this->context.push_traits( node.m_traits ); + this->push_traits( node.m_traits ); for( unsigned int i = 0; i < node.m_nodes.size(); i ++ ) { @@ -118,7 +117,7 @@ public: snp->visit(*this); } - this->context.pop_traits( node.m_traits ); + this->pop_traits( node.m_traits ); } void visit(::HIR::ExprNode_Return& node) override { @@ -550,7 +549,8 @@ public: this->context.add_ivars( val->m_res_type ); } - // TODO: Locate method and link arguments + // Nothing can be done until type is known + this->context.add_revisit(node); node.m_value->visit( *this ); for( auto& val : node.m_args ) { @@ -565,7 +565,26 @@ public: this->context.add_ivars( val->m_res_type ); } - // Resolution can't be done until lefthand type is know. + // - Search in-scope trait list for traits that provide a method of this name + const ::std::string& method_name = node.m_method; + ::HIR::t_trait_list possible_traits; + for(const auto& trait_ref : ::reverse(m_traits)) + { + if( trait_ref.first == nullptr ) + break; + + // TODO: Search supertraits too + auto it = trait_ref.second->m_values.find(method_name); + if( it == trait_ref.second->m_values.end() ) + continue ; + if( !it->second.is_Function() ) + continue ; + possible_traits.push_back( trait_ref ); + } + // > Store the possible set of traits for later + node.m_traits = mv$(possible_traits); + + // Resolution can't be done until lefthand type is known. // > Has to be done during iteraton this->context.add_revisit( node ); @@ -816,6 +835,14 @@ public: node.m_code->visit( *this ); } + +private: + void push_traits(const ::HIR::t_trait_list& list) { + this->m_traits.insert( this->m_traits.end(), list.begin(), list.end() ); + } + void pop_traits(const ::HIR::t_trait_list& list) { + this->m_traits.erase( this->m_traits.end() - list.size(), this->m_traits.end() ); + } }; @@ -825,6 +852,8 @@ void Typecheck_Code_CS(Context context, const ::HIR::TypeRef& result_type, ::HIR expr->visit(visitor); context.equate_types(expr->span(), result_type, expr->m_res_type); + + // TODO: Run } void Context::add_ivars(::HIR::TypeRef& ty) { @@ -1269,8 +1298,16 @@ void Context::equate_types_coerce(const Span& sp, const ::HIR::TypeRef& l, ::HIR l.clone(), node_ptr }); } -void Context::equate_types_assoc(const Span& sp, const ::HIR::TypeRef& l, const ::HIR::SimplePath& trait, const ::std::vector< ::HIR::TypeRef>& ty_args, const ::HIR::TypeRef& impl_ty, const char *name) +void Context::equate_types_assoc(const Span& sp, const ::HIR::TypeRef& l, const ::HIR::SimplePath& trait, ::std::vector< ::HIR::TypeRef> ty_args, const ::HIR::TypeRef& impl_ty, const char *name) { + this->link_assoc.push_back(Associated { + l.clone(), + + trait.clone(), + mv$(ty_args), + impl_ty.clone(), + name + }); } void Context::add_revisit(::HIR::ExprNode& node) { this->to_visit.push_back( &node ); @@ -1290,10 +1327,6 @@ const ::HIR::TypeRef& Context::get_var(const Span& sp, unsigned int idx) const { BUG(sp, "get_var - Binding index out of range"); } } -void Context::push_traits(const t_trait_list& list) { -} -void Context::pop_traits(const t_trait_list& list) { -} template<typename T> |