summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp25
-rw-r--r--src/hir_typeck/helpers.cpp38
2 files changed, 61 insertions, 2 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 729571d3..e8bf8842 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -3004,7 +3004,6 @@ namespace {
return true;
}
-
// If either side (or both) are ivars, then coercion can't be known yet - but they could be equal
// TODO: Fix and deduplicate the following code for InferClass::Diverge
@@ -3219,7 +3218,29 @@ namespace {
return true;
}
- // TODO: CoerceUnsized trait
+ // CoerceUnsized trait
+ // - Only valid for generic or path destination types
+ if( ty_dst.m_data.is_Generic() || ty_dst.m_data.is_Path() ) {
+
+ const auto& lang_CoerceUnsized = context.m_crate.get_lang_item_path(sp, "coerce_unsized");
+ ::HIR::PathParams pp;
+ pp.m_types.push_back( ty_dst.clone() );
+ bool found = context.m_resolve.find_trait_impls(sp, lang_CoerceUnsized, pp, ty_src, [&](auto impl, auto cmp) {
+ // TODO: Allow fuzzy match if only match
+ return cmp == ::HIR::Compare::Equal;
+ });
+ if( found )
+ {
+ DEBUG("- CoerceUnsize " << &*node_ptr << " -> " << ty_dst);
+
+ TODO(sp, "Add Coerce op applying to pointer type for " << ty_src << " -> " << ty_dst);
+ //add_coerce_borrow(context, node_ptr, ty_dst, [&](auto& node_ptr) {
+ // auto span = node_ptr->span();
+ // node_ptr = NEWNODE( ty_dst.clone(), span, _Unsize, mv$(node_ptr), ty_dst.clone() );
+ // });
+ return true;
+ }
+ }
// 1. Check that the source type can coerce
TU_MATCH( ::HIR::TypeRef::Data, (ty_src.m_data), (e),
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index ec62bcfe..b5a122ae 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1109,6 +1109,44 @@ bool TraitResolution::find_trait_impls(const Span& sp,
}
}
}
+
+ if( trait == m_crate.get_lang_item_path(sp, "unsize") )
+ {
+ ASSERT_BUG(sp, params.m_types.size() == 1, "");
+ const auto& dst_ty = m_ivars.get_type( params.m_types[0] );
+ if( ! dst_ty.m_data.is_TraitObject() ) {
+ // If the destination isn't a trait object, don't even bother
+ return false;
+ }
+ const auto& e2 = dst_ty.m_data.as_TraitObject();
+
+ auto cmp = ::HIR::Compare::Equal;
+
+ // TODO: Fuzzy compare
+ if( e2.m_trait != e.m_trait ) {
+ return false;
+ }
+ // The destination must have a strict subset of marker traits.
+ const auto& src_markers = e.m_markers;
+ const auto& dst_markers = e2.m_markers;
+ for(const auto& mt : dst_markers)
+ {
+ // TODO: Fuzzy match
+ bool found = false;
+ for(const auto& omt : src_markers) {
+ if( omt == mt ) {
+ found = true;
+ break;
+ }
+ }
+ if( !found ) {
+ // Return early.
+ return false;
+ }
+ }
+
+ return callback( ImplRef(&type, &e.m_trait.m_path.m_params, &e.m_trait.m_type_bounds), cmp );
+ }
)
// 1. Search generic params