Merge pull request #13366 from davezarzycki/nfc_repack_misc_typebase_bits

diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 15b7ff1..a06a0d1 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -285,6 +285,15 @@
   };
   NUMBITS(ErrorType, NumTypeBaseBits + 1);
 
+  struct ParenTypeBitfields {
+    unsigned : NumTypeBaseBits;
+
+    /// Whether there is an original type.
+    enum { NumFlagBits = 5 };
+    unsigned Flags : NumFlagBits;
+  };
+  NUMBITS(ParenType, NumTypeBaseBits + ParenTypeBitfields::NumFlagBits);
+
   struct AnyFunctionTypeBitfields {
     unsigned : NumTypeBaseBits;
 
@@ -309,7 +318,14 @@
     unsigned : NumTypeBaseBits;
 
     /// \brief The unique number assigned to this type variable.
-    uint64_t ID : 64 - NumTypeBaseBits;
+    uint64_t ID : 32 - NumTypeBaseBits;
+
+    /// Type variable options.
+    unsigned Options : 3;
+
+    ///  Index into the list of type variables, as used by the
+    ///  constraint graph.
+    unsigned GraphIndex : 29;
   };
   NUMBITS(TypeVariableType, 64);
 
@@ -353,6 +369,7 @@
   union {
     TypeBaseBitfields TypeBaseBits;
     ErrorTypeBitfields ErrorTypeBits;
+    ParenTypeBitfields ParenTypeBits;
     AnyFunctionTypeBitfields AnyFunctionTypeBits;
     TypeVariableTypeBitfields TypeVariableTypeBits;
     ArchetypeTypeBitfields ArchetypeTypeBits;
@@ -1415,6 +1432,9 @@
 
 public:
   ParameterTypeFlags() = default;
+  static ParameterTypeFlags fromRaw(uint8_t raw) {
+    return ParameterTypeFlags(OptionSet<ParameterFlags>(raw));
+  }
 
   ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping, bool inOut, bool shared)
       : value((variadic ? Variadic : 0) |
@@ -1465,7 +1485,6 @@
 /// ParenType - A paren type is a type that's been written in parentheses.
 class ParenType : public TypeBase {
   Type UnderlyingType;
-  ParameterTypeFlags parameterFlags;
 
   friend class ASTContext;
   
@@ -1482,7 +1501,9 @@
   TypeBase *getSinglyDesugaredType();
 
   /// Get the parameter flags
-  ParameterTypeFlags getParameterFlags() const { return parameterFlags; }
+  ParameterTypeFlags getParameterFlags() const {
+    return ParameterTypeFlags::fromRaw(ParenTypeBits.Flags);
+  }
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const TypeBase *T) {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index f48268c..ad95b8d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1314,8 +1314,8 @@
   : TypeBase(TypeKind::Paren, nullptr, properties),
     UnderlyingType(flags.isInOut()
                      ? InOutType::get(baseType)
-                     : baseType),
-    parameterFlags(flags) {
+                     : baseType) {
+  ParenTypeBits.Flags = flags.toRaw();
   if (flags.isInOut())
     assert(!baseType->is<InOutType>() && "caller did not pass a base type");
   if (baseType->is<InOutType>())
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 506a3d3..d4aa233 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -177,9 +177,6 @@
 /// to, what specific types it might be and, eventually, the fixed type to
 /// which it is assigned.
 class TypeVariableType::Implementation {
-  /// Type variable options.
-  unsigned Options : 3;
-
   /// \brief The locator that describes where this type variable was generated.
   constraints::ConstraintLocator *locator;
 
@@ -191,37 +188,9 @@
   /// The corresponding node in the constraint graph.
   constraints::ConstraintGraphNode *GraphNode = nullptr;
 
-  ///  Index into the list of type variables, as used by the
-  ///  constraint graph.
-  unsigned GraphIndex;
-
   friend class constraints::SavedTypeVariableBinding;
 
 public:
-  explicit Implementation(constraints::ConstraintLocator *locator,
-                          unsigned options)
-    : Options(options), locator(locator),
-      ParentOrFixed(getTypeVariable()) { }
-
-  /// \brief Retrieve the unique ID corresponding to this type variable.
-  unsigned getID() const { return getTypeVariable()->getID(); }
-
-  /// Whether this type variable can bind to an lvalue type.
-  bool canBindToLValue() const { return Options & TVO_CanBindToLValue; }
-
-  /// Whether this type variable can bind to an inout type.
-  bool canBindToInOut() const { return Options & TVO_CanBindToInOut; }
-
-  /// Whether this type variable prefers a subtype binding over a supertype
-  /// binding.
-  bool prefersSubtypeBinding() const {
-    return Options & TVO_PrefersSubtypeBinding;
-  }
-
-  bool mustBeMaterializable() const {
-    return !(Options & TVO_CanBindToInOut) && !(Options & TVO_CanBindToLValue);
-  }
-
   /// \brief Retrieve the type variable associated with this implementation.
   TypeVariableType *getTypeVariable() {
     return reinterpret_cast<TypeVariableType *>(this) - 1;
@@ -232,6 +201,42 @@
     return reinterpret_cast<const TypeVariableType *>(this) - 1;
   }
 
+  explicit Implementation(constraints::ConstraintLocator *locator,
+                          unsigned options)
+    : locator(locator), ParentOrFixed(getTypeVariable()) {
+    getTypeVariable()->TypeVariableTypeBits.Options = options;
+  }
+
+  /// \brief Retrieve the unique ID corresponding to this type variable.
+  unsigned getID() const { return getTypeVariable()->getID(); }
+
+  unsigned getRawOptions() const {
+    return getTypeVariable()->TypeVariableTypeBits.Options;
+  }
+
+  void setRawOptions(unsigned bits) {
+    getTypeVariable()->TypeVariableTypeBits.Options = bits;
+    assert(getTypeVariable()->TypeVariableTypeBits.Options == bits
+           && "Trucation");
+  }
+
+  /// Whether this type variable can bind to an lvalue type.
+  bool canBindToLValue() const { return getRawOptions() & TVO_CanBindToLValue; }
+
+  /// Whether this type variable can bind to an inout type.
+  bool canBindToInOut() const { return getRawOptions() & TVO_CanBindToInOut; }
+
+  /// Whether this type variable prefers a subtype binding over a supertype
+  /// binding.
+  bool prefersSubtypeBinding() const {
+    return getRawOptions() & TVO_PrefersSubtypeBinding;
+  }
+
+  bool mustBeMaterializable() const {
+    return !(getRawOptions() & TVO_CanBindToInOut) &&
+           !(getRawOptions() & TVO_CanBindToLValue);
+  }
+
   /// Retrieve the corresponding node in the constraint graph.
   constraints::ConstraintGraphNode *getGraphNode() const { return GraphNode; }
 
@@ -243,11 +248,13 @@
   /// Retrieve the index into the constraint graph's list of type variables.
   unsigned getGraphIndex() const { 
     assert(GraphNode && "Graph node isn't set");
-    return GraphIndex; 
+    return getTypeVariable()->TypeVariableTypeBits.GraphIndex; 
   }
 
   /// Set the index into the constraint graph's list of type variables.
-  void setGraphIndex(unsigned newIndex) { GraphIndex = newIndex; }
+  void setGraphIndex(unsigned newIndex) {
+    getTypeVariable()->TypeVariableTypeBits.GraphIndex = newIndex;
+  }
   
   /// \brief Check whether this type variable either has a representative that
   /// is not itself or has a fixed type binding.
@@ -339,8 +346,8 @@
     if (!mustBeMaterializable() && otherRep->getImpl().mustBeMaterializable()) {
       if (record)
         recordBinding(*record);
-      Options &= ~TVO_CanBindToLValue;
-      Options &= ~TVO_CanBindToInOut;
+      getTypeVariable()->TypeVariableTypeBits.Options &= ~TVO_CanBindToLValue;
+      getTypeVariable()->TypeVariableTypeBits.Options &= ~TVO_CanBindToInOut;
     }
   }
 
@@ -381,8 +388,10 @@
     if (!rep->getImpl().mustBeMaterializable()) {
       if (record)
         rep->getImpl().recordBinding(*record);
-      rep->getImpl().Options &= ~TVO_CanBindToLValue;
-      rep->getImpl().Options &= ~TVO_CanBindToInOut;
+      rep->getImpl().getTypeVariable()->TypeVariableTypeBits.Options
+        &= ~TVO_CanBindToLValue;
+      rep->getImpl().getTypeVariable()->TypeVariableTypeBits.Options
+        &= ~TVO_CanBindToInOut;
     }
   }
 
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index ab4641d..170c01d 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -61,12 +61,12 @@
 }
 
 SavedTypeVariableBinding::SavedTypeVariableBinding(TypeVariableType *typeVar)
-  : TypeVarAndOptions(typeVar, typeVar->getImpl().Options),
+  : TypeVarAndOptions(typeVar, typeVar->getImpl().getRawOptions()),
     ParentOrFixed(typeVar->getImpl().ParentOrFixed) { }
 
 void SavedTypeVariableBinding::restore() {
   auto *typeVar = getTypeVariable();
-  typeVar->getImpl().Options = getOptions();
+  typeVar->getImpl().setRawOptions(getOptions());
   typeVar->getImpl().ParentOrFixed = ParentOrFixed;
 }