summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-12 17:19:07 +1000
committerJohn Hodge <tpg@mutabah.net>2016-07-12 17:19:07 +1000
commita7fb52b0e1f2a0159a986b25b10241655b56c077 (patch)
tree5006d580d3d4e3389e409bbafab0e1253c3f47bf
parentb9b64ffbf3a54dcaa41ba8d186911d6d63d09721 (diff)
downloadmrust-a7fb52b0e1f2a0159a986b25b10241655b56c077.tar.gz
HIR Types - Support returning match state from match generic callback
-rw-r--r--src/hir/type.cpp4
-rw-r--r--src/hir/type.hpp6
-rw-r--r--src/hir_typeck/expr_cs.cpp2
-rw-r--r--src/hir_typeck/expr_simple.cpp10
-rw-r--r--src/hir_typeck/helpers.cpp6
5 files changed, 17 insertions, 11 deletions
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 28d11aa9..ae49f3db 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -301,9 +301,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
BUG(sp, "Encountered '_' as this - " << *this);
}
if( m_data.is_Generic() ) {
- callback(m_data.as_Generic().binding, x_in);
- // - TODO: Allow callback to return a match form
- return Compare::Equal;
+ return callback(m_data.as_Generic().binding, x_in);
}
const auto& x = (x_in.m_data.is_Infer() || x_in.m_data.is_Generic() ? resolve_placeholder(x_in) : x_in);
TU_IFLET(::HIR::TypeRef::Data, x.m_data, Infer, xe,
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index 940ebc04..f75a4d51 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -16,7 +16,7 @@ struct ExprNode_Closure;
class TypeRef;
-typedef ::std::function<void(unsigned int, const ::HIR::TypeRef&)> t_cb_match_generics;
+typedef ::std::function< ::HIR::Compare(unsigned int, const ::HIR::TypeRef&) > t_cb_match_generics;
enum class InferClass
{
@@ -223,9 +223,9 @@ public:
// Match generics in `this` with types from `x`
// Raises a bug against `sp` if there is a form mismatch or `this` has an infer
- void match_generics(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder, ::std::function<void(unsigned int, const ::HIR::TypeRef&)> callback) const;
+ void match_generics(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder, t_cb_match_generics) const;
- bool match_test_generics(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder, ::std::function<void(unsigned int, const ::HIR::TypeRef&)> callback) const;
+ bool match_test_generics(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder, t_cb_match_generics) const;
// Compares this type with another, calling the first callback to resolve placeholders in the other type, and the second callback for generics in this type
::HIR::Compare match_test_generics_fuzz(const Span& sp, const ::HIR::TypeRef& x_in, t_cb_resolve_type resolve_placeholder, t_cb_match_generics callback) const;
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 2cd2626f..db86900e 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -252,6 +252,7 @@ namespace {
impl_ptr->m_type.match_generics(sp, *e.type, context.m_ivars.callback_resolve_infer(), [&](auto idx, const auto& ty) {
assert( idx < impl_params.m_types.size() );
impl_params.m_types[idx] = ty.clone();
+ return ::HIR::Compare::Equal;
});
for(const auto& ty : impl_params.m_types)
assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) );
@@ -1111,6 +1112,7 @@ namespace {
impl_ptr->m_type.match_generics(sp, *e.type, this->context.m_ivars.callback_resolve_infer(), [&](auto idx, const auto& ty) {
assert( idx < impl_params.m_types.size() );
impl_params.m_types[idx] = ty.clone();
+ return ::HIR::Compare::Equal;
});
for(const auto& ty : impl_params.m_types)
assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) );
diff --git a/src/hir_typeck/expr_simple.cpp b/src/hir_typeck/expr_simple.cpp
index ce3b0ef5..5eb8e668 100644
--- a/src/hir_typeck/expr_simple.cpp
+++ b/src/hir_typeck/expr_simple.cpp
@@ -766,19 +766,21 @@ namespace typeck {
assert( idx < impl_params.size() );
if( ! impl_params[idx] ) {
impl_params[idx] = &ty;
+ return ::HIR::Compare::Equal;
}
else {
switch( impl_params[idx]->compare_with_placeholders(node.span(), ty, this->context.callback_resolve_infer()) )
{
case ::HIR::Compare::Unequal:
fail = true;
- break;
+ return ::HIR::Compare::Unequal;
case ::HIR::Compare::Fuzzy:
fuzzy = true;
- break;
+ return ::HIR::Compare::Fuzzy;
case ::HIR::Compare::Equal:
- break;
+ return ::HIR::Compare::Equal;
}
+ return ::HIR::Compare::Equal;
}
};
fail |= !impl.m_type.match_test_generics(sp, ty_left, this->context.callback_resolve_infer(), cb);
@@ -1298,6 +1300,7 @@ namespace typeck {
impl_ptr->m_type.match_generics(sp, *e.type, this->context.callback_resolve_infer(), [&](auto idx, const auto& ty) {
assert( idx < impl_params.m_types.size() );
impl_params.m_types[idx] = ty.clone();
+ return ::HIR::Compare::Equal;
});
for(const auto& ty : impl_params.m_types)
assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) );
@@ -1713,6 +1716,7 @@ namespace typeck {
impl_ptr->m_type.match_generics(sp, *e.type, this->context.callback_resolve_infer(), [&](auto idx, const auto& ty) {
assert( idx < impl_params.m_types.size() );
impl_params.m_types[idx] = ty.clone();
+ return ::HIR::Compare::Equal;
});
for(const auto& ty : impl_params.m_types)
assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) );
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 8f877b25..71fb5b2c 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1690,16 +1690,18 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
assert( idx < impl_params.size() );
if( ! impl_params[idx] ) {
impl_params[idx] = &ty;
+ return ::HIR::Compare::Equal;
}
else if( this->m_ivars.types_equal(*impl_params[idx], ty) ) {
// Fall
+ return ::HIR::Compare::Equal;
}
else if( ty.m_data.is_Infer() ) {
// Fall
- match = ::HIR::Compare::Fuzzy;
+ return (match = ::HIR::Compare::Fuzzy);
}
else {
- match = ::HIR::Compare::Unequal;
+ return (match = ::HIR::Compare::Unequal);
}
};
assert( impl.m_trait_args.m_types.size() == params.m_types.size() );