Using switch with enum fails with internal error

IDE: Version 10.0.0.2397 (develop) built on bajor, 20190419-153353. Commit 6f2fbf4.
Version: Version 10.0.0.2397 (develop) built on bajor, 20190419-153353. Commit 6f2fbf4.
Target (If relevant): iOS
Description:
When I try to use a simple enum as defined here:

private struct FormSection {
    var title: String?
    var rows: [FormItem]
    
    public init(title: String?, rows: [FormItem]) {
        self.title = title
        self.rows = rows
    }
}

public enum FormItem {
    case text(title: String?, details: String?)
    case editable(text: String?, placeholder: String?)
}

and I then use FormSection and FormItem struct and enum by defining a list of items like this:

    public override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(TextFieldCell.self, forCellReuseIdentifier: "TextFieldCell")
        self.sections = [
            FormSection(title: "Title", rows: [
                FormItem.editable("Text", "Placeholder"),
                FormItem.editable("Text", "Placeholder")
            ])
        ]
        self.tableView.reloadData()
    }

If I next try to use switch to determine which enum types is to return the appropriate table view cell like this:

    private func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell {
        let row: FormItem = sections[indexPath.section].rows[indexPath.row]
        switch row {
            case .editable(let title, let placeholder):
                let cell: TextFieldCell = tableView.dequeueReusableCell(identifier: "TextFieldCell", for: indexPath)
                cell.textField.placeholder = "Placeholder"
                cell.textField.text = "Title"
                return cell! //UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")                
        }
    }

I am getting an internal error in the compiler:

                  Reference: /Applications/Fire.app/Contents/Resources/Toffee SDKs/iOS 12.2 Simulator/CoreFoundation.fx (implicit)
                  -> Phase Resolving Bodies started.
                     Reference: /Applications/Fire.app/Contents/Resources/Toffee SDKs/iOS 12.2 Simulator/CloudKit.fx
                     Reference: /Applications/Fire.app/Contents/Resources/Toffee SDKs/iOS 12.2 Simulator/QuartzCore.fx
E:                   Internal error: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
  at System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) [0x00011] in <dbb16e0bacdc4a0f87478e401bc29b6c>:0 
  at System.ThrowHelper.ThrowArgumentOutOfRangeException () [0x00000] in <dbb16e0bacdc4a0f87478e401bc29b6c>:0 
  at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x0000c] in <dbb16e0bacdc4a0f87478e401bc29b6c>:0 
  at RemObjects.Oxygene.Code.SwitchStatementTransform.ResolveSilverSwitchStatement (RemObjects.Oxygene.Code.Compiler.ScopeInfo aScope, RemObjects.Oxygene.Code.SwitchStatement element) [0x0077a] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.SwitchStatementTransform.ResolveStatement (RemObjects.Oxygene.Code.Compiler.ScopeInfo aScope, RemObjects.Oxygene.Code.SwitchStatement element) [0x0025c] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.Compiler.NewResolveExpressionAndStatement.VisitStatement (RemObjects.Oxygene.Code.Compiler.ScopeInfo aScope, RemObjects.Oxygene.Code.Statement element) [0x00268] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.BeginStatementTransform.ResolveStatement (RemObjects.Oxygene.Code.Compiler.ScopeInfo aScope, RemObjects.Oxygene.Code.BeginStatement beginStatement) [0x00204] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.Compiler.NewResolveExpressionAndStatement.VisitStatement (RemObjects.Oxygene.Code.Compiler.ScopeInfo aScope, RemObjects.Oxygene.Code.Statement element) [0x00421] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.ResolveMethodBody (RemObjects.Oxygene.Code.Compiler.ScopeInfo aScope, RemObjects.Oxygene.Code.IMethodImplementation aMethod) [0x01934] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler+<>c__DisplayClass49.<ResolveMembers>b__5 (RemObjects.Oxygene.Code.IParsedType aType) [0x00105] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.ForAllInternalTypes (System.Action`1[T] aAt) [0x0007b] in <49a69325a9084390aa0ad4a888bd7f9c>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.ResolveMembers () [0x001f5] in <49a69325a9084390aa0ad4a888bd7f9c>:0  [/Users/x/Development/Projects/x/x/version-3/config-app/XConfigiOS/View Controllers/AssignViewController.swift (79)]

Expected Behavior:
The switch allows to destructure the enum and get the values title and placeholder of the .editable-enum type.

Actual Behavior:
An internal error is raised (see above) while I would expect the code to compile

Steps:

  1. Attempt to compile this

Complet failing source

import UIKit

private struct FormSection {
    var title: String?
    var rows: [FormItem]
    
    public init(title: String?, rows: [FormItem]) {
        self.title = title
        self.rows = rows
    }
}

public enum FormItem {
    case text(title: String?, details: String?)
    case editable(text: String?, placeholder: String?)
}

@IBObject public class AssignSensorViewController: UITableViewController {
    
    private var sections: [FormSection] = []

    public override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(TextFieldCell.self, forCellReuseIdentifier: "TextFieldCell")
        self.sections = [
            FormSection(title: "Title", rows: [
                FormItem.editable("Text", "Placeholder"),
                FormItem.editable("Text", "Placeholder")
            ])
        ]
        self.tableView.reloadData()
    }

    public override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

extension AssignSensorViewController {
    
    //
    // Table view data source
    //

    private func numberOfSectionsInTableView(_ tableView: UITableView!) -> Int {
        // Return the number of sections.
        return self.sections.count
    }

    private func tableView(_ tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return self.sections[section].rows.count
    }

    private func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell {
        let row: FormItem = sections[indexPath.section].rows[indexPath.row]
        switch row {
            case .editable(let title, let placeholder):
                let cell: TextFieldCell = tableView.dequeueReusableCell(identifier: "TextFieldCell", for: indexPath)
                cell.textField.placeholder = title
                cell.textField.text = placeholder
                return cell!         
        }
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: NSInteger) -> NSString? {
        return sections[section].title
    }

    //
    // Table view delegate
    //

    private func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        //
    }
}

Thanks, logged as bugs://82447

bugs://82447 got closed with status fixed.

1 Like

I can confirm it’s working in the 10.0.0.2398 build! Thanks :smiley:

1 Like