Error messages - vilinski/nemerle GitHub Wiki

Basics

The most important rule of thumb here is:

If you see some strange error message, and this is not the first error message in this ncc invocation, first fix the previous error and then proceed.

This is because compiler internal structures can be messed up by the previous error. We are trying to limit this, but this doesn't get very high priority.

Messages from type inference engine

It often laments about type suffixed with -, +, -- and ++. In most cases you should read this int-- (and int-, int+, int++) just like int. However in certain cases the +/- etc can provide additional information. For example:

if (true) 3 else ()

will give the following error:

foo.n:1:18: error: expected int--, got void in literal: int is not a 
            subtype of void [simple require]

This is because the compiler expects () to be of some type that has a common super type with int, so this common super type is returned from the entire if expression. So int-- stands here for some type with common super type with int.

mutable x = 3;
x = 3.0;

here the error is:

foo.n:2:1: error: expected int-, got System.Double in assigned value:
           common super type of types [int, System.Double] is just 
           `System.ValueType', please upcast one of the types to 
           `System.ValueType' if this is desired

Here the compiler expects some super type of int to be assigned, so if we assigned System.Object, then it would change the type of x to be System.Object and would still be happy (until of course you use x in context requiring int).

In fact it would also accept super type, because of how assignment works.

So this is a good example when int- should be read as int.

Assignment result and match branches

The result of the assignment is something you got after the assignment is done. The expression x = 42 has the type int in C/C#, but it has the type void in Nemerle. That is after the assignment is done you got nothing, and cannot use this value to do anything reasonable except for returning it from a void function.

For example:

mutable x = 7;
(x = 42) : bool;
when (x = 42) { }
will yield two errors:
bar.n:2:2: error: expected bool, got void in type-enforced expression: void 
           is not a subtype of bool [simple require]
bar.n:3:1: error: expected void, got bool in matched value: the types bool 
           and void are not compatible [simple unify]

Another example is:

def some_func () { true }
mutable x = 42;
match (3) {
  | 1 => some_func ()
  | _ => x = 7;
}
which gives:
t.n:4:1: error: expected bool-, got void in computation branch: bool is not a subtype of void [simple require]
t.n:4:1: hint: this means two branches of ``if'' or ``match'' have different types

This is because the compiler assumes all branches of matching to have the same type. After the first branch (of type bool) is typed it assumes all the following branches will have the same type. Therefore it screams about wrong type of computation branch. I would get similar error if I have used if instead of match.

The solution here is to ignore the result from some_func(), like this: _ = some_func (). This will make the first branch (and therefore the entire match) return void. The second solution is to make the second branch return bool, like this: x = 7; true.

⚠️ **GitHub.com Fallback** ⚠️