diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-06 23:12:39 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-06 23:12:39 +0800 |
commit | 0a18cb44477d4ac241ce08feb768136684714a07 (patch) | |
tree | 6df36577d55037afff2270afc7e581d6c78b187b | |
parent | e31213085b8d4846981b4db61502bbf46d1ed59f (diff) | |
download | mrust-0a18cb44477d4ac241ce08feb768136684714a07.tar.gz |
HIR - BorrowType on pointer, allow pointer coerce
-rw-r--r-- | src/hir/from_ast.cpp | 5 | ||||
-rw-r--r-- | src/hir/hir.cpp | 2 | ||||
-rw-r--r-- | src/hir/type.cpp | 14 | ||||
-rw-r--r-- | src/hir/type.hpp | 4 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 26 |
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"); } |