Track recent unsafe evolution decisions - #55939
Conversation
Update all docs for the unsafe evolution feature that's in preview for C# 15. Newer decisions aren't reflected in the docs. Fixes dotnet#55917
There was a problem hiding this comment.
🟡 Changes recommended
Several updated pages still need wording fixes to match the issue’s activation-tier requirements and to avoid ambiguous/misleading opt-in guidance.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates the C# 15 / .NET 11 preview documentation for the unsafe-evolution (“updated memory safety rules”) work, aligning terminology on requires-unsafe and adding opt-in guidance that points readers to the activation instructions.
Changes:
- Replaces “caller-unsafe” wording with requires-unsafe across the updated memory safety model docs.
- Adds/updates preview activation guidance (LangVersion=preview and
updated-memory-safety-rules) and links to the compiler-options page. - Moves/centralizes activation and cross-assembly behavior explanation into
compiler-options/language.md.
File summaries
| File | Description |
|---|---|
| docs/csharp/whats-new/csharp-15.md | Updates the C# 15 “Memory safety” section to reference requires-unsafe and preview activation. |
| docs/csharp/language-reference/xmldoc/recommended-tags.md | Updates <safety> tag guidance to match requires-unsafe and preview activation. |
| docs/csharp/language-reference/unsafe-code.md | Refreshes the updated memory safety model section and its terminology/activation references. |
| docs/csharp/language-reference/keywords/unsafe.md | Updates the unsafe keyword page note to reflect preview behavior and activation. |
| docs/csharp/language-reference/keywords/safe.md | Updates the safe keyword page to reflect preview activation and enforcement behavior. |
| docs/csharp/language-reference/compiler-options/language.md | Adds a dedicated section describing how to enable the updated memory safety rules. |
Review details
Suppressed comments (3)
docs/csharp/language-reference/keywords/safe.md:24
- "updated-rules opt-in" is ambiguous here; use the actual feature name so readers can map the comment to the documented activation knob.
// Syntax requires LangVersion preview; enforcement requires the updated-rules opt-in.
docs/csharp/language-reference/keywords/safe.md:39
- Same ambiguity as earlier: "updated-rules opt-in" doesn't tell readers what to set. Use the concrete feature name.
// Syntax requires LangVersion preview; enforcement requires the updated-rules opt-in.
docs/csharp/language-reference/unsafe-code.md:234
- This comment reads like the example won't compile unless you enable
updated-memory-safety-rules, but the feature gate is about enforcement/semantics, not parsing the member declaration. Clarify that the opt-in is required for enforcement.
// Preview: requires the updated-memory-safety-rules feature.
- Files reviewed: 6/6 changed files
- Comments generated: 6
- Review effort level: Lite
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
…idance with current diagnostics Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 034a2c2e-2753-46ff-b8b4-81ceb93073b3
…s= wording, caller-unsafe terminology, safety qualifier Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 034a2c2e-2753-46ff-b8b4-81ceb93073b3
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved documentation inaccuracies and missing activation and diagnostic updates remain.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (4)
docs/csharp/language-reference/compiler-messages/unsafe-code-errors.md:249
- The new paragraph correctly calls CS4004 legacy, but the page still presents it as a current diagnostic in the overview and detailed diagnostic list at lines 148 and 234. Readers can therefore still conclude that C# 15 reports the blanket error that this paragraph says no longer applies; remove CS4004 from the current lists or label those entries as legacy.
- Treat **CS4004** as legacy guidance. In C# 14 and earlier, `await` inside an unsafe context isn't allowed. Under the C# 15 preview memory safety changes, `await` is allowed in an unsafe context, so this blanket restriction no longer describes the current rule.
docs/csharp/language-reference/compiler-messages/unsafe-code-errors.md:57
- The page now advertises CS9392, CS9396, CS9397, and CS9398 in its frontmatter, but the Unsafe code
displayNameindocs/csharp/language-reference/toc.yml:804-811still ends at CS9390. Compiler-message pages keep this diagnostic list in both frontmatter and the TOC, so add the four new IDs to the TOC as well.
- "CS9392"
- "CS9396"
- "CS9397"
- "CS9398"
docs/csharp/language-reference/compiler-messages/unsafe-code-errors.md:293
- A primary-constructor parameter isn't a supported place for the
safe/unsafefield annotation. The unsafe-evolution design moves the requirement to an auto-property or field-like event when the field is synthesized; telling readers to put the modifier on the parameter leads to invalid syntax.
- Mark every instance field in a type with `[StructLayout(LayoutKind.Explicit)]` or `[ExtendedLayout]` as either `unsafe` or `safe` (**CS9392**). If the field is synthesized for an auto-property, field-backed property, primary-constructor parameter, or field-like event, put the modifier on the property, parameter, or event that owns that generated field.
docs/csharp/language-reference/unsafe-code.md:224
- The terminology update removes the historical term entirely. Because the requested change keeps caller-unsafe only as a historical synonym, retain one parenthetical here (for example, “formerly called caller-unsafe”) while using requires-unsafe as the canonical term everywhere else.
In the original model, the `unsafe` modifier on a member only allows pointers in the member's signature and body. It doesn't inform callers about safety. The updated model gives the modifier meaning for callers. When you mark a member `unsafe`, the compiler treats it as *requires-unsafe*: every caller must invoke it from an `unsafe` context, and the obligation to audit safety moves to that caller.
- Files reviewed: 8/8 changed files
- Comments generated: 3
- Review effort level: Lite
Add additional updated diagnostics for unsafe code.
There was a problem hiding this comment.
🟡 Changes recommended
Two moderate documentation corrections and several minor fixes remain unresolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (5)
Previously missed (1) — in code that hasn't changed since the last review.
docs/csharp/language-reference/operators/await.md:4
- This Markdown page has substantive content changes in the PR, but its front matter still lacks the required AI-use disclosure. Add
ai-usage: ai-assistedso the updatedawaitguidance is identified as AI-assisted.
docs/csharp/language-reference/compiler-messages/attribute-usage-errors.md:260
- Use an API cross-reference for
ExtendedLayoutAttribute, as the same sentence already does forStructLayoutAttribute. Leaving the newly documented attribute as plain code prevents readers from navigating to its API reference.
- Don't apply both <xref:System.Runtime.InteropServices.StructLayoutAttribute> and `ExtendedLayoutAttribute` to the same type (**CS9351**). These two layout attributes represent mutually exclusive layout strategies under the [updated memory safety model](../unsafe-code.md#the-updated-memory-safety-model-preview): explicit layout requires a `FieldOffset` on every instance field, while extended layout lets the runtime choose field offsets while still requiring each field to be marked `safe` or `unsafe`. Remove one of the two attributes from the type declaration.
docs/csharp/language-reference/compiler-messages/unsafe-code-errors.md:293
safeandunsafemodifiers are currently disallowed on primary-constructor parameters, so this instruction doesn't give a compilable way to satisfy CS9392 for a captured primary-constructor field. The feature proposal leaves that case as an open design question; remove or qualify the parameter advice and document a supported workaround instead.
- Mark every instance field in a type with `[StructLayout(LayoutKind.Explicit)]` or `[ExtendedLayout]` as either `unsafe` or `safe` (**CS9392**). If the field is synthesized for an auto-property, field-backed property, primary-constructor parameter, or field-like event, put the modifier on the property, parameter, or event that owns that generated field.
docs/csharp/language-reference/unsafe-code.md:396
- The new em dash has spaces on both sides, which conflicts with the documentation style used for dashes. Write the phrase with closed punctuation instead of
layout — that is, marked ....
A `readonly unsafe` field pairs the contract with a built-in guard: `unsafe` names the invariant, and `readonly` prevents a write that could break it after construction. Marking a property or an event `unsafe` doesn't make its backing field requires-unsafe. In a type with explicit or extended layout — that is, marked with <xref:System.Runtime.InteropServices.StructLayoutAttribute> set to `LayoutKind.Explicit`, or with <xref:System.Runtime.InteropServices.ExtendedLayoutAttribute> — you mark every field either `safe` or `unsafe`.
docs/csharp/whats-new/csharp-15.md:162
- Link the public attribute type with an API cross-reference instead of leaving the fully qualified type name as plain text. The activation section in
compiler-options/language.mdalready uses<xref:System.Runtime.CompilerServices.MemorySafetyRulesAttribute>, and the cross-reference makes the new C# 15 guidance navigable.
When you enable the updated rules, `unsafe` on a member marks it as *requires-unsafe*: the audit obligation flows to the caller, who must use the member from an `unsafe` context. The compiler records the assembly's use of the updated rules with the `System.Runtime.CompilerServices.MemorySafetyRulesAttribute` attribute. The model also adds a `safe` contextual keyword that marks `extern` members and fields in explicit or extended layout types as safe. Together, these rules make the boundaries of potential memory unsafety explicit across a program.
- Files reviewed: 13/13 changed files
- Comments generated: 6
- Review effort level: Lite
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
It added blank lines for fun.
Update all docs for the unsafe evolution feature that's in preview for C# 15. Newer decisions hadn't been reflected in the docs.
Fixes #55917 - Updated language reference documents.
Fixes #55918 - Updated diagnostics, part 1.
Fixes #55919 - Updated diagnostics, part 2.
Fixes #55920 - Updated diagnostics, part 3.
Internal previews
Toggle expand/collapse
Build report