[svn] r7785: nemerle/trunk/ncc:
testsuite/negative/where-constraints1.n typing/StaticTyVar.n
typing/Subst....
nazgul
svnadmin at nemerle.org
Wed Sep 5 12:22:05 CEST 2007
Log:
Fix checking of generic constraints - bugs 1048 and 1046. Patch by BOleg.
Author: nazgul
Date: Wed Sep 5 12:22:03 2007
New Revision: 7785
Modified:
nemerle/trunk/ncc/testsuite/negative/where-constraints1.n
nemerle/trunk/ncc/typing/StaticTyVar.n
nemerle/trunk/ncc/typing/Subst.n
nemerle/trunk/ncc/typing/TyVarEnv.n
Modified: nemerle/trunk/ncc/testsuite/negative/where-constraints1.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/negative/where-constraints1.n (original)
+++ nemerle/trunk/ncc/testsuite/negative/where-constraints1.n Wed Sep 5 12:22:03 2007
@@ -1,2 +1,15 @@
class A ['a] where 'a : System.IComparable ['a], System.IComparable ['a] { // E: constraint `System.IComparable.*' is already declared for 'a
}
\ No newline at end of file
+
+namespace Bug1048 {
+using System;
+
+class RefTypeA {}
+class RefTypeB {}
+
+struct StructType {}
+
+class Test1[T1] where T1 : Object, Int32 {} // E: generic parameter cannot be constrained by multiple non-interfaces : int, System.Object
+class Test2[T1] where T1 : Object, StructType {} // E: generic parameter cannot be constrained by multiple non-interfaces : Bug1048.StructType, System.Object
+class Test3[T1] where T1 : RefTypeA, RefTypeB {} // E: generic parameter cannot be constrained by multiple non-interfaces : Bug1048.RefTypeB, Bug1048.RefTypeA
+}
Modified: nemerle/trunk/ncc/typing/StaticTyVar.n
==============================================================================
--- nemerle/trunk/ncc/typing/StaticTyVar.n (original)
+++ nemerle/trunk/ncc/typing/StaticTyVar.n Wed Sep 5 12:22:03 2007
@@ -77,6 +77,9 @@
get {
assert (constraints != null, $"for $this");
match (constraints) {
+ | [] when (IsValueType)=>
+ assert (InternalType.ValueType != null);
+ InternalType.ValueType
| [] =>
assert (InternalType.Object != null);
InternalType.Object
@@ -156,12 +159,32 @@
internal SetConstraints (special : GenericParameterAttributes, subtype : list [MType]) : void
{
- when ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) %&&
- (special & ~GenericParameterAttributes.NotNullableValueTypeConstraint))
- Message.Error ("`struct' generic constraint cannot be used together with `class' or `new ()'");
+ when ((special %&& GenericParameterAttributes.NotNullableValueTypeConstraint) &&
+ (special %&& GenericParameterAttributes.ReferenceTypeConstraint))
+ Message.Error ("`struct' generic constraint cannot be used together with `class'");
this.special = special;
+
+ def check_class_constraints(lst)
+ {
+ mutable c=null;
+ lst.ForAll (fun(x) {
+ | x is MType.Class when (!x.tycon.IsInterface) =>
+ if(c==null) {
+ c = x;
+ true;
+ }
+ else {
+ Message.Error ($ "generic parameter cannot be constrained by multiple non-interfaces : $(c), $(x)");
+ false
+ }
+ | _ => true
+ });
+ }
+ if (check_class_constraints(subtype))
Constraints = subtype;
+ else
+ Constraints = [];
}
public IsValueType : bool {
@@ -242,7 +265,6 @@
}
}
-
/// Check if [tv] fullfills [this]'s constraints.
public CheckConstraints (tv : TyVar, thing : object) : void
{
@@ -261,11 +283,20 @@
| _ => false
}
+ def check_constraints (t, c) {
+ ! match(t)
+ {
+ | MType.TyVarRef (s) =>
+ s.Constraints.ForAll( ctr => { ctr.IsInterface || ! c (ctr) });
+ | _ => t.IsInterface || ! c (t);
+ }
+ }
+
def t = tv.Fix ();
when (SpecialConstraints %&&
GenericParameterAttributes.NotNullableValueTypeConstraint &&
- t.CanBeNull)
+ check_constraints (t, c => { c.CanBeNull }))
// cs453
Message.Error ($ "the type `$t' must be a value type "
"in order to use it as type parameter "
@@ -273,7 +304,7 @@
when (SpecialConstraints %&&
GenericParameterAttributes.ReferenceTypeConstraint &&
- ! t.CanBeNull)
+ check_constraints (t, c => { !c.CanBeNull }))
// cs452
Message.Error ($ "the type `$t' must be a reference type "
"in order to use it as type parameter "
Modified: nemerle/trunk/ncc/typing/Subst.n
==============================================================================
--- nemerle/trunk/ncc/typing/Subst.n (original)
+++ nemerle/trunk/ncc/typing/Subst.n Wed Sep 5 12:22:03 2007
@@ -212,8 +212,9 @@
});
List.Iter2 (vars, vars', fun (v : StaticTyVar, tv : TyVar) {
- when (!v.LowerBound.Equals (tv.Manager.InternalType.Object)) {
- def ok = tv.Require (res.Apply (v.LowerBound));
+ def lb = v.LowerBound;
+ when (!lb.Equals (tv.Manager.InternalType.Object) && !lb.Equals (tv.Manager.InternalType.ValueType)) {
+ def ok = tv.Require (res.Apply (lb));
Util.cassert (was_error || ok, $ "req fail, $tv $(res.Apply (v.LowerBound))");
}
});
Modified: nemerle/trunk/ncc/typing/TyVarEnv.n
==============================================================================
--- nemerle/trunk/ncc/typing/TyVarEnv.n (original)
+++ nemerle/trunk/ncc/typing/TyVarEnv.n Wed Sep 5 12:22:03 2007
@@ -421,7 +421,7 @@
match (c.ty) {
| <[ @class ]> => special |= GenericParameterAttributes.ReferenceTypeConstraint;
- | <[ @struct ]> => special |= GenericParameterAttributes.NotNullableValueTypeConstraint;
+ | <[ @struct ]> => special |= (GenericParameterAttributes.NotNullableValueTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint);
| <[ @new ]> => special |= GenericParameterAttributes.DefaultConstructorConstraint;
| <[ @+ ]> => special |= GenericParameterAttributes.Covariant;
| <[ @- ]> => special |= GenericParameterAttributes.Contravariant;
@@ -510,8 +510,6 @@
if (cyclicConstraints.IsEmpty)
foreach (tv : StaticTyVar in tyParams)
- // FIXME: check Intersection invariants and flag error
- // to the user, otherwise we'll get an ICE
tv.SetConstraints (get (tv.id));
else
foreach (tv : StaticTyVar in tyParams)
More information about the svn
mailing list