Skip to content

Commit

Permalink
Typecheck Expessions - Improved handling of overlapping bounds, diver…
Browse files Browse the repository at this point in the history
…ging ivars
  • Loading branch information
thepowersgang committed Apr 21, 2019
1 parent 76c596b commit 3bf9a10
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 10 deletions.
27 changes: 21 additions & 6 deletions src/hir_typeck/expr_cs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,15 @@ struct Context
bool is_operator;

friend ::std::ostream& operator<<(::std::ostream& os, const Associated& v) {
os << "R" << v.rule_idx << " ";
if( v.name == "" ) {
os << "R" << v.rule_idx << " " << "req ty " << v.impl_ty << " impl " << v.trait << v.params;
os << "req ty " << v.impl_ty << " impl " << v.trait << v.params;
}
else {
os << "R" << v.rule_idx << " " << v.left_ty << " = " << "< `" << v.impl_ty << "` as `" << v.trait << v.params << "` >::" << v.name;
os << v.left_ty << " = " << "< `" << v.impl_ty << "` as `" << v.trait << v.params << "` >::" << v.name;
}
if( v.is_operator )
os << " - op";
return os;
}
};
Expand Down Expand Up @@ -5802,13 +5805,23 @@ namespace {
unsigned int count = 0;

::HIR::PathParams pp { dst.clone() };
bool found = context.m_resolve.find_trait_impls(sp, lang_Unsize, pp, src, [&best_impl,&count](auto impl, auto cmp){
bool found = context.m_resolve.find_trait_impls(sp, lang_Unsize, pp, src, [&best_impl,&count,&context](auto impl, auto cmp){
DEBUG("[check_unsize_tys] Found impl " << impl << (cmp == ::HIR::Compare::Fuzzy ? " (fuzzy)" : ""));
if( impl.more_specific_than(best_impl) )
if( !impl.overlaps_with(context.m_crate, best_impl) )
{
best_impl = mv$(impl);
// No overlap, count it as a new possibility
if( count == 0 )
best_impl = mv$(impl);
count ++;
}
else if( impl.more_specific_than(best_impl) )
{
best_impl = mv$(impl);
}
else
{
// Less specific
}
// TODO: Record the best impl (if fuzzy) and equate params
return cmp != ::HIR::Compare::Fuzzy;
});
Expand All @@ -5830,6 +5843,7 @@ namespace {
{
// TODO: Fuzzy?
//context.equate_types(sp, *e.inner, *s_e.inner);
DEBUG("Multiple impls");
}
}

Expand Down Expand Up @@ -6814,7 +6828,8 @@ namespace {
return false;
}

// Don't attempt to guess literalS
// Don't attempt to guess literals
// - What about if they're bounded?
if( ty_l.m_data.as_Infer().is_lit() )
{
DEBUG(i << ": Literal " << ty_l);
Expand Down
9 changes: 7 additions & 2 deletions src/hir_typeck/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -619,8 +619,12 @@ void HMTypeInferrence::set_ivar_to(unsigned int slot, ::HIR::TypeRef type)
}

#if 1
if( type.m_data.is_Diverge() ) {
root_ivar.type->m_data.as_Infer().ty_class = ::HIR::InferClass::Diverge;
if( type.m_data.is_Diverge() )
{
if( root_ivar.type->m_data.as_Infer().ty_class == ::HIR::InferClass::None )
{
root_ivar.type->m_data.as_Infer().ty_class = ::HIR::InferClass::Diverge;
}
}
else
#endif
Expand Down Expand Up @@ -2276,6 +2280,7 @@ bool TraitResolution::find_named_trait_in_trait(const Span& sp,

//DEBUG(pt << " => " << pt_mono);
if( pt.m_path.m_path == des ) {
//DEBUG("Found potential " << pt_mono);
// NOTE: Doesn't quite work...
//auto cmp = this->compare_pp(sp, pt_mono.m_path.m_params, des_params);
//if( cmp != ::HIR::Compare::Unequal )
Expand Down
1 change: 1 addition & 0 deletions src/hir_typeck/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class HMTypeInferrence
public: // ?? - Needed once, anymore?
struct IVar
{
//bool could_be_diverge; // TODO: use this instead of InferClass::Diverge
unsigned int alias; // If not ~0, this points to another ivar
::std::unique_ptr< ::HIR::TypeRef> type; // Type (only nullptr if alias!=0)

Expand Down
31 changes: 29 additions & 2 deletions src/hir_typeck/impl_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,24 @@ bool ImplRef::more_specific_than(const ImplRef& other) const
)
),
(BoundedPtr,
return true;
if( !other.m_data.is_BoundedPtr() )
return false;
const auto& oe = other.m_data.as_BoundedPtr();
assert( *te.type == *oe.type );
assert( *te.trait_args == *oe.trait_args );
if( te.assoc->size() > oe.assoc->size() )
return true;
return false;
),
(Bounded,
return true;
if( !other.m_data.is_Bounded() )
return false;
const auto& oe = other.m_data.as_Bounded();
assert( te.type == oe.type );
assert( te.trait_args == oe.trait_args );
if( te.assoc.size() > oe.assoc.size() )
return true;
return false;
)
)
throw "";
Expand All @@ -50,8 +64,21 @@ bool ImplRef::overlaps_with(const ::HIR::Crate& crate, const ImplRef& other) con
return te.impl->overlaps_with( crate, *oe.impl );
),
(BoundedPtr,
// TODO: Bounded and BoundedPtr are compatible
if( *te.type != *oe.type )
return false;
if( *te.trait_args != *oe.trait_args )
return false;
// Don't check associated types
return true;
),
(Bounded,
if( te.type != oe.type )
return false;
if( te.trait_args != oe.trait_args )
return false;
// Don't check associated types
return true;
)
)
return false;
Expand Down

0 comments on commit 3bf9a10

Please sign in to comment.