Skip to content

[wasm] Clean up browser/CoreCLR test exclusions and enable passing tests#126469

Draft
radekdoulik wants to merge 86 commits intodotnet:mainfrom
radekdoulik:wasm-coreclr-enable-passing-tests
Draft

[wasm] Clean up browser/CoreCLR test exclusions and enable passing tests#126469
radekdoulik wants to merge 86 commits intodotnet:mainfrom
radekdoulik:wasm-coreclr-enable-passing-tests

Conversation

@radekdoulik
Copy link
Copy Markdown
Member

Note

This PR was AI/Copilot-generated.

Summary

  1. Remove 5 redundant CoreCLR-specific exclusions already covered by general browser exclusion blocks
  2. Enable 2 test suites that now pass on browser-wasm/CoreCLR

Tests re-enabled

Suite Passed Failed Skipped
Microsoft.Extensions.Http.Tests 84 0 76
System.Threading.Overlapped.Tests 12 0 0

Redundant exclusions removed

These 5 were already excluded by general TargetOS=browser blocks (not CoreCLR-specific):

  • Microsoft.Extensions.DependencyInjection.Tests
  • System.Linq.Expressions.Tests
  • System.Diagnostics.Tracing.Tests
  • System.Dynamic.Runtime.Tests
  • System.Text.Json.Tests

Validation

Tests verified locally with:

./dotnet.sh build -c Debug /t:Test <csproj> \
  /p:TargetOS=browser /p:TargetArchitecture=wasm \
  /p:RuntimeFlavor=CoreCLR /p:Scenario=WasmTestOnChrome

radekdoulik and others added 2 commits April 2, 2026 14:33
…eneral browser exclusions

These 5 test suites are already excluded by general browser/wasm
exclusion blocks that apply regardless of RuntimeFlavor. The
CoreCLR-specific exclusions were redundant:

- Microsoft.Extensions.DependencyInjection.Tests
- System.Linq.Expressions.Tests
- System.Diagnostics.Tracing.Tests
- System.Dynamic.Runtime.Tests
- System.Text.Json.Tests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
These 2 test suites now pass on browser-wasm with CoreCLR:

- Microsoft.Extensions.Http.Tests (84 passed, 76 skipped, 0 failed)
- System.Threading.Overlapped.Tests (12 passed, 0 failed)

Verified by running with:
  ./dotnet.sh build -c Debug /t:Test <csproj>     /p:TargetOS=browser /p:TargetArchitecture=wasm     /p:RuntimeFlavor=CoreCLR /p:Scenario=WasmTestOnChrome

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@radekdoulik radekdoulik added this to the Future milestone Apr 2, 2026
Copilot AI review requested due to automatic review settings April 2, 2026 13:03
Copy link
Copy Markdown
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 PR updates the library test traversal exclusions for the browser-wasm/CoreCLR configuration to remove some exclusions and allow additional test suites to run.

Changes:

  • Re-enables Microsoft.Extensions.Http.Tests and System.Threading.Overlapped.Tests for browser/CoreCLR by removing their exclusions.
  • Removes several browser/CoreCLR exclusions that are described as redundant in the PR description.

The 5 test suites (DependencyInjection, Linq.Expressions, Diagnostics.Tracing,
Dynamic.Runtime, Text.Json) were removed assuming they were covered by general
browser exclusions. However, the general block at line 397 only applies when
BuildAOTTestsOnHelix=true, which is not set for the non-AOT LibraryTestsCoreCLR
pipeline. Restore them to fix CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 15 commits April 9, 2026 12:35
…otnet#126468)

Dependabot updates pinned SHA refs but doesn't correct the inline
version comment when it was already wrong. Audited all
`.github/workflows/*.yml` files by resolving each pinned SHA against its
upstream tags.

Two mismatches found and fixed:

- **`copilot-echo.lock.yml`** (5 occurrences):
`github/gh-aw-actions/setup@536ea1b...` commented as `# v0.63.0`, actual
tag is `v0.65.4`
- **`labeler-*.yml`** (13 occurrences across 5 files):
`dotnet/issue-labeler/*@46125e8...` commented as `# v2.0.0`, actual tag
is `v2.0.0-release`

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: akoeplinger <1376924+akoeplinger@users.noreply.github.com>
…dotnet#126464)

## Description

Skip tests that throw `PlatformNotSupportedException` or fail due to
platform-specific behavior on Apple mobile (iOS, tvOS, MacCatalyst) and
Android devices.

Fixes dotnet#126455
Fixes dotnet#126456
Fixes dotnet#126462
Fixes dotnet#126463

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…#126370)

Interpreter IR was logged through functionality inside InterpCompiler
class via PrintCompiledCode (only during compilation via
DOTNET_InterpDump). This commit extracts this logic outside of the
class, passing all necessary information as arguments (dataItems,
pointer to name map, etc). This also adds code size field on the
InterpMethod since this information wasn't easily available. Some data
will not be pretty printed, because we don't have access to the
jitinterface methods.

Example for crash in InterpExecMethod:

```
(lldb) frame sel 4
frame 4: 0x00007ffff72f8b19 libcoreclr.so`InterpExecMethod(pInterpreterFrame=0x00007ffb899eaa20, pFrame=0x00007ffb899e92b0, pThreadContext=0x00007ffb78009000, pExceptionClauseArgs=0x0000000000000000) at interpexec.cpp:2566:42 [opt]
   2563	                case INTOP_STIND_O:
   2564	                {
   2565	                    char *dst = LOCAL_VAR(ip[1], char*);
-> 2566	                    OBJECTREF storeObj = LOCAL_VAR(ip[2], OBJECTREF);
   2567	                    NULL_CHECK(dst);
   2568	                    SetObjectReferenceUnchecked((OBJECTREF*)(dst + ip[3]), storeObj);
   2569	                    ip += 4;
(lldb) call InterpDumpIR(pFrame->startIp)
Dumping interpreter IR at 0x7fff7b514460 (method 0x7fff7a8c9230))
0008: IR_0000: initlocals     [nil <- nil], 16,16
0014: IR_0003: safepoint      [nil <- nil],
0018: IR_0004: mov.8          [48 <- 0],
0024: IR_0007: ldc.i4         [32 <- nil], 0
0030: IR_000a: ldc.i4         [64 <- nil], 0
003c: IR_000d: ldloca         [40 <- nil], 16
0048: IR_0010: zeroblk.imm    [nil <- 40], 8
0054: IR_0013: mov.vt         [72 <- 16], 8
0064: IR_0017: conv.u1.i4     [56 <- 32],
0070: IR_001a: call           [32 <- 48], 0x7fff79ea2030
0080: IR_001e: mov.8          [32 <- 0],
008c: IR_0021: mov.8          [40 <- 8],
0098: IR_0024: stind.o        [nil <- 32 40], 56
00a8: IR_0028: ret.void       [nil <- nil],
End of method: 00ac: IR_0029
(lldb) dumpmd 0x7fff7a8c9230
Method Name:          System.Threading.Tasks.Task`1[[System.__Canon, System.Private.CoreLib]]..ctor(System.__Canon)
...
(lldb) dumpmd 0x7fff79ea2030
Method Name:          System.Threading.Tasks.Task..ctor(Boolean, System.Threading.Tasks.TaskCreationOptions, System.Threading.CancellationToken)
...
```
This pull request refactors memory management in the createdump and
related debugging code by removing the legacy `ArrayHolder` (and some
other holders) and replacing them with new, more robust holder types
defined in `holder.h`. The changes modernize resource management,
improve safety, and simplify code by consolidating smart pointer logic.
Additionally, some minor improvements and cleanups are made to COM
interface holders and other utility types.

