summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-07-21 23:10:00 +0800
committerJohn Hodge <tpg@mutabah.net>2016-07-21 23:10:00 +0800
commit717e518629c7e4b7a4c5db4a1b4a520bc217e5ee (patch)
treebf5bb70f920c230ef9e61947d5f31bf63e6cb8dd /src
parent3fab1f6071718b5456d4c6b33fa5afe8f9a43f71 (diff)
downloadmrust-717e518629c7e4b7a4c5db4a1b4a520bc217e5ee.tar.gz
HIR Typecheck - BROKEN: Switch to ImplRef everywhere
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_context.cpp14
-rw-r--r--src/hir_typeck/expr_cs.cpp46
-rw-r--r--src/hir_typeck/expr_simple.cpp44
-rw-r--r--src/hir_typeck/expr_simple.hpp13
-rw-r--r--src/hir_typeck/helpers.cpp56
-rw-r--r--src/hir_typeck/helpers.hpp8
-rw-r--r--src/hir_typeck/impl_ref.hpp57
-rw-r--r--src/hir_typeck/outer.cpp2
-rw-r--r--src/hir_typeck/static.cpp109
-rw-r--r--src/hir_typeck/static.hpp67
10 files changed, 249 insertions, 167 deletions
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 07dddc45..05faf069 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -915,9 +915,10 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
// Allow cases where `right`: ::core::marker::Unsize<`left`>
::HIR::PathParams pp;
pp.m_types.push_back( left_inner_res.clone() );
- bool succ = this->find_trait_impls(sp, this->m_crate.get_lang_item_path(sp, "unsize"), pp, right_inner_res, [&](const auto& args, const auto& ) {
- DEBUG("- Found unsizing with args " << args);
- return args.m_types[0] == left_inner_res;
+ bool succ = this->find_trait_impls(sp, this->m_crate.get_lang_item_path(sp, "unsize"), pp, right_inner_res, [&](auto impl, auto match) {
+ DEBUG("- Found unsizing " << impl);
+ //return args.m_types[0] == left_inner_res;
+ return match == ::HIR::Compare::Equal;//args.m_types[0] == left_inner_res;
});
if( succ ) {
auto span = node_ptr->span();
@@ -975,11 +976,8 @@ void typeck::TypecheckContext::apply_equality(const Span& sp, const ::HIR::TypeR
// 1. Search for an implementation of the data trait for this type
auto r = this->expand_associated_types(sp, right_inner_res.clone());
//bool succ = this->find_trait_impls(sp, e.m_trait.m_path.m_path, e.m_trait.m_path.m_params, right_inner_res, [&](const auto& args,const auto& types) {
- bool succ = this->find_trait_impls(sp, e.m_trait.m_path.m_path, e.m_trait.m_path.m_params, r, [&](const auto& args,const auto& types) {
- if( args.m_types.size() > 0 )
- TODO(sp, "Handle unsizing to traits with params");
- // TODO: Check `types`
- return true;
+ bool succ = this->find_trait_impls(sp, e.m_trait.m_path.m_path, e.m_trait.m_path.m_params, r, [&](auto impl, auto match) {
+ return match == ::HIR::Compare::Equal;
});
if(!succ) {
// XXX: Debugging - Resolves to the correct type in a failing case
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 86304b4a..c420b388 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1446,20 +1446,13 @@ namespace {
::HIR::TypeRef possible_index_type;
::HIR::TypeRef possible_res_type;
unsigned int count = 0;
- bool rv = this->context.m_resolve.find_trait_impls(node.span(), lang_Index, trait_pp, ty, [&](const auto& ty, const auto& args, const auto& assoc) {
- assert( args.m_types.size() == 1 );
- const auto& impl_index = args.m_types[0];
-
- auto cmp = impl_index.compare_with_placeholders(node.span(), trait_pp.m_types[0], this->context.m_ivars.callback_resolve_infer());
- if( cmp == ::HIR::Compare::Unequal) {
- return false;
- }
- possible_res_type = assoc.at("Output").clone();
+ bool rv = this->context.m_resolve.find_trait_impls(node.span(), lang_Index, trait_pp, ty, [&](auto impl, auto cmp) {
+ possible_res_type = impl.get_type("Output");
count += 1;
if( cmp == ::HIR::Compare::Equal ) {
return true;
}
- possible_index_type = impl_index.clone();
+ possible_index_type = impl.get_trait_ty_param(0);
return false;
});
if( rv ) {
@@ -1557,11 +1550,11 @@ namespace {
}
trait_pp.m_types.push_back( ::HIR::TypeRef( mv$(arg_types) ) );
}
- auto was_bounded = this->context.m_resolve.find_trait_impls_bound(node.span(), lang_FnOnce, trait_pp, ty, [&](const auto& , const auto& args, const auto& assoc) {
- const auto& tup = args.m_types[0];
+ auto was_bounded = this->context.m_resolve.find_trait_impls_bound(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto cmp) {
+ auto tup = impl.get_trait_ty_param(0);
if( !tup.m_data.is_Tuple() )
ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup);
- fcn_args_tup = tup.clone();
+ fcn_args_tup = mv$(tup);
return true;
});
if( was_bounded )
@@ -3016,26 +3009,14 @@ namespace {
unsigned int count = 0;
DEBUG("Searching for impl " << v.trait << v.params << " for " << context.m_ivars.fmt_type(v.impl_ty));
bool found = context.m_resolve.find_trait_impls(sp, v.trait, v.params, v.impl_ty,
- [&](const auto& impl_ty, const auto& args, const auto& assoc) {
- assert( args.m_types.size() == v.params.m_types.size() );
- ::HIR::Compare cmp = impl_ty.compare_with_placeholders(sp, v.impl_ty, context.m_ivars.callback_resolve_infer());
- for( unsigned int i = 0; i < args.m_types.size(); i ++ )
- {
- const auto& impl_ty = args.m_types[i];
- const auto& rule_ty = v.params.m_types[i];
- cmp &= impl_ty.compare_with_placeholders(sp, rule_ty, context.m_ivars.callback_resolve_infer());
- }
- if( cmp == ::HIR::Compare::Unequal ) {
- DEBUG("- (fail) bounded impl " << v.trait << v.params << " (ty_right = " << context.m_ivars.fmt_type(v.impl_ty));
- return false;
- }
- ::HIR::TypeRef out_ty_o;
- if( v.name != "" && assoc.count(v.name) == 0 ) {
+ [&](auto impl, auto cmp) {
+ ::HIR::TypeRef out_ty_o = impl.get_type(v.name.c_str());
+ if( v.name != "" && out_ty_o == ::HIR::TypeRef() ) {
auto ty1 = ::HIR::TypeRef( ::HIR::Path(::HIR::Path( v.impl_ty.clone(), ::HIR::GenericPath(v.trait, v.params.clone()), v.name, ::HIR::PathParams() )) );
out_ty_o = context.m_resolve.expand_associated_types(sp, mv$(ty1));
//BUG(sp, "Getting associated type '" << v.name << "' which isn't in " << v.trait << " (" << ty << ")");
}
- const auto& out_ty = (v.name == "" ? v.left_ty : (out_ty_o == ::HIR::TypeRef() ? assoc.at(v.name) : out_ty_o));
+ const auto& out_ty = (v.name == "" ? v.left_ty : out_ty_o);
// - If we're looking for an associated type, allow it to eliminate impossible impls
// > This makes `let v: usize = !0;` work without special cases
@@ -3054,11 +3035,11 @@ namespace {
}
else {
if( possible_impl_ty == ::HIR::TypeRef() ) {
- possible_impl_ty = impl_ty.clone();
- possible_params = args.clone();
+ possible_impl_ty = impl.get_impl_type();
+ possible_params = impl.get_trait_params();
}
- DEBUG("- (possible) " << v.trait << args << " for " << impl_ty);
+ DEBUG("- (possible) " << impl);
return false;
}
@@ -3265,6 +3246,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:
// - Keep a list in the ivar of what types that ivar could be equated to.
DEBUG("--- Coercion checking");
for(auto it = context.link_coerce.begin(); it != context.link_coerce.end(); ) {
+ it->left_ty = context.m_resolve.expand_associated_types( (*it->right_node_ptr)->span(), mv$(it->left_ty) );
if( check_coerce(context, *it) ) {
DEBUG("- Consumed coercion " << it->left_ty << " := " << (**it->right_node_ptr).m_res_type);
it = context.link_coerce.erase(it);
diff --git a/src/hir_typeck/expr_simple.cpp b/src/hir_typeck/expr_simple.cpp
index 5eb8e668..5b6c40b9 100644
--- a/src/hir_typeck/expr_simple.cpp
+++ b/src/hir_typeck/expr_simple.cpp
@@ -460,9 +460,9 @@ namespace typeck {
::HIR::TypeRef possible_right_type;
unsigned int count = 0;
- bool rv = this->context.find_trait_impls(node.span(), trait_path,trait_path_pp, ty_left, [&](const auto& args, const auto& a_types) {
- assert( args.m_types.size() == 1 );
- const auto& impl_right = args.m_types[0];
+ bool rv = this->context.find_trait_impls(node.span(), trait_path,trait_path_pp, ty_left, [&](auto impl, auto ) {
+ auto impl_right = impl.get_trait_ty_param(0);
+ assert(impl_right != ::HIR::TypeRef());
// NOTE: `find_trait_impls` has already done this (and did it better)! Need to get that info off it
auto cmp = impl_right.compare_with_placeholders(node.span(), ty_right, this->context.callback_resolve_infer());
@@ -473,7 +473,7 @@ namespace typeck {
return true;
}
- possible_right_type = impl_right.clone();
+ possible_right_type = mv$(impl_right);
return false;
});
@@ -726,9 +726,10 @@ namespace typeck {
ops_trait_pp.m_types.push_back( ty_right.clone() );
DEBUG("Searching for impl " << ops_trait << "< " << ty_right << "> for " << ty_left);
bool found_bound = this->context.find_trait_impls_bound(sp, ops_trait, ops_trait_pp, ty_left,
- [&](const auto& args, const auto& assoc) {
- assert(args.m_types.size() == 1);
- const auto& arg_type = args.m_types[0];
+ [&](auto impl, auto impl_cmp) {
+ auto arg_type = impl.get_trait_ty_param(0);
+ assert(arg_type != ::HIR::TypeRef());
+
// TODO: if arg_type mentions Self?
auto cmp = arg_type.compare_with_placeholders(node.span(), ty_right, this->context.callback_resolve_infer());
if( cmp == ::HIR::Compare::Unequal ) {
@@ -999,9 +1000,9 @@ namespace typeck {
::HIR::TypeRef possible_index_type;
unsigned int count = 0;
- bool rv = this->context.find_trait_impls(node.span(), path_Index,trait_pp, ty, [&](const auto& args, const auto& assoc) {
- assert( args.m_types.size() == 1 );
- const auto& impl_index = args.m_types[0];
+ bool rv = this->context.find_trait_impls(node.span(), path_Index,trait_pp, ty, [&](auto impl, auto ) {
+ auto impl_index = impl.get_trait_ty_param(0);
+ assert(impl_index != ::HIR::TypeRef());
auto cmp = impl_index.compare_with_placeholders(node.span(), trait_pp.m_types[0], this->context.callback_resolve_infer());
if( cmp == ::HIR::Compare::Unequal)
@@ -1078,12 +1079,12 @@ namespace typeck {
// TODO: Search for Deref impl
::HIR::TypeRef res;
const auto& op_deref = this->context.m_crate.get_lang_item_path(node.span(), "deref");
- bool rv = this->context.find_trait_impls(node.span(), op_deref, ::HIR::PathParams{}, ty, [&](const auto& _args, const auto& types) {
+ bool rv = this->context.find_trait_impls(node.span(), op_deref, ::HIR::PathParams{}, ty, [&](auto impl, auto ) {
if( res != ::HIR::TypeRef() )
TODO(node.span(), "Handle multiple implementations of Deref");
- if( types.find("Target") == types.end() )
+ res = impl.get_type("Target");
+ if( res == ::HIR::TypeRef() )
BUG(node.span(), "Impl of Deref didn't include `Target` associated type (TODO: Is this a bug, what about bounds?)");
- res = types.at("Target").clone();
return true;
});
if( rv ) {
@@ -1405,13 +1406,15 @@ namespace typeck {
auto real_trait = monomorphise_genericpath_with(sp, be.trait.m_path, cache.m_monomorph_cb, false);
DEBUG("Bound " << be.type << ": " << be.trait);
DEBUG("= (" << real_type << ": " << real_trait << ")");
- auto monomorph_bound = [&](const auto& gt)->const auto& {
- return gt;
- };
+ //auto monomorph_bound = [&](const auto& gt)->const auto& {
+ // return gt;
+ // };
const auto& trait_params = be.trait.m_path.m_params;
// TODO: Detect marker traits
const auto& trait_gp = be.trait.m_path;
- auto rv = this->context.find_trait_impls(sp, trait_gp.m_path, real_trait.m_params, real_type, [&](const auto& pp, const auto& at) {
+ auto rv = this->context.find_trait_impls(sp, trait_gp.m_path, real_trait.m_params, real_type, [&](auto impl, auto ) {
+ TODO(sp, impl << " cmp with " << trait_params);
+ #if 0
if( pp.m_types.size() != trait_params.m_types.size() ) {
BUG(sp, "Parameter mismatch");
}
@@ -1423,6 +1426,7 @@ namespace typeck {
//this->context.apply_equality(sp, pp.m_types[i], monomorph_bound, trait_params.m_types[i], cache.m_monomorph_cb, nullptr);
this->context.apply_equality(sp, pp.m_types[i], monomorph_bound, real_trait.m_params.m_types[i], IDENT_CR, nullptr);
}
+ #endif
// TODO: Use `at`
// - Check if the associated type bounds are present
#if 0
@@ -1504,11 +1508,11 @@ namespace typeck {
const auto& lang_FnOnce = this->context.m_crate.get_lang_item_path(node.span(), "fn_once");
::HIR::PathParams trait_pp;
trait_pp.m_types.push_back( this->context.new_ivar_tr() ); // TODO: Bind to arguments?
- auto was_bounded = this->context.find_trait_impls_bound(node.span(), lang_FnOnce, trait_pp, ty, [&](const auto& args, const auto& assoc) {
- const auto& tup = args.m_types[0];
+ auto was_bounded = this->context.find_trait_impls_bound(node.span(), lang_FnOnce, trait_pp, ty, [&](auto impl, auto ) {
+ auto tup = impl.get_trait_ty_param(0);
if( !tup.m_data.is_Tuple() )
ERROR(node.span(), E0000, "FnOnce expects a tuple argument, got " << tup);
- fcn_args_tup = tup.clone();
+ fcn_args_tup = mv$(tup);
return true;
});
if( was_bounded )
diff --git a/src/hir_typeck/expr_simple.hpp b/src/hir_typeck/expr_simple.hpp
index 18cf966a..957fbc67 100644
--- a/src/hir_typeck/expr_simple.hpp
+++ b/src/hir_typeck/expr_simple.hpp
@@ -122,19 +122,20 @@ public:
}
typedef ::std::function<bool(const ::HIR::PathParams&, const ::std::map< ::std::string,::HIR::TypeRef>&)> t_cb_trait_impl;
+ typedef TraitResolution::t_cb_trait_impl_r t_cb_trait_impl_r;
/// Searches for a trait impl that matches the provided trait name and type
- bool find_trait_impls(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const {
- return m_resolve.find_trait_impls(sp, trait, params, type, [&](const auto& _, const auto& a, const auto& b){ return callback(a,b); });
+ bool find_trait_impls(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl_r callback) const {
+ return m_resolve.find_trait_impls(sp, trait, params, type, [&](auto a, auto b){ return callback( mv$(a), b ); });
}
/// Search for a trait implementation in current bounds
- bool find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const {
- return m_resolve.find_trait_impls_bound(sp, trait, params, type, [&](const auto& _, const auto& a, const auto& b){ return callback(a,b); });
+ bool find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl_r callback) const {
+ return m_resolve.find_trait_impls_bound(sp, trait, params, type, callback);
}
/// Search for a trait implementation in the crate
- bool find_trait_impls_crate(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const {
- return m_resolve.find_trait_impls_crate(sp, trait, params, type, [&](const auto& _, const auto& a, const auto& b){ return callback(a,b); });
+ bool find_trait_impls_crate(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, TraitResolution::t_cb_trait_impl_r callback) const {
+ return m_resolve.find_trait_impls_crate(sp, trait, params, type, [&](auto r, auto m){ return callback( mv$(r), m ); });
}
/// Locate the named method by applying auto-dereferencing.
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 516bd40d..748559b3 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1030,9 +1030,12 @@ bool TraitResolution::iterate_bounds( ::std::function<bool(const ::HIR::GenericB
bool TraitResolution::find_trait_impls(const Span& sp,
const ::HIR::SimplePath& trait, const ::HIR::PathParams& params,
const ::HIR::TypeRef& ty,
- t_cb_trait_impl callback
+ t_cb_trait_impl_r callback
) const
{
+ static ::HIR::PathParams null_params;
+ static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc;
+
const auto& type = this->m_ivars.get_type(ty);
TRACE_FUNCTION_F("trait = " << trait << ", type = " << type);
@@ -1055,7 +1058,7 @@ bool TraitResolution::find_trait_impls(const Span& sp,
return false;
)
)
- return callback( type, ::HIR::PathParams(), {} );
+ return callback( ImplRef(&type, &null_params, &null_assoc), ::HIR::Compare::Equal );
}
if( trait == this->m_crate.get_lang_item_path(sp, "copy") ) {
@@ -1085,7 +1088,7 @@ bool TraitResolution::find_trait_impls(const Span& sp,
}
};
if( H::is_copy(sp, *this, type) ) {
- return callback( type, ::HIR::PathParams(), {} );
+ return callback( ImplRef(&type, &null_params, &null_assoc), ::HIR::Compare::Equal );
}
else {
return false;
@@ -1120,7 +1123,7 @@ bool TraitResolution::find_trait_impls(const Span& sp,
pp.m_types.push_back( ::HIR::TypeRef(mv$(args)) );
::std::map< ::std::string, ::HIR::TypeRef> types;
types.insert( ::std::make_pair( "Output", e.m_rettype->clone() ) );
- return callback( type, pp, types );
+ return callback( ImplRef(type.clone(), mv$(pp), mv$(types)), ::HIR::Compare::Equal );
}
else {
return false;
@@ -1151,7 +1154,7 @@ bool TraitResolution::find_trait_impls(const Span& sp,
pp.m_types.push_back( ::HIR::TypeRef(mv$(args)) );
::std::map< ::std::string, ::HIR::TypeRef> types;
types.insert( ::std::make_pair( "Output", e.m_rettype->clone() ) );
- return callback( type, pp, types );
+ return callback( ImplRef(type.clone(), mv$(pp), mv$(types)), ::HIR::Compare::Equal );
}
// Continue
)
@@ -1347,6 +1350,8 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const
}
)
+ //this->find_impl()
+
// 1. Bounds
bool rv;
bool assume_opaque = true;
@@ -1489,14 +1494,14 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const
BUG(sp, "Cannot find associated type " << pe.item << " anywhere in trait " << pe.trait);
//pe.trait = mv$(trait_path);
- rv = this->find_trait_impls_crate(sp, trait_path.m_path, trait_path.m_params, *pe.type, [&](const auto& , const auto& args, const auto& assoc) {
- DEBUG("Found impl for " << pe.trait.m_path << args << " with types {" << assoc << "}");
- auto it = assoc.find( pe.item );
- if( it == assoc.end() )
+ rv = this->find_trait_impls_crate(sp, trait_path.m_path, trait_path.m_params, *pe.type, [&](auto impl, auto qual) {
+ DEBUG("Found " << impl);
+ auto ty = impl.get_type( pe.item.c_str() );
+ if( ty == ::HIR::TypeRef() )
ERROR(sp, E0000, "Couldn't find assocated type " << pe.item << " in " << pe.trait);
- DEBUG("Converted UfcsKnown - " << e.path << " = " << it->second);
- input = it->second.clone();
+ DEBUG("Converted UfcsKnown - " << e.path << " = " << ty);
+ input = mv$(ty);
return true;
});
if( rv ) {
@@ -1595,7 +1600,7 @@ bool TraitResolution::find_named_trait_in_trait(const Span& sp,
}
return false;
}
-bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const
+bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl_r callback) const
{
struct H {
static ::HIR::Compare compare_pp(const Span& sp, const TraitResolution& self, const ::HIR::PathParams& left, const ::HIR::PathParams& right) {
@@ -1636,7 +1641,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple
}
// Hand off to the closure, and return true if it does
// TODO: The type bounds are only the types that are specified.
- if( callback(e.type, e.trait.m_path.m_params, e.trait.m_type_bounds) ) {
+ if( callback( ImplRef(&e.type, &e.trait.m_path.m_params, &e.trait.m_type_bounds), ord) ) {
return true;
}
}
@@ -1658,7 +1663,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple
assoc2.insert( ::std::make_pair(i.first, i.second.clone()) );
//}
}
- return callback(ty, params, assoc2);
+ return callback( ImplRef(ty.clone(), params.clone(), mv$(assoc2)), ::HIR::Compare::Equal );
});
if( rv ) {
return true;
@@ -1703,7 +1708,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple
}
DEBUG("- tp_mono = " << tp_mono);
// TODO: Instead of using `type` here, build the real type
- if( callback(type, tp_mono.m_path.m_params, tp_mono.m_type_bounds) ) {
+ if( callback( ImplRef(type.clone(), mv$(tp_mono.m_path.m_params), mv$(tp_mono.m_type_bounds)), ord ) ) {
return true;
}
}
@@ -1718,7 +1723,7 @@ bool TraitResolution::find_trait_impls_bound(const Span& sp, const ::HIR::Simple
bool TraitResolution::find_trait_impls_crate(const Span& sp,
const ::HIR::SimplePath& trait, const ::HIR::PathParams& params,
const ::HIR::TypeRef& type,
- t_cb_trait_impl callback
+ t_cb_trait_impl_r callback
) const
{
// TODO: Parameter defaults - apply here or in the caller?
@@ -1834,14 +1839,13 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
}
const auto& real_trait_path = real_trait.m_path;
DEBUG("- " << real_type << " : " << real_trait_path);
- auto rv = this->find_trait_impls(sp, real_trait_path.m_path, real_trait_path.m_params, real_type, [&](const auto&, const auto& a, const auto& t) {
+ auto rv = this->find_trait_impls(sp, real_trait_path.m_path, real_trait_path.m_params, real_type, [&](auto impl, auto impl_cmp) {
for(const auto& assoc_bound : real_trait.m_type_bounds) {
::HIR::TypeRef tmp;
const ::HIR::TypeRef* ty_p;
- auto it = t.find(assoc_bound.first);
- if( it == t.end() )
- {
+ tmp = impl.get_type(assoc_bound.first.c_str());
+ if( tmp == ::HIR::TypeRef() ) {
// This bound isn't from this particular trait, go the slow way of using expand_associated_types
tmp = this->expand_associated_types(sp, ::HIR::TypeRef(
::HIR::Path(::HIR::Path::Data::Data_UfcsKnown { box$(real_type.clone()), real_trait_path.clone(), assoc_bound.first, {} }))
@@ -1849,7 +1853,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
ty_p = &tmp;
}
else {
- ty_p = &this->m_ivars.get_type(it->second);
+ ty_p = &tmp;
}
const auto& ty = *ty_p;
DEBUG(" - Compare " << ty << " and " << assoc_bound.second << ", matching generics");
@@ -1892,7 +1896,8 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
//if( match == ::HIR::Compare::Fuzzy ) {
// TODO(sp, "- Pass on fuzzy match status");
//}
- return callback(ty_mono, args_mono, types/*, (match == ::HIR::Compare::Fuzzy)*/);
+ return callback(ImplRef(mv$(impl_params), impl), match);
+ //return callback(ty_mono, args_mono, types/*, (match == ::HIR::Compare::Fuzzy)*/);
}
);
}
@@ -1969,9 +1974,8 @@ const ::HIR::TypeRef* TraitResolution::autoderef(const Span& sp, const ::HIR::Ty
return &tmp_type;
)
else {
- bool succ = this->find_trait_impls(sp, this->m_crate.get_lang_item_path(sp, "deref"), ::HIR::PathParams {}, ty, [&](const auto&, const auto& args, const auto& types) {
- assert(args.m_types.size() == 0);
- tmp_type = types.at("Target").clone();
+ bool succ = this->find_trait_impls(sp, this->m_crate.get_lang_item_path(sp, "deref"), ::HIR::PathParams {}, ty, [&](auto impls, auto match) {
+ tmp_type = impls.get_type("Target");
return true;
});
if( succ ) {
@@ -2162,7 +2166,7 @@ bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& trait
//}
// TODO: Need a "don't care" marker for the PathParams
- if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](const auto&,const auto&,const auto&) { return true; }) ) {
+ if( find_trait_impls_crate(sp, *trait_ref.first, ::HIR::PathParams{}, ty, [](auto , auto ) { return true; }) ) {
DEBUG("Found trait impl " << *trait_ref.first << " (" /*<< m_ivars.fmt_type(*trait_ref.first)*/ << ") for " << ty << " ("<<m_ivars.fmt_type(ty)<<")");
fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({
box$( ty.clone() ),
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index 2e55978e..d6b4e149 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -5,6 +5,7 @@
#include <hir/type.hpp>
#include <hir/hir.hpp>
#include <hir/expr.hpp>
+#include "impl_ref.hpp"
// TODO/NOTE - This is identical to ::HIR::t_cb_resolve_type
typedef ::std::function<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> t_cb_generic;
@@ -179,9 +180,10 @@ public:
bool iterate_bounds( ::std::function<bool(const ::HIR::GenericBound&)> cb) const;
typedef ::std::function<bool(const ::HIR::TypeRef&, const ::HIR::PathParams&, const ::std::map< ::std::string,::HIR::TypeRef>&)> t_cb_trait_impl;
+ typedef ::std::function<bool(ImplRef, ::HIR::Compare)> t_cb_trait_impl_r;
/// Searches for a trait impl that matches the provided trait name and type
- bool find_trait_impls(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const;
+ bool find_trait_impls(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl_r callback) const;
/// Locate a named trait in the provied trait (either itself or as a parent trait)
bool find_named_trait_in_trait(const Span& sp,
@@ -191,9 +193,9 @@ public:
t_cb_trait_impl callback
) const;
/// Search for a trait implementation in current bounds
- bool find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const;
+ bool find_trait_impls_bound(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl_r callback) const;
/// Search for a trait implementation in the crate
- bool find_trait_impls_crate(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl callback) const;
+ bool find_trait_impls_crate(const Span& sp, const ::HIR::SimplePath& trait, const ::HIR::PathParams& params, const ::HIR::TypeRef& type, t_cb_trait_impl_r callback) const;
/// Locate the named method by applying auto-dereferencing.
/// \return Number of times deref was applied (or ~0 if _ was hit)
diff --git a/src/hir_typeck/impl_ref.hpp b/src/hir_typeck/impl_ref.hpp
new file mode 100644
index 00000000..e2ec171e
--- /dev/null
+++ b/src/hir_typeck/impl_ref.hpp
@@ -0,0 +1,57 @@
+/*
+ */
+#pragma once
+
+#include <hir/type.hpp>
+
+struct ImplRef
+{
+ TAGGED_UNION(Data, TraitImpl,
+ (TraitImpl, struct {
+ ::std::vector<const ::HIR::TypeRef*> params;
+ const ::HIR::TraitImpl* impl;
+ }),
+ (BoundedPtr, struct {
+ const ::HIR::TypeRef* type;
+ const ::HIR::PathParams* trait_args;
+ const ::std::map< ::std::string, ::HIR::TypeRef>* assoc;
+ }),
+ (Bounded, struct {
+ ::HIR::TypeRef type;
+ ::HIR::PathParams trait_args;
+ ::std::map< ::std::string, ::HIR::TypeRef> assoc;
+ })
+ );
+
+ Data m_data;
+
+ ImplRef():
+ m_data(Data::make_TraitImpl({ {}, nullptr }))
+ {}
+ ImplRef(::std::vector<const ::HIR::TypeRef*> params, const ::HIR::TraitImpl& impl):
+ m_data(Data::make_TraitImpl({ mv$(params), &impl }))
+
+ {}
+ ImplRef(const ::HIR::TypeRef* type, const ::HIR::PathParams* args, const ::std::map< ::std::string, ::HIR::TypeRef>* assoc):
+ m_data(Data::make_BoundedPtr({ type, mv$(args), mv$(assoc) }))
+ {}
+ ImplRef(::HIR::TypeRef type, ::HIR::PathParams args, ::std::map< ::std::string, ::HIR::TypeRef> assoc):
+ m_data(Data::make_Bounded({ mv$(type), mv$(args), mv$(assoc) }))
+ {}
+
+ bool is_valid() const {
+ return !(m_data.is_TraitImpl() && m_data.as_TraitImpl().impl == nullptr);
+ }
+
+ bool more_specific_than(const ImplRef& other) const;
+
+ ::HIR::TypeRef get_impl_type() const;
+ ::HIR::PathParams get_trait_params() const;
+
+ ::HIR::TypeRef get_trait_ty_param(unsigned int) const;
+
+ bool type_is_specializable(const char* name) const;
+ ::HIR::TypeRef get_type(const char* name) const;
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const ImplRef& x);
+};
diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp
index 2baa6ec5..cb27ffe5 100644
--- a/src/hir_typeck/outer.cpp
+++ b/src/hir_typeck/outer.cpp
@@ -251,7 +251,7 @@ namespace {
e.binding = ::HIR::TypeRef::TypePathBinding::make_Opaque({});
}
else {
- StaticTraitResolve::ImplRef best_impl;
+ ImplRef best_impl;
m_resolve.find_impl(sp, pe.trait.m_path, pe.trait.m_params, *pe.type, [&](auto impl) {
DEBUG("[visit_type] Found " << impl);
if( best_impl.more_specific_than(impl) )
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index 1ee20dfd..df344c79 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -547,7 +547,7 @@ bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::Generi
return false;
}
-bool StaticTraitResolve::ImplRef::more_specific_than(const ImplRef& other) const
+bool ImplRef::more_specific_than(const ImplRef& other) const
{
TU_MATCH(Data, (this->m_data), (e),
(TraitImpl,
@@ -565,7 +565,7 @@ bool StaticTraitResolve::ImplRef::more_specific_than(const ImplRef& other) const
)
throw "";
}
-bool StaticTraitResolve::ImplRef::type_is_specializable(const char* name) const
+bool ImplRef::type_is_specializable(const char* name) const
{
TU_MATCH(Data, (this->m_data), (e),
(TraitImpl,
@@ -585,8 +585,83 @@ bool StaticTraitResolve::ImplRef::type_is_specializable(const char* name) const
)
throw "";
}
-::HIR::TypeRef StaticTraitResolve::ImplRef::get_type(const char* name) const
+::HIR::TypeRef ImplRef::get_impl_type() const
{
+ Span sp;
+ TU_MATCH(Data, (this->m_data), (e),
+ (TraitImpl,
+ if( e.impl == nullptr ) {
+ BUG(Span(), "nullptr");
+ }
+ return monomorphise_type_with(sp, e.impl->m_type, [&e](const auto& t)->const auto& {
+ const auto& ge = t.m_data.as_Generic();
+ return *e.params.at(ge.binding);
+ });
+ ),
+ (BoundedPtr,
+ return e.type->clone();
+ ),
+ (Bounded,
+ return e.type.clone();
+ )
+ )
+ throw "";
+}
+::HIR::PathParams ImplRef::get_trait_params() const
+{
+ Span sp;
+ TU_MATCH(Data, (this->m_data), (e),
+ (TraitImpl,
+ if( e.impl == nullptr ) {
+ BUG(Span(), "nullptr");
+ }
+ return monomorphise_path_params_with(sp, e.impl->m_trait_args, [&e](const auto& t)->const auto& {
+ const auto& ge = t.m_data.as_Generic();
+ return *e.params.at(ge.binding);
+ }, true);
+ ),
+ (BoundedPtr,
+ return e.trait_args->clone();
+ ),
+ (Bounded,
+ return e.trait_args.clone();
+ )
+ )
+ throw "";
+}
+::HIR::TypeRef ImplRef::get_trait_ty_param(unsigned int idx) const
+{
+ Span sp;
+ TU_MATCH(Data, (this->m_data), (e),
+ (TraitImpl,
+ if( e.impl == nullptr ) {
+ BUG(Span(), "nullptr");
+ }
+ if( idx >= e.impl->m_trait_args.m_types.size() )
+ return ::HIR::TypeRef();
+ return monomorphise_type_with(sp, e.impl->m_trait_args.m_types[idx], [&e](const auto& t)->const auto& {
+ const auto& ge = t.m_data.as_Generic();
+ return *e.params.at(ge.binding);
+ }, true);
+ ),
+ (BoundedPtr,
+ if( idx >= e.trait_args->m_types.size() )
+ return ::HIR::TypeRef();
+ return e.trait_args->m_types.at(idx).clone();
+ ),
+ (Bounded,
+ if( idx >= e.trait_args.m_types.size() )
+ return ::HIR::TypeRef();
+ return e.trait_args.m_types.at(idx).clone();
+ )
+ )
+ throw "";
+ TODO(Span(), "");
+}
+::HIR::TypeRef ImplRef::get_type(const char* name) const
+{
+ if( !name[0] )
+ return ::HIR::TypeRef();
static Span sp;
TU_MATCH(Data, (this->m_data), (e),
(TraitImpl,
@@ -609,11 +684,35 @@ bool StaticTraitResolve::ImplRef::type_is_specializable(const char* name) const
}
),
(BoundedPtr,
- TODO(Span(), *this);
+ TODO(Span(), name << " - " << *this);
),
(Bounded,
- TODO(Span(), *this);
+ auto it = e.assoc.find(name);
+ if(it == e.assoc.end())
+ return ::HIR::TypeRef();
+ return it->second.clone();
)
)
return ::HIR::TypeRef();
}
+
+::std::ostream& operator<<(::std::ostream& os, const ImplRef& x)
+{
+ TU_MATCH(ImplRef::Data, (x.m_data), (e),
+ (TraitImpl,
+ if( e.impl == nullptr ) {
+ os << "none";
+ }
+ else {
+ os << "impl" << e.impl->m_params.fmt_args() << " ?" << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds();
+ }
+ ),
+ (BoundedPtr,
+ os << "bound (ptr) " << *e.type << " : ?" << *e.trait_args << " + {" << *e.assoc << "}";
+ ),
+ (Bounded,
+ os << "bound " << e.type << " : ?" << e.trait_args << " + {"<<e.assoc<<"}";
+ )
+ )
+ return os;
+}
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index 8c9989f6..bb39e164 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -9,6 +9,7 @@
#include <hir/hir.hpp>
#include "helpers.hpp"
+#include "impl_ref.hpp"
class StaticTraitResolve
{
@@ -49,72 +50,6 @@ public:
}
/// \}
-
- struct ImplRef
- {
- TAGGED_UNION(Data, TraitImpl,
- (TraitImpl, struct {
- ::std::vector<const ::HIR::TypeRef*> params;
- const ::HIR::TraitImpl* impl;
- }),
- (BoundedPtr, struct {
- const ::HIR::TypeRef* type;
- const ::HIR::PathParams* trait_args;
- const ::std::map< ::std::string, ::HIR::TypeRef>* assoc;
- }),
- (Bounded, struct {
- ::HIR::TypeRef type;
- ::HIR::PathParams trait_args;
- ::std::map< ::std::string, ::HIR::TypeRef> assoc;
- })
- );
-
- Data m_data;
-
- ImplRef():
- m_data(Data::make_TraitImpl({ {}, nullptr }))
- {}
- ImplRef(::std::vector<const ::HIR::TypeRef*> params, const ::HIR::TraitImpl& impl):
- m_data(Data::make_TraitImpl({ mv$(params), &impl }))
-
- {}
- ImplRef(const ::HIR::TypeRef* type, const ::HIR::PathParams* args, const ::std::map< ::std::string, ::HIR::TypeRef>* assoc):
- m_data(Data::make_BoundedPtr({ type, mv$(args), mv$(assoc) }))
- {}
- ImplRef(::HIR::TypeRef type, ::HIR::PathParams args, ::std::map< ::std::string, ::HIR::TypeRef> assoc):
- m_data(Data::make_Bounded({ mv$(type), mv$(args), mv$(assoc) }))
- {}
-
- bool is_valid() const {
- return !(m_data.is_TraitImpl() && m_data.as_TraitImpl().impl == nullptr);
- }
-
- bool more_specific_than(const ImplRef& other) const;
-
- bool type_is_specializable(const char* name) const;
- ::HIR::TypeRef get_type(const char* name) const;
-
- friend ::std::ostream& operator<<(::std::ostream& os, const ImplRef& x) {
- TU_MATCH(Data, (x.m_data), (e),
- (TraitImpl,
- if( e.impl == nullptr ) {
- os << "none";
- }
- else {
- os << "impl" << e.impl->m_params.fmt_args() << " ?" << e.impl->m_trait_args << " for " << e.impl->m_type << e.impl->m_params.fmt_bounds();
- }
- ),
- (BoundedPtr,
- os << "bound";
- ),
- (Bounded,
- os << "bound";
- )
- )
- return os;
- }
- };
-
/// \brief Lookups
/// \{
typedef ::std::function<bool(ImplRef)> t_cb_find_impl;