Skip to content
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

[BUG] Unable to call a member function on a heap object. #673

Closed
guybrush77 opened this issue Sep 11, 2023 · 3 comments
Closed

[BUG] Unable to call a member function on a heap object. #673

guybrush77 opened this issue Sep 11, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@guybrush77
Copy link

Describe the bug

Unable to call a member function on a heap object.

To Reproduce

I am presuming the following should work seamlessly:

// test.cpp2
foo : type = {
    print: (this) = std::cout << "Hello!\n";
}

main: () = {
    f := new<foo>;
    f*.print();
}

Transpiling works:

cppfront -version
cppfront compiler v0.2.1   Build 8910:1255

cppfront -p test.cpp2 
test.cpp2... ok (all Cpp2, passes safety checks)

Compiling fails:

clang++-15 -std=c++20 test.cpp
test.cpp2:8:17: error: use of undeclared identifier 'print'
CPP2_UFCS_0(print, (*cpp2::assert_not_null(std::move(f))));
@guybrush77 guybrush77 added the bug Something isn't working label Sep 11, 2023
@guybrush77 guybrush77 changed the title [BUG] [BUG] Unable to call a member function on a heap object. Sep 11, 2023
@JohelEGP
Copy link
Contributor

The error message is bad due to #439.
Here's what I get using Clang with #506:

Waarudo.cpp2:220:3: error: no matching function for call to object of type '(lambda at Waarudo.cpp2:220:3)'
  220 |   CPP2_UFCS(print)((*cpp2::assert_not_null(std::move(f))));
      |   ^~~~~~~~~~~~~~~~
/home/johel/root/include/cpp2util_macros.h:104:42: note: expanded from macro 'CPP2_UFCS'
  104 | #define CPP2_UFCS(...)                   CPP2_UFCS_(&,,__VA_ARGS__)
      |                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/root/include/cpp2util_macros.h:88:46: note: expanded from macro 'CPP2_UFCS_'
   88 | #define CPP2_UFCS_(LAMBDADEFCAPT,TEMPKW,...) \
      |                                              ^
   89 | [LAMBDADEFCAPT] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA_CLANG \
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   90 |   noexcept(requires { requires requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }; \
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   91 |                       requires noexcept(CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...)); } \
      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   92 |            || requires { requires !requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }; \
      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   93 |                          requires noexcept(__VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...)); }) \
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   94 |     CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   95 |     requires requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); } \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   96 |              || requires { __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } { \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   97 |     if constexpr (requires{ CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); }) { \
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   98 |         return CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   99 |     } else { \
      |     ~~~~~~~~~~
  100 |         return __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  101 |     } \
      |     ~~~
Waarudo.cpp2:220:3: note: candidate template ignored: constraints not satisfied [with obj:auto = std::__1::unique_ptr<foo> (&)(), params:auto = <>]
/home/johel/root/include/cpp2util_macros.h:104:42: note: expanded from macro 'CPP2_UFCS'
  104 | #define CPP2_UFCS(...)                   CPP2_UFCS_(&,,__VA_ARGS__)
      |                                          ^
/home/johel/root/include/cpp2util_macros.h:88:46: note: expanded from macro 'CPP2_UFCS_'
   88 | #define CPP2_UFCS_(LAMBDADEFCAPT,TEMPKW,...) \
      |                                              ^
Waarudo.cpp2:220:3: note: because 'std::forward<decltype(obj)>(obj).print(std::forward<decltype(params)>(params)...)' would be invalid: member reference base type 'std::__1::unique_ptr<foo> ()' is not a structure or union
/home/johel/root/include/cpp2util_macros.h:104:42: note: expanded from macro 'CPP2_UFCS'
  104 | #define CPP2_UFCS(...)                   CPP2_UFCS_(&,,__VA_ARGS__)
      |                                          ^
/home/johel/root/include/cpp2util_macros.h:95:42: note: expanded from macro 'CPP2_UFCS_'
   95 |     requires requires { CPP2_FORWARD(obj).TEMPKW __VA_ARGS__(CPP2_FORWARD(params)...); } \
      |                                          ^
Waarudo.cpp2:220:13: note: and 'print(std::forward<decltype(obj)>(obj), std::forward<decltype(params)>(params)...)' would be invalid: no matching function for call to 'print'
  220 |   CPP2_UFCS(print)((*cpp2::assert_not_null(std::move(f))));
      |             ^
1 error generated.

new<foo> lowers to the template-id cpp2_new<foo>, which is a function pointer.
What you want to use instead is new<foo>().

@guybrush77
Copy link
Author

@JohelEGP Thanks, that makes sense. I will close this bug.

@JohelEGP
Copy link
Contributor

Maybe new<foo> should reference a callable object of non-copyable type.
Then this bug could have been prevented.
But something like :(_) = {}(new<foo>) would still work.

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

2 participants