Skip to content

[Swift][MiscDiagnostics] Assertion (numMissing + numExtra + numWrong > 0) in diagnoseArgumentLabelError when type-checking a trailing closure call with label on overloaded function #89196

@YuanchengJiang

Description

@YuanchengJiang

Description

swift reproduce.swift crashes with an assertion failure (numMissing + numExtra + numWrong > 0) && "Should not call this function with nothing to diagnose" in diagnoseArgumentLabelError at MiscDiagnostics.cpp:2973 when type-checking a call expression foo {} a: {} where foo is overloaded with one variant taking a default parameter and a labeled a: argument. The constraint system applies a RelabelArguments fix and calls diagnoseArgumentLabelError, but the computed label mismatch counts are all zero — there are no missing, extra, or wrong labels — causing the assertion to fire.

Reproducer

func foo(a: Int) {}
func foo(q: String = "", a: Int) {}

foo {} a: {}

Command

swift reproduce.swift

Expected behavior

The compiler should emit a diagnostic about the invalid trailing closure call syntax or the mismatched argument types, then exit gracefully. It should not crash with an assertion failure in diagnoseArgumentLabelError.

Actual behavior

reproduce.swift: error: consecutive statements on a line must be separated by ';'
reproduce.swift: error: expected expression

Assertion failed: ((numMissing + numExtra + numWrong > 0) &&
  "Should not call this function with nothing to diagnose"),
function diagnoseArgumentLabelError at MiscDiagnostics.cpp:2973.

While evaluating request TypeCheckPrimaryFileRequest(source_file "reproduce.swift")
While type-checking statement at [reproduce.swift:4:1] RangeText="foo {} a: {"
While type-checking expression at [reproduce.swift:4:1] RangeText="foo {} a: {"

Call chain

TypeCheckPrimaryFileRequest::evaluate
  → typeCheckTopLevelCodeDecl
    → typeCheckExpression          (foo {} a: {})
      → ConstraintSystem::applySolution
        → ConstraintSystem::applySolutionFixes
          → RelabelArguments::diagnose
            → diagnoseArgumentLabelError   ← assertion: all counts are zero

Root cause

When type-checking foo {} a: {}, the parser interprets this as a call to foo with a trailing closure followed by a: {} which is parsed as a labeled argument. The constraint system resolves the overload to foo(q:a:) and applies a RelabelArguments fix. When RelabelArguments::diagnose calls diagnoseArgumentLabelError, it computes the number of missing, extra, and wrong argument labels. Due to the unusual call syntax (trailing closure with subsequent labeled expression), all three counts come out as zero — meaning no actual relabeling is needed — but diagnoseArgumentLabelError asserts that at least one must be non-zero. The fix should add a guard in RelabelArguments::diagnose to bail out when all counts are zero rather than calling diagnoseArgumentLabelError, or ensure that RelabelArguments is not applied when the label mismatch is empty.

Environment

  • Compiler: Swift 6.5-dev (LLVM 7c86461e21cca7e, Swift 6da4da7)
  • Platform: x86_64 Linux (Ubuntu 24.04.4 LTS)
  • Command: swift reproduce.swift (no special flags required)
  • Crash site: swift/lib/Sema/MiscDiagnostics.cpp:2973 (diagnoseArgumentLabelError)
  • Affected code: swift/lib/Sema/CSFixes.cpp (RelabelArguments::diagnose)

This bug was found by fusion-fuzz

Metadata

Metadata

Assignees

No one assigned

    Labels

    crashBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions