Skip to content

Commit 8019517

Browse files
committed
---
yaml --- r: 212956 b: refs/heads/master c: 1d33318 h: refs/heads/master v: v3
1 parent bc566dc commit 8019517

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1078
-394
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: cabd0682e9aa406cca2541c3c5d420d100487b04
2+
refs/heads/master: 1d33318018466a97dec2d61195e38952ca30d597
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: ba0e1cd8147d452c356aacb29fb87568ca26f111
55
refs/heads/try: 1864973ae17213c5a58c4dd3f9af6d1b6c7d2e05

trunk/src/doc/reference.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ apply to the crate as a whole.
638638
```
639639

640640
A crate that contains a `main` function can be compiled to an executable. If a
641-
`main` function is present, its return type must be [`unit`](#primitive-types)
641+
`main` function is present, its return type must be [`unit`](#tuple-types)
642642
and it must take no arguments.
643643

644644
# Items and attributes
@@ -928,21 +928,20 @@ A _generic function_ allows one or more _parameterized types_ to appear in its
928928
signature. Each type parameter must be explicitly declared, in an
929929
angle-bracket-enclosed, comma-separated list following the function name.
930930

931-
```{.ignore}
932-
fn iter<T, F>(seq: &[T], f: F) where T: Copy, F: Fn(T) {
933-
for elt in seq { f(*elt); }
934-
}
935-
fn map<T, U, F>(seq: &[T], f: F) -> Vec<U> where T: Copy, U: Copy, F: Fn(T) -> U {
936-
let mut acc = vec![];
937-
for elt in seq { acc.push(f(*elt)); }
938-
acc
939-
}
931+
```rust,ignore
932+
// foo is generic over A and B
933+
934+
fn foo<A, B>(x: A, y: B) {
940935
```
941936

