Skip to content
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

Add nullablePublicOnly Roslyn Feature #29908

Merged
merged 2 commits into from
Feb 6, 2021

Conversation

eerhardt
Copy link
Member

@eerhardt eerhardt commented Feb 4, 2021

This tells Roslyn to not add [AllowNull] attributes in IL to non-public APIs. The same feature is set for dotnet/runtime.

See https://github.com/dotnet/runtime/blob/8033217b3c9d59da81436e120b32dd5ec74a856c/Directory.Build.props#L249.

This is causing the AllowNullAttribute to be in a default Blazor WASM app, and should allow for it to be trimmed.

cc @stephentoub

This tells Roslyn to not add [AllowNull] attributes in IL to non-public APIs. The same feature is set for dotnet/runtime.
@eerhardt eerhardt requested a review from pranavkm February 4, 2021 19:23
@eerhardt eerhardt requested a review from a team as a code owner February 4, 2021 19:23
@ghost ghost added the area-infrastructure Includes: MSBuild projects/targets, build scripts, CI, Installers and shared framework label Feb 4, 2021
@stephentoub
Copy link
Member

This tells Roslyn to not add [AllowNull] attributes in IL to non-public APIs

I was confused about this when we were talking... we should still make this change, but it's not about AllowNull but rather about the Nullable/NullableContext attributes. Those are the attributes the compiler itself emits to track nullable annotations in metadata.

That said, if we don't have a linker feature that enables removing an allow list of attributes when on non-public surface area, we should consider adding one, and then add all of the System.Diagnostic.CodeAnalysis nullable attributes.

@eerhardt
Copy link
Member Author

eerhardt commented Feb 4, 2021

if we don't have a linker feature that enables removing an allow list of attributes when on non-public surface area, we should consider adding one, and then add all of the System.Diagnostic.CodeAnalysis nullable attributes.

We already have the setting to strip these attributes for WASM:

https://github.com/dotnet/runtime/blob/8033217b3c9d59da81436e120b32dd5ec74a856c/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.xml#L33-L53

But since the ASP.NET assemblies aren't marked for trimming, the linker needs to leave the attributes applied in those assemblies.

Looks like this is another case where making ASP.NET libraries "aggressively trimmed" (as opposed to "type granular" trimmed) will help. FYI - @pranavkm

@pranavkm
Copy link
Contributor

pranavkm commented Feb 5, 2021

@eerhardt could you add this snippet to

  • src/Mvc/Mvc.DataAnnotations/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test.csproj
  • src/Mvc/test/Mvc.IntegrationTests/Microsoft.AspNetCore.Mvc.IntegrationTests.csproj
<!-- This project has tests that rely on nullability on non-public types. Undo nullablePublicOnly configured by default -->
<Features>$(Features.Replace('nullablePublicOnly', ''))</Features>

Also FYI @roji in case you wanted to set this feature flag in EF

@roji
Copy link
Member

roji commented Feb 5, 2021

@pranavkm thanks. This would be problematic in EF Core since pubternal types are in extensive use - we have very little real internals, instead we place public types under Internal namespaces.

  • Does the compiler emit attributes in the IL for private members? If so, is there a similar feature to turn only that off?
  • Do I understand correctly that if EF Core is correctly marked for trimming, this becomes unnecessary? Because we have plans to work on that for 6.0.

@stephentoub
Copy link
Member

This would be problematic in EF Core since pubternal types are in extensive use

"pubternal" is just a convention: from the compiler's perspective, it's all still public, so nothing would be removed from them. So I'm not following why this setting would be problematic for that case...?

Do I understand correctly that if EF Core is correctly marked for trimming, this becomes unnecessary? Because we have plans to work on that for 6.0.

For final trimmed wasm app size, I believe it should be fine. For the binaries in the nuget package, the attributes on non-public surface area would all still be there, which is unnecessary unless you actually rely on code being able to inspect Nullable{Context} via reflection on true internals.

@eerhardt eerhardt requested a review from javiercn as a code owner February 5, 2021 16:20
@eerhardt
Copy link
Member Author

eerhardt commented Feb 5, 2021

@eerhardt could you add this snippet to

Done. Thanks for the help, @pranavkm!

@roji
Copy link
Member

roji commented Feb 5, 2021

This would be problematic in EF Core since pubternal types are in extensive use

"pubternal" is just a convention: from the compiler's perspective, it's all still public, so nothing would be removed from them. So I'm not following why this setting would be problematic for that case...?

What I meant was that since there are practically no (true) internal types/members in EF Core, publicOnly simply wouldn't do much - everything is public anyway Unless the point here is to avoid generating the attributes for private members; are those emitted without publicOnly being set?

Thanks for the wasm/linker info, I still have no idea how feasible it is to get EF Core working with aggressive linking, given the extensive reliance on reflection. But it's something I'm planning to look into.

@stephentoub
Copy link
Member

stephentoub commented Feb 5, 2021

Unless the point here is to avoid generating the attributes for private members; are those emitted without publicOnly being set?

Yes, the compiler emits all Nullable/NullableContext attributes on all members regardless of visibility, unless you specify nullablePublicOnly, in which case it only does so for publics.

@roji
Copy link
Member

roji commented Feb 5, 2021

Thanks, all clear now. Will do this for EF Core as well.

@pranavkm pranavkm merged commit 73212a6 into dotnet:main Feb 6, 2021
@pranavkm pranavkm added this to the 6.0-preview2 milestone Feb 6, 2021
@eerhardt eerhardt deleted the NullablePublicOnly branch April 14, 2023 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-infrastructure Includes: MSBuild projects/targets, build scripts, CI, Installers and shared framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants