Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a shame this is not seen as dead code.
Expr[T]
is sealed, and there are only three valid values forT
:Pos
,Int
andString
, each of which is fully determined by the subclass.Would be nice if
case PosExpr(p) => p
was seen as a total match here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can have that (seeing
case StrExpr(_)
as dead) by moving the match to the companion of the opaque type. You should not have that otherwise, as it would be making the abstraction leak, which is very bad.Also,
case PosExpr(p)
is not "total" as anyIntExpr(_)
can also be given typeExpr[Pos]
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, I neglected the existence of
coerce
here, which can translateF[Int]
toF[Pos]
. I see your point: for an opaque type, we have to inspect and understand all possible functions like this in the companion, and it may be pretty non-trivial to rule out certain branches.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with @LPTK.
@johnynek There are two different problems — checking whether
StringExpr
is dead and whetherIntExpr
is dead. Checking those scenarios would break guarantees you expect from a type system. For both, it'd only be fine in whole-program static analysis tools, but you have different expectations. This is a tradeoff currently under discussion.StrExpr
is dead once you know thatPos
is implemented asInt
— ignoringeval(StrExpr.asInstanceOf[Expr[Pos])
(which we should). But we shall not do it to avoid abstraction leaks. To be more precise on the guarantee: If client code compiles and you changePos
to be implemented asString
, the client code should keep compiling.IntExpr
is dead, by checking whethercoerce
-like functions exist. It might be possible by static analysis of the companion object, but again you change warnings in client code depending on implementation details that (it seems) should be hidden (and are not visible in types). That breaks separate compilation/separate typechecking. Type systems usually don't do that, because if they did it'd be much harder to keep a library source-compatible. Especially with-Xfatal-warnings
.