From 2f49eb77a9e1ba6ca8c7e58cc3278d5a1513b04e Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 08:35:36 -0500 Subject: [PATCH 1/2] support relaxed shift operator requirements --- standard/expressions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/standard/expressions.md b/standard/expressions.md index 82ce81a03..6e411169b 100644 --- a/standard/expressions.md +++ b/standard/expressions.md @@ -253,7 +253,7 @@ An operation of the form `«op» x` or `x «op»`, where «op» is an overloada An operation of the form `x «op» y`, where «op» is an overloadable binary operator, `x` is an expression of type `X`, and `y` is an expression of type `Y`, is processed as follows: -- The set of candidate user-defined operators provided by `X` and `Y` for the operation `operator «op»(x, y)` is determined. The set consists of the union of the candidate operators provided by `X` and the candidate operators provided by `Y`, each determined using the rules of [§12.4.6](expressions.md#1246-candidate-user-defined-operators). For the combined set, candidates are merged as follows: +- The set of candidate user-defined operators provided by `X` and `Y` for the operation `operator «op»(x, y)` is determined. The set consists of the union of the candidate operators provided by `X` and, unless the operator is a shift operator, the candidate operators provided by `Y`, each determined using the rules of [§12.4.6](expressions.md#1246-candidate-user-defined-operators). For the combined set, candidates are merged as follows: - If `X` and `Y` are identity convertible, or if `X` and `Y` are derived from a common base type, then shared candidate operators only occur in the combined set once. - If there is an identity conversion between `X` and `Y`, an operator `«op»Y` provided by `Y` has the same return type as an `«op»X` provided by `X` and the operand types of `«op»Y` have an identity conversion to the corresponding operand types of `«op»X` then only `«op»X` occurs in the set. - If the set of candidate user-defined operators is not empty, then this becomes the set of candidate operators for the operation. Otherwise, the predefined binary `operator «op»` implementations, including their lifted forms, become the set of candidate operators for the operation. The predefined implementations of a given operator are specified in the description of the operator. For predefined enum and delegate operators, the only operators considered are those provided by an enum or delegate type that is the binding-time type of one of the operands. @@ -4512,7 +4512,7 @@ If an operand of a *shift_expression* has the compile-time type `dynamic`, then For an operation of the form `x << count` or `x >> count`, binary operator overload resolution ([§12.4.5](expressions.md#1245-binary-operator-overload-resolution)) is applied to select a specific operator implementation. The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator. -When declaring an overloaded shift operator, the type of the first operand shall always be the class or struct containing the operator declaration, and the type of the second operand shall always be `int`. +When declaring an overloaded shift operator, the type of the first operand shall always be the class or struct containing the operator declaration. The predefined shift operators are listed below. From 9da4f2e97758ef8ba848f5da6ec7288fac3910a8 Mon Sep 17 00:00:00 2001 From: Rex Jaeschke Date: Mon, 2 Mar 2026 08:37:53 -0500 Subject: [PATCH 2/2] support relaxed shift operator requirements --- standard/classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard/classes.md b/standard/classes.md index 594d56fb5..62e065037 100644 --- a/standard/classes.md +++ b/standard/classes.md @@ -5025,7 +5025,7 @@ The `true` and `false` unary operators require pair-wise declaration. A compile- The following rules apply to binary operator declarations, where `T` denotes the instance type of the class or struct that contains the operator declaration: - A binary non-shift operator shall take two parameters, at least one of which shall have type `T` or `T?`, and can return any type. -- A binary `<<` or `>>` operator ([§12.14](expressions.md#1214-shift-operators)) shall take two parameters, the first of which shall have type `T` or `T?` and the second of which shall have type `int` or `int?`, and can return any type. +- A binary `<<` or `>>` operator ([§12.14](expressions.md#1214-shift-operators)) shall take two parameters, the first of which shall have type `T` or `T?`, and can return any type. The signature of a binary operator consists of the operator token (`+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, `>>`, `==`, `!=`, `>`, `<`, `>=`, or `<=`) and the types of the two parameters. The return type and the names of the parameters are not part of a binary operator’s signature.