Skip to content

Commit 66fc743

Browse files
committed
Merge branch 'master' into remotemirror-hide-reflection-sections
2 parents 553ef86 + 2380950 commit 66fc743

26 files changed

+764
-350
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,25 @@ Swift 5.0
4747
Swift 4.1
4848
---------
4949

50+
* [SE-0075][]
51+
52+
Compile-time testing for the existence and importability of modules is now
53+
implemented as a build configuration test. The `canImport` test allows
54+
the development of features that require a possibly-failing import
55+
declaration across multiple platforms.
56+
57+
```swift
58+
#if canImport(UIKit)
59+
import UIKit
60+
class MyView : UIView {}
61+
#elseif canImport(AppKit)
62+
import AppKit
63+
class MyView : NSView {}
64+
#else
65+
class MyView : CustomView {}
66+
#endif
67+
```
68+
5069
* [SE-0189][]
5170

5271
If an initializer is declared in a different module from a struct, it must

cmake/modules/AddSwift.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ function(_add_variant_c_compile_flags)
248248
list(APPEND result "-D_DLL")
249249
# NOTE: We assume that we are using VS 2015 U2+
250250
list(APPEND result "-D_ENABLE_ATOMIC_ALIGNMENT_FIX")
251+
252+
# msvcprt's std::function requires RTTI, but we do not want RTTI data.
253+
# Emulate /GR-
254+
if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
255+
list(APPEND result -frtti)
256+
list(APPEND result -Xclang;-fno-rtti-data)
257+
endif()
251258
endif()
252259

253260
if(CFLAGS_ENABLE_ASSERTIONS)

cmake/modules/SwiftHandleGybSources.cmake

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ function(handle_gyb_source_single dependency_out_var_name)
3737
GYB_SINGLE # prefix
3838
"${options}" "${single_value_args}" "${multi_value_args}" ${ARGN})
3939

40-
set(gyb_flags
41-
${SWIFT_GYB_FLAGS}
42-
${GYB_SINGLE_FLAGS})
43-
4440
set(gyb_tool "${SWIFT_SOURCE_DIR}/utils/gyb")
4541
set(gyb_tool_source "${gyb_tool}" "${gyb_tool}.py")
4642

@@ -62,11 +58,9 @@ function(handle_gyb_source_single dependency_out_var_name)
6258
COMMAND
6359
"${CMAKE_COMMAND}" -E make_directory "${dir}"
6460
COMMAND
65-
"${PYTHON_EXECUTABLE}" "${gyb_tool}" "${gyb_flags}"
66-
-o "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_SOURCE}"
61+
"${PYTHON_EXECUTABLE}" "${gyb_tool}" ${SWIFT_GYB_FLAGS} ${GYB_SINGLE_FLAGS} -o "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_SOURCE}"
6762
COMMAND
68-
"${CMAKE_COMMAND}" -E copy_if_different
69-
"${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_OUTPUT}"
63+
"${CMAKE_COMMAND}" -E copy_if_different "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_OUTPUT}"
7064
COMMAND
7165
"${CMAKE_COMMAND}" -E remove "${GYB_SINGLE_OUTPUT}.tmp"
7266
OUTPUT "${GYB_SINGLE_OUTPUT}"

include/swift/IDE/DigesterEnums.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ KEY(ownership)
9191
KEY(superclassUsr)
9292
KEY(parentExtensionReqs)
9393
KEY(hasDefaultArg)
94+
KEY(conformingProtocols)
9495

9596
KNOWN_TYPE(Optional)
9697
KNOWN_TYPE(ImplicitlyUnwrappedOptional)

include/swift/IRGen/Linking.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,9 +756,6 @@ class LinkEntity {
756756
bool isForeignTypeMetadataCandidate() const {
757757
return getKind() == Kind::ForeignTypeMetadataCandidate;
758758
}
759-
bool isObjCClassRef() const {
760-
return getKind() == Kind::ObjCClassRef;
761-
}
762759

763760
/// Determine whether this entity will be weak-imported.
764761
bool isWeakImported(ModuleDecl *module) const {

include/swift/Syntax/CMakeLists.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
set(line_directive "#line" "%(line)d" "\"%(file)s\"")
2-
set(SWIFT_GYB_FLAGS
3-
--line-directive "'${line_directive}'")
1+
if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
2+
set(SWIFT_GYB_FLAGS --line-directive "^\"#line %(line)d \\\"%(file)s\\\"^\"")
3+
else()
4+
set(SWIFT_GYB_FLAGS --line-directive "\'#line" "%(line)d" "\"%(file)s\"\'")
5+
endif()
46

57
set(generated_include_sources
68
SyntaxKind.h.gyb

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,15 +2442,6 @@ IRGenModule::getAddrOfLLVMVariableOrGOTEquivalent(LinkEntity entity,
24422442
Alignment alignment,
24432443
llvm::Type *defaultType,
24442444
ConstantReference::Directness forceIndirectness) {
2445-
// ObjC class references can always be directly referenced, even in
2446-
// the weird cases where we don't see a definition.
2447-
if (entity.isObjCClassRef()) {
2448-
auto value = getAddrOfObjCClassRef(
2449-
const_cast<ClassDecl *>(cast<ClassDecl>(entity.getDecl())));
2450-
return { cast<llvm::Constant>(value.getAddress()),
2451-
ConstantReference::Direct };
2452-
}
2453-
24542445
// Ensure the variable is at least forward-declared.
24552446
if (entity.isForeignTypeMetadataCandidate()) {
24562447
auto foreignCandidate
@@ -2528,7 +2519,7 @@ IRGenModule::getTypeEntityReference(NominalTypeDecl *decl) {
25282519

25292520
kind = TypeMetadataRecordKind::IndirectObjCClass;
25302521
defaultTy = TypeMetadataPtrTy;
2531-
entity = LinkEntity::forObjCClassRef(clas);
2522+
entity = LinkEntity::forObjCClass(clas);
25322523
} else {
25332524
// A reference to a concrete type.
25342525
// TODO: consider using a symbolic reference (i.e. a symbol string
@@ -2543,8 +2534,8 @@ IRGenModule::getTypeEntityReference(NominalTypeDecl *decl) {
25432534

25442535
// Adjust the flags now that we know whether the reference to this
25452536
// entity will be indirect.
2546-
if (ref.isIndirect()) {
2547-
assert(kind == TypeMetadataRecordKind::DirectNominalTypeDescriptor);
2537+
if (ref.isIndirect() &&
2538+
kind == TypeMetadataRecordKind::DirectNominalTypeDescriptor) {
25482539
kind = TypeMetadataRecordKind::IndirectNominalTypeDescriptor;
25492540
}
25502541

lib/SILGen/SILGenPoly.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,9 @@ class ResultPlanner {
15731573
///
15741574
/// Valid: reabstraction info, InnerResult, OuterResult.
15751575
ReabstractDirectToDirect,
1576+
1577+
/// Ignore the next direct inner result, since the outer is 'Void'.
1578+
IgnoreDirectResult,
15761579
};
15771580

15781581
Operation(Kind kind) : TheKind(kind) {}
@@ -1717,6 +1720,24 @@ class ResultPlanner {
17171720
SILResultInfo outerResult,
17181721
SILValue optOuterResultAddr);
17191722

1723+
void planIgnoredResult(AbstractionPattern innerOrigType,
1724+
CanType innerSubstType, PlanData &planData) {
1725+
if (innerOrigType.isTuple()) {
1726+
auto innerSubstTuple = cast<TupleType>(innerSubstType);
1727+
for (unsigned i = 0, n = innerSubstTuple->getNumElements(); i != n; ++i)
1728+
planIgnoredResult(innerOrigType.getTupleElementType(i),
1729+
innerSubstTuple.getElementType(i), planData);
1730+
return;
1731+
}
1732+
1733+
auto innerResult = claimNextInnerResult(planData);
1734+
if (innerResult.isFormalIndirect() &&
1735+
SGF.silConv.isSILIndirect(innerResult))
1736+
(void)addInnerIndirectResultTemporary(planData, innerResult);
1737+
else
1738+
addIgnoreDirectResult();
1739+
}
1740+
17201741
/// Claim the next inner result from the plan data.
17211742
SILResultInfo claimNextInnerResult(PlanData &data) {
17221743
return claimNext(data.InnerResults);
@@ -1866,6 +1887,10 @@ class ResultPlanner {
18661887
op.OuterOrigType = outerOrigType;
18671888
op.OuterSubstType = outerSubstType;
18681889
}
1890+
1891+
void addIgnoreDirectResult() {
1892+
(void)addOperation(Operation::IgnoreDirectResult);
1893+
}
18691894
};
18701895

18711896
} // end anonymous namespace
@@ -1876,6 +1901,13 @@ void ResultPlanner::plan(AbstractionPattern innerOrigType,
18761901
AbstractionPattern outerOrigType,
18771902
CanType outerSubstType,
18781903
PlanData &planData) {
1904+
// Conversion from `() -> T` to `() -> Void` is allowed when
1905+
// the argument is a closure.
1906+
if (!innerSubstType->isVoid() && outerSubstType->isVoid()) {
1907+
planIgnoredResult(innerOrigType, innerSubstType, planData);
1908+
return;
1909+
}
1910+
18791911
// The substituted types must match up in tuple-ness and arity.
18801912
assert(
18811913
isa<TupleType>(innerSubstType) == isa<TupleType>(outerSubstType) ||
@@ -2584,6 +2616,10 @@ void ResultPlanner::execute(ArrayRef<SILValue> innerDirectResults,
25842616
case Operation::InjectOptionalIndirect:
25852617
SGF.B.createInjectEnumAddr(Loc, op.OuterResultAddr, op.SomeDecl);
25862618
continue;
2619+
2620+
case Operation::IgnoreDirectResult:
2621+
(void)claimNext(innerDirectResults);
2622+
continue;
25872623
}
25882624
llvm_unreachable("bad operation kind");
25892625
}

lib/Sema/CSRanking.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,14 +1007,32 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
10071007
// Compare the type variable bindings.
10081008
auto &tc = cs.getTypeChecker();
10091009
for (auto &binding : diff.typeBindings) {
1010+
auto type1 = binding.bindings[idx1];
1011+
auto type2 = binding.bindings[idx2];
1012+
1013+
auto &impl = binding.typeVar->getImpl();
1014+
1015+
if (auto *locator = impl.getLocator()) {
1016+
auto path = locator->getPath();
1017+
if (!path.empty() &&
1018+
path.back().getKind() == ConstraintLocator::ClosureResult) {
1019+
// Since we support `() -> T` to `() -> Void` and
1020+
// `() -> Never` to `() -> T` conversions, it's always
1021+
// preferable to pick `T` rather than `Never` with
1022+
// all else being equal.
1023+
if (type2->isUninhabited())
1024+
++score1;
1025+
1026+
if (type1->isUninhabited())
1027+
++score2;
1028+
}
1029+
}
1030+
10101031
// If the type variable isn't one for which we should be looking at the
10111032
// bindings, don't.
1012-
if (!binding.typeVar->getImpl().prefersSubtypeBinding())
1033+
if (!impl.prefersSubtypeBinding())
10131034
continue;
10141035

1015-
auto type1 = binding.bindings[idx1];
1016-
auto type2 = binding.bindings[idx2];
1017-
10181036
// If the types are equivalent, there's nothing more to do.
10191037
if (type1->isEqual(type2))
10201038
continue;

lib/Sema/CSSimplify.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,10 +1212,8 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
12121212
return result;
12131213

12141214
// Result type can be covariant (or equal).
1215-
return matchTypes(func1->getResult(), func2->getResult(), subKind,
1216-
subflags,
1217-
locator.withPathElement(
1218-
ConstraintLocator::FunctionResult));
1215+
return matchTypes(func1->getResult(), func2->getResult(), subKind, subflags,
1216+
locator.withPathElement(ConstraintLocator::FunctionResult));
12191217
}
12201218

12211219
ConstraintSystem::TypeMatchResult
@@ -1501,6 +1499,8 @@ ConstraintSystem::TypeMatchResult
15011499
ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
15021500
TypeMatchOptions flags,
15031501
ConstraintLocatorBuilder locator) {
1502+
auto origType1 = type1;
1503+
15041504
bool isArgumentTupleConversion
15051505
= kind == ConstraintKind::ArgumentTupleConversion ||
15061506
kind == ConstraintKind::OperatorArgumentTupleConversion;
@@ -2243,7 +2243,32 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
22432243
// Allow '() -> T' to '() -> ()' and '() -> Never' to '() -> T' for closure
22442244
// literals.
22452245
if (auto elt = locator.last()) {
2246-
if (elt->getKind() == ConstraintLocator::ClosureResult) {
2246+
auto isClosureResult = [&]() {
2247+
if (elt->getKind() == ConstraintLocator::ClosureResult)
2248+
return true;
2249+
2250+
// If constraint is matching function results where
2251+
// left-hand side is a 'closure result' we need to allow
2252+
// certain implicit conversions.
2253+
if (elt->getKind() != ConstraintLocator::FunctionResult)
2254+
return false;
2255+
2256+
if (auto *typeVar = origType1->getAs<TypeVariableType>()) {
2257+
auto *locator = typeVar->getImpl().getLocator();
2258+
if (!locator)
2259+
return false;
2260+
2261+
auto path = locator->getPath();
2262+
if (path.empty())
2263+
return false;
2264+
2265+
return path.back().getKind() == ConstraintLocator::ClosureResult;
2266+
}
2267+
2268+
return false;
2269+
};
2270+
2271+
if (isClosureResult()) {
22472272
if (concrete && kind >= ConstraintKind::Subtype &&
22482273
(type1->isUninhabited() || type2->isVoid())) {
22492274
increaseScore(SK_FunctionConversion);

0 commit comments

Comments
 (0)