Skip to content

Improving mapping of generic types #316

@madsmtm

Description

@madsmtm

Currently, we're mapping generic types roughly as:

extern_class!(
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSArray<T: Message = Object, O: Ownership = Shared> {
        p: PhantomData<Id<T, O>>,
    }

    unsafe impl<T: Message, O: Ownership> ClassType for NSArray<T, O> {
        type Super = NSObject;
    }
);

impl<T: Message, O: Ownership> NSArray<T, O> {
    fn get(&self, index: usize) -> Option<&T>;
}

impl<T: Message> NSArray<T, Owned> {
    fn get_mut(&mut self, index: usize) -> Option<&mut T>;
}

But this can be a bit limiting, since there's no easy way to carry any lifetime information in the type. Also, it is IMO a bit confusing to see Id<NSArray<NSObject, Shared>, Shared>, and this only gets worse on types with multiple generics (like NSDictionary).

So perhaps we could instead introduce a helper trait and do it like this:

trait Foo: Sealed {
    type Item: Message;
    type Ownership: Ownership;
}

impl<T: Message> Foo for &T {
    type Item = T;
    type Ownership = Shared;
}
impl<T: Message> Foo for &mut T {
    type Item = T;
    type Ownership = Owned;
}
impl<T: Message, O: Ownership> Foo for Id<T, Owned> {
    type Item = T;
    type Ownership = O;
}

// Usage

extern_class!(
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSArray<T: Foo> {
        p: PhantomData<T>,
    }

    unsafe impl<T: Foo> ClassType for NSArray<T> {
        type Super = NSObject;
    }
);

impl<T: Foo> NSArray<T> {
    fn get(&self, index: usize) -> Option<&T>;
}

impl<T: Foo<Owneship = Owned>> NSArray<T> {
    fn get_mut(&mut self, index: usize) -> Option<&mut T>;
}

Where usage would then be Id<NSArray<&NSObject>, Shared> or Id<NSArray<Id<NSObject, Shared>>, Shared>.

This will also help with #304, since -[NSEnumerator nextObject] by itself could now be safe by default (though -[NSArray objectEnumerator] would still be unsafe).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-frameworkAffects the framework crates and the translator for themenhancementNew feature or request

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions