Skip to content

Commit e27acb7

Browse files
author
Immo Landwerth
committed
Clarify expected compiler behavior with respect to RuntimeFeature querying
1 parent 86bb567 commit e27acb7

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

accepted/2021/preview-features/preview-features.md

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -179,36 +179,41 @@ dependencies ([discussed later](#api-analyzer)).
179179

180180
### Compilation context
181181

182-
When `EnablePreviewFeatures` is true, the `LangVersion` property should be set
183-
to `Preview` (unless the customer has explicitly set `LangVersion` in their
184-
project file already). This avoids customers having to turn on preview features
185-
for the language separately.
182+
When `EnablePreviewFeatures` is true, the `LangVersion` property is set to
183+
`Preview` (unless the customer has explicitly set `LangVersion` in their project
184+
file already). This avoids customers having to turn on preview features for the
185+
language separately.
186186

187187
In addition, the property `EnablePreviewFeatures` should be passed to the
188188
compilation context (akin to how `TargetFramework` is passed in today). An
189189
analyzer will use that to block use of APIs that are marked as preview as basing
190190
this off the language preview mode is nonsensical.
191191

192-
***Note:*** F# doesn't have this capability today.
192+
The way the compiler knows which features a targeted runtime supports is by
193+
looking at the `RuntimeFeature` type. Each runtime feature corresponds to a
194+
specific field on that type. If the type doesn't have the field, the runtime is
195+
considered as not-supporting the feature. To indicate that a feature is there
196+
but requires turning on preview mode, we'll simply mark the field with the
197+
`[RequiresPreviewFeatures]` attribute, just like any other preview API.
193198

194-
Since we use a separate property the user can have preview features off, but
195-
language is in preview mode. This would result in configuration where the user
196-
can use runtime features that are in preview.
199+
This solves two problems:
197200

198-
We have two options on how we can deal with this:
201+
* The customer is using a future version of C# where a given language feature is
202+
no longer considered "preview" and thus doesn't require `LangVersion` to be
203+
set to preview but in the targeted runtime the feature is still preview. When
204+
a language feature is used that requires the given runtime feature, the
205+
compiler should check if the field is marked as preview and fail unless the
206+
customer has turned preview mode on.
199207

200-
1. One option is to use `RuntimeFeatures` and mark the field as
201-
`[RequiresPreviewFeatures]` that causes the compiler to enforce the
202-
containing assembly/type/member to be marked as `[RequiresPreviewFeatures]`
203-
as well. Aleksey believes this check needs to be in-place regardless of
204-
number of checks. Another option is to simply fail the build as an invalid
205-
configuration.
208+
* The customer has manually set `LangVersion` to `Preview` but
209+
`EnablePreviewFeatures` is not configured (thus defaulting to `False`).
210+
Similar case as above, the customer can use any language feature that doesn't
211+
require runtime changes but as soon as a feature is used that requires a
212+
preview runtime feature, the compiler will report an error, demanding that
213+
preview mode needs to be turned on.
206214

207-
2. The other option is to simply fail the build with an error instructing the
208-
customer that this configuration is invalid. This could be in MSBuild and
209-
doesn't require work in the compiler.
210-
211-
***OPEN QUESTION**: Do we want to use the first or the second mechanism?*
215+
***Note:*** F# doesn't have the capability to use analyzers today. We can
216+
decided to make this a compiler feature for F#.
212217

213218
### API Analyzer
214219

@@ -451,3 +456,9 @@ preview features for the .NET platform:
451456
* Using this property might not work well for VB and F#
452457
* The biggest counter argument is that the compiler can be in stable version but
453458
the TFM you're targeting is not.
459+
* Due to the transitivity tracking, this can be a breaking change for anyone who
460+
has set `LangVersion` to `Preview`. That's because today, the resulting binary
461+
isn't marked as requiring callers to be in preview mode as well where we'd now
462+
demand this to be the case. We could address this by only applying the new
463+
behavior to code that is targeting .NET 6 (or higher), but this will likely
464+
still bite folks that upgrade to .NET 6.

0 commit comments

Comments
 (0)