diff --git a/stdlib/public/core/Random.swift b/stdlib/public/core/Random.swift index 360fe05001e20..1b11382e96497 100644 --- a/stdlib/public/core/Random.swift +++ b/stdlib/public/core/Random.swift @@ -64,6 +64,15 @@ public protocol RandomNumberGenerator { } extension RandomNumberGenerator { + + // An unavailable default implementation of next() prevents types that do + // not implement the RandomNumberGenerator interface from conforming to the + // protocol; without this, the default next() method returning a generic + // unsigned integer will be used, recursing infinitely and probably blowing + // the stack. + @available(*, unavailable) + public mutating func next() -> UInt64 { fatalError() } + /// Returns a value from a uniform, independent distribution of binary data. /// /// Use this method when you need random binary data to generate another diff --git a/test/stdlib/Random.swift b/test/stdlib/Random.swift new file mode 100644 index 0000000000000..8a8c2258d4320 --- /dev/null +++ b/test/stdlib/Random.swift @@ -0,0 +1,21 @@ +//===--- Random.swift -----------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2021 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// RUN: %target-typecheck-verify-swift + +struct Jawn { } + +// Me, sobbing: "Look, you can't just point at an empty struct and call it a +// RandomNumberGenerator." +// Swift 5.4, pointing at this Jawn: "RNG." +extension Jawn: RandomNumberGenerator { } +// expected-error@-1 {{type 'Jawn' does not conform to protocol 'RandomNumberGenerator'}} +// expected-error@-2 {{unavailable instance method 'next()' was used to satisfy a requirement of protocol 'RandomNumberGenerator'}}