Skip to content

Give sum_value and sum_error a noexcept specification#298

Merged
Bronek merged 2 commits into
mainfrom
bronek/P4/sum_value_error_noexcept
Jul 13, 2026
Merged

Give sum_value and sum_error a noexcept specification#298
Bronek merged 2 commits into
mainfrom
bronek/P4/sum_value_error_noexcept

Conversation

@Bronek

@Bronek Bronek commented Jul 13, 2026

Copy link
Copy Markdown
Member

Both sum_value / sum_error gaps: the missing noexcept specification, and the missing constexpr.

Give sum_value and sum_error a noexcept specification

No overload had one, so a pipeline crossing them lost noexcept unnecessarily. The overloads whose side already is a sum return *this by reference and cannot throw, so they are unconditionally noexcept; the lifting overloads wrap one side in a sum and relocate the other, so they weigh both constructions, and the free functions propagate whatever the member says.

The lifting overloads still report noexcept(false) even for trivial types, because sum's own value constructor carries no specifier to derive from (#280) - conservatively correct, and it sharpens when that lands. The tests assert both halves.

Make sum_value and sum_error usable in a constant expression

They were the only monadic members not declared constexpr, so a constexpr pipeline could not cross the graded lift - and the free functions, though marked constexpr themselves, forwarded to them and were equally unusable.

Closes #276


Stack: P4 of 13 — the release-0.1 bugfix queue, merging bottom-up into main. Based on #297 and to be retargeted to main once it merges; the diff shows only this PR's commits. Every stack boundary was validated with a gcc build and the full test suite on top of main, and the aggregate branch ran the full CI matrix green (#289).

@augmentcode

augmentcode Bot commented Jul 13, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: Makes the graded-monad lifts sum_value/sum_error usable in constant evaluation and preserves exception guarantees when they are used in pipelines.

Changes:

  • Mark expected::sum_error/expected::sum_value overloads constexpr and add conditional noexcept where the operation can be proven non-throwing.
  • Mark the “already-a-sum” overloads noexcept unconditionally since they only return *this (by ref/rref).
  • Apply the same constexpr + conditional noexcept treatment to optional::sum_value.
  • Propagate the member exception specifications through the free-function lifts fn::sum_value/fn::sum_error via noexcept(noexcept(...)).
  • Add tests asserting both constant-expression usability and the intended noexcept behavior for sum-preserving vs lifting overloads.

Technical Notes: The lifting overloads remain conservatively noexcept(false) for many types until sum's value constructor becomes conditionally noexcept (tracked in #280).

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread tests/fn/expected.cpp
fn::expected<int, Error> a{12};
return fn::sum_value(a).value() == fn::sum{12};
}());
SUCCEED();

@augmentcode augmentcode Bot Jul 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests/fn/expected.cpp:251: The new WHEN("constexpr")/WHEN("noexcept") sections only use static_assert plus SUCCEED(), so they don’t actually validate the behavior at runtime. Consider adding runtime CHECK/CHECK_FALSE counterparts (even if they mirror the constant expressions) to match the repo’s “runtime + constexpr twin” testing convention.

Severity: low

Other Locations
  • tests/fn/optional.cpp:95

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@Bronek Bronek force-pushed the bronek/P3/sum_transform_constraints branch from 3acb5e5 to 23c55fa Compare July 13, 2026 11:53
@Bronek Bronek changed the base branch from bronek/P3/sum_transform_constraints to main July 13, 2026 12:08
Bronek added 2 commits July 13, 2026 13:09
No overload had one, so a pipeline crossing them lost `noexcept` unnecessarily.
The overloads whose side already is a sum return `*this` by reference and cannot
throw, so they are unconditionally `noexcept`; the lifting overloads wrap one side
in a sum and relocate the other, so they weigh both constructions, and the free
functions propagate whatever the member says.

The lifting overloads still report `noexcept(false)` even for trivial types,
because `sum`'s own value constructor carries no specifier to derive from (#280) -
conservatively correct, and it sharpens when that lands. The tests assert both
halves.

Closes #276

Assisted-by: Claude:claude-opus-4-8[1m]
They were the only monadic members not declared `constexpr`, so a constexpr
pipeline could not cross the graded lift - and the free functions, though marked
`constexpr` themselves, forwarded to them and were equally unusable.

Assisted-by: Claude:claude-opus-4-8[1m]
@Bronek Bronek force-pushed the bronek/P4/sum_value_error_noexcept branch from 683c4a1 to 3beae5a Compare July 13, 2026 12:09
@Bronek

Bronek commented Jul 13, 2026

Copy link
Copy Markdown
Member Author

augment review

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

@sonarqubecloud

Copy link
Copy Markdown

@Bronek Bronek merged commit ef3c978 into main Jul 13, 2026
64 checks passed
Bronek added a commit that referenced this pull request Jul 13, 2026
Flip #276's tripwires: the self-returning sum_value and sum_error overloads
are noexcept now, while the lifting ones stay conservatively false and are
re-pinned to #280, the sum value constructor whose missing specifier they
weigh. Take #298's constexpr coverage, and its free-function noexcept probes
folded into the sections that already assert those functions' return types -
main states the rest in separate blocks, which those sections already cover,
per value category and in place.

Assisted-by: Claude:claude-opus-4-8[1m]
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.

sum_value() / sum_error() are not declared noexcept

1 participant