[Method Contracts] Extensibility of flow state analysis via attributes #7180
Unanswered
Rekkonnect
asked this question in
Language Ideas
Replies: 1 comment 4 replies
-
That seems like an incredibly complicated syntax to describe the behavior of nullable flow control, and in the end it's all going to have to be boiled down into attributes that can be attached to the methods anyway. This would require a lot of specification work and compiler work just to return to par, and supporting new scenarios is going to end up requiring new flavors of this DSL and the metadata to go along with it. I also don't understand trying to conflate method contracts with NRT flow analysis. I would expect that method contracts would affect the runtime semantics of the method, where flow analysis certainly shouldn't. |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
This proposal enables extending the capabilities and coverage of flow state analysis via attributes onto method contracts.
Motivation
Since the release of C# 8.0, with the introduction of nullable reference types, most JetBrains' flow state analysis attributes were ported over to the BCL with native support from the compiler for the analysis. Ever since, even more attributes were being added, covering even more scenarios. In C# 11.0,
nameof
for method parameters was primarily motivated due to this use case, to support writing the nameof expression on the compared method parameter.This however is never reaching a satisfactory coverage rate due to the attributes' lack of customizability. Each new attribute must be considered and individually analyzed on top of a system that acts as a simulation of a method contract system in a very bound scope, mainly concerning nullability.
Proposal
Enable a fundamental grammar for declaring method contracts, that are encodable in metadata. The metadata encoding is not part of this discussion; it will have its own difficulties that are not considered here.
By method contracts, we mean clauses similar to
where
on generic type and method declarations. Those contracts will declare the state of certain values and the flow analysis system will be able to keep track of that state, providing a flexible solution for showing fewer false warnings.Currently, the flow state analysis article mentions the following attributes:
AllowNull
DisallowNull
MaybeNull
NotNull
MaybeNullWhen
NotNullWhen
NotNullIfNotNull
MemberNotNull
MemberNotNullWhen
DoesNotReturn
DoesNotReturnIf
There are even more proposals for more attributes and further expansion of the current attribute-based system.
Method contracts can cover all the above scopes, and way further due to their reliance on expressions, pattern-based or not. Those expressions are hints to the compiler, code that will never slip onto runtime execution, and will not impose further strain on the runtime memory by having to load such attributes.
Method contracts will have one major difference compared to the attribute-based approach that is being currently followed, and that is the fact that violation of the declared contracts will result in a compilation error. This is a healthy design in the scope of having compile-time safety without silently leaking a potential bug, or an unwanted exception being thrown. Consumers will have to wisely apply those rules.
Namely, this is how the above attributes will be covered using method contracts:
Examples
All the showcased examples come from the flow state analysis article linked above.
AllowNull
Attributes:
Method contracts:
DisallowNull
Attributes:
Method contracts:
MaybeNull
Attributes:
Method contracts:
NotNull
Attributes:
Method contracts:
MaybeNullWhen
The original article does not provide an example for
MaybeNullWhen
, so it was omitted here.NotNullWhen
Attributes:
Method contracts:
NotNullIfNotNull
Attributes:
Method contracts:
MemberNotNull
Attributes:
Method contracts:
MaybeNullWhen
The original article does not provide an example for
MemberNotNullWhen
, so it was omitted here.DoesNotReturn
Attributes:
Method contracts:
NOTE: There also exist other proposals for handling the case of methods that always throw, like the proposal about the
never
type to indicate that.DoesNotReturnIf
Attributes:
Method contracts:
Additional proposals that also introduce more attributes:
MemberNotNullWhenComplete
(#5657)Attributes:
Method contracts:
Risks
Extras
All code that relies on the traditional flow analysis system via attributes will be offered a code fix to immediately convert all those attributes into method contracts. This will have to be used wisely, as there is the aforementioned risk of breaking users when updating to a newer version of the assembly that introduces method contracts.
Beta Was this translation helpful? Give feedback.
All reactions