summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorSaem Ghani <saemghani+github@gmail.com>2021-02-15 00:51:05 -0800
committerGitHub <noreply@github.com>2021-02-15 09:51:05 +0100
commit260a5dacb7a3854d6d6aa18d9996b88bfcd13cc6 (patch)
tree175b30daf8594641e5f47e0576914e73fd386594
parentb68ecc82cb404dbbd291320139955794e88c24ff (diff)
downloadNim-260a5dacb7a3854d6d6aa18d9996b88bfcd13cc6.tar.gz
fixed dot operator recursive loop & macro suggest (#16922)
* basic stability improvements; refs nimsuggest
* fixed dot operator recursive loop & macro suggest
* hacky fix for run away dot operator sem check

Committing this mostly to make the issue more clear. Perhaps get better
feedback.

* semExprWithType seems like a better place to check
* fixed error messages const case expressions
* Clean-up test
* stopped the dot operator madness

No longer get infinite recursion when seming broken code with a dot
operator macro like in jsffi.

Co-authored-by: Araq <rumpf_a@web.de>
-rw-r--r--compiler/semexprs.nim18
-rw-r--r--compiler/semtypinst.nim2
-rw-r--r--compiler/vm.nim4
-rw-r--r--compiler/vmgen.nim5
-rw-r--r--nimsuggest/tests/twithin_macro.nim6
-rw-r--r--nimsuggest/tests/twithin_macro_prefix.nim7
-rw-r--r--tests/errmsgs/t10734.nim15
-rw-r--r--tests/js/t11166.nim18
8 files changed, 51 insertions, 24 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index bac2daa2e..c1365a83d 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -66,10 +66,17 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
 proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode =
   rejectEmptyNode(n)
   result = semExpr(c, n, flags+{efWantValue})
-  if result.kind == nkEmpty:
+
+  let
+    isEmpty = result.kind == nkEmpty
+    isTypeError = result.typ != nil and result.typ.kind == tyError
+
+  if isEmpty or isTypeError:
     # bug #12741, redundant error messages are the lesser evil here:
     localError(c.config, n.info, errExprXHasNoType %
                 renderTree(result, {renderNoComments}))
+  
+  if isEmpty:
     # do not produce another redundant error message:
     result = errorNode(c, n)
 
@@ -79,6 +86,9 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     localError(c.config, n.info, errExprXHasNoType %
                 renderTree(result, {renderNoComments}))
     result.typ = errorType(c)
+  elif result.typ.kind == tyError:
+    # associates the type error to the current owner
+    result.typ = errorType(c)
   else:
     if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
 
@@ -887,6 +897,9 @@ proc setGenericParams(c: PContext, n: PNode) =
     n[i].typ = semTypeNode(c, n[i], nil)
 
 proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
+  if efNoSemCheck notin flags and n.typ != nil and n.typ.kind == tyError:
+    return errorNode(c, n)
+
   result = n
   let callee = result[0].sym
   case callee.kind
@@ -1368,6 +1381,9 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
       return tryReadingTypeField(c, n, i, ty.base)
   elif isTypeExpr(n.sons[0]):
     return tryReadingTypeField(c, n, i, ty)
+  elif ty.kind == tyError:
+    # a type error doesn't have any builtin fields
+    return nil
 
   if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
     ty = ty.lastSon
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 07fe6b27d..f9ac6ccca 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -229,6 +229,8 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
     n = reResolveCallsWithTypedescParams(cl, n)
     result = if cl.allowMetaTypes: n
              else: cl.c.semExpr(cl.c, n)
+    if not cl.allowMetaTypes:
+      assert result.kind notin nkCallKinds
   else:
     if n.len > 0:
       newSons(result, n.len)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 0c9c0ec33..246d9d4d2 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -2184,7 +2184,7 @@ const evalPass* = makePass(myOpen, myProcess, myClose)
 proc evalConstExprAux(module: PSym; idgen: IdGenerator;
                       g: ModuleGraph; prc: PSym, n: PNode,
                       mode: TEvalMode): PNode =
-  if g.config.errorCounter > 0: return n
+  #if g.config.errorCounter > 0: return n
   let n = transformExpr(g, idgen, module, n)
   setupGlobalCtx(module, g, idgen)
   var c = PCtx g.vm
@@ -2262,7 +2262,7 @@ proc errorNode(idgen: IdGenerator; owner: PSym, n: PNode): PNode =
 
 proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstCounter: ref int;
                     n, nOrig: PNode, sym: PSym): PNode =
-  if g.config.errorCounter > 0: return errorNode(idgen, module, n)
+  #if g.config.errorCounter > 0: return errorNode(idgen, module, n)
 
   # XXX globalError() is ugly here, but I don't know a better solution for now
   inc(g.config.evalMacroCounter)
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 6790276a9..d74bd44d8 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -505,7 +505,10 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) =
       let it = n[i]
       if it.len == 1:
         # else stmt:
-        c.gen(it[0], dest)
+        if it[0].kind != nkNilLit or it[0].typ != nil:
+          # an nkNilLit with nil for typ implies there is no else branch, this
+          # avoids unused related errors as we've already consumed the dest
+          c.gen(it[0], dest)
       else:
         let b = rawGenLiteral(c, it)
         c.gABx(it, opcBranch, tmp, b)
diff --git a/nimsuggest/tests/twithin_macro.nim b/nimsuggest/tests/twithin_macro.nim
index 2f5e278c4..d79dae1be 100644
--- a/nimsuggest/tests/twithin_macro.nim
+++ b/nimsuggest/tests/twithin_macro.nim
@@ -41,15 +41,11 @@ echo r.age_human_yrs()
 echo r
 
 discard """
-disabled:true
-$nimsuggest --tester $file
+$nimsuggest --tester --maxresults:5 $file
 >sug $1
 sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;None
 sug;;skField;;name;;string;;$file;;5;;6;;"";;100;;None
 sug;;skMethod;;twithin_macro.age_human_yrs;;proc (self: Animal): int;;$file;;8;;9;;"";;100;;None
 sug;;skMethod;;twithin_macro.vocalize;;proc (self: Animal): string;;$file;;7;;9;;"";;100;;None
 sug;;skMethod;;twithin_macro.vocalize;;proc (self: Rabbit): string;;$file;;23;;9;;"";;100;;None
-sug;;skMacro;;twithin_macro.class;;proc (head: untyped, body: untyped): untyped{.gcsafe, locks: <unknown>.};;$file;;4;;6;;"";;50;;None*
 """
-
-# TODO: disabled due to semantic error reporting in nimsuggest results
diff --git a/nimsuggest/tests/twithin_macro_prefix.nim b/nimsuggest/tests/twithin_macro_prefix.nim
index 1c06397c5..dd3810818 100644
--- a/nimsuggest/tests/twithin_macro_prefix.nim
+++ b/nimsuggest/tests/twithin_macro_prefix.nim
@@ -46,10 +46,3 @@ $nimsuggest --tester $file
 sug;;skField;;age;;int;;$file;;6;;6;;"";;100;;Prefix
 sug;;skMethod;;twithin_macro_prefix.age_human_yrs;;proc (self: Animal): int;;$file;;8;;9;;"";;100;;Prefix
 """
-
-#[
-TODO: additional calls to `>sug $1` produces different output with errors,
-      possibly related to cached results from the first analysis, which refers
-      to expanded macros/templates which rely on imported symbols from `system`
-      module that are not present in this module.
-]#
diff --git a/tests/errmsgs/t10734.nim b/tests/errmsgs/t10734.nim
index 32ee5415e..4e73db7cd 100644
--- a/tests/errmsgs/t10734.nim
+++ b/tests/errmsgs/t10734.nim
@@ -2,13 +2,14 @@ discard """
   cmd: "nim check $file"
   errormsg: ""
   nimout: '''
-t10734.nim(18, 1) Error: invalid indentation
-t10734.nim(18, 6) Error: invalid indentation
-t10734.nim(19, 7) Error: expression expected, but found '[EOF]'
-t10734.nim(17, 5) Error: 'proc' is not a concrete type; for a callback without parameters use 'proc()'
-t10734.nim(18, 6) Error: undeclared identifier: 'p'
-t10734.nim(18, 6) Error: 'p' cannot be assigned to
-t10734.nim(16, 3) Hint: 'T' is declared but not used [XDeclaredButNotUsed]
+t10734.nim(19, 1) Error: invalid indentation
+t10734.nim(19, 6) Error: invalid indentation
+t10734.nim(20, 7) Error: expression expected, but found '[EOF]'
+t10734.nim(18, 5) Error: 'proc' is not a concrete type; for a callback without parameters use 'proc()'
+t10734.nim(19, 6) Error: undeclared identifier: 'p'
+t10734.nim(19, 6) Error: expression 'p' has no type (or is ambiguous)
+t10734.nim(19, 6) Error: 'p' cannot be assigned to
+t10734.nim(17, 3) Hint: 'T' is declared but not used [XDeclaredButNotUsed]
 '''
 """
 
diff --git a/tests/js/t11166.nim b/tests/js/t11166.nim
index 8dd77925c..e98ccda10 100644
--- a/tests/js/t11166.nim
+++ b/tests/js/t11166.nim
@@ -1,4 +1,20 @@
+discard """
+  output: '''
+test1
+test2
+'''
+"""
+
 import jsffi
 
+type
+  C = object
+    props: int
+
+var c: C
+
 when compiles(c.props):
-  echo "test"
+  echo "test1"
+
+when not compiles(d.props):
+  echo "test2"
1c334c68a4423fdd9752e9918aec06e135df'>690a1c3 ^
fd7d36f ^




690a1c3 ^






fd7d36f ^






e1c5a42 ^
21b1583 ^
bc464fe ^
e1c5a42 ^
fd7d36f ^
e1c5a42 ^
fd7d36f ^
d141822 ^





e1c5a42 ^







21b1583 ^



e1c5a42 ^

21b1583 ^
bc464fe ^















































21b1583 ^




























































d141822 ^




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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294