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)