@@ -179,36 +179,41 @@ dependencies ([discussed later](#api-analyzer)).
179
179
180
180
### Compilation context
181
181
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.
186
186
187
187
In addition, the property ` EnablePreviewFeatures ` should be passed to the
188
188
compilation context (akin to how ` TargetFramework ` is passed in today). An
189
189
analyzer will use that to block use of APIs that are marked as preview as basing
190
190
this off the language preview mode is nonsensical.
191
191
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.
193
198
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:
197
200
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.
199
207
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 .
206
214
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#.
212
217
213
218
### API Analyzer
214
219
@@ -451,3 +456,9 @@ preview features for the .NET platform:
451
456
* Using this property might not work well for VB and F#
452
457
* The biggest counter argument is that the compiler can be in stable version but
453
458
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