[svn] r7120: nemerle/trunk/ncc: testsuite/positive/overloading.n typing/Typer-DelayedTyping.n typing/Typer...

malekith svnadmin at nemerle.org
Tue Dec 19 16:46:49 CET 2006


Log:
Don't constrain overloads to a single one, until absolutely needed. Resolves #770.

Author: malekith
Date: Tue Dec 19 16:46:48 2006
New Revision: 7120

Modified:
   nemerle/trunk/ncc/testsuite/positive/overloading.n
   nemerle/trunk/ncc/typing/Typer-DelayedTyping.n
   nemerle/trunk/ncc/typing/Typer.n

Modified: nemerle/trunk/ncc/testsuite/positive/overloading.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/overloading.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/overloading.n	Tue Dec 19 16:46:48 2006
@@ -95,6 +95,16 @@
 }
 }
 
+module Bug770 {
+    test(_ : object) : void { }
+    test(_ : array[object]) : void { }
+    foo() : void {
+        def z(x,y){x+y}
+        test(z(1,2));
+    }
+}
+
+
 module M {
   foo (_ : array [string]) : void { }
   foo (_ : array [object]) : void { assert (false) }

Modified: nemerle/trunk/ncc/typing/Typer-DelayedTyping.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer-DelayedTyping.n	(original)
+++ nemerle/trunk/ncc/typing/Typer-DelayedTyping.n	Tue Dec 19 16:46:48 2006
@@ -396,30 +396,6 @@
       }
 
 
-      /*
-        A side, future implementation, note:
-          [Resolve] should have [badness] parameter. It would tell [Resolve]
-          what kind of bad things it can do, for example:
-            0 -- nothing bad
-            1 -- choose a better overload, even when it is not sure it will
-                 be possible to enforce
-            2 -- invoke macros taking typed arguments
-
-          Now, after we are done with typing a function:
-
-          start:
-            foreach (e in yet untyped)
-              e.Resolve(0)
-            if (something changed) goto start
-            foreach (e in yet untyped)
-              if (e.Resolve(1) succeeded) goto start
-            foreach (e in yet untyped)
-              if (e.Resolve(2) succeeded) goto start
-            if (yet untyped.IsEmpty) ok
-            else error
-      */
-
-
       ResolveOverload (overloads : list [OverloadPossibility], 
                        parms : list [Parm], expected : TyVar)
                        : list [OverloadPossibility]
@@ -430,6 +406,8 @@
         foreach (overload in overloads)
           overload.UsedLastTime = false;
 
+        def has_untyped_parm = parms.Exists (p => p.expr.Type.Hint.IsNone);
+
         def try_type (overload : OverloadPossibility, final) {
           def parms =
             if (overload.ExtensionMethodObject == null) parms
@@ -491,7 +469,28 @@
                 }
                 []
 
-              | [one] =>
+              /*
+                In general we do not commit to a single, best overload when we still
+                have some parameters that have no Hint (which means they are of a totally
+                unknown type), except:
+                  - when it is the only possible overload, 
+                  - we're in a special second pass of delayed typings or 
+                  - it is == or !=. 
+
+                The last part is a hack, it might be a good idea to
+                commit to a single overload also in some other cases
+                but the comparison operators seem to be crucial.
+
+                Bug #770.
+              */
+
+              | [one] when 
+                ok is [_] || 
+                !has_untyped_parm ||
+                typer.BadnessAllowed > 0 || 
+                one.Member.Name == "op_Equality" ||
+                one.Member.Name == "op_Inequality" =>
+
                 match (try_type (one, final = true)) {
                   | TExpr.Call (_func, parms, _) =>
                     def expr = DtKind.filtering_expression;

Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n	(original)
+++ nemerle/trunk/ncc/typing/Typer.n	Tue Dec 19 16:46:48 2006
@@ -97,6 +97,10 @@
     mutable inside_yielding_function : bool;
     mutable yield_labels : list [int];
 
+    // Ranges 0-1 currently. Used by delayed typing to determine how agressively
+    // it should work. For example uncertain overloads are dropped at level 1.
+    mutable badness_allowed : int;
+
     #region Toplevel typing
     class SwitchToYielding : System.Exception { }
     
@@ -394,6 +398,16 @@
 
 
     #region Delayed typing queues
+    BadnessAllowed : int
+    {
+      get {
+        match (parent_typer) {
+          | None => badness_allowed
+          | Some (p) => p.BadnessAllowed
+        }
+      }
+    }
+
     RunDelayedTypings () : void
     {
       mutable seen_unresolved = false;
@@ -409,9 +423,14 @@
         }
       });
 
+      def max_badness = 1;
+
       if (did_something)
         RunDelayedTypings ();
-      else if (seen_unresolved) {
+      else if (seen_unresolved && badness_allowed < max_badness) {
+        badness_allowed++;
+        RunDelayedTypings ();
+      } else if (seen_unresolved) {
         mutable error_dt = null;
         
         solver.dt_store.Iter (fun (dt : DelayedTyping, _) {
@@ -428,7 +447,9 @@
         foreach (hint in errors.Tail)
           Util.locate (error_dt.loc,
             ReportError (messenger, hint));
-      } else {}
+      } else {
+        badness_allowed = max_badness;
+      }
     }
     #endregion
 



More information about the svn mailing list