Uploaded image for project: 'Swift'
  1. Swift
  2. SR-5828

Cyclical metadata graphs should either not be formed or be a compile failure

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Medium
    • Resolution: Duplicate
    • Component/s: Compiler
    • Labels:
      None

      Description

      consider the following code:

      enum _TrieNode<Element : Equatable> {
          case leaf(Array<Element>)
          case node(Element, Array<_TrieNode<Element>>)
          
          mutating func insert<I>(_ iterator: inout I) -> _TrieNode<Element>? where I : IteratorProtocol, I.Element == Element {
              if let element = iterator.next() {
                  switch self {
                  case .leaf(let elements):
                      let filtered = elements.filter { $0 != element }
                      var items = [Element]()
                      while let item = iterator.next() {
                          items.append(item)
                      }
                      self = .node(element, [.leaf(items)])
                      return .leaf(filtered)
                  case .node(let nodeElement, let children_):
                      var children = children_
                      for idx in 0..<children.count {
                          if children[idx].matches(element) {
                              if let additional = children[idx].insert(&iterator) {
                                  children.append(additional)
                              }
                              break
                          }
                      }
                      self = .node(nodeElement, children)
                      return nil
                  }
              }
              return nil
          }
          
          func matches(_ element: Element) -> Bool {
              switch self {
              case .leaf(let elements):
                  return elements.contains(element)
              case .node(let nodeElement, _):
                  return nodeElement == element
              }
          }
      }
      
      struct Trie<Element : Equatable> {
          var nodes = [_TrieNode<Element>]()
          
          mutating func insert<C>(_ elements: C) where C : Sequence, C.Iterator.Element == Element {
              var iter = elements.makeIterator()
              if let element = iter.next() {
                  for idx in 0..<nodes.count {
                      if nodes[idx].matches(element) {
                          if let additional = nodes[idx].insert(&iter) {
                              nodes.append(additional)
                          }
                          return
                      }
                  }
              }
          }
      }
      
      var trie = Trie<String.Element>()
      trie.insert("hello")
      trie.insert("hello world")
      
      

      Since this code compiles I would expect it would execute with no failures. Unfortunately it seems to hit a runtime failure?

      GenericCache(0x1005d54f8): cyclic metadata dependency detected, aborting
      

      Either these types of metadata dependencies should not be created or it should be compile failure. Additionally this debugging information is not very actionable to help avoid this type of cyclical graph.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned
              Reporter:
              phausler Philippe Hausler
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: