Files
swift-mirror/test/Interpreter/currying_protocols.swift
Robert Widmann 1beb75583a Push FunctionTypeRepr Input Invariants Up
Validation of the input side of FunctionTypeRepr was previously being done in Sema because of expression folding.  If we instead push the invariant that the input TypeRepr should always be a TupleTypeRepr into the AST a number of nice cleanups fall out:

- The SIL Parser no longer accepts Swift 2-style type declarations
-  Parse is more cleanly able to reject invalid FunctionTypeReprs
- Clients of the AST can be assured the input type is always a TupleType so we can flush Swift 2 hacks
2018-06-13 18:41:20 -07:00

118 lines
2.4 KiB
Swift

// RUN: %target-run-simple-swift | %FileCheck %s
// REQUIRES: executable_test
enum Medal {
case Bronze, Silver, Gold
}
struct Steroids {}
protocol Gymnast {
func backflip(_ angle: Double) -> Self
func compete() -> (Medal) -> Self
func scandal() -> (Steroids) -> ()
static func currentYear() -> Int
}
final class Archimedes : Gymnast {
func backflip(_ angle: Double) -> Self {
print(angle >= 360 ? "Not in a thousand years" : "Ok")
return self
}
func compete() -> (Medal) -> Archimedes {
return { (m: Medal) in
print(m == .Gold ? "We won gold!" : "Try again next time")
return Archimedes()
}
}
func scandal() -> (Steroids) -> () {
return { s in print("Archimedes don't do that") }
}
static func currentYear() -> Int {
return -287
}
}
////
// Protocol-constrained archetype
////
func genericOlympicGames<T: Gymnast>(_ g1: T) -> T {
let f1: (T) -> (Double) -> T = T.backflip
let f2: (Double) -> T = f1(g1)
let g2: T = f2(180)
let f3: (Double) -> T = g2.backflip
let g3: T = f3(360)
let f4: (T) -> () -> (Medal) -> T = T.compete
let f5: () -> (Medal) -> T = f4(g3)
let f6: (Medal) -> T = f5()
let g4: T = f6(Medal.Silver)
let f7: () -> (Medal) -> T = g4.compete
let f8: (Medal) -> T = f7()
let g5: T = f8(Medal.Gold)
let f9: (T) -> () -> (Steroids) -> () = T.scandal
let f10: () -> (Steroids) -> () = f9(g5)
let f11: (Steroids) -> () = f10()
f11(Steroids())
let f12: () -> (Steroids) -> () = g5.scandal
let f13: (Steroids) -> () = f12()
f13(Steroids())
let f14: () -> Int = T.currentYear
print(f14())
let metatype: T.Type = T.self
let f15: () -> Int = metatype.currentYear
print(f15())
return g5
}
genericOlympicGames(Archimedes())
// CHECK: Ok
// CHECK: Not in a thousand years
// CHECK: Try again next time
// CHECK: We won gold!
// CHECK: Archimedes don't do that
// CHECK: Archimedes don't do that
// CHECK: -287
// CHECK: -287
////
// Existential
////
func olympicGames(_ g1: Gymnast) -> Gymnast {
// FIXME -- <rdar://problem/21391055>
#if false
let f1: (Double) -> Gymnast = g1.backflip
let g2: Gymnast = f1(180)
let f2: (Medal) -> Gymnast = g2.compete
let g4: Gymnast = f2()(Medal.Gold)
#endif
let f3: () -> (Steroids) -> () = g1.scandal
let f4: (Steroids) -> () = f3()
f4(Steroids())
let f5: () -> Int = type(of: g1).currentYear
print(f5())
return g1
}
olympicGames(Archimedes())
// CHECK: Archimedes don't do that
// CHECK: -287