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.
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
Declaring Non-Nullable Parameters #708
Declaring Non-Nullable Parameters #708
Changes from all commits
f9aa216
fc27fb0
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
Declaring Non-Nullable Parameters
Background
Variables of certain WinRT types – classes, interfaces, and delegates – may be null to indicate the absence of an object. In such cases, the variable should only be used, or dereferenced, when the caller has previously checked that the variable is not null.
Languages like C# and Rust can benefit greatly from knowing that output or return parameters are not null by eliding the code needed to check that the resulting value is not null. This helps by improving the correctness of the code via static analysis, reducing code size, and eliminating run time checks. In the case of Rust, it also simplifies the syntax at call sites where these checks cannot easily be overlooked as is permitted in C# and C++.
Metadata Representation
The
NotNull
attribute will be added to theWindows.Foundation.Metadata
namespace alongside the existingNoException
attribute that performs a complementary function. The nameNotNull
is borrowed from .NET that previously introduced aNotNull
attribute in C# 8 to mean the same thing. While theNoException
attribute may only be applied to methods and properties as a whole, theNotNull
attribute may only be applied to parameters.namespace Windows.Foundation.Metadata { [attributeusage(target_parameter)] [attributename("not_null")] attribute NotNullAttribute { } }
Impact on MIDL3
API authors may apply the
NotNull
attribute, or its shortened form, to any parameter but will most often be used with return types.The resulting metadata, in the form of a winmd file, will include the
NotNull
attribute. As with theNoException
attribute, language projections that are unaware of the new attribute, or choose not to apply it in any way, will simply ignore it. And as with theNoException
attribute,NotNull
is additive and may be retroactively applied to existing APIs. This allows existing code to be optimized without breaking compatibility with existing callers.Impact on C#
The
Windows.Foundation.Metadata.NotNullAttribute
attribute will directly map to the C#System.Diagnostics.CodeAnalysis.NotNullAttribute
class. The C#/WinRT language projection will simply include theNotNull
attribute on any WinRT parameters that include the attribute in metadata. The C# compiler can then use it as part of its static analysis processing to optimize call sites.https://docs.microsoft.com/en-us/dotnet/csharp/nullable-references
https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.notnullattribute?view=netcore-3.1
Impact on Rust
Rust is explicit about error propagation and about nullability. What that means for WinRT in practice (at call sites) is that a method that returns a nullable type requires something like
method().unwrap().unwrap()
- the firstunwrap
deals with unpacking theResult<T>
that might report failure and the secondunwrap
deals with resolving theOption<T>
that may or may not be a null return value. This doubleunwrap
is gross to say the least. TheNoException
WinRT attribute previously introduced deals with the firstunwrap
and theNotNull
deals with the second. This significantly improves the quality of life for Rust developers. It is perhaps the only complaint we’ve heard about WinRT from the Rust community.https://doc.rust-lang.org/std/result/enum.Result.html
https://doc.rust-lang.org/std/option/enum.Option.html
Impact on Other Languages
Other languages will be unaffected but may in future choose to apply an appropriate use for the NotNull attribute.