Bad error message when struct initializer inside a map is missing an argument

Originator:pharkas
Number:rdar://42338973 Date Originated:7/18/2018
Status: Resolved:
Product:Swift Compiler Product Version:
Classification:Serious Bug Reproducible:Always
 
I ran into an odd compiler error when I was trying to return the results of a map() in a function that used a generic type from a class. The error message was:
  error: 'map' produces '[T]', not the expected contextual result type '[Person]'
        return data.map({ Person(firstName: $0) })

The code causing this error is:
class MyPersonClass : MyGenericSuperclass<[(String, String)]> {
    override func mapPeople(from data: [(String, String)]) -> [Person] {
==>     return data.map({ Person(firstName: $0) })
    }
}

Person is defined as
struct Person {
    public var firstName : String
    public var lastName : String?
}

I incorrectly assumed that since lastName was optional I didn't need to pass it in the initializer for Person, but I got sent down a weird path because this error message has nothing to do with the initializer for Person. I assumed I was doing something wrong with map() or with the arguments or return type of that function.

I would expect that Swift would have the same error for this bad initializer inside of a map as it would when I try to do this outside of a map call:

error: missing argument for parameter 'lastName' in call
Person(firstName: "Jacob") 
                         ^
                         , lastName: <#String?#>

Comments

Sample code:

import Foundation

struct Person { public var firstName : String public var lastName : String?

func description() -> String {
    if let lastName = lastName {
        return firstName + " " + lastName
    } else {
        return firstName
    }
}

}

class MyGenericSuperclass { public func mapPeople(from data: T) -> [Person] { fatalError("Must be overridden by subclass") } }

class MyPersonClass : MyGenericSuperclass<[(String, String)]> { override func mapPeople(from data: [(String, String)]) -> [Person] { // This line produces an odd error about map not producing the correct type return data.map({ Person(firstName: $0) })

    // This is the proper initializer for Person
    //return data.map({ Person(firstName: $0, lastName: $1) })

    // This line produces the error that I would expect on line 33 above
    Person(firstName: "Jacob")
}

}

let fullNames = [("Johnny", "Appleseed"), ("Kate", "Bell"), ("Anna", "Haro")] let personClass = MyPersonClass() let people = personClass.mapPeople(from: fullNames) for person in people { print("Person: (person.description())") }


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!