Skip to content

Conversation

@StephaneDelcroix
Copy link
Contributor

@StephaneDelcroix StephaneDelcroix commented Dec 1, 2025

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description

When binding path contains nullable access (e.g., Child.Message where Child is nullable), the XAML SourceGen was generating a setter that assigns a nullable value to a non-nullable property, causing CS8601 "Possible null reference assignment" error.

Before (generated code):

global::System.Action<MainPageVm, string?>? setter = static (source, value) =>
{
    if (source.Child is {} p0)
    {
        p0.Message = value;  // CS8601: value is string? but Message is string
    }
};

After (generated code):

global::System.Action<MainPageVm, string?>? setter = static (source, value) =>
{
    if (value is null)  // NEW: early return for null values
    {
        return;
    }
    if (source.Child is {} p0)
    {
        p0.Message = value;  // Now safe: value is not null
    }
};

Changes

  • Added early return for null values in AppendSetterLambda when:
    • PropertyType.IsNullable is true (the binding path involves nullable access)
    • SetterOptions.AcceptsNullValue is false (the target property does not accept null)
  • This mirrors the existing logic in BindingCodeWriter.cs used for C# binding interceptors
  • Updated the CorrectlyDetectsNullableReferenceTypes test to expect the new null-check

Reproduction

The issue was reproduced using the test project from this comment.

@StephaneDelcroix StephaneDelcroix added this to the .NET 10.0 SR2 milestone Dec 1, 2025
@StephaneDelcroix StephaneDelcroix added area-xaml XAML, CSS, Triggers, Behaviors xsg Xaml sourceGen labels Dec 1, 2025
@StephaneDelcroix StephaneDelcroix changed the title Fix CS8601 error in XAML SourceGen setter for nullable reference types [XSG] Fix CS8601 error in XAML SourceGen setter for nullable reference types Dec 1, 2025
Copilot finished reviewing on behalf of StephaneDelcroix December 1, 2025 15:11
Copy link
Contributor

Copilot AI left a comment

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 fixes CS8601 compiler errors that occur when XAML SourceGen generates setters for bindings with nullable access paths targeting non-nullable properties. The fix adds null checks in the generated setter code to prevent assigning potentially null values to non-nullable properties.

Key Changes:

  • Added early return logic in AppendSetterLambda for nullable values when the target property doesn't accept nulls
  • Handles both nullable reference types (with is null check) and nullable value types (with HasValue check and .Value unwrapping)
  • Updated test expectations to reflect the new null-check behavior

Reviewed changes

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

File Description
src/Controls/src/SourceGen/CompiledBindingMarkup.cs Implements null-checking logic in setter generation that mirrors the existing implementation in BindingCodeWriter.cs for C# binding interceptors
src/Controls/tests/SourceGen.UnitTests/InitializeComponent/CompiledBindings.cs Updates test expectations to include the new null-check in generated setters for nullable reference type bindings

Comment on lines +424 to +427
if (value is null)
{
return;
}
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The test only covers nullable reference types. Consider adding a test case for nullable value types (e.g., int?, DateTime?) to ensure the HasValue check and .Value unwrapping logic works correctly. For example, a binding path like Product?.Quantity where Product is nullable and Quantity is int?, being bound to a non-nullable int property.

Copilot uses AI. Check for mistakes.
When binding path contains nullable access (e.g., Child.Message where Child
is nullable), the generated setter was assigning a nullable value to a
non-nullable property, causing CS8601 'Possible null reference assignment'.

The fix adds an early return for null values in the setter when:
- PropertyType.IsNullable is true (the binding path involves nullable access)
- SetterOptions.AcceptsNullValue is false (the target property doesn't accept null)

This mirrors the existing logic in BindingCodeWriter.cs used for C# binding
interceptors.

Fixes #32893
@StephaneDelcroix StephaneDelcroix force-pushed the fix/cs8601-xaml-sourcegen-nullable-setter branch from 3b044fc to bdb47d6 Compare December 1, 2025 15:18
Copy link
Member

@simonrozsival simonrozsival left a comment

Choose a reason for hiding this comment

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

I'd like to see more test coverage:

  • a scenario with a value type that's at the end of an expression with conditional access in the middle
  • a scenario with a non-nullable reference type that's at the end of an expression with conditional access in the middle
  • a scenario with a nullable reference type that's at the end of an expression with conditional access in the middle -- should not contain the early return

The test verifies that binding to non-nullable value type properties through
nullable paths works correctly. In XAML SourceGen, value types accessed through
nullable paths remain non-nullable (using ?? default fallback in getter) rather
than becoming Nullable<T>, so the setter uses pattern matching instead of
HasValue checks.
@simonrozsival
Copy link
Member

@copilot I'd like to see more test coverage:

  • a scenario with a value type that's at the end of an expression with conditional access in the middle
  • a scenario with a non-nullable reference type that's at the end of an expression with conditional access in the middle
  • a scenario with a nullable reference type that's at the end of an expression with conditional access in the middle -- should not contain the early return

What other scenarios would be helpful to allow us to prevent future regressions with nullable types in compiled bindings?

Copy link
Contributor

Copilot AI commented Dec 2, 2025

@simonrozsival I've opened a new pull request, #32951, to work on those changes. Once the pull request is ready, I'll request review from you.

…al access paths (#32951)

* Initial plan

* Add comprehensive nullable type tests for conditional access paths

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

* Refactor test assertions to use regex matching and full expressions

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
@StephaneDelcroix
Copy link
Contributor Author

/azp run MAUI-UITests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@StephaneDelcroix StephaneDelcroix merged commit aae0d33 into main Dec 3, 2025
161 of 163 checks passed
@StephaneDelcroix StephaneDelcroix deleted the fix/cs8601-xaml-sourcegen-nullable-setter branch December 3, 2025 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-xaml XAML, CSS, Triggers, Behaviors xsg Xaml sourceGen

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants