Merge pull request #15038 from xedin/rdar-38203776-4.1
[4.1][AST] Disable comment printing while emitting diagnostics
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 6886f77..14568dd 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -3326,17 +3326,21 @@
// Retrieve the requirement that a given typealias introduces when it
// overrides an inherited associated type with the same name, as a string
// suitable for use in a where clause.
- auto getTypeAliasReq = [&](TypeAliasDecl *typealias, const char *start) {
+ auto getConcreteTypeReq = [&](TypeDecl *type, const char *start) {
std::string result;
{
llvm::raw_string_ostream out(result);
out << start;
- out << typealias->getFullName() << " == ";
- if (auto underlyingTypeRepr =
- typealias->getUnderlyingTypeLoc().getTypeRepr())
- underlyingTypeRepr->print(out);
- else
- typealias->getUnderlyingTypeLoc().getType().print(out);
+ out << type->getFullName() << " == ";
+ if (auto typealias = dyn_cast<TypeAliasDecl>(type)) {
+ if (auto underlyingTypeRepr =
+ typealias->getUnderlyingTypeLoc().getTypeRepr())
+ underlyingTypeRepr->print(out);
+ else
+ typealias->getUnderlyingTypeLoc().getType().print(out);
+ } else {
+ type->print(out);
+ }
}
return result;
};
@@ -3466,51 +3470,68 @@
inheritedTypeDecls.erase(knownInherited);
continue;
}
+ }
- if (auto typealias = dyn_cast<TypeAliasDecl>(Member)) {
- // Check whether we inherited any types with the same name.
- auto knownInherited = inheritedTypeDecls.find(typealias->getFullName());
- if (knownInherited == inheritedTypeDecls.end()) continue;
+ // Check all remaining inherited type declarations to determine if
+ // this protocol has a non-associated-type type with the same name.
+ inheritedTypeDecls.remove_if(
+ [&](const std::pair<DeclName, TinyPtrVector<TypeDecl *>> &inherited) {
+ auto name = inherited.first;
+ for (auto found : proto->lookupDirect(name)) {
+ // We only want concrete type declarations.
+ auto type = dyn_cast<TypeDecl>(found);
+ if (!type || isa<AssociatedTypeDecl>(type)) continue;
- bool shouldWarnAboutRedeclaration =
- source->kind == RequirementSource::RequirementSignatureSelf;
+ // ... from the same module as the protocol.
+ if (type->getModuleContext() != proto->getModuleContext()) continue;
- for (auto inheritedType : knownInherited->second) {
- // If we have inherited associated type...
- if (auto inheritedAssocTypeDecl =
- dyn_cast<AssociatedTypeDecl>(inheritedType)) {
- // Infer a same-type requirement between the typealias' underlying
- // type and the inherited associated type.
- addInferredSameTypeReq(inheritedAssocTypeDecl, typealias);
-
- // Warn that one should use where clauses for this.
- if (shouldWarnAboutRedeclaration) {
- auto inheritedFromProto = inheritedAssocTypeDecl->getProtocol();
- auto fixItWhere = getProtocolWhereLoc();
- Diags.diagnose(typealias,
- diag::typealias_override_associated_type,
- typealias->getFullName(),
- inheritedFromProto->getDeclaredInterfaceType())
- .fixItInsertAfter(fixItWhere.first,
- getTypeAliasReq(typealias, fixItWhere.second))
- .fixItRemove(typealias->getSourceRange());
- Diags.diagnose(inheritedAssocTypeDecl, diag::decl_declared_here,
- inheritedAssocTypeDecl->getFullName());
-
- shouldWarnAboutRedeclaration = false;
- }
-
- continue;
+ // Or is constrained.
+ if (auto ext = dyn_cast<ExtensionDecl>(type->getDeclContext())) {
+ if (ext->isConstrainedExtension()) continue;
}
- // Two typealiases that should be the same.
- addInferredSameTypeReq(inheritedType, typealias);
+ // We found something.
+ bool shouldWarnAboutRedeclaration =
+ source->kind == RequirementSource::RequirementSignatureSelf;
+
+ for (auto inheritedType : inherited.second) {
+ // If we have inherited associated type...
+ if (auto inheritedAssocTypeDecl =
+ dyn_cast<AssociatedTypeDecl>(inheritedType)) {
+ // Infer a same-type requirement between the typealias' underlying
+ // type and the inherited associated type.
+ addInferredSameTypeReq(inheritedAssocTypeDecl, type);
+
+ // Warn that one should use where clauses for this.
+ if (shouldWarnAboutRedeclaration) {
+ auto inheritedFromProto = inheritedAssocTypeDecl->getProtocol();
+ auto fixItWhere = getProtocolWhereLoc();
+ Diags.diagnose(type,
+ diag::typealias_override_associated_type,
+ name,
+ inheritedFromProto->getDeclaredInterfaceType())
+ .fixItInsertAfter(fixItWhere.first,
+ getConcreteTypeReq(type, fixItWhere.second))
+ .fixItRemove(type->getSourceRange());
+ Diags.diagnose(inheritedAssocTypeDecl, diag::decl_declared_here,
+ inheritedAssocTypeDecl->getFullName());
+
+ shouldWarnAboutRedeclaration = false;
+ }
+
+ continue;
+ }
+
+ // Two typealiases that should be the same.
+ addInferredSameTypeReq(inheritedType, type);
+ }
+
+ // We can remove this entry.
+ return true;
}
- inheritedTypeDecls.erase(knownInherited);
- continue;
- }
- }
+ return false;
+ });
// Infer same-type requirements among inherited type declarations.
for (auto &entry : inheritedTypeDecls) {
diff --git a/validation-test/compiler_crashers_2_fixed/0145-sr7097.swift b/validation-test/compiler_crashers_2_fixed/0145-sr7097.swift
new file mode 100644
index 0000000..4ae7282
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0145-sr7097.swift
@@ -0,0 +1,34 @@
+// RUN: %target-swift-frontend -typecheck -verify %s
+// RUN: %target-swift-frontend -typecheck -debug-generic-signatures %s 2>&1 | %FileCheck %s
+// RUN: %target-swift-frontend -primary-file %s -emit-ir -o -
+
+protocol P1 { }
+
+protocol P2 {
+ associatedtype Assoc // expected-note{{'Assoc' declared here}}
+}
+
+// CHECK-LABEL: .P3@
+// CHECK-NEXT: Requirement signature: <Self where Self : P2, Self.Assoc == ConformsToP1>
+protocol P3 : P2 { }
+
+struct S0<M: P3> where M.Assoc: P1 { } // expected-warning{{redundant conformance constraint 'M.Assoc': 'P1'}}
+// expected-note@-1{{conformance constraint 'M.Assoc': 'P1' implied here}}
+
+struct ConformsToP1: P1 { }
+
+extension P3 {
+ typealias Assoc = ConformsToP1 // expected-warning{{typealias overriding associated type 'Assoc' from protocol 'P2' is better expressed as same-type constraint on the protocol}}
+}
+
+protocol P5 {
+}
+
+extension P5 {
+ // CHECK-LABEL: P5.testSR7097
+ // CHECK-NEXT: Generic signature: <Self, M where Self : P5, M : P3>
+ // CHECK-NEXT: <τ_0_0, τ_1_0 where τ_0_0 : P5, τ_1_0 : P3>
+ func testSR7097<M>(_: S0<M>.Type) {}
+}
+
+