[swift-evolution] Subscripts assignable to closure vars

Joanna Carter joanna at carterconsulting.org.uk
Sat Sep 16 03:58:35 CDT 2017


Hi Jordan

> Le 15 sept. 2017 à 23:55, Jordan Rose <jordan_rose at apple.com> a écrit :
> 
> The crash is already fixed in master, thanks to Alex Hoppen's work on making actual subscripts distinct from the name "subscript".
> 
> I think John's right that this should not be allowed. After all, a subscript may have both a getter and a setter, and it's not immediately obvious from your syntax which one you mean.

As of Xcode 9.0 (9A235), there are still numerous segmentation faults instead of proper errors. This is one of them.

Not wanting to confuse things but, I am also getting a segmentation fault if I pass an incorrect type as a generic parameter to a generic type e.g.

    let personProvider = PersonDataProvider()

   let listModel = ListModel<PersonDataProvider>(data: AnyDataProvider(personProvider))

… provokes a segmentation fault instead of a coherent error.

The code should read :

    let personProvider = PersonDataProvider()

   let listModel = ListModel<Person>(data: AnyDataProvider(personProvider))

See the code below for the entities involved.

> We could invent some kind of answer for this (including simply just checking the contextual type), but it would be nice™ if any such solution also had a good answer for properties. Or we could just make key paths and closures work a little better together, which has also been discussed on the list.

Slava Pestov showed me a good solution for the subscript assignment, which works fine. Here is the fully updated code for my example :

protocol DataProvider
{
  associatedtype ItemType
  
  subscript(index: Int) -> ItemType { get }
}

struct AnyDataProvider<itemType> : DataProvider
{
  private let _subscript: (Int) -> itemType

  subscript(index: Int) -> itemType
  {
    return _subscript(index)
  }
  
  init<providerType : DataProvider>(_ base: providerType) where providerType.ItemType == itemType
  {
    _subscript = { base[$0] }
  }
}

class ListModel<itemType>
{
  private var data: AnyDataProvider<itemType>
  
  init(data: AnyDataProvider<itemType>)
  {
    self.data = data
  }
  
  subscript(index: Int) -> itemType
  {
    return data[index]
  }
}

Regards

Joanna

--
Joanna Carter
Carter Consulting



More information about the swift-evolution mailing list