diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/static.cpp | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index b35dbfe2..cb3c2ead 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -804,19 +804,22 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp, if( pp.m_types.size() != trait_ptr.m_params.m_types.size() ) { BUG(sp, "Incorrect number of parameters for trait"); } + + auto monomorph_cb = [&](const auto& gt)->const auto& { + const auto& ge = gt.m_data.as_Generic(); + if( ge.binding == 0xFFFF ) { + return target_type; + } + else { + if( ge.binding >= pp.m_types.size() ) + BUG(sp, "find_named_trait_in_trait - Generic #" << ge.binding << " " << ge.name << " out of range"); + return pp.m_types[ge.binding]; + } + }; + for( const auto& pt : trait_ptr.m_parent_traits ) { - auto pt_mono = monomorphise_traitpath_with(sp, pt, [&](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return target_type; - } - else { - if( ge.binding >= pp.m_types.size() ) - BUG(sp, "find_named_trait_in_trait - Generic #" << ge.binding << " " << ge.name << " out of range"); - return pp.m_types[ge.binding]; - } - }, false); + auto pt_mono = monomorphise_traitpath_with(sp, pt, monomorph_cb, false); DEBUG(pt << " => " << pt_mono); if( pt.m_path.m_path == des && pt_mono.m_path.m_params == des_params ) { @@ -829,6 +832,33 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp, return true; } } + + // Also check bounds for `Self: T` bounds + for(const auto& b : trait_ptr.m_params.m_bounds) + { + if( !b.is_TraitBound() ) continue; + const auto& be = b.as_TraitBound(); + + if( be.type == ::HIR::TypeRef("Self", 0xFFFF) ) + { + // Something earlier adds a "Self: SelfTrait" bound, prevent that from causing infinite recursion + if( be.trait.m_path.m_path == trait_path ) + continue ; + auto pt_mono = monomorphise_traitpath_with(sp, be.trait, monomorph_cb, false); + DEBUG(be.trait << " (Bound) => " << pt_mono); + + if( pt_mono.m_path.m_path == des ) { + callback( pt_mono.m_path.m_params, mv$(pt_mono.m_type_bounds) ); + return true; + } + + const auto& tr = m_crate.get_trait_by_path(sp, pt_mono.m_path.m_path); + if( find_named_trait_in_trait(sp, des, des_params, tr, pt_mono.m_path.m_path, pt_mono.m_path.m_params, target_type, callback) ) { + return true; + } + } + } + return false; } bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const |