Skip to content

Commit 2e6c933

Browse files
committed
Merge remote-tracking branch 'origin/swift-4.1-branch' into swift-5.0-branch
2 parents fb31051 + ca1cb64 commit 2e6c933

File tree

63 files changed

+685
-123
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+685
-123
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ Swift 5.0
3333
Swift 4.1
3434
---------
3535

36+
* [SE-0189][]
37+
38+
If an initializer is declared in a different module from a struct, it must
39+
use `self.init(…)` or `self = …` before returning or accessing `self`.
40+
Failure to do so will produce a warning in Swift 4 and an error in Swift 5.
41+
This is to keep a client app from accidentally depending on a library's
42+
implementation details, and matches an existing restriction for classes,
43+
where cross-module initializers must be convenience initializers.
44+
45+
This will most commonly affect code that extends a struct imported from C.
46+
However, most imported C structs are given a zeroing no-argument initializer,
47+
which can be called as `self.init()` before modifying specific properties.
48+
49+
Swift library authors who wish to continue allowing initialization on a
50+
per-member basis should explicitly declare a public memberwise initializer
51+
for clients in other modules to use.
52+
3653
* [SE-0166][] / [SE-0143][]
3754

3855
The standard library now defines the conformances of `Optional`,

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ supported host development operating systems.
5454

5555
#### macOS
5656

