diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/expr.cpp | 4 | ||||
-rw-r--r-- | src/hir/expr.hpp | 3 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 7 | ||||
-rw-r--r-- | src/hir/path.hpp | 3 | ||||
-rw-r--r-- | src/hir/pattern.hpp | 1 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 15 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 439 |
7 files changed, 373 insertions, 99 deletions
diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index 59651c57..e9768e02 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -11,8 +11,10 @@ const Span& ::HIR::ExprNode::span() const return rv; } -#define DEF_VISIT(nt, n, code) void ::HIR::nt::visit(ExprVisitor& nv) { nv.visit(*this); } void ::HIR::ExprVisitorDef::visit(::HIR::nt& n) { code } +#define DEF_VISIT(nt, n, code) void ::HIR::nt::visit(ExprVisitor& nv) { nv.visit_node(*this); nv.visit(*this); } void ::HIR::ExprVisitorDef::visit(::HIR::nt& n) { code } +void ::HIR::ExprVisitor::visit_node(::HIR::ExprNode& node) { +} DEF_VISIT(ExprNode_Block, node, for(const auto& subnode : node.m_nodes) { assert(subnode); diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 1f13bea7..5d55393c 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -14,7 +14,7 @@ class ExprVisitor; class ExprNode { public: - //::HIR::TypeRef m_res_type; + ::HIR::TypeRef m_res_type; const Span& span() const; @@ -436,6 +436,7 @@ struct ExprNode_Closure: class ExprVisitor { public: + virtual void visit_node(ExprNode& node); #define NV(nt) virtual void visit(nt& n) = 0; NV(ExprNode_Block) diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 8f306957..a3584663 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -8,6 +8,7 @@ ::HIR::Module LowerHIR_Module(const ::AST::Module& module, ::HIR::SimplePath path); ::HIR::Function LowerHIR_Function(const ::AST::Function& f); +::HIR::SimplePath LowerHIR_SimplePath(const Span& sp, const ::AST::Path& path, bool allow_final_generic = false); // -------------------------------------------------------------------- ::HIR::GenericParams LowerHIR_GenericParams(const ::AST::GenericParams& gp) @@ -330,7 +331,7 @@ } } -::HIR::SimplePath LowerHIR_SimplePath(const ::AST::Path& path, bool allow_final_generic = false) +::HIR::SimplePath LowerHIR_SimplePath(const Span& sp, const ::AST::Path& path, bool allow_final_generic) { TU_IFLET(::AST::Path::Class, path.m_class, Absolute, e, ::HIR::SimplePath rv( e.crate ); @@ -357,7 +358,7 @@ ::HIR::GenericPath LowerHIR_GenericPath(const Span& sp, const ::AST::Path& path) { TU_IFLET(::AST::Path::Class, path.m_class, Absolute, e, - auto sp = LowerHIR_SimplePath(path, true); + auto simpepath = LowerHIR_SimplePath(sp, path, true); ::HIR::PathParams params; const auto& src_params = e.nodes.back().args(); //for(const auto& param : src_params.m_lifetimes) { @@ -366,7 +367,7 @@ params.m_types.push_back( LowerHIR_Type(param) ); } // TODO: Lifetime params (not encoded in AST::PathNode as yet) - auto rv = ::HIR::GenericPath(mv$(sp), mv$(params)); + auto rv = ::HIR::GenericPath(mv$(simpepath), mv$(params)); DEBUG(path << " => " << rv); return rv; ) diff --git a/src/hir/path.hpp b/src/hir/path.hpp index e482469e..b5bc061b 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -35,6 +35,9 @@ struct SimplePath bool operator==(const SimplePath& x) const { return m_crate_name == x.m_crate_name && m_components == x.m_components; } + bool operator!=(const SimplePath& x) const { + return !(*this == x); + } bool operator<(const SimplePath& x) const { if( m_crate_name < x.m_crate_name ) return true; if( m_components < x.m_components ) return true; diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index 0db35059..fc763f54 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -60,6 +60,7 @@ struct Pattern (Ref, struct { ::HIR::BorrowType type; ::std::unique_ptr<Pattern> sub; } ), (Tuple, struct { ::std::vector<Pattern> sub_patterns; } ), (StructTuple, struct { + // NOTE: Type paths in patterns _can_ have parameters GenericPath path; const Struct* binding; ::std::vector<Pattern> sub_patterns; diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 4b4acf4d..948a3d75 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -83,6 +83,16 @@ namespace { throw ""; } + void fix_type_params(const Span& sp, const ::HIR::GenericParams& params_def, ::HIR::PathParams& params) + { + if( params.m_types.size() == 0 ) { + params.m_types.resize( params_def.m_types.size() ); + } + if( params.m_types.size() != params_def.m_types.size() ) { + ERROR(sp, E0000, "Incorrect parameter count, expected " << params_def.m_types.size() << ", got " << params.m_types.size()); + } + } + class Visitor: public ::HIR::Visitor { @@ -111,6 +121,8 @@ namespace { else { ERROR(sp, E0000, "Struct tuple pattern on non-tuple struct " << e.path); } + + fix_type_params(sp, str.m_params, e.path.m_params); e.binding = &str; ), (Struct, @@ -121,6 +133,7 @@ namespace { else { ERROR(sp, E0000, "Struct pattern on field-less struct " << e.path); } + fix_type_params(sp, str.m_params, e.path.m_params); e.binding = &str; ), (EnumTuple, @@ -137,6 +150,7 @@ namespace { else { ERROR(sp, E0000, "Enum tuple pattern on non-tuple variant " << e.path); } + fix_type_params(sp, enm.m_params, e.path.m_params); e.binding_ptr = &enm; e.binding_idx = idx; ), @@ -154,6 +168,7 @@ namespace { else { ERROR(sp, E0000, "Enum tuple pattern on non-tuple variant " << e.path); } + fix_type_params(sp, enm.m_params, e.path.m_params); e.binding_ptr = &enm; e.binding_idx = idx; ) diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index cb95fb42..18937155 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -4,9 +4,136 @@ #include <hir/expr.hpp> #include <hir/hir.hpp> #include <hir/visitor.hpp> +#include <algorithm> // std::find_if namespace { + bool monomorphise_type_needed(const ::HIR::TypeRef& tpl); + + bool monomorphise_pathparams_needed(const ::HIR::PathParams& tpl) + { + for(const auto& ty : tpl.m_types) + if( monomorphise_type_needed(ty) ) + return true; + return false; + } + bool monomorphise_path_needed(const ::HIR::Path& tpl) + { + TU_MATCH(::HIR::Path::Data, (tpl.m_data), (e), + (Generic, + return monomorphise_pathparams_needed(e.m_params); + ), + (UfcsInherent, + return monomorphise_type_needed(*e.type) || monomorphise_pathparams_needed(e.params); + ), + (UfcsKnown, + return monomorphise_type_needed(*e.type) || monomorphise_pathparams_needed(e.trait.m_params) || monomorphise_pathparams_needed(e.params); + ), + (UfcsUnknown, + return monomorphise_type_needed(*e.type) || monomorphise_pathparams_needed(e.params); + ) + ) + throw ""; + } + bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) + { + TU_MATCH(::HIR::TypeRef::Data, (tpl.m_data), (e), + (Infer, + assert(!"ERROR: _ type found in monomorphisation target"); + ), + (Diverge, + return false; + ), + (Primitive, + return false; + ), + (Path, + return monomorphise_path_needed(e.path); + ), + (Generic, + return true; + ), + (TraitObject, + TODO(Span(), "TraitObject - " << tpl); + ), + (Array, + TODO(Span(), "Array - " << tpl); + ), + (Slice, + return monomorphise_type_needed(*e.inner); + ), + (Tuple, + for(const auto& ty : e) { + if( monomorphise_type_needed(ty) ) + return true; + } + return false; + ), + (Borrow, + return monomorphise_type_needed(*e.inner); + ), + (Pointer, + return monomorphise_type_needed(*e.inner); + ), + (Function, + TODO(Span(), "Function - " << tpl); + ) + ) + throw ""; + } + //::HIR::Path monomorphise_path(const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::Path& tpl) + //{ + //} + ::HIR::TypeRef monomorphise_type(const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl) + { + TU_MATCH(::HIR::TypeRef::Data, (tpl.m_data), (e), + (Infer, + assert(!"ERROR: _ type found in monomorphisation target"); + ), + (Diverge, + return ::HIR::TypeRef(e); + ), + (Primitive, + return ::HIR::TypeRef(e); + ), + (Path, + TODO(Span(), "Path"); + ), + (Generic, + if( e.binding >= params.m_types.size() ) { + BUG(Span(), "Generic param out of range"); + } + return params.m_types[e.binding].clone(); + ), + (TraitObject, + TODO(Span(), "TraitObject"); + ), + (Array, + TODO(Span(), "Array"); + ), + (Slice, + return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Slice({ box$(monomorphise_type(params_def, params, *e.inner)) }) ); + ), + (Tuple, + ::std::vector< ::HIR::TypeRef> types; + for(const auto& ty : e) { + types.push_back( monomorphise_type(params_def, params, ty) ); + } + return ::HIR::TypeRef( mv$(types) ); + ), + (Borrow, + return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Borrow({ e.type, box$(monomorphise_type(params_def, params, *e.inner)) }) ); + ), + (Pointer, + return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Pointer({ e.is_mut, box$(monomorphise_type(params_def, params, *e.inner)) }) ); + ), + (Function, + TODO(Span(), "Function"); + ) + ) + throw ""; + } + struct IVar { unsigned int alias; @@ -83,6 +210,11 @@ namespace { ) ) } + void add_ivars_params(::HIR::PathParams& params) + { + for(auto& arg : params.m_types) + add_ivars(arg); + } void add_pattern_binding(const ::HIR::PatternBinding& pb, ::HIR::TypeRef type) @@ -102,12 +234,15 @@ namespace { } } - void add_binding(const ::HIR::Pattern& pat, ::HIR::TypeRef type) + void add_binding(::HIR::Pattern& pat, ::HIR::TypeRef& type) { + static Span _sp; + const Span& sp = _sp; + if( pat.m_binding.is_valid() ) { - this->add_pattern_binding(pat.m_binding, mv$(type)); + this->add_pattern_binding(pat.m_binding, type.clone()); // TODO: Can there be bindings within a bound pattern? - return ; + //return ; } // @@ -116,100 +251,86 @@ namespace { // Just leave it, the pattern says nothing ), (Value, - TODO(Span(), "Value pattern"); + //TODO(sp, "Value pattern"); ), (Range, - TODO(Span(), "Range pattern"); + //TODO(sp, "Range pattern"); ), (Box, - // Type must be box-able - TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), - ( - // TODO: Type mismatch - ), - (Infer, - // Apply rule based on recursing the pattern? - this->add_binding(*e.sub, this->new_ivar_tr()); - ) - ) + TODO(sp, "Box pattern"); ), (Ref, + if( type.m_data.is_Infer() ) { + type.m_data = ::HIR::TypeRef::Data::make_Borrow({ e.type, box$(this->new_ivar_tr()) }); + } // Type must be a &-ptr TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), + (Infer, throw "";), (Borrow, if( te.type != e.type ) { // TODO: Type mismatch } - this->add_binding( *e.sub, mv$(*te.inner) ); - ), - (Infer, - // Apply rule based on recursing the pattern? - this->add_binding( *e.sub, this->new_ivar_tr()); + this->add_binding( *e.sub, *te.inner ); ) ) ), (Tuple, + if( type.m_data.is_Infer() ) { + ::std::vector< ::HIR::TypeRef> sub_types; + for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) + sub_types.push_back( this->new_ivar_tr() ); + type.m_data = ::HIR::TypeRef::Data::make_Tuple( mv$(sub_types) ); + } TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), + (Infer, throw ""; ), (Tuple, if( te.size() != e.sub_patterns.size() ) { // TODO: Type mismatch } for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) - this->add_binding( e.sub_patterns[i], mv$(te[i]) ); - ), - (Infer, - // Apply rule based on recursing the pattern? - for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) - this->add_binding( e.sub_patterns[i], this->new_ivar_tr() ); + this->add_binding( e.sub_patterns[i], te[i] ); ) ) ), (Slice, + if( type.m_data.is_Infer() ) { + type.m_data = ::HIR::TypeRef::Data::make_Slice( {box$(this->new_ivar_tr())} ); + this->mark_change(); + } TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), + (Infer, throw""; ), (Slice, - for(const auto& sp : e.sub_patterns) - this->add_binding( sp, te.inner->clone() ); - ), - (Infer, - // Apply rule based on recursing the pattern? - auto ty = this->new_ivar_tr(); - for(const auto& sp : e.sub_patterns) - this->add_binding( sp, ty.clone() ); + for(auto& sp : e.sub_patterns) + this->add_binding( sp, *te.inner ); ) ) ), (SplitSlice, + if( type.m_data.is_Infer() ) { + type.m_data = ::HIR::TypeRef::Data::make_Slice( {box$(this->new_ivar_tr())} ); + this->mark_change(); + } TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), + (Infer, throw ""; ), (Slice, - for(const auto& sp : e.leading) - this->add_binding( sp, te.inner->clone() ); - for(const auto& sp : e.trailing) - this->add_binding( sp, te.inner->clone() ); - if( e.extra_bind.is_valid() ) { - this->add_local( e.extra_bind.m_slot, ::HIR::TypeRef(::HIR::TypeRef::Data::make_Slice({ box$(mv$(*te.inner)) })) ); - } - ), - (Infer, - // Apply rule based on recursing the pattern? - auto ty = this->new_ivar_tr(); - for(const auto& sp : e.leading) - this->add_binding( sp, ty.clone() ); - for(const auto& sp : e.trailing) - this->add_binding( sp, ty.clone() ); + for(auto& sp : e.leading) + this->add_binding( sp, *te.inner ); + for(auto& sp : e.trailing) + this->add_binding( sp, *te.inner ); if( e.extra_bind.is_valid() ) { - this->add_local( e.extra_bind.m_slot, ::HIR::TypeRef(::HIR::TypeRef::Data::make_Slice({ box$(mv$(ty)) })) ); + this->add_local( e.extra_bind.m_slot, type.clone() ); } ) ) @@ -217,54 +338,169 @@ namespace { // - Enums/Structs (StructTuple, + this->add_ivars_params( e.path.m_params ); + if( type.m_data.is_Infer() ) { + type.m_data = ::HIR::TypeRef::Data::make_Path( {e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)} ); + } + assert(e.binding); + const auto& str = *e.binding; + // - assert check from earlier pass + assert( str.m_data.is_Tuple() ); + const auto& sd = str.m_data.as_Tuple(); + TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), - (Infer, - TODO(Span(), "StructTuple - bind + infer"); - ), + (Infer, throw ""; ), (Path, - TODO(Span(), "StructTuple - bind"); + if( ! te.binding.is_Struct() || te.binding.as_Struct() != &str ) { + ERROR(sp, E0000, "Type mismatch in struct pattern - " << type << " is not " << e.path); + } + // NOTE: Must be Generic for the above to have passed + auto& gp = te.path.m_data.as_Generic(); + + if( e.sub_patterns.size() != sd.size() ) { + ERROR(sp, E0000, "Tuple struct pattern with an incorrect number of fields"); + } + for( unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) + { + const auto& field_type = sd[i].ent; + if( monomorphise_type_needed(field_type) ) { + auto var_ty = monomorphise_type(str.m_params, gp.m_params, field_type); + this->add_binding(e.sub_patterns[i], var_ty); + } + else { + // SAFE: Can't have _ as monomorphise_type_needed checks for that + this->add_binding(e.sub_patterns[i], const_cast< ::HIR::TypeRef&>(field_type)); + } + } ) ) ), (Struct, + this->add_ivars_params( e.path.m_params ); + if( type.m_data.is_Infer() ) { + type.m_data = ::HIR::TypeRef::Data::make_Path( {e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)} ); + } + assert(e.binding); + const auto& str = *e.binding; + // - assert check from earlier pass + assert( str.m_data.is_Named() ); + const auto& sd = str.m_data.as_Named(); + TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), - (Infer, - TODO(Span(), "Struct - bind + infer"); - ), + (Infer, throw ""; ), (Path, - TODO(Span(), "Struct - bind"); + if( ! te.binding.is_Struct() || te.binding.as_Struct() != &str ) { + ERROR(sp, E0000, "Type mismatch in struct pattern - " << type << " is not " << e.path); + } + // NOTE: Must be Generic for the above to have passed + auto& gp = te.path.m_data.as_Generic(); + for( auto& field_pat : e.sub_patterns ) + { + unsigned int f_idx = ::std::find_if( sd.begin(), sd.end(), [&](const auto& x){ return x.first == field_pat.first; } ) - sd.begin(); + if( f_idx == sd.size() ) { + ERROR(sp, E0000, "Struct " << e.path << " doesn't have a field " << field_pat.first); + } + const ::HIR::TypeRef& field_type = sd[f_idx].second.ent; + if( monomorphise_type_needed(field_type) ) { + auto field_type_mono = monomorphise_type(str.m_params, gp.m_params, field_type); + this->add_binding(field_pat.second, field_type_mono); + } + else { + // SAFE: Can't have _ as monomorphise_type_needed checks for that + this->add_binding(field_pat.second, const_cast< ::HIR::TypeRef&>(field_type)); + } + } ) ) ), (EnumTuple, + this->add_ivars_params( e.path.m_params ); + if( type.m_data.is_Infer() ) { + auto path = e.path.clone(); + path.m_path.m_components.pop_back(); + type.m_data = ::HIR::TypeRef::Data::make_Path( {mv$(path), ::HIR::TypeRef::TypePathBinding(e.binding_ptr)} ); + } + assert(e.binding_ptr); + const auto& enm = *e.binding_ptr; + const auto& var = enm.m_variants[e.binding_idx].second; + assert(var.is_Tuple()); + const auto& tup_var = var.as_Tuple(); + TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), - (Infer, - TODO(Span(), "EnumTuple - bind + infer"); - ), + (Infer, throw ""; ), (Path, - TODO(Span(), "EnumTuple - bind"); + if( ! te.binding.is_Enum() || te.binding.as_Enum() != &enm ) { + ERROR(sp, E0000, "Type mismatch in enum pattern - " << type << " is not " << e.path); + } + // NOTE: Must be Generic for the above to have passed + auto& gp = te.path.m_data.as_Generic(); + if( e.sub_patterns.size() != tup_var.size() ) { + ERROR(sp, E0000, "Enum pattern with an incorrect number of fields - " << e.path << " - expected " << tup_var.size() << ", got " << e.sub_patterns.size()); + } + for( unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) + { + if( monomorphise_type_needed(tup_var[i]) ) { + auto var_ty = monomorphise_type(enm.m_params, gp.m_params, tup_var[i]); + this->add_binding(e.sub_patterns[i], var_ty); + } + else { + // SAFE: Can't have _ as monomorphise_type_needed checks for that + this->add_binding(e.sub_patterns[i], const_cast< ::HIR::TypeRef&>(tup_var[i])); + } + } ) ) ), (EnumStruct, + this->add_ivars_params( e.path.m_params ); + if( type.m_data.is_Infer() ) { + auto path = e.path.clone(); + path.m_path.m_components.pop_back(); + type.m_data = ::HIR::TypeRef::Data::make_Path( {mv$(path), ::HIR::TypeRef::TypePathBinding(e.binding_ptr)} ); + } + assert(e.binding_ptr); + const auto& enm = *e.binding_ptr; + const auto& var = enm.m_variants[e.binding_idx].second; + assert(var.is_Struct()); + const auto& tup_var = var.as_Struct(); + TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (te), ( // TODO: Type mismatch ), - (Infer, - TODO(Span(), "EnumStruct - bind + infer"); - ), + (Infer, throw ""; ), (Path, - TODO(Span(), "EnumStruct - bind"); + if( ! te.binding.is_Enum() || te.binding.as_Enum() != &enm ) { + ERROR(sp, E0000, "Type mismatch in enum pattern - " << type << " is not " << e.path); + } + // NOTE: Must be Generic for the above to have passed + auto& gp = te.path.m_data.as_Generic(); + + for( auto& field_pat : e.sub_patterns ) + { + unsigned int f_idx = ::std::find_if( tup_var.begin(), tup_var.end(), [&](const auto& x){ return x.first == field_pat.first; } ) - tup_var.begin(); + if( f_idx == tup_var.size() ) { + ERROR(sp, E0000, "Enum variant " << e.path << " doesn't have a field " << field_pat.first); + } + const ::HIR::TypeRef& field_type = tup_var[f_idx].second; + if( monomorphise_type_needed(field_type) ) { + auto field_type_mono = monomorphise_type(enm.m_params, gp.m_params, field_type); + this->add_binding(field_pat.second, field_type_mono); + } + else { + // SAFE: Can't have _ as monomorphise_type_needed checks for that + this->add_binding(field_pat.second, const_cast< ::HIR::TypeRef&>(field_type)); + } + } ) ) ) @@ -297,8 +533,7 @@ namespace { ), (Ref, if( ty.m_data.is_Infer() ) { - ty.m_data = ::HIR::TypeRef::Data::make_Borrow( {e.type, box$(this->new_ivar_tr())} ); - this->mark_change(); + BUG(sp, "Infer type hit that should already have been fixed"); } // Type must be a &-ptr TU_MATCH_DEF(::HIR::TypeRef::Data, (ty.m_data), (te), @@ -316,12 +551,7 @@ namespace { ), (Tuple, if( ty.m_data.is_Infer() ) { - ::std::vector< ::HIR::TypeRef> sub_types; - for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) - sub_types.push_back( this->new_ivar_tr() ); - ty.m_data = ::HIR::TypeRef::Data::make_Tuple( mv$(sub_types) ); - - this->mark_change(); + BUG(sp, "Infer type hit that should already have been fixed"); } TU_MATCH_DEF(::HIR::TypeRef::Data, (ty.m_data), (te), ( @@ -340,8 +570,7 @@ namespace { // --- Slices (Slice, if( ty.m_data.is_Infer() ) { - ty.m_data = ::HIR::TypeRef::Data::make_Slice( {box$(this->new_ivar_tr())} ); - this->mark_change(); + BUG(sp, "Infer type hit that should already have been fixed"); } TU_MATCH_DEF(::HIR::TypeRef::Data, (ty.m_data), (te), ( @@ -356,8 +585,7 @@ namespace { ), (SplitSlice, if( ty.m_data.is_Infer() ) { - ty.m_data = ::HIR::TypeRef::Data::make_Slice( {box$(this->new_ivar_tr())} ); - this->mark_change(); + BUG(sp, "Infer type hit that should already have been fixed"); } TU_MATCH_DEF(::HIR::TypeRef::Data, (ty.m_data), (te), ( @@ -377,7 +605,7 @@ namespace { // - Enums/Structs (StructTuple, if( ty.m_data.is_Infer() ) { - TODO(sp, "StructTuple - infer"); + ty.m_data = ::HIR::TypeRef::Data::make_Path( {e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)} ); this->mark_change(); } @@ -387,7 +615,7 @@ namespace { ), (Infer, throw "";), (Path, - TODO(sp, "StructTuple - destructure"); + // TODO: Does anything need to happen here? This can only introduce equalities? ) ) ), @@ -404,12 +632,7 @@ namespace { ), (Infer, throw "";), (Path, - if( ! te.path.m_data.is_Generic() ) { - ERROR(sp, E0000, "UFCS path being destructured - " << te.path); - } - const auto& s = *te.binding.as_Struct(); - assert(&s); - TODO(sp, "Struct - destructure - " << te.path); + // TODO: Does anything need to happen here? This can only introduce equalities? ) ) ), @@ -425,7 +648,6 @@ namespace { ), (Infer, throw "";), (Path, - TODO(sp, "EnumTuple - destructure"); ) ) ), @@ -441,7 +663,6 @@ namespace { ), (Infer, throw "";), (Path, - TODO(sp, "EnumStruct - destructure"); ) ) ) @@ -488,16 +709,28 @@ namespace { { } + void visit_node(::HIR::ExprNode& node) override { + this->context.add_ivars(node.m_res_type); + } void visit(::HIR::ExprNode_Let& node) override { this->context.add_ivars(node.m_type); - this->context.add_binding(node.m_pattern, node.m_type.clone()); - //if( node.m_value ) { - // this->context.add_rule_equality(node.m_type, node.m_value->m_res_type); - //} + this->context.add_binding(node.m_pattern, node.m_type); } + void visit(::HIR::ExprNode_Match& node) override + { + ::HIR::ExprVisitorDef::visit(node); + + for(auto& arm : node.m_arms) + { + for(auto& pat : arm.m_patterns) + { + this->context.add_binding(pat, node.m_res_type); + } + } + } }; class ExprVisitor_Run: @@ -648,8 +881,9 @@ namespace { if( &*item.m_code ) { TypecheckContext typeck_context { item.m_return }; - for( const auto& arg : item.m_args ) - typeck_context.add_binding( arg.first, arg.second.clone() ); + for( auto& arg : item.m_args ) { + typeck_context.add_binding( arg.first, arg.second ); + } Typecheck_Code( mv$(typeck_context), *item.m_code ); } } @@ -658,6 +892,7 @@ namespace { if( &*item.m_value ) { TypecheckContext typeck_context { item.m_type }; + Typecheck_Code( mv$(typeck_context), *item.m_value ); } } void visit_constant(::HIR::Constant& item) override { @@ -665,6 +900,22 @@ namespace { if( &*item.m_value ) { TypecheckContext typeck_context { item.m_type }; + Typecheck_Code( mv$(typeck_context), *item.m_value ); + } + } + void visit_enum(::HIR::Enum& item) override { + auto _ = this->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, + TypecheckContext typeck_context { enum_type }; + Typecheck_Code( mv$(typeck_context), *e ); + ) } } }; |