Skip to content

Conversation

@333fred
Copy link
Member

@333fred 333fred commented Jan 23, 2026

We now mark preview language feature public APIs as experimental before the language version ships fully. As demonstration, I've marked the collection expression arguments public APIs as experimental, so we can see what this actually looks like.

@333fred 333fred requested review from a team as code owners January 23, 2026 20:24
@333fred 333fred requested a review from jcouv January 23, 2026 20:24
@dotnet-policy-service dotnet-policy-service bot added VSCode Needs API Review Needs to be reviewed by the API review council labels Jan 23, 2026
Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

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

Let a few comments at least. My biggest high level thought is whether we should just be suppressing the experimental warning for our entire codebase; since if we build together and ship together, I'm not sure we're getting any benefit for it. (The attribute absolutely makes sense for other projects!)

internal const string GeneratorHostOutputs = "RSEXPERIMENTAL004";
internal const string GeneratorHostOutputs_Url = "https://github.com/dotnet/roslyn/issues/74753";

// The URL is customized per-api to point at the test plan for the feature
Copy link
Member

Choose a reason for hiding this comment

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

Seeing this comment made me think 'which URL?' Given the other examples in this file I expected to see a URL here; maybe it's expanding on this comment a bit.

@333fred
Copy link
Member Author

333fred commented Jan 24, 2026

My biggest high level thought is whether we should just be suppressing the experimental warning for our entire codebase; since if we build together and ship together, I'm not sure we're getting any benefit for it.

No. This will help ensure that manually-written public APIs that include the API are also marked Experimental. #Closed

(node is ExpressionSyntax && (isSpeculative || allowNamedArgumentName || !SyntaxFacts.IsNamedArgumentName(node))) ||
(node is ConstructorInitializerSyntax
or PrimaryConstructorBaseTypeSyntax
#pragma warning disable RSEXPERIMENTAL006 // With Element: https://github.com/dotnet/roslyn/issues/80613
Copy link
Member

@jcouv jcouv Jan 24, 2026

Choose a reason for hiding this comment

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

Could we instead suppress this warning globally within the compiler codebase?
That would avoid sprinkling of suppressions and would make it much easier for the PR that adds a new LangVer #Closed

Copy link
Member Author

@333fred 333fred Jan 26, 2026

Choose a reason for hiding this comment

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

No. The non-suppressed global warning helped me catch manually-written public APIs that also need to be marked as Experimental. We could consider suppressing it in test projects/IDE, but I very much do not think we should do so in the main compiler codebase.

Copy link
Contributor

Choose a reason for hiding this comment

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

The non-suppressed global warning helped me catch manually-written public APIs that also need to be marked as Experimental.

How exactly did that help you?

// - [ ] update _MaxAvailableLangVersion cap (a relevant test should break when new version is introduced)
// - [ ] update the "UpgradeProject" codefixer
// - [ ] Remove the `Experimental` section from any entries being shipped in Syntax.xml and OperationInterfaces.xml, and rerun the generator
// - [ ] Search the codebase for the URLs that were linked in the Syntax.xml and OperationInterfaces.xml files and remove suppressions or attributes added for those issues.
Copy link
Member

@jcouv jcouv Jan 24, 2026

Choose a reason for hiding this comment

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

I'm hoping we can remove this work item by using a global suppression for the compiler codebase #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

No. See previous comment.

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 remove this work item now that we've landed decision to suppress globally?

Copy link
Member Author

Choose a reason for hiding this comment

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

We can adjust it, not remove it. Some APIs may still need to be adjusted because they were manually marked.

Copy link
Member

Choose a reason for hiding this comment

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

Search the codebase for the URLs [...] and remove suppressions

URLs wouldn't be linked in the suppressions, right?

@jcouv
Copy link
Member

jcouv commented Jan 24, 2026

This will help ensure that manually-written public APIs that include the API are also marked Experimental.

I can think of two cases:

  1. INamedTypeSymbol.IsExtension: I don't know that local suppression would help remind us to mark this as Experimental
  2. GetCreationMethods(WithElementSyntax, ...): local suppression means we'd be reminded to mark this as Experimental, but since the WithElementSyntax is already marked as Experimental, any callers would already be notified

I'm still in favor of a global suppression, but maybe we could pick a few files (those where we put public APIs) to re-enable the warning?


In reply to: 3793141614

@jcouv
Copy link
Member

jcouv commented Jan 24, 2026

A possible middle-ground: we add file-level suppression for files with internal types (Binder, SemanticModel, etc) and all our test projects to reduce need for local suppressions


In reply to: 3795392872

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (commit 5)

@jcouv jcouv self-assigned this Jan 24, 2026
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="Base" type="xs:string" use="required" />
<xs:attribute name="ExperimentalUrl" type="xs:string" use="optional" />
Copy link
Contributor

Choose a reason for hiding this comment

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

<xs:attribute name="ExperimentalUrl" type="xs:string" use="optional" />

Is this file maintained manually? If so, why do we need it?

Copy link
Member Author

Choose a reason for hiding this comment

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

It is maintained manually. It predates my time here, and presumably provides completion for the XML structure in Syntax.xml. If we decide we don't want it, that's ok with me, but I think that should be a separate PR. For now, I'm going to keep this as is and update appropriately.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it's used for that. I think the checker also uses this to validate the structure of the XML too?

@AlekseyTs
Copy link
Contributor

@333fred I think it would be good to provide a general description:

  • How an experimental APIs is supposed to be marked. I.e. what constitutes a properly parked experimental API
  • What artifacts should be placed and where they should be placed in order to achieve proper marking of generated APIs.

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jan 28, 2026

I very much dislike the suppressions sprinkled throughout the code base and would like to understand what benefits they provide by comparison to a global suppression. #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jan 28, 2026

Done with review pass (commit 6) #Closed

@333fred
Copy link
Member Author

333fred commented Jan 29, 2026

@dotnet/roslyn-compiler for review

@AlekseyTs
Copy link
Contributor

It looks like there are some related CI errors

@AlekseyTs
Copy link
Contributor

Done with review pass (commit 10)

// See the LICENSE file in the project root for more information.
// < auto-generated />
#nullable enable
#pragma warning disable RSEXPERIMENTAL006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
Copy link
Member

@jcouv jcouv Jan 29, 2026

Choose a reason for hiding this comment

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

Do we still need this suppression given the suppression editorconfig?
Also applies to other generated files #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

I can remove it from the iop trees, but not the syntax generator ones, since those actually use source generation and the .editorconfig value does not apply to them.

static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WithElement(Microsoft.CodeAnalysis.SyntaxToken withKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax! argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.WithElementSyntax!
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitWithElement(Microsoft.CodeAnalysis.CSharp.Syntax.WithElementSyntax! node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitWithElement(Microsoft.CodeAnalysis.CSharp.Syntax.WithElementSyntax! node) -> TResult?
[RSEXPERIMENTAL006]Microsoft.CodeAnalysis.CSharp.Syntax.WithElementSyntax
Copy link
Member

Choose a reason for hiding this comment

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

Should the SyntaxKind above bet considered experimental too?

Microsoft.CodeAnalysis.IPropertySymbol.ReduceExtensionMember(Microsoft.CodeAnalysis.ITypeSymbol! receiverType) -> Microsoft.CodeAnalysis.IPropertySymbol?
Microsoft.CodeAnalysis.OperationKind.CollectionExpressionElementsPlaceholder = 129 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.Operations.ICollectionExpressionElementsPlaceholderOperation
[RSEXPERIMENTAL006]Microsoft.CodeAnalysis.OperationKind.CollectionExpressionElementsPlaceholder = 129 -> Microsoft.CodeAnalysis.OperationKind
Copy link
Member

Choose a reason for hiding this comment

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

Should ConstructArguments below be marked as experimental?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

I've fixed the bug in the PR, but since we reference the package via nuget, not via a project reference, consuming the bugfix will need to wait for the next time we bump this.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (commit 11)


if (!string.IsNullOrEmpty(experimentalUrl))
{
WriteLine($"[Experimental(global::Microsoft.CodeAnalysis.RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = {QuoteString(experimentalUrl)})]");
Copy link
Member

Choose a reason for hiding this comment

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

I think this is the same as WriteExperimentalAttribute? And then delete QuoteString since this might be the only user?

- Any time the compiler reads in metadata containing crypto hashes, even if it's an attribute value, ensure the crypto hash algorithm name is included in the metadata (e.g. prefixing it to the hash value), so that it can be changed over time and the compiler can continue to read both metadata using both the old and new algorithms.
- All newly added APIs are experimental
- Tracking issue for marking APIs as non-experimental
- APIs are marked with `[Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = @"link to tracking issue")]`
Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't expect backslashes in the URL

Suggested change
- APIs are marked with `[Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = @"link to tracking issue")]`
- APIs are marked with `[Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "link to tracking issue")]`

dotnet_diagnostic.xUnit2029.severity = none

# RS0006: Roslyn experimental language API
dotnet_diagnostic.RSEXPERIMENTAL006.severity = none
Copy link
Member

Choose a reason for hiding this comment

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

Did you consider putting this into a .globalconfig file instead? Then we wouldn't need separate suppressions in source-generated files.

// - [ ] update _MaxAvailableLangVersion cap (a relevant test should break when new version is introduced)
// - [ ] update the "UpgradeProject" codefixer
// - [ ] Remove the `Experimental` section from any entries being shipped in Syntax.xml and OperationInterfaces.xml, and rerun the generator
// - [ ] Search the codebase for the URLs that were linked in the Syntax.xml and OperationInterfaces.xml files and remove suppressions or attributes added for those issues.
Copy link
Member

Choose a reason for hiding this comment

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

Search the codebase for the URLs [...] and remove suppressions

URLs wouldn't be linked in the suppressions, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Compilers Needs API Review Needs to be reviewed by the API review council VSCode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants