//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
// Swift Standard Prolog Library.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Standardized uninhabited type
//===----------------------------------------------------------------------===//
/// A type that has no values and can't be constructed.
///
/// Use `Never` as the return type of a function
/// that doesn't return normally --- for example,
/// because it runs forever or terminates the program.
///
///     // An infinite loop never returns.
///     func forever() -> Never {
///         while true {
///             print("I will print forever.")
///         }
///     }
///
///     // Calling fatalError(_:file:line:) unconditionally stops the program.
///     func crashAndBurn() -> Never {
///         fatalError("Something very, very bad happened")
///     }
///
/// A function that returns `Never` is called a _nonreturning_ function.
/// Closures, methods, computed properties, and subscripts
/// can also be nonreturning.
///
/// There's no way to create an instance of `Never`;
/// this characteristic makes it an _uninhabited_ type.
/// You can use an uninhabited type like `Never`
/// to represent states in your program
/// that are impossible to reach during execution.
/// Swift's type system uses this information ---
/// for example, to reason about control statements
/// in cases that are known to be unreachable.
///
///     let favoriteNumber: Result<Int, Never> = .success(42)
///     switch favoriteNumber {
///     case .success(let value):
///         print("My favorite number is", value)
///     }
///
/// In the code above,
/// `favoriteNumber` has a failure type of `Never`,
/// indicating that it always succeeds.
/// The switch statement is therefore exhaustive,
/// even though it doesn't contain a `.failure` case,
/// because that case could never be reached.
@frozen
public enum Never {}

extension Never: BitwiseCopyable {}

extension Never: Sendable {}

extension Never: Error {}

extension Never: Equatable, Comparable, Hashable {}

@available(SwiftStdlib 5.5, *)
@_unavailableInEmbedded
extension Never: Identifiable {
  @available(SwiftStdlib 5.5, *)
  public var id: Never {
    switch self {}
  }
}

@available(SwiftStdlib 5.9, *)
@_unavailableInEmbedded
extension Never: Encodable {
  @available(SwiftStdlib 5.9, *)
  public func encode(to encoder: any Encoder) throws {}
}

@available(SwiftStdlib 5.9, *)
@_unavailableInEmbedded
extension Never: Decodable {
  @available(SwiftStdlib 5.9, *)
  public init(from decoder: any Decoder) throws {
    let context = DecodingError.Context(
      codingPath: decoder.codingPath,
      debugDescription: "Unable to decode an instance of Never.")
    throw DecodingError.typeMismatch(Never.self, context)
  }
}

//===----------------------------------------------------------------------===//
// Standardized aliases
//===----------------------------------------------------------------------===//
/// The return type of functions that don't explicitly specify a return type,
/// that is, an empty tuple `()`.
///
/// When declaring a function or method, you don't need to specify a return
/// type if no value will be returned. However, the type of a function,
/// method, or closure always includes a return type, which is `Void` if
/// otherwise unspecified.
///
/// Use `Void` or an empty tuple as the return type when declaring a closure,
/// function, or method that doesn't return a value.
///
///     // No return type declared:
///     func logMessage(_ s: String) {
///         print("Message: \(s)")
///     }
///
///     let logger: (String) -> Void = logMessage
///     logger("This is a void function")
///     // Prints "Message: This is a void function"
public typealias Void = ()

//===----------------------------------------------------------------------===//
// Aliases for floating point types
//===----------------------------------------------------------------------===//
// FIXME: it should be the other way round, Float = Float32, Double = Float64,
// but the type checker loses sugar currently, and ends up displaying 'FloatXX'
// in diagnostics.
/// A 32-bit floating point type.
public typealias Float32 = Float
/// A 64-bit floating point type.
public typealias Float64 = Double

//===----------------------------------------------------------------------===//
// Default types for unconstrained literals
//===----------------------------------------------------------------------===//
/// The default type for an otherwise-unconstrained integer literal.
public typealias IntegerLiteralType = Int
/// The default type for an otherwise-unconstrained floating-point literal.
public typealias FloatLiteralType = Double

/// The default type for an otherwise-unconstrained Boolean literal.
///
/// When you create a constant or variable using one of the Boolean literals
/// `true` or `false`, the resulting type is determined by the
/// `BooleanLiteralType` alias. For example:
///
///     let isBool = true
///     print("isBool is a '\(type(of: isBool))'")
///     // Prints "isBool is a 'Bool'"
///
/// The type aliased by `BooleanLiteralType` must conform to the
/// `ExpressibleByBooleanLiteral` protocol.
public typealias BooleanLiteralType = Bool

