ocamllabs / compiler-hacking

Wiki for compiler hacking sessions
91 stars 5 forks source link

Type variable names should be retained #4

Open dsheets opened 10 years ago

dsheets commented 10 years ago

In error messages regarding polymorphic values, it would be nice to have the names of type variables retained.

For instance:

class ['repo, 'pkg] universe :
object ('self)
  constraint 'repo =
  < filter        : ('repo -> 'pkg -> bool) -> 'repo;
    map           : ('repo -> 'pkg -> 'pkg) -> 'repo;
    name          : string;
    opam          : OpamTypes.repository;
    packages      : 'pkg OpamPackage.Map.t;
    priority      : int;
    with_priority : int -> 'repo;
    ..
  >

but then when a type error is printed:

A type parameter has type
         < filter : ('b -> < package : OpamPackage.Set.elt; .. > -> bool) ->
                    'a;
           map : 'c -> 'a; name : OpamRepositoryName.Map.key;
           opam : OpamTypes.repository;
           packages : < conflicts : OpamTypes.formula;
                        depends : OpamTypes.formula;
                        depopts : OpamTypes.formula; .. >
                      OpamPackage.Map.t;
           priority : int; with_priority : int -> 'a; .. >
         as 'a
       but is expected to have type
         < filter : ('d ->
                     (< conflicts : OpamTypes.formula;
                        depends : OpamTypes.formula;
                        depopts : OpamTypes.formula;
                        package : OpamTypes.package; .. >
                      as 'e) ->
                     bool) ->
                    'd;
           map : ('d -> 'e -> 'e) -> 'd; name : string;
           opam : OpamTypes.repository; packages : 'e OpamPackage.Map.t;
           priority : int; with_priority : int -> 'd; .. >
         as 'd
       This instance of 'd is ambiguous:
       it would escape the scope of its equation

This probably requires annotation and a disambiguation pass before error printing.

dsheets commented 10 years ago

The whole error message, which contains ambiguous type names:

File "lib/opamfUniverse.ml", line 1:
Error: The implementation lib/opamfUniverse.ml
       does not match the interface lib/opamfUniverse.cmi:
       Class declarations do not match:
         class ['a, 'b] universe :
           object ('c)
             constraint 'a =
               < filter : ('d ->
                           < package : OpamPackage.Set.elt; .. > -> bool) ->
                          'a;
                 map : 'e -> 'a; name : string; opam : OpamTypes.repository;
                 packages : 'b OpamPackage.Map.t; priority : int;
                 with_priority : int -> 'a; .. >
             constraint 'b =
               < conflicts : OpamTypes.formula; depends : OpamTypes.formula;
                 depopts : OpamTypes.formula; .. >
             val max_versions :
               OpamPackage.Version.Set.elt OpamPackage.Name.Map.t Lazy.t
             val package_set : OpamPackage.Set.t Lazy.t
             val packages : ('a * 'b) OpamPackage.Map.t Lazy.t
             val repos : 'a OpamRepositoryName.Map.t
             val versions :
               OpamPackage.Version.Set.t OpamPackage.Name.Map.t Lazy.t
             method add_repo : 'a -> 'c
             method filter : ?depopts:bool -> ('a -> 'b -> bool) -> 'c
             method filter_repos : ('a -> bool) -> 'c
             method load_repos : 'a OpamRepositoryName.Map.t -> 'c
             method map : 'e -> 'c
             method map_repos : ('a -> 'a) -> 'c
             method max_versions :
               OpamPackage.Version.Set.elt OpamPackage.Name.Map.t
             method package : OpamPackage.Map.key -> 'a * 'b
             method package_set : OpamPackage.Set.t
             method packages : ('a * 'b) OpamPackage.Map.t
             method push_repo : 'a -> 'c
             method repos : 'a OpamRepositoryName.Map.t
             method versions :
               OpamPackage.Version.Set.t OpamPackage.Name.Map.t
           end
       does not match
         class ['a, 'b] universe :
           object ('c)
             constraint 'a =
               < filter : ('a -> 'b -> bool) -> 'a;
                 map : ('a -> 'b -> 'b) -> 'a; name : string;
                 opam : OpamTypes.repository;
                 packages : 'b OpamPackage.Map.t; priority : int;
                 with_priority : int -> 'a; .. >
             constraint 'b =
               < conflicts : OpamTypes.formula; depends : OpamTypes.formula;
                 depopts : OpamTypes.formula; package : OpamTypes.package;
                 .. >
             method add_repo : 'a -> 'c
             method filter : ?depopts:bool -> ('a -> 'b -> bool) -> 'c
             method filter_repos : ('a -> bool) -> 'c
             method load_repos : 'a OpamRepositoryName.Map.t -> 'c
             method map : ('a -> 'b -> 'b) -> 'c
             method map_repos : ('a -> 'a) -> 'c
             method max_versions : OpamTypes.version OpamPackage.Name.Map.t
             method package : OpamTypes.package -> 'a * 'b
             method package_set : OpamPackage.Set.t
             method packages : ('a * 'b) OpamPackage.Map.t
             method push_repo : 'a -> 'c
             method repos : 'a OpamRepositoryName.Map.t
             method versions : OpamTypes.version_set OpamPackage.Name.Map.t
           end
       A type parameter has type
         < filter : ('b -> < package : OpamPackage.Set.elt; .. > -> bool) ->
                    'a;
           map : 'c -> 'a; name : string; opam : OpamTypes.repository;
           packages : < conflicts : OpamTypes.formula;
                        depends : OpamTypes.formula;
                        depopts : OpamTypes.formula; .. >
                      OpamPackage.Map.t;
           priority : int; with_priority : int -> 'a; .. >
         as 'a
       but is expected to have type
         < filter : ('d ->
                     (< conflicts : OpamTypes.formula;
                        depends : OpamTypes.formula;
                        depopts : OpamTypes.formula;
                        package : OpamTypes.package; .. >
                      as 'e) ->
                     bool) ->
                    'd;
           map : ('d -> 'e -> 'e) -> 'd; name : string;
           opam : OpamTypes.repository; packages : 'e OpamPackage.Map.t;
           priority : int; with_priority : int -> 'd; .. >
         as 'd
       This instance of 'd is ambiguous:
       it would escape the scope of its equation