mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Auto merge of #31214 - Manishearth:rollup, r=Manishearth
- Successful merges: #31172, #31177, #31211 - Failed merges:
This commit is contained in:
commit
5d6e8fceda
@ -4252,13 +4252,15 @@ impl<A: Step> RangeFrom<A> {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```
|
||||||
/// for i in (0u8..).step_by(2) {
|
/// # #![feature(step_by)]
|
||||||
|
///
|
||||||
|
/// for i in (0u8..).step_by(2).take(10) {
|
||||||
/// println!("{}", i);
|
/// println!("{}", i);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// This prints all even `u8` values.
|
/// This prints the first ten even natural integers (0 to 18).
|
||||||
#[unstable(feature = "step_by", reason = "recent addition",
|
#[unstable(feature = "step_by", reason = "recent addition",
|
||||||
issue = "27741")]
|
issue = "27741")]
|
||||||
pub fn step_by(self, by: A) -> StepBy<A, Self> {
|
pub fn step_by(self, by: A) -> StepBy<A, Self> {
|
||||||
|
@ -112,7 +112,7 @@ impl<W: io::Write> io::Write for Maybe<W> {
|
|||||||
impl<R: io::Read> io::Read for Maybe<R> {
|
impl<R: io::Read> io::Read for Maybe<R> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
match *self {
|
match *self {
|
||||||
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), buf.len()),
|
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), 0),
|
||||||
Maybe::Fake => Ok(0)
|
Maybe::Fake => Ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,10 +351,15 @@ fn make_dirp(d: Option<&OsString>) -> (*const u16, Vec<u16>) {
|
|||||||
impl Stdio {
|
impl Stdio {
|
||||||
fn to_handle(&self, stdio_id: c::DWORD) -> io::Result<Handle> {
|
fn to_handle(&self, stdio_id: c::DWORD) -> io::Result<Handle> {
|
||||||
match *self {
|
match *self {
|
||||||
|
// If no stdio handle is available, then inherit means that it
|
||||||
|
// should still be unavailable so propagate the
|
||||||
|
// INVALID_HANDLE_VALUE.
|
||||||
Stdio::Inherit => {
|
Stdio::Inherit => {
|
||||||
stdio::get(stdio_id).and_then(|io| {
|
match stdio::get(stdio_id) {
|
||||||
io.handle().duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
|
Ok(io) => io.handle().duplicate(0, true,
|
||||||
})
|
c::DUPLICATE_SAME_ACCESS),
|
||||||
|
Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Stdio::Raw(handle) => {
|
Stdio::Raw(handle) => {
|
||||||
RawHandle::new(handle).duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
|
RawHandle::new(handle).duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
use self::Destination::*;
|
use self::Destination::*;
|
||||||
|
|
||||||
use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span};
|
use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, DUMMY_SP, Pos, Span};
|
||||||
use diagnostics;
|
use diagnostics;
|
||||||
|
|
||||||
use errors::{Level, RenderSpan, DiagnosticBuilder};
|
use errors::{Level, RenderSpan, DiagnosticBuilder};
|
||||||
@ -109,8 +109,8 @@ impl Emitter for EmitterWriter {
|
|||||||
lvl: Level) {
|
lvl: Level) {
|
||||||
let error = match sp {
|
let error = match sp {
|
||||||
Some(COMMAND_LINE_SP) => self.emit_(FileLine(COMMAND_LINE_SP), msg, code, lvl),
|
Some(COMMAND_LINE_SP) => self.emit_(FileLine(COMMAND_LINE_SP), msg, code, lvl),
|
||||||
|
Some(DUMMY_SP) | None => print_diagnostic(&mut self.dst, "", lvl, msg, code),
|
||||||
Some(sp) => self.emit_(FullSpan(sp), msg, code, lvl),
|
Some(sp) => self.emit_(FullSpan(sp), msg, code, lvl),
|
||||||
None => print_diagnostic(&mut self.dst, "", lvl, msg, code),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = error {
|
if let Err(e) = error {
|
||||||
|
@ -2218,6 +2218,12 @@ impl<'a> Parser<'a> {
|
|||||||
ex = ExprBreak(None);
|
ex = ExprBreak(None);
|
||||||
}
|
}
|
||||||
hi = self.last_span.hi;
|
hi = self.last_span.hi;
|
||||||
|
} else if self.token.is_keyword(keywords::Let) {
|
||||||
|
// Catch this syntax error here, instead of in `check_strict_keywords`, so
|
||||||
|
// that we can explicitly mention that let is not to be used as an expression
|
||||||
|
let mut db = self.fatal("expected expression, found statement (`let`)");
|
||||||
|
db.note("variable declaration using `let` is a statement");
|
||||||
|
return Err(db);
|
||||||
} else if self.check(&token::ModSep) ||
|
} else if self.check(&token::ModSep) ||
|
||||||
self.token.is_ident() &&
|
self.token.is_ident() &&
|
||||||
!self.check_keyword(keywords::True) &&
|
!self.check_keyword(keywords::True) &&
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// ignore-cross-compile
|
// ignore-cross-compile
|
||||||
|
|
||||||
// error-pattern:expected identifier, found keyword `let`
|
// error-pattern:expected expression, found statement (`let`)
|
||||||
|
|
||||||
#![feature(quote, rustc_private)]
|
#![feature(quote, rustc_private)]
|
||||||
|
|
||||||
|
124
src/test/run-pass/no-stdio.rs
Normal file
124
src/test/run-pass/no-stdio.rs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#![feature(libc)]
|
||||||
|
|
||||||
|
extern crate libc;
|
||||||
|
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
use std::env;
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R {
|
||||||
|
let doit = |a| {
|
||||||
|
let r = libc::dup(a);
|
||||||
|
assert!(r >= 0);
|
||||||
|
return r
|
||||||
|
};
|
||||||
|
let a = doit(0);
|
||||||
|
let b = doit(1);
|
||||||
|
let c = doit(2);
|
||||||
|
|
||||||
|
assert!(libc::close(0) >= 0);
|
||||||
|
assert!(libc::close(1) >= 0);
|
||||||
|
assert!(libc::close(2) >= 0);
|
||||||
|
|
||||||
|
let r = f();
|
||||||
|
|
||||||
|
assert!(libc::dup2(a, 0) >= 0);
|
||||||
|
assert!(libc::dup2(b, 1) >= 0);
|
||||||
|
assert!(libc::dup2(c, 2) >= 0);
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R {
|
||||||
|
type DWORD = u32;
|
||||||
|
type HANDLE = *mut u8;
|
||||||
|
type BOOL = i32;
|
||||||
|
|
||||||
|
const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
|
||||||
|
const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
|
||||||
|
const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
|
||||||
|
const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
|
||||||
|
|
||||||
|
extern "system" {
|
||||||
|
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||||
|
fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
let doit = |id| {
|
||||||
|
let handle = GetStdHandle(id);
|
||||||
|
assert!(handle != INVALID_HANDLE_VALUE);
|
||||||
|
assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0);
|
||||||
|
return handle
|
||||||
|
};
|
||||||
|
|
||||||
|
let a = doit(STD_INPUT_HANDLE);
|
||||||
|
let b = doit(STD_OUTPUT_HANDLE);
|
||||||
|
let c = doit(STD_ERROR_HANDLE);
|
||||||
|
|
||||||
|
let r = f();
|
||||||
|
|
||||||
|
let doit = |id, handle| {
|
||||||
|
assert!(SetStdHandle(id, handle) != 0);
|
||||||
|
};
|
||||||
|
doit(STD_INPUT_HANDLE, a);
|
||||||
|
doit(STD_OUTPUT_HANDLE, b);
|
||||||
|
doit(STD_ERROR_HANDLE, c);
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if env::args().len() > 1 {
|
||||||
|
println!("test");
|
||||||
|
assert!(io::stdout().write(b"test\n").is_ok());
|
||||||
|
assert!(io::stderr().write(b"test\n").is_ok());
|
||||||
|
assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, make sure reads/writes without stdio work if stdio itself is
|
||||||
|
// missing.
|
||||||
|
let (a, b, c) = unsafe {
|
||||||
|
without_stdio(|| {
|
||||||
|
let a = io::stdout().write(b"test\n");
|
||||||
|
let b = io::stderr().write(b"test\n");
|
||||||
|
let c = io::stdin().read(&mut [0; 10]);
|
||||||
|
|
||||||
|
(a, b, c)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(a.unwrap(), 5);
|
||||||
|
assert_eq!(b.unwrap(), 5);
|
||||||
|
assert_eq!(c.unwrap(), 0);
|
||||||
|
|
||||||
|
// Second, spawn a child and do some work with "null" descriptors to make
|
||||||
|
// sure it's ok
|
||||||
|
let me = env::current_exe().unwrap();
|
||||||
|
let status = Command::new(&me)
|
||||||
|
.arg("next")
|
||||||
|
.stdin(Stdio::null())
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.status().unwrap();
|
||||||
|
assert!(status.success(), "{:?} isn't a success", status);
|
||||||
|
|
||||||
|
// Finally, close everything then spawn a child to make sure everything is
|
||||||
|
// *still* ok.
|
||||||
|
let status = unsafe {
|
||||||
|
without_stdio(|| Command::new(&me).arg("next").status())
|
||||||
|
}.unwrap();
|
||||||
|
assert!(status.success(), "{:?} isn't a success", status);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user