Skip to content

Commit 221f6dc

Browse files
authored
[spec/const3] Improve immutable storage class docs (#4332)
An immutable declaration is not a manifest constant! Make some examples runnable, add static asserts. Add links. Fix example - *shared* static this() is needed to initialize immutable vars. See also manifest constants. Tweak immutable method example.
1 parent a532fc1 commit 221f6dc

File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed

spec/const3.dd

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,51 +46,68 @@ $(H2 $(LNAME2 immutable_storage_class, Immutable Storage Class))
4646

4747
$(P
4848
The simplest immutable declarations use it as a storage class.
49-
It can be used to declare manifest constants.
49+
It can be used to declare a variable whose value never changes.
5050
)
5151

52+
$(SPEC_RUNNABLE_EXAMPLE_RUN
5253
---
5354
immutable int x = 3; // x is set to 3
54-
x = 4; // error, x is immutable
55-
char[x] s; // s is an array of 3 chars
56-
---
55+
//x = 4; // error, x is immutable
5756

57+
// x is initialized by a compile-time constant,
58+
// and it doesn't change, so the compiler knows its value
59+
static assert(x == 3);
60+
61+
char[x] s;
62+
static assert(s.length == 3);
63+
---
64+
)
5865
$(P The type can be inferred from the initializer:
5966
)
6067
---
6168
immutable y = 4; // y is of type int
6269
y = 5; // error, y is immutable
6370
---
6471

65-
$(P If the initializer is not present, the immutable can
66-
be initialized from the corresponding constructor:
72+
$(P If the initializer is not present, the immutable variable can
73+
be initialized from the corresponding $(DDSUBLINK spec/module, staticorder,
74+
shared static constructor):
6775
)
6876

77+
$(SPEC_RUNNABLE_EXAMPLE_RUN
6978
---
7079
immutable int z;
71-
void test()
80+
81+
void main()
7282
{
73-
z = 3; // error, z is immutable
83+
assert(z == 3);
84+
//z = 4; // error, z is immutable
7485
}
75-
static this()
86+
87+
shared static this()
7688
{
77-
z = 3; // ok, can set immutable that doesn't
78-
// have static initializer
89+
z = 3; // ok, can initialize immutable variable that doesn't
90+
// have a static initializer
7991
}
8092
---
93+
)
8194
$(P
82-
The initializer for a non-local immutable declaration must be
83-
evaluatable
84-
at compile time:
95+
The initializer for a non-$(DDSUBLINK spec/function, local-variables, local)/static
96+
immutable declaration must be evaluatable at compile time:
8597
)
8698

99+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
87100
---
101+
immutable x = 3 * 4;
102+
static assert(x == 12);
103+
88104
int foo(int f) { return f * 3; }
89105
int i = 5;
90-
immutable x = 3 * 4; // ok, 12
91-
immutable y = i + 1; // error, cannot evaluate at compile time
92-
immutable z = foo(2) + 1; // ok, foo(2) can be evaluated at compile time, 7
106+
//immutable y = i + 1; // error, cannot evaluate `i` at compile time
107+
immutable z = foo(2) + 1; // ok, foo(2) can be evaluated at compile time
108+
static assert(z == 7);
93109
---
110+
)
94111

95112
$(P The initializer for a non-static local immutable declaration
96113
is evaluated at run time:
@@ -104,8 +121,8 @@ int foo(int f)
104121
---
105122

106123
$(P
107-
Because immutable is transitive, data referred to by an immutable is
108-
also immutable:
124+
Because immutable is transitive, data referred to by an immutable
125+
variable is also immutable:
109126
)
110127

111128
---
@@ -118,6 +135,8 @@ s = "bar"; // error, s is immutable
118135
have their address taken, and occupy storage.
119136
)
120137

138+
$(P **See also:** $(DDSUBLINK spec/enum, manifest_constants, Manifest Constants).)
139+
121140
$(H2 $(LNAME2 const_storage_class, Const Storage Class))
122141

123142
$(P
@@ -348,18 +367,20 @@ $(H2 $(LNAME2 immutable_member_functions, Immutable Member Functions))
348367
They are declared as:
349368
)
350369

370+
$(SPEC_RUNNABLE_EXAMPLE_FAIL
351371
---
352372
struct S
353373
{
354374
int x;
355375

356376
void foo() immutable
357377
{
358-
x = 4; // error, x is immutable
359-
this.x = 4; // error, x is immutable
378+
x = 4; // error, `x` is immutable
379+
this = S(); // error, `this` is immutable
360380
}
361381
}
362382
---
383+
)
363384
$(P Note that using $(D_KEYWORD immutable) on the left hand side of a method does not apply to the return type:
364385
)
365386

0 commit comments

Comments
 (0)