Merge pull request #4085 from apple/stdlib-make-array-implementation-internal-3

stdlib: make Array implementation internal, part 2
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 66e3fd7..ae0d379 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -78,6 +78,9 @@
 NOTE(did_you_mean_raw_type,none,
      "did you mean to specify a raw type on the enum declaration?", ())
 
+NOTE(any_as_anyobject_fixit, none,
+     "cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members", ())
+
 ERROR(expected_argument_in_contextual_member,none,
       "contextual member %0 expects argument of type %1", (DeclName, Type))
 
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 41d6b52..ea63bec 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -2523,6 +2523,14 @@
           diagnose(loc, diag::did_you_mean_raw_type);
           return; // Always prefer this over typo corrections.
         }
+      } else if (baseObjTy->isAny()) {
+        if (auto DRE = dyn_cast<DeclRefExpr>(baseExpr)) {
+          auto name = DRE->getDecl()->getName().str().str();
+          std::string replacement = "(" + name + " as AnyObject)";
+          diagnose(loc, diag::any_as_anyobject_fixit)
+            .fixItReplace(baseExpr->getSourceRange(), replacement);
+          return;
+        }
       }
     }
 
diff --git a/test/Constraints/dynamic_lookup.swift b/test/Constraints/dynamic_lookup.swift
index 116d90c..eefa295 100644
--- a/test/Constraints/dynamic_lookup.swift
+++ b/test/Constraints/dynamic_lookup.swift
@@ -219,3 +219,9 @@
 // Should not be able to see private or internal @objc methods.
 uopt.privateFoo!() // expected-error{{'privateFoo' is inaccessible due to 'private' protection level}}
 uopt.internalFoo!() // expected-error{{'internalFoo' is inaccessible due to 'internal' protection level}}
+
+let anyValue: Any = X()
+_ = anyValue.bar() // expected-error {{value of type 'Any' has no member 'bar'}}
+// expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}{{5-13=(anyValue as AnyObject)}}
+_ = (anyValue as AnyObject).bar()
+_ = (anyValue as! X).bar()
diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift
index 02ef3d2..b67dc84 100644
--- a/test/Constraints/tuple.swift
+++ b/test/Constraints/tuple.swift
@@ -61,6 +61,9 @@
 // Scalars don't have .0/.1/etc
 i = j.0 // expected-error{{value of type 'Int' has no member '0'}}
 any.1 // expected-error{{value of type 'Any' has no member '1'}}
+// expected-note@-1{{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
+any = (5.0, 6.0) as (Float, Float)
+_ = (any as! (Float, Float)).1
 
 // Fun with tuples
 protocol PosixErrorReturn {