Thread overview
[Issue 8104] New: UFCS on forward reference won't compile
May 16, 2012
John Belmonte
May 16, 2012
John Belmonte
May 19, 2012
John Belmonte
[Issue 8104] UFCS on opaque struct won't compile
May 20, 2012
John Belmonte
May 20, 2012
Kenji Hara
May 20, 2012
John Belmonte
May 20, 2012
Kenji Hara
Jun 28, 2012
Walter Bright
May 16, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104

           Summary: UFCS on forward reference won't compile
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: john@neggie.net


--- Comment #0 from John Belmonte <john@neggie.net> 2012-05-15 17:55:50 PDT ---
It should be possible to use UFCS on an opaque struct.

----
struct State;

void foo(State*) {};

void main() {
    State* s;
    foo(s);  // ok
    s.foo(); // compile error
}

----
Error: struct State is forward referenced when looking for 'foo' Error: struct State is forward referenced when looking for 'opDot' Error: struct State is forward referenced when looking for 'opDispatch'

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 16, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104



--- Comment #1 from John Belmonte <john@neggie.net> 2012-05-15 19:54:46 PDT ---
I scanned the dmd UFCS implementation.  Apparently expressions are blindly translated from e.g. foo.bar() to bar(foo) when the normal searches on foo fail.  In other words, we don't know at the time of the normal searches whether there is a matching free function.

I propose resolving this by, in all cases, not considering a search on an opaque struct to be an error.  That is, foo.bar() will not yield a "forward referenced" error regardless of whether a matching free function exists.

For the case where no free function exists, the compile error would then be "undefined identifier 'bar'"-- i.e. the same as for a non-opaque struct.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 19, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104


John Belmonte <john@neggie.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
         AssignedTo|nobody@puremagic.com        |john@neggie.net


--- Comment #2 from John Belmonte <john@neggie.net> 2012-05-18 18:36:34 PDT ---
Appears to be a one-line fix.  Assuming I can figure out the build and unit test framework I'll prepare a pull request.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 20, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104



--- Comment #3 from John Belmonte <john@neggie.net> 2012-05-19 18:57:11 PDT ---
https://github.com/D-Programming-Language/dmd/pull/955

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 20, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104



--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2012-05-19 19:10:14 PDT ---
(In reply to comment #0)
> It should be possible to use UFCS on an opaque struct.
> 
> ----
> struct State;
> 
> void foo(State*) {};
> 
> void main() {
>     State* s;
>     foo(s);  // ok
>     s.foo(); // compile error
> }
> 
> ----
> Error: struct State is forward referenced when looking for 'foo' Error: struct State is forward referenced when looking for 'opDot' Error: struct State is forward referenced when looking for 'opDispatch'

I think this is expected behavior. s.foo() should look up Stete's members, but
it is impossible, then errors occur.
UFCS should be a lookup for fall-back. If properly lookup fails, UFCS should
not hide the error.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 20, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104


John Belmonte <john@neggie.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |k.hara.pg@gmail.com,
                   |                            |timon.gehr@gmx.ch


--- Comment #5 from John Belmonte <john@neggie.net> 2012-05-20 06:44:31 PDT ---
@Kenji: When brought up on the forum there seemed to be consensus that this was a bug.  http://forum.dlang.org/thread/rseaqsqosqrnirrclcic@forum.dlang.org

Why should the act of function member lookup on an opaque struct necessarily be an error?  It should only be an error if the member cannot be resolved.  Prior to UFCS, there was no way to resolve function members outside of the struct itself, so it made sense to raise an error directly from the struct's search call.

At http://dlang.org/struct.html there is a section "Opaque Structs and Unions".
 It says that the members of such a struct are hidden from the user.  It's not
clear on what "hidden" implies though.  With respect to function members this
documentation should be clarified:  an opaque struct behaves as if it has no
function members.

Note that all the errors regarding "forward reference" are misleading.  These structs not a forward reference, there are opaque.  It's illegal to redefine an opaque struct:

  struct S;
  struct S { int foo; } // Error: struct S conflicts with struct S

Given that, what are you trying to protect the user from by disallowing UFCS on these structs?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 20, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104



--- Comment #6 from Kenji Hara <k.hara.pg@gmail.com> 2012-05-20 08:31:49 PDT ---
(In reply to comment #5)
> @Kenji: When brought up on the forum there seemed to be consensus that this was a bug.  http://forum.dlang.org/thread/rseaqsqosqrnirrclcic@forum.dlang.org
> 
> Why should the act of function member lookup on an opaque struct necessarily be an error?  It should only be an error if the member cannot be resolved.  Prior to UFCS, there was no way to resolve function members outside of the struct itself, so it made sense to raise an error directly from the struct's search call.

Because of function hijacking.

> At http://dlang.org/struct.html there is a section "Opaque Structs and Unions".
>  It says that the members of such a struct are hidden from the user.  It's not
> clear on what "hidden" implies though.  With respect to function members this
> documentation should be clarified:  an opaque struct behaves as if it has no
> function members.

No. opaque struct means "may or may not have members", not "has no members". They are different.

> Note that all the errors regarding "forward reference" are misleading.  These structs not a forward reference, there are opaque.  It's illegal to redefine an opaque struct:
> 
>   struct S;
>   struct S { int foo; } // Error: struct S conflicts with struct S
> 
> Given that, what are you trying to protect the user from by disallowing UFCS on these structs?

I'd like to explain a use case.
---
1. module m_a has a struct S with members. module m_b imports m_a and use S.

module m_a;
struct S { void foo() { ... } ... }
S* makeS() { ... }

module m_b;
void foo(S* ps) { ... }
void main(){ auto ps = makeS(); ps.foo(); /* call S.foo */ }

2. S is changed to 'opaque struct'.
   (e.g. m_a is provided by hand-made di file.)

module m_a;
struct S;
S* makeS();

3. In module m_b, now ps.foo() accidently calls m_b.foo.
---

Additionaly, current UFCS lookup mechanism is not completely
defined/implemented.
It's debated recently (See
http://forum.dlang.org/thread/jl09ui$ii8$1@digitalmars.com), so I wouldn't like
to change/add lookup mechanism yet.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 28, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8104


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
                 CC|                            |bugzilla@digitalmars.com
         Resolution|                            |INVALID


--- Comment #8 from Walter Bright <bugzilla@digitalmars.com> 2012-06-28 12:21:33 PDT ---
I believe this is invalid.

Code must not change behavior depending on whether a struct's members are there or are opaque, hence if there is a possible dependency on what those members are then it should fail to compile.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------