diff options
author | John Hodge <tpg@mutabah.net> | 2017-01-08 09:48:19 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-01-08 09:48:19 +0800 |
commit | 3f047e495793a1eed8244b96bc0dddff275cd19c (patch) | |
tree | a53112cc7ecfd414b1832a8a1a28c4643c100b46 /src/hir/hir.cpp | |
parent | af7089cec53828533462af5349e861f7d524d22e (diff) | |
download | mrust-3f047e495793a1eed8244b96bc0dddff275cd19c.tar.gz |
All - i128/u182 support, typecheck and parse fixes
Diffstat (limited to 'src/hir/hir.cpp')
-rw-r--r-- | src/hir/hir.cpp | 122 |
1 files changed, 120 insertions, 2 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 7f4df952..f5d75101 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -471,6 +471,7 @@ namespace { } // TODO: Add traits from `Self: Foo` bounds? + // TODO: Move associated types to the source trait. } ::std::vector< ::HIR::GenericBound> flatten_bounds(const ::std::vector<::HIR::GenericBound>& bounds) { @@ -493,6 +494,7 @@ namespace { ) ) } + ::std::sort(rv.begin(), rv.end(), [](const auto& a, const auto& b){ return ::ord(a,b) == OrdLess; }); return rv; } } @@ -519,8 +521,6 @@ bool ::HIR::TraitImpl::more_specific_than(const ::HIR::TraitImpl& other) const // TODO: Cache these lists (calculate after outer typecheck?) auto bounds_t = flatten_bounds(m_params.m_bounds); auto bounds_o = flatten_bounds(other.m_params.m_bounds); - ::std::sort(bounds_t.begin(), bounds_t.end(), [](const auto& a, const auto& b){ return ::ord(a,b) == OrdLess; }); - ::std::sort(bounds_o.begin(), bounds_o.end(), [](const auto& a, const auto& b){ return ::ord(a,b) == OrdLess; }); DEBUG("bounds_t = " << bounds_t); DEBUG("bounds_o = " << bounds_o); @@ -589,6 +589,124 @@ bool ::HIR::TraitImpl::more_specific_than(const ::HIR::TraitImpl& other) const } } +// Returns `true` if the two impls overlap in the types they will accept +bool ::HIR::TraitImpl::overlaps_with(const ::HIR::TraitImpl& other) const +{ + struct H { + static bool types_overlap(const ::HIR::PathParams& a, const ::HIR::PathParams& b) + { + for(unsigned int i = 0; i < ::std::min(a.m_types.size(), b.m_types.size()); i ++) + { + if( ! H::types_overlap(a.m_types[i], b.m_types[i]) ) + return false; + } + return true; + } + static bool types_overlap(const ::HIR::TypeRef& a, const ::HIR::TypeRef& b) + { + static Span sp; + if( a.m_data.is_Generic() || b.m_data.is_Generic() ) + return true; + // TODO: Unbound/Opaque paths? + if( a.m_data.tag() != b.m_data.tag() ) + return false; + TU_MATCHA( (a.m_data, b.m_data), (ae, be), + (Generic, + ), + (Infer, + ), + (Diverge, + ), + (Closure, + BUG(sp, "Hit closure"); + ), + (Primitive, + if( ae != be ) + return false; + ), + (Path, + if( ae.path.m_data.tag() != be.path.m_data.tag() ) + return false; + TU_MATCHA( (ae.path.m_data, be.path.m_data), (ape, bpe), + (Generic, + if( ape.m_path != bpe.m_path ) + return false; + return H::types_overlap(ape.m_params, bpe.m_params); + ), + (UfcsUnknown, + ), + (UfcsKnown, + ), + (UfcsInherent, + ) + ) + TODO(sp, "Path - " << ae.path << " and " << be.path); + ), + (TraitObject, + if( ae.m_trait.m_path != be.m_trait.m_path ) + return false; + TODO(sp, "TraitObject - " << a << " and " << b); + ), + (ErasedType, + TODO(sp, "ErasedType - " << a); + ), + (Function, + if( ae.is_unsafe != be.is_unsafe ) + return false; + if( ae.m_abi != be.m_abi ) + return false; + if( ae.m_arg_types.size() != be.m_arg_types.size() ) + return false; + for(unsigned int i = 0; i < ae.m_arg_types.size(); i ++) + { + if( ! H::types_overlap(ae.m_arg_types[i], be.m_arg_types[i]) ) + return false; + } + ), + (Tuple, + if( ae.size() != be.size() ) + return false; + for(unsigned int i = 0; i < ae.size(); i ++) + { + if( ! H::types_overlap(ae[i], be[i]) ) + return false; + } + ), + (Slice, + return H::types_overlap( *ae.inner, *be.inner ); + ), + (Array, + if( ae.size_val != be.size_val ) + return false; + return H::types_overlap( *ae.inner, *be.inner ); + ), + (Pointer, + if( ae.type != be.type ) + return false; + return H::types_overlap( *ae.inner, *be.inner ); + ), + (Borrow, + if( ae.type != be.type ) + return false; + return H::types_overlap( *ae.inner, *be.inner ); + ) + ) + return true; + } + }; + + // 1. Are the impl types of the same form (or is one generic) + if( ! H::types_overlap(this->m_type, other.m_type) ) + return false; + if( ! H::types_overlap(this->m_trait_args, other.m_trait_args) ) + return false; + + return this->m_type == other.m_type && this->m_trait_args == other.m_trait_args; + + // TODO: Detect `impl<T> Foo<T> for Bar<T>` vs `impl<T> Foo<&T> for Bar<T>` + // > Create values for impl params from the type, then check if the trait params are compatible + return true; +} const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path(const Span& sp, const char* name) const |