-
Notifications
You must be signed in to change notification settings - Fork 128
Description
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."