Closed
Bug 1332785
Opened 8 years ago
Closed 8 years ago
MozPromiseHolder::Resolve and Reject should take references
Categories
(Core :: XPCOM, defect)
Tracking
()
RESOLVED
FIXED
mozilla54
| Tracking | Status | |
|---|---|---|
| firefox54 | --- | fixed |
People
(Reporter: mozbugz, Assigned: mozbugz)
References
Details
Attachments
(1 file)
MozPromiseHolder::Resolve and Reject currently take their argument by-value, which could add an unwanted copy.
In particular, it would prevent moving a temporary value into the function, if the value type prohibit implicit copies (e.g.: nsTArray).
So we should allow both copy and moves, by providing Resolve/Reject functions taking both 'const T&' and 'T&&'.
(Note that I won't just take forwarding references of any type, as this could lead to implicit conversions by bypassing the 'explicit' marker of the value type constructors, like in bug 1331137.)
| Comment hidden (mozreview-request) |
| Assignee | ||
Updated•8 years ago
|
Attachment #8829046 -
Flags: review?(nfroyd) → review?(jwwang)
Comment 2•8 years ago
|
||
(In reply to Gerald Squelart [:gerald] from comment #0)
> (Note that I won't just take forwarding references of any type, as this
> could lead to implicit conversions by bypassing the 'explicit' marker of the
> value type constructors, like in bug 1331137.)
Can you give an example? I can't see how this is possible in MozPromise.
| Comment hidden (typo) |
| Assignee | ||
Comment 4•8 years ago
|
||
Here's a little test, just to see how things build:
https://hg.mozilla.org/try/rev/2cb8bd56627b
The most interesting lines are:
> struct Other {};
> struct Explicit { Explicit() {}; explicit Explicit(const Other&) {} };
> typedef MozPromise<Explicit, Explicit, true> ExplicitPromise;
> MozPromiseHolder<ExplicitPromise> holder;
> holder.Resolve(Other{}, __func__);
The last line (and more similar ones under it) should fail to compile, because we are trying to build an ExplicitPromise::ResolveOrRejectValue::ResolveType (aka Explicit) from an 'Other{}', but the conversion constructor for that is marked 'explicit' and therefore should be ignored.
Here's a try with just that test on top of the current code (which takes ResolveType by value) :
https://treeherder.mozilla.org/#/jobs?repo=try&revision=42a6dbce20b1a345f67070b63a238bee914d4b9c
It fails as expected.
Here's a try with my proposed patch (which takes Resolve/RejectType by const&& or &&) :
https://treeherder.mozilla.org/#/jobs?repo=try&revision=c418b3a0e1aea2c5eb17b5b245919626d7d9f2be
It also fails for the same reason.
And this is a try with a patch where Resolve/Reject take forwarding references of any type:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=dfceedabb6b095bbd5121f5959bebf1cd918dd00
It doesn't fail anymore, meaning the 'explicit' for the conversion constructor was ignored!
(Well, there's a failure in the static analysis build, but it's happening later and is unrelated to our 'explicit' issue.)
Does that convince you?
Comment 5•8 years ago
|
||
Thanks for the detailed explanation.
Comment 6•8 years ago
|
||
| mozreview-review | ||
Comment on attachment 8829046 [details]
Bug 1332785 - Optimize MozPromiseHolder::Resolve and Reject -
https://reviewboard.mozilla.org/r/106246/#review107380
::: xpcom/threads/MozPromise.h:1028
(Diff revision 1)
> {
> if (!IsEmpty()) {
> Resolve(aResolveValue, aMethodName);
> }
> }
> + void ResolveIfExists(typename PromiseType::ResolveValueType&& aResolveValue,
I think we can use forwarding reference there because Resolve() takes either ResolveValueType&& or const ResolveValueType& and prevents implicit conversions.
Attachment #8829046 -
Flags: review?(jwwang) → review+
Pushed by gsquelart@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/839e34051bf9
Optimize MozPromiseHolder::Resolve and Reject - r=jwwang
| Assignee | ||
Comment 8•8 years ago
|
||
| mozreview-review-reply | ||
Comment on attachment 8829046 [details]
Bug 1332785 - Optimize MozPromiseHolder::Resolve and Reject -
https://reviewboard.mozilla.org/r/106246/#review107380
> I think we can use forwarding reference there because Resolve() takes either ResolveValueType&& or const ResolveValueType& and prevents implicit conversions.
(Sorry, forgot to publish this comment before pushing.)
Thank you for the review & suggestions.
You are correct that forwarding references would work in Resolve/RejectIfExists and would still prevent implicit conversions.
I even gave it a Try:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=8fccce0eb1b0eefd987806f55560e1cc03266fbe
As I feared, it makes it harder to spot the location of the error, as the compiler first points at Resolve/Reject inside MozPromise.h, instead of the call site, which is only mentioned 13 lines after the error message!
So I'll keep the patch as-is: I prefer a small maintenance cost in one location (with the duplicated const&/&& functions) as a trade-off for more obvious error messages whenever something wrong is done.
(There may be a way to use templated functions that only accept the correct type, but it'd be quite a bit of work to get right; we can do that in a future bug if really deemed useful...)
Comment 9•8 years ago
|
||
| bugherder | ||
Status: NEW → RESOLVED
Closed: 8 years ago
status-firefox54:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla54
You need to log in
before you can comment on or make changes to this bug.
Description
•