diff --git a/stdlib/public/core/FloatingPointParsing.swift.gyb b/stdlib/public/core/FloatingPointParsing.swift.gyb index f65c8c2b7018..aef8227f40b7 100644 --- a/stdlib/public/core/FloatingPointParsing.swift.gyb +++ b/stdlib/public/core/FloatingPointParsing.swift.gyb @@ -256,15 +256,21 @@ extension ${Self}: LosslessStringConvertible { // Use the all-Swift `parse_float${bits}()` implementation for Float16/32/64 @available(SwiftStdlib 5.3, *) public init?(_ text: Substring) { - // TODO: Someday, this whole function should simplify down to just: - // ${Self}(text.utf8.span) #if _pointerBitWidth(_16) // Always fail on 16-bit targets return nil #else - // Work around span availability limits - let parsed = unsafe text.base._guts.withFastUTF8 { chars -> ${Self}? in - unsafe parse_float${bits}(chars.span) + let parsed: ${Self}? + if text.base._guts.isFastUTF8 { + parsed = unsafe text.base._guts.withFastUTF8 { chars -> ${Self}? in + unsafe parse_float${bits}(chars.span.extracting(text._offsetRange)) + } + } else { + // Otherwise, make a copy so we have contiguous UTF8... + let string = String(text) + parsed = unsafe string._guts.withFastUTF8 { chars -> ${Self}? in + unsafe parse_float${bits}(chars.span) + } } if let parsed { diff --git a/test/stdlib/ParseFloat64.swift b/test/stdlib/ParseFloat64.swift index 4683a5495150..10b1a895fe31 100644 --- a/test/stdlib/ParseFloat64.swift +++ b/test/stdlib/ParseFloat64.swift @@ -328,6 +328,14 @@ tests.test("Decimal Floats") { expectParse("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.999999999999999999999999999", Float64.infinity) } +tests.test("Substring") { + let s1 = "1.02.03.0" + let s1sub = s1[s1.firstIndex(of: "2")!..>,