Skip to content

Commit ddaa390

Browse files
committed
Merge branch 'master' into synthesize-equatable-hashable
2 parents 715ba63 + d866ebf commit ddaa390

30 files changed

+991
-361
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,6 +2209,9 @@ class ValueDecl : public Decl {
22092209
return result;
22102210
}
22112211

2212+
/// Determine whether this Decl has either Private or FilePrivate access.
2213+
bool isOutermostPrivateOrFilePrivateScope() const;
2214+
22122215
/// Returns the outermost DeclContext from which this declaration can be
22132216
/// accessed, or null if the declaration is public.
22142217
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,11 @@ ERROR(witness_requires_dynamic_self,none,
14521452
"method %0 in non-final class %1 must return `Self` to conform to "
14531453
"protocol %2",
14541454
(DeclName, Type, Type))
1455+
ERROR(witness_requires_class_implementation,none,
1456+
"method %0 in non-final class %1 cannot be implemented in a "
1457+
"protocol extension because it returns `Self` and has associated type "
1458+
"requirements",
1459+
(DeclName, Type))
14551460
ERROR(witness_not_accessible_proto,none,
14561461
"%select{initializer %1|method %1|%select{|setter for }2property %1"
14571462
"|subscript%select{| setter}2}0 must be declared "
@@ -3115,6 +3120,13 @@ ERROR(invalid_weak_ownership_not_optional,none,
31153120
"'weak' variable should have optional type %0", (Type))
31163121
ERROR(invalid_weak_let,none,
31173122
"'weak' must be a mutable variable, because it may change at runtime", ())
3123+
ERROR(ownership_invalid_in_protocols,none,
3124+
"'%select{strong|weak|unowned|unowned}0' cannot be applied to a property declaration in a protocol",
3125+
(/*Ownership*/unsigned))
3126+
WARNING(ownership_invalid_in_protocols_compat_warning,none,
3127+
"'%select{strong|weak|unowned|unowned}0' should not be applied to a property declaration "
3128+
"in a protocol and will be disallowed in future versions",
3129+
(/*Ownership*/unsigned))
31183130

31193131
// required
31203132
ERROR(required_initializer_nonclass,none,

include/swift/AST/Types.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3520,10 +3520,16 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
35203520

35213521
CanType getSelfInstanceType() const;
35223522

3523-
/// If this a @convention(witness_method) function with an abstract
3524-
/// self parameter, return the protocol constraint for the Self type.
3523+
/// If this is a @convention(witness_method) function with a protocol
3524+
/// constrained self parameter, return the protocol constraint for
3525+
/// the Self type.
35253526
ProtocolDecl *getDefaultWitnessMethodProtocol(ModuleDecl &M) const;
35263527

3528+
/// If this is a @convention(witness_method) function with a class
3529+
/// constrained self parameter, return the class constraint for the
3530+
/// Self type.
3531+
ClassDecl *getWitnessMethodClass(ModuleDecl &M) const;
3532+
35273533
ExtInfo getExtInfo() const { return ExtInfo(SILFunctionTypeBits.ExtInfo); }
35283534

35293535
/// \brief Returns the language-level calling convention of the function.

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -533,25 +533,6 @@ void ASTMangler::appendSymbolKind(SymbolKind SKind) {
533533
}
534534
}
535535

536-
/// Returns true if one of the ancestor DeclContexts of \p D is either marked
537-
/// private or is a local context.
538-
static bool isInPrivateOrLocalContext(const ValueDecl *D) {
539-
const DeclContext *DC = D->getDeclContext();
540-
if (!DC->isTypeContext()) {
541-
assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
542-
"unexpected context kind");
543-
return DC->isLocalContext();
544-
}
545-
546-
auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
547-
if (nominal == nullptr)
548-
return false;
549-
550-
if (nominal->getFormalAccess() <= AccessLevel::FilePrivate)
551-
return true;
552-
return isInPrivateOrLocalContext(nominal);
553-
}
554-
555536
static bool getUnnamedParamIndex(const ParameterList *ParamList,
556537
const ParamDecl *D,
557538
unsigned &UnnamedIndex) {
@@ -593,11 +574,8 @@ static unsigned getUnnamedParamIndex(const ParamDecl *D) {
593574
}
594575

595576
static StringRef getPrivateDiscriminatorIfNecessary(const ValueDecl *decl) {
596-
if (!decl->hasAccess() ||
597-
decl->getFormalAccess() > AccessLevel::FilePrivate ||
598-
isInPrivateOrLocalContext(decl)) {
577+
if (!decl->isOutermostPrivateOrFilePrivateScope())
599578
return StringRef();
600-
}
601579

602580
// Mangle non-local private declarations with a textual discriminator
603581
// based on their enclosing file.

lib/AST/Decl.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,34 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
14331433
llvm_unreachable("bad access semantics");
14341434
}
14351435

1436+
static bool hasPrivateOrFilePrivateFormalAccess(const ValueDecl *D) {
1437+
return D->hasAccess() && D->getFormalAccess() <= AccessLevel::FilePrivate;
1438+
}
1439+
1440+
/// Returns true if one of the ancestor DeclContexts of this ValueDecl is either
1441+
/// marked private or fileprivate or is a local context.
1442+
static bool isInPrivateOrLocalContext(const ValueDecl *D) {
1443+
const DeclContext *DC = D->getDeclContext();
1444+
if (!DC->isTypeContext()) {
1445+
assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
1446+
"unexpected context kind");
1447+
return DC->isLocalContext();
1448+
}
1449+
1450+
auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
1451+
if (nominal == nullptr)
1452+
return false;
1453+
1454+
if (hasPrivateOrFilePrivateFormalAccess(nominal))
1455+
return true;
1456+
return isInPrivateOrLocalContext(nominal);
1457+
}
1458+
1459+
bool ValueDecl::isOutermostPrivateOrFilePrivateScope() const {
1460+
return hasPrivateOrFilePrivateFormalAccess(this) &&
1461+
!isInPrivateOrLocalContext(this);
1462+
}
1463+
14361464
bool AbstractStorageDecl::hasFixedLayout() const {
14371465
// If we're in a nominal type, just query the type.
14381466
auto *dc = getDeclContext();

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,13 +1132,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
11321132
}
11331133
#endif
11341134

1135-
Opts.EnableObjCInterop = Target.isOSDarwin();
1136-
if (auto A = Args.getLastArg(OPT_enable_objc_interop,
1137-
OPT_disable_objc_interop)) {
1138-
Opts.EnableObjCInterop
1139-
= A->getOption().matches(OPT_enable_objc_interop);
1140-
}
1141-
1135+
Opts.EnableObjCInterop =
1136+
Args.hasFlag(OPT_enable_objc_interop, OPT_disable_objc_interop,
1137+
Target.isOSDarwin());
11421138
Opts.EnableSILOpaqueValues |= Args.hasArg(OPT_enable_sil_opaque_values);
11431139

11441140
// Must be processed after any other language options that could affect

lib/IRGen/GenProto.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,18 +314,35 @@ void PolymorphicConvention::considerWitnessSelf(CanSILFunctionType fnType) {
314314
selfTy);
315315

316316
if (auto *proto = fnType->getDefaultWitnessMethodProtocol(M)) {
317-
// The Self type is abstract, so we must pass in a witness table.
317+
// The Self type is abstract, so we can fulfill its metadata from
318+
// the Self metadata parameter.
318319
addSelfMetadataFulfillment(selfTy);
319320

320-
// Look at the witness table for the conformance.
321+
// The witness table for the Self : P conformance can be
322+
// fulfilled from the Self witness table parameter.
321323
Sources.emplace_back(MetadataSource::Kind::SelfWitnessTable,
322324
MetadataSource::InvalidSourceIndex,
323325
selfTy);
324326
addSelfWitnessTableFulfillment(selfTy, proto);
327+
} else if (auto *classDecl = fnType->getWitnessMethodClass(M)) {
328+
// The Self type is abstract, so we can fulfill its metadata from
329+
// the Self metadata parameter.
330+
addSelfMetadataFulfillment(selfTy);
331+
332+
// FIXME: We should fulfill the witness table too, but we don't
333+
// have the original protocol anymore -- we should store it as part
334+
// of the @convention(witness_method) bit in the SILFunctionType's
335+
// ExtInfo
325336
} else {
326337
// If the Self type is concrete, we have a witness thunk with a
327338
// fully substituted Self type. The witness table parameter is not
328339
// used.
340+
//
341+
// FIXME: As above, we should fulfill the Self metadata and
342+
// conformance from our two special paramaters here. However, the
343+
// Self metadata will be inexact.
344+
//
345+
// For now, just fulfill the generic arguments of 'Self'.
329346
considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
330347
}
331348
}

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13951395
return nullptr;
13961396
}
13971397

