Bug 211674 - Switch from WTF::Optional to std::optional
Summary: Switch from WTF::Optional to std::optional
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Darin Adler
URL:
Keywords: InRadar
Depends on: 211703
Blocks: 226251
  Show dependency treegraph
 
Reported: 2020-05-09 16:24 PDT by Darin Adler
Modified: 2021-05-25 22:04 PDT (History)
33 users (show)

See Also:


Attachments
Patch (64.75 KB, patch)
2020-05-09 16:25 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (34.62 KB, patch)
2020-05-11 23:06 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (79.11 KB, patch)
2021-05-24 11:06 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (79.62 KB, patch)
2021-05-24 14:13 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (80.56 KB, patch)
2021-05-24 16:39 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (82.82 KB, patch)
2021-05-24 18:48 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (83.12 KB, patch)
2021-05-25 09:16 PDT, Darin Adler
cdumez: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Darin Adler 2020-05-09 16:24:34 PDT
Switch from WTF::Optional to std::optional
Comment 1 Darin Adler 2020-05-09 16:25:43 PDT
Created attachment 398944 [details]
Patch
Comment 2 Darin Adler 2020-05-09 16:27:51 PDT
Comment on attachment 398944 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=398944&action=review

> Source/WTF/ChangeLog:3
> +        Switch from WTF::Optional to std::optional

I think a first cut would be to check the changes that are needed to get compiling with std::optional, without actually changing from WTF::Optional to std::optional.

Hoping EWS can find more of those. I found a number of them.

> Source/WTF/wtf/Optional.h:58
> +#define hasValue has_value
> +#define valueOr value_or

This super-horrible hack seems like something I would not check in.
Comment 3 Chris Dumez 2020-05-09 16:30:15 PDT
The move constructor of std::optional behaves very differently iirc. We have to watch out everywhere we WTFMove() an optional. I thought we had decided to stick with our WTF class because of move constructor was safer. We have had multiple bugs due to use after move of std optional in the past. I believe there was a mailing list discussion about it.
Comment 4 Darin Adler 2020-05-09 16:37:10 PDT
OK, that seems like a reason to not switch yet.

Are you saying we might never switch?

