-
Notifications
You must be signed in to change notification settings - Fork 263
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: Generate a warning when 'old' has no effect #2610
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
0881783
snapshot
RustanLeino a341eca
Enhance two-state detection in resolver
RustanLeino c35603d
chore: Improve code to use modern C#
RustanLeino b50a6f8
fix: Use old heap in StmtExpr inside old
RustanLeino 2dae005
fix: Check well-definedness of forall-ensures
RustanLeino ad59a9c
Update PR number in release notes
RustanLeino 6f25adb
Merge branch 'master' into issue-2605
RustanLeino 8a3949d
Merge branch 'master' into issue-2597
RustanLeino 9127e05
Merge branch 'issue-2605' into issue-2597
RustanLeino d819bf1
Add test, now that 2605 is fixed
RustanLeino 5395c68
Add release notes
RustanLeino 5da653f
Update tests
RustanLeino e329d6a
Adjusts tests and answers
RustanLeino 1d6b5f7
Add method to iterate over all expressions, even those in substatements
RustanLeino 0434f90
Update concurrency tests
RustanLeino 3216743
Update release notes
RustanLeino f4f26b6
Update release notes
RustanLeino 439bd1e
Merge branch 'issue-2597' into issue-1989
RustanLeino 3d5f5fb
Merge branch 'master' into issue-1989
RustanLeino 5651f86
Add .expect file
RustanLeino db755a2
Merge branch 'master' into issue-1989
RustanLeino 97cfb00
Merge branch 'master' into issue-1989
RustanLeino c3f6ebb
Merge branch 'master' into issue-1989
keyboardDrummer bfc3d61
Merge branch 'master' into issue-1989
RustanLeino a526739
Rename Linter to something more specific
RustanLeino 2f75116
Merge branch 'master' into issue-1989
RustanLeino 8b88899
Merge branch 'master' into issue-1989
keyboardDrummer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//----------------------------------------------------------------------------- | ||
// | ||
// Copyright (C) Microsoft Corporation. All Rights Reserved. | ||
// Copyright by the contributors to the Dafny Project | ||
// SPDX-License-Identifier: MIT | ||
// | ||
//----------------------------------------------------------------------------- | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reactive; | ||
|
||
namespace Microsoft.Dafny { | ||
|
||
public class UselessOldLinter : IRewriter { | ||
internal override void PostResolve(Program program) { | ||
base.PostResolve(program); | ||
foreach (var moduleDefinition in program.Modules()) { | ||
foreach (var topLevelDecl in moduleDefinition.TopLevelDecls.OfType<TopLevelDeclWithMembers>()) { | ||
foreach (var callable in topLevelDecl.Members.OfType<ICallable>()) { | ||
var visitor = new UselessOldLinterVisitor(this.Reporter); | ||
visitor.Visit(callable, Unit.Default); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public UselessOldLinter(ErrorReporter reporter) : base(reporter) { | ||
} | ||
} | ||
|
||
class UselessOldLinterVisitor : TopDownVisitor<Unit> { | ||
private readonly ErrorReporter reporter; | ||
|
||
public UselessOldLinterVisitor(ErrorReporter reporter) { | ||
this.reporter = reporter; | ||
} | ||
|
||
protected override bool VisitOneExpr(Expression expr, ref Unit st) { | ||
if (expr is OldExpr oldExpr && !AutoGeneratedToken.Is(oldExpr.tok)) { | ||
var fvs = new HashSet<IVariable>(); | ||
var usesHeap = false; | ||
FreeVariablesUtil.ComputeFreeVariables(oldExpr.E, fvs, ref usesHeap, true); | ||
if (!usesHeap) { | ||
this.reporter.Warning(MessageSource.Rewriter, oldExpr.tok, | ||
$"Argument to 'old' does not dereference the mutable heap, so this use of 'old' has no effect"); | ||
} | ||
} | ||
return base.VisitOneExpr(expr, ref st); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
|
||
Dafny program verifier finished with 204 verified, 0 errors | ||
Dafny program verifier finished with 202 verified, 0 errors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we run 'the old has no effect' detection after we generate the iterator method specs? This works as well, but I'm curious what the best ordering of operations is. Maybe
CreateIteratorMethodSpecs
should not be part of the main resolution phase, but instead be part of the code-gen phase?Can
FreeVariableUtil.ComputeFreeVariables
not be called before resolution? Maybe we should specify that in a comment on the before.Side note: the AutoGeneratedToken concept seems strange to me. In generated code I wouldn't expect warnings/errors, and I wouldn't expect any non-nullish tokens there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The linter is run after resolution. At that time (and not before that time), we have information about heap usage and variable definitions. For example, we know whether
s[i]
is referring to a sequence element or an array element. The free-variable machinery already has the ability to detect heap usage, so it made sense to call it from the linter.There are a number of desugaring tasks (
match
, datatype update, iterators, ...) that are being done quite early. Creating new AST nodes is easier pre-resolution, because then the resolution pass will fill in type information. To my taste, some of that desugaring is done too early, or perhaps shouldn't be done at all. It would be good to have a discussion and redesign of all of that sometime. But for iterators, the desugaring does need to be done early, because the iterator desugaring introduces names that the program is allowed to call. So, this means iterator desugaring is necessarily done before the linter runs.One could consider making the iterator desugaring more clever, so that it never generates useless
old
expressions. But this is difficult to determine before resolution (cf. mys[i]
example above).Therefore, to avoid linter warnings from such generated code, we need some way to keep track of which expressions have been automatically generated. We already had a mechanism for this, which is to put some information into the tokens. This is not perfect, and I'm not sure that we're using nested token wrappers correctly. For linter warnings, any such imperfections seem okay, since at worst we'd generate bad warnings or omit some warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the info. This approach seems good :)