[svn] r7720: nemerle/trunk/ncc: testsuite/positive/operators2.n
typing/Typer-CallTyper.n typing/Typer-Dela...
divan
svnadmin at nemerle.org
Thu Jun 28 22:12:26 CEST 2007
Log:
Improve delayed operators (fix 635, 1026).
Author: divan
Date: Thu Jun 28 22:12:21 2007
New Revision: 7720
Added:
nemerle/trunk/ncc/testsuite/positive/operators2.n
Modified:
nemerle/trunk/ncc/typing/Typer-CallTyper.n
nemerle/trunk/ncc/typing/Typer-DelayedTyping.n
nemerle/trunk/ncc/typing/Typer.n
Added: nemerle/trunk/ncc/testsuite/positive/operators2.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/operators2.n Thu Jun 28 22:12:21 2007
@@ -0,0 +1,89 @@
+using Nemerle.Collections.List;
+using System.Console;
+
+module Bug635 {
+
+ [Record]
+ public class T0 { //simplified bug 635
+ public x : list [int];
+ public y : list [int];
+
+ public static @+ (_a : T0, _b : T0) : T0 {
+ def f = _ + _;
+ def _g = f(1, 2);
+ null;
+ }
+ }
+
+ [Record]
+ public class T { //bug 635
+ public x : list [int];
+ public y : list [int];
+
+ public static @+ (a : T, b : T) : T {
+ T (Map2 (a.x, b.x, _ + _), Map2 (a.y, b.y, _ + _))
+ }
+ }
+
+ public Go () : void {
+ _ = T0 ([], []) + T0 ([], []);
+ def a = T ([1], [2, 3]);
+ def b = T ([4], [5, 6]);
+ def c = a + b;
+ WriteLine ($"$(c.x) $(c.y)");
+ }
+}
+
+
+namespace A {
+using System;
+using Bug1026.DateHelper;
+
+module Bug1026 {
+
+ public class DateHelper {
+ public static @+ (date : DateTime, delta : double) : DateTime {
+ date.AddDays (delta);
+ }
+ public static @+ (_ : int, _ : DateTime) : int {
+ 1
+ }
+ }
+ public Go () : void {
+ def x = [1.0].FoldLeft (2.0, _ + _);
+ WriteLine (x);
+ def x = 2 + DateTime ();
+ WriteLine (x);
+ _ = DateTime () + 1;
+ }
+}
+}
+
+namespace B {
+using System.UInt32;
+//this makes only one global op_Addition, which caused bugs
+
+module BugSingle {
+
+ public Go () : void {
+ def a = (_ + _) ([1], [2]);
+ def b = (_ + _) (1, 2);
+ def c = [1].FoldLeft (2, _ + _);
+ WriteLine ($"$a $b $c")
+ }
+}
+}
+
+
+Bug635.Go ();
+A.Bug1026.Go ();
+B.BugSingle.Go ();
+
+/*
+BEGIN-OUTPUT
+[5] [7, 9]
+3
+1
+[1, 2] 3 3
+END-OUTPUT
+*/
Modified: nemerle/trunk/ncc/typing/Typer-CallTyper.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer-CallTyper.n (original)
+++ nemerle/trunk/ncc/typing/Typer-CallTyper.n Thu Jun 28 22:12:21 2007
@@ -183,9 +183,13 @@
{
//Message.Debug ($ "$(parm.expr.Type) <<< $ftype");
- Util.cassert (parm.required_type == null);
when (is_final)
+ {
+ if (parm.required_type == null)
parm.required_type = ftype;
+ else
+ _ = parm.required_type.Provide (ftype);
+ }
def msg =
if (messenger.NeedMessage)
@@ -566,4 +570,3 @@
}
}
}
-
Modified: nemerle/trunk/ncc/typing/Typer-DelayedTyping.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer-DelayedTyping.n (original)
+++ nemerle/trunk/ncc/typing/Typer-DelayedTyping.n Thu Jun 28 22:12:21 2007
@@ -87,6 +87,10 @@
{
| MemberAccess { expr : TExpr; name : PT.Name; }
| Overloaded { overloads : list [OverloadPossibility]; }
+ | OverloadedOperator { overloads : list [OverloadPossibility];
+ t1 : TyVar; t2 : TyVar; name : string; env : GlobalEnv;
+ seen : list [OverloadPossibility];
+ }
| Operator { t1 : TyVar; t2 : TyVar; name : string; env : GlobalEnv; }
| Resolved { expr : TExpr; }
| Macro { action : DelayedAction }
@@ -142,11 +146,14 @@
}
| Kind.Overloaded (lst) =>
Kind.Overloaded (OverloadPossibility.Unique (lst))
+ | Kind.OverloadedOperator (lst, t1, t2, n, e, s) =>
+ Kind.OverloadedOperator (OverloadPossibility.Unique (lst), t1, t2, n, e, s)
| _ => k
}
when (generic_specifier != null)
match (k) {
+ | Kind.OverloadedOperator (lst, _, _, _, _, _)
| Kind.Overloaded (lst) =>
foreach (o in lst)
o.SetGenericSpecifier (generic_specifier);
@@ -198,6 +205,7 @@
{
get {
match (DtKind) {
+ | Kind.OverloadedOperator (lst, _, _, _, _, _)
| Kind.Overloaded (lst) =>
List.ForAll (lst, fun (op : OverloadPossibility) {
match (op.Member) {
@@ -219,6 +227,7 @@
{
get {
match (DtKind) {
+ | Kind.OverloadedOperator (lst, _, _, _, _, _)
| Kind.Overloaded (lst) =>
lst.ForAll (fun (op) { op.Member is IMethod })
@@ -258,6 +267,7 @@
| Kind.Macro
| Kind.Error => true
+ | Kind.OverloadedOperator
| Kind.Operator => false
}
}
@@ -273,6 +283,20 @@
}
match (DtKind) {
+ | Kind.OverloadedOperator (lst, t1, t2, n, e, s) =>
+ when (InternalType.Object_tc.LookupMember (name) is []) {
+ // otherwise it's pointless
+ def newlst = List.RevFilter (lst, fun (o : OverloadPossibility) {
+ match (o.Type.Hint) {
+ | Some (mt) => can_have (mt)
+ | None => true // we don't yet know
+ }
+ });
+
+ if (newlst is []) {}
+ else SetKind (Kind.OverloadedOperator (newlst, t1, t2, n, e, s));
+ }
+
| Kind.Overloaded (lst) =>
when (InternalType.Object_tc.LookupMember (name) is []) {
// otherwise it's pointless
@@ -327,6 +351,10 @@
| Operator (t1, t2, name, _) =>
$ "operator `$(name)' on $(t1)"
+ (if (t2 == null) "" else $ " and $(t2)")
+ | OverloadedOperator (lst, t1, t2, name, _, _) =>
+ $ "overloaded operator `$(name)' on $(t1)"
+ + (if (t2 == null) "" else $ " and $(t2)") + "\n"
+ + lst.ToString ("\n ")
| Macro (action) => action.ToString ()
}
}
@@ -335,6 +363,16 @@
public GetDescriptionForError () : list [string]
{
match (DtKind) {
+ | OverloadedOperator (overloads, t1, t2, name, _env, _seen) =>
+ def used (o) { o.UsedLastTime }
+ "ambiguity between operator " +
+ $"$name($t1" + (if (t2 != null) $", $t2" else "") + ")"
+ " overloads:" ::
+ (if (overloads.Exists (used))
+ overloads.Filter (used)
+ else
+ overloads).Map (x => $"Posible overload: $x")
+
| Overloaded (overloads) =>
def used (o) { o.UsedLastTime }
"ambiguity between overloads:" ::
@@ -360,7 +398,7 @@
public IsOverloaded : bool
{
- get { DtKind is Kind.Overloaded }
+ get { DtKind is Kind.Overloaded || DtKind is Kind.OverloadedOperator }
}
@@ -376,6 +414,7 @@
match (DtKind) {
| MemberAccess
| Overloaded
+ | OverloadedOperator
| Error
| Operator => true
| Resolved
@@ -632,6 +671,63 @@
| lst =>
SetKind (Kind.Overloaded (lst))
}
+ | Kind.OverloadedOperator (overloads, t1, t2, name, env, seen) =>
+ def not_seen (l) {
+ | None with l = []
+ | Some (l) =>
+ l.Filter ( fun (x) { !seen.Contains (x) } );
+ }
+ def new_operators = not_seen (LookupOperator (t1, name)) + not_seen (LookupOperator (t2, name));
+ def seen = new_operators + seen;
+ def added =
+ match (new_operators) {
+ | lst when lst != [] =>
+ def lst = OverloadPossibility.Unique (overloads + lst);
+ if (lst == overloads)
+ false
+ else
+ {
+ SetKind (Kind.OverloadedOperator (lst, t1, t2, name, env, seen));
+ true
+ }
+ | _ => false
+ }
+ unless (added)
+ {
+ def args = if (t2 == null) 1 else 2;
+ def hints = (if (t1.Hint.IsSome) 1 else 0) + (if (t2 != null && t2.Hint.IsSome) 1 else 0);
+
+ def expr = DtKind.filtering_expression;
+ def o' =
+ if (expr == null) {
+ RemoveExtensionMethods (OverloadPossibility.OnlyPossible (overloads, expected))
+ } else {
+ if (typer.Expect (expected, expr.func.Type,
+ "overloaded function call"))
+ match (overloads) {
+ | [one] when hints == 0
+ || typer.BadnessAllowed > 1 =>
+ [one] //don't call ResolveOverload early, as it can add wrong hints
+ | _ => ResolveOverload (overloads, expr.parms, expr.Type)
+ }
+ else
+ []
+ }
+
+ when (o'.Length != overloads.Length || o'.Length == 1)
+ match (o') {
+ | [] =>
+ SetKind (Kind.Error ())
+
+ | [one] when hints == args
+ || hints > 0 && typer.BadnessAllowed > 0
+ || typer.BadnessAllowed > 1 =>
+ SetKind (Kind.Resolved (one.Compile ()))
+
+ | lst =>
+ SetKind (Kind.OverloadedOperator (lst, t1, t2, name, env, seen));
+ }
+ }
| Kind.Operator (t1, t2, name, env) =>
def operators =
@@ -660,7 +756,7 @@
SetKind (Kind.Error ())
| Some (lst) =>
- SetKind (Kind.Overloaded (lst));
+ SetKind (Kind.OverloadedOperator (lst, t1, t2, name, env, lst));
Resolve ()
| None => {}
Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n (original)
+++ nemerle/trunk/ncc/typing/Typer.n Thu Jun 28 22:12:21 2007
@@ -386,7 +386,7 @@
}
});
- def max_badness = 1;
+ def max_badness = 2;
if (did_something)
RunDelayedTypings ();
More information about the svn
mailing list