Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Source/DafnyCore/AST/Expressions/Heap/WildcardExpr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class WildcardExpr : Expression, ICloneable<WildcardExpr> { // a Wildcar
public WildcardExpr(Cloner cloner, WildcardExpr original) : base(cloner, original) {
}

[SyntaxConstructor]
public WildcardExpr(IOrigin origin)
: base(origin) {
Contract.Requires(origin != null);
Expand Down
6 changes: 4 additions & 2 deletions Source/DafnyCore/AST/Statements/Verification/AssumeStmt.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using Microsoft.Dafny.Auditor;
Expand All @@ -12,7 +13,8 @@ public AssumeStmt Clone(Cloner cloner) {
public AssumeStmt(Cloner cloner, AssumeStmt original) : base(cloner, original) {
}

public AssumeStmt(IOrigin origin, Expression expr, Attributes attributes)
[SyntaxConstructor]
public AssumeStmt(IOrigin origin, Expression expr, Attributes? attributes)
: base(origin, expr, attributes) {
Contract.Requires(origin != null);
Contract.Requires(expr != null);
Expand Down Expand Up @@ -43,7 +45,7 @@ public override void GenResolve(INewOrOldResolver resolver, ResolutionContext co

public override void ResolveGhostness(ModuleResolver resolver, ErrorReporter reporter, bool mustBeErasable,
ICodeContext codeContext,
string proofContext, bool allowAssumptionVariables, bool inConstructorInitializationPhase) {
string? proofContext, bool allowAssumptionVariables, bool inConstructorInitializationPhase) {
IsGhost = true;
}
}
44 changes: 44 additions & 0 deletions Source/DafnyCore/AST/SyntaxDeserializer/Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,22 @@ public CharLiteralExpr ReadCharLiteralExprOption()
return ReadCharLiteralExpr();
}

public WildcardExpr ReadWildcardExpr()
{
var parameter0 = ReadAbstract<IOrigin>();
return new WildcardExpr(parameter0);
}

public WildcardExpr ReadWildcardExprOption()
{
if (ReadIsNull())
{
return default;
}

return ReadWildcardExpr();
}

public UnchangedExpr ReadUnchangedExpr()
{
var parameter0 = ReadAbstract<IOrigin>();
Expand Down Expand Up @@ -587,6 +603,24 @@ public ExpectStmt ReadExpectStmtOption()
return ReadExpectStmt();
}

public AssumeStmt ReadAssumeStmt()
{
var parameter0 = ReadAbstract<IOrigin>();
var parameter2 = ReadAttributesOption();
var parameter1 = ReadAbstract<Expression>();
return new AssumeStmt(parameter0, parameter1, parameter2);
}

public AssumeStmt ReadAssumeStmtOption()
{
if (ReadIsNull())
{
return default;
}

return ReadAssumeStmt();
}

public AssertStmt ReadAssertStmt()
{
var parameter0 = ReadAbstract<IOrigin>();
Expand Down Expand Up @@ -2319,6 +2353,11 @@ private object ReadObject(System.Type actualType)
return ReadCharLiteralExpr();
}

if (actualType == typeof(WildcardExpr))
{
return ReadWildcardExpr();
}

if (actualType == typeof(UnchangedExpr))
{
return ReadUnchangedExpr();
Expand Down Expand Up @@ -2394,6 +2433,11 @@ private object ReadObject(System.Type actualType)
return ReadExpectStmt();
}

if (actualType == typeof(AssumeStmt))
{
return ReadAssumeStmt();
}

if (actualType == typeof(AssertStmt))
{
return ReadAssertStmt();
Expand Down
3 changes: 2 additions & 1 deletion Source/DafnyCore/Resolver/ModuleResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1696,7 +1696,8 @@ private void ComputeGhostInterestAndMisc(List<TopLevelDecl> declarations) {

private void CheckForCyclesAmongRedirectingTypes(RedirectingTypeDecl dd, HashSet<ICallable> cycleErrorHasBeenReported) {
var enclosingModule = dd.EnclosingModule;
if (enclosingModule.CallGraph.GetSCCSize(dd) != 1) {
if (enclosingModule.CallGraph.GetSCCSize(dd) != 1 ||
enclosingModule.CallGraph.FindVertex(dd).Successors.Any(v => v.N == dd)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand this line. In fact, if I remove it, the new test example still goes through.

This line looks to me as if it would be true for any SCC of size 1. If so, this if condition would always be true. Here's my reasoning: If the SCC where dd is has size 1, then the only successor of dd is dd itself.

If you think this line is necessary, please add a comment describing what it does.

var r = enclosingModule.CallGraph.GetSCCRepresentative(dd);
if (cycleErrorHasBeenReported.Contains(r)) {
// An error has already been reported for this cycle, so don't report another.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4222,15 +4222,14 @@ public ResolveTypeReturn ResolveTypeLenient(IOrigin tok, Type type, ResolutionCo
t.ResolvedClass = d; // Store the decl, so the compiler will generate the fully qualified name
} else if (d is RedirectingTypeDecl) {
var dd = (RedirectingTypeDecl)d;
var caller = CodeContextWrapper.Unwrap(resolutionContext.CodeContext) as ICallable;
if (caller != null && !(d is SubsetTypeDecl && caller is SpecialFunction)) {
if (caller != d) {
} else if (d is TypeSynonymDecl && !(d is SubsetTypeDecl)) {
// detect self-loops here, since they don't show up in the graph's SCC methods
reporter.Error(MessageSource.Resolver, d.Origin, "type-synonym cycle: {0} -> {0}", d.Name);
} else {
// detect self-loops here, since they don't show up in the graph's SCC methods
reporter.Error(MessageSource.Resolver, d.Origin, "recursive constraint dependency involving a {0}: {1} -> {1}", d.WhatKind, d.Name);
var parent = CodeContextWrapper.Unwrap(resolutionContext.CodeContext) as ICallable;
if (parent != null && !(d is SubsetTypeDecl && parent is SpecialFunction)) {
var cycleFound = parent == d;
if (cycleFound) {
if (d is TypeSynonymDecl && !(d is SubsetTypeDecl)) {
// detect self-loops here, since they don't show up in the graph's SCC methods
reporter.Error(MessageSource.Resolver, d.Origin, "type-synonym cycle: {0} -> {0}", d.Name);
}
Comment on lines +4229 to +4232
Copy link
Collaborator

Choose a reason for hiding this comment

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

With this change, you have removed one of the recursive constraint dependency error messages. But there must be more places in the code that generate it. Case in point: the cycles.dfy test case (below) generates such a message.

As I will argue (in a comment that I'm about to post on the PR), I think we should remove those messages, too.

(But we do need to still check for cycles that consist solely of type synonyms, as you still do here on LL 4229-4232.)

}
}
t.ResolvedClass = d;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: ! %testDafnyForEachResolver "%s" -- --allow-axioms=false

type Even = x: int | x % 2 == 0
opaque const ten: Even := 10

const twoHundred: LessThanTwoHundred := 200
type LessThanTwoHundred = k | 0 <= k < twoHundred

const twoHundred_2: LessThanHundredNinetyNine := 200
const hundredNinetyNine: int := twoHundred_2 as int - 1
type LessThanHundredNinetyNine = k | 0 <= k < hundredNinetyNine
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
constResolution.dfy(7,5): Error: recursive constraint dependency involving a subset type: LessThanTwoHundred -> twoHundred -> LessThanTwoHundred
constResolution.dfy(11,5): Error: recursive constraint dependency involving a subset type: LessThanHundredNinetyNine -> hundredNinetyNine -> twoHundred_2 -> LessThanHundredNinetyNine
2 resolution/type errors detected in constResolution.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: ! %verify --type-system-refresh --general-traits=datatype %s &> "%t"
// RUN: %diff "%s.expect" "%t"

datatype Stmt =
| Skip
| Block(stmts: seq<Stmt>)
| If(b: bool, thn: BlockStmt, els: BlockStmt)

type BlockStmt = s: Stmt | s.Block? witness Block([])
Comment on lines +4 to +9
Copy link
Collaborator

Choose a reason for hiding this comment

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

Great example! (I think you got this from me. :)) But I would like to see this program go through. The cycles.dfy.expect file below shows that an error is still generated for this program.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cycles.dfy(9,5): Error: recursive constraint dependency involving a subset type: BlockStmt -> Stmt -> BlockStmt
1 resolution/type errors detected in cycles.dfy
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %verify --type-system-refresh --general-traits=datatype %s &> "%t"
// RUN: %diff "%s.expect" "%t"

trait SelfConstraintDep<T extends SelfConstraintDep<T>> {}
trait SelfConstraintDep2<T extends SelfConstraintDep2<T>> extends object {}

datatype D extends SelfConstraintDep<D> = D {}
class C extends SelfConstraintDep2<C> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

Dafny program verifier finished with 0 verified, 0 errors
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,13 @@ GeneralNewtypeResolution.dfy(927,4): Error: type parameter 'ZZ' is not allowed t
GeneralNewtypeResolution.dfy(932,5): Error: type parameter 'A' is not allowed to change variance (here, from '+' to '-')
GeneralNewtypeResolution.dfy(933,5): Error: type parameter 'B' is not allowed to change variance (here, from '=' to '+')
GeneralNewtypeResolution.dfy(934,4): Error: type parameter 'C' is not allowed to change variance (here, from '-' to '=')
GeneralNewtypeResolution.dfy(940,10): Error: recursive constraint dependency involving a newtype: A -> A
GeneralNewtypeResolution.dfy(945,10): Error: recursive constraint dependency involving a newtype: A -> A
GeneralNewtypeResolution.dfy(939,10): Error: a newtype ('W') must be based on some numeric type (got X)
GeneralNewtypeResolution.dfy(940,10): Error: Cyclic dependency among declarations: A -> A
Copy link
Collaborator

Choose a reason for hiding this comment

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

A recent change in Dafny was to make verification error messages more consistent. I believe those verification error messages now start with a lower-case letter. I'm not suggesting we change all resolution errors the same way (or at least not in this PR), but I think it would be nice to change this one.

GeneralNewtypeResolution.dfy(944,10): Error: a newtype ('W') must be based on some numeric type (got X)
GeneralNewtypeResolution.dfy(945,10): Error: Cyclic dependency among declarations: A -> A
GeneralNewtypeResolution.dfy(950,7): Error: type-synonym cycle: A -> A
GeneralNewtypeResolution.dfy(955,10): Error: recursive constraint dependency involving a newtype: A -> A
197 resolution/type errors detected in GeneralNewtypeResolution.dfy
GeneralNewtypeResolution.dfy(955,10): Error: Cyclic dependency among declarations: A -> A
199 resolution/type errors detected in GeneralNewtypeResolution.dfy
GeneralNewtypeResolution.dfy(34,10): Error: a newtype ('MyOrdinal') must be based on some non-reference, non-trait, non-arrow, non-ORDINAL, non-datatype type (got ORDINAL)
GeneralNewtypeResolution.dfy(40,10): Error: a newtype ('MyObject') must be based on some non-reference, non-trait, non-arrow, non-ORDINAL, non-datatype type (got object)
GeneralNewtypeResolution.dfy(41,10): Error: a newtype ('MyTrait') must be based on some non-reference, non-trait, non-arrow, non-ORDINAL, non-datatype type (got Trait)
Expand Down Expand Up @@ -355,8 +357,8 @@ GeneralNewtypeResolution.dfy(927,4): Error: type parameter 'ZZ' is not allowed t
GeneralNewtypeResolution.dfy(932,5): Error: type parameter 'A' is not allowed to change variance (here, from '+' to '-')
GeneralNewtypeResolution.dfy(933,5): Error: type parameter 'B' is not allowed to change variance (here, from '=' to '+')
GeneralNewtypeResolution.dfy(934,4): Error: type parameter 'C' is not allowed to change variance (here, from '-' to '=')
GeneralNewtypeResolution.dfy(940,10): Error: recursive constraint dependency involving a newtype: A -> A
GeneralNewtypeResolution.dfy(945,10): Error: recursive constraint dependency involving a newtype: A -> A
GeneralNewtypeResolution.dfy(940,10): Error: Cyclic dependency among declarations: A -> A
GeneralNewtypeResolution.dfy(945,10): Error: Cyclic dependency among declarations: A -> A
GeneralNewtypeResolution.dfy(950,7): Error: type-synonym cycle: A -> A
GeneralNewtypeResolution.dfy(955,10): Error: recursive constraint dependency involving a newtype: A -> A
GeneralNewtypeResolution.dfy(955,10): Error: Cyclic dependency among declarations: A -> A
162 resolution/type errors detected in GeneralNewtypeResolution.dfy
8 changes: 8 additions & 0 deletions Source/Scripts/Syntax.cs-schema
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ class CharLiteralExpr : LiteralExpr
{
}

class WildcardExpr : Expression
{
}

class UnchangedExpr : Expression
{
List<FrameExpression> frame;
Expand Down Expand Up @@ -313,6 +317,10 @@ class ExpectStmt : PredicateStmt
Expression? message;
}

class AssumeStmt : PredicateStmt
{
}

class AssertStmt : PredicateStmt
{
AssertLabel? label;
Expand Down
Loading