A class's name and its keyword are one dispatch value
(defmethod area point ...) and (defmethod area :point ...) were both accepted and the second was dead code: a class stands for the keyword its instances carry -- that is the whole of how the two dispatch styles share a mechanism -- so the duplicate scan has to compare them as one. It compared the written forms, which differ. Normalised in the scan and pinned in test_flan.ml.
This commit is contained in:
parent
52a1ea183a
commit
0511cc1a01
@ -124,9 +124,15 @@ let collect (decls : Ast.decl list) =
|
|||||||
list: one call site reaches all of them, and it can only pass \
|
list: one call site reaches all of them, and it can only pass \
|
||||||
one number of arguments"
|
one number of arguments"
|
||||||
m.Ast.mgen want (if want = 1 then "" else "s") n;
|
m.Ast.mgen want (if want = 1 then "" else "s") n;
|
||||||
|
(* A class's name and its keyword are one dispatch value — a class
|
||||||
|
stands for the keyword its instances carry, which is the whole of
|
||||||
|
how the two dispatch styles share a mechanism — so [point] and
|
||||||
|
[:point] have to be compared as one or the second method is
|
||||||
|
accepted and is dead code. *)
|
||||||
|
let norm = function Ast.Dclass c -> Ast.Dkw c | k -> k in
|
||||||
List.iter
|
List.iter
|
||||||
(fun (prev : Ast.methd) ->
|
(fun (prev : Ast.methd) ->
|
||||||
if prev.Ast.mkey = m.Ast.mkey then
|
if norm prev.Ast.mkey = norm m.Ast.mkey then
|
||||||
Loc.failk "check/duplicate-method" d.Ast.dloc
|
Loc.failk "check/duplicate-method" d.Ast.dloc
|
||||||
"%s already has a method for %s. Two methods for one \
|
"%s already has a method for %s. Two methods for one \
|
||||||
dispatch value is an ambiguity nothing resolves — there \
|
dispatch value is an ambiguity nothing resolves — there \
|
||||||
|
|||||||
@ -1803,6 +1803,16 @@ let () =
|
|||||||
(defmethod area point [p] 2)\n\
|
(defmethod area point [p] 2)\n\
|
||||||
(defn main [] i32 0)"
|
(defn main [] i32 0)"
|
||||||
~needle:"already has a method for point";
|
~needle:"already has a method for point";
|
||||||
|
(* A class's name and its keyword are one value: a class stands for the
|
||||||
|
keyword its instances carry, so these two methods are the same method
|
||||||
|
written twice and the second would be dead code. *)
|
||||||
|
rejects_check "a class and its keyword are one dispatch value"
|
||||||
|
"(defclass point [x y])\n\
|
||||||
|
(defgeneric area [self] dyn)\n\
|
||||||
|
(defmethod area point [p] 1)\n\
|
||||||
|
(defmethod area :point [p] 2)\n\
|
||||||
|
(defn main [] i32 0)"
|
||||||
|
~needle:"already has a method for :point";
|
||||||
rejects_check "two :else methods for one generic"
|
rejects_check "two :else methods for one generic"
|
||||||
"(defmulti d [x] dyn x)\n\
|
"(defmulti d [x] dyn x)\n\
|
||||||
(defmethod d :else [x] 1)\n\
|
(defmethod d :else [x] 1)\n\
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user