swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.51k stars 10.35k forks source link

[SR-8047] compiler should warn when implicitly casting Array<CVarArg> to CVarArg #50580

Open mayoff opened 6 years ago

mayoff commented 6 years ago
Previous ID SR-8047
Radar rdar://problem/41292685
Original Reporter @mayoff
Type Improvement
Environment macOS 10.13.5 (17F77) Xcode Version 10.0 beta 2 (10L177m) Toolchain: Swift 4.2 Snapshot 2018-06-19 (a)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 2 | |Component/s | Compiler | |Labels | Improvement | |Assignee | None | |Priority | Medium | md5: 3c00c89e0804ded75ece394b8719c377

relates to:

Issue Description:

Consider this:

import Foundation
import os.log

class OSLogWrapper {

    func logDefault(_ message: StaticString, _ args: CVarArg...) {
        os_log(message, type: .default, args)
    }

    func testWrapper() {
        logDefault("WTF: %f", 1.2345)
    }
}

let logger = OSLogWrapper()
logger.testWrapper()

This code compiles and runs without warning, but produces unexpected output:

2018-06-20 02:50:21.137119-0500 test[39525:6101799] WTF: 0.000000

The bug (in the example code, not in Swift) is that logDefault receives an Array<CVarArg> in its args parameter, and passes it to os_log, which is expecting variadic CVarArg arguments. Since Array conforms to CVarArg, Swift casts args to CVarArg implicitly.

The bug in Swift is that the conversion of Array<CVarArg> to CVarArg is rarely the desired behavior. (What's wanted is argument splatting, but I think that's unlikely to happen any time soon.) Swift should emit a warning when Array<CVarArg> is implicitly converted to CVarArg, and require an explicit cast to silence the warning.

P.S. This issue is based on https://stackoverflow.com/q/50937765/77567

belkadan commented 6 years ago

@swift-ci create

DeFrenZ commented 5 years ago

I think that this might be the same as SR-6386, just for os_log instead of String(format:arguments:)