summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_conv/bind.cpp2
-rw-r--r--src/hir_conv/resolve_ufcs.cpp60
-rw-r--r--src/hir_typeck/outer.cpp242
-rw-r--r--src/hir_typeck/static.cpp45
-rw-r--r--src/hir_typeck/static.hpp13
-rw-r--r--src/include/span.hpp4
6 files changed, 307 insertions, 59 deletions
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index ab561085..7addeb5b 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -253,7 +253,7 @@ namespace {
)
),
(UfcsUnknown,
- TODO(sp, "Should UfcsKnown be encountered here?");
+ //TODO(sp, "Should UfcsKnown be encountered here?");
),
(UfcsInherent,
),
diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp
index 2cac5311..105dde2e 100644
--- a/src/hir_conv/resolve_ufcs.cpp
+++ b/src/hir_conv/resolve_ufcs.cpp
@@ -7,6 +7,7 @@
#include <hir/hir.hpp>
#include <hir/expr.hpp>
#include <hir/visitor.hpp>
+#include <hir_typeck/static.hpp>
namespace {
class Visitor:
@@ -17,16 +18,14 @@ namespace {
typedef ::std::vector< ::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > t_trait_imports;
t_trait_imports m_traits;
- const ::HIR::GenericParams* m_impl_params;
- const ::HIR::GenericParams* m_item_params;
+ StaticTraitResolve m_resolve;
const ::HIR::Trait* m_current_trait;
const ::HIR::PathChain* m_current_trait_path;
public:
Visitor(const ::HIR::Crate& crate):
m_crate(crate),
- m_impl_params(nullptr),
- m_item_params(nullptr),
+ m_resolve(crate),
m_current_trait(nullptr)
{}
@@ -39,9 +38,12 @@ namespace {
}
};
ModTraitsGuard push_mod_traits(const ::HIR::Module& mod) {
+ DEBUG("");
auto rv = ModTraitsGuard { this, mv$(this->m_traits) };
- for( const auto& trait_path : mod.m_traits )
+ for( const auto& trait_path : mod.m_traits ) {
+ DEBUG("- " << trait_path);
m_traits.push_back( ::std::make_pair( &trait_path, &this->find_trait(trait_path) ) );
+ }
return rv;
}
void visit_module(::HIR::PathChain p, ::HIR::Module& mod) override
@@ -50,40 +52,35 @@ namespace {
::HIR::Visitor::visit_module(p, mod);
}
- void visit_struct(::HIR::PathChain p, ::HIR::Struct& fcn) override {
- m_item_params = &fcn.m_params;
- ::HIR::Visitor::visit_struct(p, fcn);
- m_item_params = nullptr;
+ void visit_struct(::HIR::PathChain p, ::HIR::Struct& item) override {
+ auto _ = m_resolve.set_item_generics(item.m_params);
+ ::HIR::Visitor::visit_struct(p, item);
}
- void visit_enum(::HIR::PathChain p, ::HIR::Enum& fcn) override {
- m_item_params = &fcn.m_params;
- ::HIR::Visitor::visit_enum(p, fcn);
- m_item_params = nullptr;
+ void visit_enum(::HIR::PathChain p, ::HIR::Enum& item) override {
+ auto _ = m_resolve.set_item_generics(item.m_params);
+ ::HIR::Visitor::visit_enum(p, item);
}
- void visit_function(::HIR::PathChain p, ::HIR::Function& fcn) override {
- m_item_params = &fcn.m_params;
- ::HIR::Visitor::visit_function(p, fcn);
- m_item_params = nullptr;
+ void visit_function(::HIR::PathChain p, ::HIR::Function& item) override {
+ auto _ = m_resolve.set_item_generics(item.m_params);
+ ::HIR::Visitor::visit_function(p, item);
}
void visit_trait(::HIR::PathChain p, ::HIR::Trait& trait) override {
m_current_trait = &trait;
m_current_trait_path = &p;
- m_impl_params = &trait.m_params;
+ //auto _ = m_resolve.set_item_generics(trait.m_params);
+ auto _ = m_resolve.set_impl_generics(trait.m_params);
::HIR::Visitor::visit_trait(p, trait);
- m_impl_params = nullptr;
m_current_trait = nullptr;
}
void visit_type_impl(::HIR::TypeImpl& impl) override {
- auto _ = this->push_mod_traits( this->m_crate.get_mod_by_path(Span(), impl.m_src_module) );
- m_impl_params = &impl.m_params;
+ auto _t = this->push_mod_traits( this->m_crate.get_mod_by_path(Span(), impl.m_src_module) );
+ auto _g = m_resolve.set_impl_generics(impl.m_params);
::HIR::Visitor::visit_type_impl(impl);
- m_impl_params = nullptr;
}
void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) {
- auto _ = this->push_mod_traits( this->m_crate.get_mod_by_path(Span(), impl.m_src_module) );
- m_impl_params = &impl.m_params;
+ auto _t = this->push_mod_traits( this->m_crate.get_mod_by_path(Span(), impl.m_src_module) );
+ auto _g = m_resolve.set_impl_generics(impl.m_params);
::HIR::Visitor::visit_trait_impl(trait_path, impl);
- m_impl_params = nullptr;
}
void visit_expr(::HIR::ExprPtr& expr) override
@@ -236,13 +233,8 @@ namespace {
if( this->locate_item_in_trait(pc, trait, pd) ) {
const auto& type = *e.type;
- return this->m_crate.find_trait_impls(trait_path.m_path, type, [](const auto& x)->const auto&{return x;}, [&](const auto& impl) {
- DEBUG("FOUND impl" << impl.m_params.fmt_args() << " " << trait_path.m_path << impl.m_trait_args << " for " << impl.m_type);
- // TODO: Check bounds
- for(const auto& bound : impl.m_params.m_bounds) {
- DEBUG("- TODO: Bound " << bound);
- return false;
- }
+ return this->m_resolve.find_impl(sp, trait_path.m_path, nullptr, type, [&](const auto& impl){
+ DEBUG("FOUND impl from " << impl);
pd = get_ufcs_known(mv$(e), make_generic_path(trait_path.m_path, trait), trait);
return true;
});
@@ -278,10 +270,10 @@ namespace {
this->visit_path_params( e.params );
// Search for matching impls in current generic blocks
- if( m_item_params != nullptr && locate_trait_item_in_bounds(pc, *e.type, *m_item_params, p.m_data) ) {
+ if( m_resolve.m_item_generics != nullptr && locate_trait_item_in_bounds(pc, *e.type, *m_resolve.m_item_generics, p.m_data) ) {
return ;
}
- if( m_impl_params != nullptr && locate_trait_item_in_bounds(pc, *e.type, *m_impl_params, p.m_data) ) {
+ if( m_resolve.m_impl_generics != nullptr && locate_trait_item_in_bounds(pc, *e.type, *m_resolve.m_impl_generics, p.m_data) ) {
return ;
}
diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp
index 9439a007..22dcaa43 100644
--- a/src/hir_typeck/outer.cpp
+++ b/src/hir_typeck/outer.cpp
@@ -99,16 +99,42 @@ namespace {
{
::HIR::Crate& crate;
StaticTraitResolve m_resolve;
+
+ const ::HIR::Trait* m_current_trait;
+ const ::HIR::PathChain* m_current_trait_path;
::std::vector< ::HIR::TypeRef* > m_self_types;
+
+ typedef ::std::vector< ::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > t_trait_imports;
+ t_trait_imports m_traits;
public:
Visitor(::HIR::Crate& crate):
crate(crate),
- m_resolve(crate)
+ m_resolve(crate),
+ m_current_trait(nullptr)
{
}
private:
+ struct ModTraitsGuard {
+ Visitor* v;
+ t_trait_imports old_imports;
+
+ ~ModTraitsGuard() {
+ this->v->m_traits = mv$(this->old_imports);
+ }
+ };
+ ModTraitsGuard push_mod_traits(const ::HIR::Module& mod) {
+ static Span sp;
+ DEBUG("");
+ auto rv = ModTraitsGuard { this, mv$(this->m_traits) };
+ for( const auto& trait_path : mod.m_traits ) {
+ DEBUG("- " << trait_path);
+ m_traits.push_back( ::std::make_pair( &trait_path, &this->crate.get_trait_by_path(sp, trait_path) ) );
+ }
+ return rv;
+ }
+
void update_self_type(const Span& sp, ::HIR::TypeRef& ty)
{
TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e),
@@ -259,6 +285,209 @@ namespace {
::HIR::Visitor::visit_generic_path(p, pc);
}
+
+ private:
+ bool locate_trait_item_in_bounds(const Span& sp, ::HIR::Visitor::PathContext pc, const ::HIR::TypeRef& tr, const ::HIR::GenericParams& params, ::HIR::Path::Data& pd) {
+ //const auto& name = pd.as_UfcsUnknown().item;
+ for(const auto& b : params.m_bounds)
+ {
+ TU_IFLET(::HIR::GenericBound, b, TraitBound, e,
+ DEBUG("- " << e.type << " : " << e.trait.m_path);
+ if( e.type == tr ) {
+ DEBUG(" - Match");
+ if( locate_in_trait_and_set(sp, pc, e.trait.m_path, this->crate.get_trait_by_path(sp, e.trait.m_path.m_path), pd) ) {
+ return true;
+ }
+ }
+ );
+ // -
+ }
+ return false;
+ }
+ static ::HIR::Path::Data get_ufcs_known(::HIR::Path::Data::Data_UfcsUnknown e, ::HIR::GenericPath trait_path, const ::HIR::Trait& trait)
+ {
+ return ::HIR::Path::Data::make_UfcsKnown({ mv$(e.type), mv$(trait_path), mv$(e.item), mv$(e.params)} );
+ }
+ static bool locate_item_in_trait(::HIR::Visitor::PathContext pc, const ::HIR::Trait& trait, ::HIR::Path::Data& pd)
+ {
+ const auto& e = pd.as_UfcsUnknown();
+
+ switch(pc)
+ {
+ case ::HIR::Visitor::PathContext::VALUE:
+ if( trait.m_values.find( e.item ) != trait.m_values.end() ) {
+ return true;
+ }
+ break;
+ case ::HIR::Visitor::PathContext::TRAIT:
+ break;
+ case ::HIR::Visitor::PathContext::TYPE:
+ if( trait.m_types.find( e.item ) != trait.m_types.end() ) {
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+ bool locate_in_trait_and_set(const Span& sp, ::HIR::Visitor::PathContext pc, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait, ::HIR::Path::Data& pd) {
+ if( locate_item_in_trait(pc, trait, pd) ) {
+ pd = get_ufcs_known(mv$(pd.as_UfcsUnknown()), make_generic_path(trait_path.m_path, trait), trait);
+ return true;
+ }
+ // Search supertraits (recursively)
+ for( unsigned int i = 0; i < trait.m_parent_traits.size(); i ++ )
+ {
+ const auto& par_trait_path = trait.m_parent_traits[i].m_path;
+ //const auto& par_trait_ent = *trait.m_parent_trait_ptrs[i];
+ const auto& par_trait_ent = this->crate.get_trait_by_path(sp, par_trait_path.m_path);
+ if( locate_in_trait_and_set(sp, pc, par_trait_path, par_trait_ent, pd) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+ bool locate_in_trait_impl_and_set(::HIR::Visitor::PathContext pc, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait, ::HIR::Path::Data& pd) {
+ static Span sp;
+
+ auto& e = pd.as_UfcsUnknown();
+ //if( this->m_resolve.trait_contains_type(sp, trait_path, trait, e.item, out_path) )
+ if( this->locate_item_in_trait(pc, trait, pd) ) {
+ const auto& type = *e.type;
+
+ return this->crate.find_trait_impls(trait_path.m_path, type, [](const auto& x)->const auto&{return x;}, [&](const auto& impl) {
+ DEBUG("FOUND impl" << impl.m_params.fmt_args() << " " << trait_path.m_path << impl.m_trait_args << " for " << impl.m_type);
+ // TODO: Check bounds
+ for(const auto& bound : impl.m_params.m_bounds) {
+ DEBUG("- TODO: Bound " << bound);
+ return false;
+ }
+ pd = get_ufcs_known(mv$(e), make_generic_path(trait_path.m_path, trait), trait);
+ return true;
+ });
+ }
+ else {
+ DEBUG("- Item " << e.item << " not in trait " << trait_path.m_path);
+ }
+
+
+ // Search supertraits (recursively)
+ for( unsigned int i = 0; i < trait.m_parent_traits.size(); i ++ )
+ {
+ const auto& par_trait_path = trait.m_parent_traits[i].m_path;
+ //const auto& par_trait_ent = *trait.m_parent_trait_ptrs[i];
+ const auto& par_trait_ent = this->crate.get_trait_by_path(sp, par_trait_path.m_path);
+ // TODO: Modify path parameters based on the current trait's params
+ if( locate_in_trait_impl_and_set(pc, par_trait_path, par_trait_ent, pd) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+ static ::HIR::GenericPath make_generic_path(::HIR::SimplePath sp, const ::HIR::Trait& trait)
+ {
+ auto trait_path_g = ::HIR::GenericPath( mv$(sp) );
+ for(unsigned int i = 0; i < trait.m_params.m_types.size(); i ++ ) {
+ trait_path_g.m_params.m_types.push_back( ::HIR::TypeRef(trait.m_params.m_types[i].m_name, i) );
+ }
+ return trait_path_g;
+ }
+ void visit_path_UfcsUnknown(const Span& sp, ::HIR::Path& p, ::HIR::Visitor::PathContext pc)
+ {
+ TRACE_FUNCTION_F("UfcsUnknown - p=" << p);
+ auto& e = p.m_data.as_UfcsUnknown();
+
+ this->visit_type( *e.type );
+ this->visit_path_params( e.params );
+
+ // Search for matching impls in current generic blocks
+ if( m_resolve.m_item_generics != nullptr && locate_trait_item_in_bounds(sp, pc, *e.type, *m_resolve.m_item_generics, p.m_data) ) {
+ return ;
+ }
+ if( m_resolve.m_impl_generics != nullptr && locate_trait_item_in_bounds(sp, pc, *e.type, *m_resolve.m_impl_generics, p.m_data) ) {
+ return ;
+ }
+
+ TU_IFLET(::HIR::TypeRef::Data, e.type->m_data, Generic, te,
+ // If processing a trait, and the type is 'Self', search for the type/method on the trait
+ // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues?
+ if( te.name == "Self" && m_current_trait ) {
+ auto trait_path = ::HIR::GenericPath( m_current_trait_path->to_path() );
+ for(unsigned int i = 0; i < m_current_trait->m_params.m_types.size(); i ++ ) {
+ trait_path.m_params.m_types.push_back( ::HIR::TypeRef(m_current_trait->m_params.m_types[i].m_name, i) );
+ }
+ if( this->locate_in_trait_and_set(sp, pc, trait_path, *m_current_trait, p.m_data) ) {
+ // Success!
+ return ;
+ }
+ }
+ ERROR(sp, E0000, "Failed to find impl with '" << e.item << "' for " << *e.type);
+ return ;
+ )
+ else {
+ // 1. Search for applicable inherent methods (COMES FIRST!)
+ for( const auto& impl : this->crate.m_type_impls )
+ {
+ if( !impl.matches_type(*e.type) ) {
+ continue ;
+ }
+ DEBUG("- matched inherent impl " << *e.type);
+ // Search for item in this block
+ switch( pc )
+ {
+ case ::HIR::Visitor::PathContext::VALUE:
+ if( impl.m_methods.find(e.item) == impl.m_methods.end() ) {
+ continue ;
+ }
+ // Found it, just keep going (don't care about details here)
+ break;
+ case ::HIR::Visitor::PathContext::TRAIT:
+ case ::HIR::Visitor::PathContext::TYPE:
+ continue ;
+ }
+
+ auto new_data = ::HIR::Path::Data::make_UfcsInherent({ mv$(e.type), mv$(e.item), mv$(e.params)} );
+ p.m_data = mv$(new_data);
+ DEBUG("- Resolved, replace with " << p);
+ return ;
+ }
+ // 2. Search all impls of in-scope traits for this method on this type
+ for( const auto& trait_info : m_traits )
+ {
+ const auto& trait = *trait_info.second;
+
+ switch(pc)
+ {
+ case ::HIR::Visitor::PathContext::VALUE:
+ if( trait.m_values.find(e.item) == trait.m_values.end() )
+ continue ;
+ break;
+ case ::HIR::Visitor::PathContext::TRAIT:
+ case ::HIR::Visitor::PathContext::TYPE:
+ if( trait.m_types.find(e.item) == trait.m_types.end() )
+ continue ;
+ break;
+ }
+ DEBUG("- Trying trait " << *trait_info.first);
+
+ auto trait_path = ::HIR::GenericPath( *trait_info.first );
+ for(unsigned int i = 0; i < trait.m_params.m_types.size(); i ++ ) {
+ trait_path.m_params.m_types.push_back( ::HIR::TypeRef() );
+ }
+
+ // TODO: Search supertraits
+ // TODO: Should impls be searched first, or item names?
+ // - Item names add complexity, but impls are slower
+ if( this->locate_in_trait_impl_and_set(pc, mv$(trait_path), trait, p.m_data) ) {
+ return ;
+ }
+ }
+ }
+
+ // Couldn't find it
+ ERROR(sp, E0000, "Failed to find impl with '" << e.item << "' for " << *e.type << " (in " << p << ")");
+ }
+
+ public:
void visit_path(::HIR::Path& p, ::HIR::Visitor::PathContext pc) override
{
assert(pc == ::HIR::Visitor::PathContext::TYPE);
@@ -314,13 +543,24 @@ namespace {
}
}
+ void visit_module(::HIR::PathChain p, ::HIR::Module& mod) override
+ {
+ auto _ = this->push_mod_traits( mod );
+ ::HIR::Visitor::visit_module(p, mod);
+ }
+
void visit_trait(::HIR::PathChain p, ::HIR::Trait& item) override
{
+ m_current_trait = &item;
+ m_current_trait_path = &p;
+
auto _ = m_resolve.set_item_generics(item.m_params);
::HIR::TypeRef tr { "Self", 0xFFFF };
m_self_types.push_back(&tr);
::HIR::Visitor::visit_trait(p, item);
m_self_types.pop_back();
+
+ m_current_trait = nullptr;
}
void visit_struct(::HIR::PathChain p, ::HIR::Struct& item) override
{
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index c8cb0df5..7a717fbc 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -9,12 +9,12 @@
bool StaticTraitResolve::find_impl(
const Span& sp,
- const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& trait_params,
+ const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params,
const ::HIR::TypeRef& type,
t_cb_find_impl found_cb
) const
{
- TRACE_FUNCTION_F(trait_path << trait_params << " for " << type);
+ TRACE_FUNCTION_F(trait_path << FMT_CB(os, if(trait_params) { os << *trait_params; } else { os << "<?>"; }) << " for " << type);
auto cb_ident = [](const auto&ty)->const auto&{return ty;};
struct H {
@@ -47,32 +47,36 @@ bool StaticTraitResolve::find_impl(
{
if( e.trait.m_path.m_path == trait_path ) {
// Check against `params`
- DEBUG("Checking " << trait_params << " vs " << b_params);
- if( !H::compare_pp(sp, trait_params, b_params) )
- return false;
+ if( trait_params ) {
+ DEBUG("Checking " << *trait_params << " vs " << b_params);
+ if( !H::compare_pp(sp, *trait_params, b_params) )
+ return false;
+ }
// Hand off to the closure, and return true if it does
if( found_cb(ImplRef(e.type, e.trait.m_path.m_params, e.trait.m_type_bounds)) ) {
return true;
}
}
+ #if 1
// HACK: The wrapping closure takes associated types from this bound and applies them to the returned set
// - XXX: This is actually wrong (false-positive) in many cases. FIXME
bool rv = this->find_named_trait_in_trait(sp,
- trait_path,trait_params,
+ trait_path,b_params,
*e.trait.m_trait_ptr, e.trait.m_path.m_path,e.trait.m_path.m_params,
type,
- [&](auto assoc) {
+ [&](const auto& params, auto assoc) {
for(const auto& i : e.trait.m_type_bounds) {
// TODO: Only include from above when needed
//if( des_trait_ref.m_types.count(i.first) ) {
assoc.insert( ::std::make_pair(i.first, i.second.clone()) );
//}
}
- return found_cb( ImplRef(type, trait_params, assoc) );
+ return found_cb( ImplRef(type, params, assoc) );
});
if( rv ) {
return true;
}
+ #endif
}
// If the input type is an associated type controlled by this trait bound, check for added bounds.
@@ -89,7 +93,7 @@ bool StaticTraitResolve::find_impl(
TODO(sp, "Handle associated type bounds on !Self");
continue ;
}
- if( be.trait.m_path.m_path == trait_path && H::compare_pp(sp, be.trait.m_path.m_params, trait_params) ) {
+ if( be.trait.m_path.m_path == trait_path && (!trait_params || H::compare_pp(sp, be.trait.m_path.m_params, *trait_params)) ) {
DEBUG("- Found an associated type impl");
auto tp_mono = monomorphise_traitpath_with(sp, be.trait, [&assoc_info,&sp](const auto& gt)->const auto& {
@@ -141,12 +145,15 @@ bool StaticTraitResolve::find_impl(
}
};
auto match = impl.m_type.match_test_generics_fuzz(sp, type, cb_ident, cb);
- assert( trait_params.m_types.size() == impl.m_trait_args.m_types.size() );
- for( unsigned int i = 0; i < impl.m_trait_args.m_types.size(); i ++ )
+ if( trait_params )
{
- const auto& l = impl.m_trait_args.m_types[i];
- const auto& r = trait_params.m_types[i];
- match &= l.match_test_generics_fuzz(sp, r, cb_ident, cb);
+ assert( trait_params->m_types.size() == impl.m_trait_args.m_types.size() );
+ for( unsigned int i = 0; i < impl.m_trait_args.m_types.size(); i ++ )
+ {
+ const auto& l = impl.m_trait_args.m_types[i];
+ const auto& r = trait_params->m_types[i];
+ match &= l.match_test_generics_fuzz(sp, r, cb_ident, cb);
+ }
}
if( match != ::HIR::Compare::Equal )
return false;
@@ -200,7 +207,7 @@ bool StaticTraitResolve::find_impl(
auto b_tp_mono = monomorphise_traitpath_with(sp, e.trait, cb_monomorph, false);
DEBUG("- b_ty_mono = " << b_ty_mono << ", b_tp_mono = " << b_tp_mono);
if( !this->find_impl(sp, b_tp_mono.m_path.m_path, b_tp_mono.m_path.m_params, b_ty_mono, [](const auto&){return true;}) ) {
- DEBUG("> Fail");
+ DEBUG("> Fail - " << b_ty_mono << ": " << b_tp_mono);
return false;
}
)
@@ -297,7 +304,7 @@ void StaticTraitResolve::expand_associated_types(const Span& sp, ::HIR::TypeRef&
bool found_supertrait = this->find_named_trait_in_trait(sp,
e2.trait.m_path, e2.trait.m_params,
*be.trait.m_trait_ptr, be.trait.m_path.m_path, be.trait.m_path.m_params, *e2.type,
- [&e2,&input,&assume_opaque](auto assoc){
+ [&e2,&input,&assume_opaque](const auto& params, auto assoc){
auto it = assoc.find(e2.item);
if( it != assoc.end() ) {
assume_opaque = false;
@@ -514,7 +521,7 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp,
const ::HIR::SimplePath& des, const ::HIR::PathParams& des_params,
const ::HIR::Trait& trait_ptr, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& pp,
const ::HIR::TypeRef& target_type,
- ::std::function<void(::std::map< ::std::string, ::HIR::TypeRef>)> callback
+ ::std::function<void(const ::HIR::PathParams&, ::std::map< ::std::string, ::HIR::TypeRef>)> callback
) const
{
TRACE_FUNCTION_F(des << " from " << trait_path << pp);
@@ -537,12 +544,12 @@ bool StaticTraitResolve::find_named_trait_in_trait(const Span& sp,
DEBUG(pt << " => " << pt_mono);
if( pt.m_path.m_path == des ) {
- callback( mv$(pt_mono.m_type_bounds) );
+ 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.m_path.m_path);
- if( find_named_trait_in_trait(sp, des, des_params, tr, pt.m_path.m_path, pt_mono.m_path.m_params, target_type, [](const auto&){}) ) {
+ if( find_named_trait_in_trait(sp, des, des_params, tr, pt.m_path.m_path, pt_mono.m_path.m_params, target_type, callback) ) {
return true;
}
}
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index 8c540a6e..a4baaf57 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -79,7 +79,7 @@ public:
friend ::std::ostream& operator<<(::std::ostream& os, const ImplRef& x) {
TU_MATCH(Data, (x.m_data), (e),
(TraitImpl,
- os << "impl" << e.impl->m_params.fmt_args() << " SomeTrait" << e.impl->m_trait_args << " for " << e.impl->m_type << " where " << e.impl->m_params.fmt_bounds();
+ os << "impl" << e.impl->m_params.fmt_args() << " SomeTrait" << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds();
),
(Bounded,
os << "bound";
@@ -98,6 +98,15 @@ public:
const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& trait_params,
const ::HIR::TypeRef& type,
t_cb_find_impl found_cb
+ ) const
+ {
+ return this->find_impl(sp, trait_path, &trait_params, type, found_cb);
+ }
+ bool find_impl(
+ const Span& sp,
+ const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params,
+ const ::HIR::TypeRef& type,
+ t_cb_find_impl found_cb
) const;
void expand_associated_types(const Span& sp, ::HIR::TypeRef& input) const;
@@ -111,7 +120,7 @@ public:
const ::HIR::SimplePath& des, const ::HIR::PathParams& params,
const ::HIR::Trait& trait_ptr, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& pp,
const ::HIR::TypeRef& self_type,
- ::std::function<void(::std::map< ::std::string, ::HIR::TypeRef>)> callback
+ ::std::function<void(const ::HIR::PathParams&, ::std::map< ::std::string, ::HIR::TypeRef>)> callback
) const;
///
bool 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;
diff --git a/src/include/span.hpp b/src/include/span.hpp
index 881c34df..35d59f42 100644
--- a/src/include/span.hpp
+++ b/src/include/span.hpp
@@ -66,7 +66,7 @@ Spanned<T> make_spanned(Span sp, T val) {
#define ERROR(span, code, msg) do { ::Span(span).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0)
#define WARNING(span, code, msg) do { ::Span(span).warning(code, [&](::std::ostream& os) { os << msg; }); } while(0)
-#define BUG(span, msg) do { ::Span(span).bug([&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Bug fell through"); } while(0)
-#define TODO(span, msg) do { const char* __TODO_func = __func__; ::Span(span).bug([&](::std::ostream& os) { os << "TODO: " << __TODO_func << " - " << msg; }); throw ::std::runtime_error("Bug (todo) fell through"); } while(0)
+#define BUG(span, msg) do { ::Span(span).bug([&](::std::ostream& os) { os << __FILE__ << ":" << __LINE__ << ": " << msg; }); throw ::std::runtime_error("Bug fell through"); } while(0)
+#define TODO(span, msg) do { const char* __TODO_func = __func__; ::Span(span).bug([&](::std::ostream& os) { os << __FILE__ << ":" << __LINE__ << ": TODO: " << __TODO_func << " - " << msg; }); throw ::std::runtime_error("Bug (todo) fell through"); } while(0)
#define ASSERT_BUG(span, cnd, msg) do { if( !(cnd) ) { ::Span(span).bug([&](::std::ostream& os) { os << "ASSERT FAIL: " #cnd << ": " << msg; }); throw ::std::runtime_error("Bug fell through"); } } while(0)