Skip to content

[wasm] mono-aot-cross asserts with function:mono_method_to_ir, VAR 1 (TValue_REF) cannot be expanded in this context with 1 instantiations  #57560

Closed

Description

@martinothamar

Description

Migrated a Blazor application from .NET 5 to latest 6 preview and wanted to test AOT which led me to this error.
Managed to narrow it down to a dictionary implementation which had a strange equality operator overload using EqualityComparer<>.Default.Equals(left, right);. Changing it to just Equals(left, right); fixed it (IEquatable<> is implemented). I have a full repro in the zip-file below.

> dotnet publish -c Release
Microsoft (R) Build Engine version 17.0.0-preview-21378-03+d592862ed for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
  SomeTestLib -> C:\code\private\wasmtest\SomeTestLib\bin\Release\net6.0\SomeTestLib.dll
  wasmtest -> C:\code\private\wasmtest\wasmtest\bin\Release\net6.0\wasmtest.dll
  wasmtest (Blazor output) -> C:\code\private\wasmtest\wasmtest\bin\Release\net6.0\wwwroot
  Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  AOT'ing 30 assemblies
C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.WebAssembly.Sdk\6.0.0-preview.7.21377.19\Sdk\WasmApp.Native.targets(443,5): error : Precompiling failed for C:\code\private\wasmtest\wasmtest\obj\Release\net6.0\linked\SomeTestLib.dll: Mono Ahead of Time compiler - compiling assembly C:\code\private\wasmtest\wasmtest\obj\Release\net6.0\linked\SomeTestLib.dll [C:\code\private\wasmtest\wasmtest\wasmtest.csproj]
C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.WebAssembly.Sdk\6.0.0-preview.7.21377.19\Sdk\WasmApp.Native.targets(443,5): error : * Assertion at D:\workspace\_work\1\s\src\mono\mono\mini\method-to-ir.c:7318, condition `is_ok (error)' not met, function:mono_method_to_ir, VAR 1 (TValue_REF) cannot be expanded in this context with 1 instantiations [C:\code\private\wasmtest\wasmtest\wasmtest.csproj]

Repro solution:
wasmtest.zip

In Classes.cs, make the following modification to let the build complete successfully with AOT.

    public static bool operator ==(ValueDictionary<TKey, TValue>? left, ValueDictionary<TKey, TValue>? right) =>
-        EqualityComparer<ValueDictionary<TKey, TValue>>.Default.Equals(left, right);
+        Equals(left, right);

dotnet publish -c Release

Configuration

  • Windows 10, x64
PS > dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.100-preview.7.21379.14
 Commit:    22d70b47bc

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100-preview.7.21379.14\

Host (useful for support):
  Version: 6.0.0-preview.7.21377.19
  Commit:  91ba01788d

Regression?

I haven't tried to reproduce in older previews.

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Aug 17, 2021
  2. removed
    untriagedNew issue has not been triaged by the area owner
    on Aug 23, 2021
  3. radical commented on Aug 23, 2021

    @radical
    Member

    This can be reproduced with the wasm/console sample in src/mono/sample/wasm/console:

    1. Add ValueDictionary.cs with:
    using System;
    using System.Collections.Generic;
    
    #nullable enable
    
    public sealed class ValueDictionary<TKey, TValue>
            : Dictionary<TKey, TValue>, IEquatable<Dictionary<TKey, TValue>>, IEquatable<ValueDictionary<TKey, TValue>>
            where TKey : notnull
    {
        public ValueDictionary()
            : base()
        {
        }
    
        public ValueDictionary(IDictionary<TKey, TValue> other)
            : base(other)
        {
        }
    
        public override bool Equals(object? obj) => obj is Dictionary<TKey, TValue> other && Equals(other);
    
        public bool Equals(Dictionary<TKey, TValue>? other)
        {
            if (other is null)
                return false;
    
            if (ReferenceEquals(this, other))
                return true;
    
            if (Count != other.Count)
                return false;
    
            var valueComparer = EqualityComparer<TValue>.Default;
    
            foreach (var kvp in this)
            {
                if (!other.TryGetValue(kvp.Key, out var otherValue))
                    return false;
    
                if (!valueComparer.Equals(kvp.Value, otherValue))
                    return false;
            }
    
            return true;
        }
    
        public bool Equals(ValueDictionary<TKey, TValue>? other) => Equals(other as Dictionary<TKey, TValue>);
    
        public override int GetHashCode() => base.GetHashCode();
    
        public static bool operator ==(ValueDictionary<TKey, TValue>? left, ValueDictionary<TKey, TValue>? right) =>
            EqualityComparer<ValueDictionary<TKey, TValue>>.Default.Equals(left, right);
    
        public static bool operator !=(ValueDictionary<TKey, TValue>? left, ValueDictionary<TKey, TValue>? right) =>
            !(left == right);
    }
    1. And add ValueDictionary<string, string> vd = new(); to Program.cs

    src/mono/sample/wasm/console$ make all V=1 AOT=1

      Mono Ahead of Time compiler - compiling assembly /Users/radical/dev/r2/src/mono/sample/wasm/console/bin/browser-wasm/publish/Wasm.Console.Sample.dll
      * Assertion at /Users/radical/dev/r2/src/mono/mono/mini/method-to-ir.c:7319, condition `is_ok (error)' not met, function:mono_method_to_ir, VAR 1 (TValue_REF) cannot be expanded in this context with 1 instantiations

    cc @vargaz @BrzVlad

  4. changed the title [-]Blazor AOT build failure due to EqualityComparer usage[/-] [+][wasm] `mono-aot-cross` asserts with `function:mono_method_to_ir, VAR 1 (TValue_REF) cannot be expanded in this context with 1 instantiations `[/+] on Aug 23, 2021
  5. added this to the 6.0.0 milestone on Aug 23, 2021
  6. lewing commented on Aug 24, 2021

    @lewing
    Member
  7. vargaz commented on Aug 24, 2021

    @vargaz
    Contributor

    If this is release critical, the assert can simple by removed, i.e. change it to:

    if (is_ok (error)) { <rest> }
    

    Since this is just an optimization, disabling it in this case is not going to matter much.

  8. added a commit that references this issue on Aug 25, 2021
  9. added a commit that references this issue on Aug 27, 2021
  10. ghost locked as resolved and limited conversation to collaborators on Sep 30, 2021
  11. reopened this on Oct 1, 2021
  12. vargaz commented on Oct 1, 2021

    @vargaz
    Contributor

    This was not actually fixed, the testcase still fails. My bad.

  13. SamMonoRT commented on Oct 1, 2021

    @SamMonoRT
    Member

    @vargaz @marek-safar - should the right fix be backported to rc2 ?

  14. vargaz commented on Oct 1, 2021

    @vargaz
    Contributor

    I think so. Its low-risk.

  15. lewing commented on Oct 1, 2021

    @lewing
    Member

    too late for rc2, we can still target 6.0 if required

  16. added a commit that references this issue on Oct 1, 2021
  17. marek-safar commented on Oct 1, 2021

    @marek-safar
    Contributor

    This is low risk with already 2 reports from customers, let's get this in.

    @lewing could you send tactics email?

  18. added a commit that references this issue on Oct 1, 2021
  19. added a commit that references this issue on Oct 6, 2021
  20. added a commit that references this issue on Oct 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions