-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Implement ExperimentalAttribute
#85444
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
src/libraries/System.Private.CoreLib/src/ILLink/ILLink.LinkAttributes.Shared.xml
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
Show resolved
Hide resolved
Build failures don't seem related to my change, as other PRs fail on the same CI legs... |
...ibraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs
Outdated
Show resolved
Hide resolved
...ibraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs
Outdated
Show resolved
Hide resolved
...ibraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs
Outdated
Show resolved
Hide resolved
...libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs
Outdated
Show resolved
Hide resolved
...libraries/System.Runtime/tests/System/Diagnostics/CodeAnalysis/ExperimentalAttributeTests.cs
Outdated
Show resolved
Hide resolved
If this resolves that issue, what is tracking the tooling side of this, either in an analyzer or the compiler (wherever we landed)? And when do we expect that tooling to land? We don't want to ship the attribute without associated tooling. |
@terrajobst is working on that AFAIK. |
...ibraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/ExperimentalAttribute.cs
Show resolved
Hide resolved
Tagging subscribers to this area: @tommcdon Issue DetailsResolves #77869 /cc: @geeknoid @joperezr @stephentoub
|
@terrajobst or @stephentoub, can you remind me what is the plan for using this attribute downlevel? Is the idea to just define the attribute as part of your assembly as an internal type or were we planning on having a Microsoft.BCL.* package with this? |
@terrajobst can correct me if I'm wrong, but I believe the plan is:
Immo? |
You have several pipelines (over 10) configured to build pull requests in this repository. Specify which pipelines you would like to run by using /azp run [pipelines] command. You can specify multiple pipelines using a comma separated list. |
/azp run runtime |
I'm with Jose here, I don't value the custom diag IDs and after a year or two of using an experimental attribute + analyzer in our code base, this has just not been an issue. |
Ok, I've re-watched the API Proposal meeting where this was discussed and understand the scenario now. The answer to my question above seems to be that the 1% case is for library authors that want to use a custom diagnostic ID for their experimental APIs. So for example, I build the FooBar library and want to introduce an experimental API, and I want to specify that people calling this API should get a diagnostic warning That scenario does seem niche, and seems like it was mostly inspired by the Obsolete attribute, which has the same concept. I propose we do an incremental approach here where we start with an attribute that doesn't support custom diagnostic IDs and can be merged now and we can have a temporary analyzer on the roslyn-analyzers repo for this as @geeknoid suggests, and then if we think it's necessary and @jaredpar thinks we have time to get to this in .NET 8, we later re-add the DiagnosticId support and move the analyzer to be part of the compiler instead. Does that sound reasonable? |
(I only have limited experience with this and didn't try this idea) While analyzers have to declare the diagnostics they want to emit, source generators do not. So shouldn't it be possible to implement this as a very weird source generator, that doesn't emit any sources and just raises the experimental diagnostics with the custom ids? |
I'll give you a firm yes / no by end of week on this. |
We're going to try and get our end done this week / early next. The change itself is small but the testing is not. @jcouv will be doing the work. |
That's great, thanks @jaredpar for confirming. Apologies if this is a very dumb question, but in order for you to start the work, do you need this PR to be merged first or can you start the work in parallel? |
We can start the work without this PR. |
If the tooling is going to happen soon, whether in compiler or analyzer as a backup, I have no problem merging the attribute now. I just wanted to make sure it was still in the works, as I hadn't heard any update for literally months :) |
Sounds good to me. Merging this in then, thanks folks! |
/// This attribute allows call sites to be flagged with a diagnostic that indicates that an experimental | ||
/// feature is used. Authors can use this attribute to ship preview features in their assemblies. | ||
/// </remarks> | ||
[AttributeUsage(AttributeTargets.Assembly | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joperezr @stephentoub Let's not include "Assembly" and "Module" in the list. I don't think those targets are valid for other attributes of this kind (Obsolete
, Windows.Foundation.Metadata.Experimental
, Windows.Foundation.Metadata.Deprecated
, ...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc: @terrajobst @geeknoid
Thanks for the feedback @jcouv. Aside from the fact that other attributes don't support this, is there a particular reason why you don't think we should allow Assembly or Module use? Seems to me that there are valid scenarios where people developing new assemblies might opt to use it at that level, in the past this has been done mostly via using prerelease package versions but I think that not everybody uses that and there are some scenarios where it might be better to have stable p ackages with assemblies marked as experimental in them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main reason for my question is precedent. The secondary reason is implementation cost (deviating from existing attributes means additional complexity and testing).
I'm not saying it's a bad idea, but since the previous design worked, I think we'd need a strong reason to revise it (why was it sufficient for those other attributes but not this one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair enough. @bartonjs @terrajobst @stephentoub Do you know off the top of your head why the Obsolete attribute doesn't support Assembly or Module targets? I would have expected the same arguments should be made for both Obsolete and Experimental, since they are essentially the same attribute but just tracking the two opposing ends of an API lifecycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe dotnet/extensions has assembly-level applications of the attribute. E.g., https://github.com/dotnet/extensions/blob/d558f8de86adf93044bc5386bd4367b3d509ead3/Directory.Build.targets#L68-L72
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the platform compat attributes we allowed assembly/module and we use it quite a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with excluding them for now if we want to match ObsoleteAttribute. We can revisit then we run into limitations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geeknoid FYI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, the compiler/roslyn change was merged.
AttributeTargets.Event | | ||
AttributeTargets.Interface | | ||
AttributeTargets.Delegate, Inherited = false)] | ||
public sealed class ExperimentalAttribute : Attribute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joperezr @stephentoub I just want to confirm the expected user experience with an example. I'm re-using a message we already have for APIs marked as experimental.
Let me know if you have any feedback.
[Fact]
public void Test()
{
var src = """
C.M();
[System.Diagnostics.CodeAnalysis.Experimental("DiagID1", UrlFormat = "https://example.org/{0}")]
class C
{
public static void M() { }
}
""";
var comp = CreateCompilation(new[] { src, experimentalAttributeSrc });
comp.VerifyDiagnostics(
// 0.cs(1,1): warning DiagID1: 'C' is for evaluation purposes only and is subject to change or removal in future updates. (https://example.org/DiagID1)
// C.M();
Diagnostic("DiagID1", "C").WithArguments("C").WithLocation(1, 1)
);
var diag = comp.GetDiagnostics().Single();
Assert.Equal("DiagID1", diag.Id);
Assert.Equal(ErrorCode.WRN_Experimental, (ErrorCode)diag.Code);
Assert.Equal("https://example.org/DiagID1", diag.Descriptor.HelpLinkUri);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, the above looks right to me. You can then also write a compilation which passes in the NoWarn for your diagnostic which should not show it any more, or alternatively suppress at each call site by using pragma.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
) * Update dependencies from https://github.com/dotnet/aspnetcore build 20230621.15 Microsoft.AspNetCore.App.Runtime.win-x64 , Microsoft.AspNetCore.Mvc.Testing , Microsoft.AspNetCore.TestHost , Microsoft.Extensions.Caching.StackExchangeRedis , Microsoft.Extensions.Diagnostics.HealthChecks , Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions , Microsoft.Extensions.Features , Microsoft.Extensions.Http.Polly , Microsoft.Extensions.ObjectPool From Version 8.0.0-preview.6.23315.13 -> To Version 8.0.0-preview.6.23321.15 Dependency coherency updates Microsoft.Bcl.TimeProvider,Microsoft.Extensions.Caching.Abstractions,Microsoft.Extensions.Caching.Memory,Microsoft.Extensions.Configuration.Abstractions,Microsoft.Extensions.Configuration.Binder,Microsoft.Extensions.Configuration.CommandLine,Microsoft.Extensions.Configuration.Json,Microsoft.Extensions.Configuration,Microsoft.Extensions.DependencyInjection.Abstractions,Microsoft.Extensions.DependencyInjection,Microsoft.Extensions.Hosting.Abstractions,Microsoft.Extensions.Hosting,Microsoft.Extensions.Http,Microsoft.Extensions.Logging.Abstractions,Microsoft.Extensions.Logging.Configuration,Microsoft.Extensions.Logging.Console,Microsoft.Extensions.Logging,Microsoft.Extensions.Options.ConfigurationExtensions,Microsoft.Extensions.Options.DataAnnotations,Microsoft.Extensions.Options,Microsoft.Extensions.Primitives,System.Collections.Immutable,System.Configuration.ConfigurationManager,System.Diagnostics.DiagnosticSource,System.Diagnostics.PerformanceCounter,System.IO.Hashing,System.Net.Http.Json,System.Security.Cryptography.Pkcs,System.Security.Cryptography.Xml,System.Text.Encodings.Web,System.Text.Json,System.Runtime.Caching From Version 8.0.0-preview.6.23314.15 -> To Version 8.0.0-preview.6.23318.9 (parent: Microsoft.AspNetCore.App.Runtime.win-x64 * Bump the SDK to resolve the break caused by dotnet/runtime#87621 * Update local copy of ExperimentalAttribute per dotnet/runtime#85444 * Update dependencies from https://github.com/dotnet/aspnetcore build 20230623.8 Microsoft.AspNetCore.App.Runtime.win-x64 , Microsoft.AspNetCore.Mvc.Testing , Microsoft.AspNetCore.TestHost , Microsoft.Extensions.Caching.StackExchangeRedis , Microsoft.Extensions.Diagnostics.HealthChecks , Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions , Microsoft.Extensions.Features , Microsoft.Extensions.Http.Polly , Microsoft.Extensions.ObjectPool From Version 8.0.0-preview.6.23315.13 -> To Version 8.0.0-preview.6.23323.8 Dependency coherency updates Microsoft.Bcl.TimeProvider,Microsoft.Extensions.Caching.Abstractions,Microsoft.Extensions.Caching.Memory,Microsoft.Extensions.Configuration.Abstractions,Microsoft.Extensions.Configuration.Binder,Microsoft.Extensions.Configuration.CommandLine,Microsoft.Extensions.Configuration.Json,Microsoft.Extensions.Configuration,Microsoft.Extensions.DependencyInjection.Abstractions,Microsoft.Extensions.DependencyInjection,Microsoft.Extensions.Hosting.Abstractions,Microsoft.Extensions.Hosting,Microsoft.Extensions.Http,Microsoft.Extensions.Logging.Abstractions,Microsoft.Extensions.Logging.Configuration,Microsoft.Extensions.Logging.Console,Microsoft.Extensions.Logging,Microsoft.Extensions.Options.ConfigurationExtensions,Microsoft.Extensions.Options.DataAnnotations,Microsoft.Extensions.Options,Microsoft.Extensions.Primitives,System.Collections.Immutable,System.Configuration.ConfigurationManager,System.Diagnostics.DiagnosticSource,System.Diagnostics.PerformanceCounter,System.IO.Hashing,System.Net.Http.Json,System.Security.Cryptography.Pkcs,System.Security.Cryptography.Xml,System.Text.Encodings.Web,System.Text.Json,System.Runtime.Caching From Version 8.0.0-preview.6.23314.15 -> To Version 8.0.0-preview.6.23323.4 (parent: Microsoft.AspNetCore.App.Runtime.win-x64 * Update dependencies from https://github.com/dotnet/aspnetcore build 20230625.3 Microsoft.AspNetCore.App.Runtime.win-x64 , Microsoft.AspNetCore.Mvc.Testing , Microsoft.AspNetCore.TestHost , Microsoft.Extensions.Caching.StackExchangeRedis , Microsoft.Extensions.Diagnostics.HealthChecks , Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions , Microsoft.Extensions.Features , Microsoft.Extensions.Http.Polly , Microsoft.Extensions.ObjectPool From Version 8.0.0-preview.6.23315.13 -> To Version 8.0.0-preview.6.23325.3 Dependency coherency updates Microsoft.Bcl.TimeProvider,Microsoft.Extensions.Caching.Abstractions,Microsoft.Extensions.Caching.Memory,Microsoft.Extensions.Configuration.Abstractions,Microsoft.Extensions.Configuration.Binder,Microsoft.Extensions.Configuration.CommandLine,Microsoft.Extensions.Configuration.Json,Microsoft.Extensions.Configuration,Microsoft.Extensions.DependencyInjection.Abstractions,Microsoft.Extensions.DependencyInjection,Microsoft.Extensions.Hosting.Abstractions,Microsoft.Extensions.Hosting,Microsoft.Extensions.Http,Microsoft.Extensions.Logging.Abstractions,Microsoft.Extensions.Logging.Configuration,Microsoft.Extensions.Logging.Console,Microsoft.Extensions.Logging,Microsoft.Extensions.Options.ConfigurationExtensions,Microsoft.Extensions.Options.DataAnnotations,Microsoft.Extensions.Options,Microsoft.Extensions.Primitives,System.Collections.Immutable,System.Configuration.ConfigurationManager,System.Diagnostics.DiagnosticSource,System.Diagnostics.PerformanceCounter,System.IO.Hashing,System.Net.Http.Json,System.Security.Cryptography.Pkcs,System.Security.Cryptography.Xml,System.Text.Encodings.Web,System.Text.Json,System.Runtime.Caching From Version 8.0.0-preview.6.23314.15 -> To Version 8.0.0-preview.6.23323.4 (parent: Microsoft.AspNetCore.App.Runtime.win-x64 * Deprecate this repo's option validator code gen in favor of the runtime'src - This removes traces of the option code generator in this repo, now that the code has moved to dotnet/runtime. Unfortunately, the generator in dotnet/runtime has currently dropped the use of the 'file' visibility accessor in generated code, which leads to some conflicting type definitions in this code base due to the use of IntervalsVisibleTo. This surfaces as build warnings which are safe to ignore, since the C# compiler ends up binding to the right thing. Fixing these warnings will require a new drop of the runtime's generator. * Bump SDK * Suppress CS0436 --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Igor Velikorossov <igor.velikorossov@microsoft.com> Co-authored-by: Martin Taillefer <mataille@microsoft.com>
* Update local copy of ExperimentalAttribute per dotnet/runtime#85444 * Deprecate this repo's option validator code gen in favor of the runtime'src - This removes traces of the option code generator in this repo, now that the code has moved to dotnet/runtime. Unfortunately, the generator in dotnet/runtime has currently dropped the use of the 'file' visibility accessor in generated code, which leads to some conflicting type definitions in this code base due to the use of IntervalsVisibleTo. This surfaces as build warnings which are safe to ignore, since the C# compiler ends up binding to the right thing. Fixing these warnings will require a new drop of the runtime's generator. * Suppress CS0436
[main] Update dependencies from dotnet/aspnetcore - Coherency Updates: - Microsoft.Bcl.TimeProvider: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Caching.Abstractions: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Caching.Memory: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Configuration.Abstractions: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Configuration.Binder: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Configuration.CommandLine: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Configuration.Json: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Configuration: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.DependencyInjection.Abstractions: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.DependencyInjection: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Hosting.Abstractions: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Hosting: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Http: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Logging.Abstractions: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Logging.Configuration: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Logging.Console: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Logging: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Options.ConfigurationExtensions: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Options.DataAnnotations: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Options: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Microsoft.Extensions.Primitives: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Collections.Immutable: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Configuration.ConfigurationManager: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Diagnostics.DiagnosticSource: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Diagnostics.PerformanceCounter: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.IO.Hashing: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Net.Http.Json: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Security.Cryptography.Pkcs: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Security.Cryptography.Xml: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Text.Encodings.Web: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Text.Json: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - System.Runtime.Caching: from 8.0.0-preview.6.23314.15 to 8.0.0-preview.7.23325.2 (parent: Microsoft.AspNetCore.App.Runtime.win-x64) - Build fixes * Update local copy of ExperimentalAttribute per dotnet/runtime#85444 * Deprecate this repo's option validator code gen in favor of the runtime'src - This removes traces of the option code generator in this repo, now that the code has moved to dotnet/runtime. Unfortunately, the generator in dotnet/runtime has currently dropped the use of the 'file' visibility accessor in generated code, which leads to some conflicting type definitions in this code base due to the use of IntervalsVisibleTo. This surfaces as build warnings which are safe to ignore, since the C# compiler ends up binding to the right thing. Fixing these warnings will require a new drop of the runtime's generator. * Suppress CS0436 - Bump SDK - fixup! Build fixes
Resolves #77869
/cc: @geeknoid @joperezr @stephentoub