Mercury Bugs - mercury
View Issue Details
0000184mercuryBugpublic2011-02-03 17:282016-06-30 11:46
Reportermgiuca 
Assigned Tojuliensf 
PrioritynormalSeveritycrashReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version 
Target Version15.11Fixed in Version 
Summary0000184: Unresolved polymorphism in typeclass crashes mmc
DescriptionThe following program causes a software error in mmc (I believe I am using the HLC grade -- is there any way to check this?):

:- module compileerror.

:- interface.

:- func test = int.

:- implementation.

:- import_module list.

test = f([]).

:- typeclass myclass(T) where [
    func f(T) = int
].

:- instance myclass(list(T)) <= myclass(T) where [
    f(_) = 4
].

Uncaught Mercury exception:
Software Error: map.lookup: key not found
    Key Type: parse_tree.prog_data.prog_constraint
    Key Value: constraint(qualified(unqualified("compileerror"), "myclass"), [type_variable(var(1), kind_star)])
    Value Type: set_ordlist.set_ordlist(hlds.hlds_data.constraint_id)
Stack dump not available in this grade.

There are two factors which cause this. First, the instance for list has a constraint on T -- this can be any constraint but it doesn't crash unless there is a constraint on T. Second, I am calling 'f' with a type with unresolved polymorphism (the empty list has type list(T) and I have not bound the type variable T). Had I written f([] : list(int)) and added an instance myclass(int), it would compile successfully.

What I would have expected is to receive a warning due to unresolved polymorphism, along the lines of:
compileerror.m:005: In function `test'/0:
compileerror.m:005: warning: unresolved polymorphism.
compileerror.m:005: The variable with an unbound type was:
compileerror.m:005: V_2: list.list(T)
compileerror.m:005: The unbound type variable will be implicitly bound to the
compileerror.m:005: builtin type `void'.

Then I suppose this would cause an error, since `void' is not an instance of myclass:
compileerror.m:011: In clause for function `test'/0:
compileerror.m:011: unsatisfiable typeclass constraint:
compileerror.m:011: `compileerror.myclass(void)'.

This would then communicate to the user the folly of passing a list with an unspecified type to a method which really needs the list elements to have a concrete instance of myclass.
Additional InformationIt seems as though the problem is that things are happening in the wrong order inside the compiler. With minor changes, I can cause the "unresolved polymorphism" warning to occur, so I think the problem is that mmc is trying to choose a "type dictionary" or "vtable" for the elements-of-the-list type *before* it assigns the type `void'. I figure that if it assigned the type `void' earlier, then it would cause the above more user-friendly error instead.

For what it's worth, this situation does cause the following error in GHCI for Haskell:
    Ambiguous type variable `a' in the constraint:
      `MyClass a' arising from a use of `f' at compileerror.hs:2:7-10
    Probable fix: add a type signature that fixes these type variable(s)
TagsNo tags attached.
Attached Files

Notes
(0000889)
juliensf   
2016-06-30 11:46   
Fixed in commit ced4134.

Issue History
2011-02-03 17:28mgiucaNew Issue
2015-10-31 20:54juliensfTarget Version => 15.11
2016-06-30 11:46juliensfNote Added: 0000889
2016-06-30 11:46juliensfStatusnew => resolved
2016-06-30 11:46juliensfResolutionopen => fixed
2016-06-30 11:46juliensfAssigned To => juliensf