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-7062] Type inference with AnyObject dispatch & Optional differs in Release+WMO builds #49610

Closed
sharplet opened this issue Feb 22, 2018 · 17 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@sharplet
Copy link

Previous ID SR-7062
Radar rdar://problem/37828077
Original Reporter @sharplet
Type Bug
Status Closed
Resolution Done

Attachment: Download

Environment

Xcode Version 9.2 (9C40b)
macOS High Sierra Version 10.13.3

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

md5: 51d8f3ea57f32c1b31b8730930e2b9db

Issue Description:

This compiler error only occurs when I build in Release configuration or Archive. It doesn't occur if I switch to single-file optimisation (-O). Unfortunately I haven't been able to reproduce it in a smaller project, but I'll attach what I can about the failure.

The code:

// ReplaceChildViewControllerSegue.swift
import UIKit

final class ReplaceChildViewControllerSegue: UIStoryboardSegue {
    override func perform() {
        let contentView = (source as AnyObject).contentView ?? source.view!

        if let currentChild = source.childViewControllers.first {
            currentChild.willMove(toParentViewController: nil)
            source.addChildViewController(destination)
            contentView.embedSubview(destination.view)

            UIView.transition(
                with: contentView,
                duration: 0.2,
                options: [.transitionCrossDissolve],
                animations: nil,
                completion: { [destination, source] _ in
                    currentChild.view.removeFromSuperview()
                    currentChild.removeFromParentViewController()
                    destination.didMove(toParentViewController: source)
                }
            )
        } else {
            source.addChildViewController(destination)
            contentView.embedSubview(destination.view)
            destination.didMove(toParentViewController: source)
        }
    }
}

The error:

/Users/adsharp/src/peerfit/pf-ios/Peerfit/Components/ReplaceChildViewControllerSegue.swift:10:13: error: value of optional type 'UIView?' not unwrapped; did you mean to use '!' or '?'?
            contentView.embedSubview(destination.view)
            ^
                       ?
/Users/adsharp/src/peerfit/pf-ios/Peerfit/Components/ReplaceChildViewControllerSegue.swift:13:23: error: value of optional type 'UIView?' not unwrapped; did you mean to use '!' or '?'?
                with: contentView,
                      ^
                                 !
/Users/adsharp/src/peerfit/pf-ios/Peerfit/Components/ReplaceChildViewControllerSegue.swift:25:13: error: value of optional type 'UIView?' not unwrapped; did you mean to use '!' or '?'?
            contentView.embedSubview(destination.view)
            ^
                       ?

In Debug builds, the type of contentView is inferred as UIView. In Release builds, it is apparently being inferred as UIView?, causing a compiler error.

I've attached a file that includes the invocation of the "Compile Swift source files" step in Xcode.

@belkadan
Copy link
Contributor

Does anything else in your project declare a property named contentView?

@belkadan
Copy link
Contributor

Note that AnyObject dispatch for properties wraps the result in an ImplicitlyUnwrappedOptional, and contentView is probably Optional itself. So you could probably make this go away by putting ! after the get of contentView (or just not using AnyObject dispatch). But WMO vs. non-WMO definitely shouldn't behave differently here.

@sharplet
Copy link
Author

Here's the only declaration of this property in project so far:

@IBOutlet private(set) var contentView: UIView!

@belkadan
Copy link
Contributor

Hm, that could definitely be relevant. It might be assuming you meant that contentView in WMO mode but the UIKit one in non-WMO mode.

@belkadan
Copy link
Contributor

@swift-ci create

@rudkx
Copy link
Member

rudkx commented Feb 28, 2018

What is the type of source.view?

Have you tried building your project with the Xcode 9.3 betas or a Swift nightly build? I am wondering if you will see the same behavior with those.

@sharplet
Copy link
Author

@rudkx The source.view is UIViewController.view, which is also imported as UIView!.

@sharplet
Copy link
Author

@rudkx I hadn't been able to test in the beta yet because one of my dependencies was broken. I worked around that to test this, and I haven't reproduced the error in Xcode 9.3 beta 3 (9Q117m).

@rudkx
Copy link
Member

rudkx commented Feb 28, 2018

I suspect what was happening here is that we were for some reason selecting the overload of `??` that returns a `T?` rather than `T`. It could be related to the other property called contentView.

Are you able to work-around this by using an `if let`?

@sharplet
Copy link
Author

The workaround I used in practice was to explicitly annotate the result as `UIView`:

let contentView: UIView = (source as AnyObject).contentView ?? source.view

@belkadan
Copy link
Contributor

belkadan commented Mar 1, 2018

Um. If you're going to work around this at all, why not not use AnyObject dispatch?

@sharplet
Copy link
Author

sharplet commented Mar 1, 2018

Which workaround I choose to implement is beside the point — this is a valid use of AnyObject dispatch.

@belkadan
Copy link
Contributor

belkadan commented Mar 1, 2018

Oh, sure, that's true. AnyObject dispatch itself is just…not great to begin with.

@belkadan
Copy link
Contributor

belkadan commented Mar 1, 2018

It can cause your project to rebuild the file more often than it otherwise would during an incremental build, for example.

@rudkx
Copy link
Member

rudkx commented Mar 1, 2018

Since this appears to be fixed on master, I am going to resolve the issue. It would be nice to know exactly what changed here, but we won't have the cycles to chase that down.

@AnnaZaks
Copy link
Mannequin

AnnaZaks mannequin commented Jul 26, 2018

@sharplet, Could you verify if the problem is fixed and if so move the JIRA to "Closed"?
Thanks!
Anna

@sharplet
Copy link
Author

Happy to close this!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

3 participants