Skip to content

Conversation

@jnm2
Copy link
Contributor

@jnm2 jnm2 commented Aug 9, 2025

While working on #1386, I found some spec bugs I could fix.

@jnm2 jnm2 force-pushed the jnm2/nrt_type_params branch from 62bd6f5 to a4af924 Compare August 9, 2025 20:38
### 8.2.1 General

A reference type is a class type, an interface type, an array type, a delegate type, or the `dynamic` type. For each non-nullable reference type, there is a corresponding nullable reference type noted by appending the `?` to the type name.
A reference type is a class type, an interface type, an array type, a delegate type, the `dynamic` type, or any type parameter that is constrained to be a reference type (that is, any type parameter with the reference type constraint or a class type constraint ([§15.2.5](classes.md#1525-type-parameter-constraints))). For each non-nullable reference type, there is a corresponding nullable reference type noted by appending the `?` to the type name.
Copy link
Contributor Author

@jnm2 jnm2 Aug 9, 2025

Choose a reason for hiding this comment

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

This borrows the existing language which appears in https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/types.md#8312-nullable-value-types:

Conversely, a non-nullable value type is any value type other than System.Nullable<T> and its shorthand T? (for any T), plus any type parameter that is constrained to be a non-nullable value type (that is, any type parameter with a value type constraint (§15.2.5)).

> *Note*: To specify that a type argument is a nullable reference type, don’t add the nullable type annotation as a constraint (use `T : class` or `T : BaseClass`), but use `T?` throughout the generic declaration to indicate the corresponding nullable reference type for the type argument. *end note*
<!-- Remove in C# 9, when this is allowed -->
The nullable type annotation, `?`, can’t be used on an unconstrained type argument.
Copy link
Contributor Author

@jnm2 jnm2 Aug 9, 2025

Choose a reason for hiding this comment

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

Here is an example of a type parameter that is not unconstrained, and thus was not disallowed by the original statement, which is still not allowed to use ?:

#nullable enable

class C
{
    void M<T>(T? test) where T : System.IDisposable
    {
    }
}

Roslyn:

A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '9.0' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.

@jnm2 jnm2 force-pushed the jnm2/nrt_type_params branch from a4af924 to 2b23085 Compare August 9, 2025 20:44
Comment on lines +448 to +449
<!-- Add in C# 9, when `?` is allowed on nullable reference type parameters. -->
<!-- For a type parameter `T` when the type argument is a nullable reference type `C?`, instances of `T?` are interpreted as `C?`, not `C??`. -->
Copy link
Contributor Author

@jnm2 jnm2 Aug 9, 2025

Choose a reason for hiding this comment

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

Instances of T? do not exist when the type argument is a nullable reference type C? in C# 8, e.g.:

#nullable enable

class C
{
    void M<T>(T? test) where T : class?
    {
    }
}

Roslyn:

A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '9.0' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.

@jnm2 jnm2 force-pushed the jnm2/nrt_type_params branch from fa3774f to 918e022 Compare August 9, 2025 20:55
Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

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

These all look good to me.

I'd like to have another set of eyes on them before merging, or have brief review in our next meeting.

/cc @jskeet

@jnm2 jnm2 requested a review from jskeet September 4, 2025 20:41
@jnm2
Copy link
Contributor Author

jnm2 commented Sep 27, 2025

Oops! Missed bringing this to the meeting since @jskeet didn't have a chance to look at it. I'll add the tag now.

@jnm2 jnm2 added the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Sep 27, 2025
@jnm2 jnm2 merged commit b79db0e into draft-v8 Oct 20, 2025
9 checks passed
@jnm2 jnm2 deleted the jnm2/nrt_type_params branch October 20, 2025 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

meeting: discuss This issue should be discussed at the next TC49-TG2 meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants