Bug 1525663 - Use return type deduction to remove complex decltype expressions r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 08 Feb 2019 10:34:02 +0000
changeset 516182 fdbb8bed650a29167dfe90105cdcbce4c7726c20
parent 516181 0ae4d42ca65b4e4e576353b97d3cb7b25ee30b68
child 516183 e3f24df9bdce4ae53ca3c671ca258a9c9095bcfb
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1525663
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1525663 - Use return type deduction to remove complex decltype expressions r=sfink
js/public/HeapAPI.h
js/public/Id.h
js/public/TraceKind.h
js/public/Value.h
js/src/frontend/EitherParser.h
js/src/gc/AllocKind.h
js/src/gc/HashUtil.h
js/src/gc/Statistics.cpp
js/src/vm/Compartment.h
js/src/vm/TaggedProto.h
js/src/wasm/AsmJS.cpp
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -342,19 +342,17 @@ class JS_FRIEND_API GCCellPtr {
   JS::TraceKind outOfLineKind() const;
 
   uintptr_t ptr;
 };
 
 // Unwraps the given GCCellPtr and calls the given functor with a template
 // argument of the actual type of the pointer.
 template <typename F, typename... Args>
-auto DispatchTyped(F f, GCCellPtr thing, Args&&... args)
-    -> decltype(f(static_cast<JSObject*>(nullptr),
-                  std::forward<Args>(args)...)) {
+auto DispatchTyped(F f, GCCellPtr thing, Args&&... args) {
   switch (thing.kind()) {
 #define JS_EXPAND_DEF(name, type, _) \
   case JS::TraceKind::name:          \
     return f(&thing.as<type>(), std::forward<Args>(args)...);
     JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
 #undef JS_EXPAND_DEF
     default:
       MOZ_CRASH("Invalid trace kind in DispatchTyped for GCCellPtr.");
--- a/js/public/Id.h
+++ b/js/public/Id.h
@@ -205,19 +205,17 @@ struct BarrierMethods<jsid> {
       js::gc::ExposeGCThingToActiveJS(JSID_TO_GCTHING(id));
     }
   }
 };
 
 // If the jsid is a GC pointer type, convert to that type and call |f| with
 // the pointer. If the jsid is not a GC type, calls F::defaultValue.
 template <typename F, typename... Args>
-auto DispatchTyped(F f, const jsid& id, Args&&... args)
-    -> decltype(f(static_cast<JSString*>(nullptr),
-                  std::forward<Args>(args)...)) {
+auto DispatchTyped(F f, const jsid& id, Args&&... args) {
   if (JSID_IS_STRING(id)) {
     return f(JSID_TO_STRING(id), std::forward<Args>(args)...);
   }
   if (JSID_IS_SYMBOL(id)) {
     return f(JSID_TO_SYMBOL(id), std::forward<Args>(args)...);
   }
   MOZ_ASSERT(!JSID_IS_GCTHING(id));
   return F::defaultValue(id);
--- a/js/public/TraceKind.h
+++ b/js/public/TraceKind.h
@@ -207,37 +207,33 @@ struct MapTypeToRootKind<JSFunction*> : 
 // The clang-cl front end defines _MSC_VER, but still requires the explicit
 // template declaration, so we must test for __clang__ here as well.
 #if (defined(_MSC_VER) && _MSC_VER < 1910) && !defined(__clang__)
 #  define JS_DEPENDENT_TEMPLATE_HINT
 #else
 #  define JS_DEPENDENT_TEMPLATE_HINT template
 #endif
 template <typename F, typename... Args>
-auto DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args)
-    -> decltype(f.JS_DEPENDENT_TEMPLATE_HINT operator()<JSObject>(
-        std::forward<Args>(args)...)) {
+auto DispatchTraceKindTyped(F f, JS::TraceKind traceKind, Args&&... args) {
   switch (traceKind) {
 #define JS_EXPAND_DEF(name, type, _)                      \
   case JS::TraceKind::name:                               \
     return f.JS_DEPENDENT_TEMPLATE_HINT operator()<type>( \
         std::forward<Args>(args)...);
     JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
 #undef JS_EXPAND_DEF
     default:
       MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped.");
   }
 }
 #undef JS_DEPENDENT_TEMPLATE_HINT
 
 template <typename F, typename... Args>
 auto DispatchTraceKindTyped(F f, void* thing, JS::TraceKind traceKind,
-                            Args&&... args)
-    -> decltype(f(static_cast<JSObject*>(nullptr),
-                  std::forward<Args>(args)...)) {
+                            Args&&... args) {
   switch (traceKind) {
 #define JS_EXPAND_DEF(name, type, _) \
   case JS::TraceKind::name:          \
     return f(static_cast<type*>(thing), std::forward<Args>(args)...);
     JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF);
 #undef JS_EXPAND_DEF
     default:
       MOZ_CRASH("Invalid trace kind in DispatchTraceKindTyped.");
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -1308,19 +1308,17 @@ class HeapBase<JS::Value, Wrapper>
   }
 };
 
 /*
  * If the Value is a GC pointer type, convert to that type and call |f| with
  * the pointer. If the Value is not a GC type, calls F::defaultValue.
  */
 template <typename F, typename... Args>
-auto DispatchTyped(F f, const JS::Value& val, Args&&... args)
-    -> decltype(f(static_cast<JSObject*>(nullptr),
-                  std::forward<Args>(args)...)) {
+auto DispatchTyped(F f, const JS::Value& val, Args&&... args) {
   if (val.isString()) {
     JSString* str = val.toString();
     MOZ_ASSERT(gc::IsCellPointerValid(str));
     return f(str, std::forward<Args>(args)...);
   }
   if (val.isObject()) {
     JSObject* obj = &val.toObject();
     MOZ_ASSERT(gc::IsCellPointerValid(obj));
--- a/js/src/frontend/EitherParser.h
+++ b/js/src/frontend/EitherParser.h
@@ -59,40 +59,40 @@ struct InvokeMemberFunction {
 
 template <class Parser>
 struct GetParser {
   static Parser* get(Parser* parser) { return parser; }
 };
 
 template <class Parser>
 struct GetTokenStream {
-  static auto get(Parser* parser) -> decltype(&parser->tokenStream) {
+  static auto get(Parser* parser) {
     return &parser->tokenStream;
   }
 };
 
 // Member function-computing templates.
 
 template <class Parser>
 struct ParserOptions {
-  static constexpr auto get() -> decltype(&Parser::options) {
+  static constexpr auto get() {
     return &Parser::options;
   }
 };
 
 template <class Parser>
 struct ParserNewObjectBox {
-  static constexpr auto get() -> decltype(&Parser::newObjectBox) {
+  static constexpr auto get() {
     return &Parser::newObjectBox;
   }
 };
 
 template <class TokenStream>
 struct TokenStreamComputeLineAndColumn {
-  static constexpr auto get() -> decltype(&TokenStream::computeLineAndColumn) {
+  static constexpr auto get() {
     return &TokenStream::computeLineAndColumn;
   }
 };
 
 // Generic matchers.
 
 struct ParseHandlerMatcher {
   template <class Parser>
--- a/js/src/gc/AllocKind.h
+++ b/js/src/gc/AllocKind.h
@@ -123,35 +123,30 @@ inline bool IsObjectAllocKind(AllocKind 
 }
 
 inline bool IsShapeAllocKind(AllocKind kind) {
   return kind == AllocKind::SHAPE || kind == AllocKind::ACCESSOR_SHAPE;
 }
 
 // Returns a sequence for use in a range-based for loop,
 // to iterate over all alloc kinds.
-inline decltype(mozilla::MakeEnumeratedRange(AllocKind::FIRST,
-                                             AllocKind::LIMIT))
-AllAllocKinds() {
+inline auto AllAllocKinds() {
   return mozilla::MakeEnumeratedRange(AllocKind::FIRST, AllocKind::LIMIT);
 }
 
 // Returns a sequence for use in a range-based for loop,
 // to iterate over all object alloc kinds.
-inline decltype(mozilla::MakeEnumeratedRange(AllocKind::OBJECT_FIRST,
-                                             AllocKind::OBJECT_LIMIT))
-ObjectAllocKinds() {
+inline auto ObjectAllocKinds() {
   return mozilla::MakeEnumeratedRange(AllocKind::OBJECT_FIRST,
                                       AllocKind::OBJECT_LIMIT);
 }
 
 // Returns a sequence for use in a range-based for loop,
 // to iterate over alloc kinds from |first| to |limit|, exclusive.
-inline decltype(mozilla::MakeEnumeratedRange(AllocKind::FIRST,
-                                             AllocKind::LIMIT))
+inline auto
 SomeAllocKinds(AllocKind first = AllocKind::FIRST,
                AllocKind limit = AllocKind::LIMIT) {
   MOZ_ASSERT(IsAllocKind(first), "|first| is not a valid AllocKind!");
   MOZ_ASSERT(IsAllocKind(limit), "|limit| is not a valid AllocKind!");
   return mozilla::MakeEnumeratedRange(first, limit);
 }
 
 // AllAllocKindArray<ValueType> gives an enumerated array of ValueTypes,
--- a/js/src/gc/HashUtil.h
+++ b/js/src/gc/HashUtil.h
@@ -68,19 +68,17 @@ struct DependentAddPtr {
 
   DependentAddPtr() = delete;
   DependentAddPtr(const DependentAddPtr&) = delete;
   DependentAddPtr& operator=(const DependentAddPtr&) = delete;
 };
 
 template <typename T, typename Lookup>
 inline auto MakeDependentAddPtr(const JSContext* cx, T& table,
-                                const Lookup& lookup)
-    -> DependentAddPtr<
-        typename mozilla::RemoveReference<decltype(table)>::Type> {
+                                const Lookup& lookup) {
   using Ptr =
       DependentAddPtr<typename mozilla::RemoveReference<decltype(table)>::Type>;
   return Ptr(cx, table, lookup);
 }
 
 }  // namespace js
 
 #endif
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -38,24 +38,21 @@ using mozilla::TimeStamp;
 /*
  * If this fails, then you can either delete this assertion and allow all
  * larger-numbered reasons to pile up in the last telemetry bucket, or switch
  * to GC_REASON_3 and bump the max value.
  */
 JS_STATIC_ASSERT(JS::GCReason::NUM_TELEMETRY_REASONS >=
                  JS::GCReason::NUM_REASONS);
 
-using PhaseKindRange =
-    decltype(mozilla::MakeEnumeratedRange(PhaseKind::FIRST, PhaseKind::LIMIT));
-
-static inline PhaseKindRange AllPhaseKinds() {
+static inline auto AllPhaseKinds() {
   return mozilla::MakeEnumeratedRange(PhaseKind::FIRST, PhaseKind::LIMIT);
 }
 
-static inline PhaseKindRange MajorGCPhaseKinds() {
+static inline auto MajorGCPhaseKinds() {
   return mozilla::MakeEnumeratedRange(PhaseKind::GC_BEGIN,
                                       PhaseKind(size_t(PhaseKind::GC_END) + 1));
 }
 
 const char* js::gcstats::ExplainInvocationKind(JSGCInvocationKind gckind) {
   MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK);
   if (gckind == GC_NORMAL) {
     return "Normal";
@@ -183,18 +180,17 @@ Phase Statistics::lookupChildPhase(Phase
     MOZ_CRASH_UNSAFE_PRINTF(
         "Child phase kind %u not found under current phase kind %u",
         unsigned(phaseKind), unsigned(currentPhaseKind()));
   }
 
   return phase;
 }
 
-inline decltype(mozilla::MakeEnumeratedRange(Phase::FIRST, Phase::LIMIT))
-AllPhases() {
+inline auto AllPhases() {
   return mozilla::MakeEnumeratedRange(Phase::FIRST, Phase::LIMIT);
 }
 
 void Statistics::gcDuration(TimeDuration* total, TimeDuration* maxPause) const {
   *total = *maxPause = 0;
   for (auto& slice : slices_) {
     *total += slice.duration();
     if (slice.duration() > *maxPause) {
--- a/js/src/vm/Compartment.h
+++ b/js/src/vm/Compartment.h
@@ -82,39 +82,37 @@ class CrossCompartmentKey {
     return wrapped.is<T>();
   }
   template <typename T>
   const T& as() const {
     return wrapped.as<T>();
   }
 
   template <typename F>
-  auto applyToWrapped(F f) -> decltype(f(static_cast<JSObject**>(nullptr))) {
-    using ReturnType = decltype(f(static_cast<JSObject**>(nullptr)));
+  auto applyToWrapped(F f) {
     struct WrappedMatcher {
       F f_;
       explicit WrappedMatcher(F f) : f_(f) {}
-      ReturnType match(JSObject*& obj) { return f_(&obj); }
-      ReturnType match(JSString*& str) { return f_(&str); }
-      ReturnType match(DebuggerAndScript& tpl) {
+      auto match(JSObject*& obj) { return f_(&obj); }
+      auto match(JSString*& str) { return f_(&str); }
+      auto match(DebuggerAndScript& tpl) {
         return f_(&mozilla::Get<1>(tpl));
       }
-      ReturnType match(DebuggerAndLazyScript& tpl) {
+      auto match(DebuggerAndLazyScript& tpl) {
         return f_(&mozilla::Get<1>(tpl));
       }
-      ReturnType match(DebuggerAndObject& tpl) {
+      auto match(DebuggerAndObject& tpl) {
         return f_(&mozilla::Get<1>(tpl));
       }
     } matcher(f);
     return wrapped.match(matcher);
   }
 
   template <typename F>
-  auto applyToDebugger(F f)
-      -> decltype(f(static_cast<NativeObject**>(nullptr))) {
+  auto applyToDebugger(F f) {
     using ReturnType = decltype(f(static_cast<NativeObject**>(nullptr)));
     struct DebuggerMatcher {
       F f_;
       explicit DebuggerMatcher(F f) : f_(f) {}
       ReturnType match(JSObject*& obj) { return ReturnType(); }
       ReturnType match(JSString*& str) { return ReturnType(); }
       ReturnType match(DebuggerAndScript& tpl) {
         return f_(&mozilla::Get<0>(tpl));
--- a/js/src/vm/TaggedProto.h
+++ b/js/src/vm/TaggedProto.h
@@ -126,19 +126,17 @@ class WrappedPtrOperations<TaggedProto, 
   JSObject* raw() const { return value().raw(); }
   HashNumber hashCode() const { return value().hashCode(); }
   uint64_t uniqueId() const { return value().uniqueId(); }
 };
 
 // If the TaggedProto is a JSObject pointer, convert to that type and call |f|
 // with the pointer. If the TaggedProto is lazy, calls F::defaultValue.
 template <typename F, typename... Args>
-auto DispatchTyped(F f, const TaggedProto& proto, Args&&... args)
-    -> decltype(f(static_cast<JSObject*>(nullptr),
-                  std::forward<Args>(args)...)) {
+auto DispatchTyped(F f, const TaggedProto& proto, Args&&... args) {
   if (proto.isObject()) {
     return f(proto.toObject(), std::forward<Args>(args)...);
   }
   return F::defaultValue(proto);
 }
 
 // Since JSObject pointers are either nullptr or a valid object and since the
 // object layout of TaggedProto is identical to a bare object pointer, we can
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -1976,17 +1976,17 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED Modu
       return false;
     }
 
     return true;
   }
 
   AsmJSParser<Unit>& parser() const { return parser_; }
 
-  auto tokenStream() const -> decltype(parser_.tokenStream)& {
+  auto& tokenStream() const {
     return parser_.tokenStream;
   }
 
  public:
   bool addFuncDef(PropertyName* name, uint32_t firstUse, FuncType&& sig,
                   Func** func) {
     uint32_t sigIndex;
     if (!declareSig(std::move(sig), &sigIndex)) {