Skip to content

[SR-14848] A Collection without any subscript[Range<Index>] can compile #57195

@glessard

Description

@glessard
Previous ID SR-14848
Radar rdar://problem/79891982
Original Reporter @glessard
Type Bug
Status Closed
Resolution Done

Attachment: Download

Environment

swift-driver version: 1.26 Apple Swift version 5.5 (swiftlang-1300.0.20.104 clang-1300.0.21.1)
Target: arm64-apple-macosx11.0

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

md5: e982e40416288e077649666cd5387791

Issue Description:

Collection has the following requirement:

subscript(bounds: Range<Index>) -> SubSequence { get }

Its only default implementation is in an extension Collection where SubSequence == Slice<Self>. Therefore it should be required to supply such a subscript in order to compile a Collection whose SubSequence is not Slice. Somehow, it isn't! However, trying to access such an un-defined subscript results in a crash at runtime, even though it had compiled successfully.

struct MyRange {
  public let start: Int
  public let count: Int

  public init(_ range: Range<Int>) {
    start = range.lowerBound
    count = range.count
  }
}

extension MyRange: Sequence {
  public struct Iterator: IteratorProtocol {
    public mutating func next() -> Int? { nil }
  }

  public func makeIterator() -> Iterator { Iterator() }
}

extension MyRange: Collection {
  public typealias Index = Int
  public typealias SubSequence = Self

  public var startIndex: Index { start }
  public var endIndex: Index { start + count }

  public func index(after i: Index) -> Index {
    i.advanced(by: 1)
  }

  public subscript(position: Index) -> Int {
    get {
      precondition(position < endIndex)
      return position
    }
  }

//  public subscript(bounds: Range<Index>) -> SubSequence {
//    get {
//      precondition(bounds.lowerBound >= startIndex)
//      precondition(bounds.upperBound <= endIndex)
//      return SubSequence(bounds)
//    }
//  }
}

var rb: MyRange
rb = MyRange(0..<48)

let subseq: MyRange.SubSequence = rb[16..<24]
assert(subseq.start == 16)
assert(subseq.count == 8)

// The following doesn't compile, as expected.
//let slice: Slice<MyRange> = rb[16..<24]
//_ = slice

Instructions:
$ swiftc myrange.swift
$ ./myrange
Segmentation fault: 11

The .swift file is included, for convenience.

Metadata

Metadata

Assignees

Labels

bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfstandard libraryArea: Standard library umbrella

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions