Bug 17879 – UFCS can enable some forms of hijacking

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-10-05T19:42:19Z
Last change time
2024-12-13T18:54:47Z
Assigned to
No Owner
Creator
Walter Bright
Moved to GitHub: dmd#17819 →

Comments

Comment #0 by bugzilla — 2017-10-05T19:42:19Z
From Timon Gehr: struct S{ // string foo(){ return "hijacked!"; } // uncomment to hijack } string foo(S s){ return "not hijacked!"; } void main(){ S s; import std.stdio; writeln(s.foo()); }
Comment #1 by bugzilla — 2017-10-05T19:42:56Z
Comment #2 by issues.dlang — 2017-10-05T21:58:15Z
How is that hijacking? When you use UFCS, you're saying that it should call the member function with that name, and if there is no member function, then it tries to call a matching free function. Anything else would make it impossible to use a member function and a free function for the same functionality, and if you reversed it so that it used UFCS instead, that would make it so that you couldn't call the member function. It was my understanding that UFCS was purposefully designed this way, and I don't see how doing anything else makes sense. If you want to guarantee that you're calling a free function rather than a member function, then just don't use UFCS.
Comment #3 by bugzilla — 2017-10-05T23:10:43Z
I listed it as an enhancement, not a bug, for the reasons you describe. The issue has come up before, it will again, and a bugzilla entry can serve as a focal point for it so discussions on it won't keep restarting from scratch.
Comment #4 by schveiguy — 2017-10-06T13:13:42Z
According to the PR discussion, the issue was more like this: mod1.d: struct S { // private string foo(){ return "hijacked"; } } main.d: import mod1; string foo(S s) { return "not hijacked"; } void main() { S s; import std.stdio; writeln(s.foo()); } In other words, the *private* symbol was hijacking UFCS. S should be able to build whatever it wants privately without interfering with UFCS. When I try to build this now, it doesn't work anyway. I get both a deprecation warning and an error. I can't figure out why the original code that the PR was fixing actually worked before the PR. I agree with Jonathan that UFCS just doesn't take precedent over the member, and can't be considered a hijacking. If we "fixed" this, for instance, any code that used output ranges might break. However, allowing UFCS to provide unrelated added methods that the type has the same name for, should work.
Comment #5 by robert.schadek — 2024-12-13T18:54:47Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17819 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB