Skip to content

[BUG] Static member function call accepts both . and :: #339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
msadeqhe opened this issue Apr 9, 2023 · 8 comments
Closed

[BUG] Static member function call accepts both . and :: #339

msadeqhe opened this issue Apr 9, 2023 · 8 comments
Labels
bug Something isn't working

Comments

@msadeqhe
Copy link

msadeqhe commented Apr 9, 2023

This is an example code:

#include <iostream>
#include <string>

Class: type = {
    static_call: () = {
        std::cout << "Hello World!\n";
    }
}

main: () -> int = {
    klass: Class = ();

    Class::static_call();
    klass.static_call();

    // Why aren't these lines syntax errors?
    Class.static_call();
    klass::static_call();
}

The last two lines should led to compilation fail, but C++2 generates the following C++1 code:



//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"


class Class;

//=== Cpp2 type definitions and function declarations ===========================

#include <iostream>
#include <string>

class Class {
    public: static auto static_call() -> void;

};

[[nodiscard]] auto main() -> int;

//=== Cpp2 function definitions =================================================


    auto Class::static_call() -> void{
        std::cout << "Hello World!\n";
    }

[[nodiscard]] auto main() -> int{
    Class klass {}; 

    Class::static_call();
    CPP2_UFCS_0(static_call, klass);

    // Why aren't these lines syntax errors?
    CPP2_UFCS_0(static_call, Class);
    std::move(klass)::static_call();
}
@msadeqhe msadeqhe added the bug Something isn't working label Apr 9, 2023
@leejy12
Copy link

leejy12 commented Apr 9, 2023

I'm surprised that klass.static_call() is valid syntax. I think only Class::staic_call() should be valid.

@filipsajdak
Copy link
Contributor

filipsajdak commented Apr 9, 2023

Check 2016 roadmap diagram from README.md

image

@msadeqhe
Copy link
Author

msadeqhe commented Apr 9, 2023

Thanks. What about :: operator in klass::static_call();?

@AbhinavK00
Copy link

AbhinavK00 commented Apr 9, 2023

Even with unified scope/member selection, shouldn't the call translate to
klass::static_call()
instead of UFCS or does the current way work?

@msadeqhe
Copy link
Author

msadeqhe commented Apr 9, 2023

Both klass::static_call() and generated std::move(klass)::static_call(); don't work in C++1.

@filipsajdak
Copy link
Contributor

Most probably this is an incidental bug.

@hsutter
Copy link
Owner

hsutter commented Apr 9, 2023

Thanks.

Interim reply re .: Yes, I originally intended to use . for all scope/member selection, but backed off on that at least for now. The ./:: distinction isn't a major pain point, and using . for everything actually made some cases unclear (including, but not only, for doing the right thing when lowering to Cpp1).

@hsutter
Copy link
Owner

hsutter commented Apr 9, 2023

Elaborating, now that I'm paging this back into my own memory:

Using . for everything was an experiment that I think doesn't work out, most importantly because it would require doing name lookup to determine meaning -- that's something I want Cpp2 to avoid having to do. For example, referring to members of base classes would be harder in some cases. Think of chains like w.x.y.z in this example (Godbolt), where w has the base type y nested within type x, and the programmer wanted to refer to member z within that type... we would have had to invent syntax to disambiguate that. We actually did try this path briefly, and in an earlier pre-cppfront prototype for a while users had to write things like w.(x.y).z in those cases, but it just felt unclear both to the compiler and more importantly to the programmer. Writing w.x::y::z is not bad and IMO is actually clearer, because forcibly unifying everything to . really lost information (actually and visually).

Shout out with thanks to Andrew Sutton, Wyatt Childers, and the other good folks then at @lock3 who pointed out this issue, and who suggested and implemented the ( ) disambiguation I mentioned above in their cppx compiler that was a first attempt to implement Cpp2. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants