summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-04 13:48:21 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-04 13:48:21 +0800
commitf92a45d8054cc18a037449ec136bf874ce20fc5a (patch)
tree0a0f977790faaa73f1b7987b3abbc7dbfc3e9364 /src
parente33d210a4a85e91abe04f1874f460b6e60c6b5e0 (diff)
downloadmrust-f92a45d8054cc18a037449ec136bf874ce20fc5a.tar.gz
HIR Typeck - Add slice unsize, breaks due to inferrence order
Diffstat (limited to 'src')
-rw-r--r--src/hir/expr.cpp3
-rw-r--r--src/hir/expr.hpp39
-rw-r--r--src/hir/path.hpp2
-rw-r--r--src/hir/type.cpp13
-rw-r--r--src/hir_conv/constant_evaluation.cpp7
-rw-r--r--src/hir_typeck/expr.cpp52
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 };