diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/type.cpp | 20 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 44 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 1 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 93 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 23 | ||||
-rw-r--r-- | src/parse/lex.cpp | 4 |
6 files changed, 172 insertions, 13 deletions
diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 46ecf229..14fa4c46 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -367,13 +367,29 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x return match_generics_pp(sp, tpe.m_params, xpe.m_params, resolve_placeholder, callback); ), (UfcsKnown, + auto cmp = tpe.type->match_test_generics_fuzz( sp, *xpe.type, resolve_placeholder, callback ); + if( tpe.trait.m_path != xpe.trait.m_path ) + return Compare::Unequal; + cmp &= match_generics_pp(sp, tpe.trait.m_params, xpe.trait.m_params, resolve_placeholder, callback); + if( tpe.item != xpe.item ) + return Compare::Unequal; + cmp &= match_generics_pp(sp, tpe.params, xpe.params, resolve_placeholder, callback); + return cmp; TODO(sp, "Path UfcsKnown - " << *this << " and " << x); ), (UfcsUnknown, - TODO(sp, "Path UfcsUnknown - " << *this << " and " << x); + auto cmp = tpe.type->match_test_generics_fuzz( sp, *xpe.type, resolve_placeholder, callback ); + if( tpe.item != xpe.item ) + return Compare::Unequal; + cmp &= match_generics_pp(sp, tpe.params, xpe.params, resolve_placeholder, callback); + return cmp; ), (UfcsInherent, - TODO(sp, "Path UfcsInherent - " << *this << " and " << x); + auto cmp = tpe.type->match_test_generics_fuzz( sp, *xpe.type, resolve_placeholder, callback ); + if( tpe.item != xpe.item ) + return Compare::Unequal; + cmp &= match_generics_pp(sp, tpe.params, xpe.params, resolve_placeholder, callback); + return cmp; ) ) ), diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 6276a287..ab561085 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -6,6 +6,8 @@ #include <hir/expr.hpp> #include <algorithm> // std::find_if +#include <hir_typeck/static.hpp> + namespace { @@ -110,6 +112,7 @@ namespace { return ::std::make_pair( &enm, idx ); } + class Visitor: public ::HIR::Visitor { @@ -229,28 +232,51 @@ namespace { ::HIR::Visitor::visit_type(ty); TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Path, e, - TU_IFLET( ::HIR::Path::Data, e.path.m_data, Generic, e2, - const auto& item = *reinterpret_cast< const ::HIR::TypeItem*>( get_type_pointer(sp, m_crate, e2.m_path, Target::TypeItem) ); + TU_MATCH( ::HIR::Path::Data, (e.path.m_data), (pe), + (Generic, + const auto& item = *reinterpret_cast< const ::HIR::TypeItem*>( get_type_pointer(sp, m_crate, pe.m_path, Target::TypeItem) ); TU_MATCH_DEF( ::HIR::TypeItem, (item), (e3), ( - ERROR(sp, E0000, "Unexpected item type returned for " << e2.m_path << " - " << item.tag_str()); + ERROR(sp, E0000, "Unexpected item type returned for " << pe.m_path << " - " << item.tag_str()); ), (Struct, - fix_param_count(sp, e2, e3.m_params, e2.m_params); + fix_param_count(sp, pe, e3.m_params, pe.m_params); e.binding = ::HIR::TypeRef::TypePathBinding::make_Struct(&e3); ), (Enum, - fix_param_count(sp, e2, e3.m_params, e2.m_params); + fix_param_count(sp, pe, e3.m_params, pe.m_params); e.binding = ::HIR::TypeRef::TypePathBinding::make_Enum(&e3); ), (Trait, - ty.m_data = ::HIR::TypeRef::Data::make_TraitObject({ mv$(e2), {}, {} }); + ty.m_data = ::HIR::TypeRef::Data::make_TraitObject({ mv$(pe), {}, {} }); ) ) + ), + (UfcsUnknown, + TODO(sp, "Should UfcsKnown be encountered here?"); + ), + (UfcsInherent, + ), + (UfcsKnown, + if( pe.type->m_data.is_Path() && pe.type->m_data.as_Path().binding.is_Opaque() ) { + // - Opaque type, opaque result + e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({}); + } + else if( pe.type->m_data.is_Generic() ) { + // - Generic type, opaque resut. (TODO: Sometimes these are known - via generic bounds) + e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({}); + } + else { + //bool found = find_impl(sp, m_crate, pe.trait.m_path, pe.trait.m_params, *pe.type, [&](const auto& impl_params, const auto& impl) { + // DEBUG("TODO"); + // return false; + // }); + //if( found ) { + //} + //TODO(sp, "Resolve known UfcsKnown - " << ty); + } + ) ) - else { - e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({}); - } ) } diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index c98d9c59..e3662cdc 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -3185,6 +3185,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: root_ptr->visit(visitor); //context.equate_types(expr->span(), result_type, root_ptr->m_res_type); + DEBUG("Return type = " << result_type); context.equate_types_coerce(expr->span(), result_type, root_ptr); } diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp new file mode 100644 index 00000000..5fc4dc5f --- /dev/null +++ b/src/hir_typeck/static.cpp @@ -0,0 +1,93 @@ + +#include "static.hpp" + +bool StaticTraitResolve::find_impl( + const Span& sp, + const ::HIR::Crate& crate, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams& trait_params, + const ::HIR::TypeRef& type, + t_cb_find_impl found_cb + ) +{ + auto cb_ident = [](const auto&ty)->const auto&{return ty;}; + return crate.find_trait_impls(trait_path, type, cb_ident, [&](const auto& impl) { + DEBUG("TODO: impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << " where " << impl.m_params.fmt_bounds()); + + ::std::vector< const ::HIR::TypeRef*> impl_params; + impl_params.resize( impl.m_params.m_types.size() ); + + auto cb = [&impl_params,&sp,cb_ident](auto idx, const auto& ty) { + assert( idx < impl_params.size() ); + if( ! impl_params[idx] ) { + impl_params[idx] = &ty; + return ::HIR::Compare::Equal; + } + else { + return impl_params[idx]->compare_with_placeholders(sp, ty, cb_ident); + } + }; + 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 ++ ) + { + 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; + + ::std::vector< ::HIR::TypeRef> placeholders; + for(unsigned int i = 0; i < impl_params.size(); i ++ ) { + if( !impl_params[i] ) { + if( placeholders.size() == 0 ) + placeholders.resize(impl_params.size()); + placeholders[i] = ::HIR::TypeRef("impl_?", 2*256 + i); + } + } + auto cb_match = [&](unsigned int idx, const auto& ty) { + if( ty.m_data.is_Generic() && ty.m_data.as_Generic().binding == idx ) + return ::HIR::Compare::Equal; + if( idx >> 8 == 2 ) { + auto i = idx % 256; + ASSERT_BUG(sp, !impl_params[i], "Placeholder to populated type returned"); + auto& ph = placeholders[i]; + if( ph.m_data.is_Generic() && ph.m_data.as_Generic().binding == idx ) { + DEBUG("Bind placeholder " << i << " to " << ty); + ph = ty.clone(); + return ::HIR::Compare::Equal; + } + else { + TODO(sp, "Compare placeholder " << i << " " << ph << " == " << ty); + } + } + else { + return ::HIR::Compare::Unequal; + } + }; + auto cb_monomorph = [&](const auto& gt)->const auto& { + const auto& ge = gt.m_data.as_Generic(); + ASSERT_BUG(sp, ge.binding >> 8 != 2, ""); + assert( ge.binding < impl_params.size() ); + if( !impl_params[ge.binding] ) { + return placeholders[ge.binding]; + } + return *impl_params[ge.binding]; + }; + + // Bounds + for(const auto& bound : impl.m_params.m_bounds) { + TU_MATCH_DEF(::HIR::GenericBound, (bound), (e), + ( + ), + (TraitBound, + DEBUG("TODO: Trait bound " << e.type << " : " << e.trait); + auto b_ty_mono = monomorphise_type_with(sp, e.type, cb_mono); + DEBUG("- b_ty_mono = " << b_ty_mono); + ) + ) + } + + return found_cb(impl_params, impl); + }); +} + diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp new file mode 100644 index 00000000..851e092d --- /dev/null +++ b/src/hir_typeck/static.hpp @@ -0,0 +1,23 @@ + +#include <hir/hir.hpp> + +class StaticTraitResolve +{ + const ::HIR::Crate& m_crate; +public: + StaticTraitResolve(const ::HIR::Crate& crate): + m_crate(crate) + {} + + typedef ::std::function<bool(const ::std::vector<const ::HIR::TypeRef*>& , const ::HIR::TraitImpl&)> t_cb_find_impl; + + bool find_impl( + const Span& sp, + const ::HIR::Crate& crate, 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; +}; + diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 6097839d..2b84d0e4 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -20,8 +20,8 @@ #include <typeinfo> #include <algorithm> // std::count -//const bool DEBUG_PRINT_TOKENS = false; -const bool DEBUG_PRINT_TOKENS = true; +const bool DEBUG_PRINT_TOKENS = false; +//const bool DEBUG_PRINT_TOKENS = true; Lexer::Lexer(const ::std::string& filename): m_path(filename.c_str()), |