about summary refs log tree commit diff
path: root/src/rustllvm/RustWrapper.cpp
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-01-28 00:40:10 +0000
committerbors <bors@rust-lang.org>2018-01-28 00:40:10 +0000
commit6beb06ee5ef6f031aab7586211f1818d346033d6 (patch)
treeba541694b09ecbc9a955e0256e240770d70d0d5f /src/rustllvm/RustWrapper.cpp
parent7d6e5b9da0865fbc9fa54edb324fefe80f358da7 (diff)
parentadcb37e275ee9b06114d4debdfe453cbc89b7716 (diff)
downloadrust-6beb06ee5ef6f031aab7586211f1818d346033d6.tar.gz
rust-6beb06ee5ef6f031aab7586211f1818d346033d6.zip
Auto merge of #47746 - varkor:never-type-ice, r=nikomatsakis
Fix never-type rvalue ICE

This fixes #43061.
r? @nikomatsakis

A small post-mortem as a follow-up to our investigations in https://github.com/rust-lang/rust/pull/47291:
The problem as I understand it is that when `NeverToAny` coercions are made, the expression/statement that is coerced may be enclosed in a block. In our case, the statement `x;` was being transformed to something like: `NeverToAny( {x;} )`. Then, `NeverToAny` is transformed into an expression:
https://github.com/rust-lang/rust/blob/000fbbc9b8f88adc6a417f1caef41161f104250f/src/librustc_mir/build/expr/into.rs#L52-L59
Which ends up calling `ast_block_stmts` on the block `{x;}`, which triggers this condition:
https://github.com/rust-lang/rust/blob/000fbbc9b8f88adc6a417f1caef41161f104250f/src/librustc_mir/build/block.rs#L141-L147
In our case, there is no return expression, so `push_assign_unit` is called. But the block has already been recorded as _diverging_, meaning the result of the block will be assigned to a location of type `!`, rather than `()`. This causes the MIR error.
I'm assuming the `NeverToAny` coercion code is doing what it's supposed to (there don't seem to be any other problems), so fixing the issue simply consists of checking that the destination for the return value actually _is_ supposed to be a unit. (If no return value is given, the only other possible type for the return value is `!`, which can just be ignored, as it will be unreachable anyway.)

I checked the other cases of `push_assign_unit`, and it didn't look like they could be affected by the divergence issue (blocks are kind of special-cased in this regard as far as I can tell), so this should be sufficient to fix the issue.
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions