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

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Tue Jul 8 22:43:33 PDT 2014


https://issues.dlang.org/show_bug.cgi?id=11946

--- Comment #43 from Kenji Hara <k.hara.pg at 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.

--


More information about the Digitalmars-d-bugs mailing list