Backed out 4 changesets (bug 1559814) for causing bustages. CLOSED TREE
authorMihai Alexandru Michis <malexandru@mozilla.com>
Thu, 27 Jun 2019 00:04:50 +0300
changeset 543059 c95bc282ae96b48c3249b3d4942b7c15fbda5a58
parent 543058 61aa0e6727f5495cde716c89dde7dd47d0e80b4d
child 543060 0581a4a4bdf3d445727ed432256f39082ad5f794
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1559814
milestone69.0a1
backs out11ec9de590766855f98bdc3fbe839c0a1209c8e2
fec03c5d3661b2137566bdab78a3314221eb057f
62f9d89fb827af89e810b728a54c2bb2024085e4
362d9435ca4e6d90ee16fe2c6a9d620a03c03e90
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
Backed out 4 changesets (bug 1559814) for causing bustages. CLOSED TREE Backed out changeset 11ec9de59076 (bug 1559814) Backed out changeset fec03c5d3661 (bug 1559814) Backed out changeset 62f9d89fb827 (bug 1559814) Backed out changeset 362d9435ca4e (bug 1559814)
layout/generic/nsGridContainerFrame.cpp
layout/generic/nsGridContainerFrame.h
layout/style/ServoBindings.toml
layout/style/ServoStyleConstsInlines.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
servo/components/servo_arc/lib.rs
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/shorthands/position.mako.rs
servo/components/style/rule_tree/mod.rs
servo/components/style/values/animated/grid.rs
servo/components/style/values/computed/mod.rs
servo/components/style/values/generics/grid.rs
servo/components/style/values/specified/mod.rs
servo/ports/geckolib/cbindgen.toml
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -34,26 +34,23 @@
 #include "nsPresContext.h"
 #include "nsReadableUtils.h"
 #include "nsTableWrapperFrame.h"
 
 using namespace mozilla;
 
 typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
 typedef nsGridContainerFrame::TrackSize TrackSize;
+const uint32_t nsGridContainerFrame::kTranslatedMaxLine =
+    uint32_t(nsStyleGridLine::kMaxLine - nsStyleGridLine::kMinLine);
+const uint32_t nsGridContainerFrame::kAutoLine = kTranslatedMaxLine + 3457U;
 typedef nsTHashtable<nsPtrHashKey<nsIFrame>> FrameHashtable;
 typedef mozilla::CSSAlignUtils::AlignJustifyFlags AlignJustifyFlags;
 typedef nsLayoutUtils::IntrinsicISizeType IntrinsicISizeType;
 
-static const int32_t kMaxLine = StyleMAX_GRID_LINE;
-static const int32_t kMinLine = StyleMIN_GRID_LINE;
-// The maximum line number, in the zero-based translated grid.
-static const uint32_t kTranslatedMaxLine = uint32_t(kMaxLine - kMinLine);
-static const uint32_t kAutoLine = kTranslatedMaxLine + 3457U;
-
 static const nsFrameState kIsSubgridBits =
     (NS_STATE_GRID_IS_COL_SUBGRID | NS_STATE_GRID_IS_ROW_SUBGRID);
 
 // https://drafts.csswg.org/css-sizing/#constraints
 enum class SizingConstraint {
   MinContent,   // sizing under min-content constraint
   MaxContent,   // sizing under max-content constraint
   NoConstraint  // no constraint, used during Reflow
@@ -383,34 +380,39 @@ static void MergeSortedFrameListsFor(nsF
  * i.e. the invariant is slightly relaxed compared to normal flow items.
  */
 struct nsGridContainerFrame::LineRange {
   LineRange(int32_t aStart, int32_t aEnd)
       : mUntranslatedStart(aStart), mUntranslatedEnd(aEnd) {
 #ifdef DEBUG
     if (!IsAutoAuto()) {
       if (IsAuto()) {
-        MOZ_ASSERT(aEnd >= kMinLine && aEnd <= kMaxLine, "invalid span");
+        MOZ_ASSERT(aEnd >= nsStyleGridLine::kMinLine &&
+                       aEnd <= nsStyleGridLine::kMaxLine,
+                   "invalid span");
       } else {
-        MOZ_ASSERT(aStart >= kMinLine && aStart <= kMaxLine,
+        MOZ_ASSERT(aStart >= nsStyleGridLine::kMinLine &&
+                       aStart <= nsStyleGridLine::kMaxLine,
                    "invalid start line");
-        MOZ_ASSERT(aEnd == int32_t(kAutoLine) ||
-                       (aEnd >= kMinLine && aEnd <= kMaxLine),
-                   "invalid end line");
+        MOZ_ASSERT(
+            aEnd == int32_t(kAutoLine) || (aEnd >= nsStyleGridLine::kMinLine &&
+                                           aEnd <= nsStyleGridLine::kMaxLine),
+            "invalid end line");
       }
     }
 #endif
   }
   bool IsAutoAuto() const { return mStart == kAutoLine && mEnd == kAutoLine; }
   bool IsAuto() const { return mStart == kAutoLine; }
   bool IsDefinite() const { return mStart != kAutoLine; }
   uint32_t Extent() const {
     MOZ_ASSERT(mEnd != kAutoLine, "Extent is undefined for abs.pos. 'auto'");
     if (IsAuto()) {
-      MOZ_ASSERT(mEnd >= 1 && mEnd < uint32_t(kMaxLine), "invalid span");
+      MOZ_ASSERT(mEnd >= 1 && mEnd < uint32_t(nsStyleGridLine::kMaxLine),
+                 "invalid span");
       return mEnd;
     }
     return mEnd - mStart;
   }
 
   /**
    * Return an object suitable for iterating this range.
    */
@@ -454,21 +456,22 @@ struct nsGridContainerFrame::LineRange {
   /**
    * Translate the lines to account for (empty) removed tracks.  This method
    * is only for abs.pos. children and should only be called after placement.
    * Same as for in-flow items, but we don't touch 'auto' lines here and we
    * also need to adjust areas that span into the removed tracks.
    */
   void AdjustAbsPosForRemovedTracks(
       const nsTArray<uint32_t>& aNumRemovedTracks) {
-    if (mStart != kAutoLine) {
+    if (mStart != nsGridContainerFrame::kAutoLine) {
       mStart -= aNumRemovedTracks[mStart];
     }
-    if (mEnd != kAutoLine) {
-      MOZ_ASSERT(mStart == kAutoLine || mEnd > mStart, "invalid line range");
+    if (mEnd != nsGridContainerFrame::kAutoLine) {
+      MOZ_ASSERT(mStart == nsGridContainerFrame::kAutoLine || mEnd > mStart,
+                 "invalid line range");
       mEnd -= aNumRemovedTracks[mEnd];
     }
   }
   /**
    * Return the contribution of this line range for step 2 in
    * http://dev.w3.org/csswg/css-grid/#auto-placement-algo
    */
   uint32_t HypotheticalEnd() const { return mEnd; }
@@ -1350,28 +1353,28 @@ struct nsGridContainerFrame::TrackSizing
     if (q.rem != 0 && maxFill == NS_UNCONSTRAINEDSIZE) {
       // "Otherwise, if the grid container has a definite min size in
       // the relevant axis, the number of repetitions is the largest possible
       // positive integer that fulfills that minimum requirement."
       ++numRepeatTracks;  // one more to ensure the grid is at least min-size
     }
     // Clamp the number of repeat tracks so that the last line <= kMaxLine.
     // (note that |numTracks| already includes one repeat() track)
-    const uint32_t maxRepeatTracks = kMaxLine - numTracks;
+    const uint32_t maxRepeatTracks = nsStyleGridLine::kMaxLine - numTracks;
     return std::min(numRepeatTracks, maxRepeatTracks);
   }
 
   /**
    * Compute the explicit grid end line number (in a zero-based grid).
    * @param aGridTemplateAreasEnd 'grid-template-areas' end line in this axis
    */
   uint32_t ComputeExplicitGridEnd(uint32_t aGridTemplateAreasEnd) {
     uint32_t end = NumExplicitTracks() + 1;
     end = std::max(end, aGridTemplateAreasEnd);
-    end = std::min(end, uint32_t(kMaxLine));
+    end = std::min(end, uint32_t(nsStyleGridLine::kMaxLine));
     return end;
   }
 
   const nsStyleCoord& MinSizingFor(uint32_t aTrackIndex) const {
     if (MOZ_UNLIKELY(aTrackIndex < mExplicitGridOffset)) {
       return mAutoMinSizing;
     }
     uint32_t index = aTrackIndex - mExplicitGridOffset;
@@ -2533,18 +2536,18 @@ struct MOZ_STACK_CLASS nsGridContainerFr
                              const GridItemInfo& aGridItem);
 
   /**
    * As above but for an abs.pos. child.  Any 'auto' lines will be represented
    * by kAutoLine in the LineRange result.
    * @param aGridStart the first line in the final, but untranslated grid
    * @param aGridEnd the last line in the final, but untranslated grid
    */
-  LineRange ResolveAbsPosLineRange(const StyleGridLine& aStart,
-                                   const StyleGridLine& aEnd,
+  LineRange ResolveAbsPosLineRange(const nsStyleGridLine& aStart,
+                                   const nsStyleGridLine& aEnd,
                                    const LineNameMap& aNameMap,
                                    LogicalAxis aAxis, uint32_t aExplicitGridEnd,
                                    int32_t aGridStart, int32_t aGridEnd,
                                    const nsStylePosition* aStyle);
 
   /**
    * Return a GridArea for abs.pos. item with non-auto lines placed at
    * a definite line (1-based) with placement errors resolved.  One or both
@@ -2655,29 +2658,29 @@ struct MOZ_STACK_CLASS nsGridContainerFr
    * @param aLineNameList the explicit named lines
    * @param aSide the axis+edge we're resolving names for (e.g. if we're
                   resolving a grid-row-start line, pass eLogicalSideBStart)
    * @param aExplicitGridEnd the last line in the explicit grid
    * @param aStyle the StylePosition() for the grid container
    * @return a definite line (1-based), clamped to
    *   the mClampMinLine..mClampMaxLine range
    */
-  int32_t ResolveLine(const StyleGridLine& aLine, int32_t aNth,
+  int32_t ResolveLine(const nsStyleGridLine& aLine, int32_t aNth,
                       uint32_t aFromIndex, const LineNameMap& aNameMap,
                       LogicalSide aSide, uint32_t aExplicitGridEnd,
                       const nsStylePosition* aStyle);
 
   /**
    * Helper method for ResolveLineRange.
    * @see ResolveLineRange
    * @return a pair (start,end) of lines
    */
   typedef std::pair<int32_t, int32_t> LinePair;
-  LinePair ResolveLineRangeHelper(const StyleGridLine& aStart,
-                                  const StyleGridLine& aEnd,
+  LinePair ResolveLineRangeHelper(const nsStyleGridLine& aStart,
+                                  const nsStyleGridLine& aEnd,
                                   const LineNameMap& aNameMap,
                                   LogicalAxis aAxis, uint32_t aExplicitGridEnd,
                                   const nsStylePosition* aStyle);
 
   /**
    * Return a LineRange based on the given style data. Non-auto lines
    * are resolved to a definite line number (1-based) per:
    * http://dev.w3.org/csswg/css-grid/#line-placement
@@ -2686,18 +2689,18 @@ struct MOZ_STACK_CLASS nsGridContainerFr
    * @param aStyle the StylePosition() for the grid container
    * @param aStart style data for the start line
    * @param aEnd style data for the end line
    * @param aLineNameList the explicit named lines
    * @param aAxis the axis we're resolving names in
    * @param aExplicitGridEnd the last line in the explicit grid
    * @param aStyle the StylePosition() for the grid container
    */
-  LineRange ResolveLineRange(const StyleGridLine& aStart,
-                             const StyleGridLine& aEnd,
+  LineRange ResolveLineRange(const nsStyleGridLine& aStart,
+                             const nsStyleGridLine& aEnd,
                              const LineNameMap& aNameMap, LogicalAxis aAxis,
                              uint32_t aExplicitGridEnd,
                              const nsStylePosition* aStyle);
 
   /**
    * Return a GridArea with non-auto lines placed at a definite line (1-based)
    * with placement errors resolved.  One or both positions may still
    * be 'auto'.
@@ -3326,17 +3329,18 @@ nsContainerFrame* NS_NewGridContainerFra
              "container should've reflowed this item by now and set up cb");
   return *cb;
 }
 
 void nsGridContainerFrame::AddImplicitNamedAreas(
     const nsTArray<nsTArray<RefPtr<nsAtom>>>& aLineNameLists) {
   // http://dev.w3.org/csswg/css-grid/#implicit-named-areas
   // Note: recording these names for fast lookup later is just an optimization.
-  const uint32_t len = std::min(aLineNameLists.Length(), size_t(kMaxLine));
+  const uint32_t len =
+      std::min(aLineNameLists.Length(), size_t(nsStyleGridLine::kMaxLine));
   nsTHashtable<nsStringHashKey> currentStarts;
   ImplicitNamedAreas* areas = GetImplicitNamedAreas();
   for (uint32_t i = 0; i < len; ++i) {
     for (nsAtom* name : aLineNameLists[i]) {
       uint32_t indexOfSuffix;
       if (Grid::IsNameWithStartSuffix(name, &indexOfSuffix) ||
           Grid::IsNameWithEndSuffix(name, &indexOfSuffix)) {
         // Extract the name that was found earlier.
@@ -3374,69 +3378,69 @@ void nsGridContainerFrame::InitImplicitN
   AddImplicitNamedAreas(aStyle->GridTemplateColumns().mLineNameLists);
   AddImplicitNamedAreas(aStyle->GridTemplateRows().mLineNameLists);
   if (areas && areas->count() == 0) {
     DeleteProperty(ImplicitNamedAreasProperty());
   }
 }
 
 int32_t nsGridContainerFrame::Grid::ResolveLine(
-    const StyleGridLine& aLine, int32_t aNth, uint32_t aFromIndex,
+    const nsStyleGridLine& aLine, int32_t aNth, uint32_t aFromIndex,
     const LineNameMap& aNameMap, LogicalSide aSide, uint32_t aExplicitGridEnd,
     const nsStylePosition* aStyle) {
   MOZ_ASSERT(!aLine.IsAuto());
   int32_t line = 0;
-  if (aLine.LineName()->IsEmpty()) {
+  if (aLine.mLineName->IsEmpty()) {
     MOZ_ASSERT(aNth != 0, "css-grid 9.2: <integer> must not be zero.");
     line = int32_t(aFromIndex) + aNth;
   } else {
     if (aNth == 0) {
       // <integer> was omitted; treat it as 1.
       aNth = 1;
     }
-    bool isNameOnly = !aLine.is_span && aLine.line_num == 0;
+    bool isNameOnly = !aLine.mHasSpan && aLine.mInteger == 0;
     if (isNameOnly) {
       AutoTArray<uint32_t, 16> implicitLines;
-      aNameMap.FindNamedAreas(aLine.ident.AsAtom(), aSide, implicitLines);
+      aNameMap.FindNamedAreas(aLine.mLineName, aSide, implicitLines);
       if (!implicitLines.IsEmpty() ||
-          aNameMap.HasImplicitNamedArea(aLine.LineName())) {
+          aNameMap.HasImplicitNamedArea(aLine.mLineName)) {
         // aName is a named area - look for explicit lines named
         // <name>-start/-end depending on which side we're resolving.
         // http://dev.w3.org/csswg/css-grid/#grid-placement-slot
-        nsAutoString lineName(nsDependentAtomString(aLine.LineName()));
+        nsAutoString lineName(nsDependentAtomString(aLine.mLineName));
         if (IsStart(aSide)) {
           lineName.AppendLiteral("-start");
         } else {
           lineName.AppendLiteral("-end");
         }
         RefPtr<nsAtom> name = NS_Atomize(lineName);
         line = aNameMap.FindNamedLine(name, &aNth, aFromIndex, implicitLines);
       }
     }
 
     if (line == 0) {
-      // If LineName() ends in -start/-end, try the prefix as a named area.
+      // If mLineName ends in -start/-end, try the prefix as a named area.
       AutoTArray<uint32_t, 16> implicitLines;
       uint32_t index;
-      bool useStart = IsNameWithStartSuffix(aLine.LineName(), &index);
-      if (useStart || IsNameWithEndSuffix(aLine.LineName(), &index)) {
+      bool useStart = IsNameWithStartSuffix(aLine.mLineName, &index);
+      if (useStart || IsNameWithEndSuffix(aLine.mLineName, &index)) {
         auto side = MakeLogicalSide(
             GetAxis(aSide), useStart ? eLogicalEdgeStart : eLogicalEdgeEnd);
         RefPtr<nsAtom> name = NS_Atomize(nsDependentSubstring(
-            nsDependentAtomString(aLine.LineName()), 0, index));
+            nsDependentAtomString(aLine.mLineName), 0, index));
         aNameMap.FindNamedAreas(name, side, implicitLines);
       }
-      line = aNameMap.FindNamedLine(aLine.LineName(), &aNth, aFromIndex,
+      line = aNameMap.FindNamedLine(aLine.mLineName, &aNth, aFromIndex,
                                     implicitLines);
     }
 
     if (line == 0) {
       MOZ_ASSERT(aNth != 0, "we found all N named lines but 'line' is zero!");
       int32_t edgeLine;
-      if (aLine.is_span) {
+      if (aLine.mHasSpan) {
         // http://dev.w3.org/csswg/css-grid/#grid-placement-span-int
         // 'span <custom-ident> N'
         edgeLine = IsStart(aSide) ? 1 : aExplicitGridEnd;
       } else {
         // http://dev.w3.org/csswg/css-grid/#grid-placement-int
         // '<custom-ident> N'
         edgeLine = aNth < 0 ? 1 : aExplicitGridEnd;
       }
@@ -3445,39 +3449,40 @@ int32_t nsGridContainerFrame::Grid::Reso
       line = edgeLine + aNth;
     }
   }
   return clamped(line, aNameMap.mClampMinLine, aNameMap.mClampMaxLine);
 }
 
 nsGridContainerFrame::Grid::LinePair
 nsGridContainerFrame::Grid::ResolveLineRangeHelper(
-    const StyleGridLine& aStart, const StyleGridLine& aEnd,
+    const nsStyleGridLine& aStart, const nsStyleGridLine& aEnd,
     const LineNameMap& aNameMap, LogicalAxis aAxis, uint32_t aExplicitGridEnd,
     const nsStylePosition* aStyle) {
-  MOZ_ASSERT(int32_t(kAutoLine) > kMaxLine);
-
-  if (aStart.is_span) {
-    if (aEnd.is_span || aEnd.IsAuto()) {
+  MOZ_ASSERT(int32_t(nsGridContainerFrame::kAutoLine) >
+             nsStyleGridLine::kMaxLine);
+
+  if (aStart.mHasSpan) {
+    if (aEnd.mHasSpan || aEnd.IsAuto()) {
       // http://dev.w3.org/csswg/css-grid/#grid-placement-errors
-      if (aStart.LineName()->IsEmpty()) {
+      if (aStart.mLineName->IsEmpty()) {
         // span <integer> / span *
         // span <integer> / auto
-        return LinePair(kAutoLine, aStart.line_num);
+        return LinePair(kAutoLine, aStart.mInteger);
       }
       // span <custom-ident> / span *
       // span <custom-ident> / auto
       return LinePair(kAutoLine, 1);  // XXX subgrid explicit size instead of 1?
     }
 
-    uint32_t from = aEnd.line_num < 0 ? aExplicitGridEnd + 1 : 0;
-    auto end = ResolveLine(aEnd, aEnd.line_num, from, aNameMap,
+    uint32_t from = aEnd.mInteger < 0 ? aExplicitGridEnd + 1 : 0;
+    auto end = ResolveLine(aEnd, aEnd.mInteger, from, aNameMap,
                            MakeLogicalSide(aAxis, eLogicalEdgeEnd),
                            aExplicitGridEnd, aStyle);
-    int32_t span = aStart.line_num == 0 ? 1 : aStart.line_num;
+    int32_t span = aStart.mInteger == 0 ? 1 : aStart.mInteger;
     if (end <= 1) {
       // The end is at or before the first explicit line, thus all lines before
       // it match <custom-ident> since they're implicit.
       int32_t start = std::max(end - span, aNameMap.mClampMinLine);
       return LinePair(start, end);
     }
     auto start = ResolveLine(aStart, -span, end, aNameMap,
                              MakeLogicalSide(aAxis, eLogicalEdgeStart),
@@ -3486,70 +3491,70 @@ nsGridContainerFrame::Grid::ResolveLineR
   }
 
   int32_t start = kAutoLine;
   if (aStart.IsAuto()) {
     if (aEnd.IsAuto()) {
       // auto / auto
       return LinePair(start, 1);  // XXX subgrid explicit size instead of 1?
     }
-    if (aEnd.is_span) {
-      if (aEnd.LineName()->IsEmpty()) {
+    if (aEnd.mHasSpan) {
+      if (aEnd.mLineName->IsEmpty()) {
         // auto / span <integer>
-        MOZ_ASSERT(aEnd.line_num != 0);
-        return LinePair(start, aEnd.line_num);
+        MOZ_ASSERT(aEnd.mInteger != 0);
+        return LinePair(start, aEnd.mInteger);
       }
       // http://dev.w3.org/csswg/css-grid/#grid-placement-errors
       // auto / span <custom-ident>
       return LinePair(start, 1);  // XXX subgrid explicit size instead of 1?
     }
   } else {
-    uint32_t from = aStart.line_num < 0 ? aExplicitGridEnd + 1 : 0;
-    start = ResolveLine(aStart, aStart.line_num, from, aNameMap,
+    uint32_t from = aStart.mInteger < 0 ? aExplicitGridEnd + 1 : 0;
+    start = ResolveLine(aStart, aStart.mInteger, from, aNameMap,
                         MakeLogicalSide(aAxis, eLogicalEdgeStart),
                         aExplicitGridEnd, aStyle);
     if (aEnd.IsAuto()) {
       // A "definite line / auto" should resolve the auto to 'span 1'.
       // The error handling in ResolveLineRange will make that happen and also
       // clamp the end line correctly if we return "start / start".
       return LinePair(start, start);
     }
   }
 
   uint32_t from;
-  int32_t nth = aEnd.line_num == 0 ? 1 : aEnd.line_num;
-  if (aEnd.is_span) {
+  int32_t nth = aEnd.mInteger == 0 ? 1 : aEnd.mInteger;
+  if (aEnd.mHasSpan) {
     if (MOZ_UNLIKELY(start < 0)) {
-      if (aEnd.LineName()->IsEmpty()) {
+      if (aEnd.mLineName->IsEmpty()) {
         return LinePair(start, start + nth);
       }
       from = 0;
     } else {
       if (start >= int32_t(aExplicitGridEnd)) {
         // The start is at or after the last explicit line, thus all lines
         // after it match <custom-ident> since they're implicit.
         return LinePair(start, std::min(start + nth, aNameMap.mClampMaxLine));
       }
       from = start;
     }
   } else {
-    from = aEnd.line_num < 0 ? aExplicitGridEnd + 1 : 0;
+    from = aEnd.mInteger < 0 ? aExplicitGridEnd + 1 : 0;
   }
   auto end = ResolveLine(aEnd, nth, from, aNameMap,
                          MakeLogicalSide(aAxis, eLogicalEdgeEnd),
                          aExplicitGridEnd, aStyle);
   if (start == int32_t(kAutoLine)) {
     // auto / definite line
     start = std::max(aNameMap.mClampMinLine, end - 1);
   }
   return LinePair(start, end);
 }
 
 nsGridContainerFrame::LineRange nsGridContainerFrame::Grid::ResolveLineRange(
-    const StyleGridLine& aStart, const StyleGridLine& aEnd,
+    const nsStyleGridLine& aStart, const nsStyleGridLine& aEnd,
     const LineNameMap& aNameMap, LogicalAxis aAxis, uint32_t aExplicitGridEnd,
     const nsStylePosition* aStyle) {
   LinePair r = ResolveLineRangeHelper(aStart, aEnd, aNameMap, aAxis,
                                       aExplicitGridEnd, aStyle);
   MOZ_ASSERT(r.second != int32_t(kAutoLine));
 
   if (r.first == int32_t(kAutoLine)) {
     // r.second is a span, clamp it to aNameMap.mClampMaxLine - 1 so that
@@ -3580,51 +3585,51 @@ nsGridContainerFrame::GridArea nsGridCon
                        aStyle),
       ResolveLineRange(itemStyle->mGridRowStart, itemStyle->mGridRowEnd,
                        aRowLineNameMap, eLogicalAxisBlock, mExplicitGridRowEnd,
                        aStyle));
 }
 
 nsGridContainerFrame::LineRange
 nsGridContainerFrame::Grid::ResolveAbsPosLineRange(
-    const StyleGridLine& aStart, const StyleGridLine& aEnd,
+    const nsStyleGridLine& aStart, const nsStyleGridLine& aEnd,
     const LineNameMap& aNameMap, LogicalAxis aAxis, uint32_t aExplicitGridEnd,
     int32_t aGridStart, int32_t aGridEnd, const nsStylePosition* aStyle) {
   if (aStart.IsAuto()) {
     if (aEnd.IsAuto()) {
       return LineRange(kAutoLine, kAutoLine);
     }
-    uint32_t from = aEnd.line_num < 0 ? aExplicitGridEnd + 1 : 0;
-    int32_t end = ResolveLine(aEnd, aEnd.line_num, from, aNameMap,
+    uint32_t from = aEnd.mInteger < 0 ? aExplicitGridEnd + 1 : 0;
+    int32_t end = ResolveLine(aEnd, aEnd.mInteger, from, aNameMap,
                               MakeLogicalSide(aAxis, eLogicalEdgeEnd),
                               aExplicitGridEnd, aStyle);
-    if (aEnd.is_span) {
+    if (aEnd.mHasSpan) {
       ++end;
     }
     // A line outside the existing grid is treated as 'auto' for abs.pos (10.1).
     end = AutoIfOutside(end, aGridStart, aGridEnd);
     return LineRange(kAutoLine, end);
   }
 
   if (aEnd.IsAuto()) {
-    uint32_t from = aStart.line_num < 0 ? aExplicitGridEnd + 1 : 0;
-    int32_t start = ResolveLine(aStart, aStart.line_num, from, aNameMap,
+    uint32_t from = aStart.mInteger < 0 ? aExplicitGridEnd + 1 : 0;
+    int32_t start = ResolveLine(aStart, aStart.mInteger, from, aNameMap,
                                 MakeLogicalSide(aAxis, eLogicalEdgeStart),
                                 aExplicitGridEnd, aStyle);
-    if (aStart.is_span) {
+    if (aStart.mHasSpan) {
       start = std::max(aGridEnd - start, aGridStart);
     }
     start = AutoIfOutside(start, aGridStart, aGridEnd);
     return LineRange(start, kAutoLine);
   }
 
   LineRange r =
       ResolveLineRange(aStart, aEnd, aNameMap, aAxis, aExplicitGridEnd, aStyle);
   if (r.IsAuto()) {
-    MOZ_ASSERT(aStart.is_span && aEnd.is_span,
+    MOZ_ASSERT(aStart.mHasSpan && aEnd.mHasSpan,
                "span / span is the only case "
                "leading to IsAuto here -- we dealt with the other cases above");
     // The second span was ignored per 9.2.1.  For abs.pos., 10.1 says that this
     // case should result in "auto / auto" unlike normal flow grid items.
     return LineRange(kAutoLine, kAutoLine);
   }
 
   return LineRange(AutoIfOutside(r.mUntranslatedStart, aGridStart, aGridEnd),
@@ -3871,18 +3876,18 @@ void nsGridContainerFrame::Grid::PlaceGr
   // Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
   // This is determined by the larger of the number of rows/columns defined
   // by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
   // Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
   // Note that this is for a grid with a 1,1 origin.  We'll change that
   // to a 0,0 based grid after placing definite lines.
   const nsStylePosition* const gridStyle = aState.mGridStyle;
   const auto* areas = gridStyle->mGridTemplateAreas.IsNone() ? nullptr : &*gridStyle->mGridTemplateAreas.AsAreas();
-  int32_t clampMinColLine = kMinLine;
-  int32_t clampMaxColLine = kMaxLine;
+  int32_t clampMinColLine = nsStyleGridLine::kMinLine;
+  int32_t clampMaxColLine = nsStyleGridLine::kMaxLine;
   uint32_t numRepeatCols;
   const LineNameMap* parentLineNameMap = nullptr;
   const LineRange* subgridRange = nullptr;
   bool subgridAxisIsSameDirection = true;
   if (!aState.mFrame->IsColSubgrid()) {
     numRepeatCols = aState.mColFunctions.InitRepeatTracks(
         gridStyle->mColumnGap, aSizes.mMin.ISize(aState.mWM),
         aSizes.mSize.ISize(aState.mWM), aSizes.mMax.ISize(aState.mWM));
@@ -3908,18 +3913,19 @@ void nsGridContainerFrame::Grid::PlaceGr
         aState.mWM.ParallelAxisStartsOnSameSide(eLogicalAxisInline, parentWM);
   }
   mGridColEnd = mExplicitGridColEnd;
   LineNameMap colLineNameMap(
       gridStyle, mAreas, gridStyle->GridTemplateColumns(), numRepeatCols,
       clampMinColLine, clampMaxColLine, parentLineNameMap, subgridRange,
       subgridAxisIsSameDirection);
 
-  int32_t clampMinRowLine = kMinLine;
-  int32_t clampMaxRowLine = kMaxLine;
+  int32_t clampMinRowLine = nsStyleGridLine::kMinLine;
+
+  int32_t clampMaxRowLine = nsStyleGridLine::kMaxLine;
   uint32_t numRepeatRows;
   if (!aState.mFrame->IsRowSubgrid()) {
     numRepeatRows = aState.mRowFunctions.InitRepeatTracks(
         gridStyle->mRowGap, aSizes.mMin.BSize(aState.mWM),
         aSizes.mSize.BSize(aState.mWM), aSizes.mMax.BSize(aState.mWM));
     uint32_t areaRows = areas ? areas->strings.Length() + 1 : 1;
     mExplicitGridRowEnd = aState.mRowFunctions.ComputeExplicitGridEnd(areaRows);
     parentLineNameMap = nullptr;
@@ -4290,18 +4296,18 @@ void nsGridContainerFrame::Grid::PlaceGr
   if (mAreas &&
       aState.mFrame->HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES)) {
     for (auto iter = mAreas->iter(); !iter.done(); iter.next()) {
       auto& areaInfo = iter.get().value();
 
       // Resolve the lines for the area. We use the name of the area as the
       // name of the lines, knowing that the line placement algorithm will
       // add the -start and -end suffixes as appropriate for layout.
-      StyleGridLine lineStartAndEnd;
-      lineStartAndEnd.ident = areaInfo.name;
+      nsStyleGridLine lineStartAndEnd;
+      lineStartAndEnd.mLineName = areaInfo.name.AsAtom();
 
       LineRange columnLines =
           ResolveLineRange(lineStartAndEnd, lineStartAndEnd, colLineNameMap,
                            eLogicalAxisInline, mExplicitGridColEnd, gridStyle);
 
       LineRange rowLines =
           ResolveLineRange(lineStartAndEnd, lineStartAndEnd, rowLineNameMap,
                            eLogicalAxisBlock, mExplicitGridRowEnd, gridStyle);
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -281,16 +281,19 @@ class nsGridContainerFrame final : publi
     // Does the above item span the first(last) track?
     bool mIsInEdgeTrack;
   };
 
   /** Return our parent grid container; |this| MUST be a subgrid. */
   nsGridContainerFrame* ParentGridContainerForSubgrid() const;
 
  protected:
+  static const uint32_t kAutoLine;
+  // The maximum line number, in the zero-based translated grid.
+  static const uint32_t kTranslatedMaxLine;
   typedef mozilla::LogicalPoint LogicalPoint;
   typedef mozilla::LogicalRect LogicalRect;
   typedef mozilla::LogicalSize LogicalSize;
   typedef mozilla::CSSOrderAwareFrameIterator CSSOrderAwareFrameIterator;
   typedef mozilla::ReverseCSSOrderAwareFrameIterator
       ReverseCSSOrderAwareFrameIterator;
   typedef mozilla::WritingMode WritingMode;
   typedef mozilla::layout::AutoFrameListPtr AutoFrameListPtr;
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -508,17 +508,16 @@ cbindgen-types = [
     { gecko = "StyleSpecifiedImageUrl", servo = "gecko::url::SpecifiedImageUrl" },
     { gecko = "StyleComputedUrl", servo = "gecko::url::ComputedUrl" },
     { gecko = "StyleComputedImageUrl", servo = "gecko::url::ComputedImageUrl" },
     { gecko = "StyleLoadData", servo = "gecko::url::LoadData" },
     { gecko = "StyleGenericFilter", servo = "values::generics::effects::Filter" },
     { gecko = "StyleGenericGradient", servo = "values::generics::image::Gradient" },
     { gecko = "StyleLineDirection", servo = "values::computed::image::LineDirection" },
     { gecko = "StyleGridTemplateAreas", servo = "values::computed::position::GridTemplateAreas" },
-    { gecko = "StyleGenericGridLine", servo = "values::generics::grid::GridLine" },
 ]
 
 mapped-generic-types = [
     { generic = true, gecko = "mozilla::RustCell", servo = "::std::cell::Cell" },
     { generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
     { generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
     { generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>" },
     { generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
--- a/layout/style/ServoStyleConstsInlines.h
+++ b/layout/style/ServoStyleConstsInlines.h
@@ -231,23 +231,17 @@ inline nsAtom* StyleAtom::AsAtom() const
     auto* atom = reinterpret_cast<const nsStaticAtom*>(
         reinterpret_cast<const uint8_t*>(&detail::gGkAtoms) + (_0 >> 1));
     MOZ_ASSERT(atom->IsStatic());
     return const_cast<nsStaticAtom*>(atom);
   }
   return reinterpret_cast<nsAtom*>(_0);
 }
 
-inline void StyleAtom::AddRef() {
-  if (!IsStatic()) {
-    AsAtom()->AddRef();
-  }
-}
-
-inline void StyleAtom::Release() {
+inline StyleAtom::~StyleAtom() {
   if (!IsStatic()) {
     AsAtom()->Release();
   }
 }
 
 inline StyleAtom::StyleAtom(already_AddRefed<nsAtom> aAtom) {
   nsAtom* atom = aAtom.take();
   if (atom->IsStatic()) {
@@ -257,30 +251,21 @@ inline StyleAtom::StyleAtom(already_AddR
   } else {
     _0 = reinterpret_cast<uintptr_t>(atom);
   }
   MOZ_ASSERT(IsStatic() == atom->IsStatic());
   MOZ_ASSERT(AsAtom() == atom);
 }
 
 inline StyleAtom::StyleAtom(const StyleAtom& aOther) : _0(aOther._0) {
-  AddRef();
+  if (!IsStatic()) {
+    reinterpret_cast<nsAtom*>(_0)->AddRef();
+  }
 }
 
-inline StyleAtom& StyleAtom::operator=(const StyleAtom& aOther) {
-  if (MOZ_LIKELY(this != &aOther)) {
-    Release();
-    _0 = aOther._0;
-    AddRef();
-  }
-  return *this;
-}
-
-inline StyleAtom::~StyleAtom() { Release(); }
-
 inline nsAtom* StyleCustomIdent::AsAtom() const { return _0.AsAtom(); }
 
 inline nsDependentCSubstring StyleOwnedStr::AsString() const {
   Span<const uint8_t> s = _0.AsSpan();
   return nsDependentCSubstring(reinterpret_cast<const char*>(s.Elements()),
                                s.Length());
 }
 
@@ -379,27 +364,11 @@ inline bool StyleComputedUrl::HasRef() c
     return NS_SUCCEEDED(uri->GetHasRef(&hasRef)) && hasRef;
   }
   return false;
 }
 
 template <>
 bool StyleGradient::IsOpaque() const;
 
-template <typename Integer>
-inline StyleGenericGridLine<Integer>::StyleGenericGridLine()
-    : ident(do_AddRef(static_cast<nsAtom*>(nsGkAtoms::_empty))),
-      line_num(0),
-      is_span(false) {}
-
-template <>
-inline nsAtom* StyleGridLine::LineName() const {
-  return ident.AsAtom();
-}
-
-template <>
-inline bool StyleGridLine::IsAuto() const {
-  return LineName()->IsEmpty() && line_num == 0 && !is_span;
-}
-
 }  // namespace mozilla
 
 #endif
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1614,16 +1614,52 @@ already_AddRefed<CSSValue> nsComputedDOM
 
   if (gridFrame) {
     info = gridFrame->GetComputedTemplateRows();
   }
 
   return GetGridTemplateColumnsRows(StylePosition()->GridTemplateRows(), info);
 }
 
+already_AddRefed<CSSValue> nsComputedDOMStyle::GetGridLine(
+    const nsStyleGridLine& aGridLine) {
+  if (aGridLine.IsAuto()) {
+    RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
+    val->SetIdent(eCSSKeyword_auto);
+    return val.forget();
+  }
+
+  RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
+
+  if (aGridLine.mHasSpan) {
+    RefPtr<nsROCSSPrimitiveValue> span = new nsROCSSPrimitiveValue;
+    span->SetIdent(eCSSKeyword_span);
+    valueList->AppendCSSValue(span.forget());
+  }
+
+  if (aGridLine.mInteger != 0) {
+    RefPtr<nsROCSSPrimitiveValue> integer = new nsROCSSPrimitiveValue;
+    integer->SetNumber(aGridLine.mInteger);
+    valueList->AppendCSSValue(integer.forget());
+  }
+
+  if (aGridLine.mLineName != nsGkAtoms::_empty) {
+    RefPtr<nsROCSSPrimitiveValue> lineName = new nsROCSSPrimitiveValue;
+    nsString escapedLineName;
+    nsStyleUtil::AppendEscapedCSSIdent(
+        nsDependentAtomString(aGridLine.mLineName), escapedLineName);
+    lineName->SetString(escapedLineName);
+    valueList->AppendCSSValue(lineName.forget());
+  }
+
+  NS_ASSERTION(valueList->Length() > 0,
+               "Should have appended at least one value");
+  return valueList.forget();
+}
+
 already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingTop() {
   return GetPaddingWidthFor(eSideTop);
 }
 
 already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetPaddingBottom() {
   return GetPaddingWidthFor(eSideBottom);
 }
 
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -201,16 +201,17 @@ class nsComputedDOMStyle final : public 
   void AppendGridLineNames(nsDOMCSSValueList* aValueList,
                            const nsTArray<RefPtr<nsAtom>>& aLineNames1,
                            const nsTArray<RefPtr<nsAtom>>& aLineNames2);
   already_AddRefed<CSSValue> GetGridTrackSize(const nsStyleCoord& aMinSize,
                                               const nsStyleCoord& aMaxSize);
   already_AddRefed<CSSValue> GetGridTemplateColumnsRows(
       const nsStyleGridTemplate& aTrackList,
       const mozilla::ComputedGridTrackInfo* aTrackInfo);
+  already_AddRefed<CSSValue> GetGridLine(const nsStyleGridLine& aGridLine);
 
   bool GetLineHeightCoord(nscoord& aCoord);
 
   bool ShouldHonorMinSizeAutoInAxis(mozilla::PhysicalAxis aAxis);
 
   /* Properties queryable as CSSValues.
    * To avoid a name conflict with nsIDOM*CSS2Properties, these are all
    * DoGetXXX instead of GetXXX.
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -41,16 +41,19 @@
 #include "nsIURI.h"
 #include "mozilla/dom/Document.h"
 #include <algorithm>
 #include "ImageLoader.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+/* static */ const int32_t nsStyleGridLine::kMinLine;
+/* static */ const int32_t nsStyleGridLine::kMaxLine;
+
 static const nscoord kMediumBorderWidth = nsPresContext::CSSPixelsToAppUnits(3);
 
 // We set the size limit of style structs to 504 bytes so that when they
 // are allocated by Servo side with Arc, the total size doesn't exceed
 // 512 bytes, which minimizes allocator slop.
 static constexpr size_t kStyleStructSizeLimit = 504;
 #define STYLE_STRUCT(name_)                                      \
   static_assert(sizeof(nsStyle##name_) <= kStyleStructSizeLimit, \
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -940,16 +940,54 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
 
  public:
   mozilla::StyleQuotes mQuotes;
   nsRect mImageRegion;  // the rect to use within an image
   mozilla::StyleMozListReversed
       mMozListReversed;  // true in an <ol reversed> scope
 };
 
+struct nsStyleGridLine {
+  // http://dev.w3.org/csswg/css-grid/#typedef-grid-line
+  // XXXmats we could optimize memory size here
+  bool mHasSpan;
+  int32_t mInteger;    // 0 means not provided
+  RefPtr<nsAtom> mLineName;  // Empty string means not provided.
+
+  // These are the limits that we choose to clamp grid line numbers to.
+  // http://dev.w3.org/csswg/css-grid/#overlarge-grids
+  // mInteger is clamped to this range:
+  static const int32_t kMinLine = -10000;
+  static const int32_t kMaxLine = 10000;
+
+  nsStyleGridLine()
+      : mHasSpan(false), mInteger(0), mLineName(nsGkAtoms::_empty) {}
+
+  nsStyleGridLine(const nsStyleGridLine& aOther) { (*this) = aOther; }
+
+  void operator=(const nsStyleGridLine& aOther) {
+    mHasSpan = aOther.mHasSpan;
+    mInteger = aOther.mInteger;
+    mLineName = aOther.mLineName;
+  }
+
+  bool operator!=(const nsStyleGridLine& aOther) const {
+    return mHasSpan != aOther.mHasSpan || mInteger != aOther.mInteger ||
+           mLineName != aOther.mLineName;
+  }
+
+  bool IsAuto() const {
+    bool haveInitialValues = mInteger == 0 && mLineName == nsGkAtoms::_empty;
+    MOZ_ASSERT(!(haveInitialValues && mHasSpan),
+               "should not have 'span' when other components are "
+               "at their initial values");
+    return haveInitialValues;
+  }
+};
+
 // Computed value of the grid-template-columns or grid-template-rows property
 // (but *not* grid-template-areas.)
 // http://dev.w3.org/csswg/css-grid/#track-sizing
 //
 // This represents either:
 // * none:
 //   mIsSubgrid is false, all three arrays are empty
 // * <track-list>:
@@ -1008,17 +1046,17 @@ struct nsStyleGridTemplate {
            mRepeatAutoLineNameListBefore ==
                aOther.mRepeatAutoLineNameListBefore &&
            mRepeatAutoLineNameListAfter == aOther.mRepeatAutoLineNameListAfter;
   }
 
   bool HasRepeatAuto() const { return mRepeatAutoIndex != -1; }
 
   bool IsRepeatAutoIndex(uint32_t aIndex) const {
-    MOZ_ASSERT(aIndex < uint32_t(2 * mozilla::StyleMAX_GRID_LINE));
+    MOZ_ASSERT(aIndex < uint32_t(2 * nsStyleGridLine::kMaxLine));
     return int32_t(aIndex) == mRepeatAutoIndex;
   }
 };
 
 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
   using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
   using Position = mozilla::Position;
   template <typename T>
@@ -1099,20 +1137,20 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   float mFlexGrow;
   float mFlexShrink;
   mozilla::StyleZIndex mZIndex;
   mozilla::UniquePtr<nsStyleGridTemplate> mGridTemplateColumns;
   mozilla::UniquePtr<nsStyleGridTemplate> mGridTemplateRows;
 
   mozilla::StyleGridTemplateAreas mGridTemplateAreas;
 
-  mozilla::StyleGridLine mGridColumnStart;
-  mozilla::StyleGridLine mGridColumnEnd;
-  mozilla::StyleGridLine mGridRowStart;
-  mozilla::StyleGridLine mGridRowEnd;
+  nsStyleGridLine mGridColumnStart;
+  nsStyleGridLine mGridColumnEnd;
+  nsStyleGridLine mGridRowStart;
+  nsStyleGridLine mGridRowEnd;
   mozilla::NonNegativeLengthPercentageOrNormal mColumnGap;
   mozilla::NonNegativeLengthPercentageOrNormal mRowGap;
 
   bool OffsetHasPercent(mozilla::Side aSide) const {
     return mOffset.Get(aSide).HasPercent();
   }
 
   // Logical-coordinate accessors for width and height properties,
--- a/servo/components/servo_arc/lib.rs
+++ b/servo/components/servo_arc/lib.rs
@@ -177,17 +177,17 @@ impl<T> Arc<T> {
             data,
         }));
 
         #[cfg(feature = "gecko_refcount_logging")]
         unsafe {
             // FIXME(emilio): Would be so amazing to have
             // std::intrinsics::type_name() around, so that we could also report
             // a real size.
-            NS_LogCtor(ptr as *mut _, b"ServoArc\0".as_ptr() as *const _, 8);
+            NS_LogCtor(ptr as *const _, b"ServoArc\0".as_ptr() as *const _, 8);
         }
 
         unsafe {
             Arc {
                 p: ptr::NonNull::new_unchecked(ptr),
                 phantom: PhantomData,
             }
         }
@@ -310,17 +310,17 @@ impl<T: ?Sized> Arc<T> {
         unsafe { &*self.ptr() }
     }
 
     #[inline(always)]
     fn record_drop(&self) {
         #[cfg(feature = "gecko_refcount_logging")]
         unsafe {
             NS_LogDtor(
-                self.ptr() as *mut _,
+                self.ptr() as *const _,
                 b"ServoArc\0".as_ptr() as *const _,
                 8,
             );
         }
     }
 
     /// Marks this `Arc` as intentionally leaked for the purposes of refcount
     /// logging.
@@ -350,22 +350,22 @@ impl<T: ?Sized> Arc<T> {
     fn ptr(&self) -> *mut ArcInner<T> {
         self.p.as_ptr()
     }
 }
 
 #[cfg(feature = "gecko_refcount_logging")]
 extern "C" {
     fn NS_LogCtor(
-        aPtr: *mut std::os::raw::c_void,
+        aPtr: *const std::os::raw::c_void,
         aTypeName: *const std::os::raw::c_char,
         aSize: u32,
     );
     fn NS_LogDtor(
-        aPtr: *mut std::os::raw::c_void,
+        aPtr: *const std::os::raw::c_void,
         aTypeName: *const std::os::raw::c_char,
         aSize: u32,
     );
 }
 
 impl<T: ?Sized> Clone for Arc<T> {
     #[inline]
     fn clone(&self) -> Self {
@@ -757,17 +757,17 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> {
             );
         }
 
         #[cfg(feature = "gecko_refcount_logging")]
         unsafe {
             if !is_static {
                 // FIXME(emilio): Would be so amazing to have
                 // std::intrinsics::type_name() around.
-                NS_LogCtor(ptr as *mut _, b"ServoArc\0".as_ptr() as *const _, 8)
+                NS_LogCtor(ptr as *const _, b"ServoArc\0".as_ptr() as *const _, 8)
             }
         }
 
         // Return the fat Arc.
         assert_eq!(
             size_of::<Self>(),
             size_of::<usize>() * 2,
             "The Arc will be fat"
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -875,18 +875,25 @@ impl ${style_struct.gecko_struct_name} {
 
 <%!
 class Side(object):
     def __init__(self, name, index):
         self.name = name
         self.ident = name.lower()
         self.index = index
 
+class GridLine(object):
+    def __init__(self, name):
+        self.ident = "grid-" + name.lower()
+        self.name = self.ident.replace('-', '_')
+        self.gecko = "m" + to_camel_case(self.ident)
+
 SIDES = [Side("Top", 0), Side("Right", 1), Side("Bottom", 2), Side("Left", 3)]
 CORNERS = ["top_left", "top_right", "bottom_right", "bottom_left"]
+GRID_LINES = map(GridLine, ["row-start", "row-end", "column-start", "column-end"])
 %>
 
 #[allow(dead_code)]
 fn static_assert() {
     // Note: using the above technique with an enum hits a rust bug when |structs| is in a different crate.
     % for side in SIDES:
     { const DETAIL: u32 = [0][(structs::Side::eSide${side.name} as usize != ${side.index}) as usize]; let _ = DETAIL; }
     % endfor
@@ -1065,17 +1072,17 @@ fn static_assert() {
     % for side in SIDES:
     <% impl_split_style_coord("padding_%s" % side.ident,
                               "mPadding",
                               side.index) %>
     <% impl_split_style_coord("scroll_padding_%s" % side.ident, "mScrollPadding", side.index) %>
     % endfor
 </%self:impl_trait>
 
-<% skip_position_longhands = " ".join(x.ident for x in SIDES) %>
+<% skip_position_longhands = " ".join(x.ident for x in SIDES + GRID_LINES) %>
 <%self:impl_trait style_struct_name="Position"
                   skip_longhands="${skip_position_longhands} order
                                   align-content justify-content align-self
                                   justify-self align-items justify-items
                                   grid-auto-rows grid-auto-columns
                                   grid-auto-flow grid-template-rows
                                   grid-template-columns">
     % for side in SIDES:
@@ -1120,16 +1127,74 @@ fn static_assert() {
     }
 
     pub fn clone_order(&self) -> longhands::order::computed_value::T {
         self.gecko.mOrder
     }
 
     ${impl_simple_copy('order', 'mOrder')}
 
+    % for value in GRID_LINES:
+    pub fn set_${value.name}(&mut self, v: longhands::${value.name}::computed_value::T) {
+        use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
+
+        let line = &mut self.gecko.${value.gecko};
+        line.mLineName.set_move(unsafe {
+            RefPtr::from_addrefed(match v.ident {
+                Some(i) => i.0,
+                None => atom!(""),
+            }.into_addrefed())
+        });
+        line.mHasSpan = v.is_span;
+        if let Some(integer) = v.line_num {
+            // clamping the integer between a range
+            line.mInteger = cmp::max(
+                nsStyleGridLine_kMinLine,
+                cmp::min(integer, nsStyleGridLine_kMaxLine),
+            );
+        }
+    }
+
+    pub fn copy_${value.name}_from(&mut self, other: &Self) {
+        self.gecko.${value.gecko}.mHasSpan = other.gecko.${value.gecko}.mHasSpan;
+        self.gecko.${value.gecko}.mInteger = other.gecko.${value.gecko}.mInteger;
+        unsafe {
+            self.gecko.${value.gecko}.mLineName.set(&other.gecko.${value.gecko}.mLineName);
+        }
+    }
+
+    pub fn reset_${value.name}(&mut self, other: &Self) {
+        self.copy_${value.name}_from(other)
+    }
+
+    pub fn clone_${value.name}(&self) -> longhands::${value.name}::computed_value::T {
+        use crate::gecko_bindings::structs::{nsStyleGridLine_kMinLine, nsStyleGridLine_kMaxLine};
+
+        longhands::${value.name}::computed_value::T {
+            is_span: self.gecko.${value.gecko}.mHasSpan,
+            ident: {
+                let name = unsafe { Atom::from_raw(self.gecko.${value.gecko}.mLineName.mRawPtr) };
+                if name == atom!("") {
+                    None
+                } else {
+                    Some(CustomIdent(name))
+                }
+            },
+            line_num:
+                if self.gecko.${value.gecko}.mInteger == 0 {
+                    None
+                } else {
+                    debug_assert!(nsStyleGridLine_kMinLine <= self.gecko.${value.gecko}.mInteger);
+                    debug_assert!(self.gecko.${value.gecko}.mInteger <= nsStyleGridLine_kMaxLine);
+                    Some(self.gecko.${value.gecko}.mInteger)
+                },
+        }
+    }
+    % endfor
+
     % for kind in ["rows", "columns"]:
     pub fn set_grid_auto_${kind}(&mut self, v: longhands::grid_auto_${kind}::computed_value::T) {
         let gecko = &mut *self.gecko;
         v.to_gecko_style_coords(&mut gecko.mGridAuto${kind.title()}Min,
                                 &mut gecko.mGridAuto${kind.title()}Max)
     }
 
     pub fn copy_grid_auto_${kind}_from(&mut self, other: &Self) {
@@ -1143,36 +1208,36 @@ fn static_assert() {
 
     pub fn clone_grid_auto_${kind}(&self) -> longhands::grid_auto_${kind}::computed_value::T {
         crate::values::generics::grid::TrackSize::from_gecko_style_coords(&self.gecko.mGridAuto${kind.title()}Min,
                                                                      &self.gecko.mGridAuto${kind.title()}Max)
     }
 
     pub fn set_grid_template_${kind}(&mut self, v: longhands::grid_template_${kind}::computed_value::T) {
         <% self_grid = "self.gecko.mGridTemplate%s" % kind.title() %>
-        use crate::gecko_bindings::structs::nsTArray;
+        use crate::gecko_bindings::structs::{nsTArray, nsStyleGridLine_kMaxLine};
         use std::usize;
         use crate::values::CustomIdent;
         use crate::values::generics::grid::TrackListType::Auto;
-        use crate::values::generics::grid::{GridTemplateComponent, RepeatCount, MAX_GRID_LINE};
+        use crate::values::generics::grid::{GridTemplateComponent, RepeatCount};
 
         #[inline]
         fn set_line_names(servo_names: &[CustomIdent], gecko_names: &mut nsTArray<structs::RefPtr<structs::nsAtom>>) {
             unsafe {
                 bindings::Gecko_ResizeAtomArray(gecko_names, servo_names.len() as u32);
             }
 
             for (servo_name, gecko_name) in servo_names.iter().zip(gecko_names.iter_mut()) {
                 gecko_name.set_move(unsafe {
                     RefPtr::from_addrefed(servo_name.0.clone().into_addrefed())
                 });
             }
         }
 
-        let max_lines = MAX_GRID_LINE as usize - 1; // for accounting the final <line-names>
+        let max_lines = nsStyleGridLine_kMaxLine as usize - 1;      // for accounting the final <line-names>
 
         let result = match v {
             GridTemplateComponent::None => ptr::null_mut(),
             GridTemplateComponent::TrackList(track) => {
                 let mut num_values = track.values.len();
                 if let Auto(_) = track.list_type {
                     num_values += 1;
                 }
--- a/servo/components/style/properties/shorthands/position.mako.rs
+++ b/servo/components/style/properties/shorthands/position.mako.rs
@@ -139,32 +139,31 @@
 </%helpers:shorthand>
 
 % for kind in ["row", "column"]:
 <%helpers:shorthand name="grid-${kind}" sub_properties="grid-${kind}-start grid-${kind}-end"
                     spec="https://drafts.csswg.org/css-grid/#propdef-grid-${kind}"
                     products="gecko">
     use crate::values::specified::GridLine;
     use crate::parser::Parse;
-    use crate::Zero;
 
     // NOTE: Since both the shorthands have the same code, we should (re-)use code from one to implement
     // the other. This might not be a big deal for now, but we should consider looking into this in the future
     // to limit the amount of code generated.
     pub fn parse_value<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Longhands, ParseError<'i>> {
         let start = input.try(|i| GridLine::parse(context, i))?;
         let end = if input.try(|i| i.expect_delim('/')).is_ok() {
             GridLine::parse(context, input)?
         } else {
             let mut line = GridLine::auto();
-            if start.line_num.is_zero() && !start.is_span {
-                line.ident = start.ident.clone(); // ident from start value should be taken
+            if start.line_num.is_none() && !start.is_span {
+                line.ident = start.ident.clone();       // ident from start value should be taken
             }
 
             line
         };
 
         Ok(expanded! {
             grid_${kind}_start: start,
             grid_${kind}_end: end,
@@ -182,26 +181,25 @@
 % endfor
 
 <%helpers:shorthand name="grid-area"
                     sub_properties="grid-row-start grid-row-end grid-column-start grid-column-end"
                     spec="https://drafts.csswg.org/css-grid/#propdef-grid-area"
                     products="gecko">
     use crate::values::specified::GridLine;
     use crate::parser::Parse;
-    use crate::Zero;
 
     // The code is the same as `grid-{row,column}` except that this can have four values at most.
     pub fn parse_value<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Longhands, ParseError<'i>> {
         fn line_with_ident_from(other: &GridLine) -> GridLine {
             let mut this = GridLine::auto();
-            if other.line_num.is_zero() && !other.is_span {
+            if other.line_num.is_none() && !other.is_span {
                 this.ident = other.ident.clone();
             }
 
             this
         }
 
         let row_start = input.try(|i| GridLine::parse(context, i))?;
         let (column_start, row_end, column_end) = if input.try(|i| i.expect_delim('/')).is_ok() {
--- a/servo/components/style/rule_tree/mod.rs
+++ b/servo/components/style/rule_tree/mod.rs
@@ -945,35 +945,35 @@ unsafe impl Send for RuleTree {}
 // On Gecko builds, hook into the leak checking machinery.
 #[cfg(feature = "gecko_refcount_logging")]
 mod gecko_leak_checking {
     use super::RuleNode;
     use std::mem::size_of;
     use std::os::raw::{c_char, c_void};
 
     extern "C" {
-        fn NS_LogCtor(aPtr: *mut c_void, aTypeName: *const c_char, aSize: u32);
-        fn NS_LogDtor(aPtr: *mut c_void, aTypeName: *const c_char, aSize: u32);
+        pub fn NS_LogCtor(aPtr: *const c_void, aTypeName: *const c_char, aSize: u32);
+        pub fn NS_LogDtor(aPtr: *const c_void, aTypeName: *const c_char, aSize: u32);
     }
 
     static NAME: &'static [u8] = b"RuleNode\0";
 
     /// Logs the creation of a heap-allocated object to Gecko's leak-checking machinery.
     pub fn log_ctor(ptr: *const RuleNode) {
         let s = NAME as *const [u8] as *const u8 as *const c_char;
         unsafe {
-            NS_LogCtor(ptr as *mut c_void, s, size_of::<RuleNode>() as u32);
+            NS_LogCtor(ptr as *const c_void, s, size_of::<RuleNode>() as u32);
         }
     }
 
     /// Logs the destruction of a heap-allocated object to Gecko's leak-checking machinery.
     pub fn log_dtor(ptr: *const RuleNode) {
         let s = NAME as *const [u8] as *const u8 as *const c_char;
         unsafe {
-            NS_LogDtor(ptr as *mut c_void, s, size_of::<RuleNode>() as u32);
+            NS_LogDtor(ptr as *const c_void, s, size_of::<RuleNode>() as u32);
         }
     }
 
 }
 
 #[inline(always)]
 fn log_new(_ptr: *const RuleNode) {
     #[cfg(feature = "gecko_refcount_logging")]
--- a/servo/components/style/values/animated/grid.rs
+++ b/servo/components/style/values/animated/grid.rs
@@ -57,17 +57,20 @@ impl Animate for TrackSize {
                 &generics::TrackSize::FitContent(ref to),
             ) => animate_with_discrete_fallback(from, to, procedure)
                 .map(generics::TrackSize::FitContent),
             (_, _) => discrete(self, other, procedure),
         }
     }
 }
 
-impl Animate for generics::TrackRepeat<LengthPercentage, Integer> {
+impl Animate for generics::TrackRepeat<LengthPercentage, Integer>
+where
+    generics::RepeatCount<Integer>: PartialEq,
+{
     fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
         // If the keyword, auto-fit/fill, is the same it can result in different
         // number of tracks. For both auto-fit/fill, the number of columns isn't
         // known until you do layout since it depends on the container size, item
         // placement and other factors, so we cannot do the correct interpolation
         // by computed values. Therefore, return Err(()) if it's keywords. If it
         // is Number, we support animation only if the count is the same and the
         // length of track_sizes is the same.
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -2,17 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 //! Computed values.
 
 use self::transform::DirectionVector;
 use super::animated::ToAnimatedValue;
 use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
-use super::generics::grid::{GenericGridLine, TrackBreadth as GenericTrackBreadth};
+use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
 use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
 use super::generics::transform::IsParallelTo;
 use super::generics::{self, GreaterThanOrEqualToOne, NonNegative, ZeroToOne};
 use super::specified;
 use super::{CSSFloat, CSSInteger};
 use crate::context::QuirksMode;
 use crate::font_metrics::{get_metrics_provider_for_product, FontMetricsProvider};
 use crate::media_queries::Device;
--- a/servo/components/style/values/generics/grid.rs
+++ b/servo/components/style/values/generics/grid.rs
@@ -1,115 +1,94 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 //! Generic types for the handling of
 //! [grids](https://drafts.csswg.org/css-grid/).
 
-use crate::{Atom, Zero};
 use crate::parser::{Parse, ParserContext};
 use crate::values::computed::{Context, ToComputedValue};
 use crate::values::specified;
 use crate::values::specified::grid::parse_line_names;
 use crate::values::{CSSFloat, CustomIdent};
 use cssparser::Parser;
 use std::fmt::{self, Write};
-use std::{cmp, mem, usize};
+use std::{mem, usize};
 use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
 
-
-/// These are the limits that we choose to clamp grid line numbers to.
-/// http://drafts.csswg.org/css-grid/#overlarge-grids
-/// line_num is clamped to this range at parse time.
-pub const MIN_GRID_LINE: i32 = -10000;
-/// See above.
-pub const MAX_GRID_LINE: i32 = 10000;
-
 /// A `<grid-line>` type.
 ///
 /// <https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line>
 #[derive(
     Clone,
     Debug,
     Default,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToResolvedValue,
     ToShmem,
 )]
-#[repr(C)]
-pub struct GenericGridLine<Integer> {
-    /// A custom identifier for named lines, or the empty atom otherwise.
+pub struct GridLine<Integer> {
+    /// Flag to check whether it's a `span` keyword.
+    pub is_span: bool,
+    /// A custom identifier for named lines.
     ///
     /// <https://drafts.csswg.org/css-grid/#grid-placement-slot>
-    pub ident: Atom,
+    pub ident: Option<CustomIdent>,
     /// Denotes the nth grid line from grid item's placement.
-    ///
-    /// This is clamped by MIN_GRID_LINE and MAX_GRID_LINE.
-    ///
-    /// NOTE(emilio): If we ever allow animating these we need to either do
-    /// something more complicated for the clamping, or do this clamping at
-    /// used-value time.
-    pub line_num: Integer,
-    /// Flag to check whether it's a `span` keyword.
-    pub is_span: bool,
+    pub line_num: Option<Integer>,
 }
 
-pub use self::GenericGridLine as GridLine;
-
-impl<Integer> GridLine<Integer>
-where
-    Integer: Zero,
-{
+impl<Integer> GridLine<Integer> {
     /// The `auto` value.
     pub fn auto() -> Self {
         Self {
             is_span: false,
-            line_num: Zero::zero(),
-            ident: atom!(""),
+            line_num: None,
+            ident: None,
         }
     }
 
     /// Check whether this `<grid-line>` represents an `auto` value.
     pub fn is_auto(&self) -> bool {
-        self.ident == atom!("") && self.line_num.is_zero() && !self.is_span
+        self.ident.is_none() && self.line_num.is_none() && !self.is_span
     }
 }
 
 impl<Integer> ToCss for GridLine<Integer>
 where
-    Integer: ToCss + Zero,
+    Integer: ToCss,
 {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: Write,
     {
         if self.is_auto() {
             return dest.write_str("auto");
         }
 
         if self.is_span {
             dest.write_str("span")?;
         }
 
-        if !self.line_num.is_zero() {
+        if let Some(ref i) = self.line_num {
             if self.is_span {
                 dest.write_str(" ")?;
             }
-            self.line_num.to_css(dest)?;
+            i.to_css(dest)?;
         }
 
-        if self.ident != atom!("") {
-            if self.is_span || !self.line_num.is_zero() {
+        if let Some(ref s) = self.ident {
+            if self.is_span || self.line_num.is_some() {
                 dest.write_str(" ")?;
             }
-            CustomIdent(self.ident.clone()).to_css(dest)?;
+            s.to_css(dest)?;
         }
 
         Ok(())
     }
 }
 
 impl Parse for GridLine<specified::Integer> {
     fn parse<'i, 't>(
@@ -130,52 +109,51 @@ impl Parse for GridLine<specified::Integ
         for _ in 0..3 {
             // Maximum possible entities for <grid-line>
             let location = input.current_source_location();
             if input.try(|i| i.expect_ident_matching("span")).is_ok() {
                 if grid_line.is_span {
                     return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                 }
 
-                if !grid_line.line_num.is_zero() || grid_line.ident != atom!("") {
+                if grid_line.line_num.is_some() || grid_line.ident.is_some() {
                     val_before_span = true;
                 }
 
                 grid_line.is_span = true;
             } else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) {
                 // FIXME(emilio): Probably shouldn't reject if it's calc()...
-                let value = i.value();
-                if value == 0 || val_before_span || !grid_line.line_num.is_zero() {
+                if i.value() == 0 || val_before_span || grid_line.line_num.is_some() {
                     return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                 }
 
-                grid_line.line_num = specified::Integer::new(cmp::max(MIN_GRID_LINE, cmp::min(value, MAX_GRID_LINE)));
+                grid_line.line_num = Some(i);
             } else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
-                if val_before_span || grid_line.ident != atom!("") {
+                if val_before_span || grid_line.ident.is_some() {
                     return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                 }
                 // NOTE(emilio): `span` is consumed above, so we only need to
                 // reject `auto`.
-                grid_line.ident = CustomIdent::from_ident(location, &name, &["auto"])?.0;
+                grid_line.ident = Some(CustomIdent::from_ident(location, &name, &["auto"])?);
             } else {
                 break;
             }
         }
 
         if grid_line.is_auto() {
             return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
         }
 
         if grid_line.is_span {
-            if !grid_line.line_num.is_zero() {
-                if grid_line.line_num.value() <= 0 {
+            if let Some(i) = grid_line.line_num {
+                if i.value() <= 0 {
                     // disallow negative integers for grid spans
                     return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
                 }
-            } else if grid_line.ident == atom!("") {
+            } else if grid_line.ident.is_none() {
                 // integer could be omitted
                 return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
             }
         }
 
         Ok(grid_line)
     }
 }
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -12,19 +12,19 @@ use super::generics::grid::{GridLine as 
 use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
 use super::generics::transform::IsParallelTo;
 use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
 use super::{Auto, CSSFloat, CSSInteger, Either, None_};
 use crate::context::QuirksMode;
 use crate::parser::{Parse, ParserContext};
 use crate::values::serialize_atom_identifier;
 use crate::values::specified::calc::CalcNode;
-use crate::{Atom, Namespace, Prefix, Zero};
+use crate::{Atom, Namespace, Prefix};
 use cssparser::{Parser, Token};
-use num_traits::One;
+use num_traits::{One, Zero};
 use std::f32;
 use std::fmt::{self, Write};
 use std::ops::Add;
 use style_traits::values::specified::AllowedNumericType;
 use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss};
 
 #[cfg(feature = "gecko")]
 pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution};
@@ -444,28 +444,16 @@ impl ToComputedValue for Opacity {
 ///
 /// <https://drafts.csswg.org/css-values/#integers>
 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, ToShmem)]
 pub struct Integer {
     value: CSSInteger,
     was_calc: bool,
 }
 
-impl Zero for Integer {
-    #[inline]
-    fn zero() -> Self {
-        Self::new(0)
-    }
-
-    #[inline]
-    fn is_zero(&self) -> bool {
-        self.value() == 0
-    }
-}
-
 impl One for Integer {
     #[inline]
     fn one() -> Self {
         Self::new(1)
     }
 }
 
 // This is not great, because it loses calc-ness, but it's necessary for One.
--- a/servo/ports/geckolib/cbindgen.toml
+++ b/servo/ports/geckolib/cbindgen.toml
@@ -24,17 +24,16 @@ braces = "SameLine"
 line_length = 80
 tab_width = 2
 language = "C++"
 namespaces = ["mozilla"]
 includes = ["mozilla/ServoStyleConstsForwards.h"]
 
 [parse]
 parse_deps = true
-extra_bindings = ["style"]
 include = ["style", "cssparser", "style_traits", "servo_arc"]
 
 [struct]
 derive_eq = true
 derive_neq = true
 
 [defines]
 # This will actually never be defined, but is handy to avoid cbindgen
@@ -47,20 +46,16 @@ bitflags = true
 [enum]
 derive_helper_methods = true
 derive_const_casts = true
 derive_tagged_enum_destructor = true
 cast_assert_name = "MOZ_ASSERT"
 
 [export]
 prefix = "Style"
-exclude = [
-  "NS_LogCtor",
-  "NS_LogDtor",
-]
 include = [
   "Appearance",
   "BreakBetween",
   "BreakWithin",
   "BorderStyle",
   "OutlineStyle",
   "ComputedFontStretchRange",
   "ComputedFontStyleDescriptor",
@@ -151,19 +146,18 @@ include = [
   "Translate",
   "BorderImageWidth",
   "ComputedUrl",
   "ComputedImageUrl",
   "UrlOrNone",
   "Filter",
   "Gradient",
   "GridTemplateAreas",
-  "GridLine",
 ]
-item_types = ["enums", "structs", "typedefs", "functions", "constants"]
+item_types = ["enums", "structs", "typedefs", "functions"]
 renaming_overrides_prefixing = true
 
 # Prevent some renaming for Gecko types that cbindgen doesn't otherwise understand.
 [export.rename]
 "nscolor" = "nscolor"
 "nsAtom" = "nsAtom"
 "nsIURI" = "nsIURI"
 "nsCompatibility" = "nsCompatibility"
@@ -463,27 +457,26 @@ renaming_overrides_prefixing = true
 "CustomIdent" = """
   inline nsAtom* AsAtom() const;
 """
 
 "Atom" = """
   StyleAtom(size_t) = delete;
   StyleAtom() = delete;
 
+  // NOTE(emilio): For now we don't need to expose anything else, but it'd be trivial if we wanted to.
   inline bool IsStatic() const;
   inline nsAtom* AsAtom() const;
 
- private:
-  inline void AddRef();
-  inline void Release();
+  inline explicit StyleAtom(already_AddRefed<nsAtom> aAtom);
 
- public:
-  inline explicit StyleAtom(already_AddRefed<nsAtom> aAtom);
+  // Could be implemented if wanted.
+  StyleAtom& operator=(const StyleAtom&) = delete;
+
   inline StyleAtom(const StyleAtom& aOther);
-  inline StyleAtom& operator=(const StyleAtom&);
   inline ~StyleAtom();
 """
 
 "OwnedStr" = """
   inline nsDependentCSubstring AsString() const;
 """
 
 "GenericTransform" = """
@@ -593,16 +586,8 @@ renaming_overrides_prefixing = true
 "GridTemplateAreas" = """
  private:
   // Private default constructor without initialization so that the helper
   // constructor functions still work as expected. They take care of
   // initializing the fields properly.
   StyleGridTemplateAreas() {}
  public:
 """
-
-"GenericGridLine" = """
-  // Returns the `auto` value.
-  inline StyleGenericGridLine();
-  inline bool IsAuto() const;
-  // The line name, or nsGkAtoms::_empty if not present.
-  inline nsAtom* LineName() const;
-"""