The most important changes are:

**Memory Management Refactoring:**

* Removed the entire `ArrayHolder` implementation (`arrayholder.h`) and
replaced all usages with new holder types like `AStringHolder`,
`WStringHolder`, and `NewArrayHolder`, as defined in `holder.h`.
* Introduced new, safer resource management types in `holder.h`,
including `LifetimeHolder`, `MapViewHolder`, and `LocalAllocHolder`, and
updated their usage throughout the codebase.

**Holder Type Consolidation and Cleanup:**

* Replaced `NonVMComHolder` with `ReleaseHolder` for COM interface
management, and removed redundant holder aliases.
* Cleaned up unused or legacy macros, includes, and warning suppressions
related to holders.

**Minor Fixes and Improvements:**

* Fixed a typo in a comment (`Relesae` → `Release`).
* Updated code to use `.Extract()` instead of `.Detach()` for stack
frame management.
* Improved contract annotations and resource release logic for new
holder types.

These changes collectively improve code safety, maintainability, and
clarity by consolidating resource management logic and removing legacy
code.This pull request refactors resource management throughout the
CoreCLR debugging components by replacing the custom `ArrayHolder` and
`NonVMComHolder` smart pointer classes with new, more general-purpose
holders defined in `holder.h`. It also removes the now-unused
`arrayholder.h` and `releaseholder.h` files and introduces more robust,
trait-based holder implementations, improving code clarity and
maintainability. The changes touch many files, especially those dealing
with memory and handle management, and update usage sites accordingly.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
...instead of BeforeTargets/AfterTargets.

Redefine the SDK's empty NativeCompile placeholder target with the
actual NativeAOT compilation pipeline, replacing the fragile
BeforeTargets/AfterTargets hooks that previously sequenced ILC into the
publish flow.

