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.