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

Fix compilation for folly::StringPiece args (regression from v10) #4086

Closed
wants to merge 1 commit into from

Conversation

mhx
Copy link

@mhx mhx commented Jul 24, 2024

When building fbthrift on Fedora Rawhide (which bundles fmt v11), the following assertion fails:

/usr/include/fmt/base.h:1612:17: error: static assertion failed: Mixing character types is disallowed.
 1612 |   static_assert(formattable_char, "Mixing character types is disallowed.");
      |                 ^~~~~~~~~~~~~~~~
/usr/include/fmt/base.h:1612:17: note: 'formattable_char' evaluates to false

This happens as it's trying to format a folly::StringPiece argument:

/usr/include/fmt/base.h: In instantiation of 'constexpr fmt::v11::detail::value<Context> fmt::v11::detail::make_arg(T&) [with bool PACKED = true; Context = fmt::v11::context; T = folly::Range<const char*>; typename std::enable_if<PACKED, int>::type <anonymous> = 0]':
/usr/include/fmt/base.h:2003:74:   required from 'constexpr fmt::v11::detail::format_arg_store<Context, NUM_ARGS, 0, DESC> fmt::v11::make_format_args(T& ...) [with Context = context; T = {folly::Range<const char*>, folly::Range<const char*>}; long unsigned int NUM_ARGS = 2; long unsigned int NUM_NAMED_ARGS = 0; long long unsigned int DESC = 255; typename std::enable_if<(NUM_NAMED_ARGS == 0), int>::type <anonymous> = 0]'
 2003 |   return {{detail::make_arg<NUM_ARGS <= detail::max_packed_args, Context>(
      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
 2004 |       args)...}};
      |       ~~~~~

This is ultimately caused by folly::Range<const char*> defining value_type as const char, which does not compare equal to char.

This change is a potential fix that uses remove_const_t to remove the const-ness of value_type for string-like types.

When building fbthrift on Fedora Rawhide (which bundles fmt v11), the
following assertion fails:

```
/usr/include/fmt/base.h:1612:17: error: static assertion failed: Mixing character types is disallowed.
 1612 |   static_assert(formattable_char, "Mixing character types is disallowed.");
      |                 ^~~~~~~~~~~~~~~~
/usr/include/fmt/base.h:1612:17: note: 'formattable_char' evaluates to false
```

This happens as it's trying to format a `folly::StringPiece` argument:

```
/usr/include/fmt/base.h: In instantiation of 'constexpr fmt::v11::detail::value<Context> fmt::v11::detail::make_arg(T&) [with bool PACKED = true; Context = fmt::v11::context; T = folly::Range<const char*>; typename std::enable_if<PACKED, int>::type <anonymous> = 0]':
/usr/include/fmt/base.h:2003:74:   required from 'constexpr fmt::v11::detail::format_arg_store<Context, NUM_ARGS, 0, DESC> fmt::v11::make_format_args(T& ...) [with Context = context; T = {folly::Range<const char*>, folly::Range<const char*>}; long unsigned int NUM_ARGS = 2; long unsigned int NUM_NAMED_ARGS = 0; long long unsigned int DESC = 255; typename std::enable_if<(NUM_NAMED_ARGS == 0), int>::type <anonymous> = 0]'
 2003 |   return {{detail::make_arg<NUM_ARGS <= detail::max_packed_args, Context>(
      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
 2004 |       args)...}};
      |       ~~~~~
```

This is ultimately caused by `folly::Range<const char*>` defining
`value_type` as `const char`, which does not compare equal to `char`.

This change is a potential fix that uses `remove_const_t` to remove
the const-ness of `value_type` for string-like types.
@vitaut
Copy link
Contributor

vitaut commented Jul 24, 2024

Thanks for the PR but I think it should be fixed in Folly by making the definition of value_type compatible to the one in string_view.

@mhx
Copy link
Author

mhx commented Jul 24, 2024

Thanks for the PR but I think it should be fixed in Folly by making the definition of value_type compatible to the one in string_view.

I agree to some extent, but:

  • It's still a regression :-)
  • I don't know about all the implications of changing the constness of folly::Range::value_type; I'll see if I can come up with a change in the hope that it won't break anything that relies on the constness of value_type.

@mhx
Copy link
Author

mhx commented Jul 24, 2024

If facebook/folly#2265 is a viable solution, this PR can be closed.

@yfeldblum
Copy link
Contributor

StringPiece is an instance of Range, which is more of a span type than a string-view type.

Changing Range in this way is questionable, or at least a larger question. It may be the case that all containers having a member type alias value_type ought to ensure that alias is to a true unqualified value type, and that we need to have the const only on reference_type or such.

@mhx
Copy link
Author

mhx commented Jul 24, 2024

StringPiece is an instance of Range, which is more of a span type than a string-view type.

See my comment on facebook/folly#2265, which argues that std::span also has an unqualified value_type.

Changing Range in this way is questionable, or at least a larger question.

I think it'd be the right change, but I don't know if there are any downstream dependencies that already rely on the qualiefied-ness of value_type.

facebook-github-bot pushed a commit to facebook/folly that referenced this pull request Jul 30, 2024
Summary:
`folly::Range` roughly models both a range and a span. This mostly works out okay. But there are edge cases where it does not, such as when the `*obj.begin()` returns a reference-proxy value-type rather than a reference. In these cases, while we can get `reference` from the iterator type via `iterator_traits`, we cannot get `value_type` or `const_reference` from `reference` directly.

* Get `value_type` also from the iterator type via `iterator_traits`.
* When `reference` is a reference-proxy value-type, let `const_reference` be an alias to `reference`. In such cases, `const_reference` and `reference` will be the same and there will be no protection against non-`const` access via a `const`-qualified `Range` receiver. As trivial, the other case when `const_reference` and `reference` are identical would be when `std::is_const_v<std::remove_reference_t<reference>>`.

Fixes a regression with fmt-11, which is stricter on the requirements for member `value_type` and requires it to be a value type, and with which folly fails to build.

See the pull request fmtlib/fmt#4086 for additional context.

Closes: fmtlib/fmt#4086.

Reviewed By: luciang, vitaut

Differential Revision: D60342412

fbshipit-source-id: 030ad9d720c8870049ed432e8523da67b8555b90
@vitaut
Copy link
Contributor

vitaut commented Jul 30, 2024

Closing in favor of the folly fix (facebook/folly@21e8dcd). Thanks for reporting (and the fix attempt)!

@vitaut vitaut closed this Jul 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants