Skip to content

Commit c62ae87

Browse files
committed
Auto merge of #23206 - nagisa:print-io, r=alexcrichton
r? @alexcrichton or @aturon This still needs to somehow figure out how to avoid unstable warnings arising from the use of unstable functions. I tried to use `#[allow_internal_unstable]` but it still spits out warnings as far as I can see. @huonw (I think you implemented it) does `#[allow_internal_unstable]` not work for some reason or am I using it incorrectly?
2 parents 542e2bb + 6e92f05 commit c62ae87

File tree

8 files changed

+62
-57
lines changed

8 files changed

+62
-57
lines changed

src/librustc_driver/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#![feature(staged_api)]
3838
#![feature(exit_status)]
3939
#![feature(io)]
40-
#![feature(set_panic)]
40+
#![feature(set_stdio)]
4141

4242
extern crate arena;
4343
extern crate flate;

src/librustdoc/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#![feature(core)]
2727
#![feature(exit_status)]
2828
#![feature(int_uint)]
29-
#![feature(set_panic)]
29+
#![feature(set_stdio)]
3030
#![feature(libc)]
3131
#![feature(old_path)]
3232
#![feature(rustc_private)]

src/libstd/io/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ pub use self::buffered::IntoInnerError;
3333
pub use self::cursor::Cursor;
3434
pub use self::error::{Result, Error, ErrorKind};
3535
pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
36-
pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
36+
pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
3737
pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
3838
#[doc(no_inline, hidden)]
39-
pub use self::stdio::set_panic;
39+
pub use self::stdio::{set_panic, set_print};
4040

4141
#[macro_use] mod lazy;
4242

src/libstd/io/stdio.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,21 @@
1111
use prelude::v1::*;
1212
use io::prelude::*;
1313

14+
use cell::RefCell;
1415
use cmp;
1516
use fmt;
1617
use io::lazy::Lazy;
1718
use io::{self, BufReader, LineWriter};
1819
use sync::{Arc, Mutex, MutexGuard};
1920
use sys::stdio;
2021

22+
/// Stdout used by print! and println! macroses
23+
thread_local! {
24+
static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
25+
RefCell::new(None)
26+
}
27+
}
28+
2129
/// A handle to a raw instance of the standard input stream of this process.
2230
///
2331
/// This handle is not synchronized or buffered in any fashion. Constructed via
@@ -338,15 +346,15 @@ impl<'a> Write for StderrLock<'a> {
338346
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
339347
}
340348

341-
/// Resets the task-local stdout handle to the specified writer
349+
/// Resets the task-local stderr handle to the specified writer
342350
///
343-
/// This will replace the current task's stdout handle, returning the old
344-
/// handle. All future calls to `print` and friends will emit their output to
351+
/// This will replace the current task's stderr handle, returning the old
352+
/// handle. All future calls to `panic!` and friends will emit their output to
345353
/// this specified handle.
346354
///
347355
/// Note that this does not need to be called for all new tasks; the default
348-
/// output handle is to the process's stdout stream.
349-
#[unstable(feature = "set_panic",
356+
/// output handle is to the process's stderr stream.
357+
#[unstable(feature = "set_stdio",
350358
reason = "this function may disappear completely or be replaced \
351359
with a more general mechanism")]
352360
#[doc(hidden)]
@@ -360,3 +368,37 @@ pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
360368
Some(s)
361369
})
362370
}
371+
372+
/// Resets the task-local stdout handle to the specified writer
373+
///
374+
/// This will replace the current task's stdout handle, returning the old
375+
/// handle. All future calls to `print!` and friends will emit their output to
376+
/// this specified handle.
377+
///
378+
/// Note that this does not need to be called for all new tasks; the default
379+
/// output handle is to the process's stdout stream.
380+
#[unstable(feature = "set_stdio",
381+
reason = "this function may disappear completely or be replaced \
382+
with a more general mechanism")]
383+
#[doc(hidden)]
384+
pub fn set_print(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
385+
use mem;
386+
LOCAL_STDOUT.with(move |slot| {
387+
mem::replace(&mut *slot.borrow_mut(), Some(sink))
388+
}).and_then(|mut s| {
389+
let _ = s.flush();
390+
Some(s)
391+
})
392+
}
393+
394+
#[unstable(feature = "print",
395+
reason = "implementation detail which may disappear or be replaced at any time")]
396+
#[doc(hidden)]
397+
pub fn _print(args: fmt::Arguments) {
398+
if let Err(e) = LOCAL_STDOUT.with(|s| match s.borrow_mut().as_mut() {
399+
Some(w) => w.write_fmt(args),
400+
None => stdout().write_fmt(args)
401+
}) {
402+
panic!("failed printing to stdout: {}", e);
403+
}
404+
}

src/libstd/macros.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,21 @@ macro_rules! panic {
6060
});
6161
}
6262

