Misleading "Cannot invoke initializer for type" error

Number:rdar://22200179 Date Originated:07-Aug-2015 06:12 PM
Status:Open Resolved:
Product:Developer Tools Product Version:7.0b5
Classification:UI/Usability Reproducible:Always
Passing UIView’s initializer an expression that cannot be itself be initialized gives a misleading error, and an amusingly wrong hint.

Trivial test case:

let dimension = 44
let view = UIView(frame: CGRectMake(10, 10, 10, dimension))
  // Error: Cannot invoke initializer for type ‘UIView’ with an argument list of type ‘(frame: CGRect)’
  //   Expected an argument list of type ‘(frame: CGRect)’

The error complains that you can’t use (frame: CGRect) and suggests you instead use (frame: CGRect).

This is a particularly confusing version of the general problem when you refactor a CGFloat from a parameter list into a variable. When you do this, the type gets inferred to Int instead of CGFloat and will fail to compile.

This, however, will get an understandable error message:

let rect = CGRectMake(10, 10, 10, dimension)
  // Error: Cannot invoke ‘CGRectMake’ with an argument list of type (Int, Int, Int, Int)

Steps to Reproduce:
Paste the two lines of code above into a playground or sample project, and build.

Expected Results:
The error message complains that dimension has been inferred to be an Int and therefore it can’t create the CGRect.
  Bonus awesomeness: the compiler realizes that you meant to create a CGFloat and the code compiles.

Actual Results:
The error message complains that you should instantiate UIView with a CGRect instead of a CGRect.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!