M. Porooshani M. Porooshani - 11 months ago 73
iOS Question

Swift 3 Generic infix operator error

In the process of updating a project from Xcode 7 to 8, I'm facing a problem.

There is a generic

operator which handles constraints on

Here is the operator's definition:

precedencegroup constPrecedence {
associativity: left
higherThan: AssignmentPrecedence

infix operator >>>- : constPrecedence

func >>>- <T: UIView> (left: (T, T), block: (inout ConstraintInfo) -> ()) -> NSLayoutConstraint {
var info = ConstraintInfo()
info.secondAttribute = info.secondAttribute == .notAnAttribute ? info.attribute : info.secondAttribute

let constraint = NSLayoutConstraint(item: left.1,
attribute: info.attribute,
relatedBy: info.relation,
toItem: left.0,
attribute: info.secondAttribute,
multiplier: 1,
constant: info.constant)
constraint.identifier = info.identifier
return constraint

now, upon using the operator, I'm getting an error I don't understand:

for attribute: NSLayoutAttribute in [.left, .right, .top, .bottom] {
(view, self) >>>- {
$0.attribute = attribute

infix operator error

I have tested with non-generic function too, it will still complain about the block's type.

Any idea?

P.S.: I'm not the original author of the code, I'm trying to updated the code for a PR and to change the syntax will impact too much code.

Answer Source

I was able to solve this problem by adding a return call at the end of the code block passed to the operator. It seems like Swift 3.0 compiler cannot infer code block to be a closure without return. As mentioned in the question's comments, the original operator should work fine with a new Swift 3.0 project, but converting the project from older Swift versions seems to break the operator somehow.

Any way This is the correct usage of the operator now and it works fine:

 for attribute: NSLayoutAttribute in [.left, .right, .top, .bottom] {
      (view, self) >>>- {
        $0.attribute = attribute

P.S.: I have been doing this fix before but I was getting a weird Segmentation Fault error 11 after a few of errors' been fixed and I wasn't aware of the reason. Turns out, Xcode could not handle some of the closure types and segmentation fault was happening. Adding return call to ALL places where the operator was being used solved the problem.

I would be happy to discuss the reason and a better solution with any interested developer.