Comment #0 by destructionator — 2023-11-20T18:03:50Z
Must have two modules so `private` applies:
---
// bug.d
import bug2;
private void fooImpl() { }
void main() {
mvd!fooImpl();
}
---
And:
---
// bug2.d
void mvd(alias fn)() {
auto this_ = null;
// we could call `fn` directly here since we got an alias
ov: foreach(overload; __traits(getOverloads, __traits(parent, fn), __traits(identifier, fn))) {
__traits(child, this_, overload)(); // but cannot use through traits
}
}
---
You actually don't need the overload loop here, you could remove that to minimize further
```
void mvd(alias fn)() {
auto this_ = null;
fn(); // this allowed
//__traits(child, this_, fn)(); // this is not
}
```
But I wanted to show the loop to give you an idea of the real world use case this is affecting; it is a multiple virtual dispatch implementation.
Interestingly, in dmd 2.098:
```
fn; // bug2.d(3): Deprecation: Function `bug.fooImpl` of type `void()` is not accessible from module `bug2`
fn(); // perfectly OK; it let me call it through the alias, but not reference it
```
Which is a bit bizarre. I suspect the fix was intended to treat these two cases the same, but it awkward in any case.
Anyway, the error when calling the function was introduced by this commit:
https://github.com/dlang/dmd/commit/421ebfe8b5777707c7a415f64523bedf6ff2dd66
Before that, it worked without issue, after that, it deprecated, then a future commit (36043ded818506936790be55f9353d6132527541) turned the deprecation into an error.
The first release to fail with this was https://dlang.org/changelog/2.105.0.html
Comment #1 by default_357-line — 2023-11-23T08:08:47Z
Fwiw, that only ever worked "by coincidence" because the access check only checked for structs and classes, and typeof(null) is a nullptr_t, which is neither. I see what I did wrong in my PR, but I'm not sure that just putting the previous check back in is the way to go. It was always weird.
Problem is that sema has a way to disable access check on a scope (SCOPE.noaccesscheck), but afterwards the __traits(child) just becomes `this_.fooImpl`, which is then rechecked in sema3 and fails access. I'd need a way to mark the *access itself*, ie. the DotExp, as "no access check".
Comment #2 by robert.schadek — 2024-12-13T19:31:55Z