Fix static analysis and code actions #5966
Merged
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.
Fixes #5962
Description
This commit removed one optimization that was gathering declaration and assignment in a single assignment in the Dafny intermediate representation. That is, before that commit, this piece:
was combined into a single
DeclareVar(name, typ, Some(rhs))`
before being translated to Rust.
The commit above removed that optimization because it can detect that "name" is going to be immediately assigned, and give it a type without Maybeplacebo tracking (that tracks whether the variable was assigned at all). And when optimizing the resulting Rust code, a declaration followed by an assignment is combined into a single statement.
It seems for some reason that the Rust optimization was not applied in the problem reported in #5962. I could not reproduce it, but because I recognized that the optimization was not applied, I decided to reinstate the optimization on the Dafny AST level itself.
Note that the splitting between the declaration and the assignment is an artefact from the code generator. Dafny declare and assign are stored in two different statements, which prevents shadowing variables. Indeed, the following two pieces of code are not equivalent. The first one is what Dafny resolves to, the second one is what users write:
and
In the second case, the name refers to the variable name before itself, whereas in the first case, the name is not assigned.
All other backends than Dafny-based backends add counters to variables to disambiguate them. However, the Rust code generator has decent shadowing rules so it makes sense to compile the Dafny
If the rhs contained "name", in Dafny it referred to a previous eponymous variable. In Rust as well. However, in the intermediate representation, since it does not add unique counters to variables, the second one is translatable in Rust whereas the first one is not:
By reinstating this optimization on the Dafny intermediate representation, it should make the code generation more robust in the future.
The second error commit introduced was that the static analyzer was faulty in the case of if-then-else statements, as it would forget the part after the if-then-else block and wrongly infer that a variable was not assigned when it was actually unknown.
I fixed the analyzer the following way:
Then, in an effort to make everything more robust,
The function still matched the method body so I'm now pretty much more confident of the analysis.
This PR also adds two more fixes in code actions I needed to figure out termination
How has this been tested?
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.