Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Rust operators and immutable collections #5081

Merged
merged 103 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
0628309
Added initial tests to support allocation
MikaelMayer Dec 21, 2023
7649600
Implemented codatatypes
MikaelMayer Dec 21, 2023
06c65ba
Sequences now defined. Only need to define more methods
MikaelMayer Dec 22, 2023
5fc5bf4
Support for traits and mutable variables without dynamic dispatch(?)
MikaelMayer Dec 22, 2023
b72cec9
Arguments always borrowed, deallocation more general now
MikaelMayer Dec 25, 2023
c2f8b24
Conversion to/from Rust strings, better handling of is_string
MikaelMayer Dec 26, 2023
bed8f90
Got rid of DafnyClone
MikaelMayer Dec 26, 2023
79f1503
Immutable lazy maps
MikaelMayer Dec 26, 2023
4b0fae7
Support to subtype testing
MikaelMayer Dec 27, 2023
754022c
Make sure StreamReaders are closed after use
MikaelMayer Dec 27, 2023
22a2897
Formatting fix 2
MikaelMayer Dec 27, 2023
ae3081c
Needed to updated GeneratedFromDafny apparently
MikaelMayer Dec 27, 2023
705b1ca
Aligning with existing runtime
MikaelMayer Dec 27, 2023
13defc6
More idiomatic rust identifiers, started to deal with indentation
MikaelMayer Dec 27, 2023
ded93a3
Allow dead code + finished all trivial impl
MikaelMayer Dec 27, 2023
70e1dcf
Added standard library
MikaelMayer Dec 27, 2023
6c6236a
Support for subset of standard libraries
MikaelMayer Dec 28, 2023
aa3e84a
much better Rust output
MikaelMayer Dec 28, 2023
eccae5e
Proof that ID encoding is bijective so that there is no collision
MikaelMayer Dec 30, 2023
5ba5c93
Constant initialization for datatypes and tests with closures
MikaelMayer Jan 10, 2024
c7fb7c0
Merge branch 'master' into feat-rust
MikaelMayer Jan 10, 2024
770da14
Fixed the merge build
MikaelMayer Jan 10, 2024
70732a7
Set and print
MikaelMayer Jan 17, 2024
b09c1a0
Ongoing work
MikaelMayer Jan 18, 2024
21a0074
Ensure we don't mess up with the system
MikaelMayer Jan 18, 2024
a2ef3f8
Fixed the build
MikaelMayer Jan 19, 2024
9704661
Better reporting
MikaelMayer Jan 22, 2024
58229de
Simplified a bit
MikaelMayer Jan 23, 2024
43c60ae
Removed useless interfaces in lib.rs
MikaelMayer Jan 24, 2024
ec7188a
Newtype decls now fully erase, support for 128 bit operations
MikaelMayer Jan 29, 2024
136b368
Many map and set operations implemented
MikaelMayer Feb 1, 2024
3cacd1f
Removed mod.rs
MikaelMayer Feb 5, 2024
eaad5be
Operators working till maps
MikaelMayer Feb 5, 2024
71f2a08
Support for set and set operations
MikaelMayer Feb 7, 2024
2c1e7ee
Merge branch 'master' into feat-rust
MikaelMayer Feb 7, 2024
42f3bd3
Comprehensive tests
MikaelMayer Feb 12, 2024
7e4457c
Operators file updated
MikaelMayer Feb 12, 2024
541d9fe
Merge branch 'master' into feat-rust-operators
MikaelMayer Feb 13, 2024
bc6ef02
Fixed the rust test
MikaelMayer Feb 13, 2024
70d95d5
Fix the CI build
MikaelMayer Feb 13, 2024
e715090
Started to add checks to multibackends using Rust
MikaelMayer Feb 14, 2024
2ede243
Merge branch 'master' into feat-rust
MikaelMayer Feb 14, 2024
6d825fb
Merge branch 'master' into feat-rust-operators
MikaelMayer Feb 20, 2024
a4bbd0e
Review comments
MikaelMayer Feb 20, 2024
dca95f9
Extract branch here: A check file for every rust test that does not pass
MikaelMayer Feb 20, 2024
1a0c3f5
Merge branch 'feat-rust-test-monitor' into feat-rust-operators
MikaelMayer Feb 20, 2024
31c4a31
Review comments
MikaelMayer Feb 26, 2024
ab90d9d
Merge branch 'master' into feat-rust-operators
MikaelMayer Feb 26, 2024
a85a31c
Fixed the merge
MikaelMayer Feb 26, 2024
b361f98
Merge branch 'master' into feat-rust-operators
MikaelMayer Feb 26, 2024
84a280c
Review comments
MikaelMayer Apr 4, 2024
bce6df2
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 4, 2024
79d9767
Fixed the merge commit
MikaelMayer Apr 4, 2024
ec471f7
Added new option to set of options not needing a check for the doo file
MikaelMayer Apr 4, 2024
805628d
Fixed CI tests
MikaelMayer Apr 5, 2024
f204d29
Fixed CI Tests
MikaelMayer Apr 8, 2024
6af66d2
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 8, 2024
fc489c7
whitespace
MikaelMayer Apr 8, 2024
450c34c
Updated Options.txt
MikaelMayer Apr 8, 2024
5b47e79
Added release helper
MikaelMayer Apr 8, 2024
2c734f4
Refactoring to reduce brittleness
MikaelMayer Apr 8, 2024
0de8444
Fixed CI tests
MikaelMayer Apr 8, 2024
084fd8f
Formatted dfy code
MikaelMayer Apr 8, 2024
fca0a64
Ensure tests works for ResolvedDesugaredExecutableDafnyBackend
MikaelMayer Apr 9, 2024
48bb366
Ensure feature descriptions are still accurate
MikaelMayer Apr 10, 2024
231b877
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 10, 2024
a667a51
Fixed a name
MikaelMayer Apr 10, 2024
2f2a34a
Ensured tests on unsupported code behave the same
MikaelMayer Apr 10, 2024
77d6fc0
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 10, 2024
8dd3e91
Added unsupported feature
MikaelMayer Apr 10, 2024
591a108
Added one more unsupported feature
MikaelMayer Apr 10, 2024
7df7a43
Fixed one more CI test
MikaelMayer Apr 10, 2024
ab8713f
Fixed a few test cases
MikaelMayer Apr 11, 2024
5c507ee
Updated hopefully last tests
MikaelMayer Apr 11, 2024
9d84841
Fixed the last test
MikaelMayer Apr 11, 2024
e06ba55
Increased code coverage
MikaelMayer Apr 11, 2024
974a622
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 11, 2024
978de94
Ensure we generate code that is not specific to Windows
MikaelMayer Apr 11, 2024
494ec95
GeneratedFromDafny now splits files in different namespaces.
MikaelMayer Apr 11, 2024
6185aea
Restored formatting
MikaelMayer Apr 11, 2024
7262e2e
Formatted Dafny file
MikaelMayer Apr 11, 2024
2388a16
Increased coverage and refactored coverage to another dafny file
MikaelMayer Apr 12, 2024
2ba549f
Moved coverage code to DafnyCore.Test
MikaelMayer Apr 12, 2024
927e0ce
formatting
MikaelMayer Apr 12, 2024
b8fa9be
Fixed generation
MikaelMayer Apr 12, 2024
ae9c6a5
formatting
MikaelMayer Apr 13, 2024
8fa13f8
reverted wrong formatting
MikaelMayer Apr 13, 2024
9fa45e9
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 13, 2024
b08160e
Update docs/DafnyRef/integration- rust/IntegrationRust.md
MikaelMayer Apr 17, 2024
7a1112b
Review comments
MikaelMayer Apr 17, 2024
428edc1
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 17, 2024
ff40edc
formatting
MikaelMayer Apr 17, 2024
628f55b
Revert "formatting"
MikaelMayer Apr 17, 2024
dc3e8eb
Fixed the format command.
MikaelMayer Apr 17, 2024
bd632f5
Fixed CI Tests
MikaelMayer Apr 17, 2024
04f055e
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 17, 2024
1adb784
emitUncompilableCode using the new CLI option format
MikaelMayer Apr 17, 2024
4b9323e
Merge branch 'feat-rust-operators' of https://github.com/dafny-lang/d…
MikaelMayer Apr 17, 2024
0787071
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 19, 2024
d160b19
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 19, 2024
94060a0
Merge branch 'master' into feat-rust-operators
MikaelMayer Apr 25, 2024
ea057e3
Addressing CI failures
MikaelMayer Apr 26, 2024
71f9e96
Missing check files
MikaelMayer Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
repos:
- repo: local
hooks:
- id: dotnet-format
name: dotnet-format
language: system
entry: dotnet format whitespace Source/Dafny.sln --include
types_or: ["c#"]
# hooks:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporary or do you mean to disable it? If the latter we should delete the file entirely

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't get this command to exclude GeneratedFromDafny.cs. It's the only generated file, and formatting it every time way too much time. So I would happily keep this pre-commit if we found a way to remove GeneratedFromDafny, but I haven't found any yet. In need for help here.

