Jump to page: 1 24  
Page
Thread overview
[Issue 11946] New: "need 'this' to access member" when passing field to template parameter
Jan 18, 2014
Vladimir Panteleev
Jan 19, 2014
Kenji Hara
Jan 19, 2014
Vladimir Panteleev
Jan 20, 2014
Kenji Hara
Jan 20, 2014
Vladimir Panteleev
Jan 21, 2014
Walter Bright
Jan 23, 2014
Kenji Hara
Jan 23, 2014
Vladimir Panteleev
Jan 23, 2014
Kenji Hara
Jan 23, 2014
Vladimir Panteleev
Jan 23, 2014
Kenji Hara
Jan 23, 2014
Kenji Hara
Jan 23, 2014
Vladimir Panteleev
Jan 24, 2014
Vladimir Panteleev
Jan 24, 2014
Kenji Hara
Jan 24, 2014
Kenji Hara
Jan 24, 2014
Vladimir Panteleev
Jan 24, 2014
Kenji Hara
Jan 24, 2014
Vladimir Panteleev
Jan 24, 2014
Kenji Hara
Jan 24, 2014
Vladimir Panteleev
Jan 24, 2014
Kenji Hara
Jan 24, 2014
Vladimir Panteleev
Jan 26, 2014
Walter Bright
Jan 26, 2014
Walter Bright
Jan 26, 2014
Walter Bright
Jan 30, 2014
Kenji Hara
Jan 30, 2014
Kenji Hara
Jan 30, 2014
Kenji Hara
Mar 03, 2014
Dicebot
Mar 03, 2014
Vladimir Panteleev
Mar 03, 2014
Dicebot
Mar 03, 2014
Vladimir Panteleev
Mar 03, 2014
Kenji Hara
Mar 03, 2014
Vladimir Panteleev
Mar 03, 2014
Kenji Hara
Mar 03, 2014
Vladimir Panteleev
Mar 04, 2014
Kenji Hara
Mar 04, 2014
Vladimir Panteleev
January 18, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946

           Summary: "need 'this' to access member" when passing field to
                    template parameter
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid
          Severity: regression
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: thecybershadow@gmail.com


--- Comment #0 from Vladimir Panteleev <thecybershadow@gmail.com> 2014-01-19 01:25:45 EET ---
////////////////////////////////////////
static // http://d.puremagic.com/issues/show_bug.cgi?id=7805
int f(A...)() { return 0; }

struct S { int x; enum y = f!x(); }
////////////////////////////////////////

This used to compile, but it was broken by https://github.com/D-Programming-Language/dmd/pull/2794

Also, issue 7805 was not fixed. It was marked as a duplicate of issue 11533, which the above pull request claims to fix. Whereas before, the "static" was required to avoid a compiler error, now it makes no difference as a compiler error occurs with and without "static".

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 19, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2014-01-18 23:45:48 PST ---
It's intended behavior introduced by issue 11533. Now, alias parameter is preferred than 'static' attribute _on template_.

If you really need the syntax f!x(), you should define function template 'f'
like follows:

template f(alias X)
{
    static string f()
    {
        //int x = X;
        return X.stringof; // OK
    }
}
struct S
{
    int i;
    enum y = f!i();
    pragma(msg, y);
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 19, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #2 from Vladimir Panteleev <thecybershadow@gmail.com> 2014-01-19 17:20:28 EET ---
It still seems like pointless breaking of code. If it really is intentional, then the diagnostic needs to be improved to tell the user how exactly to change their code.

Also, there is still no sensible reason why "static" is required on a free function, regardless of whether it's in a template or not.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 20, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull


--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> 2014-01-20 03:41:05 PST ---
(In reply to comment #2)
> It still seems like pointless breaking of code. If it really is intentional, then the diagnostic needs to be improved to tell the user how exactly to change their code.
> 
> Also, there is still no sensible reason why "static" is required on a free function, regardless of whether it's in a template or not.

OK, I reopen issue 7805 as an enhancement request. And fixing it will also fix this regression.

https://github.com/D-Programming-Language/dmd/pull/3126

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 20, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #4 from Vladimir Panteleev <thecybershadow@gmail.com> 2014-01-20 15:50:53 EET ---
> OK, I reopen issue 7805 as an enhancement request.

Unless the enhancement is making the error message better, it is still a regression and not an enhancement, is it not?

From my observations of related errors, I think there seems to be some conflation between aliases to declarations (without context pointers) and aliases to actual variables (which do have context pointers). For example, S.field and s.field. These bug reports and those where the compiler complains that "this for X should be type Y not type Z" indicates that in a lot of cases, the compiler attempts to pass the context pointer to blocks where it makes no sense to. IMO, all "this for X should be type Y not type Z" errors are confusing and useless, and need to be eliminated.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 21, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946


Walter Bright <bugzilla@digitalmars.com> changed:

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


--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> 2014-01-21 00:25:04 PST ---
(In reply to comment #0)
> ////////////////////////////////////////
> static // http://d.puremagic.com/issues/show_bug.cgi?id=7805
> int f(A...)() { return 0; }
> 
> struct S { int x; enum y = f!x(); }
> ////////////////////////////////////////
> 
> This used to compile, but it was broken by https://github.com/D-Programming-Language/dmd/pull/2794
> 
> Also, issue 7805 was not fixed. It was marked as a duplicate of issue 11533, which the above pull request claims to fix. Whereas before, the "static" was required to avoid a compiler error, now it makes no difference as a compiler error occurs with and without "static".

This should never have compiled. static should never have affected a template in global scope.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #6 from Kenji Hara <k.hara.pg@gmail.com> 2014-01-22 21:52:01 PST ---
I change my argue to that this regression should be marked as invalid.

(In reply to comment #5)
> (In reply to comment #0)
> > ////////////////////////////////////////
> > static // http://d.puremagic.com/issues/show_bug.cgi?id=7805
> > int f(A...)() { return 0; }
> > 
> > struct S { int x; enum y = f!x(); }
> > ////////////////////////////////////////
> > 
> This should never have compiled. static should never have affected a template in global scope.

I also think so. But it had been worked because 'static' attribute is always inherited to the instantiated function. I *fixed* the bug in the PR:

> > This used to compile, but it was broken by https://github.com/D-Programming-Language/dmd/pull/2794

===

The main point of enhancment 11533 is that 'static template' should always behave as same as module-level templates, regardless its declared position.

It's increasing consistency with currently known language concepts:
- 'static' attribute on module level declaration is just redundant
(meaningless).
- 'static' declaration inside aggregates/functions should behave as same as
module level declarations.
    * static member function is equivalent with free functions.
    * static local function is equivalent with free functions.

By the fix, `static int f(A...)(){ ... }` and `int f(A...)(){ ... }` have now
no difference at module level.
Therefore, instantiated f!(S.x) always requires hidden 'this' pointer on the
call.

To be more precise, current D language alias template parameter is not designed
just to take a symbol that is needed just only at compile-time.
If given template argument has implicit runtime context, compiler will _always_
try to take runtime context at the same time.
(To resolve the issue, "nested-ness interence" is sometimes proposed. But I'm
still not sure it is possible feature.)

To ignore the implicit automatic capturing, you need to write the idiom I explained in comment#1.

As a conclusion: the reported breaking change is necessary due to add more consistency to the language spec.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #7 from Vladimir Panteleev <thecybershadow@gmail.com> 2014-01-23 08:51:03 EET ---
> It's increasing consistency with currently known language concepts:

Yes, this is all fine and well, but it does not justify making code that worked before now break with an indecipherable error message! The message "need 'this' to access member f" is an outright lie and is only good at showing a glaring compiler implementation problem.

(In reply to comment #1)
> template f(alias X)
> {
>     static string f()
>     {
>         //int x = X;
>         return X.stringof; // OK
>     }
> }

This just shows another bug - that you still need "static" (which makes NO sense for a free function, templated or not), but now you must hide it inside a template!

> To be more precise, current D language alias template parameter is not designed
> just to take a symbol that is needed just only at compile-time.
> If given template argument has implicit runtime context, compiler will _always_
> try to take runtime context at the same time.

So fix this first before breaking code?

> To ignore the implicit automatic capturing, you need to write the idiom I explained in comment#1.

If one needs to go to a bugtracker and learn of a hacky workaround (put a static function in a template) from a compiler developer to make their code compile, this is a terrible situation for D.

> As a conclusion: the reported breaking change is necessary due to add more consistency to the language spec.

I suggest that consistency bugs are fixed only after there is an immediate and obvious way to transition code that should not have compiled, to correct code which functions in the same way. In either case, this bug remains a REGRESSION.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #8 from Kenji Hara <k.hara.pg@gmail.com> 2014-01-22 23:41:23 PST ---
(In reply to comment #7)
> > It's increasing consistency with currently known language concepts:
> 
> Yes, this is all fine and well, but it does not justify making code that worked before now break with an indecipherable error message! The message "need 'this' to access member f" is an outright lie and is only good at showing a glaring compiler implementation problem.

There's no lie. The instantiated function _always_ needs valid runtime context, *regardless* the context is really used or not inside function body.

Unfortunately current D has _no_ language feature to remove unused context pointer (I call it "nested-ness inference").

> (In reply to comment #1)
> > template f(alias X)
> > {
> >     static string f()
> >     {
> >         //int x = X;
> >         return X.stringof; // OK
> >     }
> > }
> 
> This just shows another bug - that you still need "static" (which makes NO sense for a free function, templated or not), but now you must hide it inside a template!

It's not a bug. If the symbol X needs runtime context ('this' object or function frame), f() will be instantiated like as member function or nested function. To remove the implicit context pointer, 'static' will work.

---
After fixing issue 11533, these two declarations have different meanings.

template f(alias X) { static string f() { return null; } }  // A
static template f(alias X) { string f() { return null; } }  // B

In A, 'static' attribute is always added to the instantiated function 'f'. So
Even if X requires runtime context, 'f' still cannot access it.
In B, 'static' attribute is added _if_ X has no runtime context. If X needs
runtime context, instantiated 'f' also take the context to access valid runtime
storage of X.
---

> > To be more precise, current D language alias template parameter is not designed
> > just to take a symbol that is needed just only at compile-time.
> > If given template argument has implicit runtime context, compiler will _always_
> > try to take runtime context at the same time.
> 
> So fix this first before breaking code?

It would be a not trivial language enhancement that still not yet designed.

> > To ignore the implicit automatic capturing, you need to write the idiom I explained in comment#1.
> 
> If one needs to go to a bugtracker and learn of a hacky workaround (put a static function in a template) from a compiler developer to make their code compile, this is a terrible situation for D.

To explain the behavior, I'll update webside documentation and add a section in release note.

> > As a conclusion: the reported breaking change is necessary due to add more consistency to the language spec.
> 
> I suggest that consistency bugs are fixed only after there is an immediate and obvious way to transition code that should not have compiled, to correct code which functions in the same way.

I already explained the way to do it in comment#1.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 23, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #9 from Vladimir Panteleev <thecybershadow@gmail.com> 2014-01-23 09:53:40 EET ---
(In reply to comment #8)
> (In reply to comment #7)
> > > It's increasing consistency with currently known language concepts:
> > 
> > Yes, this is all fine and well, but it does not justify making code that worked before now break with an indecipherable error message! The message "need 'this' to access member f" is an outright lie and is only good at showing a glaring compiler implementation problem.
> 
> There's no lie. The instantiated function _always_ needs valid runtime context, *regardless* the context is really used or not inside function body.

What?!?!?

This makes absolutely no sense!

There is nothing in the D spec about this! Templated functions must behave in the same way as free functions (whether the function itself is templated or it is inside an explicit template declaration), and "static" is meaningless on free functions!

We are not talking about template mixins! The instantiation of non-mixin templates uses the template declaration's context!

> Unfortunately current D has _no_ language feature to remove unused context pointer (I call it "nested-ness inference").

As far as I can see, this is just a compiler implementation detail!

Can you provide an example where this "feature" (passing context pointer from template instantiation site to a free function) is actually used?

> It's not a bug. If the symbol X needs runtime context ('this' object or
> function frame),

It doesn't! .stringof does not need a gosh-darn context pointer!

> f() will be instantiated like as member function or nested
> function.

WHY?!?

It is a free function!

> To remove the implicit context pointer, 'static' will work.

...

> After fixing issue 11533, these two declarations have different meanings.
> 
> template f(alias X) { static string f() { return null; } }  // A
> static template f(alias X) { string f() { return null; } }  // B
> 
> In A, 'static' attribute is always added to the instantiated function 'f'. So
> Even if X requires runtime context, 'f' still cannot access it.
> In B, 'static' attribute is added _if_ X has no runtime context. If X needs
> runtime context, instantiated 'f' also take the context to access valid runtime
> storage of X.

This looks like absurd overcomplication. Do you really expect D users to have to understand the difference?

> It would be a not trivial language enhancement that still not yet designed.

Then I suggest that you postpone all breaking changes until all that is figured out. Breaking code to clean up compiler internals is inexcusable, IMO!

> To explain the behavior, I'll update webside documentation and add a section in release note.

The more I think about it the less sense it makes to me. Maybe it makes sense from the point of view of a compiler developer (to use Chen Raymond's phraseology, you're looking at the world through "compiler-tinted glasses"). But as a D user, your explanation reads like one giant WTF to me. It is completely unintuitive and to me it seems that things are broken at a much more fundamental level if you defend the current logic in this way.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2 3 4