Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing compiler warning #70630

Closed
bastie opened this issue Dec 26, 2023 · 9 comments
Closed

Missing compiler warning #70630

bastie opened this issue Dec 26, 2023 · 9 comments
Labels
compiler The Swift compiler in itself default arguments Feature: default arguments for value parameters missing warning Bug: Missing warning not a bug Resolution → not a bug: Reported as a bug but turned out to be expected behavior or programmer error overload resolution Area → compiler → type checker: Overload resolution (ranking) swift 5.9 type checker Area → compiler: Semantic analysis

Comments

@bastie
Copy link

bastie commented Dec 26, 2023

typo - see error description 2 days later 🥺

Description

In result of overload functions / methods with same name but more parameters and these parameters get default values (line 23) the "simple" function (line 20) appears uncallable.

Bildschirmfoto 2023-12-26 um 16 45 33

Reproduction

//
//  main.swift
//  MissingInitInfo
//
//  Created by Sebastian Ritter on 26.12.23.
//

import Foundation

// ✅ expected error
//let _ = Printable ()

// 🆘 name is not set, but called is init with param *as name* and ignoring init without second parameter
let _ = Printable (from: "Sebastian")

// ✅ expected result
let _ = Printable (from: "Sebastian", as: "Mr. Ritter")

public class Printable {
  public init (form sender : String) { // 🆘 uncallable (?) init method but no compiler message
    print ("Hello from \(sender)!")
  }
  public init (from sender : String, as name : String = "Bastie") {
    print ("Hello from \(name)?")
  }
}

Expected behavior

Compiler warning at line 20 as uncallable method / function

Environment

swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Target: arm64-apple-macosx14.0

Additional information

No response

@bastie bastie added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Dec 26, 2023
@msrutek-paylocity
Copy link

Is the typo

init (form sender : String)

vs

init (from sender : String, as name : String = "Bastie")

form vs from intentional?

@bastie
Copy link
Author

bastie commented Dec 28, 2023

@msrutek-paylocity Thanks!!! I like my German "Autokorrektur"...
and so I see the missing compiler message some lines below, or please tell how default value can be used.

//
//  main.swift
//  MissingInitInfo
//
//  Created by Sebastian Ritter on 26.12.23.
//

import Foundation

// ✅ expected error
//let _ = Printable ()

// ✅ expected result
let _ = Printable (from: "Sebastian")

// ✅ expected result
let _ = Printable (from: "Sebastian", as: "Mr. Ritter")

public class Printable {
  public init (from sender : String) {
    print ("Hello from \(sender)!")
  }
  public init (from sender : String, as name : String = "Bastie") { // 🆘  in result of init with one parameter unusable default value "Bastie" from init method
    print ("Hello from \(name)?")
  }
}

@Kyle-Ye
Copy link
Collaborator

Kyle-Ye commented Dec 29, 2023

This is expected behavior currently. See https://github.com/apple/swift/blob/main/docs/ReferenceGuides/UnderscoredAttributes.md#_disfavoredoverload and there is some great forum posts discussing the issue.

Suggestion 1:

  • Call init(from sender: String) in your init(from sender: String, as name: String) method.

Suggestion 2:

  • Swift prefer a less constraint overload method. If you like your second init to be called. You can add @_disfavoredoverload to your second init method.
@_disfavoredOverload
public init(from sender: String) {
    print("Hello from \(sender)!")
}
_ = Printable(from: "Sebastian") // Hello from Bastie?

@Kyle-Ye Kyle-Ye added not a bug Resolution → not a bug: Reported as a bug but turned out to be expected behavior or programmer error and removed bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Dec 29, 2023
@Kyle-Ye
Copy link
Collaborator

Kyle-Ye commented Dec 29, 2023

Feel free to ask further. If no reply is received, I think we can close it later.

@AnthonyLatsis AnthonyLatsis added swift 5.9 compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis overload resolution Area → compiler → type checker: Overload resolution (ranking) missing warning Bug: Missing warning default arguments Feature: default arguments for value parameters labels Dec 29, 2023
@AnthonyLatsis
Copy link
Collaborator

AnthonyLatsis commented Dec 29, 2023

Per Swift overload ranking rules the function that best matches the Printable(from: "Sebastian") call is Printable.init(form:). If you want to call Printable.init(from:as:) with the default argument without rethinking anything, you must disambiguate:

let _ = Printable.init(from:as:)("Sebastian")

@_disfavoredOverload, as Kyle suggests, is one other option that requires minimal change, but please note that this is not a public feature! There are no promises made about its stability or existence.

Important

Whether any of this is reasonable depends on the actual use case.

@AnthonyLatsis AnthonyLatsis closed this as not planned Won't fix, can't repro, duplicate, stale Dec 29, 2023
@Kyle-Ye
Copy link
Collaborator

Kyle-Ye commented Dec 29, 2023

Thanks for sharing the Printable.init(from:as:)("Sebastian") tip. Don't know it before.

@AnthonyLatsis
Copy link
Collaborator

Compiler warning at line 20 as uncallable method / function

I do not think a warning is justified here. The API design expectation behind this sort of overloading is that Printable(from:) behaves exactly like Printable(from:as:) in most, if not all, sensible implementations.

@Kyle-Ye
Copy link
Collaborator

Kyle-Ye commented Dec 29, 2023

let fn = Printable.init(from:as:)
let _ = fn("Sebastian")

// or

let _ = Printable.init(from:as:)("Sebastian")

The second way can be compiled, and the former will report a compiler error - "Missing argument for parameter #2 in call"

@AnthonyLatsis
Copy link
Collaborator

the former will report a compiler error

Right, thanks. Function values do not retain default arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself default arguments Feature: default arguments for value parameters missing warning Bug: Missing warning not a bug Resolution → not a bug: Reported as a bug but turned out to be expected behavior or programmer error overload resolution Area → compiler → type checker: Overload resolution (ranking) swift 5.9 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants