diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-04 13:48:21 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-04 13:48:21 +0800 |
commit | f92a45d8054cc18a037449ec136bf874ce20fc5a (patch) | |
tree | 0a0f977790faaa73f1b7987b3abbc7dbfc3e9364 /src | |
parent | e33d210a4a85e91abe04f1874f460b6e60c6b5e0 (diff) | |
download | mrust-f92a45d8054cc18a037449ec136bf874ce20fc5a.tar.gz |
HIR Typeck - Add slice unsize, breaks due to inferrence order
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/expr.cpp | 3 | ||||
-rw-r--r-- | src/hir/expr.hpp | 39 | ||||
-rw-r--r-- | src/hir/path.hpp | 2 | ||||
-rw-r--r-- | src/hir/type.cpp | 13 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 7 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 52 |
6 files changed, 102 insertions, 14 deletions
diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index e9768e02..a56e608a 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -67,6 +67,9 @@ DEF_VISIT(ExprNode_UniOp, node, DEF_VISIT(ExprNode_Cast, node, node.m_value->visit(*this); ) +DEF_VISIT(ExprNode_Unsize, node, + node.m_value->visit(*this); +) DEF_VISIT(ExprNode_Index, node, node.m_val->visit(*this); node.m_index->visit(*this); diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 5343228e..037a848c 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -55,7 +55,7 @@ struct ExprNode_Return: ::HIR::ExprNodeP m_value; ExprNode_Return(::HIR::ExprNodeP value): - ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})), + ExprNode(::HIR::TypeRef::Data::make_Diverge({})), m_value( mv$(value) ) { } @@ -84,7 +84,7 @@ struct ExprNode_LoopControl: //::HIR::ExprNodeP m_value; ExprNode_LoopControl(::std::string label, bool cont): - ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})), + ExprNode(::HIR::TypeRef::Data::make_Diverge({})), m_label( mv$(label) ), m_continue( cont ) {} @@ -198,7 +198,19 @@ struct ExprNode_BinOp: m_op(op), m_left( mv$(left) ), m_right( mv$(right) ) - {} + { + switch(m_op) + { + case Op::BoolAnd: case Op::BoolOr: + case Op::CmpEqu: case Op::CmpNEqu: + case Op::CmpLt: case Op::CmpLtE: + case Op::CmpGt: case Op::CmpGtE: + m_res_type = ::HIR::TypeRef( ::HIR::CoreType::Bool ); + break; + default: + break; + } + } NODE_METHODS(); }; @@ -235,6 +247,19 @@ struct ExprNode_Cast: NODE_METHODS(); }; +struct ExprNode_Unsize: + public ExprNode +{ + ::HIR::ExprNodeP m_value; + ::HIR::TypeRef m_type; + + ExprNode_Unsize(::HIR::ExprNodeP value, ::HIR::TypeRef dst_type): + m_value( mv$(value) ), + m_type( mv$(dst_type) ) + {} + + NODE_METHODS(); +}; struct ExprNode_Index: public ExprNode { @@ -414,7 +439,9 @@ struct ExprNode_StructLiteral: m_path( mv$(path) ), m_base_value( mv$(base_value) ), m_values( mv$(values) ) - {} + { + // TODO: set m_res_type based on path + } NODE_METHODS(); }; @@ -498,7 +525,8 @@ public: NV(ExprNode_Assign) NV(ExprNode_BinOp) NV(ExprNode_UniOp) - NV(ExprNode_Cast) + NV(ExprNode_Cast) // Conversion + NV(ExprNode_Unsize) // Coercion NV(ExprNode_Index) NV(ExprNode_Deref) @@ -538,6 +566,7 @@ public: NV(ExprNode_BinOp) NV(ExprNode_UniOp) NV(ExprNode_Cast) + NV(ExprNode_Unsize) NV(ExprNode_Index) NV(ExprNode_Deref) diff --git a/src/hir/path.hpp b/src/hir/path.hpp index b5bc061b..02aedba4 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -56,6 +56,8 @@ struct PathParams //bool operator==(const PathParams& x) const; //bool operator<(const PathParams& x) const; + + friend ::std::ostream& operator<<(::std::ostream& os, const PathParams& x); }; /// Generic path - Simple path with one lot of generic params diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 17da7c4c..4ef81c96 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -156,11 +156,14 @@ namespace { }) ); ), (Array, - TODO(Span(), "TypeRef::clone() - this = " << *this); - //return ::HIR::TypeRef( Data::make_Array({ - // box$( e.inner->clone() ), - // /* huh */ - // }) ); + if( e.size_val == ~0u ) { + BUG(Span(), "Attempting to clone array with unknown size - " << *this); + } + return ::HIR::TypeRef( Data::make_Array({ + box$( e.inner->clone() ), + ::HIR::ExprPtr(), + e.size_val + }) ); ), (Slice, return ::HIR::TypeRef( Data::make_Slice({ diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 06abe38a..9ccd2033 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -342,6 +342,11 @@ namespace { //auto val = mv$(m_rv); //DEBUG("ExprNode_Cast - val = " << val << " as " << node.m_type); } + void visit(::HIR::ExprNode_Unsize& node) override { + node.m_value->visit(*this); + //auto val = mv$(m_rv); + //DEBUG("ExprNode_Unsize - val = " << val << " as " << node.m_type); + } void visit(::HIR::ExprNode_Index& node) override { badnode(node); } @@ -537,11 +542,13 @@ namespace { } void visit_constant(::HIR::Constant& item) override { + visit_type(item.m_type); item.m_value_res = evaluate_constant(m_crate, *item.m_value); DEBUG("constant: " << item.m_type << " = " << item.m_value_res); } void visit_static(::HIR::Static& item) override { + visit_type(item.m_type); item.m_value_res = evaluate_constant(m_crate, *item.m_value); DEBUG("static: " << item.m_type << " = " << item.m_value_res); } diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index 0018fc9d..9b35c1c7 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -191,6 +191,7 @@ namespace { { TU_MATCH(::HIR::TypeRef::Data, (type.m_data), (e), (Infer, + assert(e.index == ~0u); e.index = this->new_ivar(); ), (Diverge, @@ -775,8 +776,8 @@ namespace { root_ivar.type.reset(); ) else { + DEBUG("Set IVar " << r_e.index << " = " << left); root_ivar.type = box$( left.clone() ); - DEBUG("Set IVar " << r_e.index << " = " << *root_ivar.type); } } ) @@ -796,6 +797,7 @@ namespace { ) else { // Otherwise, store a clone of right in left's ivar + DEBUG("Set IVar " << l_e.index << " = " << right); root_ivar.type = box$( right.clone() ); } ) @@ -824,7 +826,39 @@ namespace { } ), (Path, - TODO(sp, "Recurse in apply_equality Path - " << l_t << " and " << r_t); + struct H { + static void equality_typeparams(const Span& sp, TypecheckContext& ctxt, const ::HIR::PathParams& l, const ::HIR::PathParams& r) { + if( l.m_types.size() != r.m_types.size() ) { + ERROR(sp, E0000, "Type mismatch in type params `" << l << "` and `" << r << "`"); + } + for(unsigned int i = 0; i < l.m_types.size(); i ++) + { + ctxt.apply_equality(sp, l.m_types[i], r.m_types[i]); + } + } + }; + if( l_e.path.m_data.tag() != r_e.path.m_data.tag() ) { + ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t); + } + TU_MATCH(::HIR::Path::Data, (l_e.path.m_data, r_e.path.m_data), (lpe, rpe), + (Generic, + if( lpe.m_path != rpe.m_path ) { + ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t); + } + H::equality_typeparams(sp, *this, lpe.m_params, rpe.m_params); + ), + (UfcsInherent, + this->apply_equality(sp, *lpe.type, *rpe.type); + TODO(sp, "Recurse in apply_equality Path - " << l_t << " and " << r_t); + ), + (UfcsKnown, + this->apply_equality(sp, *lpe.type, *rpe.type); + TODO(sp, "Recurse in apply_equality Path - " << l_t << " and " << r_t); + ), + (UfcsUnknown, + BUG(sp, "Encountered UfcsUnknown - TODO?"); + ) + ) ), (Generic, if( l_e.binding != r_e.binding ) { @@ -835,7 +869,10 @@ namespace { TODO(sp, "Recurse in apply_equality TraitObject - " << l_t << " and " << r_t); ), (Array, - TODO(sp, "Recurse in apply_equality Array - " << l_t << " and " << r_t); + this->apply_equality(sp, *l_e.inner, *r_e.inner); + if( l_e.size_val != r_e.size_val ) { + ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - sizes differ"); + } ), (Slice, this->apply_equality(sp, *l_e.inner, *r_e.inner); @@ -866,7 +903,9 @@ namespace { const auto& left_slice = l_e.inner->m_data.as_Slice(); TU_IFLET(::HIR::TypeRef::Data, r_e.inner->m_data, Array, right_array, this->apply_equality(sp, *left_slice.inner, *right_array.inner); - TODO(sp, "Apply slice unsize coerce operation - " << l_t << " <- " << r_t); + *node_ptr_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Unsize( mv$(*node_ptr_ptr), l_t.clone() )); + (*node_ptr_ptr)->m_res_type = l_t.clone(); + return ; ) else { @@ -904,6 +943,7 @@ namespace { { auto index = slot; unsigned int count = 0; + assert(index < m_ivars.size()); while( m_ivars.at(index).is_alias() ) { index = m_ivars.at(index).alias; @@ -1031,6 +1071,10 @@ void Typecheck_Code(TypecheckContext context, const ::HIR::TypeRef& result_type, { TRACE_FUNCTION; + // TODO: Perform type propagation "outward" from the root + + //context.apply_equality(expr->span(), result_type, expr->m_res_type); + // 1. Enumerate inferrence variables and assign indexes to them { ExprVisitor_Enum visitor { context }; |