Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UsePaging does not work with ImmutableArray struct #7628

Open
cmeeren opened this issue Oct 19, 2024 · 1 comment · May be fixed by #7712
Open

UsePaging does not work with ImmutableArray struct #7628

cmeeren opened this issue Oct 19, 2024 · 1 comment · May be fixed by #7712
Assignees
Milestone

Comments

@cmeeren
Copy link
Contributor

cmeeren commented Oct 19, 2024

Product

Hot Chocolate

Version

14.0.0

Link to minimal reproduction

See below

Steps to reproduce

Repro solution: HotChocolateBugRepro.zip

Code for reference:

public class Query
{
    [UsePaging] public ImmutableArray<int> Test => ImmutableArray<int>.Empty.AddRange(1, 2, 3);
}

What is expected?

This query works:

query {
  test {
    nodes
  }
}

What is actually happening?

The query above returns an error, which is weird, because ImmutableArray implements IEnumerable.

Expression of type 'System.Collections.Immutable.ImmutableArray1[System.Int32]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable1[System.Int32]' of method 'System.Collections.Generic.IEnumerable1[System.Int32] Take[Int32](System.Collections.Generic.IEnumerable1[System.Int32], Int32)' (Parameter 'arg0')

Complete response:

{
  "errors": [
    {
      "message": "Unexpected Execution Error",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "test"
      ],
      "extensions": {
        "message": "Expression of type 'System.Collections.Immutable.ImmutableArray`1[System.Int32]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[System.Int32]' of method 'System.Collections.Generic.IEnumerable`1[System.Int32] Take[Int32](System.Collections.Generic.IEnumerable`1[System.Int32], Int32)' (Parameter 'arg0')",
        "stackTrace": "   at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)\r\n   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1)\r\n   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)\r\n   at System.Linq.EnumerableQuery`1.GetEnumerator()\r\n   at System.Linq.EnumerableQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()\r\n   at HotChocolate.DefaultQueryableExecutable`1.ToAsyncEnumerable(CancellationToken cancellationToken)+MoveNext()\r\n   at HotChocolate.DefaultQueryableExecutable`1.ToAsyncEnumerable(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()\r\n   at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.QueryExecutor.QueryAsync(IQueryable`1 slicedQuery, Int32 offset, Boolean includeTotalCount, CancellationToken cancellationToken)\r\n   at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.QueryExecutor.QueryAsync(IQueryable`1 slicedQuery, Int32 offset, Boolean includeTotalCount, CancellationToken cancellationToken)\r\n   at HotChocolate.Types.Pagination.CursorPagingHandler`2.SliceAsync(IResolverContext context, TQuery originalQuery, CursorPagingArguments arguments, CursorPaginationAlgorithm`2 algorithm, ICursorPaginationQueryExecutor`2 executor, CancellationToken cancellationToken)\r\n   at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.SliceAsyncInternal(IResolverContext context, IQueryableExecutable`1 source, CursorPagingArguments arguments)\r\n   at HotChocolate.Types.Pagination.CursorPagingHandler.HotChocolate.Types.Pagination.IPagingHandler.SliceAsync(IResolverContext context, Object source)\r\n   at HotChocolate.Types.Pagination.PagingMiddleware.InvokeAsync(IMiddlewareContext context)\r\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"
      }
    }
  ],
  "data": {
    "test": null
  }
}

Relevant log output

No response

Additional context

If I were to take a wild guess, could this be because ImmutableArray is a struct?

@glen-84
Copy link
Collaborator

glen-84 commented Nov 13, 2024

If I were to take a wild guess, could this be because ImmutableArray is a struct?

Yes, when calling the Take method, ExpressionUtils.ValidateOneArgument checks TypeUtils.AreReferenceAssignable, which returns false for value types.

See also dotnet/runtime#41716 (comment).

I've opened #7712.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants