Skip to content

Commit dde28e9

Browse files
committed
AST: Don't call getDirectlyInheritedNominalTypeDecls() on a protocol in ConformanceLookupTable
1 parent 7909d83 commit dde28e9

File tree

4 files changed

+17
-10
lines changed

4 files changed

+17
-10
lines changed

lib/AST/ConformanceLookupTable.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,8 @@ void ConformanceLookupTable::addMacroGeneratedProtocols(
527527

528528
void ConformanceLookupTable::expandImpliedConformances(NominalTypeDecl *nominal,
529529
DeclContext *dc) {
530+
ASTContext &ctx = nominal->getASTContext();
531+
530532
// Note: recursive type-checking implies that AllConformances
531533
// may be reallocated during this traversal, so pay the lookup cost
532534
// during each iteration.
@@ -546,16 +548,23 @@ void ConformanceLookupTable::expandImpliedConformances(NominalTypeDecl *nominal,
546548
isa<EnumDecl>(nominal) && nominal->isObjC() &&
547549
cast<EnumDecl>(nominal)->hasCases() &&
548550
cast<EnumDecl>(nominal)->hasOnlyCasesWithoutAssociatedValues()) {
549-
ASTContext &ctx = nominal->getASTContext();
550551
if (auto bridgedNSError
551552
= ctx.getProtocol(KnownProtocolKind::BridgedNSError)) {
552553
addProtocol(bridgedNSError, SourceLoc(),
553554
ConformanceSource::forImplied(conformanceEntry));
554555
}
555556
}
556557

557-
addInheritedProtocols(conformingProtocol,
558-
ConformanceSource::forImplied(conformanceEntry));
558+
auto source = ConformanceSource::forImplied(conformanceEntry);
559+
for (auto *inherited : conformingProtocol->getInheritedProtocols()) {
560+
// Conforming a ~Copyable nominal to a protocol that inherits Copyable
561+
// should not imply a Copyable conformance on the nominal.
562+
if (ctx.LangOpts.hasFeature(Feature::NoncopyableGenerics))
563+
if (inherited->getInvertibleProtocolKind())
564+
continue;
565+
566+
addProtocol(inherited, SourceLoc(), source);
567+
}
559568
}
560569
}
561570

test/Generics/inverse_generics.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,17 +446,19 @@ public struct Record<Output> {
446446
protocol P {}
447447
extension Record : Decodable where Output : P {}
448448

449-
// Expect that if Copyable is an inherited protocol, then conditional
450-
// conformances carry that through, making the Blahaj conditionally Copyable.
451449
struct Blahaj<Value>: ~Copyable {
452-
deinit {} // expected-error {{deinitializer cannot be declared in generic struct 'Blahaj' that conforms to 'Copyable'}}
450+
deinit {} // this is OK
453451
}
454452
extension Blahaj: Q where Value: Q {}
453+
// expected-error@-1 {{type 'Blahaj<Value>' does not conform to protocol 'Copyable'}}
455454
protocol Q: Copyable {}
455+
// expected-note@-1 {{type 'Blahaj<Value>' does not conform to inherited protocol 'Copyable'}}
456456

457457
// expected-note@+2 3{{add}}
458458
// expected-error@+1 {{parameter of noncopyable type 'Blahaj<T>' must specify ownership}}
459459
func testBlahaj<T, U: Q>(_ x: Blahaj<T>,
460+
// expected-note@+2 3{{add}}
461+
// expected-error@+1 {{parameter of noncopyable type 'Blahaj<U>' must specify ownership}}
460462
_ y: Blahaj<U>) {}
461463

462464
extension Int: NeedsCopyable {}

test/api-digester/internal-extension.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
// RUN: %api-digester -dump-sdk -module main -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource
99
// RUN: %FileCheck %s < %t.dump.json
1010

11-
// XFAIL: noncopyable_generics
12-
1311
import cake
1412

1513
// CHECK: publicSymbol

test/decl/protocol/conforms/placement.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
// RUN: %target-swift-frontend -typecheck -primary-file %s %S/Inputs/placement_2.swift -I %t -verify
66

7-
// XFAIL: noncopyable_generics
8-
97
// Tests for the placement of conformances as well as conflicts
108
// between conformances that come from different sources.
119

0 commit comments

Comments
 (0)