/// The default type for an otherwise-unconstrained unicode scalar literal.
@_unavailableInEmbedded
public typealias UnicodeScalarType = String
/// The default type for an otherwise-unconstrained Unicode extended
/// grapheme cluster literal.
@_unavailableInEmbedded
public typealias ExtendedGraphemeClusterType = String
/// The default type for an otherwise-unconstrained string literal.
@_unavailableInEmbedded
public typealias StringLiteralType = String

//===----------------------------------------------------------------------===//
// Default types for unconstrained number literals
//===----------------------------------------------------------------------===//
#if !(os(Windows) || os(Android) || ($Embedded && !os(Linux) && !os(anyAppleOS))) && (arch(i386) || arch(x86_64))
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE80
#else
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64
#endif

//===----------------------------------------------------------------------===//
// Standard protocols
//===----------------------------------------------------------------------===//

#if _runtime(_ObjC)
/// The protocol to which all classes implicitly conform.
///
/// You use `AnyObject` when you need the flexibility of an untyped object or
/// when you use bridged Objective-C methods and properties that return an
/// untyped result. `AnyObject` can be used as the concrete type for an
/// instance of any class, class type, or class-only protocol. For example:
///
///     class FloatRef {
///         let value: Float
///         init(_ value: Float) {
///             self.value = value
///         }
///     }
///
///     let x = FloatRef(2.3)
///     let y: AnyObject = x
///     let z: AnyObject = FloatRef.self
///
/// `AnyObject` can also be used as the concrete type for an instance of a type
/// that bridges to an Objective-C class. Many value types in Swift bridge to
/// Objective-C counterparts, like `String` and `Int`.
///
///     let s: AnyObject = "This is a bridged string." as NSString
///     print(s is NSString)
///     // Prints "true"
///
///     let v: AnyObject = 100 as NSNumber
///     print(type(of: v))
///     // Prints "__NSCFNumber"
///
/// The flexible behavior of the `AnyObject` protocol is similar to
/// Objective-C's `id` type. For this reason, imported Objective-C types
/// frequently use `AnyObject` as the type for properties, method parameters,
/// and return values.
///
/// Casting AnyObject Instances to a Known Type
/// ===========================================
///
/// Objects with a concrete type of `AnyObject` maintain a specific dynamic
/// type and can be cast to that type using one of the type-cast operators
/// (`as`, `as?`, or `as!`).
///
/// This example uses the conditional downcast operator (`as?`) to
/// conditionally cast the `s` constant declared above to an instance of
/// Swift's `String` type.
///
///     if let message = s as? String {
///         print("Successful cast to String: \(message)")
///     }
///     // Prints "Successful cast to String: This is a bridged string."
///
/// If you have prior knowledge that an `AnyObject` instance has a particular
/// type, you can use the unconditional downcast operator (`as!`). Performing
/// an invalid cast triggers a runtime error.
///
///     let message = s as! String
///     print("Successful cast to String: \(message)")
///     // Prints "Successful cast to String: This is a bridged string."
///
///     let badCase = v as! String
///     // Runtime error
///
/// Casting is always safe in the context of a `switch` statement.
///
///     let mixedArray: [AnyObject] = [s, v]
///     for object in mixedArray {
///         switch object {
///         case let x as String:
///             print("'\(x)' is a String")
///         default:
///             print("'\(object)' is not a String")
///         }
///     }
///     // Prints "'This is a bridged string.' is a String"
///     // Prints "'100' is not a String"
///
/// Accessing Objective-C Methods and Properties
/// ============================================
///
/// When you use `AnyObject` as a concrete type, you have at your disposal
/// every `@objc` method and property---that is, methods and properties
/// imported from Objective-C or marked with the `@objc` attribute. Because
/// Swift can't guarantee at compile time that these methods and properties
/// are actually available on an `AnyObject` instance's underlying type, these
/// `@objc` symbols are available as implicitly unwrapped optional methods and
/// properties, respectively.
///
/// This example defines an `IntegerRef` type with an `@objc` method named
/// `getIntegerValue()`.
///
///     class IntegerRef {
///         let value: Int
///         init(_ value: Int) {
///             self.value = value
///         }
///
///         @objc func getIntegerValue() -> Int {
///             return value
///         }
///     }
///
///     func getObject() -> AnyObject {
///         return IntegerRef(100)
///     }
///
///     let obj: AnyObject = getObject()
///
/// In the example, `obj` has a static type of `AnyObject` and a dynamic type
/// of `IntegerRef`. You can use optional chaining to call the `@objc` method
/// `getIntegerValue()` on `obj` safely. If you're sure of the dynamic type of
/// `obj`, you can call `getIntegerValue()` directly.
///
///     let possibleValue = obj.getIntegerValue?()
///     print(possibleValue)
///     // Prints "Optional(100)"
///
///     let certainValue = obj.getIntegerValue()
///     print(certainValue)
///     // Prints "100"
///
/// If the dynamic type of `obj` doesn't implement a `getIntegerValue()`
/// method, the system returns a runtime error when you initialize
/// `certainValue`.
///
/// Alternatively, if you need to test whether `obj.getIntegerValue()` exists,
/// use optional binding before calling the method.
///
///     if let f = obj.getIntegerValue {
///         print("The value of 'obj' is \(f())")
///     } else {
///         print("'obj' does not have a 'getIntegerValue()' method")
///     }
///     // Prints "The value of 'obj' is 100"
public typealias AnyObject = Builtin.AnyObject
#else
/// The protocol to which all classes implicitly conform.
public typealias AnyObject = Builtin.AnyObject
#endif

