diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/path.cpp | 4 | ||||
-rw-r--r-- | src/hir/path.hpp | 1 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 30 |
3 files changed, 30 insertions, 5 deletions
diff --git a/src/hir/path.cpp b/src/hir/path.cpp index 0df8a6d2..f0590e38 100644 --- a/src/hir/path.cpp +++ b/src/hir/path.cpp @@ -103,6 +103,10 @@ namespace HIR { ::HIR::PathParams::PathParams() { } +::HIR::PathParams::PathParams(::HIR::TypeRef ty0) +{ + m_types.push_back( mv$(ty0) ); +} ::HIR::PathParams HIR::PathParams::clone() const { PathParams rv; diff --git a/src/hir/path.hpp b/src/hir/path.hpp index c791812d..0ee4c958 100644 --- a/src/hir/path.hpp +++ b/src/hir/path.hpp @@ -83,6 +83,7 @@ struct PathParams ::std::vector<TypeRef> m_types; PathParams(); + PathParams(::HIR::TypeRef ); PathParams clone() const; PathParams(const PathParams&) = delete; PathParams& operator=(const PathParams&) = delete; diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 12e4c687..abb6c125 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1615,7 +1615,7 @@ namespace { ERROR(sp, E0000, "Non-scalar cast to " << this->context.m_ivars.fmt_type(tgt_ty)); ), (Borrow, - TODO(sp, "Cast to borrow"); + TODO(sp, "Cast to borrow - coercion point"); ), (Pointer, TU_MATCH_DEF( ::HIR::TypeRef::Data, (src_ty.m_data), (s_e), @@ -1653,9 +1653,28 @@ namespace { ), (Borrow, // Check class (must be equal) and type - // TODO: Check class - this->context.equate_types(sp, *e.inner, *s_e.inner); - this->m_completed = true; + if( s_e.type != e.type ) { + ERROR(sp, E0000, "Invalid cast from " << src_ty << " to " << tgt_ty); + } + + // 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, + // If the type is an ivar, possible equate + this->context.possible_equate_type_to(s_e_i.index, *e.inner); + ) + else + { + const auto& lang_Unsize = this->context.m_crate.get_lang_item_path(sp, "unsize"); + bool found = this->context.m_resolve.find_trait_impls(sp, lang_Unsize, ::HIR::PathParams(e.inner->clone()), *s_e.inner, [](auto , auto){ return true; }); + if( found ) { + TODO(sp, "Unsizing cast"); + } + else { + this->context.equate_types(sp, *e.inner, *s_e.inner); + } + this->m_completed = true; + } ), (Pointer, // Allow with no link? @@ -1667,7 +1686,7 @@ namespace { ERROR(sp, E0000, "Non-scalar cast to " << this->context.m_ivars.fmt_type(tgt_ty)); ), (Closure, - BUG(sp, ""); + BUG(sp, "Attempting to cast to a closure type - impossible"); ) ) } @@ -3704,6 +3723,7 @@ namespace { if( r_e.type != l_e.type ) { ERROR(sp, E0000, "Type mismatch between " << ty_dst << " and " << ty_src << " - Mutability differs"); } + // TODO: This can unsize as well as convert? context.equate_types(sp, *l_e.inner, *r_e.inner); // Add downcast auto span = node_ptr->span(); |