Skip to content

Commit b98b8a4

Browse files
authored
Merge pull request #24256 from slavapestov/objc-from-witnessed-requirement-ordering-5.1
Sema: Fix order dependency in @objc inference from witnessed protocol requirement [5.1]
2 parents 7ce4f15 + 4710da5 commit b98b8a4

File tree

4 files changed

+40
-7
lines changed

4 files changed

+40
-7
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ static ValueDecl *getStandinForAccessor(AbstractStorageDecl *witnessStorage,
424424

425425
RequirementMatch
426426
swift::matchWitness(
427-
TypeChecker &tc,
428427
DeclContext *dc, ValueDecl *req, ValueDecl *witness,
429428
llvm::function_ref<
430429
std::tuple<Optional<RequirementMatch>, Type, Type>(void)>
@@ -440,10 +439,17 @@ swift::matchWitness(
440439
if (req->getKind() != witness->getKind())
441440
return RequirementMatch(witness, MatchKind::KindConflict);
442441

442+
// If the witness has not been validated yet, do so now.
443+
if (!witness->hasValidSignature()) {
444+
auto &ctx = dc->getASTContext();
445+
ctx.getLazyResolver()->resolveDeclSignature(witness);
446+
}
447+
443448
// If the witness is invalid, record that and stop now.
444449
if (witness->isInvalid())
445450
return RequirementMatch(witness, MatchKind::WitnessInvalid);
446451

452+
// If we're currently validating the witness, bail out.
447453
if (!witness->hasValidSignature())
448454
return RequirementMatch(witness, MatchKind::Circularity);
449455

@@ -946,7 +952,7 @@ swift::matchWitness(TypeChecker &tc,
946952
return result;
947953
};
948954

949-
return matchWitness(tc, dc, req, witness, setup, matchTypes, finalize);
955+
return matchWitness(dc, req, witness, setup, matchTypes, finalize);
950956
}
951957

952958
static bool
@@ -1149,9 +1155,6 @@ bool WitnessChecker::findBestWitness(
11491155
continue;
11501156
}
11511157

1152-
if (!witness->hasValidSignature())
1153-
TC.validateDecl(witness);
1154-
11551158
auto match = matchWitness(TC, ReqEnvironmentCache, Proto, conformance, DC,
11561159
requirement, witness);
11571160
if (match.isViable()) {

lib/Sema/TypeCheckProtocol.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,6 @@ class AssociatedTypeInference {
897897
///
898898
/// \returns the result of performing the match.
899899
RequirementMatch matchWitness(
900-
TypeChecker &tc,
901900
DeclContext *dc, ValueDecl *req, ValueDecl *witness,
902901
llvm::function_ref<
903902
std::tuple<Optional<RequirementMatch>, Type, Type>(void)>

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitness(ValueDecl *req,
756756
// Match the witness. If we don't succeed, throw away the inference
757757
// information.
758758
// FIXME: A renamed match might be useful to retain for the failure case.
759-
if (matchWitness(tc, dc, req, witness, setup, matchTypes, finalize)
759+
if (matchWitness(dc, req, witness, setup, matchTypes, finalize)
760760
.Kind != MatchKind::ExactMatch) {
761761
inferred.Inferred.clear();
762762
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -print-ast %s | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
// This bug required an elaborate setup where isObjC() was checked prior
6+
// to validateDecl() getting called on a declaration. In this case, we
7+
// did not infer @objc from witnessed protocol requirements as required.
8+
//
9+
// https://bugs.swift.org/browse/SR-10257
10+
11+
@objc public protocol P {
12+
@objc optional func f()
13+
}
14+
15+
public class Other {
16+
// This triggers a walk over all nominals in the file, collecting
17+
// @objc members into the dynamic dispatch lookup table.
18+
let a = (Base() as AnyObject).g()
19+
}
20+
21+
@objc public class Base : P {
22+
@objc public func g() -> Int { return 0 }
23+
}
24+
25+
public class D : Base {
26+
// This method witnesses P.f() and so it should be @objc.
27+
//
28+
// CHECK-LABEL: @objc public func f()
29+
public func f() {}
30+
}
31+

0 commit comments

Comments
 (0)