diff --git a/spec/traits.dd b/spec/traits.dd index edb8362c02..b25da5bab3 100644 --- a/spec/traits.dd +++ b/spec/traits.dd @@ -1020,6 +1020,68 @@ void main() $(P If the two arguments are expressions made up of literals or enums that evaluate to the same value, true is returned.) + $(P If the two arguments are both lambda functions (or aliases + to lambda functions), then they are compared for equality. For + the comparison to be computed correctly, the following conditions + must be met for both lambda functions:) + + $(OL + $(LI The lambda function arguments must not have a template + instantiation as an explicit argument type. Any other argument + types (basic, user-defined, template) are supported.) + $(LI The lambda function body must contain a single expression + (no return statement) which contains only numeric values, + manifest constants, enum values and function arguments. If the + expression contains local variables, function calls or return + statements, the function is considered uncomparable.) + ) + + $(P If these constraints aren't fulfilled, the function is considered + incomparable and `isSame` returns $(D false).) + +$(SPEC_RUNNABLE_EXAMPLE_COMPILE +--- +void main() +{ + static assert(__traits(isSame, (a, b) => a + b, (c, d) => c + d)); + static assert(__traits(isSame, a => ++a, b => ++b)); + static assert(!__traits(isSame, (int a, int b) => a + b, (a, b) => a + b)); + static assert(__traits(isSame, (a, b) => a + b + 10, (c, d) => c + d + 10)); + + // lambdas accessing local variables are considered incomparable + int b; + static assert(!__traits(isSame, a => a + b, a => a + b)); + + // lambdas calling a function inside their body are considered incomparable + int f() { return 3;} + static assert(!__traits(isSame, a => a + f(), a => a + f())); + + class A + { + int a; + this(int a) + { + this.a = a; + } + } + + class B + { + int a; + this(int a) + { + this.a = a; + } + } + + static assert(__traits(isSame, (A a) => ++a.a, (A b) => ++b.a)); + // lambdas with different data types are considered incomparable, + // even if the memory layout is the same + static assert(!__traits(isSame, (A a) => ++a.a, (B a) => ++a.a)); +} +--- +) + $(H2 $(GNAME compiles)) $(P Returns a bool $(D true) if all of the arguments