Rollup merge of #42016 - pietroalbini:stabilize/loop_break_value, r=nikomatsakis

Stabilize the loop_break_value feature

Tracking issue: #37339.

Documentation PRs already sent to the various repositories.
This commit is contained in:
Corey Farwell 2017-05-23 00:15:41 -04:00 committed by GitHub
commit e38d5d5039
12 changed files with 7 additions and 115 deletions

View File

@ -49,7 +49,6 @@
- [link_llvm_intrinsics](language-features/link-llvm-intrinsics.md)
- [linkage](language-features/linkage.md)
- [log_syntax](language-features/log-syntax.md)
- [loop_break_value](language-features/loop-break-value.md)
- [macro_reexport](language-features/macro-reexport.md)
- [macro_vis_matcher](language-features/macro-vis-matcher.md)
- [main](language-features/main.md)

View File

@ -1,83 +0,0 @@
# `loop_break_value`
The tracking issue for this feature is: [#37339]
[#37339]: https://github.com/rust-lang/rust/issues/37339
Documentation to be appended to section G of the book.
------------------------
### Loops as expressions
Like most things in Rust, loops are expressions, and have a value; normally `()` unless the loop
never exits.
A `loop` can instead evaluate to a useful value via *break with value*:
```rust
#![feature(loop_break_value)]
// Find the first square number over 1000:
let mut n = 1;
let square = loop {
if n * n > 1000 {
break n * n;
}
n += 1;
};
```
The evaluation type may be specified externally:
```rust
#![feature(loop_break_value)]
// Declare that value returned is unsigned 64-bit:
let n: u64 = loop {
break 1;
};
```
It is an error if types do not agree, either between a "break" value and an external requirement,
or between multiple "break" values:
```no_compile
#![feature(loop_break_value)]
loop {
if true {
break 1u32;
} else {
break 0u8; // error: types do not agree
}
};
let n: i32 = loop {
break 0u32; // error: type does not agree with external requirement
};
```
#### Break: label, value
Four forms of `break` are available, where EXPR is some expression which evaluates to a value:
1. `break;`
2. `break 'label;`
3. `break EXPR;`
4. `break 'label EXPR;`
When no value is given, the value `()` is assumed, thus `break;` is equivalent to `break ();`.
Using a label allows returning a value from an inner loop:
```rust
#![feature(loop_break_value)]
let result = 'outer: loop {
for n in 1..10 {
if n > 4 {
break 'outer n;
}
}
};
```

View File

@ -30,7 +30,6 @@
#![feature(core_intrinsics)]
#![feature(i128_type)]
#![feature(libc)]
#![feature(loop_break_value)]
#![feature(never_type)]
#![feature(nonzero)]
#![feature(quote)]
@ -45,6 +44,7 @@
#![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
#![cfg_attr(stage0, feature(rustc_private))]
#![cfg_attr(stage0, feature(staged_api))]
#![cfg_attr(stage0, feature(loop_break_value))]
#![recursion_limit="128"]

View File

@ -23,7 +23,6 @@
#![deny(warnings)]
#![feature(box_syntax)]
#![feature(loop_break_value)]
#![feature(libc)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
@ -32,6 +31,7 @@
#![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
#![cfg_attr(stage0, feature(rustc_private))]
#![cfg_attr(stage0, feature(staged_api))]
#![cfg_attr(stage0, feature(loop_break_value))]
extern crate arena;
extern crate getopts;

View File

@ -76,7 +76,6 @@ This API is completely unstable and subject to change.
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
#![feature(loop_break_value)]
#![feature(never_type)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
@ -84,6 +83,7 @@ This API is completely unstable and subject to change.
#![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
#![cfg_attr(stage0, feature(rustc_private))]
#![cfg_attr(stage0, feature(staged_api))]
#![cfg_attr(stage0, feature(loop_break_value))]
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;

View File

@ -297,9 +297,6 @@ declare_features! (
(active, use_extern_macros, "1.15.0", Some(35896)),
// Allows `break {expr}` with a value inside `loop`s.
(active, loop_break_value, "1.14.0", Some(37339)),
// Allows #[target_feature(...)]
(active, target_feature, "1.15.0", None),
@ -423,6 +420,8 @@ declare_features! (
(accepted, pub_restricted, "1.18.0", Some(32409)),
// The #![windows_subsystem] attribute
(accepted, windows_subsystem, "1.18.0", Some(37499)),
// Allows `break {expr}` with a value inside `loop`s.
(accepted, loop_break_value, "1.19.0", Some(37339)),
);
// If you change this, please modify src/doc/unstable-book as well. You must
// move that documentation into the relevant place in the other docs, and
@ -1301,10 +1300,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
}
ast::ExprKind::Break(_, Some(_)) => {
gate_feature_post!(&self, loop_break_value, e.span,
"`break` with a value is experimental");
}
ast::ExprKind::Lit(ref lit) => {
if let ast::LitKind::Int(_, ref ty) = lit.node {
match *ty {

View File

@ -1,15 +0,0 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
loop {
break 123; //~ ERROR `break` with a value is experimental
}
}

View File

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(loop_break_value)]
#![feature(never_type)]
fn main() {

View File

@ -15,7 +15,6 @@
// like to revisit these and potentially change them. --nmatsakis
#![feature(never_type)]
#![feature(loop_break_value)]
trait BadDefault {
fn default() -> Self;

View File

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(loop_break_value)]
#![feature(never_type)]
#[allow(unused)]

View File

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(loop_break_value)]
#![allow(unused_variables)]
use std::ptr;

View File

@ -1,7 +1,7 @@
error[E0571]: `break` with value from a `for` loop
--> $DIR/loop-break-value-no-repeat.rs:23:9
--> $DIR/loop-break-value-no-repeat.rs:22:9
|
23 | break 22
22 | break 22
| ^^^^^^^^ can only break with a value inside `loop`
error: aborting due to previous error