Skip to content

Commit bdb3149

Browse files
ntrelRazvanN7
andauthored
[spec] Improve is(Type == keyword) and Identifier docs (#3534)
* [spec] Improve is(Type == keyword) docs Describe `== TypeCtor` more precisely and add example. Remove is(i == const) example as even if `const int i;` was used it would still be false because `i` isn't a type. Add note to prefer isModule and isPackage __traits (ideally `== module` and `== package` would be deprecated as they only pass when *Type* is not a type). For Identifier form, link to non-Identifier to avoid repeating the same info. * Fix package modules link and unclosed macro * Tighten 'declared with' -> 'of' that TypeCtor * Split up type vs pattern forms & add examples Add example of type implicitly converting to match pattern. Update `Identifier ==` example and add pattern example. Fixes Issue 23730 - Clarify IsExpression `Identifier :` and `== TypeCtor` spec. * Tweak module/package note Co-authored-by: Razvan Nitu <[email protected]> * super, return and __parameters work without Identifier --------- Co-authored-by: Razvan Nitu <[email protected]>
1 parent 7624ccd commit bdb3149

File tree

1 file changed

+93
-57
lines changed

1 file changed

+93
-57
lines changed

spec/expression.dd

Lines changed: 93 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,7 +2748,8 @@ void foo()
27482748
$(H5 $(LNAME2 is-type-equal, $(D is $(LPAREN)) $(I Type) $(D ==) $(I TypeSpecialization) $(D $(RPAREN))))
27492749

27502750
$(P
2751-
The condition is satisfied if $(I Type) is semantically correct and is
2751+
If *TypeSpecialization* is a type,
2752+
the condition is satisfied if $(I Type) is semantically correct and is
27522753
the same type as $(I TypeSpecialization).
27532754
)
27542755
-------------
@@ -2764,7 +2765,6 @@ void foo()
27642765
-------------
27652766
$(P
27662767
If $(I TypeSpecialization) is one of
2767-
27682768
$(D struct)
27692769
$(D union)
27702770
$(D class)
@@ -2773,27 +2773,63 @@ void foo()
27732773
$(D __vector)
27742774
$(D function)
27752775
$(D delegate)
2776-
$(D const)
2777-
$(D immutable)
2778-
$(D inout)
2779-
$(D shared)
27802776
$(D module)
27812777
$(D package)
2782-
27832778
then the condition is satisfied if $(I Type) is one of those.
27842779
)
2780+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
27852781
---
27862782
static assert(is(Object == class));
2787-
2788-
int i;
2789-
static assert(!is(i == const));
2783+
static assert(is(ModuleInfo == struct));
27902784
---
2791-
$(P $(DDSUBLINK
2792-
spec/module, package-module, Package modules) are considered to be both
2785+
)
2786+
$(P The `module` and `package` forms are satisfied when *Type* is a symbol, not a *type*,
2787+
unlike the other forms. The $(DDSUBLINK spec/traits, isModule, isModule)
2788+
and $(DDSUBLINK spec/traits, isPackage, isPackage) `__traits` should be used instead.
2789+
$(DDSUBLINK spec/module, package-module, Package modules) are considered to be both
27932790
packages and modules.
27942791
)
2792+
$(P
2793+
*TypeSpecialization* can also be one of these keywords:
2794+
)
2795+
$(TABLE
2796+
$(THEAD keyword, condition)
2797+
$(TROW `super`, `true` if *Type* is a class or interface)
2798+
$(TROW `return`,
2799+
$(ARGS `true` if *Type* is a function, delegate or function pointer))
2800+
$(TROW `__parameters`,
2801+
$(ARGS `true` if *Type* is a function, delegate or function pointer))
2802+
)
2803+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
2804+
---
2805+
class C {}
2806+
static assert(is(C == super));
2807+
2808+
void foo(int i);
2809+
static assert(!is(foo == return));
2810+
static assert(is(typeof(foo) == return));
2811+
static assert(is(typeof(foo) == __parameters));
2812+
---
2813+
)
2814+
$(P
2815+
If *TypeSpecialization* is a $(GLINK2 type, TypeCtor) keyword
2816+
$(D const)
2817+
$(D immutable)
2818+
$(D inout)
2819+
$(D shared)
2820+
then the condition is satisfied if *Type* is of that *TypeCtor*:
2821+
)
2822+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
2823+
---
2824+
static assert(is(const int == const));
2825+
static assert(is(const int[] == const));
2826+
static assert(!is(const(int)[] == const)); // head is mutable
2827+
static assert(!is(immutable int == const));
2828+
---
2829+
)
27952830
$(P $(B See also:) $(DDLINK spec/traits, Traits, Traits).)
27962831

2832+
27972833
$(H4 $(LNAME2 is-identifier, Identifier Forms))
27982834

27992835
$(P *Identifier* is declared to be an alias of the resulting
@@ -2846,14 +2882,12 @@ void foo()
28462882
)
28472883

28482884
$(P
2849-
The condition is satisfied if $(I Type) is semantically
2885+
If *TypeSpecialization* is a type,
2886+
the condition is satisfied if $(I Type) is semantically
28502887
correct and it is the same as
28512888
or can be implicitly converted to $(I TypeSpecialization).
2852-
$(I TypeSpecialization) is only allowed to be a $(I Type).
2853-
The $(I Identifier) is declared to be either an alias of the
2854-
$(I TypeSpecialization) or, if $(I TypeSpecialization) is
2855-
dependent on $(I Identifier), the $(I TypeSpecialization) forms
2856-
a pattern from which the type of $(I Identifier) is deduced.
2889+
$(I Identifier) is declared to be an alias of the
2890+
$(I TypeSpecialization).
28572891
)
28582892

28592893
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
@@ -2868,11 +2902,22 @@ void foo()
28682902
static assert(is(S == int));
28692903
---
28702904
)
2905+
$(P
2906+
If $(I TypeSpecialization) is a type pattern involving
2907+
$(I Identifier), type deduction of $(I Identifier) is attempted
2908+
based on either *Type* or a type that it implicitly converts to.
2909+
The condition is only satisfied if the type pattern is matched.
2910+
)
2911+
28712912
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
28722913
---
2873-
alias Abc = long*;
2914+
struct S
2915+
{
2916+
long* i;
2917+
alias i this; // S converts to long*
2918+
}
28742919

2875-
static if (is(Abc U : U*)) // Abc is matched against the pattern U*
2920+
static if (is(S U : U*)) // S is matched against the pattern U*
28762921
{
28772922
U u;
28782923
}
@@ -2889,55 +2934,46 @@ void foo()
28892934
$(H5 $(LNAME2 is-identifier-equal, $(D is $(LPAREN)) $(I Type) $(I Identifier) $(D ==) $(I TypeSpecialization) $(D $(RPAREN))))
28902935

28912936
$(P
2892-
The condition is satisfied if $(I Type) is semantically
2893-
correct and is the same as $(I TypeSpecialization).
2894-
The $(I Identifier) is declared to be either an alias of the
2895-
$(I TypeSpecialization) or, if $(I TypeSpecialization) is
2896-
dependent on $(I Identifier), the $(I TypeSpecialization) forms
2897-
a pattern from which the type of $(I Identifier) is deduced.
2937+
If *TypeSpecialization* is a type,
2938+
the condition is satisfied if $(I Type) is semantically correct and is
2939+
the same type as $(I TypeSpecialization).
2940+
$(I Identifier) is declared to be an alias of the
2941+
$(I TypeSpecialization).
28982942
)
2899-
29002943
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
29012944
---
2902-
alias Bar = short;
2945+
const x = 5;
29032946

2904-
static if (is(Bar T == int)) // not satisfied, short is not int
2947+
static if (is(typeof(x) T == const int)) // satisfied, T is now defined
29052948
alias S = T;
29062949

2907-
static assert(!is(T)); // T is not defined
2950+
static assert(is(T)); // T is in scope
2951+
pragma(msg, T); // const int
29082952
---
29092953
)
29102954

29112955
$(P
2912-
If $(I TypeSpecialization) is one of
2913-
$(D struct)
2914-
$(D union)
2915-
$(D class)
2916-
$(D interface)
2917-
$(D enum)
2918-
$(D __vector)
2919-
$(D function)
2920-
$(D delegate)
2921-
$(D const)
2922-
$(D immutable)
2923-
$(D inout)
2924-
$(D shared)
2925-
$(D module)
2926-
$(D package)
2927-
2928-
then the condition is satisfied if $(I Type) is one of those.
2929-
*TypeSpecialization* can also match the following keywords:
2930-
)
2931-
$(TABLE
2932-
$(THEAD keyword, condition)
2933-
$(TROW `super`, `true` if *Type* is a class or interface)
2934-
$(TROW `return`,
2935-
$(ARGS `true` is *Type* is a function, delegate or function pointer))
2936-
$(TROW `__parameters`,
2937-
$(ARGS `true` is *Type* is a function, delegate or function pointer))
2956+
If $(I TypeSpecialization) is a type pattern involving
2957+
$(I Identifier), type deduction of $(I Identifier) is attempted
2958+
based on *Type*.
2959+
The condition is only satisfied if the type pattern is matched.
29382960
)
2961+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
2962+
---
2963+
alias Foo = long*;
2964+
2965+
static if (is(Foo U == U*)) // Foo is matched against the pattern U*
2966+
{
2967+
U u;
2968+
}
2969+
static assert(is(U == long));
2970+
---
2971+
)
29392972
$(P
2940-
Furthermore, $(I Identifier) is set to be an alias of the type:
2973+
If *TypeSpecialization* is a valid keyword for the
2974+
$(RELATIVE_LINK2 is-type-equal, `is(Type == Keyword)` form),
2975+
the condition is satisfied in the same manner.
2976+
$(I Identifier) is set as follows:
29412977
)
29422978

29432979
$(TABLE_2COLS ,

0 commit comments

Comments
 (0)