summary refs log tree commit diff stats
path: root/tests/concepts/texplain.nim
blob: 417d1e50224bfb4e04033d4b5321c8ec9889a27e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
discard """
  cmd: "nim c --verbosity:0 --colors:off $file"
  nimout: '''
texplain.nim(99, 10) Hint: Non-matching candidates for e(y)
proc e(i: int): int

texplain.nim(102, 7) Hint: Non-matching candidates for e(10)
proc e(o: ExplainedConcept): int
texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo'
texplain.nim(65, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(65, 5) ExplainedConcept: concept predicate failed
texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar'
texplain.nim(66, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(65, 5) ExplainedConcept: concept predicate failed

texplain.nim(105, 10) Hint: Non-matching candidates for e(10)
proc e(o: ExplainedConcept): int
texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo'
texplain.nim(65, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(65, 5) ExplainedConcept: concept predicate failed
texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar'
texplain.nim(66, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(65, 5) ExplainedConcept: concept predicate failed

texplain.nim(109, 20) Error: type mismatch: got (NonMatchingType)
but expected one of: 
proc e(o: ExplainedConcept): int
texplain.nim(65, 5) ExplainedConcept: concept predicate failed
proc e(i: int): int

texplain.nim(110, 20) Error: type mismatch: got (NonMatchingType)
but expected one of: 
proc r(o: RegularConcept): int
texplain.nim(69, 5) RegularConcept: concept predicate failed
proc r[T](a: SomeNumber; b: T; c: auto)
proc r(i: string): int

texplain.nim(111, 20) Hint: Non-matching candidates for r(y)
proc r[T](a: SomeNumber; b: T; c: auto)
proc r(i: string): int

texplain.nim(119, 2) Error: type mismatch: got (MatchingType)
but expected one of: 
proc f(o: NestedConcept)
texplain.nim(69, 6) RegularConcept: undeclared field: 'foo'
texplain.nim(69, 6) RegularConcept: undeclared field: '.'
texplain.nim(69, 6) RegularConcept: expression '.' cannot be called
texplain.nim(69, 5) RegularConcept: concept predicate failed
texplain.nim(70, 6) RegularConcept: undeclared field: 'bar'
texplain.nim(70, 6) RegularConcept: undeclared field: '.'
texplain.nim(70, 6) RegularConcept: expression '.' cannot be called
texplain.nim(69, 5) RegularConcept: concept predicate failed
texplain.nim(73, 5) NestedConcept: concept predicate failed
'''
  line: 119
  errormsg: "type mismatch: got (MatchingType)"
"""

type
  ExplainedConcept {.explain.} = concept o
    o.foo is int
    o.bar is string

  RegularConcept = concept o
    o.foo is int
    o.bar is string

  NestedConcept = concept o
    o.foo is RegularConcept

  NonMatchingType = object
    foo: int
    bar: int

  MatchingType = object
    foo: int
    bar: string

proc e(o: ExplainedConcept): int = 1
proc e(i: int): int = i

proc r[T](a: SomeNumber, b: T, c: auto) = discard
proc r(o: RegularConcept): int = 1
proc r(i: string): int = 1

proc f(o: NestedConcept) = discard

var n = NonMatchingType(foo: 10, bar: 20)
var y = MatchingType(foo: 10, bar: "bar")

# no diagnostic here:
discard e(y)

# explain that e(int) doesn't match
discard e(y) {.explain.}

# explain that e(ExplainedConcept) doesn't match
echo(e(10) {.explain.}, 20)

# explain that e(ExplainedConcept) doesn't again
discard e(10)

static:
  # provide diagnostics why the compile block failed
  assert(compiles(e(n)) {.explain.} == false)
  assert(compiles(r(n)) {.explain.} == false)
  assert(compiles(r(y)) {.explain.} == true)

  # these should not produce any output
  assert(compiles(r(10)) == false)
  assert(compiles(e(10)) == true)

# finally, provide multiple nested explanations for failed matching
# of regular concepts, even when the explain pragma is not used
f(y)