December 21, 2013
On Saturday, 21 December 2013 at 21:14:43 UTC, Martin Nowak wrote:
> If I make a refactoring and move a function from module A to B, but the function calls an overload set in A it should not have a different overload resolution.

If MUST have different overload resolution if B does not have access to those A function. Anything else is damn broken module system. Why would anyone expect to move functions between modules and have accessibility rules magically persistent?

> Similar case, if I pass an overload set via alias to a traits template in module B, the template should follow the same overload resolution.
> It's very important that we preserve these properties.

It is a major design issue with templates using declaration scope for access resolution instead of instantation scope. I think it was a mistake and is unrelated to general visibility rules.
December 21, 2013
On 12/21/2013 10:36 PM, Dicebot wrote:
>>
>
> It is a major design issue with templates using declaration scope for
> access resolution instead of instantation scope. I think it was a
> mistake and is unrelated to general visibility rules.

I think there is quite some overlap.
December 21, 2013
On 12/21/2013 10:28 PM, Timon Gehr wrote:
> Well, you pass an alias. Are you saying that for alias template
> arguments, the scope of the template declaration applies for
> accessibility checking? I.e. we cannot pass private symbols as alias
> arguments? I think this is an unreasonably high price to pay.
>
You can pass them and basically it behaves like public aliases, in the sense that the one who instantiates a template passes a public alias to a possibly private symbol.

It's a question of transitivity what the template can do with the symbol.

Currently it's not possible to call private functions or private methods of variables that are passed via alias parameter.

> Basically just the constructor thing though?
> Note that constructors cannot be passed by alias due to a syntax
> restriction... :o)

December 21, 2013
On 12/21/2013 10:22 PM, H. S. Teoh wrote:
> I was pretty upset when I encountered the following situation:
>
> 	---std/regex.d---
> 	...
> 	private struct Stack { ... }
> 	...
>
> 	---mymodule.d---
> 	...
> 	/* public */ struct Stack { ... }
> 	...
>
> 	---main.d---
> 	import std.regex;
> 	import mymodule;
>
> 	Stack s; // compile error: 'Stack' is ambiguous
>
> I find it unacceptable that introducing a *private* symbol to std.regex
> will break existing code (std.regex.Stack wasn't there in earlier
> versions of Phobos). Since std.regex.Stack is private, why would it even
> be in *any* overload set when compiling main.d??! This is leaky
> abstraction at its best: changing the implementation of a module without
> changing its API can randomly break user code due to newly-introduced
> private symbols clashing with user-defined symbols.
>
Yes, this is the big issue that we try to address with DIP22.
Happened to me too when I added a private `abs` helper to core.time
which then caused conflicts somewhere else in phobos.

December 21, 2013
On 12/21/2013 10:36 PM, Dicebot wrote:
> If MUST have different overload resolution if B does not have access to
> those A function. Anything else is damn broken module system. Why would
> anyone expect to move functions between modules and have accessibility
> rules magically persistent?
>
It's important for example to define a forwarding template in a different module.

void call(alias funcs, Args...)(auto ref Args args)
{
    funcs(args); // overload resolution happens here
}

> It is a major design issue with templates using declaration scope for
> access resolution instead of instantation scope. I think it was a
> mistake and is unrelated to general visibility rules.

What? It's a major design win that we don't have to rerun semantic for every identical instantiation, in the same sense that we don't have to reinclude header files.
Or are you only talking about access checks?
I don't think that handling access resolution separately from look-up resolution is desirable.
December 21, 2013
On 12/21/2013 11:03 PM, Martin Nowak wrote:
> On 12/21/2013 10:28 PM, Timon Gehr wrote:
>> Well, you pass an alias. Are you saying that for alias template
>> arguments, the scope of the template declaration applies for
>> accessibility checking? I.e. we cannot pass private symbols as alias
>> arguments? I think this is an unreasonably high price to pay.
>>
> You can pass them and basically it behaves like public aliases, in the
> sense that the one who instantiates a template passes a public alias to
> a possibly private symbol.
> ...

I see. Then how are you going to handle the following:

module a;

private auto foo(int x){ }
auto foo(double x){ }

auto call(alias a){ a(0); }

void x(){
    call!foo(); // ok
}

module b;
import a;

void y(){
    call!foo(); // _same_ symbol as in module 'a'.
}


> It's a question of transitivity what the template can do with the symbol.
>
> Currently it's not possible to call private functions or private methods
> of variables that are passed via alias parameter.
> ...

That's probably fine. (It is certainly nothing to touch while fixing the private symbol clash issue.)

December 21, 2013
On Saturday, 21 December 2013 at 22:14:51 UTC, Martin Nowak wrote:
> What? It's a major design win that we don't have to rerun semantic for every identical instantiation, in the same sense that we don't have to reinclude header files.

I know that and completely agree with that.

> Or are you only talking about access checks?

Yes.

> I don't think that handling access resolution separately from look-up resolution is desirable.

That was my attitude initially when I have learned about this decision but it is root to certain class of problems in generic code and I have slowly moved to position that RAI for this exception is high enough.
December 21, 2013
On 12/21/2013 11:17 PM, Timon Gehr wrote:
> On 12/21/2013 11:03 PM, Martin Nowak wrote:
>> On 12/21/2013 10:28 PM, Timon Gehr wrote:
>>> Well, you pass an alias. Are you saying that for alias template
>>> arguments, the scope of the template declaration applies for
>>> accessibility checking? I.e. we cannot pass private symbols as alias
>>> arguments? I think this is an unreasonably high price to pay.
>>>
>> You can pass them and basically it behaves like public aliases, in the
>> sense that the one who instantiates a template passes a public alias to
>> a possibly private symbol.
>> ...
>
> I see. Then how are you going to handle the following:
>
> module a;
>
> private auto foo(int x){ }
> auto foo(double x){ }
>
> auto call(alias a){ a(0); }
>
> void x(){
>      call!foo(); // ok
> }
This will work.

> module b;
> import a;
>
> void y(){
>      call!foo(); // _same_ symbol as in module 'a'.
> }
This would say, Error: overload auto a.foo(int) is not accessible from module b.
December 21, 2013
On 12/21/2013 11:56 PM, Martin Nowak wrote:
> On 12/21/2013 11:17 PM, Timon Gehr wrote:
>> ...
>>
>> I see. Then how are you going to handle the following:
>>
>> module a;
>>
>> private auto foo(int x){ }
>> auto foo(double x){ }
>>
>> auto call(alias a){ a(0); }
>>
>> void x(){
>>      call!foo(); // ok
>> }
> This will work.
>
>> module b;
>> import a;
>>
>> void y(){
>>      call!foo(); // _same_ symbol as in module 'a'.
>> }
> This would say, Error: overload auto a.foo(int) is not accessible from
> module b.

How is this going to work? Are you arguing for creating multiple instances of 'call'?
December 22, 2013
On 12/22/2013 12:05 AM, Timon Gehr wrote:
>>
>
> How is this going to work?

Ah sorry, I misread your example.
The call template function is in module a, so it has access too.

> Are you arguing for creating multiple instances of 'call'?

So this is indeed not necessary, the function is called within the template, so only the template scope determines whether a function is accessible.