Frontend: Obsolete -fixit-all and -emit-fixits-path

With `ARCMigrate` and `arcmt-test` removed from clang in
https://github.com/llvm/llvm-project/pull/119269 and the new code
migration experience under way (see
https://github.com/swiftlang/swift-evolution/pull/2673), these options
are no longer relevant nor known to be in use. They were introduced
long ago to support fix-it application in Xcode.

For now, turn them into a no-op and emit a obsoletion warning.
This commit is contained in:
Anthony Latsis
2025-05-04 05:36:10 +01:00
parent d033eec1aa
commit 4f4141fea8
25 changed files with 434 additions and 1051 deletions

View File

@@ -193,6 +193,8 @@ ERROR(cannot_emit_ir_skipping_function_bodies,none,
WARNING(emit_reference_dependencies_without_primary_file,none,
"ignoring -emit-reference-dependencies (requires -primary-file)", ())
WARNING(ignoring_option_obsolete,none,
"ignoring '%0'; this option is obsolete", (StringRef))
WARNING(ignoring_option_requires_option,none,
"ignoring %0 (requires %1)", (StringRef, StringRef))
WARNING(warn_ignore_option_overriden_by,none,

View File

@@ -317,8 +317,6 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
options::OPT_emit_reference_dependencies_path);
auto serializedDiagnostics = getSupplementaryFilenamesFromArguments(
options::OPT_serialize_diagnostics_path);
auto fixItsOutput = getSupplementaryFilenamesFromArguments(
options::OPT_emit_fixits_path);
auto loadedModuleTrace = getSupplementaryFilenamesFromArguments(
options::OPT_emit_loaded_module_trace_path);
auto TBD = getSupplementaryFilenamesFromArguments(options::OPT_emit_tbd_path);
@@ -343,7 +341,7 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
options::OPT_save_optimization_record_path);
if (!clangHeaderOutput || !moduleOutput || !moduleDocOutput ||
!dependenciesFile || !referenceDependenciesFile ||
!serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD ||
!serializedDiagnostics || !loadedModuleTrace || !TBD ||
!moduleInterfaceOutput || !privateModuleInterfaceOutput || !packageModuleInterfaceOutput ||
!moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput ||
!moduleSemanticInfoOutput || !optRecordOutput) {
@@ -361,7 +359,6 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
sop.DependenciesFilePath = (*dependenciesFile)[i];
sop.ReferenceDependenciesFilePath = (*referenceDependenciesFile)[i];
sop.SerializedDiagnosticsPath = (*serializedDiagnostics)[i];
sop.FixItsOutputPath = (*fixItsOutput)[i];
sop.LoadedModuleTracePath = (*loadedModuleTrace)[i];
sop.TBDPath = (*TBD)[i];
sop.ModuleInterfaceOutputPath = (*moduleInterfaceOutput)[i];

View File

@@ -2548,7 +2548,20 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.EmitMacroExpansionFiles = !negated;
}
Opts.FixitCodeForAllDiagnostics |= Args.hasArg(OPT_fixit_all);
{
OptSpecifier obsoleteOpts[] = {
OPT_fixit_all,
OPT_emit_fixits_path,
};
for (auto option: obsoleteOpts) {
if (auto *arg = Args.getLastArg(option)) {
Diags.diagnose(SourceLoc(), diag::ignoring_option_obsolete,
arg->getOption().getPrefixedName());
}
}
}
Opts.SuppressWarnings |= Args.hasArg(OPT_suppress_warnings);
Opts.SuppressRemarks |= Args.hasArg(OPT_suppress_remarks);
for (const Arg *arg : Args.filtered(OPT_warning_treating_Group)) {

View File

@@ -114,8 +114,6 @@ function(get_test_dependencies SDK result_var_name)
if(NOT SWIFT_BUILT_STANDALONE)
list(APPEND deps_binaries
arcmt-test
c-arcmt-test
c-index-test
CASPluginTest
clang

View File

@@ -1821,3 +1821,12 @@ struct Issue75527 {
fn(0) // Make sure the argument label does not escape here.
}
}
do {
func f(p: Int, _: String) {}
// FIXME: Wrong expected argument type.
// expected-error@+2:5 {{cannot convert value of type 'Int' to expected argument type 'String'}}
// expected-error@+1:8 {{cannot convert value of type 'String' to expected argument type 'Int'}}
f(0, "")
// expected-error@-1:4 {{missing argument label 'p:' in call}}{{5-5=p: }}
}

View File

@@ -367,6 +367,28 @@ func forceUniversalBridgeToAnyObject<T, U: KnownClassProtocol>(a: T, b: U, c: An
_ = z
}
do {
func f(an : Any, oan: Any?) -> AnyObject? {
let a1 : AnyObject
a1 = an
// expected-error@-1:8 {{value of type 'Any' expected to be an instance of a class or class-constrained type in assignment}}{{none}}
// expected-note@-2:8 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}{{12-12= as AnyObject}}
let a2 : AnyObject?
a2 = an
// expected-error@-1:10 {{value of type 'Any' expected to be an instance of a class or class-constrained type in assignment}}{{12-12= as AnyObject}}
let a3 : AnyObject!
a3 = an
// expected-error@-1:10 {{value of type 'Any' expected to be an instance of a class or class-constrained type in assignment}}{{12-12= as AnyObject}}
let obj: AnyObject = an
// expected-error@-1:26 {{value of type 'Any' expected to be instance of class or class-constrained type}}{{none}}
// expected-note@-2:26 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}{{28-28= as AnyObject}}
return oan
// expected-error@-1:12 {{return expression of type 'Any' expected to be an instance of a class or class-constrained type}}{{15-15= as AnyObject}}
}
}
func bridgeAnyContainerToAnyObject(x: [Any], y: [NSObject: Any]) {
var z: AnyObject
z = x as AnyObject

View File

@@ -1,24 +0,0 @@
// RUN: not %target-swift-frontend -typecheck -primary-file %s -emit-fixits-path %t.main.remap -primary-file %S/Inputs/batch-mode-helper.swift -emit-fixits-path %t.helper.remap
// RUN: %FileCheck -check-prefix=CHECK-MAIN %s < %t.main.remap
// RUN: %FileCheck -check-prefix=NEGATIVE-MAIN %s < %t.main.remap
// RUN: %FileCheck -check-prefix=CHECK-HELPER %s < %t.helper.remap
// RUN: %FileCheck -check-prefix=NEGATIVE-HELPER %s < %t.helper.remap
// CHECK-MAIN: "file": "{{.+}}batch-mode.swift"
// CHECK-MAIN: "text": "case .a:\n<#code#>\ncase .b:\n<#code#>\ncase .c:\n<#code#>\n"
// NEGATIVE-MAIN-NOT: batch-mode-helper.swift
// CHECK-HELPER: "file": "{{.+}}batch-mode-helper.swift"
// CHECK-HELPER: "text": "case .x:\n<#code#>\ncase .y:\n<#code#>\ncase .z:\n<#code#>\n"
// NEGATIVE-HELPER-NOT: batch-mode.swift
enum E1 {
case a
case b
case c
}
func fooMain(_ e: E1) {
switch e {
}
}

View File

@@ -0,0 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -typecheck -fixit-all -emit-fixits-path %t.remap %s 2>&1 | %FileCheck %s
// CHECK: <unknown>:0: warning: ignoring '-fixit-all'; this option is obsolete
// CHECK: <unknown>:0: warning: ignoring '-emit-fixits-path'; this option is obsolete

View File

@@ -1,26 +0,0 @@
// This tests whether we accept fixits from warnings without filtering.
// The particular diagnostics used are not important.
// RUN: %swift -typecheck -target %target-triple %s -fixit-all -emit-fixits-path %t.remap
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
func ftest1() {
let myvar = 0
}
func foo() -> Int {
do {
} catch var err {
goo(err)
}
}
func goo(_ e: Error) {
}
@warn_unused_result(message="test message")
func warn_unused_result_removal() -> Int { return 5 }
@discardableResult func discardableResultOnVoidFunc() {}
@discardableResult func discardableResultOnNeverFunc() -> Never { fatalError() }

View File

@@ -1,26 +0,0 @@
// This tests whether we accept fixits from warnings without filtering.
// The particular diagnostics used are not important.
// RUN: %swift -typecheck -target %target-triple %s -fixit-all -emit-fixits-path %t.remap
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
func ftest1() {
_ = 0
}
func foo() -> Int {
do {
} catch let err {
goo(err)
}
}
func goo(_ e: Error) {
}
func warn_unused_result_removal() -> Int { return 5 }
func discardableResultOnVoidFunc() {}
func discardableResultOnNeverFunc() -> Never { fatalError() }

View File

@@ -1,111 +0,0 @@
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -typecheck %s -emit-fixits-path %t.remap
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
import ObjectiveC
// REQUIRES: objc_interop
@objc class Selectors {
func takeSel(_: Selector) {}
@objc func mySel() {}
func test() {
takeSel("mySel")
takeSel(Selector("mySel"))
}
}
@objc class OtherClass {
func test(s: Selectors) {
s.takeSel("mySel")
s.takeSel(Selector("mySel"))
}
}
@objc class Base {
@objc func baseSel() {}
}
@objc class Outer {
func takeSel(_: Selector) {}
@objc func outerSel() {}
@objc class Inner: Base {
func takeSel(_: Selector) {}
@objc func innerSel() {}
func test(s: Selectors, o: Outer) {
s.takeSel("mySel")
s.takeSel(Selector("mySel"))
takeSel("innerSel")
takeSel(Selector("innerSel"))
takeSel("baseSel")
takeSel(Selector("baseSel"))
o.takeSel("outerSel")
o.takeSel(Selector("outerSel"))
}
}
func test(s: Selectors, i: Inner) {
s.takeSel("mySel")
s.takeSel(Selector("mySel"))
i.takeSel("innerSel")
i.takeSel(Selector("innerSel"))
i.takeSel("baseSel")
i.takeSel(Selector("baseSel"))
takeSel("outerSel")
takeSel(Selector("outerSel"))
}
}
extension Outer {
func test2(s: Selectors, i: Inner) {
s.takeSel("mySel")
s.takeSel(Selector("mySel"))
i.takeSel("innerSel")
i.takeSel(Selector("innerSel"))
i.takeSel("baseSel")
i.takeSel(Selector("baseSel"))
takeSel("outerSel")
takeSel(Selector("outerSel"))
}
}
func freeTest(s: Selectors, o: Outer, i: Outer.Inner) {
s.takeSel("mySel")
s.takeSel(Selector("mySel"))
i.takeSel("innerSel")
i.takeSel(Selector("innerSel"))
i.takeSel("baseSel")
i.takeSel(Selector("baseSel"))
o.takeSel("outerSel")
o.takeSel(Selector("outerSel"))
}
func foo(an : Any) {
let a1 : AnyObject
a1 = an
let a2 : AnyObject?
a2 = an
let a3 : AnyObject!
a3 = an
}
func foo1(_ an : Any) {
let obj: AnyObject = an
}
func foo2(_ messageData: Any?) -> AnyObject? {
return messageData
}

View File

@@ -1,111 +0,0 @@
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -typecheck %s -emit-fixits-path %t.remap
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
import ObjectiveC
// REQUIRES: objc_interop
@objc class Selectors {
func takeSel(_: Selector) {}
@objc func mySel() {}
func test() {
takeSel(#selector(self.mySel))
takeSel(#selector(self.mySel))
}
}
@objc class OtherClass {
func test(s: Selectors) {
s.takeSel(#selector(Selectors.mySel))
s.takeSel(#selector(Selectors.mySel))
}
}
@objc class Base {
@objc func baseSel() {}
}
@objc class Outer {
func takeSel(_: Selector) {}
@objc func outerSel() {}
@objc class Inner: Base {
func takeSel(_: Selector) {}
@objc func innerSel() {}
func test(s: Selectors, o: Outer) {
s.takeSel(#selector(Selectors.mySel))
s.takeSel(#selector(Selectors.mySel))
takeSel(#selector(self.innerSel))
takeSel(#selector(self.innerSel))
takeSel(#selector(self.baseSel))
takeSel(#selector(self.baseSel))
o.takeSel(#selector(Outer.outerSel))
o.takeSel(#selector(Outer.outerSel))
}
}
func test(s: Selectors, i: Inner) {
s.takeSel(#selector(Selectors.mySel))
s.takeSel(#selector(Selectors.mySel))
i.takeSel(#selector(Inner.innerSel))
i.takeSel(#selector(Inner.innerSel))
i.takeSel(#selector(Base.baseSel))
i.takeSel(#selector(Base.baseSel))
takeSel(#selector(self.outerSel))
takeSel(#selector(self.outerSel))
}
}
extension Outer {
func test2(s: Selectors, i: Inner) {
s.takeSel(#selector(Selectors.mySel))
s.takeSel(#selector(Selectors.mySel))
i.takeSel(#selector(Inner.innerSel))
i.takeSel(#selector(Inner.innerSel))
i.takeSel(#selector(Base.baseSel))
i.takeSel(#selector(Base.baseSel))
takeSel(#selector(self.outerSel))
takeSel(#selector(self.outerSel))
}
}
func freeTest(s: Selectors, o: Outer, i: Outer.Inner) {
s.takeSel(#selector(Selectors.mySel))
s.takeSel(#selector(Selectors.mySel))
i.takeSel(#selector(Inner.innerSel))
i.takeSel(#selector(Inner.innerSel))
i.takeSel(#selector(Base.baseSel))
i.takeSel(#selector(Base.baseSel))
o.takeSel(#selector(Outer.outerSel))
o.takeSel(#selector(Outer.outerSel))
}
func foo(an : Any) {
let a1 : AnyObject
a1 = an as AnyObject
let a2 : AnyObject?
a2 = an as AnyObject
let a3 : AnyObject!
a3 = an as AnyObject
}
func foo1(_ an : Any) {
let obj: AnyObject = an as AnyObject
}
func foo2(_ messageData: Any?) -> AnyObject? {
return messageData as AnyObject
}

View File

@@ -1,318 +0,0 @@
// FIXME(integers): the test started to fail with the new integer protocols
// XFAIL: *
// RUN: not %swift -typecheck -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
class Base {}
class Derived : Base {}
var b : Base
b as Derived
b as Derived
b as! Base
var opti : Int?
// Add bang.
var i : Int = opti
// But remove unnecessary bang.
var i2 : Int = i!
struct MyMask : OptionSet {
init(_ rawValue: UInt) {}
init(rawValue: UInt) {}
init(nilLiteral: ()) {}
var rawValue: UInt { return 0 }
static var allZeros: MyMask { return MyMask(0) }
static var Bingo: MyMask { return MyMask(1) }
}
let _: MyMask = 0
func supported() -> MyMask {
return Int(MyMask.Bingo.rawValue)
}
struct MyEventMask2 : OptionSet {
init(rawValue: UInt64) {}
var rawValue: UInt64 { return 0 }
}
func sendIt(_: MyEventMask2) {}
func sendItOpt(_: MyEventMask2?) {}
func sendItOpt3(_: MyEventMask2???) {}
func testMask1(a: Int) {
sendIt(a)
}
func testMask2(a: UInt64) {
sendIt(a)
}
func testMask3(a: MyEventMask2) {
testMask1(a: a)
}
func testMask4(a: MyEventMask2) {
testMask2(a: a)
}
func testMask5(a: Int) {
sendItOpt(a)
}
func testMask6(a: Int) {
sendItOpt(a)
}
func testMask7(a: Int?) {
sendItOpt(a)
}
func testMask8(a: UInt64?) {
sendItOpt(a)
}
func testMask9(a: Any) {
sendItOpt(a as? Int)
}
func testMask10(a: Int?) {
sendIt(a) // no fix, nullability mismatch.
}
func testMask11(a: MyEventMask2?) {
testMask7(a: a)
}
func testMask12(a: MyEventMask2?) {
testMask8(a: a)
}
func testMask13(a: MyEventMask2?) {
testMask1(a: a) // no fix, nullability mismatch.
}
func testMask14() {
sendIt(1)
sendItOpt(2)
}
struct Wrapper {
typealias InnerMask = MyEventMask2
}
func sendItInner(_: Wrapper.InnerMask) {}
func testInnerMask(a: UInt64) {
sendItInner(a)
}
struct SomeName : RawRepresentable {
init(_ rawValue: String) {}
init(rawValue: String) {}
var rawValue: String { return "" }
}
func testPassSomeName(_: SomeName) {}
func testConvertSomeName(s: String) {
testPassSomeName("\(s)}")
}
class WrappedClass {}
class WrappedClassSub: WrappedClass {}
struct ClassWrapper : RawRepresentable {
var rawValue: WrappedClass
}
func testPassAnyObject(_: AnyObject) {}
func testPassAnyObjectOpt(_: AnyObject?) {}
func testPassWrappedSub(_: WrappedClassSub) {}
func testConvertClassWrapper(_ x: ClassWrapper, _ sub: WrappedClassSub) {
testPassAnyObject(x)
testPassAnyObjectOpt(x)
testPassWrappedSub(x)
let iuo: ClassWrapper! = x
testPassAnyObject(iuo)
testPassAnyObjectOpt(iuo)
let _: ClassWrapper = sub
let _: ClassWrapper = x.rawValue
// FIXME: This one inserts 'as!', which is incorrect.
let _: ClassWrapper = sub as AnyObject
}
enum MyEnumType : UInt32 {
case invalid
}
_ = MyEnumType(MyEnumType.invalid)
func goo(var e : Error) {
}
func goo2(var e: Error) {}
func goo3(var e: Int) { e = 3 }
protocol A {
func bar(var s: Int)
}
extension A {
func bar(var s: Int) {
s += 5
}
}
func baz(var x: Int) {
x += 10
}
func foo(let y: String, inout x: Int) {
}
struct Test1 : OptionSet {
init(rawValue: Int) {}
var rawValue: Int { return 0 }
}
print("", false)
func ftest1() {
// Don't replace the variable name with '_'
let myvar = 0
}
func ftest2(x x: @escaping Int -> Int) {}
protocol SomeProt {
func protMeth(p: Int)
}
@objc protocol SomeObjCProt {
func objcprotMeth(p: Int)
}
class Test2 : SomeProt, SomeObjCProt {
func protMeth(_ p: Int) {}
func instMeth(p: Int) {}
func instMeth2(p: Int, p2: Int) {}
func objcprotMeth(_ p: Int) {}
}
@objc class Test3 : SomeObjCProt {
func objcprotMeth(_ p: Int) {}
}
class SubTest2 : Test2 {
override func instMeth(_ p: Int) {}
}
Test2().instMeth(0)
Test2().instMeth2(0, p2:1)
func recit(_: Int32) {}
func ftest3(_ fd: CInt) {
recit(UInt(fd))
}
func ftest4(_ fd: UInt) {
recit(fd)
}
func letToVar1() {
let x = 1
if x == 2 {
x += 3
}
let y = ""
y.append("as")
y.append("df")
}
class Node {}
class Graph<NodeType : Node> {}
var graph: Graph
class Node2 {}
class Graph2<NodeType1 : Node, NodeType2 : Node2> {}
var graph: Graph2
@objc protocol ObjCProt { }
class Graph3<NodeType : ObjCProt> {}
var graph: Graph3
class Graph4<NodeType : SomeProt> {}
var graph: Graph4
var graphAgain = Graph4()
class GraphCombo<NodeType : SomeProt & ObjCProt> {}
var graph: GraphCombo
func evilCommas(s: String) {
_ = s[s.startIndex..<<#editorplaceholder#>]
_ = true ? s[s.startIndex..<<#editorplaceholder#>] : ""
_ = [s.startIndex..<<#editorplaceholder#>]
}
import Empty
func testGenericSig(x: Empty<Int>) -> Empty<String> {}
class NonObjC {}
protocol NonObjCProtocol {}
@objc class IBIssues {
@IBOutlet static private var ibout1: IBIssues!
@IBOutlet private var ibout2: NonObjC!
@IBOutlet private var ibout3: NonObjCProtocol!
@IBOutlet private let ibout4: IBIssues!
@IBOutlet private var ibout5: [[IBIssues]]!
@IBOutlet private var ibout6: [String: String]!
@IBInspectable static private var ibinspect1: IBIssues!
@IBAction static func ibact() {}
@IBSegueAction static func ibsegact(_: String, _: IBIssues) -> IBIssues { return self }
}
@IBDesignable extension SomeProt {}
func attrNowOnType(foo: ()->()) {}
class InitDynType {
init() {}
func notInit() {
self.init()
}
}
class NoSemi {
enum Bar { case bar }
var foo: .Bar = .bar
}
func fnWithClosure(c: @escaping ()->()) {}
func testescape(rec: ()->()) {
fnWithClosure { rec() }
}
@warn_unused_result func testDeprecatedAttr() -> Int { return 0 }
protocol Prot1 {}
protocol Prot2 {
associatedtype Ty = Prot1
}
class Cls1 : Prot1 {}
func testwhere<T: Prot2 where T.Ty == Cls1>(_: T) {}
enum E {
case abc
}
func testEnumRename() { _ = E.Abc }
func testAnyToAnyObject(x: Any) {
x.instMeth(p: 1)
}
func testProtocolCompositionSyntax() {
var _: protocol<>
var _: protocol<Prot1>
var _: protocol<Prot1, Prot2>
}
func disable_unnamed_param_reorder(p: Int, _: String) {}
disable_unnamed_param_reorder(0, "") // no change.
prefix operator ***** {}
class BoolFoo : BooleanType {
var boolValue: Bool {return false}
}
func testBoolValue(a : BoolFoo) {
if a { }
guard a {}
if a as BoolFoo {}
}
protocol P1 {}
protocol P2 {}
var a : protocol<P1, P2>?
var a2 : protocol<P1>= 17
class TestOptionalMethodFixit {
optional func test() {}
}

View File

@@ -1,318 +0,0 @@
// RUN: not %swift -typecheck -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
class Base {}
class Derived : Base {}
var b : Base
b as! Derived
b as! Derived
b
var opti : Int?
// Add bang.
var i : Int = opti!
// But remove unnecessary bang.
var i2 : Int = i
struct MyMask : OptionSet {
init(_ rawValue: UInt) {}
init(rawValue: UInt) {}
init(nilLiteral: ()) {}
var rawValue: UInt { return 0 }
static var allZeros: MyMask { return MyMask(0) }
static var Bingo: MyMask { return MyMask(1) }
}
let _: MyMask = []
func supported() -> MyMask {
return MyMask(rawValue: UInt(MyMask.Bingo))
}
struct MyEventMask2 : OptionSet {
init(rawValue: UInt64) {}
var rawValue: UInt64 { return 0 }
}
func sendIt(_: MyEventMask2) {}
func sendItOpt(_: MyEventMask2?) {}
func sendItOpt3(_: MyEventMask2???) {}
func testMask1(a: Int) {
sendIt(MyEventMask2(rawValue: UInt64(a)))
}
func testMask2(a: UInt64) {
sendIt(MyEventMask2(rawValue: a))
}
func testMask3(a: MyEventMask2) {
testMask1(a: Int(a.rawValue))
}
func testMask4(a: MyEventMask2) {
testMask2(a: a.rawValue)
}
func testMask5(a: Int) {
sendItOpt(MyEventMask2(rawValue: UInt64(a)))
}
func testMask6(a: Int) {
sendItOpt(MyEventMask2(rawValue: UInt64(a)))
}
func testMask7(a: Int?) {
sendItOpt(a.map { MyEventMask2(rawValue: UInt64($0)) })
}
func testMask8(a: UInt64?) {
sendItOpt(a.map { MyEventMask2(rawValue: $0) })
}
func testMask9(a: Any) {
sendItOpt((a as? Int).map { MyEventMask2(rawValue: UInt64($0)) })
}
func testMask10(a: Int?) {
sendIt(a) // no fix, nullability mismatch.
}
func testMask11(a: MyEventMask2?) {
testMask7(a: a.map { Int($0.rawValue) })
}
func testMask12(a: MyEventMask2?) {
testMask8(a: a.map { $0.rawValue })
}
func testMask13(a: MyEventMask2?) {
testMask1(a: a) // no fix, nullability mismatch.
}
func testMask14() {
sendIt(MyEventMask2(rawValue: 1))
sendItOpt(MyEventMask2(rawValue: 2))
}
struct Wrapper {
typealias InnerMask = MyEventMask2
}
func sendItInner(_: Wrapper.InnerMask) {}
func testInnerMask(a: UInt64) {
sendItInner(Wrapper.InnerMask(rawValue: a))
}
struct SomeName : RawRepresentable {
init(_ rawValue: String) {}
init(rawValue: String) {}
var rawValue: String { return "" }
}
func testPassSomeName(_: SomeName) {}
func testConvertSomeName(s: String) {
testPassSomeName(SomeName(rawValue: "\(s)}"))
}
class WrappedClass {}
class WrappedClassSub: WrappedClass {}
struct ClassWrapper : RawRepresentable {
var rawValue: WrappedClass
}
func testPassAnyObject(_: AnyObject) {}
func testPassAnyObjectOpt(_: AnyObject?) {}
func testPassWrappedSub(_: WrappedClassSub) {}
func testConvertClassWrapper(_ x: ClassWrapper, _ sub: WrappedClassSub) {
testPassAnyObject(x.rawValue)
testPassAnyObjectOpt(x.rawValue)
testPassWrappedSub(x)
let iuo: ClassWrapper! = x
testPassAnyObject(iuo)
testPassAnyObjectOpt(iuo.map { $0.rawValue })
let _: ClassWrapper = ClassWrapper(rawValue: sub)
let _: ClassWrapper = ClassWrapper(rawValue: x.rawValue)
// FIXME: This one inserts 'as!', which is incorrect.
let _: ClassWrapper = sub as AnyObject as! ClassWrapper
}
enum MyEnumType : UInt32 {
case invalid
}
_ = MyEnumType.invalid
func goo(e : Error) {
var e = e
}
func goo2(e: Error) { var e = e }
func goo3(e: Int) { var e = e; e = 3 }
protocol A {
func bar(s: Int)
}
extension A {
func bar(s: Int) {
var s = s
s += 5
}
}
func baz(x: Int) {
var x = x
x += 10
}
func foo(y: String, x: inout Int) {
}
struct Test1 : OptionSet {
init(rawValue: Int) {}
var rawValue: Int { return 0 }
}
print("", false)
func ftest1() {
// Don't replace the variable name with '_'
let myvar = 0
}
func ftest2(x: @escaping (Int) -> Int) {}
protocol SomeProt {
func protMeth(p: Int)
}
@objc protocol SomeObjCProt {
func objcprotMeth(p: Int)
}
class Test2 : SomeProt, SomeObjCProt {
func protMeth(_ p: Int) {}
func instMeth(p: Int) {}
func instMeth2(p: Int, p2: Int) {}
func objcprotMeth(_ p: Int) {}
}
@objc class Test3 : SomeObjCProt {
func objcprotMeth(_ p: Int) {}
}
class SubTest2 : Test2 {
override func instMeth(_ p: Int) {}
}
Test2().instMeth(0)
Test2().instMeth2(0, p2:1)
func recit(_: Int32) {}
func ftest3(_ fd: CInt) {
recit(fd)
}
func ftest4(_ fd: UInt) {
recit(Int32(fd))
}
func letToVar1() {
var x = 1
if x == 2 {
x += 3
}
var y = ""
y.append("as")
y.append("df")
}
class Node {}
class Graph<NodeType : Node> {}
var graph: Graph<Node>
class Node2 {}
class Graph2<NodeType1 : Node, NodeType2 : Node2> {}
var graph: Graph2<Node, Node2>
@objc protocol ObjCProt { }
class Graph3<NodeType : ObjCProt> {}
var graph: Graph3<ObjCProt>
class Graph4<NodeType : SomeProt> {}
var graph: Graph4<<#NodeType: SomeProt#>>
var graphAgain = Graph4<<#NodeType: SomeProt#>>()
class GraphCombo<NodeType : SomeProt & ObjCProt> {}
var graph: GraphCombo<<#NodeType: ObjCProt & SomeProt#>>
func evilCommas(s: String) {
_ = s[s.startIndex..<<#editorplaceholder#>]
_ = true ? s[s.startIndex..<<#editorplaceholder#>] : ""
_ = [s.startIndex..<<#editorplaceholder#>]
}
import Empty
func testGenericSig(x: Empty<Int>) -> Empty<String> {}
class NonObjC {}
protocol NonObjCProtocol {}
@objc class IBIssues {
@IBOutlet static private var ibout1: IBIssues!
@IBOutlet private var ibout2: NonObjC!
@IBOutlet private var ibout3: NonObjCProtocol!
@IBOutlet private let ibout4: IBIssues!
@IBOutlet private var ibout5: [[IBIssues]]!
@IBOutlet private var ibout6: [String: String]!
@IBInspectable static private var ibinspect1: IBIssues!
@IBAction static func ibact() {}
@IBSegueAction static func ibsegact(_: String, _: IBIssues) -> IBIssues { return self }
}
@IBDesignable extension SomeProt {}
func attrNowOnType(foo: ()->()) {}
class InitDynType {
init() {}
func notInit() {
self.init()
}
}
class NoSemi {
enum Bar { case bar }
var foo: .Bar = .bar
}
func fnWithClosure(c: @escaping ()->()) {}
func testescape(rec: @escaping ()->()) {
fnWithClosure { rec() }
}
func testDeprecatedAttr() -> Int { return 0 }
protocol Prot1 {}
protocol Prot2 {
associatedtype Ty = Prot1
}
class Cls1 : Prot1 {}
func testwhere<T: Prot2>(_: T) where T.Ty == Cls1 {}
enum E {
case abc
}
func testEnumRename() { _ = E.Abc }
func testAnyToAnyObject(x: Any) {
(x as AnyObject).instMeth(p: 1)
}
func testProtocolCompositionSyntax() {
var _: Any
var _: Prot1
var _: Prot1 & Prot2
}
func disable_unnamed_param_reorder(p: Int, _: String) {}
disable_unnamed_param_reorder(0, "") // no change.
prefix operator *****
class BoolFoo : Bool {
var boolValue: Bool {return false}
}
func testBoolValue(a : BoolFoo) {
if a.boolValue { }
guard a.boolValue {}
if (a as BoolFoo).boolValue {}
}
protocol P1 {}
protocol P2 {}
var a : (P1 & P2)?
var a2 : P1= 17 as! P1
class TestOptionalMethodFixit {
func test() {}
}

View File

@@ -1,34 +0,0 @@
// RUN: not %swift -emit-sil -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
func something() -> Bool { return true }
func foo1() {
if something() {
} else
}
func foo2() {
if something() {
} else
foo1()
}
func foo3() {
if something() {
} else something() { // all on one line, 'if' inserted
}
}
func foo4() {
if something() {
} else something()
{
}
}
func foo5() {
if something() {
} else something()
foo1()
}

View File

@@ -1,34 +0,0 @@
// RUN: not %swift -emit-sil -target %target-triple %s -emit-fixits-path %t.remap -I %S/Inputs
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
func something() -> Bool { return true }
func foo1() {
if something() {
} else
}
func foo2() {
if something() {
} else
foo1()
}
func foo3() {
if something() {
} else if something() { // all on one line, 'if' inserted
}
}
func foo4() {
if something() {
} else something()
{
}
}
func foo5() {
if something() {
} else something()
foo1()
}

View File

@@ -7,12 +7,7 @@
// RUN: %host-build-swift -emit-library %S/Inputs/syntax_macro_definitions.swift -o %t/%target-library-name(MacroDefinition) -module-name MacroDefinition -swift-version 5 -g -no-toolchain-stdlib-rpath
// RUN: %target-swift-frontend -typecheck %s -load-plugin-library %t/%target-library-name(MacroDefinition) -swift-version 5 -serialize-diagnostics-path %t/diags.dia -fixit-all -emit-fixits-path %t/fixits.json
// RUN: %FileCheck %s --check-prefix FIXITS-JSON < %t/fixits.json
// FIXITS-JSON: [
// FIXITS-JSON-NEXT: ]
// RUN: %target-swift-frontend -typecheck %s -load-plugin-library %t/%target-library-name(MacroDefinition) -swift-version 5 -serialize-diagnostics-path %t/diags.dia
// RUN: c-index-test -read-diagnostics %t/diags.dia 2>&1 | %FileCheck -check-prefix DIAGS %s

View File

@@ -71,3 +71,8 @@ do {
// expected-swift5-warning@-1 {{cannot explicitly specialize initializer 'init(_:)'}}
// expected-swift6-error@-2 {{cannot explicitly specialize initializer 'init(_:)'}}
}
do {
// expected-error@+1:13 {{cannot specialize non-generic type 'module<Swift>'}}{{none}}
func f(_: Swift<Int>) {}
}

View File

@@ -45,7 +45,13 @@ func passClosure() {
}
}
// FIXME: No 'var x = x' fix-it.
do {
func f(x: Int) {
x = 3 // expected-error@:5 {{cannot assign to value: 'x' is a 'let' constant}}{{none}}
x += 3 // expected-error@:7 {{left side of mutating operator isn't mutable: 'x' is a 'let' constant}}{{none}}
}
}
class FooClass {
class let type_let = 5 // expected-error {{class stored properties not supported in classes}}

View File

@@ -1,7 +1,6 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -emit-fixits-path %t.remap -fixit-all
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern
// REQUIRES: swift_feature_Extern
@_extern(c) // expected-warning {{C name '+' may be invalid; explicitly specify the name in '@_extern(c)' to suppress this warning}}
@_extern(c) // expected-warning {{C name '+' may be invalid; explicitly specify the name in '@_extern(c)' to suppress this warning}}{{11-11=, "+"}}{{none}}
func +(a: Int, b: Bool) -> Bool

View File

@@ -1,7 +0,0 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -emit-fixits-path %t.remap -fixit-all
// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
// REQUIRES: swift_feature_Extern
@_extern(c, "+") // expected-warning {{C name '+' may be invalid; explicitly specify the name in '@_extern(c)' to suppress this warning}}
func +(a: Int, b: Bool) -> Bool

View File

@@ -1,8 +1,7 @@
// RUN: %empty-directory(%t)
// RUN: not %target-swift-frontend -typecheck -verify -serialize-diagnostics-path %t/serialized.dia -emit-fixits-path %t/fixits %s 2>&1 | %FileCheck %s
// RUN: not %target-swift-frontend -typecheck -verify -serialize-diagnostics-path %t/serialized.dia %s 2>&1 | %FileCheck %s
// RUN: not %target-swift-frontend -typecheck -verify -warnings-as-errors %s 2>&1 | %FileCheck %s -check-prefix CHECK-WARNINGS-AS-ERRORS
// RUN: %FileCheck %s -check-prefix CHECK-SERIALIZED <%t/serialized.dia
// RUN: %FileCheck %s -check-prefix CHECK-FIXITS <%t/fixits
// Wrong message
let x: Int = "hello, world!" // expected-error {{foo bar baz}}
@@ -45,10 +44,3 @@ extension Crap {} // expected-error {{non-nominal type 'Crap' (aka '() -> ()') c
// Verify the serialized diags have the right magic at the top.
// CHECK-SERIALIZED: DIA
// Ensure the verifier doesn't interfere with -emit-fixits-path.
// CHECK-FIXITS: {
// CHECK-FIXITS: "file":
// CHECK-FIXITS: "offset":
// CHECK-FIXITS: "text": " as! Int"
// CHECK-FIXITS: }

View File

@@ -0,0 +1,221 @@
// RUN: %target-typecheck-verify-swift
do {
struct Mask : OptionSet {
init(_ rawValue: UInt) {}
init(rawValue: UInt) {}
var rawValue: UInt { 0 }
static var Bingo: Mask { Mask(1) }
}
// FIXME: No fix-it. Could be '= Mask(rawValue: 0)' or '= []'.
let _: Mask = 0
// expected-error@-1:17 {{cannot convert value of type 'Int' to specified type 'Mask'}}{{none}}
}
do {
enum E: Int {
case a
}
// TODO: A better fix-it is to remove the init call.
_ = E(E.a)
// expected-error@-1:9 {{missing argument label 'rawValue:' in call}}{{9-9=rawValue: }}
// expected-error@-2:11 {{cannot convert value of type 'E' to expected argument type 'Int'}}{{12-12=.rawValue}}
}
// Fix-its for expectation of implicit RawRepresentable <-> RawValue cast.
do {
struct Mask : OptionSet {
init(rawValue: UInt64) {}
var rawValue: UInt64 { return 0 }
}
// RawValue -> RawRepresentable / OptionSet.
do {
struct Mask : OptionSet {
init(rawValue: UInt64) {}
var rawValue: UInt64 { return 0 }
}
func takeMask(_: Mask) {}
func takeMask_o(_: Mask?) {}
let int: Int
let int_o: Int?
let uint64: UInt64
let uint64_o: UInt64?
// FIXME: No fix-it. Could be 'Mask(rawValue: 1)'.
let _: Mask = 1
// expected-error@-1:19 {{cannot convert value of type 'Int' to specified type 'Mask'}}{{none}}
takeMask(1)
// expected-error@-1:14 {{cannot convert value of type 'Int' to expected argument type 'Mask'}}{{none}}
// FIXME: No fix-it. Could be 'Mask(rawValue: UInt64(int))'.
let _: Mask = int
// expected-error@-1:19 {{cannot convert value of type 'Int' to specified type 'Mask'}}{{none}}
takeMask(int)
// expected-error@-1:14 {{cannot convert value of type 'Int' to expected argument type 'Mask'}}{{none}}
let _: Mask = uint64
// expected-error@-1:19 {{cannot convert value of type 'UInt64' to specified type 'Mask'}}{{19-19=Mask(rawValue: }}{{25-25=) ?? <#default value#>}}
takeMask(uint64)
// expected-error@-1:14 {{cannot convert value of type 'UInt64' to expected argument type 'Mask'}}{{14-14=Mask(rawValue: }}{{20-20=) ?? <#default value#>}}
// FIXME: No fix-it. Could be 'Mask(rawValue: UInt64(int_o ?? <#default value#>)'.
let _: Mask = int_o
// expected-error@-1:19 {{cannot convert value of type 'Int?' to specified type 'Mask'}}{{none}}
takeMask(int_o)
// expected-error@-1:14 {{cannot convert value of type 'Int?' to expected argument type 'Mask'}}{{none}}
// FIXME: No fix-it. Could be 'Mask(rawValue: 1)'.
let _: Mask? = 1
// expected-error@-1:20 {{cannot convert value of type 'Int' to specified type 'Mask'}}{{none}}
takeMask_o(1)
// expected-error@-1:16 {{cannot convert value of type 'Int' to expected argument type 'Mask'}}{{none}}
// FIXME: No fix-it. Could be 'Mask(rawValue: UInt64(int))'.
let _: Mask? = int
// expected-error@-1:20 {{cannot convert value of type 'Int' to specified type 'Mask'}}{{none}}
takeMask_o(int)
// expected-error@-1:16 {{cannot convert value of type 'Int' to expected argument type 'Mask'}}{{none}}
// FIXME: No fix-it. Could be 'int_o.map { Mask(rawValue: UInt64($0)) }'.
let _: Mask? = int_o
// expected-error@-1:20 {{cannot convert value of type 'Int?' to specified type 'Mask?'}}{{none}}
takeMask_o(int_o)
// expected-error@-1:16 {{cannot convert value of type 'Int?' to expected argument type 'Mask?'}}{{none}}
// FIXME: No fix-it. Could be 'uint64_o.map(Mask(rawValue:))' or 'uint64_o.map { Mask(rawValue: $0) }'.
let _: Mask? = uint64_o
// expected-error@-1:20 {{cannot convert value of type 'UInt64?' to specified type 'Mask?'}}{{none}}
takeMask_o(uint64_o)
// expected-error@-1:16 {{cannot convert value of type 'UInt64?' to expected argument type 'Mask?'}}{{none}}
// FIXME: No fix-it. Could be '(anything as? Int).map { Mask(rawValue: UInt64($0)) }'.
let anything: Any
let _: Mask? = anything as? Int
// expected-error@-1:29 {{cannot convert value of type 'Int?' to specified type 'Mask?'}}{{none}}
takeMask_o(anything as? Int)
// expected-error@-1:25 {{cannot convert value of type 'Int?' to expected argument type 'Mask?'}}{{none}}
}
// Try a nested OptionSet.
do {
struct Shell {
struct Mask : OptionSet {
init(rawValue: UInt64) {}
var rawValue: UInt64 { return 0 }
}
}
// FIXME: This is an OptionSet, coelescing in the fix-it is not necessary.
let _: Shell.Mask = UInt64(0)
// expected-error@-1:25 {{cannot convert value of type 'UInt64' to specified type 'Shell.Mask'}}{{25-25=Shell.Mask(rawValue: }}{{34-34=) ?? <#default value#>}}
}
// Try a non-integral RawValue.
do {
struct Mask : RawRepresentable {
init(rawValue: String) {}
var rawValue: String { return "" }
}
let s: String
let _: Mask = "\(s)}"
// expected-error@-1:19 {{cannot convert value of type 'String' to specified type 'Mask'}}{{19-19=Mask(rawValue: }}{{26-26=) ?? <#default value#>}}
}
// RawRepresentable / OptionSet -> RawValue.
do {
struct Mask : OptionSet {
init(rawValue: UInt64) {}
var rawValue: UInt64 { return 0 }
}
func takeInt(_: Int) {}
func takeInt_o(_: Int?) {}
func takeUInt64(_: UInt64) {}
func takeUInt64_o(_: UInt64?) {}
let mask: Mask
let mask_o: Mask?
// FIXME: No fix-it. Could be 'Int(mask.rawValue)'.
let _: Int = mask
// expected-error@-1:18 {{cannot convert value of type 'Mask' to specified type 'Int'}}{{none}}
takeInt(mask)
// expected-error@-1:13 {{cannot convert value of type 'Mask' to expected argument type 'Int'}}{{none}}
let _: UInt64 = mask
// expected-error@-1:21 {{cannot convert value of type 'Mask' to specified type 'UInt64'}}{{25-25=.rawValue}}
takeUInt64(mask)
// expected-error@-1:16 {{cannot convert value of type 'Mask' to expected argument type 'UInt64'}}{{20-20=.rawValue}}
let _: UInt64 = mask_o
// expected-error@-1:21 {{cannot convert value of type 'Mask?' to specified type 'UInt64'}}{{27-27=?.rawValue ?? <#default value#>}}
takeUInt64(mask_o)
// expected-error@-1:16 {{cannot convert value of type 'Mask?' to expected argument type 'UInt64'}}{{22-22=?.rawValue ?? <#default value#>}}
// FIXME: No fix-it. Could be 'mask_o.map { Int($0.rawValue) }'.
let _: Int? = mask_o
// expected-error@-1:19 {{cannot convert value of type 'Mask?' to specified type 'Int?'}}{{none}}
takeInt_o(mask_o)
// expected-error@-1:15 {{cannot convert value of type 'Mask?' to expected argument type 'Int?'}}{{none}}
// FIXME: No fix-it. Could be 'mask_o?.rawValue' or 'mask_o.map { $0.rawValue }'.
let _: UInt64? = mask_o
// expected-error@-1:22 {{cannot convert value of type 'Mask?' to specified type 'UInt64?'}}{{28-28=?.rawValue}}
takeUInt64_o(mask_o)
// expected-error@-1:18 {{cannot convert value of type 'Mask?' to expected argument type 'UInt64?'}}{{none}}
}
}
do {
class Class {}
class SubClass: Class {}
struct ClassWrapper : RawRepresentable {
var rawValue: Class
}
func takeAnyObject(_: AnyObject) {}
func takeAnyObjectOpt(_: AnyObject?) {}
func takeSubClass(_: SubClass) {}
do {
let classWrapper: ClassWrapper
let subClass: SubClass
takeAnyObject(classWrapper)
// expected-error@-1:19 {{argument type 'ClassWrapper' expected to be an instance of a class or class-constrained type}}{{none}}
takeAnyObjectOpt(classWrapper)
// expected-error@-1:22 {{argument type 'ClassWrapper' expected to be an instance of a class or class-constrained type}}{{none}}
// FIXME: Bad fix-it, will not compile
takeSubClass(classWrapper)
// expected-error@-1:18 {{cannot convert value of type 'ClassWrapper' to expected argument type 'SubClass'}}{{30-30=.rawValue}}
let iuo: ClassWrapper!
takeAnyObject(iuo)
// expected-error@-1:19 {{argument type 'ClassWrapper?' expected to be an instance of a class or class-constrained type}}{{none}}
takeAnyObjectOpt(iuo)
// expected-error@-1:22 {{argument type 'ClassWrapper' expected to be an instance of a class or class-constrained type}}{{none}}
let _: ClassWrapper = subClass
// expected-error@-1:27 {{cannot convert value of type 'SubClass' to specified type 'ClassWrapper'}}{{27-27=ClassWrapper(rawValue: }} {{35-35=) ?? <#default value#>}}
let _: ClassWrapper = classWrapper.rawValue
// expected-error@-1:40 {{cannot convert value of type 'Class' to specified type 'ClassWrapper'}}{{27-27=ClassWrapper(rawValue: }} {{48-48=) ?? <#default value#>}}
// FIXME: This note replaces 'as' with 'as!', which is incorrect.
// expected-note@+3:36 {{did you mean to use 'as!' to force downcast?}}{{36-38=as!}}
// FIXME: Bad fix-it, will not compile
// expected-error@+1:36 {{cannot convert value of type 'AnyObject' to specified type 'ClassWrapper'}}{{27-27=ClassWrapper(rawValue: }} {{48-48=) ?? <#default value#>}}
let _: ClassWrapper = subClass as AnyObject
// expected-error@-1:36 {{'AnyObject' is not convertible to 'Class'}}{{none}}
}
}

View File

@@ -0,0 +1,18 @@
// RUN: %target-typecheck-verify-swift
do {
func takeInt32(_: Int32) {}
func f1(_ cint: CInt) {
takeInt32(UInt(cint))
// expected-error@-1:15 {{cannot convert value of type 'UInt' to expected argument type 'Int32'}}{{15-15=Int32(}}{{25-25=)}}
}
func f2(_ uint: UInt) {
takeInt32(uint)
// expected-error@-1:15 {{cannot convert value of type 'UInt' to expected argument type 'Int32'}}{{15-15=Int32(}}{{19-19=)}}
let int32: Int32 = uint
// expected-error@-1:24 {{cannot convert value of type 'UInt' to specified type 'Int32'}}{{24-24=Int32(}}{{28-28=)}}
}
}

View File

@@ -14,22 +14,6 @@
// Make sure we get the right diagnostics.
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t.overlays) -typecheck %s -verify
// Copy the source, apply the Fix-Its, and compile it again, making
// sure that we've cleaned up all of the deprecation warnings.
// RUN: %empty-directory(%t.sources)
// RUN: %empty-directory(%t.remapping)
// RUN: cp %s %t.sources/fixits.swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t.overlays) -typecheck %t.sources/fixits.swift -fixit-all -emit-fixits-path %t.remapping/fixits.remap
// RUN: %{python} %utils/apply-fixit-edits.py %t.remapping
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t.overlays) -typecheck %t.sources/fixits.swift -diagnostic-style llvm 2> %t.result
// RUN: %FileCheck %s < %t.result
// RUN: grep -c "warning:" %t.result | grep 3
// CHECK: warning: no method declared with Objective-C selector 'unknownMethodWithValue:label:'
// CHECK: warning: string literal is not a valid Objective-C selector
// CHECK: warning: string literal is not a valid Objective-C selector
import Foundation
import Helper
@@ -83,3 +67,129 @@ func testSelectorConstruction() {
// Note: from Foundation
_ = Selector("initWithArray:") // expected-warning{{use '#selector' instead of explicitly constructing a 'Selector'}}{{7-33=#selector(NSSet.init(array:))}}
}
@objc class Selectors: NSObject {
func takeSel(_: Selector) {}
@objc func mySel() {}
func test() {
takeSel("mySel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-20=#selector(self.mySel)}}
takeSel(Selector("mySel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-30=#selector(self.mySel)}}
}
}
@objc class OtherClass: NSObject {
func test(s: Selectors) {
s.takeSel("mySel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-22=#selector(Selectors.mySel)}}
s.takeSel(Selector("mySel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-32=#selector(Selectors.mySel)}}
}
}
@objc class Base: NSObject {
@objc func baseSel() {}
}
@objc class Outer: NSObject {
func takeSel(_: Selector) {}
@objc func outerSel() {}
@objc class Inner: Base {
func takeSel(_: Selector) {}
@objc func innerSel() {}
func test(s: Selectors, o: Outer) {
s.takeSel("mySel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{17-24=#selector(Selectors.mySel)}}
s.takeSel(Selector("mySel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{17-34=#selector(Selectors.mySel)}}
takeSel("innerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-25=#selector(self.innerSel)}}
takeSel(Selector("innerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-35=#selector(self.innerSel)}}
takeSel("baseSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-24=#selector(self.baseSel)}}
takeSel(Selector("baseSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-34=#selector(self.baseSel)}}
o.takeSel("outerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{17-27=#selector(Outer.outerSel)}}
o.takeSel(Selector("outerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{17-37=#selector(Outer.outerSel)}}
}
}
func test(s: Selectors, i: Inner) {
s.takeSel("mySel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-22=#selector(Selectors.mySel)}}
s.takeSel(Selector("mySel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-32=#selector(Selectors.mySel)}}
i.takeSel("innerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-25=#selector(Inner.innerSel)}}
i.takeSel(Selector("innerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-35=#selector(Inner.innerSel)}}
i.takeSel("baseSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-24=#selector(Base.baseSel)}}
i.takeSel(Selector("baseSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-34=#selector(Base.baseSel)}}
takeSel("outerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-23=#selector(self.outerSel)}}
takeSel(Selector("outerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-33=#selector(self.outerSel)}}
}
}
extension Outer {
func test2(s: Selectors, i: Inner) {
s.takeSel("mySel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-22=#selector(Selectors.mySel)}}
s.takeSel(Selector("mySel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-32=#selector(Selectors.mySel)}}
i.takeSel("innerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-25=#selector(Inner.innerSel)}}
i.takeSel(Selector("innerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-35=#selector(Inner.innerSel)}}
i.takeSel("baseSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{15-24=#selector(Base.baseSel)}}
i.takeSel(Selector("baseSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{15-34=#selector(Base.baseSel)}}
takeSel("outerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-23=#selector(self.outerSel)}}
takeSel(Selector("outerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-33=#selector(self.outerSel)}}
}
}
func freeTest(s: Selectors, o: Outer, i: Outer.Inner) {
s.takeSel("mySel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-20=#selector(Selectors.mySel)}}
s.takeSel(Selector("mySel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-30=#selector(Selectors.mySel)}}
// FIXME: Fix-it should be 'Outer.Inner.innerSel'.
i.takeSel("innerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-23=#selector(Inner.innerSel)}}
i.takeSel(Selector("innerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-33=#selector(Inner.innerSel)}}
i.takeSel("baseSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-22=#selector(Base.baseSel)}}
i.takeSel(Selector("baseSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-32=#selector(Base.baseSel)}}
o.takeSel("outerSel")
// expected-warning@-1 {{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{13-23=#selector(Outer.outerSel)}}
o.takeSel(Selector("outerSel"))
// expected-warning@-1 {{use '#selector' instead of explicitly constructing a 'Selector'}}{{13-33=#selector(Outer.outerSel)}}
}