[Issue 11946] "need 'this' to access member" when passing field to template parameter

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Jan 23 01:29:58 PST 2014


https://d.puremagic.com/issues/show_bug.cgi?id=11946



--- Comment #10 from Kenji Hara <k.hara.pg at gmail.com> 2014-01-23 01:29:55 PST ---
(In reply to comment #9)
> (In reply to comment #8)
> > 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!

Yes, I'm talking about normal templates. Even if the template is defined in
module level, if it has alias parameter, instantiated function may have
implicit context.

Indeed it is part of the implementation detail, but today it is mostly
unavoidable issue. If you interest, you can read issue 5710 discussion.

> > 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?

  // This is module level template function that have alias parameter.
  int foo(alias sym)() { return sym; }

  class C
  {
    int n;
    void test()
    {
      this.n = 10;
      alias fooN = foo!(C.n);
      // fooN has implicit context to access field variable n in class C.
      static assert(is(typeof(&fooN) == delegate));
      assert(fooN() == 10);
    }
  }

  void main()
  {
    int n = 10;
    alias fooN = foo!n;
    // fooN has implicit context to access local variable n in main.
    static assert(is(typeof(&fooN) == delegate));
    assert(fooN() == 10);

    new C().test();
  }

foo(alias sym) is module level template, but in both case instantiated
functions will have implicit context pointer to access runtime data of 'sym'.

> > 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!

Again, current compiler does not consider that the context is not really used
inside function.

> > f() will be instantiated like as member function or nested
> > function. 
> 
> WHY?!?
> 
> It is a free function!

No. It's a template function that is defined in module level.

> > 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?

In many cases, learning it would not be necessary. But in your case the
difference is necessary.
Honestly, the alias parameter usage in your code does not fit the expected
usage in language design.
At least from D1 age, template alias parameter is designed to use the given
symbol in runtime at instantiated code.

> > 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.

I agree that it is hard to understand behavior. That's why I had tried to fix
the issue at first.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list