swiftlang/swift

Suboptimal diagnostics on mutating on immutable + optional value on non-optional parameter

Open

#87218 opened on Feb 13, 2026

View on GitHub
 (2 comments) (0 reactions) (0 assignees)Swift (69,989 stars) (10,719 forks)batch import
compilerdiagnostics qualityexpressionsgood first issuemutatingtype checker

Description

Description

Trying to use a mutating method on an immutable value and an optional argument in place for a non-optional parameter may produce worse diagnostics than what would be emitted independently:

  • "error: cannot use mutating member on immutable value" → isn't emitted.
  • "error: no exact matches in call to instance method 'X'" → emitted instead of the more accurate "error: value of optional type 'T?' must be unwrapped to a value of type 'T'".

Reproduction

func buildThing() {
    let dictionary = [String: [String]]()
    var optionalValue: String?
    if let array = dictionary["foo"] {
        array.append(optionalValue) 
            // ❌ No exact matches in call to instance method 'append'
                // ℹ️ Found candidate with type '(__owned String) -> ()'
    }
}

Expected behavior

I think it should be possible to diagnose the "Cannot use mutating member on immutable value" in this scenario. All overloads of append on Array are mutating.

Environment

swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1) Target: arm64-apple-macosx26.0

Additional information

By itself, this emits the right diagnostic:

func buildThingB() {
    let dictionary = [String: [String]]()
    if let array = dictionary["foo"] {
        array.append("bar")
           // ❌ Cannot use mutating member on immutable value: 'array' is a 'let' constant
    }
}

And so does this:

func buildThingC() {
    var dictionary = [String: [String]]()
    var optionalValue: String?
    dictionary["foo"]!.append(optionalValue)
        // ❌ Value of optional type 'String?' must be unwrapped to a value of type 'String'
            // ℹ️ Coalesce using '??' to provide a default when the optional value contains 'nil'
            // ℹ️ Force-unwrap using '!' to abort execution if the optional value contains 'nil'
}

And the compiler is able to emit both diagnostics at once under other (similar) circumstances:

func buildThingD() {
    let dictionary = [String: [String]]()
    var optionalValue: String?
    dictionary["foo"]!.append(optionalValue)
        // ❌ Cannot use mutating member on immutable value: 'dictionary' is a 'let' constant
        // ❌ Value of optional type 'String?' must be unwrapped to a value of type 'String'
            // ℹ️ Coalesce using '??' to provide a default when the optional value contains 'nil'
            // ℹ️ Force-unwrap using '!' to abort execution if the optional value contains 'nil'
}

Contributor guide