Jump to page: 1 2
Thread overview
[Issue 11946] "need 'this' to access member" when passing field to template parameter
Jun 28, 2014
Jacob Carlborg
Jul 07, 2014
Walter Bright
Jul 07, 2014
Walter Bright
Jul 07, 2014
Jacob Carlborg
Jul 09, 2014
Kenji Hara
Jul 15, 2014
timon.gehr@gmx.ch
Jul 15, 2014
Kenji Hara
Jul 27, 2014
Dicebot
Jul 31, 2014
Kenji Hara
Aug 18, 2014
Vlad Levenfeld
[Issue 11946] need 'this' to access member when passing field to template parameter
Aug 22, 2014
Walter Bright
Aug 22, 2014
Walter Bright
Aug 22, 2014
Vladimir Panteleev
Aug 25, 2014
Walter Bright
Aug 25, 2014
Jacob Carlborg
Aug 25, 2014
Vladimir Panteleev
Aug 29, 2014
yebblies
June 28, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

Jacob Carlborg <doob@me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |doob@me.com

--- Comment #39 from Jacob Carlborg <doob@me.com> ---
I'm not sure if this is related but I have a similar case as Vladimir's first post:



module foo;

static int f(A...)() { pragma(msg, typeof(A)); return 0; }



module bar;

import foo;

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



Here "x" is private and I'm accessing the tuple in "f". The error I get is " Error: struct bar.S member x is not accessible". This worked fine in DMD 2.064.2.