1398+
/// The private discriminator is represented as an inline namespace.
1399+
llvm::DIScope *getFilePrivateScope(llvm::DIScope *Parent, TypeDecl *Decl) {
1400+
// Retrieve the private discriminator.
1401+
auto *MSC = Decl->getDeclContext()->getModuleScopeContext();
1402+
auto *FU = cast<FileUnit>(MSC);
1403+
Identifier PD = FU->getDiscriminatorForPrivateValue(Decl);
1404+
bool ExportSymbols = true;
1405+
return DBuilder.createNameSpace(Parent, PD.str(), ExportSymbols);
1406+
}
1407+
13981408
llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
13991409
// Is this an empty type?
14001410
if (DbgTy.isNull())
@@ -1438,6 +1448,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14381448
}
14391449
if (!Scope)
14401450
Scope = getOrCreateContext(Context);
1451+
1452+
// Scope outermost fileprivate decls in an inline private discriminator
1453+
// namespace.
1454+
if (auto *Decl = DbgTy.getDecl())
1455+
if (Decl->isOutermostPrivateOrFilePrivateScope())
1456+
Scope = getFilePrivateScope(Scope, Decl);
1457+
14411458
llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));
14421459

14431460
// Incrementally build the DIRefMap.
@@ -1518,9 +1535,9 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
15181535
CU_Nodes->addOperand(*CU);
15191536

15201537
// Create a module for the current compile unit.
1538+
auto *MDecl = IGM.getSwiftModule();
15211539
llvm::sys::path::remove_filename(AbsMainFile);
1522-
MainModule = getOrCreateModule(IGM.getSwiftModule(), TheCU, Opts.ModuleName,
1523-
AbsMainFile);
1540+
MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, AbsMainFile);
15241541
DBuilder.createImportedModule(MainFile, MainModule, MainFile, 0);
15251542

15261543
// Macro definitions that were defined by the user with "-Xcc -D" on the

lib/SIL/SILFunctionType.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ SILFunctionType::getDefaultWitnessMethodProtocol(ModuleDecl &M) const {
100100
assert(getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod);
101101
auto selfTy = getSelfInstanceType();
102102
if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
103+
assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
103104
auto superclass = GenericSig->getSuperclassBound(paramTy, M);
104105
if (superclass)
105106
return nullptr;
106-
assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
107107
auto protos = GenericSig->getConformsTo(paramTy, M);
108108
assert(protos.size() == 1);
109109
return protos[0];
@@ -112,6 +112,20 @@ SILFunctionType::getDefaultWitnessMethodProtocol(ModuleDecl &M) const {
112112
return nullptr;
113113
}
114114

115+
ClassDecl *
116+
SILFunctionType::getWitnessMethodClass(ModuleDecl &M) const {
117+
auto selfTy = getSelfInstanceType();
118+
auto genericSig = getGenericSignature();
119+
if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
120+
assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
121+
auto superclass = genericSig->getSuperclassBound(paramTy, M);
122+
if (superclass)
123+
return superclass->getClassOrBoundGenericClass();
124+
}
125+
126+
return nullptr;
127+
}
128+
115129
static CanType getKnownType(Optional<CanType> &cacheSlot, ASTContext &C,
116130
StringRef moduleName, StringRef typeName) {
117131
if (!cacheSlot) {

lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,22 @@ void CalleeCache::computeWitnessMethodCalleesForWitnessTable(
134134

135135
TheCallees.getPointer()->push_back(WitnessFn);
136136

137-
// FIXME: For now, conservatively assume that unknown functions
138-
// can be called from any witness_method call site.
139-
TheCallees.setInt(true);
137+
// If we can't resolve the witness, conservatively assume it can call
138+
// anything.
139+
if (!Requirement.getDecl()->isProtocolRequirement() ||
140+
!WT.getConformance()->hasWitness(Requirement.getDecl())) {
141+
TheCallees.setInt(true);
142+
continue;
143+
}
144+
145+
auto Witness = WT.getConformance()->getWitness(Requirement.getDecl(),
146+
nullptr);
147+
auto DeclRef = SILDeclRef(Witness.getDecl());
148+
149+
bool canCallUnknown = !calleesAreStaticallyKnowable(M, DeclRef);
150+
151+
if (canCallUnknown)
152+
TheCallees.setInt(true);
140153
}
141154
}
142155

0 commit comments

Comments
 (0)