summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_typeck/expr_cs.cpp58
1 files changed, 57 insertions, 1 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index b252434d..668d2b9d 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1072,7 +1072,63 @@ namespace {
BUG(sp, "Encountered UfcsUnknown");
),
(UfcsKnown,
- TODO(sp, "Look up associated constants/statics (trait)");
+ // 1. Add trait bound to be checked.
+ this->context.equate_types_assoc(sp, ::HIR::TypeRef(), e.trait.m_path, mv$(e.trait.m_params.clone().m_types), e.type->clone(), "");
+ // 2. Locate this item in the trait
+ // - If it's an associated `const`, will have to revisit
+ const auto& trait = this->context.m_crate.get_trait_by_path(sp, e.trait.m_path);
+ auto it = trait.m_values.find( e.item );
+ if( it == trait.m_values.end() || it->second.is_None() ) {
+ ERROR(sp, E0000, "`" << e.item << "` is not a value member of trait " << e.trait.m_path);
+ }
+ TU_MATCH( ::HIR::TraitValueItem, (it->second), (ie),
+ (None, throw ""; ),
+ (Constant,
+ TODO(sp, "Monomorpise associated constant type - " << ie.m_type);
+ ),
+ (Static,
+ TODO(sp, "Monomorpise associated static type - " << ie.m_type);
+ ),
+ (Function,
+ fix_param_count(sp, this->context, node.m_path, ie.m_params, e.params);
+
+ const auto& fcn_params = e.params;
+ const auto& trait_params = e.trait.m_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 >= trait_params.m_types.size() ) {
+ BUG(sp, "Generic param out of input range - " << idx << " '" << ge.name << "' >= " << trait_params.m_types.size());
+ }
+ return this->context.get_type(trait_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());
+ }
+ return this->context.get_type(fcn_params.m_types[idx]);
+ }
+ else {
+ BUG(sp, "Generic bounding out of total range");
+ }
+ };
+ ::HIR::FunctionType ft {
+ ie.m_unsafe, ie.m_abi,
+ box$( monomorphise_type_with(sp, ie.m_return, monomorph_cb) ),
+ {}
+ };
+ for(const auto& arg : ie.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);
+ )
+ )
),
(UfcsInherent,
// TODO: If ivars are valid within the type of this UFCS, then resolution has to be deferred until iteration