summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 76661d66..f012386e 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2742,6 +2742,7 @@ namespace {
const auto& ty = this->context.get_type(node.m_value->m_res_type);
TRACE_FUNCTION_F("(CallMethod) {" << this->context.m_ivars.fmt_type(ty) << "}." << node.m_method << node.m_params
<< "(" << FMT_CB(os, for( const auto& arg_node : node.m_args ) os << this->context.m_ivars.fmt_type(arg_node->m_res_type) << ", ";) << ")"
+ << " -> " << this->context.m_ivars.fmt_type(node.m_res_type)
);
// Make sure that no mentioned types are inferred until this method is known
@@ -6430,7 +6431,11 @@ namespace {
else if( count == 0 ) {
// No applicable impl
// - TODO: This should really only fire when there isn't an impl. But it currently fires when _
- DEBUG("No impl of " << v.trait << context.m_ivars.fmt(v.params) << " for " << context.m_ivars.fmt_type(v.impl_ty));
+ if( v.name == "" )
+ DEBUG("No impl of " << v.trait << context.m_ivars.fmt(v.params) << " for " << context.m_ivars.fmt_type(v.impl_ty));
+ else
+ DEBUG("No impl of " << v.trait << context.m_ivars.fmt(v.params) << " for " << context.m_ivars.fmt_type(v.impl_ty)
+ << " with " << v.name << " = " << context.m_ivars.fmt_type(v.left_ty));
const auto& ty = context.get_type(v.impl_ty);
bool is_known = !ty.m_data.is_Infer() && !(ty.m_data.is_Path() && ty.m_data.as_Path().binding.is_Unbound());
@@ -6837,16 +6842,52 @@ namespace {
}
}
if( l.m_data.is_Path() ) {
+ const auto& te_l = l.m_data.as_Path();
// Path types can be unsize targets, and can also act like infers
// - If it's a Unbound treat as Infer
// - If Opaque, then search for a CoerceUnsized/Unsize bound?
// - If Struct, look for ^ tag
// - Else, more/equal specific
- TODO(sp, l << " with " << r << " - LHS is Path");
+ TU_MATCH_HDRA( (r.m_data), { )
+ default:
+ // An ivar is less restrictive?
+ if( te_l.binding.is_Unbound() )
+ return OrdLess;
+ TODO(sp, l << " with " << r << " - LHS is Path, RHS is ?");
+ TU_ARMA(Path, te_r) {
+ if( te_l.binding.is_Unbound() && te_r.binding.is_Unbound() )
+ {
+ return OrdEqual;
+ }
+ if( te_l.binding.is_Unbound() )
+ return OrdLess;
+ if( te_r.binding.is_Unbound() )
+ {
+ return OrdGreater;
+ }
+ else if( te_r.binding.is_Opaque() )
+ {
+ TODO(sp, l << " with " << r << " - LHS is Path, RHS is opaque type");
+ }
+ else if( TU_TEST1(te_r.binding, Struct, ->m_struct_markings.can_unsize) )
+ {
+ TODO(sp, l << " with " << r << " - LHS is Path, RHS is unsize-capable struct");
+ }
+ else
+ {
+ return OrdEqual;
+ }
+ }
+ }
}
if( r.m_data.is_Path() ) {
// Path types can be unsize targets, and can also act like infers
- TODO(sp, l << " with " << r << " - RHS is Path");
+ switch( get_ordering_ty(sp, context, r, l) )
+ {
+ case OrdLess: return OrdGreater;
+ case OrdEqual: return OrdEqual;
+ case OrdGreater:return OrdLess;
+ }
}
// Slice < Array