Improve syntax on static member look up

With Extending Static Member Lookup in Generic Contexts implemented in 5.5, the static member lookup feature is improved. However, we still have not covered the following case:

@dynamicMemberLookup
protocol ImageLookup {
    static var images: Images { get }
    static subscript(dynamicMember member: KeyPath<Images, String>) -> UIImage? { get }
}

extension ImageLookup {
    static subscript(dynamicMember member: KeyPath<Images, String>) -> UIImage? {
        return UIImage(named: images[keyPath: member])
   }
}

extension UIImage: ImageLookup {
    static var images: Images {
        Images()
    }
}

struct Images {
    let sample = "sample"
}

let image: UIImage = .sample
let image2 = UIImage.sample

The complier complains on line let image: UIImage = .sample but NOT on line let image2 = UIImage.sample as shown in picture below:

I assume that it is because that sample property is from @dynamicMemberLookup. Could we improve the syntax to support this scenario?

1 Like

@xwu Any thoughts on this? Thanks.

Well, your dynamic member subscript says that you return a UIImage?, not a UIImage, so it's going to have a hard time matching...

And if you change it to let image: UIImage?, then you're saying you want to look up the .sample name on the Optional<UIImage> type, which does not support dynamic member subscripts.

I'm not sure what the right answer is here.

1 Like

Thanks @davedelong , the thing is that even if I change the type to UIImage, the complier is still complaining. Please refer to the code below:

@dynamicMemberLookup
protocol ImageLookup {
    static var images: Images { get }
    static subscript(dynamicMember member: KeyPath<Images, String>) -> UIImage { get }
}

extension ImageLookup {
    static subscript(dynamicMember member: KeyPath<Images, String>) -> UIImage {
        return UIImage(named: images[keyPath: member])!
   }
}

extension UIImage: ImageLookup {
    static var images: Images {
        Images()
    }
}

struct Images {
    let sample = "sample"
}

let image: UIImage = .sample
let image2 = UIImage.sample

The error message is below:

This, IMO, is a better example. I agree this appears unintuitive :+1:

1 Like

Not yet. There are others who have thought about this more than I.

2 Likes