Fast recursive enumeration introduces an infinite loop in the constructor

I created a recursive enumin Swift that compiles without errors or warnings, but which enters an infinite loop when I try to create it:

enum Tree<T> {
    case Leaf(T)
    case Branch(T, [Tree<T>])
}

Tree.Leaf(0) // enters infinite loop
Tree.Branch(0, []) // enters infinite loop

An infinite loop occurs when an instance is created, and not when printing or otherwise using an instance. Even if nothing is done with the result, Tree.Leaf(0)it still works forever. Just to be clear: an infinite loop occurs at runtime, not at compile time, but happens immediately after instantiation.

Oddly enough, the following very similar data structure works just fine:

enum WorkingTree<T> {
    case Leaf(T)
    case Branch([WorkingTree<T>]) // notice the lack of a `T` in this case
}

WorkingTree.Leaf(0) // works fine
WorkingTree.Branch([.Leaf(1), .Leaf(2)]) // works fine

Perhaps even stranger, the following data structure also works just fine:

enum ConcreteTree {
    case Leaf(Int)
    case Branch(Int, [ConcreteTree])
}

ConcreteTree.Leaf(0) // works fine
ConcreteTree.Branch(0, []) // works fine

, , ?

EDIT:

Swift REPL , , , "", . Swift REPL:

1> enum Tree<T> {
2.     case Leaf(T)
3.     case Branch(T, [Tree<T>])
4. } // press enter, declare type
5> Tree.Leaf(0) // separate command to the REPL

. , :

1> enum Tree<T> {
2.     case Leaf(T)
3.     case Branch(T, [Tree<T>])
4. } // press down arrow, continue multiline command
5. Tree.Leaf(0) // part of the same command

.

?

2:

. , :

enum Tree<T> {
    case Leaf(T)
    case Branch(T, [Tree<T>])
}

let test = Tree.Leaf(0)
print("Milestone 1") // prints

switch test {
    case .Leaf(_): print("Milestone 2") // prints
    default: print("This should never be called")
}

func no_op<T>(x: T) {}

no_op(test) // infinite loop entered here
print("Milestone 3") // DOES NOT print

no_op(Tree.Leaf(0))
print("Milestone 4") // DOES NOT print

, no_op?

+4
1

indirect:

enum Tree<T> {
    indirect case Leaf(T)
    indirect case Branch(T, [Tree<T>])
}

, ; .

+4

Source: https://habr.com/ru/post/1619436/


All Articles