-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
In #40224, I adopted the rule that one can coerce into the type ! if your expression is considered to diverge (in short, returns, breaks, or must evaluate some expression of type !).
However, the code doens't quite implement that rule. As described in this comment, it actually uses the self.diverges flag of the FnCtxt, which today tracks a property that is different in a subtle way. The property we are checking is: if the coercion of the expression E happens in the context of an expression F, it is permitted to coerce to ! if the expression F has diverged by the time that E finishes evaluating.
So in particular, under the rules I originally envisioned, this would not be allowed (see src/test/compile-fail/coerce-to-bang.rs for more examples):
fn foo(x: usize, y: !) { }
foo(return, 22); // the expression `22` does not divergeBut under the rules as implemented, it is allowed. It's not clear which rules we would prefer. I think I lean towards my original rules: they mean that whether an expression E can be coerced to a type T is purely a function of E (modulo free variables of course). But implementing that will require refactoring the compiler.
In my diverging-types-and-reachability branch, I changed how things work so that divergence is propagated upward, and "reachability" is passed downward. Divergence is thus a property purely of the expression at hand, whereas reachability is computed based on context. We use the combination of the two to drive unreachable warnings -- in particular, when you have reachable code which evaluates a diverging expression, the next thing to be evaluated triggered a warning. The precise setup I had in that branch doesn't work, sadly, because it only computed divergence after all types were known. Some refactoring needed.
Moreover, there are some other places I cut corners in the existing code, and I'm using this same FIXME to track them: in particular, in cast expressions, I am ignoring whether they diverge for the purposes of this check. That's just laziness.