- Rename ComputeLinkedFilesToPublish to NativeCompile in
Publish.targets, removing
AfterTargets="ComputeResolvedFilesToPublishList"
- Remove BeforeTargets="Publish" from SetupProperties,
ComputeIlcCompileInputs, and ImportRuntimeIlcPackageTarget (all
reachable via DependsOnTargets chains)
- Keep empty ComputeLinkedFilesToPublish and CopyNativeBinary for
back-compat

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…indows NTFS pending-delete race (dotnet#125915)

Two race conditions in the FSW test retry infrastructure caused
intermittent `DirectoryNotFoundException` on Windows x86/x64 CI.

## Description

**Root causes:**

- **NTFS pending-delete race**: `RemoveDirectory` marks a directory for
deletion but doesn't remove it until all handles close. The cleanup
lambda called `directoryOne.Create()` while the path was still in
pending-delete state — Windows reported it as existing, so
`CreateDirectory` silently no-oped. Once the pending delete completed,
the directory was gone, and the next retry's `Delete()` threw
`DirectoryNotFoundException`.

- **`RecreateWatcher` handle leak**: Each retry created a new
`FileSystemWatcher` without disposing the previous one. Accumulated
watchers holding handles extended the pending-delete window.

**Fixes:**

- **`ExpectEvent` (test utility)**: Simplified the retry loop —
`RecreateWatcher` always receives the original `watcher` as its argument
(since it only reads state to construct a new instance). The newly
created watcher is declared with `using` scoped inside the loop body, so
it is unconditionally disposed after each retry attempt without needing
outer `try/finally` or `newWatcher`/`previousWatcher` tracking
variables:

```csharp
// On first attempt: use original watcher directly
// On subsequent attempts:
using FileSystemWatcher newWatcher = RecreateWatcher(watcher);
result = ExecuteAndVerifyEvents(newWatcher, ...);
```

- **`FileSystemWatcher_Directory_Delete_MultipleFilters`** and
**`FileSystemWatcher_File_Delete_MultipleFilters`**: Cleanup lambdas now
call `WaitForPathToBeDeleted(path)` before `Create()`, ensuring the path
is fully gone before recreating it and surfacing a clear diagnostic if
the timeout is exceeded. The wait logic is extracted into a shared
helper method `WaitForPathToBeDeleted(string path)` on
`FileSystemWatcherTest`, which uses `Path.Exists` and the existing
`RetryDelayMilliseconds` constant as the timeout:

```csharp
// Before
cleanup: () => directoryOne.Create()

// After
cleanup: () =>
{
    WaitForPathToBeDeleted(directoryOne.FullName);
    directoryOne.Create();
}
```

```csharp
public static void WaitForPathToBeDeleted(string path)
{
    Assert.True(
        SpinWait.SpinUntil(() => !Path.Exists(path), RetryDelayMilliseconds),
        $"Timed out waiting for '{path}' to be deleted.");
}
```

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>Could not find a part of the path in
System.IO.Tests.FileSystemWatcherTests.FileSystemWatcher_Directory_Delete_MultipleFilters</issue_title>
<issue_description>### Error Blob

```json
{
  "ErrorMessage": "at System.IO.Tests.FileSystemWatcherTests.FileSystemWatcher_Directory_Delete_MultipleFilters",
  "BuildRetry": true,
  "ErrorPattern": "",
  "ExcludeConsoleLog": false
}
```


### Reproduction Steps

- Found in unrelated 7.0 PR:
dotnet#97883
- Build:
https://dev.azure.com/dnceng-public/public/_build/results?buildId=551129
- Queue: `Libraries Test Run checked coreclr windows x86 Debug`
- Job results:
https://dev.azure.com/dnceng-public/public/_build/results?buildId=551129&view=logs&j=215a953c-1e4b-5cc0-95e2-5484aabbe659&t=312e0115-80c6-5d8d-a731-029b3098bcf6
- Log file:
https://helixre107v0xd1eu3ibi6ka.blob.core.windows.net/dotnet-runtime-refs-pull-97883-merge-de8975dcd8f044af9b/System.IO.FileSystem.Watcher.Tests/1/console.87568cb0.log?helixlogtype=result
- Output:
```
===========================================================================================================

C:\h\w\C0550A4F\w\A85A0959\e>"C:\h\w\C0550A4F\p\dotnet.exe" exec --runtimeconfig System.IO.FileSystem.Watcher.Tests.runtimeconfig.json --depsfile System.IO.FileSystem.Watcher.Tests.deps.json xunit.console.dll System.IO.FileSystem.Watcher.Tests.dll -xml testResults.xml -nologo -nocolor -notrait category=IgnoreForCI -notrait category=OuterLoop -notrait category=failing  
  Discovering: System.IO.FileSystem.Watcher.Tests (method display = ClassAndMethod, method display options = None)
  Discovered:  System.IO.FileSystem.Watcher.Tests (found 174 of 209 test cases)
  Starting:    System.IO.FileSystem.Watcher.Tests (parallel test collections = on, max threads = 4)
    System.IO.Tests.FileSystemWatcherTests.FileSystemWatcher_Directory_Delete_MultipleFilters [FAIL]
      System.IO.DirectoryNotFoundException : Could not find a part of the path 'C:\h\w\C0550A4F\t\#FileSystemWatcherTests_eq2ujqlt.lfo\FileSystemWatcher_Directory_Delete_MultipleFilters_1009_7eam6lig\FileSystemWatcher_Directory_Delete_MultipleFilters_1010_cn2nu7w1'.
      Stack Trace:
        /_/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Windows.cs(436,0): at System.IO.FileSystem.RemoveDirectoryInternal(String fullPath, Boolean topLevel, Boolean allowDirectoryNotEmpty)
        /_/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Windows.cs(261,0): at System.IO.FileSystem.RemoveDirectory(String fullPath, Boolean recursive)
        /_/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs(212,0): at System.IO.DirectoryInfo.Delete(Boolean recursive)
        /_/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs(208,0): at System.IO.DirectoryInfo.Delete()
        /_/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs(1019,0): at System.IO.Tests.FileSystemWatcherTests.<>c__DisplayClass61_0.<FileSystemWatcher_Directory_Delete_MultipleFilters>b__0()
        /_/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs(309,0): at System.IO.Tests.FileSystemWatcherTest.ExecuteAndVerifyEvents(FileSystemWatcher watcher, WatcherChangeTypes expectedEvents, Action action, Boolean assertExpected, String[] expectedPaths, Int32 timeout)
        /_/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs(198,0): at System.IO.Tests.FileSystemWatcherTest.ExpectEvent(FileSystemWatcher watcher, WatcherChangeTypes expectedEvents, Action action, Action cleanup, String[] expectedPaths, Int32 attempts, Int32 timeout)
        /_/src/libraries/System.IO.FileSystem.Watcher/tests/Utility/FileSystemWatcherTest.cs(168,0): at System.IO.Tests.FileSystemWatcherTest.ExpectEvent(FileSystemWatcher watcher, WatcherChangeTypes expectedEvents, Action action, Action cleanup, String expectedPath, Int32 attempts, Int32 timeout)
        /_/src/libraries/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.unit.cs(1019,0): at System.IO.Tests.FileSystemWatcherTests.FileSystemWatcher_Directory_Delete_MultipleFilters()
           at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
        /_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInvoker.cs(81,0): at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
  Finished:    System.IO.FileSystem.Watcher.Tests
=== TEST EXECUTION SUMMARY ===
   System.IO.FileSystem.Watcher.Tests  Total: 327, Errors: 0, Failed: 1, Skipped: 0, Time: 10.115s
----- end Fri 02/02/2024 18:18:47.75 ----- exit code 1 ----------------------------------------------------------
```
<!-- Known issue validation start -->
 ### Known issue validation
**Build: :mag_right:** https://dev.azure.com/dnceng-public/publ...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes dotnet#98193

<!-- START COPILOT CODING AGENT TIPS -->
---

📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs),
[Azure Boards](https://gh.io/cca-azure-boards-docs) or
[Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in
one click without leaving your project management tool.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: danmoseley <6385855+danmoseley@users.noreply.github.com>
Co-authored-by: Dan Moseley <danmose@microsoft.com>
…ed loops (dotnet#125457)

## Fix NonBacktracking correctness issues and exponential blowup on
nested loops

Fixes dotnet#84188

### Problem

The NonBacktracking regex engine has exponential time complexity on
deeply nested loop patterns like `((a)*)*`. The root cause is in the
Brzozowski derivative computation: when the left side of a `Concat` is
nullable (as with `*` loops), the derivative creates a 2-branch
`Alternate`. With N levels of nesting, this produces O(2^N) intermediate
nodes per derivative step.

| Nesting depth | Input length | Time (before) |
|---------------|-------------|---------------|
| 15 | 1000 | 1.62s |
| 17 | 1000 | 5.93s |
| 20 | 1000 | >60s |
| 2000 | 1 | 10.7s |

The last row shows that even matching a **single character** takes 10.7s
at depth 2000 --- the bottleneck is the first derivative computation,
not cumulative per-character cost.

### Fix

Three complementary changes:

**1. Loop flattening in `CreateLoop`** --- Simplify `(R*)*` to `R*` (and
variants `(R+)*`, `(R*)+`) during symbolic AST construction. This
directly eliminates the exponential state space. The simplification is
restricted to cases where it preserves semantics:
- Inner lower bound must be 0 or 1 (with outer lower 0). Counterexample:
`(R{2,})*` cannot match a single `R`, so must not become `R*`.
- Both loops must have the same laziness. Counterexample: `(?:R*)+?`
(greedy inner, lazy outer) has different match behavior than `R*?`.
- No capture effects, since collapsing loops would change capture group
bindings.

**2. `StripEffects` caching** --- The derivative of deeply nested loop
patterns with captures produces a DAG with shared sub-trees wrapped in
different `Effect` nodes. Without caching, `StripEffects` traverses each
shared sub-tree once per reference rather than once per unique node,
leading to exponential work. Adding a cache (following the existing
pattern of `_pruneLowerPriorityThanNullabilityCache`) fixes this.

**3. `CountSingletons` defense-in-depth** --- Improve the NFA size
estimate so that nested unbounded loops multiply the estimate by 2 per
nesting level, matching the actual derivative branching cost. The helper
`ContainsNestedUnboundedLoop` walks through
Concat/Effect/DisableBacktrackingSimulation wrappers to detect nested
unbounded loops even when captures are present. This causes the existing
safe-size threshold (10,000) to reject patterns with deeply nested
unbounded loops that survive loop flattening (e.g., capturing loops like
`((a)*)*` or alternating lazy/greedy nesting like `(?:(?:a*)*?)*` at 15+
levels). With loop flattening, same-laziness non-capturing nesting is
already collapsed before the estimate runs, so the multiplier only fires
for patterns that would actually cause exponential blowup.

### Note on linear-time guarantee

The NonBacktracking engine guarantees linear time in the length of the
input, and this guarantee was never violated by the nested loop issue.
The engine is O(C * N) where N is the input length and C is a
pattern-dependent constant representing the per-character cost. For
deeply nested patterns like `((a)*)*`, the constant C grows
exponentially with the nesting depth of the pattern, but for any given
pattern the matching time remains linear in the input length.

In other words, this was an exponential blowup in the _pattern
complexity constant_, not in input-length scaling. In practice,
triggering the blowup requires deliberately nesting redundant
quantifiers 15+ levels deep, which does not arise naturally.

### Tests

- Stress test (`StressTestDeepNestingOfLoops`) uses depth 2000 for all
engines. For NonBacktracking, deeply nested unbounded patterns (`*`,
`+`) are correctly rejected with `NotSupportedException` via the
`CountSingletons` defense-in-depth. Bounded patterns (`{0,1}`) are
accepted and matched normally since they don't cause exponential
derivative branching.
- Adds unit tests for `CountSingletons` defense-in-depth:
  - Alternating-laziness depth-20 pattern exceeds unsafe threshold
  - Capturing-group depth-20 pattern exceeds unsafe threshold
  - Same-laziness depth-100 stays safe after loop flattening

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rs (dotnet#124650)

## Description

Fixes dotnet#84484
Fixes dotnet#88519
Fixes dotnet#107898

The source generator uses `[UnsafeAccessor]` (NET8+ non-generic types)
or cached reflection delegates (older targets/generic types) to access
inaccessible members, enabling three previously unsupported scenarios:

### 1. Preserve default values for init-only properties

The source generator previously set init-only properties via the
constructor delegate's object initializer expression, even when absent
from JSON. This replaced C# property initializer defaults with
`default(T)`:

```csharp
public class Foo
{
    public string Name { get; init; } = "DefaultName";
    public int Number { get; init; } = 42;
}
// Previously: static args => new Foo() { Name = (string)args[0], Number = (int)args[1] }
// Deserializing "{}" gave Name=null, Number=0 instead of Name="DefaultName", Number=42
```

Init-only properties are now removed from the constructor delegate and
set post-construction via UnsafeAccessor or reflection, only when
present in JSON.

### 2. Enable `[JsonInclude]` for inaccessible properties

Previously, `[JsonInclude]` properties with inaccessible getters or
setters generated throwing delegates. They are now fully supported:

```csharp
public class Bar
{
    [JsonInclude]
    private string Secret { get; set; } = "hidden";
}
```

### 3. Enable `[JsonConstructor]` for inaccessible constructors

Previously, inaccessible constructors marked with `[JsonConstructor]`
were ignored with a SYSLIB1222 warning. They are now invoked via
`[UnsafeAccessor(UnsafeAccessorKind.Constructor)]` or cached
`ConstructorInfo.Invoke` reflection fallback:

```csharp
public class Baz
{
    [JsonConstructor]
    private Baz(string name) { Name = name; }
    public string Name { get; }
}
```

---

## Generated Code Samples

### UnsafeAccessor path (NET8+ non-generic types)

For a type with a private `[JsonInclude]` property and an init-only
property:

```csharp
public class MyType
{
    [JsonInclude]
    private string Secret { get; set; } = "default";

    public int Value { get; init; } = 42;
}
```

The source generator emits `[UnsafeAccessor]` extern methods that are
invoked **directly** from the getter/setter delegates.
`JsonPropertyInfoValues<T>` is generic on the property type, so the
`Setter` delegate is `Action<object, T?>` and the `Getter` is
`Func<object, T?>`. The only cast in each delegate is on the `object`
parameter to the declaring type:

#### Property getter (inaccessible `[JsonInclude]`)

```csharp
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_Secret")]
private static extern string __get_MyType_Secret(MyType obj);

// Delegate: Func<object, string?>
Getter = static obj => __get_MyType_Secret((MyType)obj),
```

#### Property setter (inaccessible `[JsonInclude]`)

```csharp
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Secret")]
private static extern void __set_MyType_Secret(MyType obj, string value);

// Delegate: Action<object, string?>
Setter = static (obj, value) => __set_MyType_Secret((MyType)obj, value!),
```

#### Init-only property setter

```csharp
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Value")]
private static extern void __set_MyType_Value(MyType obj, int value);

// Delegate: Action<object, int?>
Setter = static (obj, value) => __set_MyType_Value((MyType)obj, value!),
```

#### Constructor (inaccessible `[JsonConstructor]`)

```csharp
[UnsafeAccessor(UnsafeAccessorKind.Constructor)]
private static extern Baz __ctor_Baz(string p0);

// Invoked directly from the parameterized constructor delegate
```

#### Value types (structs)

For struct types, the extern uses `ref` and the delegate passes `ref
Unsafe.Unbox<T>(obj)`:

```csharp
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_Value")]
private static extern void __set_MyStruct_Value(ref MyStruct obj, int value);

Setter = static (obj, value) => __set_MyStruct_Value(ref Unsafe.Unbox<MyStruct>(obj), value!),
```

### Reflection fallback (older targets or generic types)

When `[UnsafeAccessor]` is not available (e.g., netstandard2.0 targets)
or the declaring type is generic (not supported by UnsafeAccessor), the
generator falls back to cached reflection with **strongly typed**
wrappers:

#### Property getter (reflection)

```csharp
private static Func<MyType, string>? s_get_MyType_Secret;
private static string __get_MyType_Secret(MyType obj) =>
    (s_get_MyType_Secret ??= (Func<MyType, string>)Delegate.CreateDelegate(
        typeof(Func<MyType, string>),
        typeof(MyType).GetProperty("Secret", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)!
            .GetGetMethod(true)!))((MyType)obj);

Getter = static obj => __get_MyType_Secret((MyType)obj),
```

#### Property setter (reflection)

```csharp
private static Action<MyType, string>? s_set_MyType_Secret;
private static void __set_MyType_Secret(MyType obj, string value) =>
    (s_set_MyType_Secret ??= (Action<MyType, string>)Delegate.CreateDelegate(
        typeof(Action<MyType, string>),
        typeof(MyType).GetProperty("Secret", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)!
            .GetSetMethod(true)!))((MyType)obj, value);

Setter = static (obj, value) => __set_MyType_Secret((MyType)obj, value!),
```

#### Field accessor (reflection)

For fields, `FieldInfo` is cached directly since fields don't have
`MethodInfo` equivalents:

```csharp
private static FieldInfo? s_field_MyType_myField;
private static string __get_MyType_myField(object obj) =>
    (string)(s_field_MyType_myField ??= typeof(MyType).GetField("myField",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)!).GetValue(obj)!;

private static void __set_MyType_myField(object obj, string value) =>
    (s_field_MyType_myField ??= typeof(MyType).GetField("myField",
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)!).SetValue(obj, value);
```

#### Constructor (reflection)

Note: Unlike `MethodInfo`, `ConstructorInfo` cannot be wrapped in a
delegate, so the `ConstructorInfo` itself is cached:

```csharp
private static ConstructorInfo? s_ctor_Baz;
private static Baz __ctor_Baz(string p0) =>
    (Baz)(s_ctor_Baz ??= typeof(Baz).GetConstructor(
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
        binder: null, new Type[] { typeof(string) }, modifiers: null)!)
    .Invoke(new object?[] { p0 });
```

---

### Changes

- **Parser**: Non-required init-only properties removed from
`PropertyInitializerSpecs` (renamed `memberInitializerNames` to
`requiredMemberNames`). Inaccessible `[JsonInclude]` properties no
longer flagged as `HasInvalidConfigurationForFastPath`. Inaccessible
`[JsonConstructor]` constructors no longer nulled out ΓÇö tracked as
inaccessible for the emitter.

- **PropertyGenerationSpec**: Added `CanUseUnsafeAccessors`
(per-property, checks `UnsafeAccessorAttribute` availability and
non-generic declaring type), `NeedsAccessorForGetter`, and
`NeedsAccessorForSetter`.

- **TypeGenerationSpec**: Added `ConstructorIsInaccessible` and
`CanUseUnsafeAccessorForConstructor`.

- **Emitter**: Unified accessor pattern with identical wrapper
signatures for both paths. UnsafeAccessor externs are implementation
details. Struct types use `ref Unsafe.Unbox<T>(obj)`. Fast-path
serialization includes inaccessible `[JsonInclude]` properties. Field
reflection fallback correctly caches `FieldInfo` and calls `.GetValue()`
/ `.SetValue()`.

- **KnownTypeSymbols**: Detect `UnsafeAccessorAttribute` availability.

- **Runtime validation** (`JsonMetadataServices.Helpers.cs`): Allow
non-public `[JsonInclude]` properties when getter/setter delegates are
provided.

- **Diagnostics**: SYSLIB1038 and SYSLIB1222 no longer emitted for these
scenarios.

- **Tests**: Updated overrides, added new test types and methods
including generic type coverage for the reflection fallback path
(`GenericClassWithPrivateJsonIncludeProperties<T>`). All 7805 source gen
tests pass.

<!-- START COPILOT CODING AGENT TIPS -->
---

🔒 GitHub Advanced Security automatically protects Copilot coding
agent pull requests. You can protect all pull requests by enabling
Advanced Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)

---------

Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t ALCs (dotnet#125973)

**Enhanced InvalidCastException diagnostics:**

* Added `GetGenericArgAssemblyDetailInfo` and
`FindFirstDifferingGenericArgument` static helper functions to identify
and report the specific generic argument type and its assembly context
when an `InvalidCastException` occurs between generic types with the
same outer type but different generic arguments.
* Updated `CheckAndThrowSameTypeAndAssemblyInvalidCastException` to use
the new helpers, so the exception message now details the differing
generic argument and its assembly/ALC context, making debugging easier.
* Moved all diagnostic format strings from hardcoded `Printf` calls into
the resource string table (`mscorrc.rc`) with new resource IDs
(`IDS_EE_CANNOTCASTSAME_DETAIL_BYTE_ARRAY`,
`IDS_EE_CANNOTCASTSAME_DETAIL_LOCATION`,
`IDS_EE_CANNOTCASTSAME_GENARG_BYTE_ARRAY`,
`IDS_EE_CANNOTCASTSAME_GENARG_LOCATION`) to support potential
localization. Both `GetAssemblyDetailInfo` and
`GetGenericArgAssemblyDetailInfo` now use `SString::LoadResource` +
`FormatMessage` instead of hardcoded format strings.

**Testing improvements:**

* Added two new tests in `AssemblyLoadContextTest.cs`:
- One to verify that casting between types with the same name from
different ALCs produces an exception message including both ALC names.
- Another to verify that when the cast fails due to a differing generic
argument from a different ALC, the exception message includes the
generic argument name and both ALCs.

Example:
```
System.InvalidCastException: [A]System.Runtime.CompilerServices.StrongBox`1[InvalidCastSharedType] cannot be cast to [B]System.Runtime.CompilerServices.StrongBox`1[InvalidCastSharedType].

// before
Type A originates from 'System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' in the context 'Default' at location 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.14\System.Private.CoreLib.dll'. 
Type B originates from 'System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' in the context 'Default' at location 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.14\System.Private.CoreLib.dll'.

// after
Type A has a generic argument 'InvalidCastSharedType' that originates from 'helloworld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context '"TestALC" System.Runtime.Loader.AssemblyLoadContext #0' at location 'C:\repos\helloworld\bin\Debug\net9.0\helloworld.dll'.
Type B has a generic argument 'InvalidCastSharedType' that originates from 'helloworld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\repos\helloworld\bin\Debug\net9.0\helloworld.dll'.
```
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
Co-authored-by: Elinor Fung <elfung@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tested locally with various notifications.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…#126306)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Co-authored-by: Adam Sitnik <adam.sitnik@gmail.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
…26450)

Renames all `*.Win32.cs` files under `src/libraries` to `*.Windows.cs`.
If a corresponding `*.Windows.cs` already exists, the content of the
`*.Win32.cs` file is merged into it.

`win32.cs` vs. `windows.cs` is a historic leftover from the times when
Windows Store apps were not able to use the full Win32 API surface. It
does not make sense anymore.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
PR dotnet#125799 rewrote BigInteger internals to use native-width (`nuint`)
limbs. Its `FastReducer.SubMod` added a compensating loop:

```csharp
while (CompareActual(left, right) < 0)
{
    AddSelf(left, modulus);
}
```

This hangs on 32-bit platforms. After truncating both operands to `k`
limbs, the truncated `right` (q̂·m mod b^k) can appear much larger than
`left` (x mod b^k). Each loop iteration adds `modulus` (~2^1025), but
the gap can be ~2^1088, requiring ~2^64 iterations on 32-bit —
effectively infinite.

Barrett reduction guarantees the true residual `x − q̂·m` is in `[0,
2·modulus]`. After k-limb truncation, unsigned subtraction underflow
naturally wraps to the correct residual, which fits in k limbs since
`2·modulus < b^k`. The original (pre-dotnet#125799) code relied on this
property — it just called `SubtractSelf` directly (and hit a debug
assertion on borrow, which was separately suppressed in dotnet#98212).

This PR:
- Replaces the `AddSelf` loop with an inline subtraction that tolerates
unsigned underflow
- Re-enables the `FastReducer_AssertFailure_RegressionTest` on 32-bit
platforms (disabled in dotnet#126216)

All 3,031 System.Runtime.Numerics tests pass on x64; the
previously-hanging test completes in ~10 seconds.

Fixes dotnet#126212

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dotnet#117583)

Inline write barriers with covariance checks (in case if inliner decides
that it's profitable) - this allows to remove redundant write barriers
(previously we could only do that in early phases) and range checks
(previously they were inside the helper call and now JIT can fold them).

Related: dotnet#9159

## Benchmark

```cs
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);

public class Benchmarks
{
    static object[] _strings = new string[4];
    static object _x = "";

    [Benchmark]
    public void AssignString()
    {
        var arr = _strings;
        if (arr.Length >= 4)
        {
            // We now can remove write barriers and redundant range checks if StelemRef gets inlined
            arr[0] = "";
            arr[1] = "";
            arr[2] = "";
            arr[3] = "";
        }
    }

    [Benchmark]
    public void SwapElements()
    {
        var arr = _strings;
        (arr[1], arr[0]) = (arr[0], arr[1]);
    }

    [Benchmark]
    public void SingleAssignmentCns()
    {
        _strings[0] = "";
    }

    [Benchmark]
    public void SingleAssignmentVar()
    {
        _strings[0] = _x;
    }
}
```
**Linux-AMD (Genoa):**

| Method | Toolchain | Mean | Error | Ratio |
|----------------- |------------------------
|----------:|----------:|------:|
| AssignString     | Main | 7.5633 ns | 0.0022 ns |  1.00 |
| AssignString     | PR | 1.3160 ns | 0.0033 ns |  0.17 |
| | | | | |
| SwapElements     | Main | 2.9979 ns | 0.0008 ns |  1.00 |
| SwapElements     | PR | 1.0471 ns | 0.0012 ns |  0.35 |
| | | | | |
| SingleAssignmentCns | Main | 1.9075 ns | 0.0005 ns |  1.00 |
| SingleAssignmentCns | PR | 0.2723 ns | 0.0002 ns |  0.14 |
| | | | | |
| SingleAssignmentVar | Main | 1.9080 ns | 0.0003 ns |  1.00 |
| SingleAssignmentVar | PR | 1.6356 ns | 0.0005 ns |  0.86 |

**Linux-ARM64 (Cobalt100):**

| Method | Toolchain | Mean | Error | Ratio |
|----------------- |------------------------
|-----------:|----------:|------:|
| AssignString     | Main | 10.3296 ns | 0.0032 ns |  1.00 |
| AssignString     | PR |  1.8738 ns | 0.0006 ns |  0.18 |
| | | | | |
| SwapElements     | Main |  2.6604 ns | 0.0012 ns |  1.00 |
| SwapElements     | PR |  1.1768 ns | 0.0024 ns |  0.44 |
| | | | | |
| SingleAssignmentCns | Main |  1.9655 ns | 0.0023 ns |  1.00 |
| SingleAssignmentCns | PR |  0.3821 ns | 0.0003 ns |  0.19 |
| | | | | |
| SingleAssignmentVar | Main |  1.8030 ns | 0.0013 ns |  1.00 |
| SingleAssignmentVar | PR |  0.7219 ns | 0.0006 ns |  0.40 |

---------

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Jakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Co-authored-by: EgorBo <egorbo@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mthalman and others added 27 commits April 9, 2026 12:35
Adds [Renovate
support](https://github.com/dotnet/arcade/blob/main/Documentation/Renovate.md)
via a pipeline that will keep configured dependencies up-to-date.

This initial configuration is set to use image digest pinning for the
container images used in the builds. This is configured such that it
will automatically update any image name in the tracked files so any new
images that get manually added to this file can just reference the tag
name and Renovate will do the rest by updating it to the digest on the
next run.

~~My assumption is that we don't want digest pinning done for Helix
images which would continue to be referenced by tag.~~ Includes support
for digest pinning on Helix images.

[Example dry
run](https://dev.azure.com/dnceng/internal/_build/results?buildId=2933814&view=results)
(internal link)

Contributes to dotnet#113455
Since the old SIMD types now use HWIntrinsics, these paths are dead.
…n loading custom attribute values. (dotnet#123439)

Avoid incorrectly resolving a MonoClass for `MONO_TYPE_GENERICINST` when
loading custom attribute values.

`load_cattr_value()` previously unconditionally called
`m_type_data_get_klass()`, which is invalid for `GENERICINST` and could
lead to incorrect behavior when processing generic enum instances. This
change defers class resolution for `MONO_TYPE_GENERICINST` and handles
enum generic instances explicitly by extracting the underlying element
type. This fixes a crash when decoding custom attributes involving
generic types.

#### This crashes in Mono but doesn't in CoreClr

```
using System;
using System.Collections;
using System.Reflection;

using System.Runtime.InteropServices;

var attr = typeof(C).CustomAttributes.Single(d => d.AttributeType == typeof(A));
var arg = attr.ConstructorArguments.Single();
Console.WriteLine(arg.GetType());
class A : Attribute
{
    public unsafe A(B<delegate*<void>[]>.E e) { }
} 

class B<T>
{
    public enum E { }
}

[A(default)]
unsafe class C { }

```

#### Output on CoreClr:

```
System.Reflection.CustomAttributeTypedArgument
```

#### Output on Mono without fix:

```
MonoType with type 21 accessed by m_type_data_get_klass

=================================================================
	Native Crash Reporting
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

=================================================================
	Native stacktrace:
=================================================================
	0x7fa2a25ffd2f - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a25a3e0e - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a25ff5b1 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a2a29040 - /lib64/libc.so.6 : 
	0x7fa2a2a82e5c - /lib64/libc.so.6 : 
	0x7fa2a2a28f0e - /lib64/libc.so.6 : gsignal
	0x7fa2a2a106d0 - /lib64/libc.so.6 : abort
	0x7fa2a26ac244 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a26b9e06 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a26ac606 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a26ac73e - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a277445b - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a277408d - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a276ee74 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a276e9c4 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : mono_reflection_create_custom_attr_data_args
	0x7fa2a276fdbf - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x7fa2a2704f08 - /home/venkad/dotnet10.0.100-mono/shared/Microsoft.NETCore.App/10.0.0-dev/libcoreclr.so : 
	0x4037366b - Unknown

```

#### Output on Mono with fix:

```
System.Reflection.CustomAttributeTypedArgument
```

Co-authored-by: Larry Ewing <lewing@microsoft.com>
> [!NOTE]
> This PR was AI/Copilot-generated.

## Summary
Update the remaining documentation cleanup from dotnet#126122, excluding the
Tizen and stress-test cases for now.

- replace the stale WebAssembly image update walkthrough with current
Azure Linux / `dotnet/versions` guidance
- update the FreeBSD cross-build example to the current prereqs image
- intentionally leave the Tizen and stress-test references unchanged for
follow-up work

## Testing
Documentation only.

Ref dotnet#126122

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Closes dotnet#103468

Adds a `DirectoryPath` property to `DirectoryNotFoundException` as
approved in [API
review](dotnet#103468 (comment)).

### What's included

- `DirectoryPath` nullable property on `DirectoryNotFoundException`,
matching the pattern of `FileNotFoundException.FileName`
- Two new constructors accepting `directoryPath` (`message +
directoryPath`, `message + directoryPath + innerException`)
- Auto-constructed message when `message` is null but `directoryPath` is
provided, via null-coalescing in the constructors
- `ToString()` override that includes `DirectoryPath` on a separate line
- Serialization support via `GetObjectData` / version-tolerant
deserialization constructor
- Ref assembly updates for `System.Runtime`
- Updated `Arg_DirectoryNotFoundException` default message from
`"Attempted to access a path that is not on the disk."` to `"Unable to
find the specified directory."` to match `FileNotFoundException`'s
`"Unable to find the specified file."` pattern and align better with the
new `IO_DirectoryNotFound_Path` string.
- Tests for all new constructors, property, message auto-construction,
`ToString()` output, null edge cases, and serialization round-trip

### Implementation notes

- Follows the `FileNotFoundException` implementation pattern:
- The property is `string?` (nullable) because not all throw sites have
a path available
- The new constructors null-coalesce `message` (consistent with existing
DNFE constructors), auto-constructing a descriptive message from
`directoryPath` when `message` is null
- Uses managed `SR.Format(...)` for message construction rather than
native interop, as recommended during API review
- Version-tolerant deserialization: iterates `SerializationInfo` entries
to handle old payloads that lack the `DirectoryPath` field
- `#if NET11_0_OR_GREATER` guards on throw sites in multi-TFM files
(`Win32Marshal.cs`, `Interop.IOErrors.cs`, `PhysicalFileProvider.cs`,
`LdapSessionOptions.Linux.cs`) since the new constructor isn't available
on older TFM targets


### Internal throw-site updates

Updated 18 internal throw sites across 12 files to pass directory paths
to the new constructors, so that `DirectoryPath` is populated for
runtime-generated exceptions:

| Area | File(s) | Path variable |
|------|---------|---------------|
| CoreLib / Common | `Win32Marshal.cs` | `path` |
| CoreLib / Common | `Interop.IOErrors.cs` (Unix ENOTDIR) | `path` |
| CoreLib | `FileInfo.cs` (MoveTo) | directory of `FullName` |
| CoreLib | `FileSystem.Unix.cs` (×2, directory rename) |
`sourceFullPath` |
| System.Formats.Tar | `TarFile.cs` (×8) | `sourceDirectoryName` /
`destinationDirectoryName` |
| System.IO.IsolatedStorage | `IsolatedStorageFile.cs` |
`sourceDirectoryName` |
| System.IO.FileSystem.AccessControl | `FileSystemSecurity.cs` | `name`
|
| System.Net.Sockets | `SocketAsyncEventArgs.Unix.cs` | `dirname` |
| System.Security.AccessControl | `NativeObjectSecurity.cs` | `name` |
| System.DirectoryServices.Protocols | `LdapSessionOptions.Linux.cs` |
`value` |
| Microsoft.Extensions.FileProviders.Physical |
`PhysicalFileProvider.cs` | `Root` |

**Not updated** (by design):
- 3 sites with no path available (`SharedMemoryManager.Unix.cs` default
ctor, `Interop.IOErrors.cs` empty-path branch, `FileSystemSecurity.cs`
null-name branch)
- 4 threading sites (`EventWaitHandle`, `Mutex`, `EventWaitHandleAcl`,
`MutexAcl`) where the `name` is a named sync object, not a filesystem
directory
…yToRun header symbol (dotnet#126515)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Remove restrictions that prevented async methods from being inlined
during ReadyToRun compilation.

All 69 async tests pass with both crossgen2 and composite R2R.

Output of the src/tests/async/execution-context/execution-context.cs was
validated manually to ensure inlining is happening for async calls to
methods without awaits. In `Test()`, these two calls were inlined as
expected.

https://github.com/dotnet/runtime/blob/b7973489277b74bc5da9d36a0a2883eaa987328f/src/tests/async/execution-context/execution-context.cs#L110-L121

Fixes dotnet#124665

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t for the trimming target (dotnet#126382)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Previous codegen for FMLA, when supplied with a non-constant operand,
looked something like:
```
mov     v0.8b, v8.8b // fill in RMW operand
br      x20
fmla    v0.2s, v9.2s, v10.s[0]
b       G_M19624_IG23
fmla    v0.2s, v9.2s, v10.s[1]
b       G_M19624_IG23
// and so on for each of the immediates
```
With the recent refactor to move the mov-emit-for-RMW down into the emit
routines, the mov is emitted instead when codegen happens for each arm
of the jump table:
```
br      x20
mov     v0.8b, v8.8b                    // fill in RMW operand
fmla    v0.2s, v9.2s, v10.s[0]
b       G_M19624_IG24
mov     v0.8b, v8.8b                   // fill in RMW operand
fmla    v0.2s, v9.2s, v10.s[1]
b       G_M19624_IG24
// etc...
```
Bug happens because the jump table builder thought each case would
contain only 1 instruction, not two.

fixes dotnet#126379
Implements the approved API from dotnet#120587 — a simplified `GroupJoin`
overload that removes the need for an explicit result selector,
returning `IGrouping<TOuter, TInner>` where the outer element is the key
and the correlated inner elements are the grouping contents.

## Description

### API

```csharp
namespace System.Linq;

public static partial class Enumerable
{
    public static IEnumerable<IGrouping<TOuter, TInner>> GroupJoin<TOuter, TInner, TKey>(
        this IEnumerable<TOuter> outer,
        IEnumerable<TInner> inner,
        Func<TOuter, TKey> outerKeySelector,
        Func<TInner, TKey> innerKeySelector,
        IEqualityComparer<TKey>? comparer = null);
}

public static partial class Queryable
{
    public static IQueryable<IGrouping<TOuter, TInner>> GroupJoin<TOuter, TInner, TKey>(
        this IQueryable<TOuter> outer,
        IEnumerable<TInner> inner,
        Expression<Func<TOuter, TKey>> outerKeySelector,
        Expression<Func<TInner, TKey>> innerKeySelector,
        IEqualityComparer<TKey>? comparer = null);
}

public static partial class AsyncEnumerable
{
    public static IAsyncEnumerable<IGrouping<TOuter, TInner>> GroupJoin<TOuter, TInner, TKey>(
        this IAsyncEnumerable<TOuter> outer,
        IAsyncEnumerable<TInner> inner,
        Func<TOuter, TKey> outerKeySelector,
        Func<TInner, TKey> innerKeySelector,
        IEqualityComparer<TKey>? comparer = null);

    public static IAsyncEnumerable<IGrouping<TOuter, TInner>> GroupJoin<TOuter, TInner, TKey>(
        this IAsyncEnumerable<TOuter> outer,
        IAsyncEnumerable<TInner> inner,
        Func<TOuter, CancellationToken, ValueTask<TKey>> outerKeySelector,
        Func<TInner, CancellationToken, ValueTask<TKey>> innerKeySelector,
        IEqualityComparer<TKey>? comparer = null);
}
```

### Changes

- **System.Linq**: New `GroupJoin<TOuter,TInner,TKey>` overload with
optional `IEqualityComparer<TKey>?` parameter + internal
`GroupJoinGrouping<TKey, TElement>` wrapper class. XML doc comments with
correct `<see cref="IGrouping{TOuter, TInner}"/>` references added to
the new public API.
- **System.Linq.Queryable**: New overload with optional
`IEqualityComparer<TKey>?` parameter and `[DynamicDependency]` on
`Enumerable.GroupJoin`3`. XML doc comments added.
- **System.Linq.AsyncEnumerable**: Two new overloads (sync and async key
selector variants) with optional `IEqualityComparer<TKey>?` parameter +
internal `AsyncGroupJoinGrouping<TKey, TElement>` wrapper class. XML doc
comments added.
- Reference assemblies updated for all three projects.
- Tests for all three projects, with `#if NET` guards in the async
enumerable tests for net481 compatibility (the new
`Enumerable.GroupJoin` overload and tuple-returning `Zip` are
unavailable on .NET Framework 4.8.1).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
Co-authored-by: Shay Rojansky <roji@roji.org>
Co-authored-by: roji <1862641+roji@users.noreply.github.com>
Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
…t#126578)

> [!NOTE]
> This PR description was generated with GitHub Copilot.

Resolves dotnet#123221.

## Summary
- Adds the approved `Utf8JsonWriter.Reset` overloads that accept
`JsonWriterOptions` for both `Stream` and `IBufferWriter<byte>` outputs.
- Keeps the existing `Dispose`, `CheckNotDisposed`, and internal
serializer cache behavior unchanged.
- Adds test coverage for the new reset overloads and option-reset
behavior.

## Testing
- `dotnet build
src\\libraries\\System.Text.Json\\src\\System.Text.Json.csproj -c Debug`
- `dotnet test
src\\libraries\\System.Text.Json\\tests\\System.Text.Json.Tests\\System.Text.Json.Tests.csproj
-c Debug -f net11.0 --logger "console;verbosity=minimal"`

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dotnet#126204)

During cctor, backing field initialization was calling into
`ComparerHelpers.CreateDefaultEqualityComparer` which used the
reflection based api: `CreateInstanceForAnotherGenericParameter` to
create a new type that R2R had now knowledge of. In order to fix this,
we follow the same approach that NativeAOT takes, reusing existing
helpers. This means that we will end up with specialized helpers in the
R2R image that create these comparers in the cctor and R2R will now know
to root the specialized comparer types.

Prevents interpretation of methods like:
```
System.Collections.Generic.GenericEqualityComparer`1[int]:.ctor()
System.Collections.Generic.GenericEqualityComparer`1[int]:Equals(int,int)
```

For example, this makes
`System.Collections.ContainsFalse_Int32_.ImmutableList` benchmark 20x
faster. On my local simple testcase it resulted in 0.5% increase in
size.
…k size (dotnet#126601)

> [!NOTE]
> This PR was created with the help of GitHub Copilot.

## Summary

Tests running CoreCLR on WASM via Node.js can overflow V8's JavaScript
call stack when the test suite loads many assemblies and a test
exercises deep recursive exception handling (e.g. `test104820` with 100
levels of recursion and `when` filter funclets).

## Changes

- Increase the Node.js stack size from the default (~1MB) to 8MB via
`--stack-size=8192` in the WASM test runner scripts for both Linux/macOS
(`CLRTest.Execute.Bash.targets`) and Windows
(`CLRTest.Execute.Batch.targets`).
- Disable `test100536` on platforms without native test assets (P/Invoke
test).

## Root Cause

In the full Regressions suite, 87 test assemblies are loaded into a
single process. The combined V8 call stack usage from assembly loading +
xunit infrastructure + the deep recursive EH in `test104820` (100,000
filter funclet invocations) exceeds V8's default stack limit, causing a
silent crash (exit 0). The test passes in isolation because less V8
stack is consumed.

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

This pull request refactors how the target operating system and
architecture are handled in the bundling logic, making both parameters
required rather than optional. It removes fallback logic that previously
inferred these values from the current runtime environment, leading to
more explicit and predictable behavior.

**Bundler and TargetInfo API changes:**

* The `Bundler` and `TargetInfo` constructors now require explicit
`OSPlatform` and `Architecture` arguments, removing support for optional
values and fallback to the host environment.
* The static fallback logic (`HostOS`) in `TargetInfo` is removed, so
the OS must always be specified.
* Usage in the SDK always passes these parameters

**Test and utility updates:**

* Test code in `BundlerConsistencyTests` and `SingleFileTestApp` is
updated to pass the required `OSPlatform` and `Architecture` values,
using a new `Binaries.CurrentOSPlatform` helper and
`RuntimeInformation.OSArchitecture`.
* A new static property, `CurrentOSPlatform`, is added to the `Binaries`
utility class to encapsulate platform detection logic for tests.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
…#126475)

We expect that frameNeedsTailcallUpdate has a false default value. When
we encounter a call flagged as tail, we set this variable to true and
then proceed with the rest of the call. Once we setup the frame for the
tailcall we reset this variable. The problem is that some code paths for
the call could end up invoking compiled code. In this case we failed to
clear the tailcall flag which means that, after returning from compiled
code, if we would encounter a calling opcode that doesn't reset
frameNeedsTailcallUpdate (for example INTOP_NEWOBJ), we would
incorrectly proceed with a tailcall.

Fixes Runtime_72845 in DOTNET_InterpMode=1

Regressed after dotnet#123225
- Update webcil spec to have a spot to store the tableBase in the header
during webcil loading
- Tweak corerun build to make the stack pointer available as an export
and make the table size growable
- Compute payloadSize by reading the wasm bytes directly instead of
calling the helper function
- import "stackPointer", "tableBase", "table" and "imageBase" from
"webcil" instead of "env". [TODO! Update the webcil.md to specify that
these must be specified when importing a v1 webcil image.]
- Adjust cDAC handling of webcil images. Notably, the webcil file format
is a specification of its own, and its data structures are specified,
and shouldn't be drawn from the target, but instead hard-coded.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
dotnet#125943)

Remove spaces before parentheses in method calls/declarations and switch
from K&R to Allman brace style to match the rest of the
ILLink.RoslynAnalyzer codebase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On ARM64, the CHECK_CACHE_ENTRY macro read m_pInstanceType and
m_pTargetCode from a cache entry using two separate ldr instructions
separated by a control dependency (cmp/bne). ARM64's weak memory model
does not order loads across control dependencies, so the hardware can
speculatively satisfy the second load (target) before the first (type)
commits. When a concurrent thread atomically populates the entry via
stlxp/casp (UpdateCacheEntryAtomically), the reader can observe the new
m_pInstanceType but the old m_pTargetCode (0), then br to address 0.

Fix by using ldp to load both fields in a single instruction
(single-copy atomic on FEAT_LSE2 / ARMv8.4+ hardware), plus a cbz guard
to catch torn reads on pre-LSE2 hardware where ldp pair atomicity is not
architecturally guaranteed.

Fixes dotnet#126345
…#126612)

Per
dotnet#126437 (comment),
the `FreeBSD` `OSPlatform` extension in `PlatformExtensions` was defined
but never used after PR dotnet#126437 removed its only usage. This PR removes
the unused `extension(OSPlatform)` block while keeping the still-used
`extension(Architecture)` block for `LoongArch64`.

cc @elinor-fung @am11

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: elinor-fung <47805090+elinor-fung@users.noreply.github.com>
…e inheritance (dotnet#126318)

fixes dotnet#13943

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
Co-authored-by: Adam Sitnik <adam.sitnik@gmail.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
…126618)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Co-authored-by: adamsitnik <6011991+adamsitnik@users.noreply.github.com>
…own and defined-but-unmapped status codes (dotnet#126602)

`SmtpException.GetMessageForStatus` fell through `default` to
`SmtpStatusCode.CommandUnrecognized`, so any unrecognized status value
(e.g. `(SmtpStatusCode)0` from an uninitialized `_statusCode`) produced
the misleading message *"Syntax error, command unrecognized."* —
implying an SMTP 500 response when none occurred.

## Description

- **`Strings.resx`**: Added three new resource strings:
- `SmtpUnknownStatusCode` → `"Unknown SMTP status code."` (for truly
undefined status code values)
- `SmtpCannotVerifyUserWillAttemptDelivery` → `"Cannot verify user, but
will attempt delivery."` (for SMTP 252)
- `SmtpGeneralFailure` → `"General failure."` (for the internal
`GeneralFailure = -1` sentinel)
- **`SmtpException.cs`**: Separated `default` from `case
SmtpStatusCode.CommandUnrecognized` in `GetMessageForStatus`, and added
explicit case labels for all previously unmapped defined enum members
(`CannotVerifyUserWillAttemptDelivery` and `GeneralFailure`):
  ```csharp
  // Before
  default:
  case SmtpStatusCode.CommandUnrecognized:
      return SR.SmtpCommandUnrecognized;

  // After
  default:
      return SR.SmtpUnknownStatusCode;
  case SmtpStatusCode.GeneralFailure:
      return SR.SmtpGeneralFailure;
  case SmtpStatusCode.CannotVerifyUserWillAttemptDelivery:
      return SR.SmtpCannotVerifyUserWillAttemptDelivery;
  case SmtpStatusCode.CommandUnrecognized:
      return SR.SmtpCommandUnrecognized;
  // ... all other defined enum members explicitly handled
  ```
- **`SmtpExceptionTest.cs`**: Added assertion confirming unknown status
codes yield a message distinct from `CommandUnrecognized`.

## Customer Impact

Exceptions thrown with undefined `SmtpStatusCode` values (e.g. during
connection failures before any SMTP response is received) produce a
confusing "command unrecognized" message, making diagnosis harder —
particularly when the real cause is a transport/handshake failure
unrelated to SMTP 500. All defined `SmtpStatusCode` enum members now map
to their own descriptive messages; the `default` case exclusively
handles truly undefined values.

## Regression

No — this behavior has been present since the original .NET Framework
implementation.

## Testing

Existing `SmtpExceptionTest` suite (318 tests, 0 failures). Added
assertion to `TestConstructorWithStatusCodeArgument` verifying that `new
SmtpException((SmtpStatusCode)666).Message` differs from `new
SmtpException(SmtpStatusCode.CommandUnrecognized).Message`.

## Risk

Very low. Logic change in a `switch` statement; only affects diagnostic
messages. All previously handled enum values retain their existing
messages. The two previously unmapped defined enum values
(`CannotVerifyUserWillAttemptDelivery`, `GeneralFailure`) now return
descriptive messages instead of the misleading "command unrecognized"
text.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
HTTP/3 tests (`TelemetryTest_Http30`, and potentially other `*_Http3` /
`*_Http30` classes) consistently fail on `azurelinux.3.amd64.open.rt`
because the underlying MsQuic library fails with
`QUIC_STATUS_OUT_OF_MEMORY` on that queue.

The QUIC tests were already disabled for the same reason in PRs dotnet#125665
and dotnet#125772 using the `IsNotAzureLinux3VM` condition on
`[ConditionalClass]`. However, the HTTP/3 test classes use
`IsHttp3Supported` from `HttpClientHandlerTestBase` as their gate, so
they were not covered by the QUIC-side fix.

This PR adds the same `IsNotAzureLinux3VM` check to `IsHttp3Supported`,
which will skip all HTTP/3 test classes on AzureLinux 3 VMs where QUIC
is broken.

Relates to dotnet#123216

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

Apply issue dotnet#123011 [ActiveIssue] attributes to 22 specific failing test
methods across 22 library test files to disable them on browser/CoreCLR.

The following test suites now pass cleanly with these tests disabled:
- System.Collections
- System.Collections.Concurrent
- System.ComponentModel.EventBasedAsync
- System.Data.Common
- System.Diagnostics.Tracing
- System.Net.ServicePoint (ServicePointTests)
- System.Runtime.InteropServices
- System.Runtime.Intrinsics (45 tests, class-level)
- System.Runtime.Extensions
- System.Dynamic.Runtime
- Microsoft.Extensions.DependencyInjection
- Microsoft.Extensions.Logging.Generators

Update src/libraries/tests.proj to remove exclusions for these 12 suites
from the CoreCLR/browser block. Keep 4 suites excluded due to unfixable
issues:
- Microsoft.VisualBasic.Core (finalizer crash)
- System.IO.Compression.ZipFile (native crash)
- System.Threading.Thread (post-test finalizer crash)
- System.Formats.Nrbf (assembly loading in test discovery)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 9, 2026 10:35
Copy link
Copy Markdown
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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@dotnet-policy-service dotnet-policy-service bot added the linkable-framework Issues associated with delivering a linker friendly framework label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-Infrastructure-coreclr linkable-framework Issues associated with delivering a linker friendly framework

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.