diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-21 12:12:27 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-21 12:12:27 +0800 |
commit | a7cffac33697b43c9245db8fd7bfc1e6013fc80b (patch) | |
tree | c36dda9dd113af5332e7fd7ee7dda9778e9519d8 | |
parent | 572fa41f6e8691b329a9f3c044f474340cf3472d (diff) | |
download | mrust-a7cffac33697b43c9245db8fd7bfc1e6013fc80b.tar.gz |
Quirk - You can cast &[T;n] to *const T
-rw-r--r-- | Notes/Quirks.md | 4 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 12 |
2 files changed, 15 insertions, 1 deletions
diff --git a/Notes/Quirks.md b/Notes/Quirks.md index d3b7839d..f9b54022 100644 --- a/Notes/Quirks.md +++ b/Notes/Quirks.md @@ -26,6 +26,10 @@ Any integer can cast to a pointer =================== This includes `u8` +Array &-ptrs appear to be able to be cast to raw pointers of the element type +============================================================================= + + Modules with the same name as primtiive types have interesting lookup quirks =================== diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 0562c1b1..8e15e1ab 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2002,6 +2002,7 @@ namespace { const auto& sp = node.span(); const auto& tgt_ty = this->context.get_type(node.m_res_type); const auto& src_ty = this->context.get_type(node.m_value->m_res_type); + TRACE_FUNCTION_F(src_ty << " as " << tgt_ty); if( this->context.m_ivars.types_equal(src_ty, tgt_ty) ) { this->m_completed = true; @@ -2121,13 +2122,22 @@ namespace { if( s_e.type != e.type ) { ERROR(sp, E0000, "Invalid cast from " << src_ty << " to " << tgt_ty); } + const auto& src_inner = this->context.get_type(*s_e.inner); // NOTE: &mut T -> *mut U where T: Unsize<U> is allowed // TODO: Wouldn't this be better served by a coercion point? - TU_IFLET( ::HIR::TypeRef::Data, this->context.get_type(*s_e.inner).m_data, Infer, s_e_i, + TU_IFLET( ::HIR::TypeRef::Data, src_inner.m_data, Infer, s_e_i, // If the type is an ivar, possible equate this->context.possible_equate_type_unsize_to(s_e_i.index, *e.inner); ) + // - NOTE: Crude, and likely to break if ether inner isn't known. + else if( src_inner.m_data.is_Array() && *src_inner.m_data.as_Array().inner == *e.inner ) + { + // Allow &[T; n] -> *const T - Convert into two casts + auto ty = ::HIR::TypeRef::new_pointer(e.type, src_inner.clone()); + node.m_value = NEWNODE(ty.clone(), sp, _Cast, mv$(node.m_value), ty.clone()); + this->m_completed = true; + } else { const auto& lang_Unsize = this->context.m_crate.get_lang_item_path(sp, "unsize"); |