The warnUnused MLBasis annotation can be used to report unused identifiers. This can be useful for catching bugs and for code maintenance (e.g., eliminating dead code). However, the warnUnused annotation can sometimes behave in counterintuitive ways. This page gives some of the anomalies that have been reported.

Functions whose only uses are recursive uses within their bodies are not warned as unused:
local fun foo () = foo () : unit val bar = let fun baz () = baz () : unit in baz end in end
Warning: z.sml 3.5. Unused variable: bar.

Components of actual functor argument that are necessary to match the functor argument signature but are unused in the body of the functor are warned as unused:
functor Warning (type t val x : t) = struct val y = x end structure X = Warning (type t = int val x = 1)
Warning: z.sml 4.29. Unused type: t.

No component of a functor result is warned as unused. In the following, the only uses of f2 are to match the functor argument signatures of functor G and functor H and there are no uses of z:
functor F(structure X : sig type t end) = struct type t = X.t fun f1 (_ : X.t) = () fun f2 (_ : X.t) = () val z = () end functor G(structure Y : sig type t val f1 : t > unit val f2 : t > unit val z : unit end) = struct fun g (x : Y.t) = Y.f1 x end functor H(structure Y : sig type t val f1 : t > unit val f2 : t > unit val z : unit end) = struct fun h (x : Y.t) = Y.f1 x end functor Z() = struct structure S = F(structure X = struct type t = unit end) structure SG = G(structure Y = S) structure SH = H(structure Y = S) end structure U = Z() val _ = U.SG.g () val _ = U.SH.h ()