57-
To build for macOS, you need [Xcode 9.2](https://developer.apple.com/xcode/downloads/).
57+
To build for macOS, you need [Xcode 9.3 beta](https://developer.apple.com/xcode/downloads/).
5858
The required version of Xcode changes frequently, and is often a beta release.
5959
Check this document or the host information on <https://ci.swift.org> for the
6060
current required version.

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,10 @@ NOTE(candidate_types_inheritance_requirement,none,
14081408
(Type, Type, Type, Type, StringRef))
14091409
NOTE(types_not_equal_requirement,none,
14101410
"requirement specified as %0 == %1%2", (Type, Type, StringRef))
1411+
ERROR(type_is_not_a_class,none,
1412+
"%0 requires that %1 be a class type", (Type, Type, Type))
1413+
NOTE(anyobject_requirement,none,
1414+
"requirement specified as %0 : 'AnyObject'%2", (Type, Type, StringRef))
14111415
ERROR(non_class_cannot_conform_to_class_protocol,none,
14121416
"non-class type %0 cannot conform to class protocol %1",
14131417
(Type, Type))

include/swift/AST/GenericSignature.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
147147
/// requirements, first canonicalizing the types.
148148
static CanGenericSignature getCanonical(
149149
ArrayRef<GenericTypeParamType *> params,
150-
ArrayRef<Requirement> requirements);
150+
ArrayRef<Requirement> requirements,
151+
bool skipValidation = false);
151152

152153
/// Retrieve the generic parameters.
153154
ArrayRef<GenericTypeParamType *> getGenericParams() const {

include/swift/AST/Types.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,16 @@ class alignas(1 << TypeAlignInBits) TypeBase {
696696
/// with a class type.
697697
bool mayHaveSuperclass();
698698

699+
/// Determine whether this type satisfies a class layout constraint, written
700+
/// `T: AnyObject` in the source.
701+
///
702+
/// A class layout constraint is satisfied when we have a single retainable
703+
/// pointer as the representation, which includes:
704+
/// - @objc existentials
705+
/// - class constrained archetypes
706+
/// - classes
707+
bool satisfiesClassConstraint();
708+
699709
/// \brief Determine whether this type can be used as a base type for AST
700710
/// name lookup, which is the case for nominal types, protocol compositions
701711
/// and archetypes.

include/swift/SIL/SILLocation.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,12 @@ class RegularLocation : public SILLocation {
502502
}
503503
};
504504

505+
/// Compiler-generated locations may be applied to instructions without any
506+
/// clear correspondence to an AST node.
507+
static inline RegularLocation getCompilerGeneratedLocation() {
508+
return {SourceLoc()};
509+
}
510+
505511
/// Used to represent a return instruction in user code.
506512
///
507513
/// Allowed on an BranchInst, ReturnInst.
@@ -705,7 +711,8 @@ class SILDebugLocation {
705711
SILLocation Location;
706712

707713
public:
708-
SILDebugLocation() : Scope(nullptr), Location(RegularLocation(SourceLoc())) {}
714+
SILDebugLocation()
715+
: Scope(nullptr), Location(getCompilerGeneratedLocation()) {}
709716
SILDebugLocation(SILLocation Loc, const SILDebugScope *DS)
710717
: Scope(DS), Location(Loc) {}
711718
SILLocation getLocation() const { return Location; }

include/swift/SIL/TypeLowering.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,6 @@ class TypeLowering {
259259

260260
enum class LoweringStyle { Shallow, Deep };
261261

262-
/// Given the result of the expansion heuristic,
263-
/// return appropriate lowering style.
264-
static LoweringStyle getLoweringStyle(bool shouldExpand) {
265-
if (shouldExpand)
266-
return TypeLowering::LoweringStyle::Deep;
267-
return TypeLowering::LoweringStyle::Shallow;
268-
}
269-
270262
//===--------------------------------------------------------------------===//
271263
// DestroyValue
272264
//===--------------------------------------------------------------------===//

lib/AST/GenericSignature.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ static unsigned getRequirementKindOrder(RequirementKind kind) {
150150

151151
CanGenericSignature GenericSignature::getCanonical(
152152
ArrayRef<GenericTypeParamType *> params,
153-
ArrayRef<Requirement> requirements) {
153+
ArrayRef<Requirement> requirements,
154+
bool skipValidation) {
154155
// Canonicalize the parameters and requirements.
155156
SmallVector<GenericTypeParamType*, 8> canonicalParams;
156157
canonicalParams.reserve(params.size());
@@ -172,10 +173,14 @@ CanGenericSignature GenericSignature::getCanonical(
172173
reqt.getLayoutConstraint()));
173174
}
174175

176+
(void)skipValidation;
175177
auto canSig = get(canonicalParams, canonicalRequirements,
176178
/*isKnownCanonical=*/true);
177179

178180
#ifndef NDEBUG
181+
if (skipValidation)
182+
return CanGenericSignature(canSig);
183+
179184
PrettyStackTraceGenericSignature debugStack("canonicalizing", canSig);
180185

181186
// Check that the signature is canonical.

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3026,6 +3026,12 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
30263026
TypeDecl *nestedTypeDecl;
30273027
SmallVector<TypeDecl *, 4> concreteDecls;
30283028
if (auto assocType = depMemTy->getAssocType()) {
3029+
// Check whether this associated type references a protocol to which
3030+
// the base conforms. If not, it's unresolved.
3031+
if (baseEquivClass->conformsTo.find(assocType->getProtocol())
3032+
== baseEquivClass->conformsTo.end())
3033+
return ResolvedType::forUnresolved(baseEquivClass);
3034+
30293035
nestedTypeDecl = assocType;
30303036
} else {
30313037
nestedTypeDecl =

lib/AST/ProtocolConformance.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,9 @@ bool NormalProtocolConformance::hasTypeWitness(AssociatedTypeDecl *assocType,
530530
if (Loader)
531531
resolveLazyInfo();
532532

533-
if (TypeWitnesses.find(assocType) != TypeWitnesses.end()) {
534-
return true;
533+
auto found = TypeWitnesses.find(assocType);
534+
if (found != TypeWitnesses.end()) {
535+
return !found->getSecond().first.isNull();
535536
}
536537
if (resolver) {
537538
PrettyStackTraceRequirement trace("resolving", this, assocType);
@@ -556,24 +557,25 @@ NormalProtocolConformance::getTypeWitnessAndDecl(AssociatedTypeDecl *assocType,
556557
if (known != TypeWitnesses.end())
557558
return known->second;
558559

559-
// If this conformance is in a state where it is inferring type witnesses,
560-
// check tentative witnesses.
561-
if (getState() == ProtocolConformanceState::CheckingTypeWitnesses) {
562-
// If there is a tentative-type-witness function, use it.
563-
if (options.getTentativeTypeWitness) {
564-
if (Type witnessType =
565-
Type(options.getTentativeTypeWitness(this, assocType)))
566-
return { witnessType, nullptr };
567-
}
560+
// If there is a tentative-type-witness function, use it.
561+
if (options.getTentativeTypeWitness) {
562+
if (Type witnessType =
563+
Type(options.getTentativeTypeWitness(this, assocType)))
564+
return { witnessType, nullptr };
565+
}
568566

569-
// Otherwise, we fail; this is the only case in which we can return a
570-
// null type.
567+
// If this conformance is in a state where it is inferring type witnesses but
568+
// we didn't find anything, fail.
569+
if (getState() == ProtocolConformanceState::CheckingTypeWitnesses) {
571570
return { Type(), nullptr };
572571
}
573572

574573
// Otherwise, resolve the type witness.
575574
PrettyStackTraceRequirement trace("resolving", this, assocType);
576575
assert(resolver && "Unable to resolve type witness");
576+
577+
// Block recursive resolution of this type witness.
578+
TypeWitnesses[assocType] = { Type(), nullptr };
577579
resolver->resolveTypeWitness(this, assocType);
578580

579581
known = TypeWitnesses.find(assocType);
@@ -586,7 +588,9 @@ void NormalProtocolConformance::setTypeWitness(AssociatedTypeDecl *assocType,
586588
TypeDecl *typeDecl) const {
587589
assert(getProtocol() == cast<ProtocolDecl>(assocType->getDeclContext()) &&
588590
"associated type in wrong protocol");
589-
assert(TypeWitnesses.count(assocType) == 0 && "Type witness already known");
591+
assert((TypeWitnesses.count(assocType) == 0 ||
592+
TypeWitnesses[assocType].first.isNull()) &&
593+
"Type witness already known");
590594
assert((!isComplete() || isInvalid()) && "Conformance already complete?");
591595
assert(!type->hasArchetype() && "type witnesses must be interface types");
592596
TypeWitnesses[assocType] = std::make_pair(type, typeDecl);

lib/AST/Type.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,10 @@ bool TypeBase::mayHaveSuperclass() {
13851385
return is<DynamicSelfType>();
13861386
}
13871387

1388+
bool TypeBase::satisfiesClassConstraint() {
1389+
return mayHaveSuperclass() || isObjCExistentialType();
1390+
}
1391+
13881392
Type TypeBase::getSuperclass() {
13891393
auto *nominalDecl = getAnyNominal();
13901394
auto *classDecl = dyn_cast_or_null<ClassDecl>(nominalDecl);

lib/IDE/TypeReconstruction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1719,7 +1719,7 @@ static void VisitNodeInOut(
17191719
VisitNodeResult type_result;
17201720
VisitNode(ast, cur_node->getFirstChild(), type_result);
17211721
if (type_result._types.size() == 1 && type_result._types[0]) {
1722-
result._types.push_back(Type(LValueType::get(type_result._types[0])));
1722+
result._types.push_back(Type(InOutType::get(type_result._types[0])));
17231723
} else {
17241724
result._error = "couldn't resolve referent type";
17251725
}

lib/IRGen/ProtocolInfo.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,12 @@ class ProtocolInfo final :
227227
if (witness.matchesFunction(function))
228228
return getNonBaseWitnessIndex(&witness);
229229
}
230-
llvm_unreachable("didn't find entry for function");
230+
231+
// FIXME: This should be an "unreachable", but Swift < 4.1 had an
232+
// existing bug here that depends on (effectively) getting this
233+
// result in non-Asserts builds. Emulate that behavior for now,
234+
// but only on the Swift 4.1 branch.
235+
return WitnessIndex(0, false);
231236
}
232237

233238
/// Return the witness index for the type metadata access function

lib/SIL/TypeLowering.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,10 +2298,8 @@ TypeConverter::checkForABIDifferences(SILType type1, SILType type2) {
22982298
// Classes, class-constrained archetypes, and pure-ObjC existential types
22992299
// all have single retainable pointer representation; optionality change
23002300
// is allowed.
2301-
if ((type1.getSwiftRValueType()->mayHaveSuperclass() ||
2302-
type1.getSwiftRValueType()->isObjCExistentialType()) &&
2303-
(type2.getSwiftRValueType()->mayHaveSuperclass() ||
2304-
type2.getSwiftRValueType()->isObjCExistentialType()))
2301+
if (type1.getSwiftRValueType()->satisfiesClassConstraint() &&
2302+
type2.getSwiftRValueType()->satisfiesClassConstraint())
23052303
return ABIDifference::Trivial;
23062304

23072305
// Function parameters are ABI compatible if their differences are

lib/SILGen/SILGenPattern.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2315,7 +2315,13 @@ void PatternMatchEmission::emitCaseBody(CaseStmt *caseBlock) {
23152315

23162316
// Implicitly break out of the pattern match statement.
23172317
if (SGF.B.hasValidInsertionPoint()) {
2318-
SGF.emitBreakOutOf(CleanupLocation(caseBlock), PatternMatchStmt);
2318+
// Case blocks without trailing braces have ambiguous cleanup locations.
2319+
SILLocation cleanupLoc = getCompilerGeneratedLocation();
2320+
if (auto *braces = dyn_cast<BraceStmt>(caseBlock->getBody()))
2321+
if (braces->getNumElements() == 1 &&
2322+
dyn_cast_or_null<DoStmt>(braces->getElement(0).dyn_cast<Stmt *>()))
2323+
cleanupLoc = CleanupLocation(caseBlock);
2324+
SGF.emitBreakOutOf(cleanupLoc, PatternMatchStmt);
23192325
}
23202326
}
23212327

lib/SILGen/SILGenProlog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ unsigned SILGenFunction::emitProlog(ArrayRef<ParameterList *> paramLists,
522522
// Record the ArgNo of the artificial $error inout argument.
523523
unsigned ArgNo = emitter.getNumArgs();
524524
if (throws) {
525-
RegularLocation Loc{SourceLoc()};
525+
RegularLocation Loc = getCompilerGeneratedLocation();
526526
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC))
527527
Loc = AFD->getThrowsLoc();
528528
else if (auto *ACE = dyn_cast<AbstractClosureExpr>(DC))

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2177,7 +2177,7 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
21772177
// Use an empty location for the alloc_stack. If Loc is variable declaration
21782178
// the alloc_stack would look like the storage of that variable.
21792179
auto *ControlVariableBox =
2180-
B.createAllocStack(RegularLocation(SourceLoc()), IVType);
2180+
B.createAllocStack(getCompilerGeneratedLocation(), IVType);
21812181

21822182
// Find all the return blocks in the function, inserting a dealloc_stack
21832183
// before the return.

lib/SILOptimizer/Transforms/FunctionSignatureOpts.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -979,11 +979,11 @@ static void createArgumentRelease(SILBuilder &Builder, ArgumentDescriptor &AD) {
979979
if (Arg->getType().isAddress()) {
980980
assert(AD.PInfo->getConvention() == ParameterConvention::Indirect_In
981981
&& F.getConventions().useLoweredAddresses());
982-
Builder.createDestroyAddr(RegularLocation(SourceLoc()),
982+
Builder.createDestroyAddr(getCompilerGeneratedLocation(),
983983
F.getArguments()[AD.Index]);
984984
return;
985985
}
986-
Builder.createReleaseValue(RegularLocation(SourceLoc()),
986+
Builder.createReleaseValue(getCompilerGeneratedLocation(),
987987
F.getArguments()[AD.Index],
988988
Builder.getDefaultAtomicity());
989989
}
@@ -1028,13 +1028,14 @@ OwnedToGuaranteedAddResultRelease(ResultDescriptor &RD, SILBuilder &Builder,
10281028
SILInstruction *Call = findOnlyApply(F);
10291029
if (auto AI = dyn_cast<ApplyInst>(Call)) {
10301030
Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(AI)));
1031-
Builder.createRetainValue(RegularLocation(SourceLoc()), AI,
1031+
Builder.createRetainValue(getCompilerGeneratedLocation(), AI,
10321032
Builder.getDefaultAtomicity());
10331033
} else {
10341034
SILBasicBlock *NormalBB = cast<TryApplyInst>(Call)->getNormalBB();
10351035
Builder.setInsertionPoint(&*NormalBB->begin());
1036-
Builder.createRetainValue(RegularLocation(SourceLoc()),
1037-
NormalBB->getArgument(0), Builder.getDefaultAtomicity());
1036+
Builder.createRetainValue(getCompilerGeneratedLocation(),
1037+
NormalBB->getArgument(0),
1038+
Builder.getDefaultAtomicity());
10381039
}
10391040
}
10401041

lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,23 @@ static bool expandCopyAddr(CopyAddrInst *CA) {
112112
// retain_value %new : $*T
113113
IsTake_t IsTake = CA->isTakeOfSrc();
114114
if (IsTake_t::IsNotTake == IsTake) {
115-
TL.emitLoweredCopyValue(Builder, CA->getLoc(), New,
116-
TypeLowering::getLoweringStyle(expand));
115+
if (expand) {
116+
TL.emitLoweredCopyValueDeep(Builder, CA->getLoc(), New);
117+
} else {
118+
TL.emitCopyValue(Builder, CA->getLoc(), New);
119+
}
117120
}
118121

119122
// If we are not initializing:
120123
// strong_release %old : $*T
121124
// *or*
122125
// release_value %old : $*T
123126
if (Old) {
124-
TL.emitLoweredDestroyValue(Builder, CA->getLoc(), Old,
125-
TypeLowering::getLoweringStyle(expand));
127+
if (expand) {
128+
TL.emitLoweredDestroyValueDeep(Builder, CA->getLoc(), Old);
129+
} else {
130+
TL.emitDestroyValue(Builder, CA->getLoc(), Old);
131+
}
126132
}
127133
}
128134

@@ -155,8 +161,11 @@ static bool expandDestroyAddr(DestroyAddrInst *DA) {
155161
LoadInst *LI = Builder.createLoad(DA->getLoc(), Addr,
156162
LoadOwnershipQualifier::Unqualified);
157163
auto &TL = Module.getTypeLowering(Type);
158-
TL.emitLoweredDestroyValue(Builder, DA->getLoc(), LI,
159-
TypeLowering::getLoweringStyle(expand));
164+
if (expand) {
165+
TL.emitLoweredDestroyValueDeep(Builder, DA->getLoc(), LI);
166+
} else {
167+
TL.emitDestroyValue(Builder, DA->getLoc(), LI);
168+
}
160169
}
161170

162171
++NumExpand;

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,12 @@ static void replaceDestroy(DestroyAddrInst *DAI, SILValue NewValue) {
350350

351351
bool expand = shouldExpand(DAI->getModule(),
352352
DAI->getOperand()->getType().getObjectType());
353-
TL.emitLoweredDestroyValue(Builder, DAI->getLoc(), NewValue,
354-
Lowering::TypeLowering::getLoweringStyle(expand));
353+
if (expand) {
354+
TL.emitLoweredDestroyValueDeep(Builder, DAI->getLoc(), NewValue);
355+
} else {
356+
TL.emitDestroyValue(Builder, DAI->getLoc(), NewValue);
357+
}
358+
355359
DAI->eraseFromParent();
356360
}
357361

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ swift::createIncrementBefore(SILValue Ptr, SILInstruction *InsertPt) {
5050

5151
// Set up the builder we use to insert at our insertion point.
5252
SILBuilder B(InsertPt);
53-
auto Loc = RegularLocation(SourceLoc());
53+
auto Loc = getCompilerGeneratedLocation();
5454

5555
// If Ptr is refcounted itself, create the strong_retain and
5656
// return.
@@ -75,7 +75,7 @@ swift::createDecrementBefore(SILValue Ptr, SILInstruction *InsertPt) {
7575

7676
// Setup the builder we will use to insert at our insertion point.
7777
SILBuilder B(InsertPt);
78-
auto Loc = RegularLocation(SourceLoc());
78+
auto Loc = getCompilerGeneratedLocation();
7979

8080
// If Ptr has reference semantics itself, create a strong_release.
8181
if (Ptr->getType().isReferenceCounted(B.getModule())) {

0 commit comments

Comments
 (0)