942937
Inside the function signature and body, the name of the type parameter can be
943938
used as a type name. [Trait](#traits) bounds can be specified for type parameters
944939
to allow methods with that trait to be called on values of that type. This is
945-
specified using the `where` syntax, as in the above example.
940+
specified using the `where` syntax:
941+
942+
```rust,ignore
943+
fn foo<T>(x: T) where T: Debug {
944+
```
946945

947946
When a generic function is referenced, its type is instantiated based on the
948947
context of the reference. For example, calling the `iter` function defined
@@ -2874,7 +2873,7 @@ The `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `<<`, and `>>` operators may be
28742873
composed with the `=` operator. The expression `lval OP= val` is equivalent to
28752874
`lval = lval OP val`. For example, `x = x + 1` may be written as `x += 1`.
28762875

2877-
Any such expression always has the [`unit`](#primitive-types) type.
2876+
Any such expression always has the [`unit`](#tuple-types) type.
28782877

28792878
#### Operator precedence
28802879

@@ -3316,6 +3315,9 @@ assert!(b != "world");
33163315
assert!(p.0 == 10);
33173316
```
33183317

3318+
For historical reasons and convenience, the tuple type with no elements (`()`)
3319+
is often called ‘unit’ or ‘the unit type’.
3320+
33193321
### Array, and Slice types
33203322

33213323
Rust has two different types for a list of items:

trunk/src/doc/trpl/closures.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ let y = &mut num;
120120
```
121121

122122
If your closure requires it, however, Rust will take ownership and move
123-
the environment instead:
123+
the environment instead. This doesn’t work:
124124

125125
```rust,ignore
126126
let nums = vec![1, 2, 3];
@@ -130,7 +130,7 @@ let takes_nums = || nums;
130130
println!("{:?}", nums);
131131
```
132132

133-
This gives us:
133+
We get this error:
134134

135135
```text
136136
note: `nums` moved into closure environment here because it has type

trunk/src/doc/trpl/traits.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ fn normal<T: ConvertTo<i64>>(x: &T) -> i64 {
332332
fn inverse<T>() -> T
333333
// this is using ConvertTo as if it were "ConvertFrom<i32>"
334334
where i32: ConvertTo<T> {
335-
1i32.convert()
335+
42.convert()
336336
}
337337
```
338338

trunk/src/libcollections/vec.rs

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,42 +1469,26 @@ impl<T> ops::DerefMut for Vec<T> {
14691469
impl<T> FromIterator<T> for Vec<T> {
14701470
#[inline]
14711471
fn from_iter<I: IntoIterator<Item=T>>(iterable: I) -> Vec<T> {
1472+
// Unroll the first iteration, as the vector is going to be
1473+
// expanded on this iteration in every case when the iterable is not
1474+
// empty, but the loop in extend_desugared() is not going to see the
1475+
// vector being full in the few subsequent loop iterations.
1476+
// So we get better branch prediction and the possibility to
1477+
// construct the vector with initial estimated capacity.
14721478
let mut iterator = iterable.into_iter();
1473-
let (lower, _) = iterator.size_hint();
1474-
let mut vector = Vec::with_capacity(lower);
1475-
1476-
// This function should be the moral equivalent of:
1477-
//
1478-
// for item in iterator {
1479-
// vector.push(item);
1480-
// }
1481-
//
1482-
// This equivalent crucially runs the iterator precisely once. Below we
1483-
// actually in theory run the iterator twice (one without bounds checks
1484-
// and one with). To achieve the "moral equivalent", we use the `if`
1485-
// statement below to break out early.
1486-
//
1487-
// If the first loop has terminated, then we have one of two conditions.
1488-
//
1489-
// 1. The underlying iterator returned `None`. In this case we are
1490-
// guaranteed that less than `vector.capacity()` elements have been
1491-
// returned, so we break out early.
1492-
// 2. The underlying iterator yielded `vector.capacity()` elements and
1493-
// has not yielded `None` yet. In this case we run the iterator to
1494-
// its end below.
1495-
for element in iterator.by_ref().take(vector.capacity()) {
1496-
let len = vector.len();
1497-
unsafe {
1498-
ptr::write(vector.get_unchecked_mut(len), element);
1499-
vector.set_len(len + 1);
1500-
}
1501-
}
1502-
1503-
if vector.len() == vector.capacity() {
1504-
for element in iterator {
1505-
vector.push(element);
1479+
let mut vector = match iterator.next() {
1480+
None => return Vec::new(),
1481+
Some(element) => {
1482+
let (lower, _) = iterator.size_hint();
1483+
let mut vector = Vec::with_capacity(1 + lower);
1484+
unsafe {
1485+
ptr::write(vector.get_unchecked_mut(0), element);
1486+
vector.set_len(1);
1487+
}
1488+
vector
15061489
}
1507-
}
1490+
};
1491+
vector.extend_desugared(iterator);
15081492
vector
15091493
}
15101494
}
@@ -1569,11 +1553,27 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
15691553
impl<T> Extend<T> for Vec<T> {
15701554
#[inline]
15711555
fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
1572-
let iterator = iterable.into_iter();
1573-
let (lower, _) = iterator.size_hint();
1574-
self.reserve(lower);
1575-
for element in iterator {
1576-
self.push(element)
1556+
self.extend_desugared(iterable.into_iter())
1557+
}
1558+
}
1559+
1560+
impl<T> Vec<T> {
1561+
fn extend_desugared<I: Iterator<Item=T>>(&mut self, mut iterator: I) {
1562+
// This function should be the moral equivalent of:
1563+
//
1564+
// for item in iterator {
1565+
// self.push(item);
1566+
// }
1567+
while let Some(element) = iterator.next() {
1568+
let len = self.len();
1569+
if len == self.capacity() {
1570+
let (lower, _) = iterator.size_hint();
1571+
self.reserve(lower + 1);
1572+
}
1573+
unsafe {
1574+
ptr::write(self.get_unchecked_mut(len), element);
1575+
self.set_len(len + 1);
1576+
}
15771577
}
15781578
}
15791579
}

trunk/src/libcore/char.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,8 @@ pub const MAX: char = '\u{10ffff}';
7474
/// ```
7575
/// use std::char;
7676
///
77-
/// let c = char::from_u32(10084); // produces `Some(❤)`
78-
/// assert_eq!(c, Some('❤'));
79-
/// ```
80-
///
81-
/// An invalid character:
82-
///
83-
/// ```
84-
/// use std::char;
85-
///
86-
/// let none = char::from_u32(1114112);
87-
/// assert_eq!(none, None);
77+
/// assert_eq!(char::from_u32(0x2764), Some('❤'));
78+
/// assert_eq!(char::from_u32(0x110000), None); // invalid character
8879
/// ```
8980
#[inline]
9081
#[stable(feature = "rust1", since = "1.0.0")]

trunk/src/librustc/middle/check_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
285285
fn check_static_type(&self, e: &ast::Expr) {
286286
let ty = ty::node_id_to_type(self.tcx, e.id);
287287
let infcx = infer::new_infer_ctxt(self.tcx);
288-
let mut fulfill_cx = traits::FulfillmentContext::new();
288+
let mut fulfill_cx = traits::FulfillmentContext::new(false);
289289
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
290290
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
291291
let env = ty::empty_parameter_environment(self.tcx);

trunk/src/librustc/middle/dead.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
4848
struct_has_extern_repr: bool,
4949
ignore_non_const_paths: bool,
5050
inherited_pub_visibility: bool,
51+
ignore_variant_stack: Vec<ast::NodeId>,
5152
}
5253

5354
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@@ -60,6 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
6061
struct_has_extern_repr: false,
6162
ignore_non_const_paths: false,
6263
inherited_pub_visibility: false,
64+
ignore_variant_stack: vec![],
6365
}
6466
}
6567

@@ -80,7 +82,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
8082
def::DefPrimTy(_) => (),
8183
def::DefVariant(enum_id, variant_id, _) => {
8284
self.check_def_id(enum_id);
83-
self.check_def_id(variant_id);
85+
if !self.ignore_variant_stack.contains(&variant_id.node) {
86+
self.check_def_id(variant_id);
87+
}
8488
}
8589
_ => {
8690
self.check_def_id(def.def_id());
@@ -272,6 +276,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
272276
visit::walk_expr(self, expr);
273277
}
274278

279+
fn visit_arm(&mut self, arm: &ast::Arm) {
280+
if arm.pats.len() == 1 {
281+
let pat = &*arm.pats[0];
282+
let variants = pat_util::necessary_variants(&self.tcx.def_map, pat);
283+
284+
// Inside the body, ignore constructions of variants
285+
// necessary for the pattern to match. Those construction sites
286+
// can't be reached unless the variant is constructed elsewhere.
287+
let len = self.ignore_variant_stack.len();
288+
self.ignore_variant_stack.push_all(&*variants);
289+
visit::walk_arm(self, arm);
290+
self.ignore_variant_stack.truncate(len);
291+
} else {
292+
visit::walk_arm(self, arm);
293+
}
294+
}
295+
275296
fn visit_pat(&mut self, pat: &ast::Pat) {
276297
let def_map = &self.tcx.def_map;
277298
match pat.node {
@@ -393,6 +414,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
393414
worklist.push(*id);
394415
}
395416
for id in reachable_symbols {
417+
// Reachable variants can be dead, because we warn about
418+
// variants never constructed, not variants never used.
419+
if let Some(ast_map::NodeVariant(..)) = tcx.map.find(*id) {
420+
continue;
421+
}
396422
worklist.push(*id);
397423
}
398424

trunk/src/librustc/middle/pat_util.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,27 @@ pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
201201
span: DUMMY_SP,
202202
})
203203
}
204+
205+
/// Return variants that are necessary to exist for the pattern to match.
206+
pub fn necessary_variants(dm: &DefMap, pat: &ast::Pat) -> Vec<ast::NodeId> {
207+
let mut variants = vec![];
208+
walk_pat(pat, |p| {
209+
match p.node {
210+
ast::PatEnum(_, _) |
211+
ast::PatIdent(_, _, None) |
212+
ast::PatStruct(..) => {
213+
match dm.borrow().get(&p.id) {
214+
Some(&PathResolution { base_def: DefVariant(_, id, _), .. }) => {
215+
variants.push(id.node);
216+
}
217+
_ => ()
218+
}
219+
}
220+
_ => ()
221+
}
222+
true
223+
});
224+
variants.sort();
225+
variants.dedup();
226+
variants
227+
}

0 commit comments

Comments
 (0)