Skip to content

Commit 6a3f289

Browse files
committed
---
yaml --- r: 151501 b: refs/heads/try2 c: 3d6cf1d h: refs/heads/master i: 151499: 878a154 v: v3
1 parent 79eab5f commit 6a3f289

File tree

9 files changed

+109
-46
lines changed

9 files changed

+109
-46
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: ed7c8490572c8eaacfe2acf459660bd9003e1ba4
8+
refs/heads/try2: 3d6cf1d52558479d27355af162895c2a16c4d800
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/doc/rust.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,10 +1741,10 @@ import public items from their destination, not private items.
17411741
## Attributes
17421742

17431743
~~~~ {.notrust .ebnf .gram}
1744-
attribute : '#' '!' ? '[' attr_list ']' ;
1745-
attr_list : attr [ ',' attr_list ]* ;
1746-
attr : ident [ '=' literal
1747-
| '(' attr_list ')' ] ? ;
1744+
attribute : '#' '!' ? '[' meta_item ']' ;
1745+
meta_item : ident [ '=' literal
1746+
| '(' meta_seq ')' ] ? ;
1747+
meta_seq : meta_item [ ',' meta_seq ]* ;
17481748
~~~~
17491749

17501750
Static entities in Rust — crates, modules and items — may have _attributes_

branches/try2/src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ mod should_not_exist;
106106
mod std {
107107
pub use clone;
108108
pub use cmp;
109+
pub use kinds;
109110

110111
#[cfg(test)] pub use realstd::fmt; // needed for fail!()
111112
#[cfg(test)] pub use realstd::rt; // needed for fail!()

branches/try2/src/librustc/middle/lint.rs

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,28 +1367,38 @@ fn check_unsafe_block(cx: &Context, e: &ast::Expr) {
13671367
}
13681368
}
13691369

