Skip to content

AK: Allow Optional<T> to be used in constant expressions #4310

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

Merged
merged 11 commits into from
Apr 23, 2025

Conversation

yyny
Copy link
Contributor

@yyny yyny commented Apr 10, 2025

Attempt 1: #2455
Related SerenityOS PR: SerenityOS/serenity#25740

@ladybird-bot
Copy link
Collaborator

Hello!

One or more of the commit messages in this PR do not match the Ladybird code submission policy, please check the lint_commits CI job for more details on which commits were flagged and why.
Please do not close this PR and open another, instead modify your commit message(s) with git commit --amend and force push those changes to update this PR.

@Hendiadyoin1
Copy link
Contributor

Also take a look at SerenityOS/serenity#25880
Which has a small fixup for that (may add the same for ErrrorOr)

@yyny yyny force-pushed the constexpr-optional-v2 branch 2 times, most recently from 05fb04b to be6f59f Compare April 11, 2025 07:39
@yyny
Copy link
Contributor Author

yyny commented Apr 11, 2025

Ladybird's Optional already has optimal move-assignment, I've added your test.

Copy link
Contributor

@Hendiadyoin1 Hendiadyoin1 left a comment

Choose a reason for hiding this comment

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

first look from my side
I'd like
@alimpfard @LucasChollet and @DanShaders
To also have a look

AK/Optional.h Outdated
ALWAYS_INLINE Optional() = default;
ALWAYS_INLINE constexpr Optional()
{
construct_null_if_necessairy();
Copy link
Contributor

Choose a reason for hiding this comment

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

As Cxbyte pointed out these are not needed, just add a = {} to the null member

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would unconditionally zero-fill the Optional, which is not necessary at runtime since m_has_value guards against uninitialized access.

AK/Optional.h Outdated
Comment on lines 326 to 378
ALWAYS_INLINE constexpr void construct_null_if_necessairy()
{
// OPTIMIZATION: Only construct the `m_null` member when we are constant-evaluating.
// Otherwise, this generates an unnecessairy zero-fill.
#if defined(AK_COMPILER_GCC) || defined(HAS_ADDRESS_SANITIZER)
// NOTE: GCCs -Wuninitialized warning ends up checking this as well.
constexpr bool should_construct = true;
#else
constexpr bool should_construct = is_constant_evaluated();
#endif
if (should_construct)
m_null = {};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

See above and CxBytes comments on the serenity PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just re-confirmed in Compiler Explorer, initializing m_null does indeed zero fill in cases where it shouldn't have to at -O3 optimizations on both Clang and GCC. I fixed the constexpr bool should_construct = is_constant_evaluated(); though, since that apparently always evaluates to true.

@yyny yyny force-pushed the constexpr-optional-v2 branch 2 times, most recently from 4bf654a to ea9052d Compare April 11, 2025 14:11
@yyny yyny force-pushed the constexpr-optional-v2 branch 2 times, most recently from b6a4559 to 38376ae Compare April 12, 2025 09:27
Copy link
Contributor

@DanShaders DanShaders left a comment

Choose a reason for hiding this comment

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

Looks vaguely fine, I didn't read the diff too carefully tho

Copy link
Member

@ADKaster ADKaster left a comment

Choose a reason for hiding this comment

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

For all of these, if we already resolved one way or another on one of the SerenityOS PRs, I'll defer to that decision.

@yyny yyny force-pushed the constexpr-optional-v2 branch 2 times, most recently from 058ee0c to df1190f Compare April 21, 2025 19:29
Copy link
Member

@ADKaster ADKaster left a comment

Choose a reason for hiding this comment

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

I think this is ready, but I'd like a second opinion from @alimpfard

Copy link
Contributor

@alimpfard alimpfard left a comment

Choose a reason for hiding this comment

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

Just a couple notes, otherwise looks nice.

yyny added 9 commits April 22, 2025 21:46
Much like `IsOneOfIgnoringCV`, some functions want to ignore both
cv-qualifiers _and_ references. Add a template and concept for it.
This argument is removed (or rather, never added) by `-cc1`, which
breaks any builds using GNU libc++, including CI.
Does exactly what it says on the tin.
This matches the behaviour of `std::is_scalar_v`
If a type is non-move constructible but move assignable,
its container type may still be move assignable.

Similairly, if a type is non-copy constructible but copy assignable,
its container type may still be copy assignable.
@yyny yyny force-pushed the constexpr-optional-v2 branch from df1190f to e8f7dde Compare April 22, 2025 19:47
This will change behaviour for moved-from `Optional<T>`s, since they
will now no longer clear their value if `T` is trivial. However, a
moved-from value should be considered to be in an unspecified state.
Use `Optional<T>::clear` or `Optional<T>::release_value` instead.
@yyny yyny force-pushed the constexpr-optional-v2 branch from e8f7dde to f6ac15b Compare April 22, 2025 19:49
Copy link
Contributor

@alimpfard alimpfard left a comment

Choose a reason for hiding this comment

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

LGTM

@ADKaster ADKaster merged commit bb20a0d into LadybirdBrowser:master Apr 23, 2025
7 checks passed
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.

6 participants