summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-07 18:59:52 +1000
committerJohn Hodge <tpg@mutabah.net>2016-07-07 18:59:52 +1000
commit15af300790fab5663f480aca06887062e7517604 (patch)
treedf044bdc68543884760b6f0b1ca5629f7366fff2 /src
parent5ef1f59ce1ba4e0c96206775a72facae0ce744da (diff)
downloadmrust-15af300790fab5663f480aca06887062e7517604.tar.gz
HIR Typecheck CS - Working `let v: usize = !0;`
Diffstat (limited to 'src')
-rw-r--r--src/hir/hir.cpp25
-rw-r--r--src/hir/type.cpp12
-rw-r--r--src/hir/type.hpp23
-rw-r--r--src/hir_typeck/expr_cs.cpp13
-rw-r--r--src/hir_typeck/helpers.cpp8
5 files changed, 71 insertions, 10 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 2441b338..6de07480 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -44,7 +44,28 @@ namespace {
// TODO: What indicates what out of ty_res?
if( right.m_data.is_Infer() ) {
- // TODO: Why is this false? A _ type could match anything
+ //DEBUG("left = " << left << ", right = " << right);
+ switch(right.m_data.as_Infer().ty_class)
+ {
+ case ::HIR::InferClass::None:
+ return left.m_data.is_Generic();
+ case ::HIR::InferClass::Integer:
+ TU_IFLET(::HIR::TypeRef::Data, left.m_data, Primitive, le,
+ return is_integer(le);
+ )
+ else {
+ return left.m_data.is_Generic();
+ }
+ break;
+ case ::HIR::InferClass::Float:
+ TU_IFLET(::HIR::TypeRef::Data, left.m_data, Primitive, le,
+ return is_float(le);
+ )
+ else {
+ return left.m_data.is_Generic();
+ }
+ break;
+ }
return left.m_data.is_Generic();
//return true;
}
@@ -162,6 +183,8 @@ namespace {
bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const
{
return matches_type_int(m_params, m_type, type, ty_res, true);
+ // TODO: Using this would be nice, but may be better to handle impl params better
+ //return m_type.compare_with_placeholders(Span(), type, ty_res) != ::HIR::Compare::Unequal;
}
bool ::HIR::TypeImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const
{
diff --git a/src/hir/type.cpp b/src/hir/type.cpp
index 7431ff9d..70ce2599 100644
--- a/src/hir/type.cpp
+++ b/src/hir/type.cpp
@@ -511,10 +511,12 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
::HIR::Compare HIR::TypeRef::compare_with_placeholders(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder) const
{
TRACE_FUNCTION_F(*this << " ?= " << x);
+ const auto& left = (m_data.is_Infer() || m_data.is_Generic() ? resolve_placeholder(*this) : *this);
+ //const auto& left = *this;
const auto& right = (x.m_data.is_Infer() ? resolve_placeholder(x) : (x.m_data.is_Generic() ? resolve_placeholder(x) : x));
// If left is infer
- TU_IFLET(::HIR::TypeRef::Data, this->m_data, Infer, e,
+ TU_IFLET(::HIR::TypeRef::Data, left.m_data, Infer, e,
switch(e.ty_class)
{
case ::HIR::InferClass::None:
@@ -561,7 +563,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
case ::HIR::InferClass::None:
return Compare::Fuzzy;
case ::HIR::InferClass::Integer:
- TU_IFLET( ::HIR::TypeRef::Data, this->m_data, Primitive, le,
+ TU_IFLET( ::HIR::TypeRef::Data, left.m_data, Primitive, le,
switch(le)
{
case ::HIR::CoreType::I8: case ::HIR::CoreType::U8:
@@ -578,7 +580,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
return Compare::Unequal;
}
case ::HIR::InferClass::Float:
- TU_IFLET( ::HIR::TypeRef::Data, this->m_data, Primitive, le,
+ TU_IFLET( ::HIR::TypeRef::Data, left.m_data, Primitive, le,
switch(le)
{
case ::HIR::CoreType::F32:
@@ -598,10 +600,10 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x
// If righthand is a type parameter, it can only match another type parameter
// - See `(Generic,` below
- if( this->m_data.tag() != right.m_data.tag() ) {
+ if( left.m_data.tag() != right.m_data.tag() ) {
return Compare::Unequal;
}
- TU_MATCH(::HIR::TypeRef::Data, (this->m_data, right.m_data), (le, re),
+ TU_MATCH(::HIR::TypeRef::Data, (left.m_data, right.m_data), (le, re),
(Infer, assert(!"infer");),
(Diverge,
return Compare::Equal;
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index 02effd9c..8a404e98 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -39,6 +39,29 @@ enum class CoreType
Char, Str,
};
extern ::std::ostream& operator<<(::std::ostream& os, const CoreType& ct);
+static inline bool is_integer(const CoreType& v) {
+ switch(v)
+ {
+ case CoreType::Usize: case CoreType::Isize:
+ case CoreType::U8 : case CoreType::I8:
+ case CoreType::U16: case CoreType::I16:
+ case CoreType::U32: case CoreType::I32:
+ case CoreType::U64: case CoreType::I64:
+ return true;
+ default:
+ return false;
+ }
+}
+static inline bool is_float(const CoreType& v) {
+ switch(v)
+ {
+ case CoreType::F32:
+ case CoreType::F64:
+ return true;
+ default:
+ return false;
+ }
+}
enum class BorrowType
{
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 0d9b1344..fb55fcc6 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2598,10 +2598,19 @@ namespace {
DEBUG("- (fail) bounded impl " << v.trait << v.params << " (ty_right = " << context.m_ivars.fmt_type(v.impl_ty));
return false;
}
+ if( v.name != "" && assoc.count(v.name) == 0 )
+ BUG(sp, "Getting associated type '" << v.name << "' which isn't in list");
+ const auto& out_ty = (v.name == "" ? v.left_ty : assoc.at(v.name));
+ // - If we're looking for an associated type, allow it to eliminate impossible impls
+ // > This makes `let v: usize = !0;` work without special cases
if( v.name != "" ) {
- if( assoc.count(v.name) == 0 )
- BUG(sp, "Getting associated type '" << v.name << "' which isn't in list");
+ auto cmp2 = v.left_ty.compare_with_placeholders(sp, out_ty, context.m_ivars.callback_resolve_infer());
+ if( cmp2 == ::HIR::Compare::Unequal ) {
+ DEBUG("- (fail) known result can't match (" << context.m_ivars.fmt_type(v.left_ty) << " and " << context.m_ivars.fmt_type(out_ty) << ")");
+ return false;
+ }
+ // if solid or fuzzy, leave as-is
output_type = assoc.at(v.name).clone();
}
count += 1;
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 3d069dde..bcc2fbde 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1460,12 +1460,16 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
DEBUG("- Failed to match parameters - " << impl.m_trait_args << " != " << params);
return false;
}
- for(const auto& ty : impl_params)
- assert( ty );
+ for(unsigned int i = 0; i < impl_params.size(); i ++ ) {
+ if( !impl_params[i] ) {
+ BUG(sp, "Param " << i << " for impl " /*<< impl*/ << " wasn't constrained");
+ }
+ }
auto monomorph = [&](const auto& gt)->const auto& {
const auto& ge = gt.m_data.as_Generic();
assert( ge.binding < impl_params.size() );
+ assert(impl_params[ge.binding]);
return *impl_params[ge.binding];
};
auto ty_mono = monomorphise_type_with(sp, impl.m_type, monomorph, false);