summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-12-09 07:19:39 -0800
committerGitHub <noreply@github.com>2020-12-09 16:19:39 +0100
commitf344a704123a4b55e2b3b8a4f736a6739d0683bb (patch)
treed3bca149bf4805305d85d43cbd3533cbf2c27f59
parent87e634aab3182d6e9022f108bd6936a58682f01c (diff)
downloadNim-f344a704123a4b55e2b3b8a4f736a6739d0683bb.tar.gz
fix #16150 improve type mismatch errors (#16152)
* fix #16150 improve type mismatch errors

* allow -d:nimLegacyTypeMismatch

* address comment
-rw-r--r--changelog.md2
-rw-r--r--compiler/sem.nim2
-rw-r--r--compiler/semcall.nim2
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semfields.nim5
-rw-r--r--compiler/types.nim7
-rw-r--r--tests/config.nims1
7 files changed, 14 insertions, 7 deletions
diff --git a/changelog.md b/changelog.md
index bb49dc7f6..0e96c868a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -77,6 +77,8 @@
 - Added `nim --eval:cmd` to evaluate a command directly, see `nim --help`.
 
 - VM now supports `addr(mystring[ind])` (index + index assignment)
+- Type mismatch errors now show more context, use `-d:nimLegacyTypeMismatch` for previous
+  behavior.
 
 
 ## Tool changes
diff --git a/compiler/sem.nim b/compiler/sem.nim
index f90d9e1f9..0fec8b7e3 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -96,7 +96,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
   else:
     result = indexTypesMatch(c, formal, arg.typ, arg)
     if result == nil:
-      typeMismatch(c.config, info, formal, arg.typ)
+      typeMismatch(c.config, info, formal, arg.typ, arg)
       # error correction:
       result = copyTree(arg)
       result.typ = formal
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 70a7e099c..1e8da0298 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -476,7 +476,7 @@ proc inferWithMetatype(c: PContext, formal: PType,
     result.typ = generateTypeInstance(c, m.bindings, arg.info,
                                       formal.skipTypes({tyCompositeTypeClass}))
   else:
-    typeMismatch(c.config, arg.info, formal, arg.typ)
+    typeMismatch(c.config, arg.info, formal, arg.typ, arg)
     # error correction:
     result = copyTree(arg)
     result.typ = formal
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 8728af27c..3bbf353b1 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1745,7 +1745,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
           c.p.resultSym.typ = rhsTyp
           c.p.owner.typ[0] = rhsTyp
         else:
-          typeMismatch(c.config, n.info, lhs.typ, rhsTyp)
+          typeMismatch(c.config, n.info, lhs.typ, rhsTyp, rhs)
     borrowCheck(c, n, lhs, rhs)
 
     n[1] = fitNode(c, le, rhs, goodLineInfo(n[1]))
diff --git a/compiler/semfields.nim b/compiler/semfields.nim
index d7563e33f..602a7199d 100644
--- a/compiler/semfields.nim
+++ b/compiler/semfields.nim
@@ -127,9 +127,10 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
     localError(c.config, n.info, errGenerated, "no object or tuple type")
     return result
   for i in 1..<call.len:
-    var tupleTypeB = skipTypes(call[i].typ, skippedTypesForFields)
+    let calli = call[i]
+    var tupleTypeB = skipTypes(calli.typ, skippedTypesForFields)
     if not sameType(tupleTypeA, tupleTypeB):
-      typeMismatch(c.config, call[i].info, tupleTypeA, tupleTypeB)
+      typeMismatch(c.config, calli.info, tupleTypeA, tupleTypeB, calli)
 
   inc(c.p.nestedLoopCounter)
   if tupleTypeA.kind == tyTuple:
diff --git a/compiler/types.nim b/compiler/types.nim
index 1f2ee9d20..535703a8c 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1482,7 +1482,7 @@ proc skipHiddenSubConv*(n: PNode; idgen: IdGenerator): PNode =
   else:
     result = n
 
-proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType) =
+proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType, n: PNode) =
   if formal.kind != tyError and actual.kind != tyError:
     let actualStr = typeToString(actual)
     let formalStr = typeToString(formal)
@@ -1491,7 +1491,10 @@ proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType) =
     let verbose = actualStr == formalStr or optDeclaredLocs in conf.globalOptions
     var msg = "type mismatch:"
     if verbose: msg.add "\n"
-    msg.add  " got <$1>" % actualStr
+    if conf.isDefined("nimLegacyTypeMismatch"):
+      msg.add  " got <$1>" % actualStr
+    else:
+      msg.add  " got '$1' for '$2'" % [actualStr, n.renderTree]
     if verbose:
       msg.addDeclaredLoc(conf, actual)
       msg.add "\n"
diff --git a/tests/config.nims b/tests/config.nims
index 640df9cad..ac5e019f5 100644
--- a/tests/config.nims
+++ b/tests/config.nims
@@ -8,3 +8,4 @@ switch("path", "$lib/../testament/lib")
 switch("colors", "off")
 switch("listFullPaths", "off")
 switch("excessiveStackTrace", "off")
+switch("define", "nimLegacyTypeMismatch")