[swift-evolution] [Proposal] Type Narrowing

Jay Abbott jay at abbott.me.uk
Thu Nov 10 15:42:56 CST 2016

Consider this code:

struct Pet {
    let name: String
    weak var owner: Person?

    init(name: String, owner: Person?) {
        self.name = name
        self.owner = owner
        owner?.pet = self

    mutating func transferOwnership(to newOwner: Person) {
        let previousOwner = owner
        owner = newOwner
        newOwner.pet = self
        if(previousOwner != nil) {
            previousOwner!.pet = nil

    func feed() {
class Person {
    let name: String
    var pet: Pet?

    init(name: String) {
        self.name = name

    func givePetAway(to someone: Person) {
        if pet != nil {
            pet!.transferOwnership(to: someone)
let bert = Person(name: "Bert")let ernie = Person(name: "Ernie")var
elmo = Pet(name: "Elmo", owner: nil)

elmo.transferOwnership(to: bert)print("Bert's pet is \(bert.pet) -
Ernie's pet is \(ernie.pet)")

bert.givePetAway(to: ernie)print("Bert's pet is \(bert.pet) - Ernie's
pet is \(ernie.pet)")

This works as expected, but if you uncomment pet!.feed() in givePetAway(to:)
it will crash, because the mutating function modifies the two-way
relationship between pet and owner.

In the code I use if pet != nil to demonstrate, in your proposal for unwrap,
if I used it to unwrap pet (a value-type, but accessed through self so it
can be modified after unwrapping because it’s not nil at the moment) the
compiler would assume I could use it and pet.feed() would crash, just as
pet!.feed() does now. In your proposal for type narrowing, it would be the
same problem. This is like your foo.value example from the proposal.

I don’t think you can get around the fact that the compiler can’t guarantee
a type-narrowed or even unwrapped mutable value, which is why if let works
as it does with an immutable snapshot.

However, type narrowing for immutable values would still be good.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161110/b768721a/attachment.html>

More information about the swift-evolution mailing list