Fixes for typealiases involving generics (#3811)

* Serialization: Another fix for generic typealiases

Fixes <https://bugs.swift.org/browse/SR-1889>.

* Sema: Fix FindCapturedVars to look through typealiases

Fixes <https://bugs.swift.org/browse/SR-1781>.
diff --git a/lib/Sema/TypeCheckCaptures.cpp b/lib/Sema/TypeCheckCaptures.cpp
index ed54ffc..ce4bce4 100644
--- a/lib/Sema/TypeCheckCaptures.cpp
+++ b/lib/Sema/TypeCheckCaptures.cpp
@@ -73,6 +73,9 @@
     if (!type)
       return;
 
+    // We want to look through type aliases here.
+    type = type->getCanonicalType();
+
     // If the type contains dynamic 'Self', conservatively assume we will
     // need 'Self' metadata at runtime. We could generalize the analysis
     // used below for usages of generic parameters in Objective-C
@@ -95,42 +98,22 @@
       });
     }
 
-    // Nothing to do if the type is concrete.
-    if (!type->hasArchetype())
-      return;
-
-    // Walk the type to see if we have any archetypes that are *not* open
-    // existentials and that aren't type-erased.
-    class CapturesTypeWalker final : public TypeWalker {
-      SourceLoc &GenericParamCaptureLoc;
-      SourceLoc CurLoc;
-
-    public:
-      CapturesTypeWalker(SourceLoc &GenericParamCaptureLoc,
-                         SourceLoc curLoc)
-        : GenericParamCaptureLoc(GenericParamCaptureLoc),
-          CurLoc(curLoc) {}
-
-      Action walkToTypePre(Type t) override {
-        // Similar to dynamic 'Self', IRGen doesn't really need type metadata
-        // for class-bound archetypes in nearly as many cases as with opaque
-        // archetypes.
-        //
-        // Perhaps this entire analysis should happen at the SILGen level,
-        // instead, but even there we don't really have enough information to
-        // perform it accurately.
-        if (t->is<ArchetypeType>() && !t->isOpenedExistential()) {
-          if (GenericParamCaptureLoc.isInvalid())
-            GenericParamCaptureLoc = CurLoc;
-          return Action::Continue;
+    // Similar to dynamic 'Self', IRGen doesn't really need type metadata
+    // for class-bound archetypes in nearly as many cases as with opaque
+    // archetypes.
+    //
+    // Perhaps this entire analysis should happen at the SILGen level,
+    // instead, but even there we don't really have enough information to
+    // perform it accurately.
+    if (type->hasArchetype()) {
+      type.visit([&](Type t) {
+        if (t->is<ArchetypeType>() &&
+            !t->isOpenedExistential() &&
+          GenericParamCaptureLoc.isInvalid()) {
+          GenericParamCaptureLoc = loc;
         }
-
-        return Action::Continue;
-      }
-    };
-
-    type.walk(CapturesTypeWalker(GenericParamCaptureLoc,
-                                 loc));
+      });
+    }
   }
 
   /// Add the specified capture to the closure's capture list, diagnosing it
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index ea042aa..fd940de 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -1359,6 +1359,8 @@
           // Simple case: use the nominal type's generic parameters.
           paramList = nominal->getGenericParams();
         }
+      } else if (auto alias = dyn_cast<TypeAliasDecl>(base)) {
+        paramList = alias->getGenericParams();
       } else if (auto fn = dyn_cast<AbstractFunctionDecl>(base))
         paramList = fn->getGenericParams();
 
diff --git a/test/expr/capture/generic_params.swift b/test/expr/capture/generic_params.swift
index 7767fa8..d96c563 100644
--- a/test/expr/capture/generic_params.swift
+++ b/test/expr/capture/generic_params.swift
@@ -22,4 +22,13 @@
   // they're not mentioned in the function body
   // CHECK: func_decl "innerGeneric(u:)"<U> type='<U> (u: U) -> ()' {{.*}} captures=(<generic> )
   func innerGeneric<U>(u: U) {}
+
+  // Make sure we look through typealiases
+  typealias TT = (a: T, b: T)
+
+  // CHECK: func_decl "localFunction(tt:)" type='<T> (tt: TT) -> ()' {{.*}} captures=(<generic> )
+  func localFunction(tt: TT) {}
+
+  // CHECK: closure_expr type='(TT) -> ()' {{.*}} captures=(<generic> )
+  let _: (TT) -> () = { _ in }
 }
diff --git a/test/multifile/typealias/one-module/library.swift b/test/multifile/typealias/one-module/library.swift
new file mode 100644
index 0000000..7785da5
--- /dev/null
+++ b/test/multifile/typealias/one-module/library.swift
@@ -0,0 +1,9 @@
+// RUN: true
+
+public enum Result<T, U>
+{
+    case success(T)
+    case failure(U)
+}
+
+public typealias GenericResult<T> = Result<T, Error>
diff --git a/test/multifile/typealias/one-module/main.swift b/test/multifile/typealias/one-module/main.swift
new file mode 100644
index 0000000..445a12a
--- /dev/null
+++ b/test/multifile/typealias/one-module/main.swift
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t && mkdir %t
+
+// RUN: %target-build-swift %S/main.swift %S/library.swift
+// RUN: %target-build-swift -g %S/main.swift %S/library.swift
+
+// REQUIRES: executable_test
+
+func testFunction<T>(withCompletion completion: (Result<T, Error>) -> Void) { }
+testFunction { (result: GenericResult<Int>) in }
diff --git a/test/multifile/typealias/two-modules/main.swift b/test/multifile/typealias/two-modules/main.swift
index 7b58d1c..6f600cb 100644
--- a/test/multifile/typealias/two-modules/main.swift
+++ b/test/multifile/typealias/two-modules/main.swift
@@ -5,6 +5,10 @@
 // RUN: %target-build-swift -emit-library -c %S/library.swift -o %t/linker/library.o
 // RUN: %target-build-swift %S/main.swift %t/linker/library.o -I %t/linker/ -L %t/linker/ -o %t/linker/main
 
+// RUN: %target-build-swift -g -emit-module -c %S/library.swift -o %t/linker/library.o
+// RUN: %target-build-swift -g -emit-library -c %S/library.swift -o %t/linker/library.o
+// RUN: %target-build-swift -g %S/main.swift %t/linker/library.o -I %t/linker/ -L %t/linker/ -o %t/linker/main
+
 // REQUIRES: executable_test
 
 import library