/// The protocol to which all class types implicitly conform.
///
/// You can use the `AnyClass` protocol as the concrete type for an instance of
/// any class. When you do, all known `@objc` class methods and properties are
/// available as implicitly unwrapped optional methods and properties,
/// respectively. For example:
///
///     class IntegerRef {
///         @objc class func getDefaultValue() -> Int {
///             return 42
///         }
///     }
///
///     func getDefaultValue(_ c: AnyClass) -> Int? {
///         return c.getDefaultValue?()
///     }
///
/// The `getDefaultValue(_:)` function uses optional chaining to safely call
/// the implicitly unwrapped class method on `c`. Calling the function with
/// different class types shows how the `getDefaultValue()` class method is
/// only conditionally available.
///
///     print(getDefaultValue(IntegerRef.self))
///     // Prints "Optional(42)"
///
///     print(getDefaultValue(NSString.self))
///     // Prints "nil"
public typealias AnyClass = AnyObject.Type

//===----------------------------------------------------------------------===//
// Standard pattern matching forms
//===----------------------------------------------------------------------===//

/// Returns a Boolean value indicating whether two arguments match by value
/// equality.
///
/// The pattern-matching operator (`~=`) is used internally in `case`
/// statements for pattern matching. When you match against an `Equatable`
/// value in a `case` statement, this operator is called behind the scenes.
///
///     let weekday = 3
///     let lunch: String
///     switch weekday {
///     case 3:
///         lunch = "Taco Tuesday!"
///     default:
///         lunch = "Pizza again."
///     }
///     // lunch == "Taco Tuesday!"
///
/// In this example, the `case 3` expression uses this pattern-matching
/// operator to test whether `weekday` is equal to the value `3`.
///
/// - Note: In most cases, you should use the equal-to operator (`==`) to test
///   whether two instances are equal. The pattern-matching operator is
///   primarily intended to enable `case` statement pattern matching.
///
/// - Parameters:
///   - lhs: A value to compare.
///   - rhs: Another value to compare.
@_transparent
public func ~= <T: Equatable>(a: T, b: T) -> Bool {
  return a == b
}

//===----------------------------------------------------------------------===//
// Standard precedence groups
//===----------------------------------------------------------------------===//

precedencegroup AssignmentPrecedence {
  assignment: true
  associativity: right
}
precedencegroup FunctionArrowPrecedence {
  associativity: right
  higherThan: AssignmentPrecedence
}
precedencegroup TernaryPrecedence {
  associativity: right
  higherThan: FunctionArrowPrecedence
}
precedencegroup DefaultPrecedence {
  higherThan: TernaryPrecedence
}
precedencegroup LogicalDisjunctionPrecedence {
  associativity: left
  higherThan: TernaryPrecedence
}
precedencegroup LogicalConjunctionPrecedence {
  associativity: left
  higherThan: LogicalDisjunctionPrecedence
}
precedencegroup ComparisonPrecedence {
  higherThan: LogicalConjunctionPrecedence
}
precedencegroup NilCoalescingPrecedence {
  associativity: right
  higherThan: ComparisonPrecedence
}
precedencegroup CastingPrecedence {
  higherThan: NilCoalescingPrecedence
}
precedencegroup RangeFormationPrecedence {
  higherThan: CastingPrecedence
}
precedencegroup AdditionPrecedence {
  associativity: left
  higherThan: RangeFormationPrecedence
}
precedencegroup MultiplicationPrecedence {
  associativity: left
  higherThan: AdditionPrecedence
}
precedencegroup BitwiseShiftPrecedence {
  higherThan: MultiplicationPrecedence
}


