From 1fe18b25cfba6a2f8ee5127af053ee46d58e9b21 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Tue, 15 Dec 2015 07:45:22 -0800 Subject: [PATCH] Bug 1232686 - Use decltype to infer Variant::match return type; r=fitzgen --HG-- extra : rebase_source : 38f280cc3014b2285a79e377f1fa8edf4c5f4661 --- devtools/shared/heapsnapshot/HeapSnapshot.cpp | 13 ------- js/src/gc/Tracer.cpp | 5 +-- js/src/jscompartment.cpp | 7 +--- js/src/jscompartment.h | 24 ++++++------ js/src/jsfriendapi.cpp | 3 +- js/src/jsgc.cpp | 4 +- js/src/jsscript.cpp | 26 +++++-------- js/src/jsscript.h | 8 ++-- js/src/vm/SavedStacks.cpp | 2 - js/src/vm/UbiNode.cpp | 4 -- mfbt/Variant.h | 37 +++++++++++-------- mfbt/tests/TestVariant.cpp | 2 - 12 files changed, 50 insertions(+), 85 deletions(-) diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp index d8810f1a6b4a..e2aa40e9870e 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp +++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp @@ -137,8 +137,6 @@ parseMessage(ZeroCopyInputStream& stream, uint32_t sizeOfMessage, MessageType& m template struct GetOrInternStringMatcher { - using ReturnType = const CharT*; - InternedStringSet& internedStrings; explicit GetOrInternStringMatcher(InternedStringSet& strings) : internedStrings(strings) { } @@ -860,8 +858,6 @@ class TwoByteString : public Variant bool match(const T& t) { return t != nullptr; } }; struct LengthMatcher { - using ReturnType = size_t; - size_t match(JSAtom* atom) { MOZ_ASSERT(atom); JS::ubi::AtomOrTwoByteChars s(atom); @@ -902,8 +894,6 @@ class TwoByteString : public Variant destination; size_t maxLength; @@ -985,8 +975,6 @@ struct TwoByteString::HashPolicy { using Lookup = TwoByteString; struct HashingMatcher { - using ReturnType = js::HashNumber; - js::HashNumber match(const JSAtom* atom) { return js::DefaultHasher::hash(atom); } @@ -1009,7 +997,6 @@ struct TwoByteString::HashPolicy { } struct EqualityMatcher { - using ReturnType = bool; const TwoByteString& rhs; explicit EqualityMatcher(const TwoByteString& rhs) : rhs(rhs) { } diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp index d95b94dde1e2..21d19e28743a 100644 --- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -133,9 +133,8 @@ struct TraceIncomingFunctor { TraceIncomingFunctor(JSTracer* trc, const JS::CompartmentSet& compartments) : trc_(trc), compartments_(compartments) {} - using ReturnType = void; template - ReturnType operator()(T tp) { + void operator()(T tp) { if (!compartments_.has((*tp)->compartment())) return; TraceManuallyBarrieredEdge(trc_, tp, "cross-compartment wrapper"); @@ -143,7 +142,7 @@ struct TraceIncomingFunctor { // StringWrappers are just used to avoid copying strings // across zones multiple times, and don't hold a strong // reference. - ReturnType operator()(JSString** tp) {} + void operator()(JSString** tp) {} }; } // namespace (anonymous) diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index a4a26fed3440..4d16c35b750e 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -227,7 +227,6 @@ class WrapperMapRef : public BufferableRef const char* name_; TraceFunctor(JSTracer *trc, const char* name) : trc_(trc), name_(name) {} - using ReturnType = void; template void operator()(T* t) { TraceManuallyBarrieredEdge(trc_, t, name_); } }; void trace(JSTracer* trc) override { @@ -250,7 +249,6 @@ class WrapperMapRef : public BufferableRef #ifdef JSGC_HASH_TABLE_CHECKS namespace { struct CheckGCThingAfterMovingGCFunctor { - using ReturnType = void; template void operator()(T* t) { CheckGCThingAfterMovingGC(*t); } }; } // namespace (anonymous) @@ -275,7 +273,6 @@ JSCompartment::checkWrapperMapAfterMovingGC() namespace { struct IsInsideNurseryFunctor { - using ReturnType = bool; template bool operator()(T tp) { return IsInsideNursery(*tp); } }; } // namespace (anonymous) @@ -775,11 +772,9 @@ struct TraceRootFunctor { JSTracer* trc; const char* name; TraceRootFunctor(JSTracer* trc, const char* name) : trc(trc), name(name) {} - using ReturnType = void; - template ReturnType operator()(T* t) { return TraceRoot(trc, t, name); } + template void operator()(T* t) { return TraceRoot(trc, t, name); } }; struct NeedsSweepUnbarrieredFunctor { - using ReturnType = bool; template bool operator()(T* t) const { return IsAboutToBeFinalizedUnbarriered(t); } }; } // namespace (anonymous) diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index b768c728f896..e2dc17fac206 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -106,9 +106,9 @@ struct CrossCompartmentKey template const T& as() const { return wrapped.as(); } template - auto applyToWrapped(F f) -> typename F::ReturnType { + auto applyToWrapped(F f) -> decltype(f(static_cast(nullptr))) { + using ReturnType = decltype(f(static_cast(nullptr))); struct WrappedMatcher { - using ReturnType = typename F::ReturnType; F f_; explicit WrappedMatcher(F f) : f_(f) {} ReturnType match(JSObject*& obj) { return f_(&obj); } @@ -120,9 +120,9 @@ struct CrossCompartmentKey } template - auto applyToDebugger(F f) -> typename F::ReturnType { + auto applyToDebugger(F f) -> decltype(f(static_cast(nullptr))) { + using ReturnType = decltype(f(static_cast(nullptr))); struct DebuggerMatcher { - using ReturnType = typename F::ReturnType; F f_; explicit DebuggerMatcher(F f) : f_(f) {} ReturnType match(JSObject*& obj) { return ReturnType(); } @@ -137,10 +137,9 @@ struct CrossCompartmentKey // JSString* key. JSCompartment* compartment() { struct GetCompartmentFunctor { - using ReturnType = JSCompartment*; - ReturnType operator()(JSObject** tp) const { return (*tp)->compartment(); } - ReturnType operator()(JSScript** tp) const { return (*tp)->compartment(); } - ReturnType operator()(JSString** tp) const { + JSCompartment* operator()(JSObject** tp) const { return (*tp)->compartment(); } + JSCompartment* operator()(JSScript** tp) const { return (*tp)->compartment(); } + JSCompartment* operator()(JSString** tp) const { MOZ_CRASH("invalid ccw key"); return nullptr; } }; @@ -150,14 +149,13 @@ struct CrossCompartmentKey struct Hasher : public DefaultHasher { struct HashFunctor { - using ReturnType = HashNumber; - ReturnType match(JSObject* obj) { return DefaultHasher::hash(obj); } - ReturnType match(JSString* str) { return DefaultHasher::hash(str); } - ReturnType match(const DebuggerAndScript& tpl) { + HashNumber match(JSObject* obj) { return DefaultHasher::hash(obj); } + HashNumber match(JSString* str) { return DefaultHasher::hash(str); } + HashNumber match(const DebuggerAndScript& tpl) { return DefaultHasher::hash(mozilla::Get<0>(tpl)) ^ DefaultHasher::hash(mozilla::Get<1>(tpl)); } - ReturnType match(const DebuggerAndObject& tpl) { + HashNumber match(const DebuggerAndObject& tpl) { return DefaultHasher::hash(mozilla::Get<0>(tpl)) ^ DefaultHasher::hash(mozilla::Get<1>(tpl)) ^ (mozilla::Get<2>(tpl) << 5); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 8082b6d7169f..74f6610cd34a 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -614,9 +614,8 @@ struct VisitGrayCallbackFunctor { : callback_(callback), closure_(closure) {} - using ReturnType = void; template - ReturnType operator()(T tp) const { + void operator()(T tp) const { if ((*tp)->isTenured() && (*tp)->asTenured().isMarked(gc::GRAY)) callback_(closure_, JS::GCCellPtr(*tp)); } diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index ad7333adf21a..a8ad8a085201 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3671,7 +3671,6 @@ struct IsDestComparatorFunctor { JS::GCCellPtr dst_; explicit IsDestComparatorFunctor(JS::GCCellPtr dst) : dst_(dst) {} - using ReturnType = bool; template bool operator()(T* t) { return (*t) == dst_.asCell(); } }; } // namespace (anonymous) @@ -4379,9 +4378,8 @@ struct AddOutgoingEdgeFunctor { : needsEdge_(needsEdge), finder_(finder) {} - using ReturnType = void; template - ReturnType operator()(T tp) { + void operator()(T tp) { TenuredCell& other = (*tp)->asTenured(); /* diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index d5cfa1f697be..ac1f8ee14e1c 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1861,8 +1861,6 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde { struct CharsMatcher { - using ReturnType = const char16_t*; - JSContext* cx; ScriptSource& ss; UncompressedSourceCache::AutoHoldEntry& holder; @@ -1874,11 +1872,11 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde , holder(holder) { } - ReturnType match(Uncompressed& u) { + const char16_t* match(Uncompressed& u) { return u.string.chars(); } - ReturnType match(Compressed& c) { + const char16_t* match(Compressed& c) { if (const char16_t* decompressed = cx->caches.uncompressedSourceCache.lookup(&ss, holder)) return decompressed; @@ -1916,7 +1914,7 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde return ss.data.as().string.chars(); } - ReturnType ret = decompressed.get(); + const char16_t* ret = decompressed.get(); if (!cx->caches.uncompressedSourceCache.put(&ss, Move(decompressed), holder)) { JS_ReportOutOfMemory(cx); return nullptr; @@ -1924,7 +1922,7 @@ ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holde return ret; } - ReturnType match(Missing&) { + const char16_t* match(Missing&) { MOZ_CRASH("ScriptSource::chars() on ScriptSource with SourceType = Missing"); return nullptr; } @@ -2147,17 +2145,15 @@ ScriptSource::performXDR(XDRState* xdr) { struct CompressedLengthMatcher { - using ReturnType = size_t; - - ReturnType match(Uncompressed&) { + size_t match(Uncompressed&) { return 0; } - ReturnType match(Compressed& c) { + size_t match(Compressed& c) { return c.raw.length(); } - ReturnType match(Missing&) { + size_t match(Missing&) { MOZ_CRASH("Missing source data in ScriptSource::performXDR"); return 0; } @@ -2165,17 +2161,15 @@ ScriptSource::performXDR(XDRState* xdr) struct RawDataMatcher { - using ReturnType = void*; - - ReturnType match(Uncompressed& u) { + void* match(Uncompressed& u) { return (void*) u.string.chars(); } - ReturnType match(Compressed& c) { + void* match(Compressed& c) { return (void*) c.raw.chars(); } - ReturnType match(Missing&) { + void* match(Missing&) { MOZ_CRASH("Missing source data in ScriptSource::performXDR"); return nullptr; } diff --git a/js/src/jsscript.h b/js/src/jsscript.h index d978ae64c7e0..69a6568938bd 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -739,17 +739,15 @@ class ScriptSource size_t length() const { struct LengthMatcher { - using ReturnType = size_t; - - ReturnType match(const Uncompressed& u) { + size_t match(const Uncompressed& u) { return u.string.length(); } - ReturnType match(const Compressed& c) { + size_t match(const Compressed& c) { return c.uncompressedLength; } - ReturnType match(const Missing& m) { + size_t match(const Missing& m) { MOZ_CRASH("ScriptSource::length on a missing source"); return 0; } diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index 98632da95cf0..7fb9fc8f48e8 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -1565,8 +1565,6 @@ ConcreteStackFrame::constructSavedFrameStack(JSContext* cx, // `JS::ubi::AtomOrTwoByteChars` string to a `JSAtom*`. struct MOZ_STACK_CLASS AtomizingMatcher { - using ReturnType = JSAtom*; - JSContext* cx; size_t length; diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp index d4a9b71eb7fd..15cc8eda925b 100644 --- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -55,8 +55,6 @@ using JS::ubi::TracerConcreteWithCompartment; struct CopyToBufferMatcher { - using ReturnType = size_t; - RangedPtr destination; size_t maxLength; @@ -108,8 +106,6 @@ JS::ubi::AtomOrTwoByteChars::copyToBuffer(RangedPtr destination, size_ struct LengthMatcher { - using ReturnType = size_t; - size_t match(JSAtom* atom) { diff --git a/mfbt/Variant.h b/mfbt/Variant.h index 68ffeed2da47..31bda267eab3 100644 --- a/mfbt/Variant.h +++ b/mfbt/Variant.h @@ -169,10 +169,11 @@ struct VariantImplementation { return aLhs.template as() == aRhs.template as(); } - template::Type::ReturnType> - static ReturnType - match(Matcher&& aMatcher, ConcreteVariant& aV) { + template + static auto + match(Matcher&& aMatcher, ConcreteVariant& aV) + -> decltype(aMatcher.match(aV.template as())) + { return aMatcher.match(aV.template as()); } }; @@ -226,10 +227,10 @@ struct VariantImplementation } } - template::Type::ReturnType> - static ReturnType + template + static auto match(Matcher&& aMatcher, ConcreteVariant& aV) + -> decltype(aMatcher.match(aV.template as())) { if (aV.template is()) { return aMatcher.match(aV.template as()); @@ -370,11 +371,11 @@ struct AsVariantTemporary * // Good! * struct FooMatcher * { - * using ReturnType = char*; - * ReturnType match(A& a) { ... } - * ReturnType match(B& b) { ... } - * ReturnType match(C& c) { ... } - * ReturnType match(D& d) { ... } // Compile-time error to forget D! + * // The return type of all matchers must be identical. + * char* match(A& a) { ... } + * char* match(B& b) { ... } + * char* match(C& c) { ... } + * char* match(D& d) { ... } // Compile-time error to forget D! * } * char* foo(Variant& v) { * return v.match(FooMatcher()); @@ -558,15 +559,19 @@ public: /** Match on an immutable const reference. */ template - typename RemoveReference::Type::ReturnType - match(Matcher&& aMatcher) const { + auto + match(Matcher&& aMatcher) const + -> decltype(Impl::match(aMatcher, *this)) + { return Impl::match(aMatcher, *this); } /** Match on a mutable non-const reference. */ template - typename RemoveReference::Type::ReturnType - match(Matcher&& aMatcher) { + auto + match(Matcher&& aMatcher) + -> decltype(Impl::match(aMatcher, *this)) + { return Impl::match(aMatcher, *this); } }; diff --git a/mfbt/tests/TestVariant.cpp b/mfbt/tests/TestVariant.cpp index 4f4e8a938c4f..d47df70cb515 100644 --- a/mfbt/tests/TestVariant.cpp +++ b/mfbt/tests/TestVariant.cpp @@ -129,8 +129,6 @@ struct Describer static const char* medium; static const char* big; - using ReturnType = const char*; - const char* match(const uint8_t&) { return little; } const char* match(const uint32_t&) { return medium; } const char* match(const uint64_t&) { return big; }