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 /src | |
parent | 572fa41f6e8691b329a9f3c044f474340cf3472d (diff) | |
download | mrust-a7cffac33697b43c9245db8fd7bfc1e6013fc80b.tar.gz |
Quirk - You can cast &[T;n] to *const T
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
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"); |