[svn] r6214: nemerle/trunk/ncc: testsuite/positive/implicit-poly-conversion.n typing/Typer.n

malekith svnadmin at nemerle.org
Wed May 3 12:32:03 CEST 2006


Log:
Implement polymorphic implict conversions. Resolves #630.

Author: malekith
Date: Wed May  3 12:32:02 2006
New Revision: 6214

Added:
   nemerle/trunk/ncc/testsuite/positive/implicit-poly-conversion.n
Modified:
   nemerle/trunk/ncc/typing/Typer.n

Added: nemerle/trunk/ncc/testsuite/positive/implicit-poly-conversion.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/implicit-poly-conversion.n	Wed May  3 12:32:02 2006
@@ -0,0 +1,61 @@
+class C [T] {
+  public static @: (_ : T) : C[T] {
+    C()
+  }
+
+  public override ToString () : string
+  {
+    $ "C<$(typeof(T))>"
+  }
+}
+
+class B {}
+
+class C2 {
+  public static @: [X] (_ : X) : C2 {
+    C2()
+  }
+
+  public override ToString () : string
+  {
+    "C2"
+  }
+}
+
+
+interface IFoo {}
+
+struct Bar1['a] where 'a : IFoo
+{
+    static public @:['b](_ : 'b) : Bar1['a] where 'b : IFoo
+    {
+        Bar1()
+    }
+
+    public override ToString () : string
+    {
+      "Bar1"
+    }
+}
+
+struct Bar2 : IFoo {}
+
+
+class Implicit
+{
+  public static Main() : void
+  {
+     def x = B() : C[B];
+     def y = B() : C2;
+     Nemerle.IO.print("$x $y\n");
+     def bar : Bar1.[IFoo] = Bar2();
+     Nemerle.IO.print("$bar\n");
+  }
+}
+
+/*
+BEGIN-OUTPUT
+C<B> C2
+Bar1
+END-OUTPUT
+*/

Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n	(original)
+++ nemerle/trunk/ncc/typing/Typer.n	Wed May  3 12:32:02 2006
@@ -745,15 +745,8 @@
 
 
     #region Implicit conversions
-    /** Return all possible implicit conversions [from] -> [to].
-        Assume not [from <: to].
-      */
-    static LookupConversions (from : TypeInfo, to : TypeInfo) : list [IMethod]
+    static LookupConversions (tv : TyVar) : list [IMember]
     {
-      def ids = (from, to);
-      if (implicit_conversions.Contains (ids))
-        implicit_conversions [ids]
-      else {
         def lookup (acc, tc) {
           def acc = tc.LookupMember ("op_Implicit") + acc;
           match (tc.SuperClass ()) {
@@ -761,18 +754,10 @@
             | None => acc
           }
         }
-        def methods = SquashDuplicates (lookup (lookup ([], from), to));
-        mutable res = [];
-        def ty = 
-          MType.ConstructFunctionType ([from.GetFreshType () : TyVar], 
-                                       to.GetFreshType ());
-        foreach (meth is IMethod in methods : list [IMember]) {
-          when (meth.IsStatic && meth.GetFreshType () [0].TryRequire (ty))
-            res = meth :: res;
-        }
 
-        implicit_conversions [ids] = res;
-        res
+      match (tv.Hint) {
+        | Some (Class (tc, _)) => lookup ([], tc)
+        | _ => []
       }
     }
 
@@ -782,21 +767,20 @@
       if (from.TryRequire (to)) {
         from.Require (to)
       } else {
-        match (from.Hint) {
-          // class -> class using op_Implicit
-          | Some (MType.Class (from_tc, _)) =>
-            match (to.Hint) {
-              | Some (MType.Class (to_tc, _)) =>
-                def methods = LookupConversions (from_tc, to_tc);
+        def methods = LookupConversions (from) + LookupConversions (to);
+        def methods = SquashDuplicates (methods);
+        
                 if (methods.IsEmpty) false
                 else {
-                  mutable res = [];
                   def needed = MType.ConstructFunctionType ([from], to);
-                  foreach (meth in methods) {
-                    when (meth.GetFreshType () [0].TryRequire (needed))
-                      res = meth :: res;
+          def fresh_type (meth) {
+            meth.DeclaringType.GetFreshType ().TypeOfMethodWithTyparms (meth) [0]
                   }
-                  res = GetBestOverloads1 (res);
+          def res = $[ meth | meth is IMethod in methods, 
+                              meth.IsStatic,
+                              fresh_type (meth).TryRequire (needed) ];
+          def res = GetBestOverloads1 (res);
+          
                   match (res) {
                     | [one] =>
                       def overload = ConstructMethodOverload (one);
@@ -811,11 +795,6 @@
                       false
                   }
                 }
-              | _ => false
-            }
-
-          | _ => false
-        }
       }
     }
 
@@ -2556,7 +2535,6 @@
     static binary_operators : Hashtable [string, string] = Hashtable ();
     static unary_operators : Hashtable [string, string] = Hashtable ();
     // a cache
-    static implicit_conversions : Hashtable [TypeInfo * TypeInfo, list [IMethod]] = Hashtable ();
     
     static this ()
     {
@@ -2601,7 +2579,6 @@
 
     static Clear () : void
     {
-      implicit_conversions.Clear ();
       better_type_cache.Clear ();
       checked_macro = null;
       unchecked_macro = null;



More information about the svn mailing list