The compiler is unable to type-check this expression swift 4?

After updating xCode i am getting this error into my code :

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

The code :

//check popup in window frame

let spaceFromLeftSide = cutOutViewX.constant + cutOutViewWidth.constant/2 - (options.textWidth + padding*2)/2

if spaceFromLeftSide < 0{

    if options.side == .bottom {
        messageRightSpaceFromBottomDot.constant -= spaceFromLeftSide - padding
    }
    else if options.side == .top{
        messageRightSpaceFromTopDot.constant += spaceFromLeftSide - padding
    }
}

let spaceFromRightSide = cutOutViewX.constant + cutOutViewWidth.constant/2 + (options.textWidth + padding*2)/2

if spaceFromRightSide > targetView.frame.size.width{

    if options.side == .bottom {
        messageRightSpaceFromBottomDot.constant -= spaceFromRightSide - ( targetView.frame.size.width )
    }
    else if options.side == .top{
        messageRightSpaceFromTopDot.constant += spaceFromRightSide - ( targetView.frame.size.width )
    }
}

Error in line :

let spaceFromRightSide = cutOutViewX.constant + cutOutViewWidth.constant/2 + (options.textWidth + padding*2)/2

how to fix this ?


Solution 1:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

This error appears when swift compiler finds the expression calculation lengthy. For more details check here

To resolve this, you just need to break your expression into smaller parts. Just like:

let cutOutxOrigin = 3 * cutOutViewX.constant / 2
let actualPadding = (options.textWidth + padding * 2) / 2

let spaceFromRightSide = cutOutxOrigin + actualPadding

Solution 2:

I have faced similar issue with different scenario

I was trying to create array of string

let selectedData = [
        (data?.nose?.stuffyNose) ?? "",
        (data?.nose?.sinusProblems) ?? "",
        (data?.nose?.hayFever) ?? "",
        (data?.nose?.sneezingAttacks) ?? "",
        (data?.nose?.excessiveMucusFormation) ?? ""
] 

I have already addd Brackets () but still was not working.


To fix this I have added type [String]

let selectedData:[String] = [
        (data?.nose?.stuffyNose) ?? "",
        (data?.nose?.sinusProblems) ?? "",
        (data?.nose?.hayFever) ?? "",
        (data?.nose?.sneezingAttacks) ?? "",
        (data?.nose?.excessiveMucusFormation) ?? ""
] 

Hope it is helpful to someone facing same issue

Solution 3:

Just try to break up the expression to several simpler subexpression. E.g.:

let halfOfViewWidth = cutOutViewWidth.constant / 2
let textWidthAndPadding = options.textWidth + (padding * 2)
let spaceFromRightSide = cutOutViewX.constant + halfOfViewWidth + (textWidthAndPadding / 2)

EDIT

I noticed that I was able to fix this type of error also by providing explicit type conversions (e.g., instead of relying on the compiler to infer that by multiplying a CGFloat with an Int it should result in CGFloat, I have explicitly converted the Int to CGFloat). Seems that the problem lies indeed in types and automatic type inference and checking. While breaking up the the complex expression to smaller parts can be very useful to readability, you can solve the problem by being explicit about the types (the error message basically says that the compiler is unable do the type check - thus you can help it by providing explicit types where-ever possible).

Solution 4:

So I have this kind of expression:

return (50 + textHeight) + (dateTextHeight + 16) + (5 + 8) + (16 + 20)

I knew I had to breakdown or make this expression shorter to get rid of the error. Like perhaps:

return (50 + textHeight) + (dateTextHeight + 16) + 49

Although true enough it helped the compiler to do its job, the main cause of the error is the optional Int textHeight. I think no matter how long your expression, it should be compile-able.

Solution 5:

I had this error when I accidentally mixed in an optional in an expression. After force unwrapping the error went away.

let a : String = "A" 
let b : String = "B" 
let c = letterDictionary["C"]

let imageName : String = a + b + c //error 
let imageName : String = a + b + c! //no error