Skip to content

Commit 43b6100

Browse files
authored
Merge pull request #2454 from ntrel/scope-param
[spec/function.dd] Add scope parameter section merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
2 parents 9c3e74d + 16df53d commit 43b6100

File tree

1 file changed

+40
-20
lines changed

1 file changed

+40
-20
lines changed

spec/function.dd

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,9 +1242,11 @@ int foo(in int x, out int y, ref int z, int q);
12421242
$(TROW $(D out), parameter is passed by reference and initialized upon function entry with the default value
12431243
for its type)
12441244

1245-
$(TROW $(D scope), references in the parameter
1246-
cannot be escaped (e.g. assigned to a global variable).
1247-
Ignored for parameters with no references)
1245+
$(TROW $(D scope), $(ARGS
1246+
The parameter must not escape the function call
1247+
(e.g. by being assigned to a global variable).
1248+
Ignored for any parameter that is not a reference type.
1249+
))
12481250
$(TROW $(D return), $(ARGS Parameter may be returned or copied to the first parameter,
12491251
but otherwise does not escape from the function.
12501252
Such copies are required not to outlive the argument(s) they were derived from.
@@ -1422,10 +1424,6 @@ pure void f()
14221424

14231425
$(H3 $(LNAME2 return-ref-parameters, Return Ref Parameters))
14241426

1425-
$(P Note: The `return` attribute is currently only enforced by `dmd`
1426-
when the `-dip25` switch is passed.
1427-
)
1428-
14291427
$(P Return ref parameters are used with
14301428
$(RELATIVE_LINK2 ref-functions, ref functions) to ensure that the
14311429
returned reference will not outlive the matching argument's lifetime.
@@ -1539,35 +1537,60 @@ inout(int)* neptune(inout ref int i)
15391537
}
15401538
---
15411539

1542-
$(H3 $(LNAME2 return-scope-parameters, Return Scope Parameters))
1540+
$(H3 $(LNAME2 scope-parameters, Scope Parameters))
15431541

1544-
$(P Parameters marked as `return scope` that contain indirections
1545-
can only escape those indirections via the function's return value.)
1542+
$(P A `scope` parameter of reference type must not escape the function call
1543+
(e.g. by being assigned to a global variable). It has no effect for non-reference types.
1544+
`scope` escape analysis is only done for `@safe` functions. For other functions `scope`
1545+
semantics must be manually enforced.)
1546+
$(P $(B Note): `scope` escape analysis is currently only done by `dmd`
1547+
when the `-dip1000` switch is passed.)
15461548

15471549
---
15481550
@safe:
15491551

15501552
int* gp;
15511553
void thorin(scope int*);
15521554
void gloin(int*);
1553-
int* balin(return scope int* p, scope int* q, int* r)
1555+
int* balin(scope int* q, int* r)
15541556
{
1555-
gp = p; // error, p escapes to global gp
15561557
gp = q; // error, q escapes to global gp
15571558
gp = r; // ok
15581559

1559-
thorin(p); // ok, p does not escape thorin()
1560-
thorin(q); // ok
1560+
thorin(q); // ok, q does not escape thorin()
15611561
thorin(r); // ok
15621562

1563-
gloin(p); // error, gloin() escapes p
15641563
gloin(q); // error, gloin() escapes q
15651564
gloin(r); // ok that gloin() escapes r
15661565

1567-
return p; // ok
15681566
return q; // error, cannot return 'scope' q
15691567
return r; // ok
15701568
}
1569+
---
1570+
1571+
$(P As a `scope` parameter must not escape, the compiler can potentially avoid heap-allocating a
1572+
unique argument to a `scope` parameter. Due to this, passing an array literal, delegate
1573+
literal or a $(GLINK2 expression, NewExpression) to a scope parameter may be allowed in a
1574+
`@nogc` context, depending on the compiler implementation.)
1575+
1576+
$(H4 $(LNAME2 return-scope-parameters, Return Scope Parameters))
1577+
1578+
$(P Parameters marked as `return scope` that contain indirections
1579+
can only escape those indirections via the function's return value.)
1580+
1581+
---
1582+
@safe:
1583+
1584+
int* gp;
1585+
void thorin(scope int*);
1586+
void gloin(int*);
1587+
int* balin(return scope int* p)
1588+
{
1589+
gp = p; // error, p escapes to global gp
1590+
thorin(p); // ok, p does not escape thorin()
1591+
gloin(p); // error, gloin() escapes p
1592+
return p; // ok
1593+
}
15711594
---
15721595

15731596
$(P Class references are considered pointers that are subject to `scope`.)
@@ -1611,10 +1634,7 @@ class C
16111634
$(P Template functions, auto functions, nested functions and lambdas can deduce
16121635
the `return scope` attribute.)
16131636

1614-
$(P $(B Note:) Checks for `scope` parameters are currently enabled
1615-
only for $(D @safe) functions when compiled with the $(D -dip1000) flag.)
1616-
1617-
$(H3 $(LNAME2 ref-return-scope-parameters, Ref Return Scope Parameters))
1637+
$(H4 $(LNAME2 ref-return-scope-parameters, Ref Return Scope Parameters))
16181638

16191639
$(P Parameters marked as `ref return scope` come in two forms:)
16201640

0 commit comments

Comments
 (0)