[cfe-dev] objc++ enhancements for new c++ features

John McCall via cfe-dev cfe-dev at lists.llvm.org
Thu Mar 29 09:14:06 PDT 2018



> On Mar 29, 2018, at 12:07 PM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:
> 
> 
>> On 28 Mar 2018, at 21:07, John McCall <rjmccall at apple.com> wrote:
>> 
>> And what would the rules be for type-checking such an application?  If we're talking about C++ interactions here, we can't very well pretend that the parameters and return value are all going to be `id`.  (I wouldn't want to add new dependencies on that behavior anyway, even in pure Objective-C.)
>> 
>> Also, you can't actually make a selector a template argument today.  You can use SEL as the type of a template parameter, but it's basically useless because @selector is not a constant expression.
>> 
>> Now, there's an idea we've been kicking around for a long time to support typed selectors; I guess they would look something like
>>  SEL<NSString*()>
>> for the type of
>>  - (NSString*) foo;
>> 
>> Note that that argument is just a function type, and that it's not the actual type of an IMP because both `self` and `_cmd` are implicit.  That's an interesting thing to discuss.  You could make an argument that `self` should be explicit, so that you could say "this is a selector that only works on object arguments of a certain type".  That would be more type-safe, but I would worry about it making it more awkward to use this for the sorts of dynamic features that people use untyped selectors for today.  Maybe it'd be fine as long as you could convert `SEL<void(NSCell*)>` to `SEL<void(id)>`.
>> 
>> Anyway, since it's an ordinary function type, it can carry attributes like NS_RETURNS_RETAINED and NS_CONSUMED because we already taught the type system about those for ARC.  (It can't express the behavior of -init methods unless `self` is an explicit parameter, though.)
>> 
>> I think the application syntax is pretty obvious: you would just call the selector as if it were a C function, with the first argument being the receiver, and the compiler would automatically call the right objc_msgSend variant for the type.
>> 
>> You'd need some way of constructing one of these, probably by referring to an existing method.  Maybe that could be @selector(-Foo.bar) or something.
>> 
>> Anyway, if you had that, you could then add special template support for them.
> 
> I really like this idea - we currently don’t have a good mechanism for doing a type-safe version of -performSelector: or an ARC-safe way of calling objc_msgSend.  With the GNUstep runtime, we also have the ability to cheaply do run-time type checking at the invocation.
> 
> I don’t think you’d need special syntax for declaring the selectors, because the type here is purely a compile-time concept, so the compiler just needs to check, for example, on assignment from @selector(foo) to a variable of type SEL<NSString*()> that there exists a method of that type.  For template (or auto parameter) type deduction based on a selector, you could simple error if the selector is ambiguous and isn’t explicitly cast to a type (clang already has warnings similar to this).

Ah, that's true, we could do special-case checking / inference when converting a @selector expression to a concrete SEL<T> type.

Do you have an opinions about whether the receiver type should be explicit?  If we made it explicit, I think we'd still give it the usual ObjC lax conversions, i.e. SEL<T(R1, V...)> can be converted to SEL<T(R2, V...)> if R2 is a subtype of R1 (receivers are contravariant) *or* if either R1 or R2 is id.

John.


More information about the cfe-dev mailing list