summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp118
-rw-r--r--src/hir_typeck/helpers.cpp21
2 files changed, 85 insertions, 54 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 83476abe..774e81f4 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2532,9 +2532,11 @@ namespace {
return true;
),
(Path,
- //TODO(Span(), "check_coerce - Coercion from " << ty_r);
- context.equate_types(sp, ty, node_ptr->m_res_type);
- return true;
+ if( ! e.binding.is_Unbound() ) {
+ //TODO(Span(), "check_coerce - Coercion from " << ty_r);
+ context.equate_types(sp, ty, node_ptr->m_res_type);
+ return true;
+ }
),
(Generic,
//TODO(Span(), "check_coerce - Coercion from " << ty_r);
@@ -2602,10 +2604,11 @@ namespace {
return true;
),
(Path,
- //TODO(Span(), "check_coerce - Coercion to " << ty);
- // TODO: CoerceUnsized
- context.equate_types(sp, ty, node_ptr->m_res_type);
- return true;
+ if( ! l_e.binding.is_Unbound() ) {
+ // TODO: CoerceUnsized
+ context.equate_types(sp, ty, node_ptr->m_res_type);
+ return true;
+ }
),
(Generic,
//TODO(Span(), "check_coerce - Coercion to " << ty);
@@ -2851,6 +2854,59 @@ namespace {
return false;
}
}
+
+ void check_ivar_poss(Context& context, unsigned int i, Context::IVarPossible& ivar_ent)
+ {
+ if( ivar_ent.types.size() == 0 ) {
+ // No idea! (or unused)
+ return ;
+ }
+
+ TRACE_FUNCTION_F(i);
+
+ if( ivar_ent.types.size() > 1 ) {
+ // De-duplicate list (taking into account other ivars)
+ for( auto it = ivar_ent.types.begin(); it != ivar_ent.types.end(); )
+ {
+ bool found = false;
+ for( auto it2 = ivar_ent.types.begin(); it2 != it; ++ it2 ) {
+ //if( context.m_ivars.types_equal( **it, **it2 ) ) {
+ if( context.m_ivars.types_equal( *it, *it2 ) ) {
+ found = true;
+ break;
+ }
+ }
+ if( found ) {
+ it = ivar_ent.types.erase(it);
+ }
+ else {
+ ++ it;
+ }
+ }
+ }
+ else {
+ // One possibility, no need to dedup
+ }
+
+ ::HIR::TypeRef ty_l_ivar;
+ ty_l_ivar.m_data.as_Infer().index = i;
+ const auto& ty_l = context.m_ivars.get_type(ty_l_ivar);
+
+ if( !ty_l.m_data.is_Infer() ) {
+ DEBUG("- IVar " << ty_l << " had possibilities, but was known");
+ }
+ else if( ivar_ent.types.size() == 1 ) {
+ //const ::HIR::TypeRef& ty_r = ivar_ent.types[0];
+ const ::HIR::TypeRef& ty_r = ivar_ent.types[0];
+ // Only one possibility
+ DEBUG("- IVar " << ty_l << " = " << ty_r);
+ context.equate_types(Span(), ty_l, ty_r);
+ }
+ else {
+ }
+
+ ivar_ent.types.clear();
+ }
}
@@ -2934,53 +2990,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:
unsigned int i = 0;
for(auto& ivar_ent : context.possible_ivar_vals)
{
- if( ivar_ent.types.size() == 0 ) {
- // No idea! (or unused)
- i ++ ;
- continue ;
- }
- else if( ivar_ent.types.size() > 1 ) {
- // De-duplicate list (taking into account other ivars)
- for( auto it = ivar_ent.types.begin(); it != ivar_ent.types.end(); )
- {
- bool found = false;
- for( auto it2 = ivar_ent.types.begin(); it2 != it; ++ it2 ) {
- //if( context.m_ivars.types_equal( **it, **it2 ) ) {
- if( context.m_ivars.types_equal( *it, *it2 ) ) {
- found = true;
- break;
- }
- }
- if( found ) {
- it = ivar_ent.types.erase(it);
- }
- else {
- ++ it;
- }
- }
- }
- else {
- // One possibility, no need to dedup
- }
-
- ::HIR::TypeRef ty_l_ivar;
- ty_l_ivar.m_data.as_Infer().index = i;
- const auto& ty_l = context.m_ivars.get_type(ty_l_ivar);
-
- if( !ty_l.m_data.is_Infer() ) {
- DEBUG("- IVar " << ty_l << " had possibilities, but was known");
- }
- else if( ivar_ent.types.size() == 1 ) {
- //const ::HIR::TypeRef& ty_r = ivar_ent.types[0];
- const ::HIR::TypeRef& ty_r = ivar_ent.types[0];
- // Only one possibility
- DEBUG("- IVar " << ty_l << " = " << ty_r);
- context.equate_types(Span(), ty_l, ty_r);
- }
- else {
- }
-
- ivar_ent.types.clear();
+ check_ivar_poss(context, i, ivar_ent);
i ++ ;
}
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index d31b5b7d..13b26ab7 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -645,6 +645,27 @@ void HMTypeInferrence::set_ivar_to(unsigned int slot, ::HIR::TypeRef type)
else {
// Otherwise, store left in right's slot
DEBUG("Set IVar " << slot << " = " << type);
+ TU_IFLET(::HIR::TypeRef::Data, root_ivar.type->m_data, Infer, e,
+ switch(e.ty_class)
+ {
+ case ::HIR::InferClass::None:
+ break;
+ case ::HIR::InferClass::Integer:
+ case ::HIR::InferClass::Float:
+ // `type` can't be an ivar, so it has to be a primitive (or an associated?)
+ TU_MATCH_DEF(::HIR::TypeRef::Data, (type.m_data), (l_e),
+ (
+ ),
+ (Primitive,
+ typeck::check_type_class_primitive(sp, type, e.ty_class, l_e);
+ )
+ )
+ break;
+ }
+ )
+ else {
+ BUG(sp, "Overwriting ivar " << slot << " (" << *root_ivar.type << ") with " << type);
+ }
root_ivar.type = box$( mv$(type) );
}