123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- template accept(x) =
- static: assert(compiles(x))
- template reject(x) =
- static: assert(not compiles(x))
- type
- Kind = enum k1 = 0, k2 = 33, k3 = 84, k4 = 278, k5 = 1000 # Holed enum work! #No they don't..
- KindObj = object
- case kind: Kind
- of k1, k2..k3: i32: int32
- of k4: f32: float32
- else: str: string
- IntObj = object
- case kind: uint8
- of low(uint8) .. 127: bad: string
- of 128'u8: neutral: string
- of 129 .. high(uint8): good: string
- OtherKind = enum ok1, ok2, ok3, ok4, ok5
- NestedKindObj = object
- case kind: Kind
- of k3, k5: discard
- of k2: str: string
- of k1, k4:
- case otherKind: OtherKind
- of ok1, ok2..ok3: i32: int32
- of ok4: f32: float32
- else: nestedStr: string
- let kind = k4 # actual value should have no impact on the analysis.
- accept: # Mimics the structure of the type. The optimial case.
- case kind
- of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
- of k4: discard KindObj(kind: kind, f32: 2.0)
- else: discard KindObj(kind: kind, str: "3")
- accept: # Specifying the else explicitly is fine too.
- case kind
- of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
- of k4: discard KindObj(kind: kind, f32: 2.0)
- of k5: discard KindObj(kind: kind, str: "3")
- accept:
- case kind
- of k1..k3, k5: discard
- else: discard KindObj(kind: kind, f32: 2.0)
- accept:
- case kind
- of k4, k5: discard
- else: discard KindObj(kind: kind, i32: 1)
- accept: # elif branches are ignored
- case kind
- of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
- of k4: discard KindObj(kind: kind, f32: 2.0)
- elif kind in {k1..k5}: discard
- else: discard KindObj(kind: kind, str: "3")
- reject: # k4 conflicts with i32
- case kind
- of k1, k2, k3, k4: discard KindObj(kind: kind, i32: 1)
- else: discard KindObj(kind: kind, str: "3")
- reject: # k4 is not caught, conflicts with str in the else branch
- case kind
- of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
- else: discard KindObj(kind: kind, str: "3")
- reject: # elif branches are ignored
- case kind
- of k1, k2, k3: discard KindObj(kind: kind, i32: 1)
- elif kind == k4: discard
- else: discard KindObj(kind: kind, str: "3")
- let intKind = 29'u8
- accept:
- case intKind
- of low(uint8) .. 127: discard IntObj(kind: intKind, bad: "bad")
- of 128'u8: discard IntObj(kind: intKind, neutral: "neutral")
- of 129 .. high(uint8): discard IntObj(kind: intKind, good: "good")
- reject: # 0 leaks to else
- case intKind
- of low(uint8) .. 127: discard IntObj(kind: intKind, bad: "bad")
- of 129 .. high(uint8): discard IntObj(kind: intKind, good: "good")
- accept:
- case intKind
- of low(uint8) .. 127: discard IntObj(kind: intKind, bad: "bad")
- of 128'u8: discard IntObj(kind: intKind, neutral: "neutral")
- of 139'u8, 140 .. high(uint8), 129'u8 .. 138'u8: discard IntObj(kind: intKind, good: "good")
- accept:
- case kind
- of {k1, k2}, [k3]: discard KindObj(kind: kind, i32: 1)
- of k4: discard KindObj(kind: kind, f32: 2.0)
- else: discard KindObj(kind: kind, str: "3")
- reject:
- case kind
- of {k1, k2, k3}, [k4]: discard KindObj(kind: kind, i32: 1)
- else: discard KindObj(kind: kind, str: "3")
- accept:
- case kind
- of k3, k5: discard NestedKindObj(kind: kind)
- of k2: discard NestedKindObj(kind: kind, str: "not nested")
- of k1, k4:
- let otherKind = ok5
- case otherKind
- of ok1..ok3: discard NestedKindObj(kind: kind, otherKind: otherKind, i32: 3)
- of ok4: discard NestedKindObj(kind: kind, otherKind: otherKind, f32: 5.0)
- else: discard NestedKindObj(kind: kind, otherKind: otherKind,
- nestedStr: "nested")
- reject:
- case kind
- of k3, k5: discard NestedKindObj(kind: kind)
- of k2: discard NestedKindObj(kind: kind, str: "not nested")
- of k1, k4:
- let otherKind = ok5
- case otherKind
- of ok1..ok3: discard NestedKindObj(kind: kind, otherKind: otherKind, i32: 3)
- else: discard NestedKindObj(kind: kind, otherKind: otherKind,
- nestedStr: "nested")
- var varkind = k4
- reject: # not immutable.
- case varkind
- of k1, k2, k3: discard KindObj(varkind: kind, i32: 1)
- of k4: discard KindObj(varkind: kind, f32: 2.0)
- else: discard KindObj(varkind: kind, str: "3")
- accept:
- proc kindProc(kind: Kind): KindObj =
- case kind:
- of k1: result = KindObj(kind: kind, i32: 1)
- else: discard
- reject:
- proc varKindProc(kind: var Kind): KindObj =
- case kind:
- of k1: result = KindObj(kind: kind, i32: 1)
- else: discard
- type
- Kind3 = enum
- A, B, C, E
- OkRange = range[B..C]
- NotOkRange = range[B..E]
- CaseObject = object
- case kind: Kind3
- of B, C:
- field: int
- else: discard
- accept:
- let rtDiscriminator: OkRange = B
- discard CaseObject(kind: rtDiscriminator, field: 1)
- accept:
- let rtDiscriminator = B
- discard CaseObject(kind: OkRange(rtDiscriminator), field: 1)
- accept:
- const rtDiscriminator: NotOkRange = B
- discard CaseObject(kind: rtDiscriminator, field: 1)
- accept:
- discard CaseObject(kind: NotOkRange(B), field: 1)
- reject:
- let rtDiscriminator: NotOkRange = B
- discard CaseObject(kind: rtDiscriminator, field: 1)
- reject:
- let rtDiscriminator = B
- discard CaseObject(kind: NotOkRange(rtDiscriminator), field: 1)
- reject:
- type Obj = object
- case x: int
- of 0 .. 1000:
- field: int
- else:
- discard
- let x: range[0..15] = 1
- let o = Obj(x: x, field: 1)
|