summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_conv/constant_evaluation.cpp3
-rw-r--r--src/hir_conv/resolve_ufcs.cpp6
-rw-r--r--src/hir_typeck/expr_cs.cpp126
-rw-r--r--src/mir/from_hir.cpp23
4 files changed, 103 insertions, 55 deletions
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 0664f425..71e98993 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -560,10 +560,13 @@ namespace {
BUG(node.span(), "Path value with unsupported value type - " << ep.tag_str());
),
(Function,
+ // TODO: Associated functions
// TODO: Should be a more complex path
+ ASSERT_BUG(node.span(), node.m_path.m_data.is_Generic(), "Function path not Path::Generic - " << node.m_path);
m_rv = ::HIR::Literal(node.m_path.m_data.as_Generic().m_path);
),
(Constant,
+ // TODO: Associated constants
const auto& c = *e;
if( c.m_value_res.is_Invalid() ) {
const_cast<HIR::ExprNode&>(*c.m_value).visit(*this);
diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp
index cc136116..5fbeabed 100644
--- a/src/hir_conv/resolve_ufcs.cpp
+++ b/src/hir_conv/resolve_ufcs.cpp
@@ -336,7 +336,11 @@ namespace {
switch( pc )
{
case ::HIR::Visitor::PathContext::VALUE:
- if( impl.m_methods.find(e.item) == impl.m_methods.end() ) {
+ if( impl.m_methods.find(e.item) != impl.m_methods.end() ) {
+ }
+ else if( impl.m_constants.find(e.item) != impl.m_constants.end() ) {
+ }
+ else {
return false;
}
// Found it, just keep going (don't care about details here)
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 0a9b913f..fc590276 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1560,29 +1560,50 @@ namespace {
// - Locate function (and impl block)
const ::HIR::Function* fcn_ptr = nullptr;
+ const ::HIR::Constant* const_ptr = nullptr;
const ::HIR::TypeImpl* impl_ptr = nullptr;
// TODO: Support mutiple matches here (if there's a fuzzy match) and retry if so
unsigned int count = 0;
this->context.m_crate.find_type_impls(*e.type, context.m_ivars.callback_resolve_infer(),
[&](const auto& impl) {
DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type);
- auto it = impl.m_methods.find(e.item);
- if( it == impl.m_methods.end() )
- return false;
- fcn_ptr = &it->second.data;
- impl_ptr = &impl;
- count += 1;
+ {
+ auto it = impl.m_methods.find(e.item);
+ if( it != impl.m_methods.end() ) {
+ fcn_ptr = &it->second.data;
+ impl_ptr = &impl;
+ count += 1;
+ return false;
+ //return true;
+ }
+ }
+ {
+ auto it = impl.m_constants.find(e.item);
+ if( it != impl.m_constants.end() ) {
+ const_ptr = &it->second.data;
+ impl_ptr = &impl;
+ count += 1;
+ return false;
+ }
+ }
return false;
- //return true;
});
- if( !fcn_ptr ) {
- ERROR(sp, E0000, "Failed to locate function " << node.m_path);
+ if( count == 0 ) {
+ ERROR(sp, E0000, "Failed to locate associated value " << node.m_path);
}
if( count > 1 ) {
TODO(sp, "Revisit _PathValue when UfcsInherent has multiple options - " << node.m_path);
}
+
+ assert(fcn_ptr || const_ptr);
assert(impl_ptr);
- fix_param_count(sp, this->context, *e.type, false, node.m_path, fcn_ptr->m_params, e.params);
+
+ if( fcn_ptr ) {
+ fix_param_count(sp, this->context, *e.type, false, node.m_path, fcn_ptr->m_params, e.params);
+ }
+ else {
+ fix_param_count(sp, this->context, *e.type, false, node.m_path, const_ptr->m_params, e.params);
+ }
// If the impl block has parameters, figure out what types they map to
// - The function params are already mapped (from fix_param_count)
@@ -1597,45 +1618,58 @@ namespace {
for(const auto& ty : impl_params.m_types)
assert( !( ty.m_data.is_Infer() && ty.m_data.as_Infer().index == ~0u) );
}
+
- // Create monomorphise callback
- const auto& fcn_params = e.params;
- auto monomorph_cb = [&](const auto& gt)->const auto& {
- const auto& ge = gt.m_data.as_Generic();
- if( ge.binding == 0xFFFF ) {
- return this->context.get_type(*e.type);
- }
- else if( ge.binding < 256 ) {
- auto idx = ge.binding;
- if( idx >= impl_params.m_types.size() ) {
- BUG(sp, "Generic param out of input range - " << idx << " '" << ge.name << "' >= " << impl_params.m_types.size());
+ if( fcn_ptr )
+ {
+ // Create monomorphise callback
+ const auto& fcn_params = e.params;
+ auto monomorph_cb = [&](const auto& gt)->const auto& {
+ const auto& ge = gt.m_data.as_Generic();
+ if( ge.binding == 0xFFFF ) {
+ return this->context.get_type(*e.type);
}
- return this->context.get_type(impl_params.m_types[idx]);
- }
- else if( ge.binding < 512 ) {
- auto idx = ge.binding - 256;
- if( idx >= fcn_params.m_types.size() ) {
- BUG(sp, "Generic param out of input range - " << idx << " '" << ge.name << "' >= " << fcn_params.m_types.size());
+ else if( ge.binding < 256 ) {
+ auto idx = ge.binding;
+ if( idx >= impl_params.m_types.size() ) {
+ BUG(sp, "Generic param out of input range - " << idx << " '" << ge.name << "' >= " << impl_params.m_types.size());
+ }
+ return this->context.get_type(impl_params.m_types[idx]);
}
- return this->context.get_type(fcn_params.m_types[idx]);
- }
- else {
- BUG(sp, "Generic bounding out of total range");
- }
- };
-
- // TODO: Impl/method type bounds
-
- ::HIR::FunctionType ft {
- fcn_ptr->m_unsafe, fcn_ptr->m_abi,
- box$( monomorphise_type_with(sp, fcn_ptr->m_return, monomorph_cb) ),
- {}
- };
- for(const auto& arg : fcn_ptr->m_args)
- ft.m_arg_types.push_back( monomorphise_type_with(sp, arg.second, monomorph_cb) );
- auto ty = ::HIR::TypeRef(mv$(ft));
-
- this->context.equate_types(node.span(), node.m_res_type, ty);
+ else if( ge.binding < 512 ) {
+ auto idx = ge.binding - 256;
+ if( idx >= fcn_params.m_types.size() ) {
+ BUG(sp, "Generic param out of input range - " << idx << " '" << ge.name << "' >= " << fcn_params.m_types.size());
+ }
+ return this->context.get_type(fcn_params.m_types[idx]);
+ }
+ else {
+ BUG(sp, "Generic bounding out of total range");
+ }
+ };
+
+ // TODO: Impl/method type bounds
+
+ ::HIR::FunctionType ft {
+ fcn_ptr->m_unsafe, fcn_ptr->m_abi,
+ box$( monomorphise_type_with(sp, fcn_ptr->m_return, monomorph_cb) ),
+ {}
+ };
+ for(const auto& arg : fcn_ptr->m_args)
+ ft.m_arg_types.push_back( monomorphise_type_with(sp, arg.second, monomorph_cb) );
+ auto ty = ::HIR::TypeRef(mv$(ft));
+
+ this->context.equate_types(node.span(), node.m_res_type, ty);
+ }
+ else // !fcn_ptr, ergo const_ptr
+ {
+ auto monomorph_cb = monomorphise_type_get_cb(sp, &*e.type, &impl_params, &e.params);
+
+ ::HIR::TypeRef tmp;
+ const auto& ty = ( monomorphise_type_needed(const_ptr->m_type) ? tmp = monomorphise_type_with(sp, const_ptr->m_type, monomorph_cb) : const_ptr->m_type );
+
+ this->context.equate_types(node.span(), node.m_res_type, ty);
+ }
)
)
}
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 00b2f507..e5e11404 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -1553,15 +1553,22 @@ namespace {
auto rv = m_builder.crate().find_type_impls(*pe.type, [&](const auto& ty)->const auto& { return ty; },
[&](const auto& impl) {
DEBUG("- impl" << impl.m_params.fmt_args() << " " << impl.m_type);
- auto it = impl.m_methods.find(pe.item);
- if( it != impl.m_methods.end() ) {
- // Function!
- auto tmp = m_builder.new_temporary( node.m_res_type );
- m_builder.push_stmt_assign( sp, tmp.clone(), ::MIR::Constant::make_ItemAddr(node.m_path.clone()) );
- m_builder.set_result( sp, mv$(tmp) );
- return true;
+ // Associated functions
+ {
+ auto it = impl.m_methods.find(pe.item);
+ if( it != impl.m_methods.end() ) {
+ m_builder.set_result( sp, ::MIR::Constant::make_ItemAddr(node.m_path.clone()) );
+ return true;
+ }
+ }
+ // Associated consts
+ {
+ auto it = impl.m_constants.find(pe.item);
+ if( it != impl.m_constants.end() ) {
+ m_builder.set_result( sp, ::MIR::Constant::make_Const({node.m_path.clone()}) );
+ return true;
+ }
}
- // Associated consts (unimpl)
// Associated static (undef)
return false;
});