Skip to content

Preserving operator methods necessary for System.Linq.Expressions #1821

@eerhardt

Description

@eerhardt

Background

There are currently 2 ILLink warnings left in System.Linq.Expressions that both boil down to the same pattern.

When you create a Binary or Unary Expression, and don't specify a MethodInfo, System.Linq.Expressions will try to find an operator on the Type corresponding to the ExpressionType you specified.

For example, if you call Expression.Equal(left, right), will call the following code

        public static BinaryExpression Equal(Expression left, Expression right, bool liftToNull, MethodInfo? method)
        {
            ExpressionUtils.RequiresCanRead(left, nameof(left));
            ExpressionUtils.RequiresCanRead(right, nameof(right));
            if (method == null)
            {
                return GetEqualityComparisonOperator(ExpressionType.Equal, "op_Equality", left, right, liftToNull);
            }

GetEqualityComparisonOperator will look for the op_Equality operator on both the left and right types. This cannot be expressed in the existing trimming annotations because we don't have a System.Type parameter to annotate. left and right are System.Linq.Expressions.Expression instances.

This same pattern applies to pretty much all Binary and Unary expressions:

  • Equal
  • NotEqual
  • Add
  • Subtract
  • Divide
  • Modulo
  • Multiply
  • Power
  • LeftShift
  • RightShift
  • And
  • Or
  • Not
  • Convert
  • Increment
  • Decrement
  • etc

Proposal

We should add a new rule in the mono/linker that when System.Linq.Expressions is used in an app, it should preserve all user defined operators on Types that are being preserved. This will allow the above Expression code to keep working in a trimmed application.

In the System.Linq.Expressions library, we can then suppress the remaining warnings saying "The trimmer won't trim operators on preserved Types when Expressions are involved. It is safe to try to find these operator methods."

cc @vitek-karas @MichalStrehovsky @marek-safar

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions