Merge pull request #17576 from DougGregor/disable-generic-typealias-mangling-4.2

[4.2] Don't mangle generic type aliases at all
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 9d9d7fa..efc4208 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -3368,8 +3368,17 @@
   }
 
   void tryPostfixOperator(Expr *expr, PostfixOperatorDecl *op) {
-    if (!expr->getType())
+    auto Ty = expr->getType();
+    if (!Ty)
       return;
+
+    SWIFT_DEFER {
+      // Restore type.
+      // FIXME: This is workaround for getTypeOfExpressionWithoutApplying()
+      // modifies type of 'expr'.
+      expr->setType(Ty);
+    };
+
     // We allocate these expressions on the stack because we know they can't
     // escape and there isn't a better way to allocate scratch Expr nodes.
     UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::PostfixOperator,
@@ -3444,6 +3453,9 @@
                            LHS->getType()->is<AnyFunctionType>()))
       return;
 
+    // Preserve LHS type for restoring it.
+    Type LHSTy = LHS->getType();
+
     // We allocate these expressions on the stack because we know they can't
     // escape and there isn't a better way to allocate scratch Expr nodes.
     UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::BinaryOperator,
@@ -3456,13 +3468,20 @@
       // Reset sequence.
       SE->setElement(SE->getNumElements() - 1, nullptr);
       SE->setElement(SE->getNumElements() - 2, nullptr);
+      LHS->setType(LHSTy);
       prepareForRetypechecking(SE);
 
-      // Reset any references to operators in types, so they are properly
-      // handled as operators by sequence folding.
-      //
-      // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
       for (auto &element : sequence.drop_back(2)) {
+        // Unfold AssignExpr for re-typechecking sequence.
+        if (auto *AE = dyn_cast_or_null<AssignExpr>(element)) {
+          AE->setSrc(nullptr);
+          AE->setDest(nullptr);
+        }
+
+        // Reset any references to operators in types, so they are properly
+        // handled as operators by sequence folding.
+        //
+        // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
         if (auto operatorRef = element->getMemberOperatorRef()) {
           operatorRef->setType(nullptr);
           element = operatorRef;
@@ -3496,20 +3515,20 @@
     }
   }
 
-  void flattenBinaryExpr(BinaryExpr *expr, SmallVectorImpl<Expr *> &sequence) {
-    auto LHS = expr->getArg()->getElement(0);
-    if (auto binexpr = dyn_cast<BinaryExpr>(LHS))
-      flattenBinaryExpr(binexpr, sequence);
-    else
-      sequence.push_back(LHS);
-
-    sequence.push_back(expr->getFn());
-
-    auto RHS = expr->getArg()->getElement(1);
-    if (auto binexpr = dyn_cast<BinaryExpr>(RHS))
-      flattenBinaryExpr(binexpr, sequence);
-    else
-      sequence.push_back(RHS);
+  void flattenBinaryExpr(Expr *expr, SmallVectorImpl<Expr *> &sequence) {
+    if (auto binExpr = dyn_cast<BinaryExpr>(expr)) {
+      flattenBinaryExpr(binExpr->getArg()->getElement(0), sequence);
+      sequence.push_back(binExpr->getFn());
+      flattenBinaryExpr(binExpr->getArg()->getElement(1), sequence);
+    } else if (auto assignExpr = dyn_cast<AssignExpr>(expr)) {
+      flattenBinaryExpr(assignExpr->getDest(), sequence);
+      sequence.push_back(assignExpr);
+      flattenBinaryExpr(assignExpr->getSrc(), sequence);
+      assignExpr->setDest(nullptr);
+      assignExpr->setSrc(nullptr);
+    } else {
+      sequence.push_back(expr);
+    }
   }
 
   void typeCheckLeadingSequence(SmallVectorImpl<Expr *> &sequence) {
@@ -3519,10 +3538,10 @@
     // Take advantage of the fact the type-checker leaves the types on the AST.
     if (!typeCheckExpression(const_cast<DeclContext *>(CurrDeclContext),
                              expr)) {
-      if (auto binexpr = dyn_cast<BinaryExpr>(expr)) {
+      if (isa<BinaryExpr>(expr) || isa<AssignExpr>(expr)) {
         // Rebuild the sequence from the type-checked version.
         sequence.clear();
-        flattenBinaryExpr(binexpr, sequence);
+        flattenBinaryExpr(expr, sequence);
         return;
       }
     }
@@ -3548,6 +3567,9 @@
     if (sequence.size() > 1)
       typeCheckLeadingSequence(sequence);
 
+    // Retrieve typechecked LHS.
+    LHS = sequence.back();
+
     // Create a single sequence expression, which we will modify for each
     // operator, filling in the operator and dummy right-hand side.
     sequence.push_back(nullptr); // operator
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 56eb1a4..32192f6 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -372,6 +372,10 @@
     auto *param = paramList->get(paramNum);
     return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
   }
+  if (auto *ee = dyn_cast<EnumElementDecl>(decl)) {
+    auto *param = ee->getParameterList()->get(paramNum);
+    return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
+  }
 
   auto *subscript = cast<SubscriptDecl>(decl);
   auto *index = subscript->getIndices()->get(paramNum);
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index b40ac85..decc345 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -678,6 +678,8 @@
                                                           numConformances);
 
   auto replacementTy = getType(replacementID);
+  if (!replacementTy)
+    replacementTy = ErrorType::get(getContext());
   if (genericEnv) {
     replacementTy = genericEnv->mapTypeIntoContext(replacementTy);
   }
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 38f070b..af7f0c6 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -1646,7 +1646,8 @@
                                                      abbrCode,
                                                      addTypeRef(type),
                                                      substitutions.size());
-    writeSubstitutions(substitutions, abbrCodes, genericEnv);
+    writeSubstitutions(substitutions, abbrCodes, genericEnv,
+                       /*ignoreReplacementErrors*/true);
 
     writeConformance(conf->getGenericConformance(), abbrCodes, genericEnv);
     break;
@@ -1691,7 +1692,8 @@
 void
 Serializer::writeSubstitutions(SubstitutionList substitutions,
                                const std::array<unsigned, 256> &abbrCodes,
-                               GenericEnvironment *genericEnv) {
+                               GenericEnvironment *genericEnv,
+                               bool ignoreReplacementErrors) {
   using namespace decls_block;
   auto abbrCode = abbrCodes[BoundGenericSubstitutionLayout::Code];
 
@@ -1700,6 +1702,8 @@
     if (genericEnv && replacementType->hasArchetype()) {
       replacementType = replacementType->mapTypeOutOfContext();
     }
+    if (replacementType->hasError() && ignoreReplacementErrors)
+      replacementType = Type();
 
     BoundGenericSubstitutionLayout::emitRecord(
       Out, ScratchRecord, abbrCode,
diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h
index c571c3b..f91cd3f 100644
--- a/lib/Serialization/Serialization.h
+++ b/lib/Serialization/Serialization.h
@@ -495,7 +495,8 @@
   /// being written.
   void writeSubstitutions(SubstitutionList substitutions,
                           const std::array<unsigned, 256> &abbrCodes,
-                          GenericEnvironment *genericEnv = nullptr);
+                          GenericEnvironment *genericEnv = nullptr,
+                          bool ignoreReplacementErrors = false);
 
   /// Write a normal protocol conformance.
   void writeNormalConformance(const NormalProtocolConformance *conformance);
diff --git a/test/IDE/complete_crashes.swift b/test/IDE/complete_crashes.swift
index 8549d0e..4e07d68 100644
--- a/test/IDE/complete_crashes.swift
+++ b/test/IDE/complete_crashes.swift
@@ -220,10 +220,9 @@
 func foo_38149042(bar: Bar_38149042) {
   _ = bar.foo? #^RDAR_38149042^# .x
 }
-// RDAR_38149042: Begin completions, 3 items
+
+// RDAR_38149042: Begin completions
 // RDAR_38149042-DAG: Decl[InstanceVar]/CurrNominal:                  .x[#Int#]; name=x
-// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']=== {#AnyObject?#}[#Bool#]; name==== AnyObject?
-// RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']!== {#AnyObject?#}[#Bool#]; name=!== AnyObject?
 // RDAR_38149042: End completions
 
 // rdar://problem/38272904
@@ -246,3 +245,53 @@
   bar_38272904(a: .foo() #^RDAR_38272904^#)
 }
 // RDAR_38272904: Begin completions
+
+// rdar://problem/41159258
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41159258_1
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41159258_2 | %FileCheck %s -check-prefix=RDAR_41159258
+public func ==(lhs: RDAR41159258_MyResult1, rhs: RDAR41159258_MyResult1) -> Bool {
+  fatalError()
+}
+public func ==(lhs: RDAR41159258_MyResult2, rhs: RDAR41159258_MyResult2) -> Bool {
+  fatalError()
+}
+public enum RDAR41159258_MyResult1 {
+  case failure(Error)
+}
+public enum RDAR41159258_MyResult2 {
+  case failure(Error)
+}
+
+public struct RDAR41159258_MyError: Error {}
+
+func foo(x: RDAR41159258_MyResult1) {
+  let x: RDAR41159258_MyResult1
+  x = .failure(RDAR41159258_MyError()) #^RDAR41159258_1^#
+  let y: Bool
+  y = .failure(RDAR41159258_MyError()) #^RDAR41159258_2^#
+}
+// RDAR_41159258: Begin completions
+
+
+// rdar://problem/41232519
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41232519 | %FileCheck %s -check-prefix=RDAR_41232519
+public protocol IntProvider {
+  func nextInt() -> Int
+}
+
+public final class IntStore {
+  public var myInt: Int = 0
+  func readNextInt(from provider: IntProvider) {
+      myInt = provider.nextInt() #^RDAR41232519^#
+  }
+}
+// RDAR_41232519: Begin completions
+
+// rdar://problem/28188259
+// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_28188259 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_28188259
+func test_28188259(x: ((Int) -> Void) -> Void) {
+  x({_ in }#^RDAR_28188259^#)
+}
+// RDAR_28188259: Begin completions
+// RDAR_28188259-DAG: Pattern/CurrModule:                 ({#_#})[#Void#]; name=(_)
+// RDAR_28188259: End completions
diff --git a/validation-test/Serialization/SR7337.swift b/validation-test/Serialization/SR7337.swift
new file mode 100644
index 0000000..b3f9c81
--- /dev/null
+++ b/validation-test/Serialization/SR7337.swift
@@ -0,0 +1,20 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-module -o %t/Lib.swiftmodule %s -DLIB
+// RUN: %target-build-swift -emit-module -o %t/main.swiftmodule -I %t %s
+
+#if LIB
+
+protocol Proto {}
+
+open class Base<T> {}
+public struct ArbitraryStruct {}
+
+extension Base: Proto where T: Proto {}
+
+#else // LIB
+
+import Lib
+
+final class ConcreteSub: Base<ArbitraryStruct> {}
+
+#endif // LIB
\ No newline at end of file