--
July 07, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #40 from Walter Bright <bugzilla@digitalmars.com> ---
(In reply to Jacob Carlborg from comment #39)
> Here "x" is private and I'm accessing the tuple in "f". The error I get is " Error: struct bar.S member x is not accessible". This worked fine in DMD 2.064.2.

Yes, it's not accessible because it is marked private, and "f" does not have access to private members.

It also has nothing to do with Issue 11946, and should be filed separately if you feel it needs to be addressed further.

--
July 07, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #41 from Walter Bright <bugzilla@digitalmars.com> ---
(In reply to Kenji Hara from comment #27)
> As a technical talk, in current semantic analysis system, the "context-ness" of a function - whether a function really needs a context or not - should be determined without its body analysis. As far as I see, current dmd code relies on the assumption.

But D already has the notion of doing a "local instantiation" of a global template, if an alias parameter is a local symbol - see hasNestedArgs().

--
July 07, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #42 from Jacob Carlborg <doob@me.com> ---
(In reply to Walter Bright from comment #40)

> It also has nothing to do with Issue 11946, and should be filed separately if you feel it needs to be addressed further.

The reason I'm asking is because if I remove "private" I get the same error as reported in this issue. And the workaround in Kenji's first post [1] fixes the problem.

[1] https://issues.dlang.org/show_bug.cgi?id=11946#c1

--
July 09, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #43 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to Walter Bright from comment #41)
> But D already has the notion of doing a "local instantiation" of a global template, if an alias parameter is a local symbol - see hasNestedArgs().

Right, but if an instantiation is determined to "local instantiation", compiler cannot "unlocalize" it automatically.

---
To me current behavior is solid designed and more useful than old one.

In D, "static" keyword is used to unlocalize local symbols.

1. In class/struct member scope, variable declarations and function declarations are implicitly localized in the instance object. By emitting static, they will be unlocalized.

2. In function statement scope, variable declarations and function declarations are implicitly localized in the function execution context. By emitting static, they will be unlocalized.

3. In module scope, every declared symbols have no implicit context, so static keyword has no meaning for them.

But, with templates, the localization is checked twice - on template declaration itself and the instantiated code.

1-a. In class/struct member scope, function template is localized by default. So

  class C { int a; void foo()() { a = 1; } }
  void main() { new C().foo!()(); }

the instantiated function C.foo!()() will  work as member function.

1-b. If function template has static attribute, the template declaration it is explicitly unlocalized. So

  class C { int a; static void bar()() {} }
  void main() { C.bar!()(); }

the instantiated function C.bar!()() will work as static member function.

1-c. If function template has static attribute and alias parameter, the template declaration it is explicitly unlocalized, *but* the instantiated function can be localized depending on the argument of alias parameter. So

  class C { int a; static void baz(alias x)() { x = 10; } }
  void main() { int b; C.baz!(b)(); }

the instantiated function C.baz!(b)() can be localized in other local scope.

1-d. and then:

  class C { int a; static template goo(alias x) {
     >>static<< void goo() { static assert(!__traits(compiles, x = 10)); }
  }
  void main() { int b; C.baz!(b)(); }

the static attribute on the instantiated function will unlocalize it even if the template is instantiated with local symbol.

Completely same rule is applied for No.2 and No.3 cases.

In earier version, the semantics 'c' was not possible, because the syntax
`static void baz(alias x)() { ... }` had worked as like 'd'.

The new 'c' behavior is useful in particular case. For example:

  auto map(alias pred, R)(R r)
  {
    static struct Result(alias pred)
    {
      R r;
      auto front() { return pred(r.front); }
    }
    return Result!pred(r);
  }

If pred does not have a context, the Result!pred is unlocalized by default. Otherwise, Result!pred will be automatically localized.

--
July 15, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch

--- Comment #44 from timon.gehr@gmx.ch ---
(In reply to Kenji Hara from comment #21)
> (In reply to comment #20)
> > (In reply to comment #19)
> > > Maybe you're misunderstanding the effect of 'static' attribute. As far as I know, it means that:
> > 
> > I think I understand how it works now. But I don't think this is how it SHOULD work, because it is not intuitive. No other programming language does this, and no one expects it to act like this. So I think it is a limitation imposed by implementation detail that needs to be fixed.
> 
> I think it is enough reasonable definition because:
> 1. Currently dmd works that way.

That's basically diametrally opposed to how such things should be argued.

> 2. It is consistent definition and allow such the code in comment#1. ...

No, it is not a "consistent" definition, see below. Also, the code in comment#1 is ugly.

> Anyway, can you agree that the OP code needs fixup with 2.065 and this issue should me marked as INVALID?

I don't think this issue is invalid.

(In reply to Kenji Hara from comment #43)
> (In reply to Walter Bright from comment #41)
> > But D already has the notion of doing a "local instantiation" of a global template, if an alias parameter is a local symbol - see hasNestedArgs().
> 
> Right, but if an instantiation is determined to "local instantiation", compiler cannot "unlocalize" it automatically.
> 
> ---
> To me current behavior is solid designed and more useful than old one. ...

I'm sorry, but the current behaviour is an ugly patchwork.
Even if there is value in explicit 'unlocalization' (which I am not convinced
of), introducing/moving around subtle and completely ad-hoc distinctions
barring any sound motivation like that is not going to fly. For one thing, what
if I want to make some members of my template scope static and not others?

class C{
    int x;
    template T(alias a){
        int foo(){ return x; }
        static int bar(int y){ return a(y); }
    }
}

Just because I don't want bar to be a member function of class C, with the new behaviour I now _also_ disable local instantiation. What is this?

I also think that 'mangleof' shouldn't influence the design of this feature in the slightest, forward references need an orthogonal and well-founded design anyway.

--
July 15, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #45 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to timon.gehr from comment #44)
> For one thing, what if I want to make some members of my template scope static and not others?
> 
> class C{
>     int x;
>     template T(alias a){
>         int foo(){ return x; }
>         static int bar(int y){ return a(y); }
>     }
> }
> 
> Just because I don't want bar to be a member function of class C, with the new behaviour I now _also_ disable local instantiation. What is this?

foo will become member function, and bar will become static member function.

void main()
{
    C c = new C();
    c.x = 5;
    static int g(int n) { return n*10; }
    assert(c.T!g.foo() == 5);   // foo is member function
    assert(C.T!g.bar(2) == 20); // bar is static member function
}

--
July 27, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #46 from Dicebot <public@dicebot.lv> ---
I recommend to revert https://github.com/D-Programming-Language/dmd/pull/2794 as it blocks the release and re-introduce it back again once solution is found - with matching language spec change PR.

--
July 31, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #47 from Kenji Hara <k.hara.pg@gmail.com> ---
*** Issue 13062 has been marked as a duplicate of this issue. ***

--
August 18, 2014
https://issues.dlang.org/show_bug.cgi?id=11946

Vlad Levenfeld <vlevenfeld@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |vlevenfeld@gmail.com

--
« First   ‹ Prev
1 2