Merge pull request #7233 from rudkx/fix-rdar30311052-3.1
[Sema] Penalize conversions to Any.
diff --git a/include/swift/AST/AnyFunctionRef.h b/include/swift/AST/AnyFunctionRef.h
index c2e1a90..2d5e1fb 100644
--- a/include/swift/AST/AnyFunctionRef.h
+++ b/include/swift/AST/AnyFunctionRef.h
@@ -176,6 +176,16 @@
}
llvm_unreachable("unexpected AnyFunctionRef representation");
}
+
+ GenericSignature *getGenericSignature() const {
+ if (auto afd = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
+ return afd->getGenericSignature();
+ }
+ if (auto ce = TheFunction.dyn_cast<AbstractClosureExpr *>()) {
+ return ce->getGenericSignatureOfContext();
+ }
+ llvm_unreachable("unexpected AnyFunctionRef representation");
+ }
};
#if SWIFT_COMPILER_IS_MSVC
#pragma warning(pop)
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index d788a4a..32389f5 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -23,6 +23,7 @@
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/ForeignErrorConvention.h"
+#include "swift/AST/GenericEnvironment.h"
#include "swift/Basic/Fallthrough.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/AST/Attr.h"
@@ -742,9 +743,17 @@
// from the function to which the argument is attached.
if (constant && !constant->isDefaultArgGenerator())
if (auto function = constant->getAnyFunctionRef()) {
- auto getCanonicalType = [&](Type t) -> CanType {
- if (genericSig)
- return genericSig->getCanonicalTypeInContext(t, *M.getSwiftModule());
+ // NB: The generic signature may be elided from the lowered function type
+ // if the function is in a fully-specialized context, but we still need to
+ // canonicalize references to the generic parameters that may appear in
+ // non-canonical types in that context. We need the original generic
+ // signature from the AST for that.
+ auto origGenericSig
+ = function->getGenericSignature();
+ auto getCanonicalType = [origGenericSig, &M](Type t) -> CanType {
+ if (origGenericSig)
+ return origGenericSig->getCanonicalTypeInContext(t,
+ *M.getSwiftModule());
return t->getCanonicalType();
};
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 1c735b8..0803d3e 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -408,6 +408,11 @@
ArrayRef<SILValue> Args, bool isNonThrowing,
SILFunction &F,
SILOpenedArchetypesState &OpenedArchetypes) {
+ if (!F.getModule().Types.getCurGenericContext())
+ assert(Callee->getType().castTo<SILFunctionType>()
+ ->substGenericArgs(F.getModule(), Subs)
+ == SubstCalleeTy.getSwiftRValueType());
+
SmallVector<SILValue, 32> TypeDependentOperands;
collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
SubstCalleeTy.getSwiftRValueType(), Subs);
diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp
index 670e9b2..3fbfeba 100644
--- a/lib/SILGen/SILGenProlog.cpp
+++ b/lib/SILGen/SILGenProlog.cpp
@@ -344,7 +344,9 @@
}
}
-static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture,
+static void emitCaptureArguments(SILGenFunction &gen,
+ AnyFunctionRef closure,
+ CapturedValue capture,
unsigned ArgNo) {
auto *VD = capture.getDecl();
@@ -357,7 +359,12 @@
auto interfaceType = cast<VarDecl>(VD)->getInterfaceType();
if (!interfaceType->hasTypeParameter()) return interfaceType;
- auto genericEnv = gen.F.getGenericEnvironment();
+ // NB: The generic signature may be elided from the lowered function type
+ // if the function is in a fully-specialized context, but we still need to
+ // canonicalize references to the generic parameters that may appear in
+ // non-canonical types in that context. We need the original generic
+ // environment from the AST for that.
+ auto genericEnv = closure.getGenericEnvironment();
return genericEnv->mapTypeIntoContext(gen.F.getModule().getSwiftModule(),
interfaceType);
};
@@ -446,7 +453,7 @@
return;
}
- emitCaptureArguments(*this, capture, ++ArgNo);
+ emitCaptureArguments(*this, TheClosure, capture, ++ArgNo);
}
}
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index 958d9b7..28e59a6 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -3548,7 +3548,7 @@
// Always look at the parameters in the last parameter list.
for (auto param : *afd->getParameterLists().back()) {
- paramTypes.push_back(getTypeNameForOmission(param->getType())
+ paramTypes.push_back(getTypeNameForOmission(param->getInterfaceType())
.withDefaultArgument(param->isDefaultArgument()));
}
@@ -3616,10 +3616,10 @@
Optional<Identifier> TypeChecker::omitNeedlessWords(VarDecl *var) {
auto &Context = var->getASTContext();
- if (!var->hasType())
+ if (!var->hasInterfaceType())
validateDecl(var);
- if (var->isInvalid() || !var->hasType())
+ if (var->isInvalid() || !var->hasInterfaceType())
return None;
if (var->getName().empty())
@@ -3650,7 +3650,7 @@
// Omit needless words.
StringScratchSpace scratch;
- OmissionTypeName typeName = getTypeNameForOmission(var->getType());
+ OmissionTypeName typeName = getTypeNameForOmission(var->getInterfaceType());
OmissionTypeName contextTypeName = getTypeNameForOmission(contextType);
if (::omitNeedlessWords(name, { }, "", typeName, contextTypeName, { },
/*returnsSelf=*/false, true, allPropertyNames,
diff --git a/test/SILGen/capture-canonicalization.swift b/test/SILGen/capture-canonicalization.swift
new file mode 100644
index 0000000..6ecdf3d
--- /dev/null
+++ b/test/SILGen/capture-canonicalization.swift
@@ -0,0 +1,14 @@
+// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+
+struct Foo<T> {}
+struct Bar {}
+
+extension Foo where T == Bar {
+ func foo(x: T) -> Bar {
+ // CHECK-LABEL: sil shared @{{.*}}3foo{{.*}}4foo2{{.*}} : $@convention(thin) (Bar) -> Bar
+ func foo2() -> Bar {
+ return x
+ }
+ return foo2()
+ }
+}
diff --git a/test/SourceKit/Misc/ignore_bridging_pch.swift b/test/SourceKit/Misc/ignore_bridging_pch.swift
new file mode 100644
index 0000000..b2c9812
--- /dev/null
+++ b/test/SourceKit/Misc/ignore_bridging_pch.swift
@@ -0,0 +1,7 @@
+// RUN: %sourcekitd-test -req=complete -pos=5:3 %s -- -enable-bridging-pch %s | %FileCheck %s
+// RUN: %sourcekitd-test -req=complete -pos=5:3 %s -- -disable-bridging-pch %s | %FileCheck %s
+
+var s = 10
+s.
+
+// CHECK: littleEndian
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
index 787030e..2ff19fa 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
@@ -370,6 +370,9 @@
continue;
if (Arg == "-embed-bitcode")
continue;
+ if (Arg == "-enable-bridging-pch" ||
+ Arg == "-disable-bridging-pch")
+ continue;
NewArgs.push_back(CArg);
}
}
diff --git a/validation-test/Sema/protocol_typo_correction.swift b/validation-test/Sema/protocol_typo_correction.swift
new file mode 100644
index 0000000..14feac4
--- /dev/null
+++ b/validation-test/Sema/protocol_typo_correction.swift
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %target-swift-frontend -emit-module -D LIB %s -o %t/Lib.swiftmodule
+// RUN: %target-swift-frontend -I %t -typecheck %s -verify
+// REQUIRES: objc_interop
+
+#if LIB
+
+import Foundation
+
+@objc public protocol Proto {
+ @objc optional func method(_: Int, for object: NSObject, dividing double: Double)
+}
+
+#else
+
+import Foundation
+import Lib
+
+class Impl: Proto {
+ func methodWithInt(_: Int, forObject object: NSObject, dividingDouble: Double) { }
+ // expected-warning@-1 {{instance method 'methodWithInt(_:forObject:dividingDouble:)' nearly matches optional requirement 'method(_:for:dividing:)' of protocol 'Proto'}}
+ // expected-note@-2{{rename to 'method(_:for:dividing:)' to satisfy this requirement}}{{8-21=method}}{{30-39=for}}{{58-58=dividing }}{{none}}
+ // expected-note@-3{{move 'methodWithInt(_:forObject:dividingDouble:)' to an extension to silence this warning}}
+ // expected-note@-4{{make 'methodWithInt(_:forObject:dividingDouble:)' private to silence this warning}}{{3-3=private }}
+}
+
+#endif