@@ -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---
27862782static 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