1370-
fn check_unused_mut_pat(cx: &Context, p: &ast::Pat) {
1371-
match p.node {
1372-
ast::PatIdent(ast::BindByValue(ast::MutMutable),
1373-
ref path, _) if pat_util::pat_is_binding(&cx.tcx.def_map, p) => {
1374-
// `let mut _a = 1;` doesn't need a warning.
1375-
let initial_underscore = if path.segments.len() == 1 {
1376-
token::get_ident(path.segments
1377-
.get(0)
1378-
.identifier).get().starts_with("_")
1379-
} else {
1380-
cx.tcx.sess.span_bug(p.span,
1381-
"mutable binding that doesn't consist \
1382-
of exactly one segment")
1383-
};
1384-
1385-
if !initial_underscore &&
1386-
!cx.tcx.used_mut_nodes.borrow().contains(&p.id) {
1387-
cx.span_lint(UnusedMut, p.span,
1388-
"variable does not need to be mutable");
1370+
fn check_unused_mut_pat(cx: &Context, pats: &[@ast::Pat]) {
1371+
// collect all mutable pattern and group their NodeIDs by their Identifier to
1372+
// avoid false warnings in match arms with multiple patterns
1373+
let mut mutables = HashMap::new();
1374+
for &p in pats.iter() {
1375+
pat_util::pat_bindings(&cx.tcx.def_map, p, |mode, id, _, path| {
1376+
match mode {
1377+
ast::BindByValue(ast::MutMutable) => {
1378+
if path.segments.len() != 1 {
1379+
cx.tcx.sess.span_bug(p.span,
1380+
"mutable binding that doesn't consist \
1381+
of exactly one segment");
1382+
}
1383+
let ident = path.segments.get(0).identifier;
1384+
if !token::get_ident(ident).get().starts_with("_") {
1385+
mutables.insert_or_update_with(ident.name as uint, vec!(id), |_, old| {
1386+
old.push(id);
1387+
});
1388+
}
1389+
}
1390+
_ => {
1391+
}
13891392
}
1393+
});
1394+
}
1395+
1396+
let used_mutables = cx.tcx.used_mut_nodes.borrow();
1397+
for (_, v) in mutables.iter() {
1398+
if !v.iter().any(|e| used_mutables.contains(e)) {
1399+
cx.span_lint(UnusedMut, cx.tcx.map.span(*v.get(0)),
1400+
"variable does not need to be mutable");
13901401
}
1391-
_ => ()
13921402
}
13931403
}
13941404

@@ -1684,7 +1694,6 @@ impl<'a> Visitor<()> for Context<'a> {
16841694
fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
16851695
check_pat_non_uppercase_statics(self, p);
16861696
check_pat_uppercase_variable(self, p);
1687-
check_unused_mut_pat(self, p);
16881697

16891698
visit::walk_pat(self, p, ());
16901699
}
@@ -1700,6 +1709,11 @@ impl<'a> Visitor<()> for Context<'a> {
17001709
ast::ExprParen(expr) => if self.negated_expr_id == e.id {
17011710
self.negated_expr_id = expr.id
17021711
},
1712+
ast::ExprMatch(_, ref arms) => {
1713+
for a in arms.iter() {
1714+
check_unused_mut_pat(self, a.pats.as_slice());
1715+
}
1716+
},
17031717
_ => ()
17041718
};
17051719

@@ -1723,6 +1737,18 @@ impl<'a> Visitor<()> for Context<'a> {
17231737
check_unused_result(self, s);
17241738
check_unnecessary_parens_stmt(self, s);
17251739

1740+
match s.node {
1741+
ast::StmtDecl(d, _) => {
1742+
match d.node {
1743+
ast::DeclLocal(l) => {
1744+
check_unused_mut_pat(self, &[l.pat]);
1745+
},
1746+
_ => {}
1747+
}
1748+
},
1749+
_ => {}
1750+
}
1751+
17261752
visit::walk_stmt(self, s, ());
17271753
}
17281754

@@ -1732,6 +1758,10 @@ impl<'a> Visitor<()> for Context<'a> {
17321758
visit::walk_fn(this, fk, decl, body, span, id, ());
17331759
};
17341760

1761+
for a in decl.inputs.iter(){
1762+
check_unused_mut_pat(self, &[a.pat]);
1763+
}
1764+
17351765
match *fk {
17361766
visit::FkMethod(_, _, m) => {
17371767
self.with_lint_attrs(m.attrs.as_slice(), |cx| {

branches/try2/src/libstd/io/net/tcp.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ impl TcpStream {
169169
///
170170
/// For clarification on the semantics of interrupting a read and a write,
171171
/// take a look at `set_read_timeout` and `set_write_timeout`.
172+
#[experimental = "the timeout argument may change in type and value"]
172173
pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
173174
self.obj.set_timeout(timeout_ms)
174175
}
@@ -185,6 +186,7 @@ impl TcpStream {
185186
/// action is taken. Otherwise, the read operation will be scheduled to
186187
/// promptly return. If a timeout error is returned, then no data was read
187188
/// during the timeout period.
189+
#[experimental = "the timeout argument may change in type and value"]
188190
pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
189191
self.obj.set_read_timeout(timeout_ms)
190192
}
@@ -211,6 +213,7 @@ impl TcpStream {
211213
/// does not know how many bytes were written as part of the timeout
212214
/// operation. It may be the case that bytes continue to be written in an
213215
/// asynchronous fashion after the call to write returns.
216+
#[experimental = "the timeout argument may change in type and value"]
214217
pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
215218
self.obj.set_write_timeout(timeout_ms)
216219
}
@@ -944,21 +947,26 @@ mod test {
944947

945948
// Also make sure that even though the timeout is expired that we will
946949
// continue to receive any pending connections.
947-
let (tx, rx) = channel();
948-
spawn(proc() {
949-
tx.send(TcpStream::connect(addr).unwrap());
950-
});
951-
let l = rx.recv();
952-
for i in range(0, 1001) {
953-
match a.accept() {
954-
Ok(..) => break,
955-
Err(ref e) if e.kind == TimedOut => {}
956-
Err(e) => fail!("error: {}", e),
950+
//
951+
// FIXME: freebsd apparently never sees the pending connection, but
952+
// testing manually always works. Need to investigate this
953+
// flakiness.
954+
if !cfg!(target_os = "freebsd") {
955+
let (tx, rx) = channel();
956+
spawn(proc() {
957+
tx.send(TcpStream::connect(addr).unwrap());
958+
});
959+
let l = rx.recv();
960+
for i in range(0, 1001) {
961+
match a.accept() {
962+
Ok(..) => break,
963+
Err(ref e) if e.kind == TimedOut => {}
964+
Err(e) => fail!("error: {}", e),
965+
}
966+
::task::deschedule();
967+
if i == 1000 { fail!("should have a pending connection") }
957968
}
958-
::task::deschedule();
959-
if i == 1000 { fail!("should have a pending connection") }
960969
}
961-
drop(l);
962970

963971
// Unset the timeout and make sure that this always blocks.
964972
a.set_timeout(None);

branches/try2/src/libstd/io/net/udp.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,20 +147,23 @@ impl UdpSocket {
147147
/// Sets the read/write timeout for this socket.
148148
///
149149
/// For more information, see `TcpStream::set_timeout`
150+
#[experimental = "the timeout argument may change in type and value"]
150151
pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
151152
self.obj.set_timeout(timeout_ms)
152153
}
153154

154155
/// Sets the read timeout for this socket.
155156
///
156157
/// For more information, see `TcpStream::set_timeout`
158+
#[experimental = "the timeout argument may change in type and value"]
157159
pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
158160
self.obj.set_read_timeout(timeout_ms)
159161
}
160162

161163
/// Sets the write timeout for this socket.
162164
///
163165
/// For more information, see `TcpStream::set_timeout`
166+
#[experimental = "the timeout argument may change in type and value"]
164167
pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
165168
self.obj.set_write_timeout(timeout_ms)
166169
}

branches/try2/src/libstd/io/net/unix.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,20 +97,23 @@ impl UnixStream {
9797
/// Sets the read/write timeout for this socket.
9898
///
9999
/// For more information, see `TcpStream::set_timeout`
100+
#[experimental = "the timeout argument may change in type and value"]
100101
pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
101102
self.obj.set_timeout(timeout_ms)
102103
}
103104

104105
/// Sets the read timeout for this socket.
105106
///
106107
/// For more information, see `TcpStream::set_timeout`
108+
#[experimental = "the timeout argument may change in type and value"]
107109
pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
108110
self.obj.set_read_timeout(timeout_ms)
109111
}
110112

111113
/// Sets the write timeout for this socket.
112114
///
113115
/// For more information, see `TcpStream::set_timeout`
116+
#[experimental = "the timeout argument may change in type and value"]
114117
pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
115118
self.obj.set_write_timeout(timeout_ms)
116119
}

branches/try2/src/libstd/os.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,9 @@ pub fn homedir() -> Option<Path> {
529529
* Returns the path to a temporary directory.
530530
*
531531
* On Unix, returns the value of the 'TMPDIR' environment variable if it is
532-
* set and non-empty and '/tmp' otherwise.
533-
* On Android, there is no global temporary folder (it is usually allocated
534-
* per-app), hence returns '/data/tmp' which is commonly used.
532+
* set, otherwise for non-Android it returns '/tmp'. If Android, since there
533+
* is no global temporary folder (it is usually allocated per-app), we return
534+
* '/data/local/tmp'.
535535
*
536536
* On Windows, returns the value of, in order, the 'TMP', 'TEMP',
537537
* 'USERPROFILE' environment variable if any are set and not the empty
@@ -554,11 +554,13 @@ pub fn tmpdir() -> Path {
554554

555555
#[cfg(unix)]
556556
fn lookup() -> Path {
557-
if cfg!(target_os = "android") {
558-
Path::new("/data/tmp")
557+
let default = if cfg!(target_os = "android") {
558+
Path::new("/data/local/tmp")
559559
} else {
560-
getenv_nonempty("TMPDIR").unwrap_or(Path::new("/tmp"))
561-
}
560+
Path::new("/tmp")
561+
};
562+
563+
getenv_nonempty("TMPDIR").unwrap_or(default)
562564
}
563565

564566
#[cfg(windows)]

branches/try2/src/test/compile-fail/lint-unused-mut-variables.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ fn main() {
2828
match 30 {
2929
mut x => {} //~ ERROR: variable does not need to be mutable
3030
}
31+
match (30, 2) {
32+
(mut x, 1) | //~ ERROR: variable does not need to be mutable
33+
(mut x, 2) |
34+
(mut x, 3) => {
35+
}
36+
_ => {}
37+
}
3138

3239
let x = |mut y: int| 10; //~ ERROR: variable does not need to be mutable
3340
fn what(mut foo: int) {} //~ ERROR: variable does not need to be mutable
@@ -50,6 +57,15 @@ fn main() {
5057
}
5158
}
5259

60+
match (30, 2) {
61+
(mut x, 1) |
62+
(mut x, 2) |
63+
(mut x, 3) => {
64+
x = 21
65+
}
66+
_ => {}
67+
}
68+
5369
let x = |mut y: int| y = 32;
5470
fn nothing(mut foo: int) { foo = 37; }
5571

0 commit comments

Comments
 (0)