Bug 1443367 - Rework MakeNotNull to build with VS 2017 15.6 - r=njn
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 06 Mar 2018 20:27:27 +1100
changeset 461747 b9a8c5d66bb91065962537c56f4759b8f29b47a1
parent 461746 0ca4ef640c8b7d1a25e0dcaf80d0410b807b64d5
child 461748 32c3c20fd489fde2b9c90dfa94579896b6822bbf
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1443367
milestone60.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 1443367 - Rework MakeNotNull to build with VS 2017 15.6 - r=njn VS 2017 15.6 (March 2018) doesn't seem to understand `*DeclVal<SharedFontList*>()` anymore. To work around this issue, the pointed-to type is now extracted in a separate struct, for which we provide a specialization for raw pointers, so we don't encounter the shaky `*DeclVal<T*>()` statement anymore. MozReview-Commit-ID: FuslManbfdB
mfbt/NotNull.h
--- a/mfbt/NotNull.h
+++ b/mfbt/NotNull.h
@@ -150,27 +150,57 @@ template <typename T>
 NotNull<T>
 WrapNotNull(const T aBasePtr)
 {
   NotNull<T> notNull(aBasePtr);
   MOZ_RELEASE_ASSERT(aBasePtr);
   return notNull;
 }
 
+namespace detail {
+
+// Extract the pointed-to type from a pointer type (be it raw or smart).
+// The default implementation uses the dereferencing operator of the pointer
+// type to find what it's pointing to.
+template<typename Pointer>
+struct PointedTo
+{
+  // Remove the reference that dereferencing operators may return.
+  using Type = typename RemoveReference<decltype(*DeclVal<Pointer>())>::Type;
+  using NonConstType = typename RemoveConst<Type>::Type;
+};
+
+// Specializations for raw pointers.
+// This is especially required because VS 2017 15.6 (March 2018) started
+// rejecting the above `decltype(*DeclVal<Pointer>())` trick for raw pointers.
+// See bug 1443367.
+template<typename T>
+struct PointedTo<T*>
+{
+  using Type = T;
+  using NonConstType = T;
+};
+
+template<typename T>
+struct PointedTo<const T*>
+{
+  using Type = const T;
+  using NonConstType = T;
+};
+
+} // namespace detail
+
 // Allocate an object with infallible new, and wrap its pointer in NotNull.
 // |MakeNotNull<Ptr<Ob>>(args...)| will run |new Ob(args...)|
 // and return NotNull<Ptr<Ob>>.
 template<typename T, typename... Args>
 NotNull<T>
 MakeNotNull(Args&&... aArgs)
 {
-  // Extract the pointee type from what T's dereferencing operator returns
-  // (which could be a reference to a const type).
-  using Pointee = typename mozilla::RemoveConst<
-    typename mozilla::RemoveReference<decltype(*DeclVal<T>())>::Type>::Type;
+  using Pointee = typename detail::PointedTo<T>::NonConstType;
   static_assert(!IsArray<Pointee>::value,
                 "MakeNotNull cannot construct an array");
   return NotNull<T>(new Pointee(Forward<Args>(aArgs)...));
 }
 
 // Compare two NotNulls.
 template <typename T, typename U>
 inline bool