Skip to content

Conversation

@RustanLeino
Copy link
Collaborator

Fixes #6043

This PR changes two verification checks into resolution checks:

  • use of a function in a decreases clause in the function's SCC
  • use of naked functions inside an SCC

The first of these was omitted in the recent CanCall PR. Hence, this PR fixes that regression.

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

}
}
}
} No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

need new line here.


namespace Microsoft.Dafny;

class FunctionEntanglementChecks_Visitor : ResolverBottomUpVisitor {
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor Nitpick: Not sure Entanglement is the right word here. Following the implementation, two functions are entangled when they are in the same SCC and one uses the other either in a naked fashion or in a decreases clause. But the fact that they are in the SCC means that they depend on one another and already feel entangled. Maybe DetectUnsoundFunctionReferences or DUFR (pronounced as duffer 😂)

# Conflicts:
#	Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/parser_combinators.dfy.expect
#	Source/IntegrationTests/TestFiles/LitTests/LitTest/git-issues/git-issue-847.dfy.expect
#	Source/IntegrationTests/TestFiles/LitTests/LitTest/hofs/Naked.dfy.expect
typerSniper
typerSniper previously approved these changes Jan 13, 2025
@typerSniper
Copy link
Contributor

Looks good!


namespace Microsoft.Dafny;

class DetectUnsoundFunctionReferences_Visitor : ResolverBottomUpVisitor {
Copy link
Member

Choose a reason for hiding this comment

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

Why the _ in the name? I think that's outside of C# conventions. Does Rider not suggest to remove it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had followed the convention used by other _Visitor classes in the Dafny sources. But I agree that's outside C# conventions. So, I now renamed all classes in Dafny to remove _'s.


class DetectUnsoundFunctionReferences_Visitor : ResolverBottomUpVisitor {
private readonly ICallable context;
public bool DoDecreasesChecks;
Copy link
Member

Choose a reason for hiding this comment

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

I know it doesn't matter much, but I think C# developers generally prefer auto properties over public fields, at least I do. One example: you can put a breakpoint on a property getter/setter, but not on a field read/write.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I made it private, as per the suggestion below.

}
}

if (DoDecreasesChecks && expr is FunctionCallExpr callExpr) {
Copy link
Member

Choose a reason for hiding this comment

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

Please merge the conditions to reduce nesting, and consider inverting the condition to get an early return and fully remove the nesting.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I unnested the if's.

FillInPostConditionsAndBodiesOfPrefixLemmas(declarations);
}

// A function is not allowed to be used naked in its own SCC. Also, a function is not allowed to be used
Copy link
Member

Choose a reason for hiding this comment

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

What does the term naked here mean?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It means the function name is used without applying it to arguments. (This nomenclature is not new in this PR.) I clarified in the comment.

// in any way inside a "decreases" clause its its own SCC.
foreach (var function in ModuleDefinition.AllFunctions(declarations)) {
var visitor = new DetectUnsoundFunctionReferences_Visitor(this, function);
visitor.Visit(function);
Copy link
Member

Choose a reason for hiding this comment

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

If this visit/doDecreasesChecks/visit pattern is the only correct way to use DetectUnsoundFunctionReferences_Visitor, then it would be better to move this into a static method in that class, and make the constructor and DoDecreasesChecks field private.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea.

TailCalls.dfy(126,19): Error: the recursive call to 'Compute' is not tail recursive because the actual type argument is not the formal type parameter 'G'
TailCalls.dfy(139,17): Error: the recursive call to 'Run' is not tail recursive because the actual type argument 1 is not the formal type parameter 'G'
30 resolution/type errors detected in TailCalls.dfy
TailCalls.dfy(171,13): Error: cannot use naked function in recursive setting. Possible solution: eta expansion.
Copy link
Member

Choose a reason for hiding this comment

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

Can we avoid the use of the word naked here? Can I find more information on what the problem is and the possible solution? Maybe add a reference to documentation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I left this as is. This PR does not introduce the phrase "naked function". It would be good to revisit, and indeed to say something about it in the documentation.

@RustanLeino RustanLeino merged commit 6afa6d5 into dafny-lang:master Jan 15, 2025
22 checks passed
@RustanLeino RustanLeino deleted the issue-6043 branch January 15, 2025 17:58
RustanLeino added a commit that referenced this pull request Jan 17, 2025
Because `CanCall` is now used everywhere, the Boogie variable
`$FunctionContextHeight` is no longer needed.

This PR also removes the variable `$ModuleContextHeight`, which has been
unused for some time now.

Depends on #6045

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recursive decreases not checked properly

3 participants