//===----------------------------------------------------------------------===//
// Standard operators
//===----------------------------------------------------------------------===//

// Standard postfix operators.
postfix operator ++
postfix operator --
postfix operator ...

// Optional<T> unwrapping operator is built into the compiler as a part of
// postfix expression grammar.
//
// postfix operator !

// Standard prefix operators.
prefix operator ++
prefix operator --
prefix operator !
prefix operator ~
prefix operator +
prefix operator -
prefix operator ...
prefix operator ..<

// Standard infix operators.

// "Exponentiative"

infix operator  <<: BitwiseShiftPrecedence
infix operator &<<: BitwiseShiftPrecedence
infix operator  >>: BitwiseShiftPrecedence
infix operator &>>: BitwiseShiftPrecedence

// "Multiplicative"

infix operator   *: MultiplicationPrecedence
infix operator  &*: MultiplicationPrecedence
infix operator   /: MultiplicationPrecedence
infix operator   %: MultiplicationPrecedence
infix operator   &: MultiplicationPrecedence

// "Additive"

infix operator   +: AdditionPrecedence
infix operator  &+: AdditionPrecedence
infix operator   -: AdditionPrecedence
infix operator  &-: AdditionPrecedence
infix operator   |: AdditionPrecedence
infix operator   ^: AdditionPrecedence

// FIXME: is this the right precedence level for "..." ?
infix operator  ...: RangeFormationPrecedence
infix operator  ..<: RangeFormationPrecedence

// The cast operators 'as' and 'is' are hardcoded as if they had the
// following attributes:
// infix operator as: CastingPrecedence

// "Coalescing"

infix operator ??: NilCoalescingPrecedence

// "Comparative"

infix operator  <: ComparisonPrecedence
infix operator  <=: ComparisonPrecedence
infix operator  >: ComparisonPrecedence
infix operator  >=: ComparisonPrecedence
infix operator  ==: ComparisonPrecedence
infix operator  !=: ComparisonPrecedence
infix operator ===: ComparisonPrecedence
infix operator !==: ComparisonPrecedence
// FIXME: ~= will be built into the compiler.
infix operator  ~=: ComparisonPrecedence

// "Conjunctive"

infix operator &&: LogicalConjunctionPrecedence

// "Disjunctive"

infix operator ||: LogicalDisjunctionPrecedence

// User-defined ternary operators are not supported. The ? : operator is
// hardcoded as if it had the following attributes:
// operator ternary ? : : TernaryPrecedence

// User-defined assignment operators are not supported. The = operator is
// hardcoded as if it had the following attributes:
// infix operator =: AssignmentPrecedence

// Compound

infix operator   *=: AssignmentPrecedence
infix operator  &*=: AssignmentPrecedence
infix operator   /=: AssignmentPrecedence
infix operator   %=: AssignmentPrecedence
infix operator   +=: AssignmentPrecedence
infix operator  &+=: AssignmentPrecedence
infix operator   -=: AssignmentPrecedence
infix operator  &-=: AssignmentPrecedence
infix operator  <<=: AssignmentPrecedence
infix operator &<<=: AssignmentPrecedence
infix operator  >>=: AssignmentPrecedence
infix operator &>>=: AssignmentPrecedence
infix operator   &=: AssignmentPrecedence
infix operator   ^=: AssignmentPrecedence
infix operator   |=: AssignmentPrecedence

// Workaround for <rdar://problem/14011860> SubTLF: Default
// implementations in protocols.  Library authors should ensure
// that this operator never needs to be seen by end-users.  See
// test/Prototypes/GenericDispatch.swift for a fully documented
// example of how this operator is used, and how its use can be hidden
// from users.
infix operator ~>
