More error reporting annotations

There are a few places in the Scala library where where @deprecated is used to warn about doing something unintended, rather than to indicate actual deprecation. For example, math.round(Long):Long, RichInt.round:Int and RichLong.round:Long are all deprecated with the message "This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value?". In personal projects, I have used the @deprecated annotation similarly for a no-arg variant of a varargs method, to warn that calling it is pointless.

I opine that it would be valuable to have one or more annotations more suited to warning about unintended actions. In theory, @deprecated annotations should eventually be removed with their methods, when users have had time to stop using the methods in question. However, the annotations for the various rounding methods should exist forever, as the methods are there to help prevent accidental conversion to Float when calling the method on with Int or Long. Additionally, while it makes sense to state when a method was deprecated, it makes less sense for methods created and annotated to prevent mistakes - they were always mistakes ever since they were added.

An annotation such as @wrong or @mistake (or something else?) would be useful to mark such methods as something you probably don’t mean to do. If there are use cases with sufficiently different rationales, more than one new annotation may perhaps be useful.

1 Like

I always use

@deprecated("the message", since = "forever")

for that purpose. It clearly signals that the method had been deprecated ever since it was added, and is also a “keyword” to exclude in grep when looking for deprecated stuff to remove in a major version.

3 Likes

You could make it @compileTimeOnly("This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value?") .
Though there might still be value in having additional @error and @warn annotations.

Deprecation means avoid using this. The Javadoc: “A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.”

Removing API generally entails deprecation, but not the other way around.

3 Likes

I commented on the related ticket to make @deprecated more restrictive by requiring both string args.

I argue that it’s nicer to follow Java and recognize both “ordinary” and “terminal” deprecations.

I think the current deprecation warning for @deprecated should be turned into either a built-in -Xlint:deprecated warning or a scalafix rule. I also suggest something like @deprecated(until="1.0") for Java’s forRemoval flag. An empty until would mean the policy is defined elsewhere. Or maybe until="?", to add to the list of how many uses of ? are there in Scala?

1 Like

I like the idea of an until or forRemoval

2 Likes

I like having ‘more specific’ annotations next to @deprecated.

Previously, you could create those yourself by extending deprecated. deprecated is scheduled to become final in 2.14, however, so this would no longer be possible.

One that I like is @unused, for parameters that are no longer used, but kept around for binary compatibility. By extending from @deprecated, using the parameter marked @unused produces a warning, and it no longer produces a warning when -Ywarn-unused is enabled.

While of course you could use @deprecated for this directly as well, having a more meaningful name is valuable.

1 Like