summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-06 23:12:39 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-06 23:12:39 +0800
commit0a18cb44477d4ac241ce08feb768136684714a07 (patch)
tree6df36577d55037afff2270afc7e581d6c78b187b
parente31213085b8d4846981b4db61502bbf46d1ed59f (diff)
downloadmrust-0a18cb44477d4ac241ce08feb768136684714a07.tar.gz
HIR - BorrowType on pointer, allow pointer coerce
-rw-r--r--src/hir/from_ast.cpp5
-rw-r--r--src/hir/hir.cpp2
-rw-r--r--src/hir/type.cpp14
-rw-r--r--src/hir/type.hpp4
-rw-r--r--src/hir_typeck/expr.cpp26
5 files changed, 37 insertions, 14 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 0c094484..fff4c94a 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -523,10 +523,11 @@
),
(Borrow,
auto cl = (e.is_mut ? ::HIR::BorrowType::Unique : ::HIR::BorrowType::Shared);
- return ::HIR::TypeRef( ::HIR::TypeRef::Data( ::HIR::TypeRef::Data::Data_Borrow { cl, box$(LowerHIR_Type(*e.inner)) } ) );
+ return ::HIR::TypeRef::new_borrow( cl, LowerHIR_Type(*e.inner) );
),
(Pointer,
- return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Pointer({e.is_mut, box$(LowerHIR_Type(*e.inner))}) );
+ auto cl = (e.is_mut ? ::HIR::BorrowType::Unique : ::HIR::BorrowType::Shared);
+ return ::HIR::TypeRef::new_pointer( cl, LowerHIR_Type(*e.inner) );
),
(Array,
if( e.size ) {
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 12dee93f..756e4b7b 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -119,7 +119,7 @@ namespace {
return matches_type_int(params, *le.inner, *re.inner, ty_res);
),
(Pointer,
- if( le.is_mut != re.is_mut )
+ if( le.type != re.type )
return false;
return matches_type_int(params, *le.inner, *re.inner, ty_res);
),
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 2d87ffb9..61ba9419 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -90,11 +90,11 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const
os << *e.inner;
),
(Pointer,
- if( e.is_mut ) {
- os << "*mut ";
- }
- else {
- os << "*const ";
+ switch(e.type)
+ {
+ case ::HIR::BorrowType::Shared: os << "*const "; break;
+ case ::HIR::BorrowType::Unique: os << "*mut "; break;
+ case ::HIR::BorrowType::Owned: os << "*move "; break;
}
os << *e.inner;
),
@@ -164,7 +164,7 @@ bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const
return *te.inner == *xe.inner;
),
(Pointer,
- if( te.is_mut != xe.is_mut )
+ if( te.type != xe.type )
return false;
return *te.inner == *xe.inner;
),
@@ -301,7 +301,7 @@ namespace {
return ::HIR::TypeRef( Data::make_Borrow({e.type, box$(e.inner->clone())}) );
),
(Pointer,
- return ::HIR::TypeRef( Data::make_Pointer({e.is_mut, box$(e.inner->clone())}) );
+ return ::HIR::TypeRef( Data::make_Pointer({e.type, box$(e.inner->clone())}) );
),
(Function,
FunctionType ft;
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index bd61eea6..573cad70 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -102,7 +102,7 @@ public:
::std::unique_ptr<TypeRef> inner;
}),
(Pointer, struct {
- bool is_mut;
+ ::HIR::BorrowType type;
::std::unique_ptr<TypeRef> inner;
}),
(Function, FunctionType)
@@ -146,7 +146,7 @@ public:
static TypeRef new_borrow(BorrowType bt, TypeRef inner) {
return TypeRef(Data::make_Borrow({bt, box$(mv$(inner))}));
}
- static TypeRef new_pointer(bool bt, TypeRef inner) {
+ static TypeRef new_pointer(BorrowType bt, TypeRef inner) {
return TypeRef(Data::make_Pointer({bt, box$(mv$(inner))}));
}
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index de05493a..b8d3d880 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -164,7 +164,7 @@ namespace {
return ::HIR::TypeRef::new_borrow(e.type, monomorphise_type_with(sp, *e.inner, callback));
),
(Pointer,
- return ::HIR::TypeRef::new_pointer(e.is_mut, monomorphise_type_with(sp, *e.inner, callback));
+ return ::HIR::TypeRef::new_pointer(e.type, monomorphise_type_with(sp, *e.inner, callback));
),
(Function,
TODO(sp, "Function");
@@ -909,6 +909,28 @@ namespace {
// TODO: Should diverge check be done elsewhere? what happens if a ! ends up in an ivar?
return ;
}
+
+ if( l_t.m_data.is_Pointer() && r_t.m_data.is_Borrow() ) {
+ const auto& l_e = l_t.m_data.as_Pointer();
+ const auto& r_e = r_t.m_data.as_Borrow();
+ if( node_ptr_ptr != nullptr )
+ {
+ // 1. Equate inner types
+ this->apply_equality(sp, *l_e.inner, cb_left, *r_e.inner, cb_right, nullptr);
+ // 2. If that succeeds, add a coerce
+ auto span = (**node_ptr_ptr).span();
+ *node_ptr_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Cast( mv$(span), mv$(*node_ptr_ptr), l_t.clone() ));
+ (*node_ptr_ptr)->m_res_type = l_t.clone();
+
+ this->mark_change();
+ return ;
+ }
+ else
+ {
+ ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " (can't coerce)");
+ }
+ }
+
// - If tags don't match, error
if( l_t.m_data.tag() != r_t.m_data.tag() ) {
// Type error
@@ -1056,7 +1078,7 @@ namespace {
this->apply_equality(sp, *l_e.inner, cb_left, *r_e.inner, cb_right, nullptr);
),
(Pointer,
- if( l_e.is_mut != r_e.is_mut ) {
+ if( l_e.type != r_e.type ) {
// TODO: This could be allowed if left == false && right == true (reborrowing)
ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - Pointer mutability differs");
}