-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Certain classes have a objectAtIndexedSubscript:/objectForKeyedSubscript: selectors, which makes Swift add equivalent subscript* methods, see the docs on subscript accessor name translation.
A similar effect can be achieved with Rust's Index trait, however implementing this trait in these cases is a bit more difficult, because the trait requires that we return a &-reference (with a lifetime tied to &self), which isn't always possible.
For NSArray, the main difficulty is that we don't (statically) know whether the array comes from NSMutableArray, and since that can be mutated behind &self, any reference we give out in Index wouldn't be guaranteed to be alive for as long as the array (e.g. if someone removed the element from the array). POC:
let array = NSMutableArray::from_slices(&[&*NSNumber::new_u8(42)]);
let number: &NSNumber = &array[0];
array.removeObjectAtIndex(0); // Releases and deallocates the `NSNumber`.
// `number` is now danglingBut for other cases like MTLRenderPipelineColorAttachmentDescriptorArray, we might be able to? It seems like it has a fixed number of attachments (8 on my machine, though may vary between hardware?), meaning that no matter what you do to the descriptor array, apart from releasing it, the MTLRenderPipelineColorAttachmentDescriptor returned from its objectAtIndexedSubscript: would always be valid?
Another thing to be aware of is that the reference returned by objectAtIndexedSubscript: isn't guaranteed to be bound to the receiver, it may instead be an autoreleased object. Such cases are probably rare, but it means that we definitely can't automatically implement Index.
(IndexMut is even more difficult, as it doesn't map to the underlying operations setObject:atIndexedSubscript:/setObject:forKeyedSubscript:, but that's a different discussion).