diff --git a/compiler/desugared/from_surface.ml b/compiler/desugared/from_surface.ml index 5412e0e3..794268d3 100644 --- a/compiler/desugared/from_surface.ml +++ b/compiler/desugared/from_surface.ml @@ -1307,7 +1307,10 @@ let process_topdef | Some (eopt0, ty0), eopt -> ( let err msg = Message.raise_multispanned_error - [None, Mark.get ty0; None, Mark.get typ] + [ + None, Mark.get (TopdefName.get_info id); + None, Mark.get def.S.topdef_name; + ] (msg ^^ " for %a") TopdefName.format id in if not (Type.equal ty0 typ) then err "Conflicting type definitions" diff --git a/compiler/desugared/name_resolution.ml b/compiler/desugared/name_resolution.ml index 2b783a4d..d47ff646 100644 --- a/compiler/desugared/name_resolution.ml +++ b/compiler/desugared/name_resolution.ml @@ -699,13 +699,14 @@ let process_name_item (ctxt : context) (item : Surface.Ast.code_item Mark.pos) : { ctxt with local = { ctxt.local with typedefs } } | ScopeUse _ -> ctxt | Topdef def -> - let name, pos = def.topdef_name in - Option.iter - (fun use -> - raise_already_defined_error (TopdefName.get_info use) name pos - "toplevel definition") - (Ident.Map.find_opt name ctxt.local.topdefs); - let uid = TopdefName.fresh ctxt.local.path def.topdef_name in + let name, _ = def.topdef_name in + let uid = + match Ident.Map.find_opt name ctxt.local.topdefs with + | None -> TopdefName.fresh ctxt.local.path def.topdef_name + | Some uid -> uid + (* Topdef declaration may appear multiple times as long as their types + match and only one contains an expression defining it *) + in let topdefs = Ident.Map.add name uid ctxt.local.topdefs in { ctxt with local = { ctxt.local with topdefs } }