Thread overview
[Issue 19966] [DIP1000] DIP1000 with a template behaves differently
Mar 13, 2020
Walter Bright
Mar 13, 2020
Jacob Carlborg
Mar 13, 2020
Walter Bright
Mar 13, 2020
Walter Bright
Mar 13, 2020
Walter Bright
Mar 13, 2020
Jacob Carlborg
Mar 13, 2020
Jacob Carlborg
Mar 13, 2020
Walter Bright
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> ---
> 2. I think the above code is actually valid because it's not provable that `foo` escapes a pointer to the internal state of `Foo`

It's not valid because foo() is defined as returning a pointer that is equivalent to foo()'s `this` pointer. Then, `a = f.foo;` is treated as assigning the address of `f` to `a`, a global, which is an error. The compiler is behaving correctly for this point.

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

--- Comment #2 from Jacob Carlborg <doob@me.com> ---
(In reply to Walter Bright from comment #1)
> > 2. I think the above code is actually valid because it's not provable that `foo` escapes a pointer to the internal state of `Foo`
> 
> It's not valid because foo() is defined as returning a pointer that is equivalent to foo()'s `this` pointer. Then, `a = f.foo;` is treated as assigning the address of `f` to `a`, a global, which is an error. The compiler is behaving correctly for this point.

So it doesn't matter if "foo" is returning something else, like a global variable?

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> ---
> 1. `Foo` as a template and as a non-template struct behaves differently

What's happening is that when `Foo` is a template, then inference happens with `foo()`, which infers that `this.bar` is being returned, not `this`. You can verify this by removing the function body for `foo()` so inference cannot happen, and then the error appears, because without inference the `return` applies to `this`, not `this.bar`.

Not a bug.

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

--- Comment #4 from Walter Bright <bugzilla@digitalmars.com> ---
> So it doesn't matter if "foo" is returning something else, like a global variable?

If inference is not happening, then the compiler believes you when you say it is returning the `this` pointer. This is a feature, not a bug, as it enables you to attach the checking to the `this` pointer.

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |INVALID

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

--- Comment #5 from Jacob Carlborg <doob@me.com> ---
(In reply to Walter Bright from comment #3)
> > 1. `Foo` as a template and as a non-template struct behaves differently
> 
> What's happening is that when `Foo` is a template, then inference happens with `foo()`, which infers that `this.bar` is being returned, not `this`. You can verify this by removing the function body for `foo()` so inference cannot happen, and then the error appears, because without inference the `return` applies to `this`, not `this.bar`.
> 
> Not a bug.

Is it possible to somehow get the behavior I want? To make sure that some internal state of "f" cannot outlive "f" itself.

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

--- Comment #6 from Jacob Carlborg <doob@me.com> ---
(In reply to Walter Bright from comment #3)
> > 1. `Foo` as a template and as a non-template struct behaves differently
> 
> What's happening is that when `Foo` is a template, then inference happens with `foo()`, which infers that `this.bar` is being returned, not `this`. You can verify this by removing the function body for `foo()` so inference cannot happen, and then the error appears, because without inference the `return` applies to `this`, not `this.bar`.
> 
> Not a bug.

But is it possible to get what I want somehow? To make sure no internal state of "f" outlives "f" itself.

--
March 13, 2020
https://issues.dlang.org/show_bug.cgi?id=19966

--- Comment #7 from Walter Bright <bugzilla@digitalmars.com> ---
That's what @live is for.

--