You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Settle desired semantics of divergence for purposes of coercion #40800
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):
fnfoo(x:usize,y: !){}foo(return,22);// the expression `22` does not diverge
But 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.
It sounds to me like your original rules are more intuitive and less likely to lead to weird behaviour (e.g. under the current rules, foo(return, 22) is allowed, but bar(22, return) for fn bar(y: !, x: usize) is not allowed). So surely the only question is whether changing the rules now breaks much existing code?
@dhardy yes. I suspect the impact is quite minimal, but hard to know until we put in the implementation effort. I should probably write up some mentoring instructions; I know I don't have time to pursue it myself.
changed the title [-]settle desires semantics of divergence for purposes of coercion[/-][+]Settle desired semantics of divergence for purposes of coercion[/+]on Aug 3, 2017
@nikomatsakis What's the status of this at the moment? Has any more work been done towards it or do you have any solid ideas about what needs to be done?
@arielb1 and I were talking and I've been kind of failing to find the time to write up our conclusions. In the case of this question, we were wondering if would be possible to remove the "coerce into !" semantics entirely -- it's not clear why it's ever useful. There are some examples in run-pass of things that used to do it in the while, but they are very much corner cases. We'd be interested in removing this coercion and doing a crater run to measure the effects. @canndrew -- think you'd be interested in preparing that PR? Wouldn't be too hard (for the purposes of a crater run, just adding an if false in the right place would suffice, I suppose...)
I'm happy to do whatever needs to be done to get ! stable. I'm about to camping for the next two weeks though, so I won't be able to start until after that...
Activity
nikomatsakis commentedon Mar 24, 2017
cc @rust-lang/lang @canndrew @arielb1
dhardy commentedon May 5, 2017
It sounds to me like your original rules are more intuitive and less likely to lead to weird behaviour (e.g. under the current rules,
foo(return, 22)is allowed, butbar(22, return)forfn bar(y: !, x: usize)is not allowed). So surely the only question is whether changing the rules now breaks much existing code?nikomatsakis commentedon May 5, 2017
@dhardy yes. I suspect the impact is quite minimal, but hard to know until we put in the implementation effort. I should probably write up some mentoring instructions; I know I don't have time to pursue it myself.
dhardy commentedon May 5, 2017
Ah, I see. One of these days I should put in the effort of learning the Rust codebase.
[-]settle desires semantics of divergence for purposes of coercion[/-][+]Settle desired semantics of divergence for purposes of coercion[/+]canndrew commentedon Oct 26, 2017
@nikomatsakis What's the status of this at the moment? Has any more work been done towards it or do you have any solid ideas about what needs to be done?
nikomatsakis commentedon Nov 8, 2017
@arielb1 and I were talking and I've been kind of failing to find the time to write up our conclusions. In the case of this question, we were wondering if would be possible to remove the "coerce into
!" semantics entirely -- it's not clear why it's ever useful. There are some examples inrun-passof things that used to do it in the while, but they are very much corner cases. We'd be interested in removing this coercion and doing a crater run to measure the effects. @canndrew -- think you'd be interested in preparing that PR? Wouldn't be too hard (for the purposes of a crater run, just adding anif falsein the right place would suffice, I suppose...)canndrew commentedon Nov 9, 2017
I'm happy to do whatever needs to be done to get
!stable. I'm about to camping for the next two weeks though, so I won't be able to start until after that...canndrew commentedon Nov 21, 2017
Whereabouts might this "right place" be? I had a look but couldn't see where this coercion happens :/
nikomatsakis commentedon Dec 6, 2017
I believe @arielb1 implemented this in #45880, now merged. Closing.
remove test for `T -> !` coercion
remove test for `T -> !` coercion