Skip to content

Consolidate expression-form context restriction diagnostics - #55614

Merged
BillWagner merged 6 commits into
dotnet:mainfrom
BillWagner:expression-form
Aug 20, 2026
Merged

Consolidate expression-form context restriction diagnostics#55614
BillWagner merged 6 commits into
dotnet:mainfrom
BillWagner:expression-form

Conversation

@BillWagner

@BillWagner BillWagner commented Aug 20, 2026

Copy link
Copy Markdown
Member

Closes #55339

Summary

Consolidates five compiler diagnostics related to invalid expression contexts into a single reference article: expression-form-restrictions.md.

Included Diagnostics

Code Message
CS8115 A throw expression is not allowed in this context.
CS8185 A declaration is not allowed in this context.
CS8209 A value of type 'void' may not be assigned.
CS8310 Operator '{0}' cannot be applied to operand '{1}'
CS8312 Use of default literal is not valid in this context

Changes

  • Created docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md with content organized by remediation strategy:

    1. Throw expressions in expression contexts
    2. Declaration expressions in restricted contexts
    3. Type binding for default literals and typeless expressions
    4. Void-returning expression restrictions
  • Updated docs/csharp/language-reference/toc.yml to add TOC entry after "Lambda expressions"

  • Removed all five codes from docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md

Related Diagnostics

CS8188 (An expression tree may not contain a throw-expression) remains in expression-tree-restrictions.md per issue #55339 scope guidance.

Exhaustive Follow-up Search

A comprehensive search of all 194 catch-all diagnostics and Roslyn source identified four additional candidates fitting a related but distinct theme (varargs __arglist restrictions: CS1636, CS1669, CS8362, CS8378). Per issue triage, these have been deferred as a separate future varargs-theme consolidation. Candidates CS8081, CS8082, and CS8092 were classified as orthogonal (nameof syntax, parse-level errors) and excluded.

Standalone Diagnostic Article Consolidation Evaluation

Scope: Enumerating existing standalone CS????.md articles for potential merge into this theme.

Findings:

  • 514 total standalone diagnostic articles evaluated across docs/csharp/language-reference/compiler-messages/ and docs/csharp/misc/
  • 14 semantic candidates identified via keyword matching ("not allowed in context", "not valid in context", "cannot be applied", etc.)
  • 0 articles qualify for consolidation into expression-form-restrictions.md

Candidate Categories & Rationale for Exclusion:

  • Operator type incompatibility (CS0019, CS0023) — belong in operator overloading docs
  • Property/indexer accessors (CS0154, CS0271, CS0272) — belong in property/access-modifier docs
  • Keyword context restrictions (CS0175, CS0186, CS0119, CS1547) — belong in feature-specific docs (inheritance, iteration, type semantics)
  • By-reference returns (CS8156 + 20 more in 814x–817x range) — separate feature family; belong in ref-return docs
  • Parse/build errors (CS0726, CS1001, CS1583, CS1639) — metadata/build validation; not compiler expression diagnostics

Conclusion: The five-code article captures a unique, non-overlapping thematic scope: expressions whose syntactic form is prohibited in specific semantic contexts. Keeping the narrowly scoped five-code article aligns with the goal of shrinking article footprint through coherent thematic consolidation rather than forced merges.

Verification

  • ✅ Independent Fact Checker approval: all five Roslyn messages verified; code-set equality across front matter, master list, and TOC confirmed; YAML valid; no trailing whitespace
  • ✅ Thematic organization by remediation path
  • ✅ All anchors resolve; no anchor-tbd placeholders
  • ✅ Merged-content requirements met (no useful content discarded)
  • ✅ Standalone article consolidation search complete: 0 candidates identified

Notes for Reviewers

This is the first consolidation under the expression-form theme. The article is complete and narrowly scoped to expression-form context restrictions triggered directly during binding and compilation, not ref-safety or escape-scope analysis.


Internal previews

File Preview link
.openpublishing.redirection.csharp.json Preview published page
docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md Preview published page
docs/csharp/language-reference/toc.yml Preview published page
docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md Preview published page

Copilot AI lite review requested due to automatic review settings August 20, 2026 14:59
@BillWagner
BillWagner requested a review from a team as a code owner August 20, 2026 14:59
@dotnetrepoman dotnetrepoman Bot added this to the August 2026 milestone Aug 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request consolidates several C# compiler diagnostics about invalid expression forms/contexts into a single reference article, and wires the new article into the C# language reference navigation while removing the consolidated codes from the catch-all diagnostics page.

Changes:

  • Added a new consolidated compiler-messages article: expression-form-restrictions.md.
  • Added a TOC entry for the new article under C# language reference compiler messages.
  • Removed the consolidated diagnostic codes from the catch-all “sorry we don’t have specifics” page.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md Removes the consolidated diagnostic codes from the catch-all diagnostics list.
docs/csharp/language-reference/toc.yml Adds a TOC entry for the consolidated “Expression-form restrictions” article.
docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md Introduces the consolidated guidance article for CS8115, CS8185, CS8209, CS8310, and CS8312.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md Outdated
@BillWagner

Copy link
Copy Markdown
Member Author

Structural Revision Applied (Commit a9b5576)

Bill requested consolidation of the H3 subsections into a single H2 section with bullet-point remediation guidance. This commit implements that revision:

Changes:

  • Consolidated five separate H2/H3 subsections into one unified "Invalid expression contexts" H2 section
  • Restructured all eight diagnostic codes as scannable bullet-point remediation items
  • Updated master error list to link all codes to single anchor: #invalid-expression-contexts
  • Updated three redirects (cs0175.md, cs0186.md, cs1547.md) to point to consolidated anchor
  • Preserved all substantive examples and guidance from original structure

Style precedents followed:

  • delegate-function-pointer-diagnostics.md (22 diagnostics in H2 sections with bullet-point remediation)
  • foreach-diagnostics.md (18 diagnostics in H2 sections with bullet-point guidance)
  • async-await-errors.md (similar pattern with grouped remediation)

Validation Results:
✓ All 8 codes in front matter
✓ Single H2 anchor (#invalid-expression-contexts)
✓ 8 bullet-point remediation items
✓ 2 code examples preserved
✓ 3 redirects updated to unified anchor
✓ No trailing whitespace

Before/After:

  • BEFORE: 5 separate H2 sections with nested H3 subsections
  • AFTER: 1 unified H2 with cohesive bullet-point structure
  • Total line reduction: 118 - 37 = 81 lines (cleaner, more scannable format)

@BillWagner
BillWagner requested a lite review from Copilot August 20, 2026 20:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (10)

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:45

  • The PR summary says the article is organized into four remediation strategies, but the published page has only one section and a flat list of all diagnostics. Add the promised strategy headings for throw expressions, declarations, target typing, and void expressions, or update the description to match the content.
## Invalid expression contexts

The following diagnostics identify expressions that appear in contexts where they're not permitted. These errors typically arise when you use keywords, literals, or expressions in positions where the compiler doesn't permit them. The remediation strategy depends on the specific keyword or expression type.

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:49

  • The CS0186 guidance conflates a compile-time type-binding error with a runtime null check. foreach doesn't require a statically non-null collection: an IEnumerable variable can be null and still compile, while the bare null literal lacks a collection type and triggers CS0186. As written, these examples don't show how to fix the diagnostic and incorrectly state a compiler-enforced non-null requirement; explain the literal/type issue separately from runtime null handling.
- **CS0186**: *Use of null is not valid in this context*. You can't use the `null` literal in contexts where the compiler expects a concrete collection or enumerable. This error commonly occurs in `foreach` loops where `null` is provided as the collection to iterate over. In a `foreach` loop, the collection must implement `IEnumerable` (or similar interface) and must be non-null. If your data source might be null, check for null before the loop:

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:73

  • The CS8115 guidance lists a plain assignment and a method argument as valid locations for a throw expression, then says a value-returning method can't contain one. Throw expressions are restricted to contexts such as ?:, ??, and expression-bodied members or lambdas; a statement-bodied lambda or local function uses a throw statement, and string M() => throw ... is valid. Rewrite this paragraph so readers aren't directed to code that still produces CS8115.
- **CS8115**: *A throw expression is not allowed in this context.*. The compiler permits throw expressions only in specific contexts where an expression can appear and the exception is immediately propagated. Move the `throw` expression to a valid context, such as a conditional arm of a ternary or switch expression (where the throw is one of the arms), an assignment to evaluate the throw in place of the assigned value, or an argument to a method call where throwing is appropriate. A throw expression can also appear in a statement in a lambda or local function body (not within a method that must return a value). If the throw expression appears in a position where the expression value must be used (such as within arithmetic or operator expressions), extract it into a separate statement or conditional check.

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:79

  • new without parentheses isn't valid C# syntax, so (MyType)new isn't a usable example. Use target-typed new() or the explicit form new MyType() instead.
- **CS8310**: *Operator 'operator' cannot be applied to operand 'operand'* and **CS8312**: *Use of default literal is not valid in this context*. The `default` literal and typeless expressions (such as `null` or `new` without a target type) require a target type for the compiler to infer the expression type. When an operator is applied to these expressions without enough context, the compiler can't determine the operand type. Provide the target type by adding an explicit type cast (`(int)default` or `(MyType)new`), assigning to a typed variable (`int x = default;`), using a method parameter or return type to establish context, or using the verbose form `default(Type)` instead of the `default` literal for clarity. If the operator itself requires a specific type, ensure the operand can be implicitly converted to that type.

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:55

  • This C# sample is longer than six lines but remains inline, with no corresponding snippets/ source and project added. Move the example into the article's C# snippet folder and reference it with a :::code include so it follows the compiler-message articles' verified snippet convention.
  ```csharp
  IEnumerable collection = /* your source */;
  if (collection != null)
  {
      foreach (var item in collection)

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:75

  • out var and pattern variables are valid in expression-bodied lambdas, for example s => int.TryParse(s, out var value). Telling readers to remove declaration expressions from lambda expression bodies is therefore too broad and can make valid code look erroneous; describe the restricted declaration forms and contexts instead of banning expression-bodied lambdas.
- **CS8185**: *A declaration is not allowed in this context.*. The compiler permits declaration expressions (`out var`, pattern-matching declarations) only in specific positions, including `out` parameter declarations in method calls and in certain statement contexts. Remove the declaration expression from contexts where it's not permitted, such as lambda expression bodies (unless the lambda is a statement body), query expressions where the grammar forbids declarations, inside attribute arguments, or in contexts that require a read-only expression. If you need to use an out variable, call the method in a separate statement, then reference the resulting variable. Alternatively, use a local variable declaration before the expression.

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:65

  • T isn't declared in this article or in the preceding snippet, so the alternative block can't be copied or compiled as written. Use a concrete fallback type or introduce a complete generic context so the null-coalescing example demonstrates an actionable fix.
  foreach (var item in collection ?? Enumerable.Empty<T>())

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:45

  • The new article has no links to the language-reference pages or C# specification clauses that define these restrictions. Consolidated compiler-message articles provide those links in their resolution sections; add authoritative links for base, foreach, void, throw and declaration expressions, and target typing so readers can verify each correction.
The following diagnostics identify expressions that appear in contexts where they're not permitted. These errors typically arise when you use keywords, literals, or expressions in positions where the compiler doesn't permit them. The remediation strategy depends on the specific keyword or expression type.

.openpublishing.redirection.csharp.json:5835

  • These redirects are appended after the /redirections/proposals block and use the legacy source_path/redirect_document_id shape. Existing C# redirects are alphabetized by source path and use source_path_from_root; run the redirect creation or sorting script so these entries are inserted in the /docs/csharp/misc/ section with the repository's canonical format.
      "source_path": "docs/csharp/misc/cs0175.md",
      "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/expression-form-restrictions#invalid-expression-contexts",
      "redirect_document_id": "false"

docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md:7

  • These three diagnostics aren't in the linked issue's impacted set or the PR's stated five-code scope, yet they are added here and their standalone articles are deleted. The PR description also says the standalone-candidate evaluation found zero articles to merge. Please keep CS0175, CS0186, and CS1547 in their existing feature-specific articles, or update the approved scope and consolidation plan before merging.

This issue also appears in the following locations of the same file:

  • line 43
  • line 49
  • line 51
  • line 65
  • line 73
  • ...and 2 more
  - "CS0175"
  - "CS0186"
  - "CS1547"

Comment thread docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md Outdated
Comment thread docs/csharp/language-reference/compiler-messages/expression-form-restrictions.md Outdated
BillWagner and others added 6 commits August 20, 2026 17:01
…8115, CS8185, CS8209, CS8310, CS8312)

This article consolidates five compiler diagnostics related to invalid expression contexts:
- CS8115: Throw expressions in restricted contexts
- CS8185: Declaration expressions in restricted contexts
- CS8209: Void-returning expression restrictions
- CS8310: Operator binding for null/default/new
- CS8312: Default literal target type requirements

Content organized by remediation strategy. Codes removed from catch-all.
CS8188 preserved in expression-tree-restrictions.md per issue guidance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…context restrictions (CS0175, CS0186, CS1547)

Consolidate three standalone diagnostic articles (CS0175, CS0186, CS1547)
into expression-form-restrictions.md, broadening the article scope from 5
to 8 codes while maintaining thematic coherence:

MERGED CODES:
- CS0175: Use of keyword 'base' is not valid in this context
- CS0186: Use of null is not valid in this context
- CS1547: Keyword 'void' cannot be used in this context

CHANGES:
- Updated expression-form-restrictions.md with new 'Keyword and literal
  context restrictions' section containing substantive guidance from the
  three deleted standalone articles
- Merged all unique remediation information and examples
- Updated front matter f1_keywords and helpviewer_keywords (8 codes)
- Updated master error list with all 8 codes and exact Roslyn messages
- Updated TOC displayName with all 8 codes
- Removed old TOC entries for CS0175, CS0186, CS1547
- Created three redirects from old paths to new destination anchors
- Deleted three now-retired standalone files

FOOTPRINT REDUCTION: 3 standalone files → 1 consolidated article

VERIFICATION:
- YAML front matter valid
- All 8 codes present in f1_keywords/helpviewer_keywords
- No trailing whitespace
- Redirect JSON valid (1415 total entries)
- Exact Roslyn messages preserved per Bill's requirements

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…OC entry

The displayName folded scalar contained a duplicated five-code tail
(CS8115, CS8185, CS8209, CS8310, CS8312 with associated phrases) left
over from the original commit after the eight-code expansion appended
new content without removing the old suffix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… and bullet-point remediation

Consolidate five separate H2/H3 subsections into one unified 'Invalid expression
contexts' H2 section with scannable bullet-point remediation guidance. All eight
diagnostic codes (CS0175, CS0186, CS1547, CS8115, CS8185, CS8209, CS8310, CS8312)
now appear as cohesive remedy bullets, preserving all substantive examples and
guidance while following prevailing style in delegate-function-pointer-diagnostics.md
and foreach-diagnostics.md.

Changes:
- Removed old H2/H3 headers (Base keyword, Null iteration, Void keyword, Throw
  expressions, Declaration expressions, Target type required, Void-returning)
- Created unified 'Invalid expression contexts' H2 with all anchors consolidated
- Restructured master error list to link all codes to single #invalid-expression-contexts
- Updated redirects for cs0175.md, cs0186.md, cs1547.md to point to unified anchor
- Preserved all code examples, remediation patterns, and guidance from original

Validation: 8 codes in front matter, 8 bullet items, 2 code examples, 3 redirects
updated, no trailing whitespace, single H2 anchor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rm-restrictions.md

Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com>
@BillWagner
BillWagner enabled auto-merge (squash) August 20, 2026 21:14
@BillWagner
BillWagner merged commit 39261b5 into dotnet:main Aug 20, 2026
10 checks passed
@BillWagner
BillWagner deleted the expression-form branch August 21, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[C# diagnostics] - Expression-form context restrictions

3 participants