diff options
-rw-r--r-- | src/hir_conv/bind.cpp | 2 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs.cpp | 60 | ||||
-rw-r--r-- | src/hir_typeck/outer.cpp | 242 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 45 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 13 | ||||
-rw-r--r-- | src/include/span.hpp | 4 |
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) |