This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Add __decay_t and use it instead of decay<>::type
ClosedPublic

Authored by philnik on Mar 27 2023, 9:22 AM.

Details

Summary

This avoids instantiating lots of types.

Diff Detail

Event Timeline

philnik created this revision.Mar 27 2023, 9:22 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 27 2023, 9:22 AM
philnik requested review of this revision.Mar 27 2023, 9:22 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 27 2023, 9:22 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
ldionne accepted this revision.Mar 30 2023, 8:51 AM

LGTM but please double-check the CI

libcxx/include/__utility/auto_cast.h
20

Might as well do it as a fly-by. It's just a good habit to have for macros.

This revision is now accepted and ready to land.Mar 30 2023, 8:51 AM
philnik updated this revision to Diff 509777.Mar 30 2023, 12:17 PM
philnik marked an inline comment as done.

Address comments

philnik updated this revision to Diff 509787.Mar 30 2023, 12:49 PM

Try to fix CI

This revision was landed with ongoing or failed builds.Mar 30 2023, 5:23 PM
This revision was automatically updated to reflect the committed changes.
tcanens added inline comments.
libcxx/include/__type_traits/decay.h
73

This change is breaking (and nonconforming). Alias templates are transparent, so this changes the mangling of

template<class T> void f(std::decay_t<T>);
template void f<int>(int);

It also breaks declaration matching between that and

template<class T> void f(typename std::decay<T>::type);
ilya-biryukov added a subscriber: ilya-biryukov.EditedJun 2 2023, 7:10 AM

As the comment above mentioned, this seems to be a non-conformant breaking change.
Our integrate fails on this code snippet after this change when compiled with -std=c++20 (godbolt):

#include <vector>

struct Value {};

template <class Iter>
struct WrappedIter : Iter {
    using pointer = Value*;
    using reference = Value&;

    pointer operator-> () { return &v; }
    reference operator* () { return v;  }

private:
  Value v;
};


using WI = WrappedIter<std::vector<int>::iterator>;
void foo(WI b, WI e) {
    std::vector<Value> foo(b, e);
}

UPD: the relevant error message seems to be:

.../include/c++/v1/__algorithm/unwrap_iter.h:46:32: error: no matching function for call to '__to_address'
  using _ToAddressT = decltype(std::__to_address(std::declval<_Iter>()));
...
.../include/c++/v1/__memory/pointer_traits.h:204:1: note: candidate template ignored: requirement 'integral_constant<bool, false>::value' was not satisfied [with _Pointer = WrappedIter<std::__wrap_iter<int *>>]
__to_address(const _Pointer& __p) _NOEXCEPT {
^

My reading of the error is that to_address used to work only with operator ->, but now it (incorrectly) also requires the to_address function.

Sorry, I misread the dates. I thought this landed on May 31, not March 31.
The failure above was definitely caused by something else.