Skip to content
Merged
Changes from all commits
Commits
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
60 changes: 40 additions & 20 deletions spec/function.dd
Original file line number Diff line number Diff line change
Expand Up @@ -1242,9 +1242,11 @@ int foo(in int x, out int y, ref int z, int q);
$(TROW $(D out), parameter is passed by reference and initialized upon function entry with the default value
for its type)

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

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

$(P Note: The `return` attribute is currently only enforced by `dmd`
when the `-dip25` switch is passed.
)

$(P Return ref parameters are used with
$(RELATIVE_LINK2 ref-functions, ref functions) to ensure that the
returned reference will not outlive the matching argument's lifetime.
Expand Down Expand Up @@ -1539,35 +1537,60 @@ inout(int)* neptune(inout ref int i)
}
---

$(H3 $(LNAME2 return-scope-parameters, Return Scope Parameters))
$(H3 $(LNAME2 scope-parameters, Scope Parameters))

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

---
@safe:

int* gp;
void thorin(scope int*);
void gloin(int*);
int* balin(return scope int* p, scope int* q, int* r)
int* balin(scope int* q, int* r)
{
gp = p; // error, p escapes to global gp
gp = q; // error, q escapes to global gp
gp = r; // ok

thorin(p); // ok, p does not escape thorin()
thorin(q); // ok
thorin(q); // ok, q does not escape thorin()
thorin(r); // ok

gloin(p); // error, gloin() escapes p
gloin(q); // error, gloin() escapes q
gloin(r); // ok that gloin() escapes r

return p; // ok
return q; // error, cannot return 'scope' q
return r; // ok
}
---

$(P As a `scope` parameter must not escape, the compiler can potentially avoid heap-allocating a
unique argument to a `scope` parameter. Due to this, passing an array literal, delegate
literal or a $(GLINK2 expression, NewExpression) to a scope parameter may be allowed in a
`@nogc` context, depending on the compiler implementation.)

$(H4 $(LNAME2 return-scope-parameters, Return Scope Parameters))

$(P Parameters marked as `return scope` that contain indirections
can only escape those indirections via the function's return value.)

---
@safe:

int* gp;
void thorin(scope int*);
void gloin(int*);
int* balin(return scope int* p)
{
gp = p; // error, p escapes to global gp
thorin(p); // ok, p does not escape thorin()
gloin(p); // error, gloin() escapes p
return p; // ok
}
---

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

$(P $(B Note:) Checks for `scope` parameters are currently enabled
only for $(D @safe) functions when compiled with the $(D -dip1000) flag.)

$(H3 $(LNAME2 ref-return-scope-parameters, Ref Return Scope Parameters))
$(H4 $(LNAME2 ref-return-scope-parameters, Ref Return Scope Parameters))

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

Expand Down