diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index a135b5c1f8468..4d1cdab316afc 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -6139,11 +6139,15 @@ class TypePrinter : public TypeVisitor(T)) + if (auto alias = dyn_cast(T)) // don't desugar parent = alias->getParent(); else if (auto generic = T->getAs()) parent = generic->getParent(); - return parent && parent->isTypeParameter(); + else if (T->is()) + // Parent is always a generic parameter. + return true; + return parent && (parent->is() || + isMemberOfGenericParameter(parent.getPointer())); } bool shouldPrintModuleSelector(TypeBase *T) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d8d1719b1583b..614c4506ea35c 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -576,6 +576,13 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts, // Any heuristics we might add would go here. Opts.UseModuleSelectors = false; } + + if (Opts.PreserveTypesAsWritten && Opts.UseModuleSelectors) { + Opts.PreserveTypesAsWritten = false; + diags.diagnose(SourceLoc(), diag::warn_ignore_option_overridden_by, + "-module-interface-preserve-types-as-written", + "-enable-module-selectors-in-module-interface"); + } } /// Checks if an arg is generally allowed to be included diff --git a/test/ModuleInterface/module_selector.swift b/test/ModuleInterface/module_selector.swift index 4fdbcfcfd85c0..7c306e217ba2d 100644 --- a/test/ModuleInterface/module_selector.swift +++ b/test/ModuleInterface/module_selector.swift @@ -2,43 +2,65 @@ // Test with -enable-module-selectors-in-module-interface // RUN: %empty-directory(%t/enabled) -// RUN: %target-swift-emit-module-interface(%t/enabled/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -enable-module-selectors-in-module-interface +// RUN: %target-swift-emit-module-interface(%t/enabled/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -enable-module-selectors-in-module-interface 2>%t/enabled/stderr.txt // RUN: %FileCheck --input-file %t/enabled/TestCase.swiftinterface %s --check-prefixes CHECK,CHECK-ENABLED +// RUN: %FileCheck --input-file %t/enabled/stderr.txt %s --allow-empty --check-prefix DIAG-PRESERVE-NOT-OVERRIDDEN // RUN: %target-swift-typecheck-module-from-interface(%t/enabled/TestCase.swiftinterface) %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase // Test with -disable-module-selectors-in-module-interface // RUN: %empty-directory(%t/disabled) -// RUN: %target-swift-emit-module-interface(%t/disabled/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -disable-module-selectors-in-module-interface +// RUN: %target-swift-emit-module-interface(%t/disabled/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -disable-module-selectors-in-module-interface 2>%t/disabled/stderr.txt // RUN: %FileCheck --input-file %t/disabled/TestCase.swiftinterface %s --check-prefixes CHECK,CHECK-DISABLED +// RUN: %FileCheck --input-file %t/disabled/stderr.txt %s --allow-empty --check-prefix DIAG-PRESERVE-NOT-OVERRIDDEN // RUN: %target-swift-typecheck-module-from-interface(%t/disabled/TestCase.swiftinterface) %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase // Test default behavior // RUN: %empty-directory(%t/default) -// RUN: %target-swift-emit-module-interface(%t/default/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase +// RUN: %target-swift-emit-module-interface(%t/default/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase 2>%t/default/stderr.txt // RUN: %FileCheck --input-file %t/default/TestCase.swiftinterface %s --check-prefixes CHECK,CHECK-DISABLED +// RUN: %FileCheck --input-file %t/default/stderr.txt %s --allow-empty --check-prefix DIAG-PRESERVE-NOT-OVERRIDDEN // RUN: %target-swift-typecheck-module-from-interface(%t/default/TestCase.swiftinterface) %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase // Test with -enable-module-selectors-in-module-interface and blocklist // RUN: %empty-directory(%t/blocked) -// RUN: %target-swift-emit-module-interface(%t/blocked/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -enable-module-selectors-in-module-interface -blocklist-file %S/Inputs/module_selector/blocklist.yml +// RUN: %target-swift-emit-module-interface(%t/blocked/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -enable-module-selectors-in-module-interface -blocklist-file %S/Inputs/module_selector/blocklist.yml 2>%t/blocked/stderr.txt // RUN: %FileCheck --input-file %t/blocked/TestCase.swiftinterface %s --check-prefixes CHECK,CHECK-DISABLED +// RUN: %FileCheck --input-file %t/blocked/stderr.txt %s --allow-empty --check-prefix DIAG-PRESERVE-NOT-OVERRIDDEN // RUN: %target-swift-typecheck-module-from-interface(%t/blocked/TestCase.swiftinterface) %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase +// Test with -module-interface-preserve-types-as-written and -disable-module-selectors-in-module-interface +// RUN: %empty-directory(%t/disabled-preserve) +// RUN: %target-swift-emit-module-interface(%t/disabled-preserve/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -module-interface-preserve-types-as-written -disable-module-selectors-in-module-interface 2>%t/disabled-preserve/stderr.txt +// RUN: %FileCheck --input-file %t/disabled-preserve/TestCase.swiftinterface %s --check-prefixes CHECK,CHECK-PRESERVE +// RUN: %FileCheck --input-file %t/disabled-preserve/stderr.txt %s --allow-empty --check-prefix DIAG-PRESERVE-NOT-OVERRIDDEN +// RUN: %target-swift-typecheck-module-from-interface(%t/disabled-preserve/TestCase.swiftinterface) %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase + +// Test with -module-interface-preserve-types-as-written and -enable-module-selectors-in-module-interface +// RUN: %empty-directory(%t/enabled-preserve) +// RUN: %target-swift-emit-module-interface(%t/enabled-preserve/TestCase.swiftinterface) %s %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase -module-interface-preserve-types-as-written -enable-module-selectors-in-module-interface 2>%t/enabled-preserve/stderr.txt +// RUN: %FileCheck --input-file %t/enabled-preserve/TestCase.swiftinterface %s --check-prefixes CHECK,CHECK-ENABLED +// RUN: %FileCheck --input-file %t/enabled-preserve/stderr.txt %s --check-prefix DIAG-PRESERVE-OVERRIDDEN +// RUN: %target-swift-typecheck-module-from-interface(%t/enabled-preserve/TestCase.swiftinterface) %clang-importer-sdk -F %clang-importer-sdk-path/frameworks -I %S/Inputs/module_selector -target %target-stable-abi-triple -module-name TestCase + // CHECK: import enums_using_attributes import enums_using_attributes // CHECK-LABEL: public struct Struct : // CHECK-ENABLED-SAME: Swift::Hashable where T : Swift::Hashable { // CHECK-DISABLED-SAME: Swift.Hashable where T : Swift.Hashable { +// CHECK-PRESERVE-SAME: Hashable where T : Swift.Hashable { +// Preserve quirk: Hashable qualified in constraint? public struct Struct: Hashable { // CHECK: public let integer: // CHECK-ENABLED-SAME: Swift::Int // CHECK-DISABLED-SAME: Swift.Int + // CHECK-PRESERVE-SAME: Int public let integer: Int = 42 // CHECK: public let enumeration: // CHECK-ENABLED-SAME: enums_using_attributes::CFEnumWithAttr // CHECK-DISABLED-SAME: enums_using_attributes.CFEnumWithAttr + // CHECK-PRESERVE-SAME: CFEnumWithAttr public let enumeration: CFEnumWithAttr = CFEnumWithAttr.first // CHECK: public let t: T? @@ -47,31 +69,37 @@ public struct Struct: Hashable { // CHECK: public static func == // CHECK-ENABLED-SAME: (a: TestCase::Struct, b: TestCase::Struct) -> Swift::Bool // CHECK-DISABLED-SAME: (a: TestCase.Struct, b: TestCase.Struct) -> Swift.Bool + // CHECK-PRESERVE-SAME: (a: TestCase.Struct, b: TestCase.Struct) -> Swift.Bool // CHECK: public func hash // CHECK-ENABLED-SAME: (into hasher: inout Swift::Hasher) // CHECK-DISABLED-SAME: (into hasher: inout Swift.Hasher) + // CHECK-PRESERVE-SAME: (into hasher: inout Swift.Hasher) // CHECK: public var hashValue: // CHECK-ENABLED-SAME: Swift::Int { // CHECK-DISABLED-SAME: Swift.Int { + // CHECK-PRESERVE-SAME: Swift.Int { // CHECK: } } // CHECK-ENABLED: extension TestCase::Struct { // CHECK-DISABLED: extension TestCase.Struct { +// CHECK-PRESERVE: extension Struct { extension Struct { // CHECK-LABEL: public enum Nested { public enum Nested { // CHECK: case integer // CHECK-ENABLED-SAME: (Swift::Int) // CHECK-DISABLED-SAME: (Swift.Int) + // CHECK-PRESERVE-SAME: (Int) case integer(Int) // CHECK: case enumeration // CHECK-ENABLED-SAME: (enums_using_attributes::CFEnumWithAttr) // CHECK-DISABLED-SAME: (enums_using_attributes.CFEnumWithAttr) + // CHECK-PRESERVE-SAME: (CFEnumWithAttr) case enumeration(CFEnumWithAttr) // CHECK: case t(T) @@ -80,6 +108,7 @@ extension Struct { // CHECK: case `struct` // CHECK-ENABLED-SAME: (TestCase::Struct) // CHECK-DISABLED-SAME: (TestCase.Struct) + // CHECK-PRESERVE-SAME: (Struct) case `struct`(Struct) // CHECK: } @@ -90,6 +119,8 @@ extension Struct { // CHECK-ENABLED: extension Swift::Int { // CHECK-DISABLED: extension Swift.Int { +// CHECK-PRESERVE: extension Int { +// Preserve quirk: Int has no module selector? extension Swift::Int { // CHECK-LABEL: public enum RetroactiveNested { public enum RetroactiveNested {} @@ -97,6 +128,7 @@ extension Swift::Int { // CHECK-ENABLED: extension Swift::Int.TestCase::RetroactiveNested { // CHECK-DISABLED: extension Swift.Int.RetroactiveNested { +// CHECK-PRESERVE: extension Int.RetroactiveNested { extension Int.RetroactiveNested { public func anchor() {} } @@ -104,11 +136,14 @@ extension Int.RetroactiveNested { // CHECK-LABEL: public func fn // CHECK-ENABLED-SAME: (_: TestCase::Struct, _: TestCase::Struct.TestCase::Nested) // CHECK-DISABLED-SAME: (_: TestCase.Struct, _: TestCase.Struct.Nested) +// CHECK-PRESERVE-SAME: (_: Struct, _: Struct.Nested) public func fn(_: Struct, _: Struct.Nested) {} // CHECK-LABEL: public func fn2 // CHECK-ENABLED-SAME: (_: T) where T : Swift::Identifiable, T.ID == TestCase::Struct // CHECK-DISABLED-SAME: (_: T) where T : Swift.Identifiable, T.ID == TestCase.Struct +// CHECK-PRESERVE-SAME: (_: T) where T : Swift.Identifiable, T.ID == TestCase.Struct +// Preserve quirk: Still qualified in constraints? @available(SwiftStdlib 5.1, *) public func fn2(_: T) where T.ID == Struct {} @@ -118,20 +153,67 @@ public protocol Proto { // CHECK: associatedtype AssocType : // CHECK-ENABLED-SAME: Swift::Identifiable // CHECK-DISABLED-SAME: Swift.Identifiable + // CHECK-PRESERVE-SAME: Identifiable associatedtype AssocType: Identifiable // CHECK: typealias TypeAlias = // CHECK-ENABLED-SAME: TestCase::Struct // CHECK-DISABLED-SAME: TestCase.Struct + // CHECK-PRESERVE-SAME: Struct typealias TypeAlias = Struct - // CHECK: func requirement() -> Self.AssocType.ID + // CHECK: typealias ID = + // CHECK-ENABLED-SAME: Self.AssocType.ID + // CHECK-DISABLED-SAME: Self.AssocType.ID + // CHECK-PRESERVE-SAME: AssocType.ID + typealias ID = AssocType.ID + + // CHECK: func requirement() -> + // CHECK-ENABLED-SAME: Self.AssocType.ID + // CHECK-DISABLED-SAME: Self.AssocType.ID + // CHECK-PRESERVE-SAME: AssocType.ID func requirement() -> AssocType.ID // CHECK: func requirement2() -> - // CHECK-ENABLED: Self.TypeAlias.TestCase::Nested - // CHECK-DISABLED: Self.TypeAlias.Nested + // CHECK-ENABLED-SAME: Self.TypeAlias.Nested + // CHECK-DISABLED-SAME: Self.TypeAlias.Nested + // CHECK-PRESERVE-SAME: TypeAlias.Nested func requirement2() -> TypeAlias.Nested // CHECK: } } + +@available(SwiftStdlib 5.1, *) +extension Proto { + public typealias Text = String +} + +// Test cases from rdar://166180424 + +// CHECK-LABEL: func fn3(_ t: T) -> +// CHECK-SAME: T.TypeAlias.Nested +@available(SwiftStdlib 5.1, *) +public func fn3(_ t: T) -> T.TypeAlias.Nested { fatalError() } + +// CHECK-LABEL: struct ProtoSet +@available(SwiftStdlib 5.1, *) +public struct ProtoSet { + // CHECK: let ids: + // CHECK-ENABLED-SAME: Swift::Set + // CHECK-DISABLED-SAME: Swift.Set + // CHECK-PRESERVE-SAME: Set + public let ids: Set + + // CHECK: let texts: + // CHECK-ENABLED-SAME: Swift::Set + // CHECK-DISABLED-SAME: Swift.Set + // CHECK-PRESERVE-SAME: Set + public let texts: Set + + // CHECK: let singleText: + // CHECK-SAME: T.Text + public let singleText: T.Text +} + +// DIAG-PRESERVE-OVERRIDDEN: warning: ignoring -module-interface-preserve-types-as-written (overridden by -enable-module-selectors-in-module-interface) +// DIAG-PRESERVE-NOT-OVERRIDDEN-NOT: warning: ignoring -module-interface-preserve-types-as-written (overridden by -enable-module-selectors-in-module-interface)