diff --git a/Source/DafnyCore/Backends/SinglePassCodeGenerator/SinglePassCodeGenerator.cs b/Source/DafnyCore/Backends/SinglePassCodeGenerator/SinglePassCodeGenerator.cs index 0eb5240b5a8..424be425fba 100644 --- a/Source/DafnyCore/Backends/SinglePassCodeGenerator/SinglePassCodeGenerator.cs +++ b/Source/DafnyCore/Backends/SinglePassCodeGenerator/SinglePassCodeGenerator.cs @@ -576,7 +576,9 @@ protected virtual void EmitSetterParameter(ConcreteSyntaxTree wr) { protected virtual void EmitReturnExpr(Expression expr, Type resultType, bool inLetExprBody, ConcreteSyntaxTree wr) { // emits "return ;" for function bodies var wStmts = wr.Fork(); var w = EmitReturnExpr(wr); - EmitExpr(expr, inLetExprBody, EmitCoercionIfNecessary(expr.Type, resultType, null, w), wStmts); + w = EmitCoercionIfNecessary(expr.Type, resultType, expr.tok, w); + w = EmitDowncastIfNecessary(expr.Type, resultType, expr.tok, w); + EmitExpr(expr, inLetExprBody, w, wStmts); } protected virtual void EmitReturnExpr(string returnExpr, ConcreteSyntaxTree wr) { // emits "return ;" for function bodies var w = EmitReturnExpr(wr); @@ -2868,7 +2870,8 @@ void TrCasePatternOpt(CasePattern pat, Expression rhs, Action := m; v; // regression test -- this once tripped up the compilation to Java, whereas the next line had not s' := var u: set := var v: set := m; v; u; - var eq := s == m && m == s; + var s'' := DowncastFunction(a, b); // regression test -- the same error was later discovered in top-level function bodies + var eq := s == m && m == s && s == s''; print eq, "\n"; // true s := FId(m); // cast in @@ -367,6 +368,12 @@ method Create(a: T, b: T) returns (m: set, n: multiset, o: seq, p: m p := map[a := b, b := a]; } +function DowncastFunction(a: Integer, b: Integer): set { + var m: set := {a, b}; + var v: set := m; + v +} + function DowncastF(s: set): set { s } method DowncastM(s: set) returns (r: set) ensures r == s diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-5597.dfy b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-5597.dfy new file mode 100644 index 00000000000..a8de65a62c0 --- /dev/null +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-5597.dfy @@ -0,0 +1,51 @@ +// RUN: %testDafnyForEachCompiler "%s" + +method Main() { + var n: set := {}; + var s: set; + s := DoItWithAssignment(n); + print |s|, " "; + s := DoItWithPlainLet(n); + print |s|, " "; + s := DoItWithOptimizedLet(n); + print |s|, " "; + s := DoItViaFunctionBodyResult(n); + print |s|, "\n"; +} + +trait Number { + const value: int +} + +class Integer extends Number { + constructor(value: int) { + this.value := value; + } +} + +method DoItWithAssignment(numbers: set) returns (integers00: set) + requires |numbers| == 0 +{ + integers00 := numbers; +} + +function DoItWithPlainLet(numbers: set): set + requires |numbers| == 0 +{ + {} + + var integers11: set := numbers; + integers11 +} + +function DoItWithOptimizedLet(numbers: set): set + requires |numbers| == 0 +{ + var integers22: set := numbers; + integers22 +} + +function DoItViaFunctionBodyResult(numbers: set): set + requires |numbers| == 0 +{ + numbers +} diff --git a/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-5597.dfy.expect b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-5597.dfy.expect new file mode 100644 index 00000000000..6a20ce40185 --- /dev/null +++ b/Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-5597.dfy.expect @@ -0,0 +1 @@ +0 0 0 0