diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 521b938acfb7e..d460f72b8ec48 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -250,6 +250,7 @@ #![feature(const_fn)] #![feature(core_float)] #![feature(core_intrinsics)] +#![feature(decode_utf8)] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] #![feature(float_extras)] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 3f9bf70adde22..a7c7d3e7ef3fa 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -108,6 +108,7 @@ use ascii::*; use borrow::{Borrow, Cow}; +use char; use cmp; use error::Error; use fmt; @@ -2018,7 +2019,15 @@ impl<'a> fmt::Debug for Display<'a> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> fmt::Display for Display<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.path.to_string_lossy(), f) + let replacement = '\u{fffd}'; + let bytes = self.path.as_u8_slice().iter().cloned(); + + for r in char::decode_utf8(bytes) { + let c = r.unwrap_or(replacement); + fmt::Write::write_char(f, c)?; + } + + Ok(()) } } @@ -3595,4 +3604,21 @@ mod tests { let actual = format!("{:?}", iter); assert_eq!(expected, actual); } + + #[test] + fn test_unicode_conversion() { + let replacement = '\u{fffd}'; + + let b = [0xff]; + let path = unsafe { Path::from_u8_slice(&b) }; + assert_eq!(format!("{}", replacement), format!("{}", path.display())); + + let b = [0xff, b'A']; + let path = unsafe { Path::from_u8_slice(&b) }; + assert_eq!(format!("{}{}", replacement, 'A'), format!("{}", path.display())); + + let b = [b'A', 0xff]; + let path = unsafe { Path::from_u8_slice(&b) }; + assert_eq!(format!("{}{}", 'A', replacement), format!("{}", path.display())); + } }