summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp58
1 files changed, 56 insertions, 2 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 226be96c..ec172d0a 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -1938,10 +1938,15 @@ namespace {
{
Context& context;
bool m_completed;
+ /// Tells vistors that inferrence has stalled, and that they can take
+ /// more extreme actions (e.g. ignoring an ambigious inherent method
+ /// and using a trait method instead)
+ bool m_is_fallback;
public:
- ExprVisitor_Revisit(Context& context):
+ ExprVisitor_Revisit(Context& context, bool fallback=false):
context(context),
- m_completed(false)
+ m_completed(false),
+ m_is_fallback(fallback)
{}
bool node_completed() const {
@@ -2160,6 +2165,23 @@ namespace {
),
(Pointer,
// Allow with no link?
+ // TODO: In some rare cases, this ivar could be completely
+ // unrestricted. If in fallback mode
+ const auto& dst_inner = this->context.get_type(*e.inner);
+ if(this->m_is_fallback)
+ {
+ if( dst_inner.m_data.is_Infer() )
+ {
+ this->context.equate_types(sp, *e.inner, *s_e.inner);
+ }
+ }
+ else if( dst_inner.m_data.is_Infer() )
+ {
+ return ;
+ }
+ else
+ {
+ }
this->m_completed = true;
)
)
@@ -6294,6 +6316,38 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR:
}
}
+ if( !context.m_ivars.peek_changed() )
+ {
+ DEBUG("--- Node revisits (fallback)");
+ for( auto it = context.to_visit.begin(); it != context.to_visit.end(); )
+ {
+ ::HIR::ExprNode& node = **it;
+ ExprVisitor_Revisit visitor { context, true };
+ DEBUG("> " << &node << " " << typeid(node).name() << " -> " << context.m_ivars.fmt_type(node.m_res_type));
+ node.visit( visitor );
+ // - If the node is completed, remove it
+ if( visitor.node_completed() ) {
+ DEBUG("- Completed " << &node << " - " << typeid(node).name());
+ it = context.to_visit.erase(it);
+ }
+ else {
+ ++ it;
+ }
+ }
+ #if 0
+ for( auto it = context.adv_revisits.begin(); it != context.adv_revisits.end(); )
+ {
+ auto& ent = **it;
+ if( ent.revisit(context) ) {
+ it = context.adv_revisits.erase(it);
+ }
+ else {
+ ++ it;
+ }
+ }
+ #endif
+ }
+
// Finally. If nothing changed, apply ivar defaults
if( !context.m_ivars.peek_changed() )
{