Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-10952] xCode shows warnings about casting optional(?) value to Any while it unwrapped(!) #418

Open
swift-ci opened this issue Jun 17, 2019 · 6 comments
Labels
bug Compiler Standard Library

Comments

@swift-ci
Copy link
Contributor

@swift-ci swift-ci commented Jun 17, 2019

Previous ID SR-10952
Radar None
Original Reporter idomo (JIRA User)
Type Bug
Environment

macOS ‏10.14.4 ‏(18E226‏)

xCode 11.0 beta (11M336w)

Additional Detail from JIRA
Votes 0
Component/s Compiler, Standard Library, SwiftSyntax
Labels Bug
Assignee None
Priority Medium

md5: 924d60396351aa05301bb722f224bcf9

Issue Description:

When trying to pass value with type `Type!`, Xcode shows this warning:

Coercion of implicitly unwrappable value of type 'Type?' to 'Any' does not unwrap optional

As you can see, Xcode ignoring that the type is already unwrapped and treats it as an optional value.

For example:

@IBDesignable
class MyLabel: UILabel {
    @IBInspectable var paddingTopBottom: CGFloat = 0
    @IBInspectable var paddingRightLeft: CGFloat = 0

    override func drawText(in rect: CGRect) {
        let padding = UIEdgeInsets(top: paddingTopBottom, left: paddingRightLeft, bottom: paddingTopBottom, right: paddingRightLeft)


        guard let labelText = text else { return super.drawText(in: rect.inset(by: padding)) }


        var newRect = rect
        if labelText.matches("[א-ת]") {
            let attributedText = NSAttributedString(string: labelText, attributes: [.font: font])


            newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height


            if numberOfLines != 0 {
                newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
            }
        }
        super.drawText(in: newRect.inset(by: padding))
    }
}

You may ignore the logic itself and focus on this line:

NSAttributedString(string: labelText, attributes: [.font: font])

I'm getting the warning on the `font` variable, although you know it's defined as unwrapped value in the `UILabel` class:

open class UILabel : UIView, NSCoding, UIContentSizeCategoryAdjusting {
    ...
    open var font: UIFont!
    ...
}
@belkadan
Copy link

@belkadan belkadan commented Jun 17, 2019

The warning is correct: an implicitly-unwrapped optional type is unwrapped if it needs to be, and converting to Any is not a case where it needs to be. You can read more about this at https://swift.org/blog/iuo.

Any ideas on how to make the error message more clear?

@swift-ci
Copy link
Contributor Author

@swift-ci swift-ci commented Jun 17, 2019

Comment by Ido (JIRA)

I’ve just noticed it happens also when I’m trying to print the value of Type!, there is a reason for me to forced unwrapped this variable, so why the compiler want me to treat it as optional if I told it it shouldn’t ever be with nil value?

Sorry, but I still don’t know why the warning is correct when it’s just ignoring my force unwrapping.

@belkadan
Copy link

@belkadan belkadan commented Jun 17, 2019

You aren't force-unwrapping it. ! on a type is different from ! in an expression; the first means "unwrap automatically if necessary" and the second means "unwrap now no matter what". They're related concepts but not the same.

@swift-ci
Copy link
Contributor Author

@swift-ci swift-ci commented Jun 17, 2019

Comment by Ido (JIRA)

So what is the case that it would unwrap it automatically if I always have to give it a default value/force unwrap it in the expression itself?

@belkadan
Copy link

@belkadan belkadan commented Jun 17, 2019

You do not always have to force-unwrap it in the expression itself. As described in the blog post, it will be unwrapped automatically if the context is expecting a non-optional version of the value. But Any really can hold anything, including Optional values, and so it won't be unwrapped if that's the expected type.

@swift-ci
Copy link
Contributor Author

@swift-ci swift-ci commented Jun 17, 2019

Comment by Ido (JIRA)

I think I got it now, thanks for the explanation!

And about your question for more understandable message - You may change it to something like:

Value of type 'Optional(Type!)' could not be converted to 'Any', you may specify a default value or force-unwrap it

This would give more context to the developer about having an "auto unwrapped variable" that is an Optional in the time of the conversion and will give some examples for what should be done.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Compiler Standard Library
Projects
None yet
Development

No branches or pull requests

3 participants