diff options
author | John Hodge <tpg@mutabah.net> | 2016-07-07 18:59:52 +1000 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-07-07 18:59:52 +1000 |
commit | 15af300790fab5663f480aca06887062e7517604 (patch) | |
tree | df044bdc68543884760b6f0b1ca5629f7366fff2 /src | |
parent | 5ef1f59ce1ba4e0c96206775a72facae0ce744da (diff) | |
download | mrust-15af300790fab5663f480aca06887062e7517604.tar.gz |
HIR Typecheck CS - Working `let v: usize = !0;`
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/hir.cpp | 25 | ||||
-rw-r--r-- | src/hir/type.cpp | 12 | ||||
-rw-r--r-- | src/hir/type.hpp | 23 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 13 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 8 |
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); |