// RUN: %dafny /compile:0 /print:"%t.print" /dprint:"%t.dprint" "%s" > "%t" // RUN: %diff "%s.expect" "%t" class C { function F(c: C, d: D): bool { true } method M(x: int) returns (y: int, c: C) requires F(D.A, this); // 2 errors requires F(4, 5); // 2 errors requires F(this, D.A); // good { } method Caller() { var m,n := M(true); // error on in-parameter n,m := M(m); // 2 errors on out-parameters } } datatype D = A; datatype NeverendingList = Cons(int, NeverendingList); // error: no grounding constructor datatype MutuallyRecursiveDataType = FromANumber(int) | // this is the base case Else(TheCounterpart, C); datatype TheCounterpart = TreeLike(TheCounterpart, TheCounterpart) | More(MutuallyRecursiveDataType); // these 'ReverseOrder_' order tests may be called white-box unit tests datatype ReverseOrder_MutuallyRecursiveDataType = FromANumber(int) | // this is the base case Else(ReverseOrder_TheCounterpart, C); datatype ReverseOrder_TheCounterpart = TreeLike(ReverseOrder_TheCounterpart, ReverseOrder_TheCounterpart) | More(ReverseOrder_MutuallyRecursiveDataType); // --------------------- class ArrayTests { ghost method G(a: array) requires a != null && 10 <= a.Length; modifies a; { a[7] := 13; // error: array elements are not ghost locations } } // --------------------- method DuplicateVarName(x: int) returns (y: int) { var z: int; var z: int; // error: redeclaration of local var x := x; // redeclaration of in-parameter is fine var x := x; // error: but a redeclaration of that local is not fine { var x := x; // an inner local variable of the same name is fine var x := x; // error: but a redeclaration thereof is not okay var y := y; // duplicating an out-parameter here is fine } var y := y; // error: redeclaration of an out-parameter is not allowed (it is // treated like an outermost-scoped local in this regard) } method ScopeTests() { var x := x; // error: the 'x' in the RHS is not in scope var y: real :| y == y; // fine, 'y' is in scope in the RHS var z := DuplicateVarName(z); // error: the 'z' in the RHS is not in scope var w0, w1 := IntTransform(w1), IntTransform(w0); // errors two var c := new MyClass.Init(null); // fine var d := new MyClass.Init(c); // fine var e := new MyClass.Init(e); // error: the 'e' in the RHS is not in scope e := new MyClass.Init(e); // fine (no variable is being introduced here) e.c := new MyClass.Init(e); // also fine } function IntTransform(w: int): int class MyClass { var c: MyClass; constructor Init(c: MyClass) } // --------------------- method InitCalls() { var c := new C.F(null, null); // error: F is not a method var d := new C.M(8); // error: M has out parameters var e := new C.Caller(); } // --------------------- method ArrayRangeAssignments(a: array, c: C) requires a != null && 10 <= a.Length; { a[0..5] := new C; // error: this is not allowed a[1..4] := *; // error: this is not allowed a[2..3] := c; // error: this is not allowed var s: seq := [null,null,null,null,null]; s[0..5] := new C; // error: this is not allowed s[1..4] := *; // error: this is not allowed s[2..3] := c; // error: this is not allowed } // --------------------- tests of restrictions on subranges (nat) method K() { var s: set; // error: not allowed to instantiate 'set' with 'nat' var d: MutuallyRecursiveDataType; // error: not allowed to instantiate with 'nat' var a := new nat[100]; // error: not allowed the type array var b := new nat[100,200]; // error: not allowed the type array2 } // --------------------- more ghost tests, for assign-such-that statements method M() { ghost var b: bool; ghost var k: int, l: int; var m: int; k :| k < 10; k, m :| 0 <= k < m; // error: LHS has non-ghost and RHS has ghost m :| m < 10; // Because of the ghost guard, these 'if' statements are ghost contexts, so only // assignments to ghosts are allowed. if (b) { k :| k < 10; // should be allowed k, l :| 0 <= k < l; // ditto } if (b) { m :| m < 10; // error: not allowed in ghost context k, m :| 0 <= k < m; // error: not allowed in ghost context } } ghost method GhostM() returns (x: int) { x :| true; // no problem (but there once was a problem with this case, where an error was generated for no reason) } // ------------------ cycles that could arise from proxy assignments --------- module ProxyCycles { datatype Dt = Ctor(X -> Dt) method M0() { var dt: Dt; var f := x => x; dt := Ctor(f); // error: cannot infer a type for f } method M1() { var dt: Dt; var f := x => x; dt := Ctor(f); // error: cannot infer a type for f } function method F(x: X): set method N() { var x; x := F(x); // error: cannot infer type for x } }