Skip to content

Commit e003e5e

Browse files
committed
Don't look for near-miss witnesses for unavailable requirements.
We use unavailable requirements as migration hints, but conformance checking would try a little too hard to actually satisfy them, even though they wouldn't actually be used. This led to errors about the /new/ name not matching the /old/ name. (We now get /two/ diagnostics for using the old name, but we can fix that later. Filed rdar://problem/26358593.) rdar://problem/26313044
1 parent 680fe7e commit e003e5e

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,8 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
20362036
bool doNotDiagnoseMatches = false;
20372037
bool ignoringNames = false;
20382038
bool considerRenames =
2039-
!canDerive && !requirement->getAttrs().hasAttribute<OptionalAttr>();
2039+
!canDerive && !requirement->getAttrs().hasAttribute<OptionalAttr>() &&
2040+
!requirement->getAttrs().isUnavailable(TC.Context);
20402041

20412042
if (findBestWitness(requirement,
20422043
considerRenames ? &ignoringNames : nullptr,
@@ -2049,6 +2050,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
20492050
// If the name didn't actually line up, complain.
20502051
if (ignoringNames &&
20512052
requirement->getFullName() != best.Witness->getFullName()) {
2053+
20522054
diagnoseOrDefer(requirement, false,
20532055
[witness, requirement](TypeChecker &tc,
20542056
NormalProtocolConformance *conformance) {
@@ -4570,6 +4572,9 @@ void TypeChecker::checkConformancesInContext(DeclContext *dc,
45704572
SmallVector<ValueDecl *, 4> bestOptionalReqs;
45714573
unsigned bestScore = UINT_MAX;
45724574
for (auto req : unsatisfiedReqs) {
4575+
// Skip unavailable requirements.
4576+
if (req->getAttrs().isUnavailable(Context)) continue;
4577+
45734578
// Score this particular optional requirement.
45744579
auto score = scorePotentiallyMatching(req, value, bestScore);
45754580

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@import ObjectiveC;
2+
3+
@interface Foo : NSObject
4+
@end
5+
6+
@protocol FooDelegate
7+
- (void)foo:(Foo *)foo willConsumeObject:(id)obj __attribute__((swift_name("foo(_:willConsume:)")));
8+
@end
9+
10+
@protocol OptionalButUnavailable
11+
@optional
12+
- (void)doTheThing:(id)thingToDoItWith __attribute__((unavailable));
13+
@end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-swift-frontend -parse -import-objc-header %S/Inputs/protocol-member-renaming.h -verify %s
2+
3+
// REQUIRES: objc_interop
4+
5+
class Modern : NSObject, FooDelegate {
6+
func foo(_ foo: Foo, willConsume object: AnyObject) {}
7+
}
8+
9+
class PreMigration : NSObject, FooDelegate {
10+
func foo(_ foo: Foo, willConsumeObject object: AnyObject) {}
11+
// expected-error@-1 {{'foo(_:willConsumeObject:)' has been renamed to 'foo(_:willConsume:)'}} {{24-41=willConsume}}
12+
// expected-error@-2 {{method 'foo(_:willConsumeObject:)' has different argument names from those required by protocol 'FooDelegate' ('foo(_:willConsume:)')}} {{24-41=willConsume}}
13+
}
14+
15+
class OptionalButUnavailableImpl : OptionalButUnavailable {
16+
// Note the argument label that causes this not to match the requirement.
17+
func doTheThing(object: AnyObject) {} // no-warning
18+
}

0 commit comments

Comments
 (0)