Skip to content

Primary Type Syntax #3616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spec/expression.dd
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions spec/function.dd
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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.)

Expand Down
12 changes: 12 additions & 0 deletions spec/statement.dd
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand All @@ -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,
Expand Down
8 changes: 5 additions & 3 deletions spec/traits.dd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 26 additions & 4 deletions spec/type.dd
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)

Expand All @@ -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,
Expand Down Expand Up @@ -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 `()`
---
)

Expand Down