D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 19060 - [REG2.081] Incorrect "Using this as a type is deprecated" error
Summary: [REG2.081] Incorrect "Using this as a type is deprecated" error
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 regression
Assignee: No Owner
URL:
Keywords: industry
Depends on:
Blocks:
 
Reported: 2018-07-04 22:14 UTC by johanengelen
Modified: 2019-12-18 09:31 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description johanengelen 2018-07-04 22:14:00 UTC
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 Richard (Rikki) Andrew Cattermole 2018-07-04 22:17:48 UTC
This was changed on purpose.

https://dlang.org/changelog/2.081.0.html#deprecate_this_super_as_types
Comment 2 Richard (Rikki) Andrew Cattermole 2018-07-04 22:51:37 UTC
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 ag0aep6g 2018-07-04 23:47:48 UTC
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 RazvanN 2018-07-05 18:48:47 UTC
Indeed, this is not a regression, it is intended behavior.
Comment 5 johanengelen 2018-07-05 20:44:25 UTC
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 RazvanN 2018-11-05 14:32:37 UTC
(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 ag0aep6g 2018-11-05 16:56:31 UTC
(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 RazvanN 2018-11-06 08:19:16 UTC
(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 ag0aep6g 2018-11-06 13:50:07 UTC
(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 Walter Bright 2019-12-18 09:31:11 UTC
(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.