Bug 23941 – [DIP1000] Overloading by scope should be allowed
Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-05-28T08:41:09Z
Last change time
2023-06-26T06:10:54Z
Keywords
safe
Assigned to
No Owner
Creator
Vladimir Panteleev
Comments
Comment #0 by dlang-bugzilla — 2023-05-28T08:41:09Z
I think this should work (with -preview=dip1000):
///////////////////////// test2.d ////////////////////////
@safe:
import std.stdio;
char[] global;
void a(char[] arr) { writeln("non-scope"); global = arr; }
void a(scope char[] arr) { writeln("scope"); }
void b(scope char[] arr)
{
a(arr);
}
void c()
{
char[16] arr;
b(arr[]);
}
//////////////////////////////////////////////////////////
Currently, it complains:
test2.d(12): Error: `test2.a` called with argument types `(char[])` matches both:
test2.d(7): `test2.a(char[] arr)`
and:
test2.d(8): `test2.a(scope char[] arr)`
However, when removing one of the overloads, the program only compiles with the non-scope one, so the compiler should be able to reduce the overload set to a single viable overload.
Comment #1 by bugzilla — 2023-06-23T08:38:47Z
Looks like the problem is in the argumentMatchParameter function, which doesn't check for scope parameters.
But I'm a bit concerned that changing this may mess up scope inference, which occurs after an overload is selected. Changing this may destabilize the language.
I'm also skeptical of the utility of overloading based on `scope`. Maybe this pattern just doesn't make sense.
Comment #3 by dlang-bugzilla — 2023-06-23T09:20:54Z
But that's a problem with the compiler, not the language, right? There's nothing fundamental stopping someone from writing a D compiler that correctly allows this?
Comment #4 by bugzilla — 2023-06-24T00:26:06Z
(In reply to Vladimir Panteleev from comment #3)
> But that's a problem with the compiler, not the language, right? There's
> nothing fundamental stopping someone from writing a D compiler that
> correctly allows this?
It is a language problem. The dip1000 rules were designed as a layer that adds extra protections. But when they start changing the way overloading works, then they are changing the behavior. At some point, we lose our grip on how the language works.
This is especially true since the language allows inference of scope attributes. When does the inference happen, and how does that interact with overloading?
I really hate to get lost in a swamp over this. When we designed 'alias this', we wound up lost in a swamp of having little idea how to resolve interactions with other features in a principled way. It worked fine in isolation, but not when mixed with inheritance.
Comment #5 by bugzilla — 2023-06-24T00:27:21Z
I was going to mark it an 'Enhancement', but looks like you've already done so. We seem to be in at least some agreement!
Comment #6 by dlang-bugzilla — 2023-06-24T16:05:28Z
I don't think there is any disagreement at all. Thank you for the explanation, that's very interesting.
FWIW, I tried using scope overloads to solve the "function which only sometimes needs to make a copy" problem. The scope overload needs to call .dup, but the non-scope overload never needs to call .dup, because lack of scope implies infinite lifetime.