On the other hand, std::optional seems do to some other subtle things differently in a way that’s better. That led to the other changes in this patch.
Comment 5 Darin Adler 2020-05-09 16:38:26 PDT
I like being safer, and if this benefit is great enough we should keep it. But in the long run I think it would be better if we were using standard C++ and not our own dialect.
Comment 6 Chris Dumez 2020-05-09 16:38:37 PDT
I found the previous discussion on this:
https://lists.webkit.org/pipermail/webkit-dev/2018-December/030316.html
Comment 7 Darin Adler 2020-05-09 16:39:38 PDT
How did you get experience this? Why were you using std::optional? Was it in another project?
Comment 8 Chris Dumez 2020-05-09 16:42:21 PDT
(In reply to Darin Adler from comment #5)
> I like being safer, and if this benefit is great enough we should keep it.
> But in the long run I think it would be better if we were using standard C++
> and not our own dialect.

I agree it is better to use standard types in general. However, the fact that the move constructor of std::optional doesn’t reset the isSet flag is a serious issue that has caught us several times :(

The proper pattern would be to use std::exchange() instead of WTFMove(). However, people are used to moving and I fear we will keep having such bugs if we made the switch.
Comment 9 Chris Dumez 2020-05-09 16:45:05 PDT
(In reply to Darin Adler from comment #7)
> How did you get experience this? Why were you using std::optional? Was it in
> another project?

Definitely in WebKit. I have fixed several bugs caused by std optional move constructor behavior, which is why I decided to start that thread.
Comment 10 Darin Adler 2020-05-09 16:47:55 PDT
Where in WebKit was std::optional used?
Comment 11 Darin Adler 2020-05-09 16:48:22 PDT
(In reply to Chris Dumez from comment #8)
> The proper pattern would be to use std::exchange() instead of WTFMove().
> However, people are used to moving and I fear we will keep having such bugs
> if we made the switch.

Lets start moving from WTFMove to std::exchange. Some day we will make the switch.
Comment 12 Chris Dumez 2020-05-09 16:51:09 PDT
(In reply to Darin Adler from comment #10)
> Where in WebKit was std::optional used?

We used our own copy of std optional everywhere because we could not adopt the compiler one yet. We moved the WTF optional when I changed the move constructor if I remember correctly. Last I checked, which admittedly was at the time of that thread, the standard / compiler optional move constructor has the same behavior as our local copy of std optional.
Comment 13 Chris Dumez 2020-05-09 16:57:07 PDT
I am kind of curious if the tests are going to pass. I do think people have been using std exchange more but I would not been surprised if more used after move cases of optional had been added.
Comment 14 Darin Adler 2020-05-10 14:14:44 PDT
Looks like all the tests pass except for API tests that are depending on the move semantics. So it seems like we don’t have any code that depends on our different WTF::optional move semantics that affects any of our regression tests.

Separately, for some reason this didn’t compile on Windows, although it did on WinCairo. I can’t find an error message. I think I’ll push the "retry tests" button.
Comment 15 Darin Adler 2020-05-10 14:44:42 PDT
Uploaded a patch fixing the problems found by using std::optional in bug 211703. Checking these in does *not* commit us to switching to std::optional, but will shrink this patch here.
Comment 16 Darin Adler 2020-05-11 23:06:07 PDT Comment hidden (obsolete)
Comment 17 Darin Adler 2021-05-24 11:06:56 PDT Comment hidden (obsolete)
Comment 18 Darin Adler 2021-05-24 14:13:36 PDT Comment hidden (obsolete)
Comment 19 Darin Adler 2021-05-24 16:39:35 PDT Comment hidden (obsolete)
Comment 20 Darin Adler 2021-05-24 18:48:50 PDT Comment hidden (obsolete)
Comment 21 Darin Adler 2021-05-25 09:16:23 PDT
Created attachment 429657 [details]
Patch
Comment 22 Darin Adler 2021-05-25 12:09:17 PDT
Trying to figure out what to do next:

- This Patch

This current patch seems to build and pass all the tests, so I could get it reviewed and landed as is.

- Smaller

I could make a smaller patch with all the changes that don’t require switching to std::optional (like I did a year back). That would include all the changes in JavaScriptCore, WebCore, and WebKit, the changes to Second.h and PersistentCoder.h in WTF, and the changes to the RetainPtr tests in TestWebKitAPI. That’s easy to do, and can be done without making any decision about adopting std::optional or deciding whether to use the macro tricks in Optional.h to smooth over the transition.

- Bigger

Could go for a bigger patch that does more global replacing. Likely the first step would be to remove the need for the macro tricks for hasValue and valueOr, then do the rest of the work towards removing the need for the Optional.h header entirely, using std::optional, std::make_unique, std::nullopt, std::nullopt_t, and getting rid of valueOrCompute.
Comment 23 Chris Dumez 2021-05-25 12:13:58 PDT
(In reply to Darin Adler from comment #22)
> Trying to figure out what to do next:
> 
> - This Patch
> 
> This current patch seems to build and pass all the tests, so I could get it
> reviewed and landed as is.
> 
> - Smaller
> 
> I could make a smaller patch with all the changes that don’t require
> switching to std::optional (like I did a year back). That would include all
> the changes in JavaScriptCore, WebCore, and WebKit, the changes to Second.h
> and PersistentCoder.h in WTF, and the changes to the RetainPtr tests in
> TestWebKitAPI. That’s easy to do, and can be done without making any
> decision about adopting std::optional or deciding whether to use the macro
> tricks in Optional.h to smooth over the transition.
> 
> - Bigger
> 
> Could go for a bigger patch that does more global replacing. Likely the
> first step would be to remove the need for the macro tricks for hasValue and
> valueOr, then do the rest of the work towards removing the need for the
> Optional.h header entirely, using std::optional, std::make_unique,
> std::nullopt, std::nullopt_t, and getting rid of valueOrCompute.

I think we should land this patch as is. It is a good first step. Then we should probably follow-up to drop usage of WTF::Optional entirely?
Comment 24 Chris Dumez 2021-05-25 12:27:43 PDT
Comment on attachment 429657 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=429657&action=review

r=me

> Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp:310
> +    return options;

I would have updated early returns to return nullptr instead of { }. I assume it is equivalent but I am not 100% sure.
Comment 25 Darin Adler 2021-05-25 12:33:45 PDT
Comment on attachment 429657 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=429657&action=review

>> Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp:310
>> +    return options;
> 
> I would have updated early returns to return nullptr instead of { }. I assume it is equivalent but I am not 100% sure.

Seems OK, but I prefer not to do it before landing because it’s not really different between optionals and pointers.

The caller is not supposed to look at the return value at all when there’s an exception, so I sort of like using { } rather than giving a specific return value. I kind of wish the RETURN_IF_EXCEPTION macro did that, but I guess it doesn’t work when the return type is void.
Comment 26 Darin Adler 2021-05-25 12:35:25 PDT
Committed r278035 (238131@main): <https://commits.webkit.org/238131@main>
Comment 27 Radar WebKit Bug Importer 2021-05-25 12:36:18 PDT
<rdar://problem/78470754>
Comment 28 Lauro Moura 2021-05-25 20:50:45 PDT
Committed r278074 (238153@main): <https://commits.webkit.org/238153@main>
Comment 29 Lauro Moura 2021-05-25 21:59:18 PDT
Committed r278076 (238155@main): <https://commits.webkit.org/238155@main>
Comment 30 Darin Adler 2021-05-25 22:04:04 PDT
There’s no need for the extra braces in these GCC8 fixes. We would want you to write them like this:

    return SerializedPlatformDataCueValue { };