Suppose we are calling a function that is generic over T, where T: AnyObject.  
This comes up when e.g. calling an initializer for an ObjC generic class.

Today we allow conversions from [String] to [NSString], String to NSString, and 
[String] to [T], but we do not allow a conversion from String to T.  The 
concrete conversions are allowed because there is a bridging conversion from 
String to NSString.  The generic "scalar" conversion is not allowed because the 
type-checker's enumeration of possible supertypes does not consider bridged 
types.  The generic array conversion is allowed because the special-case code 
that governs collection up-casting in the type-checker immediately turns the 
generic argument into its bridged type and so bypasses that flaw.

One goal of the id-as-Any import change is to remove the implicit bridging 
conversions and the widespread use of AnyObject constraints.  As part of this, 
[U] will convert to [V] only when U is convertible to V.  This implies that 
both of the generic conversions above would be rejected.

With no other changes, this means that when calling an ObjC generic 
initializer, e.g.:
  @interface Generic<T>
  - (id) initWithArray: (NSArray<T> *) array;
  @end
it will not be possible to pass a [String] (inferring T == NSObject).  This is 
technically a regression.

Well, maybe we don't care.

If we do care, one option is to try to bridge generic parameters and their 
constraints.  Effectively, this would mean removing the implicitly AnyObject 
constraint on all ObjC generic parameters.  If we did this, it would be 
possible to pass a [String] to the initializer of Generic, and inferring T == 
String; SILGen would then recognize the need to bridge to NSArray<NSString> 
when passing the argument.  But this is a fair amount of work that I think is 
new to the plan.

Thoughts?

John.
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to