Skip to content

Commit 21fa049

Browse files
committed
error on type name / type abbreviation collision
1 parent c114619 commit 21fa049

File tree

4 files changed

+63
-11
lines changed

4 files changed

+63
-11
lines changed

src/compiler/compiler.ml

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ module Assembled = struct
275275
kinds : Arity.t F.Map.t;
276276
types : TypingEnv.t;
277277
type_abbrevs : Type_checker.type_abbrevs;
278+
ty_names : Loc.t F.Map.t;
278279
}
279280
[@@deriving show]
280281

@@ -305,6 +306,7 @@ module Assembled = struct
305306
types = TypingEnv.empty;
306307
type_abbrevs = F.Map.empty;
307308
toplevel_macros = F.Map.empty;
309+
ty_names = F.Map.empty;
308310
}
309311
let empty () = {
310312
clauses = [];
@@ -1038,6 +1040,12 @@ end = struct
10381040
let type_abbrevs = List.map compile_type_abbrev type_abbrevs in
10391041
let kinds = List.fold_left compile_kind F.Map.empty kinds in
10401042
let types = List.fold_left (fun m t -> map_append TypingEnv.empty t (ScopeTypeExpressionUniqueList.make @@ compile_type t) m) F.Map.empty (List.rev types) in
1043+
let ta_t_captures = List.filter_map (fun (k,loc) -> if F.Map.mem k kinds then Some (k,loc,F.Map.find k kinds) else None) type_abbrevs in
1044+
if ta_t_captures <> [] then begin
1045+
let ta, tsd, (_, oloc) = List.hd ta_t_captures in
1046+
let tad = List.assoc ta type_abbrevs in
1047+
error ~loc:tad.ScopedTypeExpression.loc ("Illegal type abbreviation for " ^ F.show ta ^ ". A type with the same name already exists in " ^ Loc.show oloc)
1048+
end;
10411049
let defs_k = defs_of_map kinds in
10421050
let defs_t = defs_of_map types in
10431051
let defs_ta = defs_of_assoclist type_abbrevs in
@@ -1283,6 +1291,11 @@ module Flatten : sig
12831291
let types = merge_types TypingEnv.empty (apply_subst_types new_ty_subst t) types in
12841292
(* Format.eprintf "@[<v>Types after:@ %a@]@," F.Map.(pp ScopeTypeExpressionUniqueList.pretty) (apply_subst_types new_ty_subst t); *)
12851293
let type_abbrevs = merge_type_abbrevs type_abbrevs (apply_subst_type_abbrevs new_ty_subst ta) in
1294+
let ta_t_captures = List.filter_map (fun (k,loc) -> if F.Map.mem k kinds then Some (k,loc,F.Map.find k kinds) else None) type_abbrevs in
1295+
if ta_t_captures <> [] then begin
1296+
let ta, tad,(_,oloc) = List.hd ta_t_captures in
1297+
error ~loc:tad.ScopedTypeExpression.loc ("Illegal type abbreviation for " ^ F.show ta ^ ". A type with the same name already exists in " ^ Loc.show oloc)
1298+
end;
12861299
let kinds, types, type_abbrevs, clauses, chr =
12871300
compile_block kinds types type_abbrevs clauses chr new_pred_subst new_ty_subst body in
12881301
compile_block kinds types type_abbrevs clauses chr pred_subst ty_subst rest
@@ -1327,14 +1340,14 @@ module Check : sig
13271340
end = struct
13281341

13291342
let check_signature ~flags (base_signature : Assembled.signature) (signature : Flat.unchecked_signature) : Assembled.signature * Assembled.signature * float * TypingEnv.t =
1330-
let { Assembled.kinds = ok; types = ot; type_abbrevs = ota; toplevel_macros = otlm } = base_signature in
1343+
let { Assembled.kinds = ok; types = ot; type_abbrevs = ota; toplevel_macros = otlm; ty_names = ots } = base_signature in
13311344

13321345
let { Flat.kinds; types; type_abbrevs; toplevel_macros } = signature in
13331346

13341347
let all_kinds = Flatten.merge_kinds ok kinds in
13351348
let check_k_begin = Unix.gettimeofday () in
1336-
let all_type_abbrevs, type_abbrevs =
1337-
List.fold_left (fun (all_type_abbrevs,type_abbrevs) (name, scoped_ty) ->
1349+
let all_type_abbrevs, type_abbrevs, all_ty_names, ty_names =
1350+
List.fold_left (fun (all_type_abbrevs,type_abbrevs, all_ty_names, ty_names) (name, scoped_ty) ->
13381351
(* TODO check disjoint from kinds *)
13391352
let loc = scoped_ty.ScopedTypeExpression.loc in
13401353
let _, _, { TypingEnv.ty } = Type_checker.check_type ~type_abbrevs:all_type_abbrevs ~kinds:all_kinds scoped_ty in
@@ -1345,23 +1358,38 @@ end = struct
13451358
("Duplicate type abbreviation for " ^ F.show name ^
13461359
". Previous declaration: " ^ Loc.show otherloc)
13471360
end;
1348-
F.Map.add name (ty,loc) all_type_abbrevs, F.Map.add name (ty,loc) type_abbrevs)
1349-
(ota,F.Map.empty) type_abbrevs in
1361+
if F.Map.mem name ots && not (Loc.equal (F.Map.find name ots) loc) then begin
1362+
error ~loc ("Illegal type abbreviation for " ^ F.show name ^ ". A type with the same name already exists in " ^ Loc.show (F.Map.find name ots))
1363+
end;
1364+
F.Map.add name (ty,loc) all_type_abbrevs,
1365+
F.Map.add name (ty,loc) type_abbrevs,
1366+
F.Map.add name loc all_ty_names,
1367+
F.Map.add name loc ty_names
1368+
)
1369+
(ota,F.Map.empty,ots,F.Map.empty) type_abbrevs in
13501370
let check_k_end = Unix.gettimeofday () in
13511371

13521372
(* Type checking *)
13531373
let check_t_begin = Unix.gettimeofday () in
13541374
(* Type_checker.check_disjoint ~type_abbrevs ~kinds; *)
13551375

1376+
let merge k a b =
1377+
match a, b with
1378+
| _, Some (_,loc) -> Some loc
1379+
| Some _, b -> a
1380+
| _ -> anomaly ("ty_names collision: " ^ F.show k) in
1381+
let ty_names = F.Map.merge merge ty_names kinds in
1382+
let all_ty_names = F.Map.merge merge all_ty_names kinds in
13561383
let types = Type_checker.check_types ~type_abbrevs:all_type_abbrevs ~kinds:all_kinds types in
13571384

1385+
13581386
let all_types = Flatten.merge_type_assignments ot types in
13591387
F.Map.iter (fun k m -> Type_checker.check_macro ~kinds:all_kinds ~type_abbrevs:all_type_abbrevs ~types:all_types k m) toplevel_macros;
13601388
let check_t_end = Unix.gettimeofday () in
13611389
let all_toplevel_macros = Flatten.merge_toplevel_macros all_types otlm toplevel_macros in
13621390

1363-
{ Assembled.kinds; types; type_abbrevs; toplevel_macros },
1364-
{ Assembled.kinds = all_kinds; types = all_types; type_abbrevs = all_type_abbrevs; toplevel_macros = all_toplevel_macros },
1391+
{ Assembled.kinds; types; type_abbrevs; toplevel_macros; ty_names },
1392+
{ Assembled.kinds = all_kinds; types = all_types; type_abbrevs = all_type_abbrevs; toplevel_macros = all_toplevel_macros; ty_names = all_ty_names },
13651393
(if flags.time_typechecking then check_t_end -. check_t_begin +. check_k_end -. check_k_begin else 0.0),
13661394
types
13671395

@@ -2012,14 +2040,17 @@ end = struct
20122040
List.fold_left (extend1_chr ~builtins ~types flags state clique) (symbols,chr) rules
20132041

20142042
let extend1_signature base_signature (signature : checked_compilation_unit_signature) =
2015-
let { Assembled.kinds = ok; types = ot; type_abbrevs = ota; toplevel_macros = otlm } = base_signature in
2016-
let { Assembled.toplevel_macros; kinds; types; type_abbrevs } = signature in
2043+
let { Assembled.kinds = ok; types = ot; type_abbrevs = ota; toplevel_macros = otlm; ty_names = ots } = base_signature in
2044+
let { Assembled.toplevel_macros; kinds; types; type_abbrevs; ty_names } = signature in
20172045
let kinds = Flatten.merge_kinds ok kinds in
2046+
F.Map.iter (fun k (_,loc) -> if F.Map.mem k ots && not (Loc.equal loc (F.Map.find k ots)) then error ~loc ("Illegal type abbreviation for " ^ F.show k ^ ". A type with the same name already exists in " ^ Loc.show (F.Map.find k ots))) type_abbrevs;
20182047
let type_abbrevs = Flatten.merge_checked_type_abbrevs ota type_abbrevs in
20192048
let types = Flatten.merge_type_assignments ot types in
20202049
let toplevel_macros = Flatten.merge_toplevel_macros types otlm toplevel_macros in
2021-
2022-
{ Assembled.kinds; types; type_abbrevs; toplevel_macros }
2050+
let merge k a b =
2051+
if Loc.equal a b then Some a else anomaly ("ty_names collision: " ^ F.show k ^ "\n" ^ Loc.show a ^ "\n" ^ Loc.show b) in
2052+
let ty_names = F.Map.union merge ots ty_names in
2053+
{ Assembled.kinds; types; type_abbrevs; toplevel_macros; ty_names }
20232054

20242055
let new_symbols_of_types ~(base_sig:checked_compilation_unit_signature) new_types =
20252056
let symbs = TypingEnv.all_symbols new_types in

tests/sources/dupta.elpi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
typeabbrev a (list int).
2+
kind a type.
3+
main.

tests/sources/dupta2.elpi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace x {
2+
typeabbrev a (list int).
3+
}
4+
kind x.a type.
5+
main.

tests/suite/elpi_specific.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,16 @@ let () = declare "implbang"
527527
~description:"tail cut =!=>"
528528
~expectation:Success
529529
()
530+
531+
532+
let () = declare "dupta"
533+
~source_elpi:"dupta.elpi"
534+
~description:"duplicate type abbreviation"
535+
~expectation:(FailureOutput (Str.regexp "Illegal type"))
536+
()
537+
538+
let () = declare "dupta2"
539+
~source_elpi:"dupta2.elpi"
540+
~description:"duplicate type abbreviation namespace"
541+
~expectation:(FailureOutput (Str.regexp "Illegal type"))
542+
()

0 commit comments

Comments
 (0)