Skip to content

Commit

Permalink
Fix: Ability to use .Key as a constant name in datatypes and classes (d…
Browse files Browse the repository at this point in the history
…afny-lang#4423)

This PR fixes dafny-lang#4394
I added the corresponding test.

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>

---------

Co-authored-by: Rustan Leino <[email protected]>
  • Loading branch information
2 people authored and keyboardDrummer committed Sep 15, 2023
1 parent 6d93ff6 commit fddbdba
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
8 changes: 5 additions & 3 deletions Source/DafnyCore/Verifier/Translator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using static Microsoft.Dafny.Util;
using Core;
using Microsoft.BaseTypes;
using Microsoft.Dafny.Compilers;
using Microsoft.Dafny.Triggers;
using Action = System.Action;
using PODesc = Microsoft.Dafny.ProofObligationDescription;
Expand Down Expand Up @@ -6662,10 +6663,11 @@ Bpl.Function GetReadonlyField(Field f) {
return predef.ArrayLength;
} else if (f.EnclosingClass is ValuetypeDecl { Name: "real" } && f.Name == "Floor") {
return predef.RealFloor;
} else if (f is SpecialField && !(f is DatatypeDestructor)) {
} else if (f is SpecialField && !(f is DatatypeDestructor || f.EnclosingClass is TopLevelDeclWithMembers and not ValuetypeDecl)) {
if (f.Name is "Keys" or "Values" or "Items") {
Contract.Assert(f.Type is SetType);
var setType = (SetType)f.Type;
var fType = f.Type.NormalizeExpand();
Contract.Assert(fType is SetType);
var setType = (SetType)fType;
return f.Name switch {
"Keys" => setType.Finite ? predef.MapDomain : predef.IMapDomain,
"Values" => setType.Finite ? predef.MapValues : predef.IMapValues,
Expand Down
32 changes: 32 additions & 0 deletions Test/git-issues/git-issue-4394.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %baredafny verify %args "%s" > "%t"
// RUN: %diff "%s.expect" "%t"

datatype T = T(
f:map<nat,nat>
) {
const Keys := f.Keys // Used to be an error
}

codatatype codatatypeT = CT(
f:map<nat,nat>
) {
const Keys := f.Keys // Used to be an error
}

type opaqueT {
const f: map<nat, nat>
const Keys := f.Keys
}

newtype newT = x: int | true {
const f: map<nat, nat> := map[]
const Keys := f.Keys
}

class C {
const Keys: set<nat>

constructor(f:map<nat,nat>) {
this.Keys := f.Keys;
}
}
2 changes: 2 additions & 0 deletions Test/git-issues/git-issue-4394.dfy.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

Dafny program verifier finished with 1 verified, 0 errors
1 change: 1 addition & 0 deletions docs/dev/news/4394.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Ability to use .Key as a constant name in datatypes and classes

0 comments on commit fddbdba

Please sign in to comment.