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/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 5fec7b2..8a8919b 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -665,6 +665,28 @@
   // type.
   if (auto parentType = unboundType->getParent()) {
     if (parentType->hasUnboundGenericType()) {
+      // If we're working with a nominal type declaration, just construct
+      // a bound generic type without checking the generic arguments.
+      if (auto *nominalDecl = dyn_cast<NominalTypeDecl>(decl)) {
+        SmallVector<Type, 2> args;
+        for (auto &genericArg : genericArgs) {
+          // Propagate failure.
+          if (validateType(genericArg, dc, options, resolver,
+                           unsatisfiedDependency))
+            return ErrorType::get(Context);
+
+          auto substTy = genericArg.getType();
+
+          // Unsatisfied dependency case.
+          if (!substTy)
+            return nullptr;
+
+          args.push_back(substTy);
+        }
+
+        return BoundGenericType::get(nominalDecl, parentType, args);
+      }
+
       assert(!resultType->hasTypeParameter());
       return resultType;
     }
diff --git a/test/decl/nested/type_in_type.swift b/test/decl/nested/type_in_type.swift
index 303237d..310857d 100644
--- a/test/decl/nested/type_in_type.swift
+++ b/test/decl/nested/type_in_type.swift
@@ -381,12 +381,28 @@
   struct Fangs<B: ExpressibleByDogLiteral> { }
 }
 
+struct NotADog {}
+
 func pets<T>(fur: T) -> Claws<Kitten>.Fangs<T> {
   return Claws<Kitten>.Fangs<T>()
 }
 
+func something<T>() -> T { // expected-note {{in call to function 'something'}}
+  while true {}
+}
+
 func test() {
   let _: Claws<Kitten>.Fangs<Puppy> = pets(fur: Puppy())
+
+  // <https://bugs.swift.org/browse/SR-5600>
+  let _: Claws.Fangs<Puppy> = pets(fur: Puppy())
+  let _: Claws.Fangs<Puppy> = Claws<Kitten>.Fangs()
+  let _: Claws.Fangs<Puppy> = Claws.Fangs()
+  // expected-error@-1 {{cannot convert value of type 'Claws<_>.Fangs<_>' to specified type 'Claws.Fangs<Puppy>'}}
+  let _: Claws.Fangs<NotADog> = something()
+  // expected-error@-1 {{generic parameter 'T' could not be inferred}} // FIXME: bad diagnostic
+  _ = Claws.Fangs<NotADog>()
+  // expected-error@-1 {{type 'NotADog' does not conform to protocol 'ExpressibleByDogLiteral'}}
 }
 
 // https://bugs.swift.org/browse/SR-4379