www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can't pass private symbols as alias parameter

reply "deadalnix" <deadalnix gmail.com> writes:
module a;

struct A(alias foo) {
     auto foo() {
         return foo();
     }
}

module b;

import a;

void main() {
     auto a = A!bar();
}

private int bar() { return 42; }

This do not work. I think it is a bug but I see how could see it 
as a feature. Which one is it ?
Nov 16 2014
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
ping pong ping ping ?
Nov 16 2014
prev sibling next sibling parent "Freddy" <Hexagonalstar64 gmail.com> writes:
On Sunday, 16 November 2014 at 10:41:20 UTC, deadalnix wrote:
 module a;

 struct A(alias foo) {
     auto foo() {
         return foo();
     }
 }

 module b;

 import a;

 void main() {
     auto a = A!bar();
 }

 private int bar() { return 42; }

 This do not work. I think it is a bug but I see how could see 
 it as a feature. Which one is it ?
Why would that be a feature?
Nov 16 2014
prev sibling next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Sunday, 16 November 2014 at 10:41:20 UTC, deadalnix wrote:
 module a;

 struct A(alias foo) {
     auto foo() {
         return foo();
     }
 }

 module b;

 import a;

 void main() {
     auto a = A!bar();
 }

 private int bar() { return 42; }

 This do not work. I think it is a bug but I see how could see 
 it as a feature. Which one is it ?
It seems like a feature to me. Otherwise, you would have A.foo, which is in module a, calling a private function from module b. I think it is sane that the function should be public if you want to do things such as this. Furthermore, it will stop you from accidentally passing private symbols to alias template arguments when you don't mean to.
Nov 16 2014
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 17 November 2014 at 03:22:49 UTC, Meta wrote:
 It seems like a feature to me. Otherwise, you would have A.foo, 
 which is in module a, calling a private function from module b. 
 I think it is sane that the function should be public if you 
 want to do things such as this. Furthermore, it will stop you 
 from accidentally passing private symbols to alias template 
 arguments when you don't mean to.
Obviously this is gonna call the private function, that is the whole point. What would be the benefit of preventing me to do that ? Stating that it would prevent me to do it do not explain why I wouldn't want that.
Nov 16 2014
parent "Meta" <jared771 gmail.com> writes:
Actually, the more I think about it, the more I'm sure that it is 
a bug. If you import A into module b, you should be able to use 
it with the symbols in b. This actually seems like quite a bad 
bug.
Nov 16 2014
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/16/14 5:41 AM, deadalnix wrote:
 module a;

 struct A(alias foo) {
      auto foo() {
          return foo();
      }
 }
I note here, the above doesn't is incorrect regardless, I assume you didn't actually try to compile this post example :) To fix, I did this: struct A(alias foo) { auto bar() { return foo(); } }
 module b;

 import a;

 void main() {
      auto a = A!bar();
 }

 private int bar() { return 42; }

 This do not work. I think it is a bug but I see how could see it as a
 feature. Which one is it ?
I think it is intentional, even if it's not desirable. Note that A is treated as if it is in a's namespace, so it cannot access functions that a does not define or that it cannot access publicly through its imports. The alias cannot override the protection attributes, and I'm pretty sure that is intentional. I tried some workarounds: void main() { public alias b = bar; auto a = A!b(); } It would be nice if that worked, because it does not expose bar except in this one case, and it identifies that you know bar has become public for this one case. But unfortunately, it has the same issue. This works: void main() { static auto b() { return bar();} auto a = A!b(); } But of course, it's not ideal, as you are relying on the inliner to make this performant. Shortened version (I think this implies static): auto a = A!(()=>bar())(); Yuck. I really think what you wish should be allowed, even if using some syntax to declare you know what you are doing. I tried some other goofy stuff, but I could not get around the requirement that the alias not change the protection of the symbol. -Steve
Nov 17 2014
parent "deadalnix" <deadalnix gmail.com> writes:
On Monday, 17 November 2014 at 14:13:21 UTC, Steven Schveighoffer
wrote:
 I note here, the above doesn't is incorrect regardless, I 
 assume you didn't actually try to compile this post example :)

 To fix, I did this:

 struct A(alias foo) {
   auto bar() {
      return foo();
   }
 }
Sorry for that, I made a mistake while typing the sample code.
 The alias cannot override the protection attributes, and I'm 
 pretty sure that is intentional.

 I tried some workarounds:

 void main() {
   public alias b = bar;
   auto a = A!b();
 }

 It would be nice if that worked, because it does not expose bar 
 except in this one case, and it identifies that you know bar 
 has become public for this one case. But unfortunately, it has 
 the same issue.
:'(
 This works:

 void main() {
   static auto b() { return bar();}
   auto a = A!b();
 }

 But of course, it's not ideal, as you are relying on the 
 inliner to make this performant. Shortened version (I think 
 this implies static):

 auto a = A!(()=>bar())();

 Yuck. I really think what you wish should be allowed, even if 
 using some syntax to declare you know what you are doing.

 I tried some other goofy stuff, but I could not get around the 
 requirement that the alias not change the protection of the 
 symbol.

 -Steve
This is not an option to me. In my specific use case, the code instantiating the template is itself a template, and they call each other. That mean I get infinite template instantiation.
Nov 17 2014
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
16-Nov-2014 13:41, deadalnix пишет:
 module a;

 struct A(alias foo) {
      auto foo() {
          return foo();
      }
 }

 module b;

 import a;

 void main() {
      auto a = A!bar();
 }

 private int bar() { return 42; }

 This do not work. I think it is a bug but I see how could see it as a
 feature. Which one is it ?
I think that it's a bug or a very annoying feature. I've seen it a few times before but never filed (I too wasn't sure if it's by design). -- Dmitry Olshansky
Nov 17 2014
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Monday, 17 November 2014 at 20:45:28 UTC, Dmitry Olshansky
wrote:
 I think that it's a bug or a very annoying feature.
 I've seen it a few times before but never filed (I too wasn't 
 sure if it's by design).
Yes me too. I'm filling.
Nov 17 2014
parent "deadalnix" <deadalnix gmail.com> writes:
On Monday, 17 November 2014 at 22:17:01 UTC, deadalnix wrote:
 On Monday, 17 November 2014 at 20:45:28 UTC, Dmitry Olshansky
 wrote:
 I think that it's a bug or a very annoying feature.
 I've seen it a few times before but never filed (I too wasn't 
 sure if it's by design).
Yes me too. I'm filling.
https://issues.dlang.org/show_bug.cgi?id=13744
Nov 17 2014