This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Untangles invoke.
ClosedPublic

Authored by Mordante on May 14 2023, 11:02 PM.

Details

Reviewers
ldionne
Group Reviewers
Restricted Project
Commits
rGbea2ff655068: [libc++] Untangles invoke.
Summary

The type traits parts are moved to a type_traits detail header.
This was discovered while working on modules.

Diff Detail

Event Timeline

Mordante created this revision.May 14 2023, 11:02 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 14 2023, 11:02 PM
Mordante updated this revision to Diff 522053.May 14 2023, 11:03 PM

Now with generated files updated.

Mordante updated this revision to Diff 522110.May 15 2023, 3:34 AM

Try to fix CI.

Mordante updated this revision to Diff 522115.May 15 2023, 3:59 AM

CI fixes.

Mordante published this revision for review.May 15 2023, 8:13 AM
Mordante added inline comments.
libcxx/utils/data/ignore_format.txt
642

Note sure why this is needed, locally no formatting changes can be done.

Herald added a project: Restricted Project. · View Herald TranscriptMay 15 2023, 8:13 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

I wouldn't consider this disentangled, since __invoke and the type traits are still very much dependent on each other. I also don't think that it makes sense to move __invoke into the type_traits module. This seems like a step backward to me.

I wouldn't consider this disentangled, since __invoke and the type traits are still very much dependent on each other.

You were the one to add the comment about disentangling that code in D126593. Did you have something else in mind back then?

I also don't think that it makes sense to move __invoke into the type_traits module.

I also agree this is kind of weird, but it seems like it is necessary. Another option would be to split into yet another header like __functional/invoke_base.h or invoke_impl.h or whatever. I do like the fact that this patch gets us to a point where the type traits are separated from the main std::invoke functionality. I don't think it's a *must*, but I kind of like it.

I think this patch unblocked things for @Mordante with his work on the std module, so I think we need to find a way to unblock this, it's not just a refactoring for the sake of it.

I wouldn't consider this disentangled, since __invoke and the type traits are still very much dependent on each other.

You were the one to add the comment about disentangling that code in D126593. Did you have something else in mind back then?

In a perfect world we'd have builtins for the traits and invoke, but that's non-trivial to implement (at least for me).

I also don't think that it makes sense to move __invoke into the type_traits module.

I also agree this is kind of weird, but it seems like it is necessary. Another option would be to split into yet another header like __functional/invoke_base.h or invoke_impl.h or whatever. I do like the fact that this patch gets us to a point where the type traits are separated from the main std::invoke functionality. I don't think it's a *must*, but I kind of like it.

It's nice that the public interface is separated from the type traits, but I really don't like moving __invoke back into <type_traits>, since it shouldn't be there.

I think this patch unblocked things for @Mordante with his work on the std module, so I think we need to find a way to unblock this, it's not just a refactoring for the sake of it.

I don't really understand how this is blocking though. Shouldn't it be enough to include <type_traits> and <functional> to implement the respective modules? All the symbols should still be available.

I wouldn't consider this disentangled, since __invoke and the type traits are still very much dependent on each other.

You were the one to add the comment about disentangling that code in D126593. Did you have something else in mind back then?

In a perfect world we'd have builtins for the traits and invoke, but that's non-trivial to implement (at least for me).

We actually discussed that. It would be indeed need to have some of the building blocks of invoke as builtins. The invoke itself might be more troublesome when WG21 changes the definition.

I also don't think that it makes sense to move __invoke into the type_traits module.

I also agree this is kind of weird, but it seems like it is necessary. Another option would be to split into yet another header like __functional/invoke_base.h or invoke_impl.h or whatever. I do like the fact that this patch gets us to a point where the type traits are separated from the main std::invoke functionality. I don't think it's a *must*, but I kind of like it.

I tried to slice things differently but that seemed to fail. If you have suggestions I'm open to them.

It's nice that the public interface is separated from the type traits, but I really don't like moving __invoke back into <type_traits>, since it shouldn't be there.

I think this patch unblocked things for @Mordante with his work on the std module, so I think we need to find a way to unblock this, it's not just a refactoring for the sake of it.

I don't really understand how this is blocking though. Shouldn't it be enough to include <type_traits> and <functional> to implement the respective modules? All the symbols should still be available.

The issue is that the tests for the modules test that the module contains the same declarations as provided by a "header", where "header" means foo, __foo/*h, __fwd/foo.h. These tests are important to validate when we add new declarations to a header we update the module.

EricWF added a subscriber: EricWF.May 17 2023, 10:10 AM

Is the patch as uploaded correct? Because some bits appear to me as having disappeared.

Also, IMHO it makes very much sense to move invoke into type traits. Because it's needed to implement the invocable traits.

Is the patch as uploaded correct? Because some bits appear to me as having disappeared.

Did you notice libcxx/include/__type_traits/invoke.h is considered a copy? So the new lines in this file are marked as unchanged?

Also, IMHO it makes very much sense to move invoke into type traits. Because it's needed to implement the invocable traits.

Thanks.

ldionne accepted this revision.May 23 2023, 9:18 AM

Just to expand on why this is important, Mark just explained to me that it allowed the test in https://reviews.llvm.org/D144994 (libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp) to check that we export the right declarations from type_traits.cppm. If is_invocable isn't declared under __type_traits/, it has to be added to the ignore list for that test and we want to minimize that. I think we should make this change cause it gets us closer to having a systematic way of determining where the declaration of an entity should live, which comes up from time to time when it's not 100% clear.

libcxx/utils/data/ignore_format.txt
642

This is probably related to the recent clang-format issues. It would be nice to avoid adding this file to the ignore list.

This revision is now accepted and ready to land.May 23 2023, 9:18 AM

I still don't think we should move the __invoke functions back into <type_traits>, since that will inevitably result in <__type_traits/*> includes when we just want __invoke (which we use at least an order of magnitude more often than all the traits combined). We could instead try to implement invoke in terms of __invoke directly instead of going through the type traits. While this will probably mean that we deviate from the standard, IMO it's better than having the functions in the wrong place.

Mordante updated this revision to Diff 524783.May 23 2023, 10:05 AM

Test formatting in the CI.

This revision was automatically updated to reflect the committed changes.