summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/hir.cpp24
-rw-r--r--src/hir_typeck/expr.cpp34
-rw-r--r--src/hir_typeck/expr_context.cpp11
3 files changed, 39 insertions, 30 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 742a2edf..818b7b28 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -30,10 +30,12 @@ namespace HIR {
}
namespace {
- bool matches_type_int(const ::HIR::GenericParams& params, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res)
+ bool matches_type_int(const ::HIR::GenericParams& params, const ::HIR::TypeRef& left, const ::HIR::TypeRef& right_in, ::HIR::t_cb_resolve_type ty_res, bool expand_generic)
{
assert(! left.m_data.is_Infer() );
- const auto& right = (right_in.m_data.is_Infer() || right_in.m_data.is_Generic() ? ty_res(right_in) : right_in);
+ const auto& right = (right_in.m_data.is_Infer() || right_in.m_data.is_Generic() == expand_generic ? ty_res(right_in) : right_in);
+ if( right_in.m_data.is_Generic() )
+ expand_generic = false;
//DEBUG("left = " << left << ", right = " << right);
@@ -85,7 +87,7 @@ namespace {
}
for( unsigned int i = 0; i < pre.m_params.m_types.size(); i ++ )
{
- if( ! matches_type_int(params, ple.m_params.m_types[i], pre.m_params.m_types[i], ty_res) )
+ if( ! matches_type_int(params, ple.m_params.m_types[i], pre.m_params.m_types[i], ty_res, expand_generic) )
return false;
}
}
@@ -101,32 +103,32 @@ namespace {
return false;
),
(Array,
- if( ! matches_type_int(params, *le.inner, *re.inner, ty_res) )
+ if( ! matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic) )
return false;
if( le.size_val != re.size_val )
return false;
return true;
),
(Slice,
- return matches_type_int(params, *le.inner, *re.inner, ty_res);
+ return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic);
),
(Tuple,
if( le.size() != re.size() )
return false;
for( unsigned int i = 0; i < le.size(); i ++ )
- if( !matches_type_int(params, le[i], re[i], ty_res) )
+ if( !matches_type_int(params, le[i], re[i], ty_res, expand_generic) )
return false;
return true;
),
(Borrow,
if( le.type != re.type )
return false;
- return matches_type_int(params, *le.inner, *re.inner, ty_res);
+ return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic);
),
(Pointer,
if( le.type != re.type )
return false;
- return matches_type_int(params, *le.inner, *re.inner, ty_res);
+ return matches_type_int(params, *le.inner, *re.inner, ty_res, expand_generic);
),
(Function,
DEBUG("TODO: Compare " << left << " and " << right);
@@ -143,15 +145,15 @@ namespace {
bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const
{
- return matches_type_int(m_params, m_type, type, ty_res);
+ return matches_type_int(m_params, m_type, type, ty_res, true);
}
bool ::HIR::TypeImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const
{
- return matches_type_int(m_params, m_type, type, ty_res);
+ return matches_type_int(m_params, m_type, type, ty_res, true);
}
bool ::HIR::MarkerImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const
{
- return matches_type_int(m_params, m_type, type, ty_res);
+ return matches_type_int(m_params, m_type, type, ty_res, true);
}
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index 667129bc..d677dfea 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -262,14 +262,7 @@ namespace typeck {
::HIR::ExprVisitorDef::visit(node);
if( node.m_nodes.size() > 0 ) {
auto& ln = *node.m_nodes.back();
- // If the child node didn't set a real return type, force it to be the same as this node's
- if( ln.m_res_type.m_data.is_Infer() ) {
- ln.m_res_type = node.m_res_type.clone();
- }
- else {
- // If it was set, equate with possiblity of coercion
- this->context.apply_equality(ln.span(), node.m_res_type, ln.m_res_type, &node.m_nodes.back());
- }
+ this->context.apply_equality(ln.span(), node.m_res_type, ln.m_res_type, &node.m_nodes.back());
}
else {
node.m_res_type = ::HIR::TypeRef::new_unit();
@@ -351,13 +344,7 @@ namespace typeck {
types.push_back( sn->m_res_type.clone() );
auto tup_type = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Tuple(mv$(types)) );
- //if( node.m_res_type.m_data.is_Infer() )
- //{
- // node.m_res_type = mv$(tup_type);
- //}
- //else {
- this->context.apply_equality(node.span(), node.m_res_type, tup_type);
- //}
+ this->context.apply_equality(node.span(), node.m_res_type, tup_type);
}
void visit(::HIR::ExprNode_Closure& node) override
{
@@ -370,9 +357,16 @@ namespace typeck {
ty_data.m_arg_types.push_back( a.second.clone() );
}
this->context.add_ivars(node.m_return);
+
ty_data.m_rettype = box$( node.m_return.clone() );
- node.m_code->m_res_type = node.m_return.clone();
+ if( node.m_code->m_res_type == ::HIR::TypeRef() ) {
+ node.m_code->m_res_type = node.m_return.clone();
+ }
+ else {
+ this->context.add_ivars( node.m_code->m_res_type );
+ this->context.apply_equality( node.span(), node.m_code->m_res_type, node.m_return );
+ }
this->context.apply_equality( node.span(), node.m_res_type, ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Closure(mv$(ty_data)) ) );
@@ -1107,6 +1101,9 @@ namespace typeck {
return ty;
},
[&](const auto& impl) {
+ DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type);
+ for(const auto& v : impl.m_methods)
+ DEBUG(" > " << v.first);
auto it = impl.m_methods.find(e.item);
if( it == impl.m_methods.end() )
return false;
@@ -1444,7 +1441,10 @@ namespace typeck {
void visit(::HIR::ExprNode_Tuple& node) override
{
auto& ty = this->context.get_type(node.m_res_type);
- assert( ty.m_data.is_Tuple() );
+ if( !ty.m_data.is_Tuple() ) {
+ this->context.dump();
+ BUG(node.span(), "Return type of tuple literal wasn't a tuple - " << node.m_res_type << " = " << ty);
+ }
auto& tup_ents = ty.m_data.as_Tuple();
assert( tup_ents.size() == node.m_vals.size() );
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index da8e81b8..d69642c9 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -1154,11 +1154,14 @@ bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait,
//TODO(sp, "Look up 'Self' in expand_associated_types::expand_placeholder (" << *e2.type << ")");
return *e2.type;
}
- else {
+ else if( e.binding < 256 ) {
assert(e.binding < impl_args.size());
assert( impl_args[e.binding] );
return *impl_args[e.binding];
}
+ else {
+ BUG(sp, "Encountered fn-level params? " << ty);
+ }
)
else
return ty;
@@ -1169,6 +1172,7 @@ bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait,
(
),
(TraitBound,
+ DEBUG("- Checking bound - " << be.type << " : " << be.trait.m_path);
if( !this->check_trait_bound(sp, be.type, be.trait.m_path, expand_placeholder) )
{
return false;
@@ -1418,7 +1422,10 @@ unsigned int typeck::TypecheckContext::autoderef_find_method(const Span& sp, con
for(const auto& impl : m_crate.m_type_impls)
{
if( impl.matches_type(ty) ) {
- DEBUG("Mactching impl " << impl.m_type);
+ auto it = impl.m_methods.find( method_name );
+ if( it == impl.m_methods.end() )
+ continue ;
+ DEBUG("Matching `impl" << impl.m_params.fmt_args() << " " << impl.m_type << "` - " << top_ty);
fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsInherent({
box$(ty.clone()),
method_name,