return scope ref outlives the scope of the argument
Eugene Wissner
belka at caraus.de
Tue Jun 25 12:32:35 UTC 2019
On Tuesday, 25 June 2019 at 12:04:27 UTC, Jonathan M Davis wrote:
> On Tuesday, June 25, 2019 1:32:58 AM MDT Eugene Wissner via
> Digitalmars-d- learn wrote:
>> struct Container
>> {
>> }
>>
>> static struct Inserter
>> {
>> private Container* container;
>>
>> private this(return scope ref Container container)
>> @trusted
>> {
>> this.container = &container;
>> }
>>
>> }
>>
>> auto func()()
>> {
>> Container container;
>> return Inserter(container);
>> }
>>
>> void main()
>> {
>> static assert(!is(typeof(func!())));
>> }
>>
>> The code above compiles with dmd 2.085, but not 2.086 (with
>> -preview=dip1000). What am I doing wrong?
>
> Okay. I clearly looked over what you posted too quickly and
> assumed that the subject was the error that you were actually
> getting. The @trusted there is what's making the static
> asertion fail.
>
> Inserter is able to compile with -dip1000 (or
> -preview=dip1000), because you marked it as @trusted, which
> throws away the scope checks. If you mark it @safe, it won't
> compile. Without -dip1000, I wouldn't have expected anything to
> be caught, but trying it on run.dlang.io, it looks like the
> return probably makes it fail, which I find surprising, since I
> didn't think that return had any effect without -dip25, but I
> haven't done much with return on parameters.
>
> You'd have an easier time figuring out what's going on if you'd
> just not make func a template rather than use the static
> assertion, because then you'd see the compiler errors.
>
> In any case, by using @trusted, you're getting around the scope
> compiler checks, which is why Inserter is able to compile with
> -dip1000. Without -dip1000, I'm not experience enough with
> return parameters to know what the compiler will or won't
> catch, but the code is an @safety probelm regardless. It does
> look like the behavior changed with 2.086 even without -dip1000
> being used, which probably has something to do with how the
> compiler was changed for DIP 1000, though it probably wasn't on
> purpose, since in theory, the behavior shouldn't have changed
> without -dip1000, but I don't know.
>
> - Jonathan M Davis
Yes, reduced code could be a bit better.
@trusted doesn't throw scope checks away (and it wouldn't make
any sense since I don't see another way to make the code above
safe). Try:
struct Container
{
}
private Container* stuff(return scope ref Container container)
@trusted
{
return &container;
}
auto func()
{
Container container;
return stuff(container);
}
It fails with -dip1000 and works without (as expected).
"return scope ref" parameter in the constructor means, that the
constructed object has the same scope as the scope of the
argument.
I just want to know whether the behaviour of 2.085 or 2.086 is
correct and if it is an "improvement" in 2.086, what I'm doing
wrong.
More information about the Digitalmars-d-learn
mailing list