]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #37412 - eddyb:lazy-6, r=nikomatsakis
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Thu, 10 Nov 2016 01:46:28 +0000 (03:46 +0200)
committerGitHub <noreply@github.com>
Thu, 10 Nov 2016 01:46:28 +0000 (03:46 +0200)
[6/n] rustc: transition HIR function bodies from Block to Expr.

_This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37408) | [next](https://github.com/rust-lang/rust/pull/37676)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments._

<hr>

The main change here is that functions and closures both use `Expr` instead of `Block` for their bodies.
For closures this actually allows a honest representation of brace-less closure bodies, e.g. `|x| x + 1` is now distinguishable from `|x| { x + 1 }`, therefore this PR is `[syntax-breaking]` (cc @Manishearth).

Using `Expr` allows more logic to be shared between constant bodies and function bodies, with some small such changes already part of this PR, and eventually easing #35078 and per-body type tables.

Incidentally, there used to be some corners cut here and there and as such I had to (re)write divergence tracking for type-checking so that it is capable of understanding basic structured control-flow:

``` rust
fn a(x: bool) -> i32 {
    // match also works (as long as all arms diverge)
    if x { panic!("true") } else { return 1; }
    0 // "unreachable expression" after this PR
}
```

And since liveness' "not all control paths return a value" moved to type-checking we can have nice things:

``` rust
// before & after:
fn b() -> i32 { 0; } // help: consider removing this semicolon

// only after this PR
fn c() -> i32 { { 0; } } // help: consider removing this semicolon
fn d() { let x: i32 = { 0; }; } // help: consider removing this semicolon
fn e() { f({ 0; }); } // help: consider removing this semicolon
```

1  2 
src/librustc/middle/dead.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc_const_eval/eval.rs
src/librustc_lint/bad_style.rs
src/librustc_lint/builtin.rs
src/librustc_passes/consts.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge