Skip to content

Commit cffdc08

Browse files
committed
---
yaml --- r: 345134 b: refs/heads/master c: 89ee9c6 h: refs/heads/master
1 parent aff53f3 commit cffdc08

Some content is hidden

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

49 files changed

+802
-230
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 88c19e1a6e834b97006f701bd45d7e33e06dd1f8
2+
refs/heads/master: 89ee9c6bcff40e1238d6af5b0b6be806ea4db41d
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/cmake/modules/AddSwift.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,13 @@ function(add_swift_library name)
15721572
endif()
15731573

15741574
if(SWIFTLIB_TARGET_LIBRARY)
1575+
# In the standard library and overlays, warn about implicit overrides
1576+
# as a reminder to consider when inherited protocols need different
1577+
# behavior for their requirements.
1578+
if (SWIFTLIB_IS_STDLIB)
1579+
list(APPEND SWIFTLIB_SWIFT_COMPILE_FLAGS "-warn-implicit-overrides")
1580+
endif()
1581+
15751582
if(NOT SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER AND NOT BUILD_STANDALONE)
15761583
list(APPEND SWIFTLIB_DEPENDS clang)
15771584
endif()

trunk/include/swift/AST/Attr.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(convenience, Convenience,
240240
DeclModifier |
241241
NotSerialized, 43)
242242
CONTEXTUAL_SIMPLE_DECL_ATTR(override, Override,
243-
OnFunc | OnAccessor | OnVar | OnSubscript | OnConstructor |
243+
OnFunc | OnAccessor | OnVar | OnSubscript | OnConstructor | OnAssociatedType |
244244
DeclModifier |
245245
NotSerialized, 44)
246246
SIMPLE_DECL_ATTR(sil_stored, SILStored,
@@ -375,6 +375,10 @@ SIMPLE_DECL_ATTR(_hasInitialValue, HasInitialValue,
375375
OnVar |
376376
UserInaccessible,
377377
78)
378+
SIMPLE_DECL_ATTR(_nonoverride, NonOverride,
379+
OnFunc | OnAccessor | OnVar | OnSubscript | OnConstructor | OnAssociatedType |
380+
UserInaccessible | NotSerialized,
381+
79)
378382

379383
#undef TYPE_ATTR
380384
#undef DECL_ATTR_ALIAS

trunk/include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6579,7 +6579,8 @@ inline bool Decl::isPotentiallyOverridable() const {
65796579
isa<SubscriptDecl>(this) ||
65806580
isa<FuncDecl>(this) ||
65816581
isa<DestructorDecl>(this)) {
6582-
return getDeclContext()->getSelfClassDecl();
6582+
return getDeclContext()->getSelfClassDecl() ||
6583+
isa<ProtocolDecl>(getDeclContext());
65836584
} else {
65846585
return false;
65856586
}

trunk/include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,9 @@ NOTE(overridden_here_can_be_objc,none,
20412041

20422042
ERROR(missing_override,none,
20432043
"overriding declaration requires an 'override' keyword", ())
2044+
WARNING(missing_override_warn,none,
2045+
"implicit override should be marked with 'override' or suppressed "
2046+
"with '@_nonoverride'", ())
20442047

20452048
ERROR(multiple_override,none,
20462049
"%0 has already been overridden", (DeclName))
@@ -2104,6 +2107,10 @@ NOTE(override_type_mismatch_with_fixits_init,none,
21042107
(unsigned, Type))
21052108
ERROR(override_nonclass_decl,none,
21062109
"'override' can only be specified on class members", ())
2110+
ERROR(nonoverride_wrong_decl_context,none,
2111+
"'@_nonoverride' can only be specified on class or protocol members", ())
2112+
ERROR(nonoverride_and_override_attr,none,
2113+
"'override' cannot be combined with '@_nonoverride'", ())
21072114
ERROR(override_property_type_mismatch,none,
21082115
"property %0 with type %1 cannot override a property with type %2",
21092116
(Identifier, Type, Type))

trunk/include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ namespace swift {
248248
Swift3ObjCInferenceWarnings WarnSwift3ObjCInference =
249249
Swift3ObjCInferenceWarnings::None;
250250

251+
/// Diagnose implicit 'override'.
252+
bool WarnImplicitOverrides = false;
253+
251254
/// Diagnose uses of NSCoding with classes that have unstable mangled names.
252255
bool EnableNSKeyedArchiverDiagnostics = true;
253256

trunk/include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ def warn_swift3_objc_inference_minimal :
359359
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
360360
HelpText<"Warn about deprecated @objc inference in Swift 3 based on direct uses of the Objective-C entrypoint">;
361361

362+
def warn_implicit_overrides :
363+
Flag<["-"], "warn-implicit-overrides">,
364+
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
365+
HelpText<"Warn about implicit overrides of protocol members">;
366+
362367
def typo_correction_limit : Separate<["-"], "typo-correction-limit">,
363368
Flags<[FrontendOption, HelpHidden]>,
364369
MetaVarName<"<n>">,

trunk/include/swift/SIL/SILDeclRef.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,13 @@ struct SILDeclRef {
334334
/// entry.
335335
bool requiresNewVTableEntry() const;
336336

337+
/// True if the decl ref references a method which introduces a new witness
338+
/// table entry.
339+
bool requiresNewWitnessTableEntry() const;
340+
341+
/// True if the decl is a method which introduces a new witness table entry.
342+
static bool requiresNewWitnessTableEntry(AbstractFunctionDecl *func);
343+
337344
/// Return a SILDeclRef to the declaration overridden by this one, or
338345
/// a null SILDeclRef if there is no override.
339346
SILDeclRef getOverridden() const;
@@ -348,6 +355,10 @@ struct SILDeclRef {
348355
/// dispatched, will return the least derived method.
349356
SILDeclRef getOverriddenVTableEntry() const;
350357

358+
/// Return the original protocol requirement that introduced the witness table
359+
/// entry overridden by this method.
360+
SILDeclRef getOverriddenWitnessTableEntry() const;
361+
351362
/// True if the referenced entity is some kind of thunk.
352363
bool isThunk() const;
353364

trunk/include/swift/SIL/SILWitnessVisitor.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
128128
return;
129129

130130
// Visit the witnesses for the direct members of a protocol.
131-
for (Decl *member : protocol->getMembers())
131+
for (Decl *member : protocol->getMembers()) {
132132
ASTVisitor<T>::visit(member);
133+
}
133134
}
134135

135136
/// If true, only the base protocols and associated types will be visited.
@@ -145,12 +146,14 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
145146

146147
void visitAbstractStorageDecl(AbstractStorageDecl *sd) {
147148
sd->visitOpaqueAccessors([&](AccessorDecl *accessor) {
148-
asDerived().addMethod(SILDeclRef(accessor, SILDeclRef::Kind::Func));
149+
if (SILDeclRef::requiresNewWitnessTableEntry(accessor))
150+
asDerived().addMethod(SILDeclRef(accessor, SILDeclRef::Kind::Func));
149151
});
150152
}
151153

152154
void visitConstructorDecl(ConstructorDecl *cd) {
153-
asDerived().addMethod(SILDeclRef(cd, SILDeclRef::Kind::Allocator));
155+
if (SILDeclRef::requiresNewWitnessTableEntry(cd))
156+
asDerived().addMethod(SILDeclRef(cd, SILDeclRef::Kind::Allocator));
154157
}
155158

156159
void visitAccessorDecl(AccessorDecl *func) {
@@ -159,7 +162,8 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
159162

160163
void visitFuncDecl(FuncDecl *func) {
161164
assert(!isa<AccessorDecl>(func));
162-
asDerived().addMethod(SILDeclRef(func, SILDeclRef::Kind::Func));
165+
if (SILDeclRef::requiresNewWitnessTableEntry(func))
166+
asDerived().addMethod(SILDeclRef(func, SILDeclRef::Kind::Func));
163167
}
164168

165169
void visitMissingMemberDecl(MissingMemberDecl *placeholder) {

trunk/lib/AST/ASTDumper.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,9 +754,18 @@ namespace {
754754
<< getAccessLevelSpelling(VD->getFormalAccess());
755755
}
756756

757-
if (auto Overridden = VD->getOverriddenDecl()) {
758-
PrintWithColorRAII(OS, OverrideColor) << " override=";
759-
Overridden->dumpRef(PrintWithColorRAII(OS, OverrideColor).getOS());
757+
if (VD->overriddenDeclsComputed()) {
758+
auto overridden = VD->getOverriddenDecls();
759+
if (!overridden.empty()) {
760+
PrintWithColorRAII(OS, OverrideColor) << " override=";
761+
interleave(overridden,
762+
[&](ValueDecl *overridden) {
763+
overridden->dumpRef(
764+
PrintWithColorRAII(OS, OverrideColor).getOS());
765+
}, [&]() {
766+
OS << ", ";
767+
});
768+
}
760769
}
761770

762771
if (VD->isFinal())

trunk/lib/AST/ASTVerifier.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,9 +865,10 @@ class Verifier : public ASTWalker {
865865
D->getAttrs().hasAttribute<OverrideAttr>()) {
866866
if (!D->isInvalid() && D->hasInterfaceType() &&
867867
!isa<ClassDecl>(D->getDeclContext()) &&
868+
!isa<ProtocolDecl>(D->getDeclContext()) &&
868869
!isa<ExtensionDecl>(D->getDeclContext())) {
869870
PrettyStackTraceDecl debugStack("verifying override", D);
870-
Out << "'override' attribute outside of a class\n";
871+
Out << "'override' attribute outside of a class or protocol\n";
871872
D->dump(Out);
872873
abort();
873874
}

trunk/lib/AST/GenericSignatureBuilder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4381,9 +4381,12 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
43814381

43824382
bool shouldWarnAboutRedeclaration =
43834383
source->kind == RequirementSource::RequirementSignatureSelf &&
4384+
!assocTypeDecl->getAttrs().hasAttribute<NonOverrideAttr>() &&
4385+
!assocTypeDecl->getAttrs().hasAttribute<OverrideAttr>() &&
43844386
assocTypeDecl->getDefaultDefinitionLoc().isNull() &&
43854387
(!assocTypeDecl->getInherited().empty() ||
4386-
assocTypeDecl->getTrailingWhereClause());
4388+
assocTypeDecl->getTrailingWhereClause() ||
4389+
getASTContext().LangOpts.WarnImplicitOverrides);
43874390
for (auto inheritedType : knownInherited->second) {
43884391
// If we have inherited associated type...
43894392
if (auto inheritedAssocTypeDecl =

trunk/lib/AST/NameLookup.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ bool swift::removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls) {
8585

8686
llvm::SmallPtrSet<ValueDecl*, 8> overridden;
8787
for (auto decl : decls) {
88+
// Don't look at the overrides of operators in protocols. The global
89+
// lookup of operators means that we can find overriding operators that
90+
// aren't relevant to the types in hand, and will fail to type check.
91+
if (isa<ProtocolDecl>(decl->getDeclContext())) {
92+
if (auto func = dyn_cast<FuncDecl>(decl))
93+
if (func->isOperator())
94+
continue;
95+
}
96+
8897
while (auto overrides = decl->getOverriddenDecl()) {
8998
overridden.insert(overrides);
9099

trunk/lib/AST/ProtocolConformance.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,37 @@ ProtocolConformanceRef::getConditionalRequirements() const {
403403
return {};
404404
}
405405

406+
ProtocolConformanceRef
407+
ProtocolConformanceRef::getInheritedConformanceRef(ProtocolDecl *base) const {
408+
if (isAbstract()) {
409+
assert(getRequirement()->inheritsFrom(base));
410+
return ProtocolConformanceRef(base);
411+
}
412+
413+
auto concrete = getConcrete();
414+
auto proto = concrete->getProtocol();
415+
auto path =
416+
proto->getGenericSignature()->getConformanceAccessPath(
417+
proto->getProtocolSelfType(), base);
418+
ProtocolConformanceRef result = *this;
419+
Type resultType = concrete->getType();
420+
bool first = true;
421+
for (const auto &step : path) {
422+
if (first) {
423+
assert(step.first->isEqual(proto->getProtocolSelfType()));
424+
assert(step.second == proto);
425+
first = false;
426+
continue;
427+
}
428+
429+
result =
430+
result.getAssociatedConformance(resultType, step.first, step.second);
431+
resultType = result.getAssociatedType(resultType, step.first);
432+
}
433+
434+
return result;
435+
}
436+
406437
void NormalProtocolConformance::differenceAndStoreConditionalRequirements()
407438
const {
408439
switch (CRState) {

trunk/lib/AST/SubstitutionMap.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,23 @@ SubstitutionMap::getProtocolSubstitutions(ProtocolDecl *protocol,
505505
}
506506

507507
SubstitutionMap
508-
SubstitutionMap::getOverrideSubstitutions(const ValueDecl *baseDecl,
509-
const ValueDecl *derivedDecl,
510-
Optional<SubstitutionMap> derivedSubs) {
508+
SubstitutionMap::getOverrideSubstitutions(
509+
const ValueDecl *baseDecl,
510+
const ValueDecl *derivedDecl,
511+
Optional<SubstitutionMap> derivedSubs) {
512+
// For overrides within a protocol hierarchy, substitute the Self type.
513+
if (auto baseProto = baseDecl->getDeclContext()->getSelfProtocolDecl()) {
514+
if (auto derivedProtoSelf =
515+
derivedDecl->getDeclContext()->getProtocolSelfType()) {
516+
return SubstitutionMap::getProtocolSubstitutions(
517+
baseProto,
518+
derivedProtoSelf,
519+
ProtocolConformanceRef(baseProto));
520+
}
521+
522+
return SubstitutionMap();
523+
}
524+
511525
auto *baseClass = baseDecl->getDeclContext()->getSelfClassDecl();
512526
auto *derivedClass = derivedDecl->getDeclContext()->getSelfClassDecl();
513527

@@ -541,6 +555,8 @@ SubstitutionMap::getOverrideSubstitutions(const ClassDecl *baseClass,
541555
if (derivedSubs)
542556
derivedClassTy = derivedClassTy.subst(*derivedSubs);
543557
auto baseClassTy = derivedClassTy->getSuperclassForDecl(baseClass);
558+
if (baseClassTy->is<ErrorType>())
559+
return SubstitutionMap();
544560

545561
baseSubMap = baseClassTy->getContextSubstitutionMap(M, baseClass);
546562
}

trunk/lib/AST/Type.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3349,7 +3349,8 @@ Type TypeBase::adjustSuperclassMemberDeclType(const ValueDecl *baseDecl,
33493349

33503350
auto type = memberType.subst(subs, SubstFlags::UseErrorType);
33513351

3352-
if (isa<AbstractFunctionDecl>(baseDecl)) {
3352+
if (isa<AbstractFunctionDecl>(baseDecl) &&
3353+
!baseDecl->getDeclContext()->getSelfProtocolDecl()) {
33533354
type = type->replaceSelfParameterType(this);
33543355
if (auto func = dyn_cast<FuncDecl>(baseDecl)) {
33553356
if (func->hasDynamicSelf()) {

trunk/lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
182182
inputArgs.AddLastArg(arguments,
183183
options::OPT_warn_swift3_objc_inference_minimal,
184184
options::OPT_warn_swift3_objc_inference_complete);
185+
inputArgs.AddLastArg(arguments, options::OPT_warn_implicit_overrides);
185186
inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);
186187
inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);
187188
inputArgs.AddLastArg(arguments, options::OPT_enable_testing);

trunk/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
321321
}
322322
}
323323

324+
Opts.WarnImplicitOverrides =
325+
Args.hasArg(OPT_warn_implicit_overrides);
326+
324327
Opts.EnableNSKeyedArchiverDiagnostics =
325328
Args.hasFlag(OPT_enable_nskeyedarchiver_diagnostics,
326329
OPT_disable_nskeyedarchiver_diagnostics,

trunk/lib/IRGen/GenProto.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,13 @@ bool irgen::isDependentConformance(const NormalProtocolConformance *conformance)
969969
return true;
970970

971971
// Check whether any of the inherited conformances are dependent.
972-
for (auto inherited : conformance->getProtocol()->getInheritedProtocols()) {
972+
auto proto = conformance->getProtocol();
973+
for (const auto &req : proto->getRequirementSignature()) {
974+
if (req.getKind() != RequirementKind::Conformance ||
975+
!req.getFirstType()->isEqual(proto->getProtocolSelfType()))
976+
continue;
977+
978+
auto inherited = req.getSecondType()->castTo<ProtocolType>()->getDecl();
973979
if (inherited->isObjC())
974980
continue;
975981

trunk/lib/IRGen/IRGenSIL.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5401,6 +5401,20 @@ void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) {
54015401
ProtocolConformanceRef conformance = i->getConformance();
54025402
SILDeclRef member = i->getMember();
54035403

5404+
// Find the original entry in the witness table.
5405+
bool wasOverriding = false;
5406+
while (auto overridden = member.getOverridden()) {
5407+
member = overridden;
5408+
wasOverriding = true;
5409+
}
5410+
5411+
// If the requirement given override another requirement, adjust the
5412+
// conformance appropriately.
5413+
if (wasOverriding) {
5414+
auto memberProto = cast<ProtocolDecl>(member.getDecl()->getDeclContext());
5415+
conformance = conformance.getInheritedConformanceRef(memberProto);
5416+
}
5417+
54045418
if (IGM.isResilient(conformance.getRequirement(),
54055419
ResilienceExpansion::Maximal)) {
54065420
auto *fnPtr = IGM.getAddrOfDispatchThunk(member, NotForDefinition);

0 commit comments

Comments
 (0)