Bug 19060 – [REG2.081] Incorrect "Using this as a type is deprecated" error
Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-07-04T22:14:00Z
Last change time
2019-12-18T09:31:11Z
Keywords
industry
Assigned to
No Owner
Creator
johanengelen
Comments
Comment #0 by johanengelen — 2018-07-04T22:14:00Z
Testcase:
```
struct S {
bool x;
public template yoyo() {
alias yoyo = this.x; // line 5
}
public ref foo() {
return yoyo!();
}
}
```
Works correctly with dmd < 2.081, fails (incorrect deprecation) with 2.081:
❯ dmd testcase.d -de
testcase.d(5): Deprecation: Using this as a type is deprecated. Use typeof(this) instead
Comment #1 by alphaglosined — 2018-07-04T22:17:48Z
Comment #2 by alphaglosined — 2018-07-04T22:51:37Z
Okay looks like I was wrong.
Removing the class it would be equivalent at the module level to:
---
module self;
bool x;
template Foo() {
alias y = self.x;
}
alias Bar = Foo!();
---
Comment #3 by ag0aep6g — 2018-07-04T23:47:48Z
As far as I can see, the deprecation is correct. You can't get an alias of an instance field. The alias was to `S.x` the whole time. You're just being forced to spell it out now.
Comment #4 by razvan.nitu1305 — 2018-07-05T18:48:47Z
Indeed, this is not a regression, it is intended behavior.
Comment #5 by johanengelen — 2018-07-05T20:44:25Z
OK, then this is still broken and should receive a deprecation message too:
```
struct S {
int a;
bool x;
public ref foo() {
alias yoyo = this.x;
return yoyo;
}
}
```
Comment #6 by razvan.nitu1305 — 2018-11-05T14:32:37Z
(In reply to johanengelen from comment #5)
> OK, then this is still broken and should receive a deprecation message too:
>
> ```
> struct S {
> int a;
> bool x;
> public ref foo() {
> alias yoyo = this.x;
> return yoyo;
> }
> }
> ```
Actually, I don't think it should. Foo can only be called on an instance, therefore `this` does make sense in that context. Imagine that you would define a local variable x, if you wouldn't be able to use `this` then the local would mask the member everywhere.
I suggest to close this as invalid.
Comment #7 by ag0aep6g — 2018-11-05T16:56:31Z
(In reply to RazvanN from comment #6)
> (In reply to johanengelen from comment #5)
> > OK, then this is still broken and should receive a deprecation message too:
> >
> > ```
> > struct S {
> > int a;
> > bool x;
> > public ref foo() {
> > alias yoyo = this.x;
> > return yoyo;
> > }
> > }
> > ```
>
> Actually, I don't think it should. Foo can only be called on an instance,
> therefore `this` does make sense in that context.
The alias is still to `S.x`. It still doesn't carry `this`.
For example, this might be surprising:
----
struct S {
int x = 1;
int foo(S other)
{
alias yoyo = other.x;
return yoyo;
}
}
void main()
{
import std.stdio;
auto s1 = S(1);
auto s2 = S(2);
writeln(s1.foo(s2)); /* prints "1" */
}
----
From the alias declaration, one might expect to get `other.x`, i.e. 2.
> Imagine that you would
> define a local variable x, if you wouldn't be able to use `this` then the
> local would mask the member everywhere.
You can still write `alias x = S.x;`.
Comment #8 by razvan.nitu1305 — 2018-11-06T08:19:16Z
(In reply to ag0aep6g from comment #7)
> (In reply to RazvanN from comment #6)
> > (In reply to johanengelen from comment #5)
> > > OK, then this is still broken and should receive a deprecation message too:
> > >
> > > ```
> > > struct S {
> > > int a;
> > > bool x;
> > > public ref foo() {
> > > alias yoyo = this.x;
> > > return yoyo;
> > > }
> > > }
> > > ```
> >
> > Actually, I don't think it should. Foo can only be called on an instance,
> > therefore `this` does make sense in that context.
>
> The alias is still to `S.x`. It still doesn't carry `this`.
>
> For example, this might be surprising:
>
> ----
> struct S {
> int x = 1;
> int foo(S other)
> {
> alias yoyo = other.x;
> return yoyo;
> }
> }
>
> void main()
> {
> import std.stdio;
> auto s1 = S(1);
> auto s2 = S(2);
> writeln(s1.foo(s2)); /* prints "1" */
> }
> ----
>
> From the alias declaration, one might expect to get `other.x`, i.e. 2.
>
>
> > Imagine that you would
> > define a local variable x, if you wouldn't be able to use `this` then the
> > local would mask the member everywhere.
>
> You can still write `alias x = S.x;`.
This is surprising, indeed, and I would say that this is a bug. Why would it do that?
Comment #9 by ag0aep6g — 2018-11-06T13:50:07Z
(In reply to RazvanN from comment #8)
> This is surprising, indeed, and I would say that this is a bug. Why would it
> do that?
Because `alias yoyo = other.x;` is the same as `alias yoyo = this.x;`. They both mean `alias yoyo = S.x;`. An alias can't refer to a field of a specific instance.
Comment #10 by bugzilla — 2019-12-18T09:31:11Z
(In reply to ag0aep6g from comment #9)
> Because `alias yoyo = other.x;` is the same as `alias yoyo = this.x;`. They
> both mean `alias yoyo = S.x;`. An alias can't refer to a field of a specific
> instance.
I believe that sums up this issue, and I'll mark it as invalid.