Skip to content

Commit 5ed8716

Browse files
Keep type synonyms in some special cases (#1086)
Co-authored-by: David Cok <[email protected]>
1 parent 27297d8 commit 5ed8716

File tree

4 files changed

+122
-2
lines changed

4 files changed

+122
-2
lines changed

Source/Dafny/DafnyAst.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,11 @@ public static Type MeetX(Type a, Type b, BuiltIns builtIns) {
18431843
Contract.Requires(b != null);
18441844
Contract.Requires(builtIns != null);
18451845

1846+
// As a special-case optimization, check for equality here, which will better preserve un-expanded type synonyms
1847+
if (a.Equals(b, true)) {
1848+
return a;
1849+
}
1850+
18461851
// Before we do anything else, make a note of whether or not both "a" and "b" are non-null types.
18471852
var abNonNullTypes = a.IsNonNullRefType && b.IsNonNullRefType;
18481853

Source/Dafny/Resolver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4378,7 +4378,7 @@ private bool AssignProxyAndHandleItsConstraints_aux(TypeProxy proxy, Type t, boo
43784378
Contract.Requires(!(t is TypeProxy));
43794379
Contract.Requires(!(t is ArtificialType));
43804380

4381-
t = keepConstraints ? t.NormalizeExpandKeepConstraints() : t.NormalizeExpand();
4381+
t = keepConstraints ? t.Normalize() : t.NormalizeExpand();
43824382
// never violate the type constraint of a literal expression
43834383
var followedRequestedAssignment = true;
43844384
foreach (var su in proxy.Supertypes) {
@@ -6051,7 +6051,7 @@ bool AssignKnownEndsFullstrength_SuperDirection(TypeProxy proxy) {
60516051
var meets = new List<Type>();
60526052
foreach (var xc in AllXConstraints) {
60536053
if (xc.ConstraintName == "Assignable" && xc.Types[1].Normalize() == proxy) {
6054-
var su = xc.Types[0].NormalizeExpandKeepConstraints();
6054+
var su = xc.Types[0].Normalize();
60556055
if (su is TypeProxy) {
60566056
continue; // don't include proxies in the meet computation
60576057
}

Test/git-issues/git-issue-623.dfy

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// RUN: %dafny /compile:0 "%s" > "%t"
2+
// RUN: %diff "%s.expect" "%t"
3+
4+
// ----- example reported in Issue 623
5+
6+
module M1 {
7+
export Abs
8+
provides M, T
9+
export Conc
10+
provides M, MyClass
11+
reveals T
12+
13+
class MyClass {
14+
}
15+
16+
type T = MyClass
17+
18+
lemma M(f: T ~> bool)
19+
requires forall t :: f.requires(t) ==> f(t) // regression test: this once crashed during checking of M2
20+
{ }
21+
}
22+
23+
module M2 {
24+
import M1`Abs
25+
26+
method K(t: M1.T) {
27+
}
28+
}
29+
30+
module M3 {
31+
import M1`Conc
32+
33+
method K(t: M1.T) {
34+
}
35+
}
36+
37+
// ----- example reported in Issue 150
38+
39+
module N1 {
40+
export
41+
provides T, Equal, Foo
42+
43+
type T(==) = seq<real>
44+
45+
predicate Equal(u: T, v: T)
46+
{
47+
u == v
48+
}
49+
50+
lemma Foo()
51+
ensures forall u, v :: Equal(u, v) ==> u == v // regression test: this once crashed during checking of N2
52+
{ }
53+
}
54+
55+
module N2 {
56+
import N1
57+
58+
lemma Bar(u: N1.T, v: N1.T)
59+
requires N1.Equal(u, v)
60+
{
61+
N1.Foo();
62+
assert u == v;
63+
}
64+
}
65+
66+
67+
// ------------------- additional examples
68+
69+
module Library {
70+
export
71+
provides W, P, X, Q
72+
provides M0, M1
73+
74+
type W = MyTrait
75+
trait MyTrait {
76+
}
77+
predicate P(u: W)
78+
79+
type X = MyClass
80+
class MyClass extends MyTrait {
81+
}
82+
predicate Q(x: X)
83+
84+
lemma M0()
85+
requires forall t :: P(t)
86+
{ }
87+
lemma M1()
88+
requires forall t :: Q(t)
89+
{ }
90+
91+
lemma Private0()
92+
requires forall t :: P(t) && Q(t) // error: t is inferred as MyTrait, so can't prove that Q(t) is well-formed
93+
{ }
94+
lemma Private1()
95+
requires forall t :: Q(t) && P(t) // error: t is inferred as MyTrait, so can't prove that Q(t) is well-formed
96+
{ }
97+
}
98+
99+
module Client {
100+
import Library
101+
102+
method K()
103+
requires forall t :: Library.P(t)
104+
requires forall t :: Library.Q(t)
105+
{
106+
}
107+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
git-issue-623.dfy(92,35): Error: the RHS value (a MyTrait) is not known to be an instance of the LHS type (MyClass)
2+
Execution trace:
3+
(0,0): anon0
4+
git-issue-623.dfy(95,27): Error: the RHS value (a MyTrait) is not known to be an instance of the LHS type (MyClass)
5+
Execution trace:
6+
(0,0): anon0
7+
8+
Dafny program verifier finished with 3 verified, 2 errors

0 commit comments

Comments
 (0)