63+
/// Macro for printing to the standard output.
64+
///
6365
/// Equivalent to the `println!` macro except that a newline is not printed at
6466
/// the end of the message.
6567
#[macro_export]
6668
#[stable(feature = "rust1", since = "1.0.0")]
69+
#[allow_internal_unstable]
6770
macro_rules! print {
68-
($($arg:tt)*) => ($crate::old_io::stdio::print_args(format_args!($($arg)*)))
71+
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
6972
}
7073

71-
/// Macro for printing to a task's stdout handle.
74+
/// Macro for printing to the standard output.
7275
///
73-
/// Each task can override its stdout handle via `std::old_io::stdio::set_stdout`.
74-
/// The syntax of this macro is the same as that used for `format!`. For more
75-
/// information, see `std::fmt` and `std::old_io::stdio`.
76+
/// Use the `format!` syntax to write data to the standard output.
77+
/// See `std::fmt` for more information.
7678
///
7779
/// # Examples
7880
///
@@ -83,7 +85,8 @@ macro_rules! print {
8385
#[macro_export]
8486
#[stable(feature = "rust1", since = "1.0.0")]
8587
macro_rules! println {
86-
($($arg:tt)*) => ($crate::old_io::stdio::println_args(format_args!($($arg)*)))
88+
($fmt:expr) => (print!(concat!($fmt, "\n")));
89+
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
8790
}
8891

8992
/// Helper macro for unwrapping `Result` values while returning early with an

src/libstd/old_io/stdio.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -535,18 +535,4 @@ mod tests {
535535
stdout();
536536
stderr();
537537
}
538-
539-
#[test]
540-
fn capture_stdout() {
541-
use old_io::{ChanReader, ChanWriter};
542-
543-
let (tx, rx) = channel();
544-
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
545-
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
546-
let _t = thread::spawn(move|| {
547-
set_stdout(Box::new(w));
548-
println!("hello!");
549-
});
550-
assert_eq!(r.read_to_string().unwrap(), "hello!\n");
551-
}
552538
}

src/libtest/lib.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,12 @@
3939
#![feature(collections)]
4040
#![feature(core)]
4141
#![feature(int_uint)]
42-
#![feature(old_io)]
4342
#![feature(rustc_private)]
4443
#![feature(staged_api)]
4544
#![feature(std_misc)]
4645
#![feature(io)]
4746
#![feature(libc)]
48-
#![feature(set_panic)]
47+
#![feature(set_stdio)]
4948

5049
extern crate getopts;
5150
extern crate serialize;
@@ -908,7 +907,6 @@ pub fn run_test(opts: &TestOpts,
908907
return;
909908
}
910909

911-
#[allow(deprecated)] // set_stdout
912910
fn run_test_inner(desc: TestDesc,
913911
monitor_ch: Sender<MonitorMsg>,
914912
nocapture: bool,
@@ -920,11 +918,6 @@ pub fn run_test(opts: &TestOpts,
920918
}
921919
fn flush(&mut self) -> io::Result<()> { Ok(()) }
922920
}
923-
impl Writer for Sink {
924-
fn write_all(&mut self, data: &[u8]) -> std::old_io::IoResult<()> {
925-
Writer::write_all(&mut *self.0.lock().unwrap(), data)
926-
}
927-
}
928921

929922
thread::spawn(move || {
930923
let data = Arc::new(Mutex::new(Vec::new()));
@@ -936,7 +929,7 @@ pub fn run_test(opts: &TestOpts,
936929

937930
let result_guard = cfg.spawn(move || {
938931
if !nocapture {
939-
std::old_io::stdio::set_stdout(box Sink(data2.clone()));
932+
io::set_print(box Sink(data2.clone()));
940933
io::set_panic(box Sink(data2));
941934
}
942935
testfn.invoke(())

src/libtest/stats.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
#![allow(missing_docs)]
1212

1313
use std::cmp::Ordering::{self, Less, Greater, Equal};
14-
use std::collections::hash_map::Entry::{Occupied, Vacant};
15-
use std::collections::hash_map;
16-
use std::hash::Hash;
1714
use std::mem;
1815
use std::num::{Float, FromPrimitive};
1916

@@ -330,22 +327,6 @@ pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
330327
}
331328
}
332329

333-
/// Returns a HashMap with the number of occurrences of every element in the
334-
/// sequence that the iterator exposes.
335-
#[cfg(not(stage0))]
336-
pub fn freq_count<T, U>(iter: T) -> hash_map::HashMap<U, uint>
337-
where T: Iterator<Item=U>, U: Eq + Clone + Hash
338-
{
339-
let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
340-
for elem in iter {
341-
match map.entry(elem) {
342-
Occupied(mut entry) => { *entry.get_mut() += 1; },
343-
Vacant(entry) => { entry.insert(1); },
344-
}
345-
}
346-
map
347-
}
348-
349330
// Test vectors generated from R, using the script src/etc/stat-test-vectors.r.
350331

351332
#[cfg(test)]

0 commit comments

Comments
 (0)