• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bemanproject / expected / 39086008363
98%

Build:
DEFAULT BRANCH: main
Ran 18 Oct 2026 01:21AM UTC
Jobs 1
Files 3
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

18 Oct 2026 01:18AM UTC coverage: 95.522%. Remained the same
39086008363

push

github

web-flow
Keep expected trivially copyable under clang when no copy assignment is eligible (#100)

Every clang job built against libstdc++ fails `beman::expected type
traits match std::expected` on `main`, for clang 19 through 22 and every
C++ mode. The gcc jobs and the clang jobs on libc++ pass. The failing
check is `is_trivially_copyable` for `expected<int, MoveOnly>` and
`expected<void, MoveOnly>` (and the same for `NoexceptMoveOnly`).

## Cause

Two things combine.

- libstdc++ 16 made `std::expected<int, MoveOnly>` trivially copyable.
The test checks "beman is at least as trivial as std", which is an
implication, so until the CI images moved to libstdc++ 16 there was
nothing to check.
- Clang gets `beman::expected<int, MoveOnly>` wrong. For a move-only E,
neither the trivial nor the non-trivial copy assignment is satisfied.
[class.prop] counts only eligible special members, so the class is
trivially copyable, and gcc agrees. Clang (17 through at least 24)
treats a class whose copy-assignment candidates all have unsatisfied
constraints as not trivially copyable:

  ```cpp
  template <bool B> struct C {
      C(const C&) = delete;
      C(C&&) = default;
      C& operator=(const C&) requires B = default;
      C& operator=(C&&) = default;
  };
static_assert(__is_trivially_copyable(C<false>)); // gcc: passes; clang:
fails
  ```

## Fix

The primary template, `expected<void, E>` and `expected<T&, E>` each get
a deleted copy assignment that is satisfied exactly when neither
existing path is. A deleted candidate is not eligible either, so the
triviality it restores is the one the standard gives, and
`is_copy_assignable` is unchanged. Move assignment is left alone: a
satisfied deleted move assignment would stop an rvalue falling back to
copy assignment for an E with a deleted move.

The new overload is `\omit`ted from the generated wording, and its
rationale sits after the primary template rather than on the
declaration, because a comment on an omitted member is ... (continued)

704 of 737 relevant lines covered (95.52%)

25.1 hits per line

Jobs
ID Job ID Ran Files Coverage
1 39086008363.1 18 Oct 2026 01:21AM UTC 3
95.52
GitHub Action Run
Source Files on build 39086008363
  • Tree
  • List 3
  • Changed 1
  • Source Changed 1
  • Coverage Changed 1
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #39086008363
  • 1875b7ae on github
  • Prev Build on main (#38983632894)
  • Next Build on main (#39147716213)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc