Skip to content

transform_error is missing pfn's value-copy constraint — move-only value types cannot call it #278

Description

@Bronek

pfn's _transform_error requires is_constructible_v<T, decltype(_value(FWD(self)))> (include/pfn/detail/expected_base.hpp:904). fn drops that conjunct:

  • non-sum overload (include/fn/expected.hpp:283-284) — no value-copy conjunct, while the body copies the untouched value at :290;
  • sum-case overload (:302) — constrained on some_sum<E> alone.

The copy is therefore checked only during deduced-return body instantiation, outside the immediate context — and since const& binds rvalues, even an rvalue call forms the losing const& candidate, whose body hard-errors on the copy. Verified on g++ and clang++:

  • fn::expected<move_only, E> cannot call transform_error from any value category;
  • pfn::expected<move_only, E> handles the same code correctly — rvalue calls work, lvalue calls SFINAE-drop.

A pfn→fn switch thus turns valid code ill-formed, violating the superset principle. Internal asymmetry confirms an oversight rather than a design: fn's own _or_else (expected.hpp:168), _and_then (:83) and _transform (:220) all carry their untouched-side copy conjunct; _transform_error alone omits it.

Fix: add (std::is_void_v<T> || std::is_constructible_v<T, decltype(_pfn_base::_value(FWD(self)))>) to both transform_error overloads' requires-clauses (the _or_else spelling at :168). The sum case additionally needs the callback constraint — #277.

Tests (branch bronek/unit_tests_cleanup, commit b88b64e): the or_else-vs-transform_error contrast is asserted with a move-only value type on the or_else side (clean SFINAE drops); the transform_error side carries GAP comments only, since any probe hard-errors until fixed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrelease-0.1Planned for release 0.1

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions