 
     // Perform a quick single-code-unit grapheme check
     if _core._baseAddress != nil {
-      let pos = start._position - _coreOffset
       if String.CharacterView._quickCheckGraphemeBreakBetween(
-        _core._nthContiguous(pos),
-        _core._nthContiguous(pos+1)
+        _core._nthContiguous(relativeOffset),
+        _core._nthContiguous(relativeOffset+1)
       ) {
         return 1
       }
-    }
-
+    } else {
+      // TODO: Check for (potentially non-contiguous) UTF16 NSStrings,
+      // especially small tagged pointers
+    }
+
+    if _core._baseAddress != nil {
+      _onFastPath() // Please aggressively inline
+      let breakIterator = _ThreadLocalStorage.getUBreakIterator(for: _core)
+      let ubrkFollowing = __swift_stdlib_ubrk_following(
+        breakIterator, Int32(relativeOffset)
+      )
+      // ubrk_following may return UBRK_DONE (-1). Treat that as the rest of the
+      // string.
+      let nextPosition =
+        ubrkFollowing == -1 ? end._position : Int(ubrkFollowing)
+      return nextPosition - relativeOffset
+    } else {
+      // TODO: See if we can get fast character contents.
+    }
+
+    // FIXME: Need to handle the general case correctly with Unicode 9+
+    // semantics, as opposed to this legacy Unicode 8 path. This gets hit for
+    // e.g. non-contiguous NSStrings. In such cases, there may be an alternative
+    // CFString API available, or worst case we can map over it via UTextFuncs.
+
+    return legacyGraphemeForward(
+      start: start, end: end, startIndexUTF16: startIndexUTF16
+    )
+  }
+
+  @inline(never)
+  func legacyGraphemeForward(
+    start: UnicodeScalarView.Index,
+    end: UnicodeScalarView.Index,
+    startIndexUTF16: Int
+  ) -> Int {
+    var start = start
     let graphemeClusterBreakProperty =
       _UnicodeGraphemeClusterBreakPropertyTrie()
     let segmenter = _UnicodeExtendedGraphemeClusterSegmenter()

      return 0
    }

    // Grapheme breaking is much simpler if known ASCII
    if _core.isASCII {
      _onFastPath() // Please aggressively inline
      let asciiBuffer = _core.asciiBuffer._unsafelyUnwrappedUnchecked
      let pos = end._position - _coreOffset - 1
      _sanityCheck(
        pos >= asciiBuffer.startIndex,
        "should of been caught in earlier start-of-scalars check")

      // With the exception of CR-LF, ASCII graphemes are single-scalar. Check
      // for that one exception.
      if _slowPath(
        asciiBuffer[pos] == _LF &&
        pos-1 >= asciiBuffer.startIndex &&
        asciiBuffer[pos-1] == _CR
      ) {
        return 2
      }

internal let _CR: UInt8 = 0x0d
internal let _LF: UInt8 = 0x0a

import SwiftShims

extension String {
  /// A view of a string's contents as a collection of characters.
  ///