# - id: dotnet-format
# name: dotnet-format
# language: system
# entry: dotnet format whitespace Source/Dafny.sln -v:d --exclude Source/DafnyCore/GeneratedFromDafny.cs --include
# types_or: ["c#"]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dfyprod: dfyprodformat dfyprodinit
(cd "${DIR}" ; dotnet build Source/Dafny.sln ) ## includes parser

dfydevinit:
(cd "${DIR}"/Source/DafnyCore ; bash DafnyGeneratedFromDafny.sh --no-verify --no-format)
(cd "${DIR}"/Source/DafnyCore ; bash DafnyGeneratedFromDafny.sh --no-verify)

dfydev: dfydevinit
(cd "${DIR}" ; dotnet build Source/Dafny.sln ) ## includes parser
Expand Down
3 changes: 3 additions & 0 deletions Source/DafnyCore/AST/Expressions/Variables/IVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ string UniqueName {
string SanitizedName {
get;
}
string SanitizedNameShadowable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth a comment what this is for

get;
}
string CompileName {
get;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ public string SanitizedName {
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
}

public string SanitizedNameShadowable {
get {
Contract.Ensures(Contract.Result<string>() != null);
throw new NotImplementedException(); // this getter implementation is here only so that the Ensures contract can be given here
}
}
public string CompileName {
get {
Contract.Ensures(Contract.Result<string>() != null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,14 @@ public static string SanitizeName(string nm) {
}
}

private string sanitizedNameShadowable;

public virtual string SanitizedNameShadowable =>
sanitizedNameShadowable ??= SanitizeName(Name);

private string sanitizedName;
public virtual string SanitizedName =>
sanitizedName ??= $"_{IVariable.CompileNameIdGenerator.FreshNumericId()}_{SanitizeName(Name)}";
sanitizedName ??= $"_{IVariable.CompileNameIdGenerator.FreshNumericId()}_{SanitizedNameShadowable}";

protected string compileName;
public virtual string CompileName =>
Expand Down
8 changes: 7 additions & 1 deletion Source/DafnyCore/AST/Statements/Assignment/LocalVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,15 @@ public string AssignUniqueName(FreshIdGenerator generator) {
return uniqueName ??= generator.FreshId(Name + "#");
}

private string sanitizedNameShadowable;

public string SanitizedNameShadowable =>
sanitizedNameShadowable ??= NonglobalVariable.SanitizeName(Name);

private string sanitizedName;

public string SanitizedName =>
sanitizedName ??= $"_{IVariable.CompileNameIdGenerator.FreshNumericId()}_{NonglobalVariable.SanitizeName(Name)}";
sanitizedName ??= $"_{IVariable.CompileNameIdGenerator.FreshNumericId()}_{SanitizedNameShadowable}";

string compileName;
public string CompileName =>
Expand Down
2 changes: 1 addition & 1 deletion Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public class NativeType {
public readonly BigInteger LowerBound;
public readonly BigInteger UpperBound;
public readonly int Bitwidth; // for unassigned types, this shows the number of bits in the type; else is 0
public enum Selection { Byte, SByte, UShort, Short, UInt, Int, Number, ULong, Long }
public enum Selection { Byte, SByte, UShort, Short, UInt, Int, Number, ULong, Long, UDoubleLong, DoubleLong }
public readonly Selection Sel;
public NativeType(string Name, BigInteger LowerBound, BigInteger UpperBound, int bitwidth, Selection sel) {
Contract.Requires(Name != null);
Expand Down
7 changes: 4 additions & 3 deletions Source/DafnyCore/Compilers/CSharp/Compiler-Csharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3387,15 +3387,16 @@ protected override ConcreteSyntaxTree EmitMapBuilder_Add(MapType mt, IToken tok,
return termLeftWriter;
}

protected override string GetCollectionBuilder_Build(CollectionType ct, IToken tok, string collName, ConcreteSyntaxTree wr) {
protected override void GetCollectionBuilder_Build(CollectionType ct, IToken tok, string collName,
ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmt) {
if (ct is SetType) {
var typeName = TypeName(ct.Arg, wr, tok);
return string.Format($"{DafnySetClass}<{typeName}>.FromCollection({collName})");
wr.Write(string.Format($"{DafnySetClass}<{typeName}>.FromCollection({collName})"));
} else if (ct is MapType) {
var mt = (MapType)ct;
var domtypeName = TypeName(mt.Domain, wr, tok);
var rantypeName = TypeName(mt.Range, wr, tok);
return $"{DafnyMapClass}<{domtypeName},{rantypeName}>.FromCollection({collName})";
wr.Write($"{DafnyMapClass}<{domtypeName},{rantypeName}>.FromCollection({collName})");
} else {
Contract.Assume(false); // unexpected collection type
throw new cce.UnreachableException(); // please compiler
Expand Down
5 changes: 3 additions & 2 deletions Source/DafnyCore/Compilers/Cplusplus/Compiler-cpp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2444,9 +2444,10 @@ protected override ConcreteSyntaxTree EmitMapBuilder_Add(MapType mt, IToken tok,
throw new UnsupportedFeatureException(tok, Feature.MapComprehensions);
}

protected override string GetCollectionBuilder_Build(CollectionType ct, IToken tok, string collName, ConcreteSyntaxTree wr) {
protected override void GetCollectionBuilder_Build(CollectionType ct, IToken tok, string collName,
ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmt) {
// collections are built in place
return collName;
wr.Write(collName);
}

protected override void EmitSingleValueGenerator(Expression e, bool inLetExprBody, string type,
Expand Down
68 changes: 58 additions & 10 deletions Source/DafnyCore/Compilers/Dafny/AST.dfy
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
module {:extern "DAST.Format"} DAST.Format
/* Cues about how to format different AST elements if necessary,
e.g. to generate idiomatic code when needed. */
{
// Dafny AST compilation tenets:
// - The Compiled Dafny AST should be minimal
// - The generated code should look idiomatic and close to the original Dafny file if possible
// Since the two might conflict, the second one is taken care of by adding formatting information

datatype UnOpFormat =
NoFormat()
| CombineNotInner()
datatype BinOpFormat =
NoFormat()
| ImpliesFormat()
| Equivalence()
| ReverseOperands()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NoFormat()
| CombineNotInner()
datatype BinOpFormat =
NoFormat()
| ImpliesFormat()
| Equivalence()
| ReverseOperands()
| NoFormat
| CombineNotInner
datatype BinOpFormat =
| NoFormat
| ImpliesFormat
| Equivalence
| ReverseOperands

(minor style nit, feel free to debate :)

}

module {:extern "DAST"} DAST {
import opened Std.Wrappers

Expand All @@ -19,13 +38,22 @@ module {:extern "DAST"} DAST {
Set(element: Type) |
Multiset(element: Type) |
Map(key: Type, value: Type) |
SetBuilder(element: Type) |
MapBuilder(key: Type, value: Type) |
Arrow(args: seq<Type>, result: Type) |
Primitive(Primitive) | Passthrough(string) |
TypeArg(Ident)

datatype Primitive = Int | Real | String | Bool | Char

datatype ResolvedType = Datatype(path: seq<Ident>) | Trait(path: seq<Ident>) | Newtype(Type)
datatype NewtypeRange =
| U8 | I8 | U16 | I16 | U32 | I32 | U64 | I64 | U128 | I128 | BigInt
| NoRange

datatype ResolvedType =
| Datatype(path: seq<Ident>)
| Trait(path: seq<Ident>)
| Newtype(baseType: Type, range: NewtypeRange, erase: bool)

datatype Ident = Ident(id: string)

Expand All @@ -37,7 +65,7 @@ module {:extern "DAST"} DAST {

datatype DatatypeCtor = DatatypeCtor(name: string, args: seq<Formal>, hasAnyArgs: bool /* includes ghost */)

datatype Newtype = Newtype(name: string, typeParams: seq<Type>, base: Type, witnessStmts: seq<Statement>, witnessExpr: Option<Expression>)
datatype Newtype = Newtype(name: string, typeParams: seq<Type>, base: Type, range: NewtypeRange, witnessStmts: seq<Statement>, witnessExpr: Option<Expression>)

datatype ClassItem = Method(Method)

Expand All @@ -47,14 +75,18 @@ module {:extern "DAST"} DAST {

datatype Method = Method(isStatic: bool, hasBody: bool, overridingPath: Option<seq<Ident>>, name: string, typeParams: seq<Type>, params: seq<Formal>, body: seq<Statement>, outTypes: seq<Type>, outVars: Option<seq<Ident>>)

datatype CallName =
Name(name: string) |
MapBuilderAdd | MapBuilderBuild | SetBuilderAdd | SetBuilderBuild

datatype Statement =
DeclareVar(name: string, typ: Type, maybeValue: Option<Expression>) |
Assign(lhs: AssignLhs, value: Expression) |
If(cond: Expression, thn: seq<Statement>, els: seq<Statement>) |
Labeled(lbl: string, body: seq<Statement>) |
While(cond: Expression, body: seq<Statement>) |
Foreach(boundName: string, boundType: Type, over: Expression, body: seq<Statement>) |
Call(on: Expression, name: string, typeArgs: seq<Type>, args: seq<Expression>, outs: Option<seq<Ident>>) |
Call(on: Expression, callName: CallName, typeArgs: seq<Type>, args: seq<Expression>, outs: Option<seq<Ident>>) |
Return(expr: Expression) |
EarlyReturn() |
Break(toLabel: Option<string>) |
Expand All @@ -72,13 +104,21 @@ module {:extern "DAST"} DAST {

datatype BinOp =
Eq(referential: bool, nullable: bool) |
Neq(referential: bool, nullable: bool) |
Div() | EuclidianDiv() |
Mod() | EuclidianMod() |
Implies() | // TODO: REplace by Not Or
Lt() | // a <= b is !(b < a)
LtChar() |
Plus() | Minus() | Times() |
BitwiseAnd() | BitwiseOr() | BitwiseXor() |
BitwiseShiftRight() | BitwiseShiftLeft() |
And() | Or() |
In() |
NotIn() | // TODO: Replace by Not In
SetDifference() |
SeqProperPrefix() | SeqPrefix() |
SetMerge() | SetSubtraction() | SetIntersection() |
Subset() | ProperSubset() | SetDisjoint() |
MapMerge() | MapSubtraction() |
MultisetMerge() | MultisetSubtraction() | MultisetIntersection() |
Submultiset() | ProperSubmultiset() | MultisetDisjoint() |
Concat() |
Passthrough(string)

Expand All @@ -94,18 +134,26 @@ module {:extern "DAST"} DAST {
SeqConstruct(length: Expression, elem: Expression) |
SeqValue(elements: seq<Expression>, typ: Type) |
SetValue(elements: seq<Expression>) |
MultisetValue(elements: seq<Expression>) |
MapValue(mapElems: seq<(Expression, Expression)>) |
MapBuilder(keyType: Type, valueType: Type) |
SeqUpdate(expr: Expression, indexExpr: Expression, value: Expression) |
MapUpdate(expr: Expression, indexExpr: Expression, value: Expression) |
SetBuilder(elemType: Type) |
ToMultiset(Expression) |
This() |
Ite(cond: Expression, thn: Expression, els: Expression) |
UnOp(unOp: UnaryOp, expr: Expression) |
BinOp(op: BinOp, left: Expression, right: Expression) |
UnOp(unOp: UnaryOp, expr: Expression, format1: Format.UnOpFormat) |
BinOp(op: BinOp, left: Expression, right: Expression, format2: Format.BinOpFormat) |
ArrayLen(expr: Expression, dim: nat) |
MapKeys(expr: Expression) |
MapValues(expr: Expression) |
Select(expr: Expression, field: string, isConstant: bool, onDatatype: bool) |
SelectFn(expr: Expression, field: string, onDatatype: bool, isStatic: bool, arity: nat) |
Index(expr: Expression, collKind: CollKind, indices: seq<Expression>) |
IndexRange(expr: Expression, isArray: bool, low: Option<Expression>, high: Option<Expression>) |
TupleSelect(expr: Expression, index: nat) |
Call(on: Expression, name: Ident, typeArgs: seq<Type>, args: seq<Expression>) |
Call(on: Expression, callName: CallName, typeArgs: seq<Type>, args: seq<Expression>) |
Lambda(params: seq<Formal>, retType: Type, body: seq<Statement>) |
BetaRedex(values: seq<(Formal, Expression)>, retType: Type, expr: Expression) |
IIFE(name: Ident, typ: Type, value: Expression, iifeBody: Expression) |
Expand Down
Loading
Loading