Merge pull request #11327 from slavapestov/nested-type-unbound-generic-4.0
Sema: Fix crash when resolving bound generic type with unbound parent [4.0]
diff --git a/stdlib/public/core/IntegerParsing.swift b/stdlib/public/core/IntegerParsing.swift
index 0032892..03ab1b5 100644
--- a/stdlib/public/core/IntegerParsing.swift
+++ b/stdlib/public/core/IntegerParsing.swift
@@ -102,7 +102,7 @@
///
/// The string passed as `text` may begin with a plus or minus sign character
/// (`+` or `-`), followed by one or more numeric digits (`0-9`) or letters
- /// (`a-z` or `A-Z`). The string is case insensitive.
+ /// (`a-z` or `A-Z`). Parsing of the string is case insensitive.
///
/// let x = Int("123")
/// // x == 123
@@ -116,7 +116,7 @@
/// // z == 123
///
/// If `text` is in an invalid format or contains characters that are out of
- /// range for the given `radix`, or if the value it denotes in the given
+ /// bounds for the given `radix`, or if the value it denotes in the given
/// `radix` is not representable, the result is `nil`. For example, the
/// following conversions result in `nil`:
///
@@ -155,4 +155,28 @@
guard _fastPath(result != nil) else { return nil }
self = result!
}
+
+ /// Creates a new integer value from the given string.
+ ///
+ /// The string passed as `description` may begin with a plus or minus sign
+ /// character (`+` or `-`), followed by one or more numeric digits (`0-9`).
+ ///
+ /// let x = Int("123")
+ /// // x == 123
+ ///
+ /// If `description` is in an invalid format, or if the value it denotes in
+ /// base 10 is not representable, the result is `nil`. For example, the
+ /// following conversions result in `nil`:
+ ///
+ /// Int(" 100") // Includes whitespace
+ /// Int("21-50") // Invalid format
+ /// Int("ff6600") // Characters out of bounds
+ /// Int("10000000000000000000000000") // Out of range
+ ///
+ /// - Parameter description: The ASCII representation of a number.
+ @_semantics("optimize.sil.specialize.generic.partial.never")
+ @inline(__always)
+ public init?(_ description: String) {
+ self.init(description, radix: 10)
+ }
}
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index 0cf5d69..28dea76 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -1908,7 +1908,8 @@
/// customization points for arithmetic operations. When you provide just those
/// methods, the standard library provides default implementations for all
/// other arithmetic methods and operators.
-public protocol FixedWidthInteger : BinaryInteger, _BitwiseOperations {
+public protocol FixedWidthInteger :
+ BinaryInteger, LosslessStringConvertible, _BitwiseOperations {
/// The number of bits used for the underlying binary representation of
/// values of this type.
///
diff --git a/test/stdlib/Integers.swift.gyb b/test/stdlib/Integers.swift.gyb
index 5e5ec99..7fd2bc5 100644
--- a/test/stdlib/Integers.swift.gyb
+++ b/test/stdlib/Integers.swift.gyb
@@ -364,6 +364,16 @@
expectEqual(129, UInt8(truncatingIfNeeded: 129 + 1024 as UDWord))
}
+tests.test("Parsing/LosslessStringConvertible") {
+ func _toArray<T: LosslessStringConvertible>(_ text: String) -> [T] {
+ return text.split(separator: " ").map { T(String($0)) }.flatMap { $0 }
+ }
+
+ expectEqualSequence([1, 2, 3], _toArray("1 2 3") as [Int])
+ expectEqualSequence(
+ [Int](), _toArray("21-50 ff6600 10000000000000000000000000") as [Int])
+}
+
tests.test("HeterogeneousEquality") {
expectTrue(-1 as DWord != UDWord.max)
expectTrue(DWord.max == UDWord.max / 2)