diff --git a/spec/expression.dd b/spec/expression.dd index e24046823b..4ae2b488ce 100644 --- a/spec/expression.dd +++ b/spec/expression.dd @@ -2393,8 +2393,8 @@ $(H3 $(LNAME2 function_literals, Function Literals)) $(GRAMMAR $(GNAME FunctionLiteral): - $(D function) $(GLINK RefOrAutoRef)$(OPT) $(GLINK BasicTypeWithSuffixes)$(OPT) $(GLINK ParameterWithAttributes)$(OPT) $(GLINK FunctionLiteralBody) - $(D delegate) $(GLINK RefOrAutoRef)$(OPT) $(GLINK BasicTypeWithSuffixes)$(OPT) $(GLINK ParameterWithMemberAttributes)$(OPT) $(GLINK FunctionLiteralBody) + $(D function) $(GLINK2 attribute, LinkageAttribute)$(OPT) $(GLINK RefOrAutoRef)$(OPT) $(GLINK BasicTypeWithSuffixes)$(OPT) $(GLINK ParameterWithAttributes)$(OPT) $(GLINK FunctionLiteralBody) + $(D delegate) $(GLINK2 attribute, LinkageAttribute)$(OPT) $(GLINK RefOrAutoRef)$(OPT) $(GLINK BasicTypeWithSuffixes)$(OPT) $(GLINK ParameterWithMemberAttributes)$(OPT) $(GLINK FunctionLiteralBody) $(GLINK RefOrAutoRef)$(OPT) $(GLINK ParameterWithMemberAttributes) $(GLINK FunctionLiteralBody) $(GLINK2 statement, BlockStatement) $(IDENTIFIER) $(D =>) $(GLINK AssignExpression) diff --git a/spec/function.dd b/spec/function.dd index 4a869b98f8..ef6b6769eb 100644 --- a/spec/function.dd +++ b/spec/function.dd @@ -50,6 +50,8 @@ $(GNAME Parameter): $(GNAME ParameterDeclaration): $(GLINK ParameterAttributes)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) + $(GLINK ParameterAttributes)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) + $(GLINK ParameterAttributes)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(D ref) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) $(GLINK ParameterAttributes)$(OPT) $(GLINK2 type, Type) $(GNAME ParameterAttributes): @@ -80,6 +82,8 @@ $(GNAME VariadicArgumentsAttribute): $(D scope) $(D shared) ) +$(P When $(I LinkageAttribute) is present, +the $(I Declarator) must include exactly one $(I CallableSuffix).) $(NOTE In D2, declaring a parameter `final` is a semantic error, but not a parse error.) diff --git a/spec/statement.dd b/spec/statement.dd index ad268cbd07..c80be3508e 100644 --- a/spec/statement.dd +++ b/spec/statement.dd @@ -241,6 +241,8 @@ $(GNAME IfCondition): $(EXPRESSION) $(GLINK IfConditionStorageClasses) $(GLINK_LEX Identifier) $(D =) $(EXPRESSION) $(GLINK IfConditionStorageClasses)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) $(D =) $(EXPRESSION) + $(GLINK IfConditionStorageClasses)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) $(D =) $(EXPRESSION) + $(GLINK IfConditionStorageClasses)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(D ref) $(GLINK2 type, TypeCtors)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) $(D =) $(EXPRESSION) $(GNAME IfConditionStorageClasses): $(GLINK IfConditionStorageClass) @@ -259,6 +261,9 @@ $(GNAME ElseStatement): $(PSSCOPE) ) + $(P When $(I LinkageAttribute) is present, + the $(I Declarator) must include exactly one $(I CallableSuffix).) + $(P If there is a declared *Identifier* variable, $(RELATIVE_LINK2 condition-variables, it is evaluated). Otherwise, *Expression* is evaluated. The result is converted to a @@ -499,6 +504,8 @@ $(GNAME ForeachTypeList): $(GNAME ForeachType): $(GLINK ForeachTypeAttributes)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) + $(GLINK ForeachTypeAttributes)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) + $(GLINK ForeachTypeAttributes)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(D ref) $(GLINK2 type, BasicType) $(GLINK2 declaration, Declarator) $(GLINK ForeachTypeAttributes)$(OPT) $(GLINK_LEX Identifier) $(GLINK ForeachTypeAttributes)$(OPT) $(D alias) $(GLINK_LEX Identifier) @@ -516,6 +523,11 @@ $(GNAME ForeachAggregate): $(EXPRESSION) ) +$(P + When $(I LinkageAttribute) is present, + the $(I Declarator) must include exactly one $(I CallableSuffix). +) + $(P $(I ForeachAggregate) is evaluated. It must evaluate to an expression which is a static array, dynamic array, associative array, diff --git a/spec/traits.dd b/spec/traits.dd index 39c2590383..5a0f500636 100644 --- a/spec/traits.dd +++ b/spec/traits.dd @@ -1957,13 +1957,15 @@ static assert(!isFooOrBar!(Point)); ) $(P The result is `true` if the two arguments are expressions - made up of literals or enums that evaluate to the same value.) + none of which are just symbols + that evaluate to the same value at compile-time.) $(SPEC_RUNNABLE_EXAMPLE_COMPILE --- enum e = 3; -static assert(__traits(isSame, (e), 3)); -static assert(__traits(isSame, 5, 2 + e)); +static assert(!__traits(isSame, e, 3)); // e is a symbol +static assert( __traits(isSame, cast(typeof(e)) e, 3)); // cast is an expression +static assert( __traits(isSame, 5, 2 + e)); // 5 and 2 + e are expressions --- ) $(P If the two arguments are both diff --git a/spec/type.dd b/spec/type.dd index 113d21f441..c48b10fffa 100644 --- a/spec/type.dd +++ b/spec/type.dd @@ -13,6 +13,9 @@ $(H2 $(LNAME2 grammar, Grammar)) $(GRAMMAR $(GNAME Type): $(GLINK TypeCtors)$(OPT) $(GLINK BasicType) $(GLINK TypeSuffixes)$(OPT) + $(GLINK TypeCtors)$(OPT) $(D ref) $(GLINK TypeCtors)$(OPT) $(GLINK BasicType) $(GLINK TypeSuffixes) + $(GLINK TypeCtors)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(GLINK TypeCtors)$(OPT) $(GLINK BasicType) $(GLINK TypeSuffixes) + $(GLINK TypeCtors)$(OPT) $(GLINK2 attribute, LinkageAttribute) $(D ref) $(GLINK TypeCtors)$(OPT) $(GLINK BasicType) $(GLINK TypeSuffixes) $(GNAME TypeCtors): $(GLINK TypeCtor) @@ -30,7 +33,7 @@ $(GNAME BasicType): $(GLINK QualifiedIdentifier) $(GLINK Typeof) $(GLINK Typeof) $(D .) $(GLINK QualifiedIdentifier) - $(GLINK TypeCtor) $(D $(LPAREN)) $(GLINK Type) $(D $(RPAREN)) + $(GLINK TypeCtor)$(OPT) $(D $(LPAREN)) $(GLINK Type) $(D $(RPAREN)) $(GLINK Vector) $(GLINK2 traits, TraitsExpression) $(GLINK MixinType) @@ -77,6 +80,9 @@ $(GNAME TypeSuffix): $(D [) $(GLINK2 expression, AssignExpression) $(D ]) $(D [) $(GLINK2 expression, AssignExpression) $(D ..) $(GLINK2 expression, AssignExpression) $(D ]) $(D [) $(GLINK Type) $(D ]) + $(GLINK CallableSuffix) + +$(GNAME CallableSuffix): $(D delegate) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) $(D function) $(GLINK2 function, Parameters) $(GLINK2 function, FunctionAttributes)$(OPT) @@ -93,6 +99,12 @@ $(GNAME QualifiedIdentifier): * $(RELATIVE_LINK2 derived-data-types, Derived Data Types) build on leaf types. * $(RELATIVE_LINK2 user-defined-types, User-Defined Types) are aggregates of basic and derived types. +$(P For a $(GLINK Type) to be well-formed, +if it uses a *LinkageAttribute* and/or `ref`, +the sequence of *TypeSuffixes* must include exactly one *CallableSuffix*; +then, initial *TypeCtors* refer to the whole type, +whereas *TypeCtors* after *LinkageAttribute* and/or `ref` affect the return type.) + $(H2 $(LEGACY_LNAME2 Basic Data Types, basic-data-types, Basic Data Types)) $(TABLE_3COLS Basic Data Types, @@ -624,19 +636,29 @@ A function type e.g. `int(int)` $(DDSUBLINK spec/declaration, alias-function, ca A function type is only used for type tests or as the target type of a pointer.) $(P Instantiating a function type is illegal. Instead, a pointer to function -or delegate can be used. Those have these type forms respectively:) +or delegate can be used. Somewhat simplified, those have these type forms respectively:) $(INFORMATIVE_GRAMMAR -$(GLINK Type) `function` $(GLINK2 function, Parameters) $(GLINK2 function, FunctionAttributes)$(OPT) -$(GLINK Type) `delegate` $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) +$(GLINK2 attribute, LinkageAttribute)$(OPT) $(GLINK Type) `function` $(GLINK2 function, Parameters) $(GLINK2 function, FunctionAttributes)$(OPT) +$(GLINK2 attribute, LinkageAttribute)$(OPT) $(GLINK Type) `delegate` $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) + +$(GLINK2 attribute, LinkageAttribute)$(OPT) $(D ref) $(GLINK BasicType) `function` $(GLINK2 function, Parameters) $(GLINK2 function, FunctionAttributes)$(OPT) +$(GLINK2 attribute, LinkageAttribute)$(OPT) $(D ref) $(GLINK BasicType) `delegate` $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT) ) +$(P When linkage attributes and/or `ref` are present, a function pointer or delegate type is not a $(GLINK BasicType), +and some contexts require surrounding them by parentheses. + $(SPEC_RUNNABLE_EXAMPLE_COMPILE --- void f(int); alias Fun = void(int); static assert(is(typeof(f) == Fun)); static assert(is(Fun* == void function(int))); + +// ref int g(ref int x) => x; +// (ref int function(ref int)) fp = &g; // variable declaration requires `()` +// static assert(is(typeof(fp) == ref int function(ref int))); // `is` requires no extra `()` --- )