diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 79b2bbce2af7c..f0c63a2eb55d5 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -297,6 +297,34 @@ impl str { /// [`str::from_utf8_mut`] function. /// /// [`str::from_utf8_mut`]: ./str/fn.from_utf8_mut.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = String::from("Hello"); + /// let bytes = unsafe { s.as_bytes_mut() }; + /// + /// assert_eq!(b"Hello", bytes); + /// ``` + /// + /// Mutability: + /// + /// ``` + /// let mut s = String::from("🗻∈🌏"); + /// + /// unsafe { + /// let bytes = s.as_bytes_mut(); + /// + /// bytes[0] = 0xF0; + /// bytes[1] = 0x9F; + /// bytes[2] = 0x8D; + /// bytes[3] = 0x94; + /// } + /// + /// assert_eq!("🍔∈🌏", s); + /// ``` #[stable(feature = "str_mut_extras", since = "1.20.0")] #[inline(always)] pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { @@ -362,16 +390,25 @@ impl str { /// # Examples /// /// ``` - /// let mut v = String::from("🗻∈🌏"); - /// - /// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v)); - /// - /// // indices not on UTF-8 sequence boundaries - /// assert!(v.get_mut(1..).is_none()); - /// assert!(v.get_mut(..8).is_none()); + /// use std::ascii::AsciiExt; /// + /// let mut v = String::from("hello"); + /// // correct length + /// assert!(v.get_mut(0..5).is_some()); /// // out of bounds /// assert!(v.get_mut(..42).is_none()); + /// assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v)); + /// + /// assert_eq!("hello", v); + /// { + /// let s = v.get_mut(0..2); + /// let s = s.map(|s| { + /// s.make_ascii_uppercase(); + /// &*s + /// }); + /// assert_eq!(Some("HE"), s); + /// } + /// assert_eq!("HEllo", v); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[inline] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index ddb23b2ef37bf..1708f3e398756 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -743,6 +743,16 @@ impl String { } /// Extracts a string slice containing the entire string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = String::from("foo"); + /// + /// assert_eq!("foo", s.as_str()); + /// ``` #[inline] #[stable(feature = "string_as_str", since = "1.7.0")] pub fn as_str(&self) -> &str { diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 1defe308713a7..599d79104c3b0 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -221,7 +221,7 @@ mod platform { } } - #[cfg(any(target_os = "android", target_os = "redox"))] + #[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { // On android we currently target API level 9 which unfortunately @@ -244,7 +244,7 @@ mod platform { libc::memalign(layout.align(), layout.size()) as *mut u8 } - #[cfg(not(any(target_os = "android", target_os = "redox")))] + #[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 6b9281d2b2f0e..38ffaf97aa418 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 6b9281d2b2f0ebb94838814b1e8ace2de4b7035b +Subproject commit 38ffaf97aa418cc369ca0197a72a0b927cc0f622 diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 0f42a244a1ff9..3e802c8be5bf4 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -383,16 +383,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { }; let msg_str = Symbol::intern(str).as_str(); let msg_str = C_str_slice(bcx.ccx, msg_str); - let msg_file_line = C_struct(bcx.ccx, - &[msg_str, filename, line], + let msg_file_line_col = C_struct(bcx.ccx, + &[msg_str, filename, line, col], false); - let align = llalign_of_min(bcx.ccx, common::val_ty(msg_file_line)); - let msg_file_line = consts::addr_of(bcx.ccx, - msg_file_line, - align, - "panic_loc"); + let align = llalign_of_min(bcx.ccx, common::val_ty(msg_file_line_col)); + let msg_file_line_col = consts::addr_of(bcx.ccx, + msg_file_line_col, + align, + "panic_loc"); (lang_items::PanicFnLangItem, - vec![msg_file_line], + vec![msg_file_line_col], None) } }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0a8d2129a890d..8ddfb5b3050b0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1554,9 +1554,12 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let repr_type_ty = def.repr.discr_type().to_ty(tcx); if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 { - if !tcx.sess.features.borrow().i128_type { + if !tcx.sess.features.borrow().repr128 { emit_feature_err(&tcx.sess.parse_sess, - "i128_type", sp, GateIssue::Language, "128-bit type is unstable"); + "repr128", + sp, + GateIssue::Language, + "repr with 128-bit type is unstable"); } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 46bb119cf9c9d..49d4bd2324033 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -606,12 +606,20 @@ pub fn run(mut krate: clean::Crate, } // A short, single-line view of `s`. -fn concise_str(s: &str) -> String { +fn concise_str(mut s: &str) -> String { if s.contains('\n') { - return format!("{}...", s.lines().next().expect("Impossible! We just found a newline")); + s = s.lines().next().expect("Impossible! We just found a newline"); } if s.len() > 70 { - return format!("{} ... {}", &s[..50], &s[s.len()-20..]); + let mut lo = 50; + let mut hi = s.len() - 20; + while !s.is_char_boundary(lo) { + lo -= 1; + } + while !s.is_char_boundary(hi) { + hi += 1; + } + return format!("{} ... {}", &s[..lo], &s[hi..]); } s.to_owned() } @@ -660,9 +668,13 @@ fn render_difference(diff: &html_diff::Difference) { elem.path, elem.element_name, elem_attributes, opposite_elem_attributes); } html_diff::Difference::NodeText { ref elem, ref elem_text, ref opposite_elem_text, .. } => { - let (s1, s2) = concise_compared_strs(elem_text, opposite_elem_text); - println!(" {} Text differs:\n expected: `{}`\n found: `{}`", - elem.path, s1, s2); + if elem_text.split("\n") + .zip(opposite_elem_text.split("\n")) + .any(|(a, b)| a.trim() != b.trim()) { + let (s1, s2) = concise_compared_strs(elem_text, opposite_elem_text); + println!(" {} Text differs:\n expected: `{}`\n found: `{}`", + elem.path, s1, s2); + } } html_diff::Difference::NotPresent { ref elem, ref opposite_elem } => { if let Some(ref elem) = *elem { @@ -1756,18 +1768,18 @@ fn render_markdown(w: &mut fmt::Formatter, // We only emit warnings if the user has opted-in to Pulldown rendering. let output = if render_type == RenderType::Pulldown { let pulldown_output = format!("{}", Markdown(md_text, RenderType::Pulldown)); - let differences = html_diff::get_differences(&pulldown_output, &hoedown_output); - let differences = differences.into_iter() - .filter(|s| { - match *s { - html_diff::Difference::NodeText { ref elem_text, - ref opposite_elem_text, - .. } - if match_non_whitespace(elem_text, opposite_elem_text) => false, - _ => true, + let mut differences = html_diff::get_differences(&pulldown_output, &hoedown_output); + differences.retain(|s| { + match *s { + html_diff::Difference::NodeText { ref elem_text, + ref opposite_elem_text, + .. } + if elem_text.split_whitespace().eq(opposite_elem_text.split_whitespace()) => { + false } - }) - .collect::>(); + _ => true, + } + }); if !differences.is_empty() { scx.markdown_warnings.borrow_mut().push((span, md_text.to_owned(), differences)); @@ -1781,40 +1793,6 @@ fn render_markdown(w: &mut fmt::Formatter, write!(w, "
{}{}
", prefix, output) } -// Returns true iff s1 and s2 match, ignoring whitespace. -fn match_non_whitespace(s1: &str, s2: &str) -> bool { - let s1 = s1.trim(); - let s2 = s2.trim(); - let mut cs1 = s1.chars(); - let mut cs2 = s2.chars(); - while let Some(c1) = cs1.next() { - if c1.is_whitespace() { - continue; - } - - loop { - if let Some(c2) = cs2.next() { - if !c2.is_whitespace() { - if c1 != c2 { - return false; - } - break; - } - } else { - return false; - } - } - } - - while let Some(c2) = cs2.next() { - if !c2.is_whitespace() { - return false; - } - } - - true -} - fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink, cx: &Context, prefix: &str) -> fmt::Result { if let Some(s) = item.doc_value() { @@ -3791,35 +3769,3 @@ fn test_name_sorting() { sorted.sort_by_key(|&s| name_key(s)); assert_eq!(names, sorted); } - -#[cfg(test)] -#[test] -fn test_match_non_whitespace() { - assert!(match_non_whitespace("", "")); - assert!(match_non_whitespace(" ", "")); - assert!(match_non_whitespace("", " ")); - - assert!(match_non_whitespace("a", "a")); - assert!(match_non_whitespace(" a ", "a")); - assert!(match_non_whitespace("a", " a")); - assert!(match_non_whitespace("abc", "abc")); - assert!(match_non_whitespace("abc", " abc ")); - assert!(match_non_whitespace("abc ", "abc")); - assert!(match_non_whitespace("abc xyz", "abc xyz")); - assert!(match_non_whitespace("abc xyz", "abc\nxyz")); - assert!(match_non_whitespace("abc xyz", "abcxyz")); - assert!(match_non_whitespace("abcxyz", "abc xyz")); - assert!(match_non_whitespace("abc xyz ", " abc xyz\n")); - - assert!(!match_non_whitespace("a", "b")); - assert!(!match_non_whitespace(" a ", "c")); - assert!(!match_non_whitespace("a", " aa")); - assert!(!match_non_whitespace("abc", "ac")); - assert!(!match_non_whitespace("abc", " adc ")); - assert!(!match_non_whitespace("abc ", "abca")); - assert!(!match_non_whitespace("abc xyz", "abc xy")); - assert!(!match_non_whitespace("abc xyz", "bc\nxyz")); - assert!(!match_non_whitespace("abc xyz", "abc.xyz")); - assert!(!match_non_whitespace("abcxyz", "abc.xyz")); - assert!(!match_non_whitespace("abc xyz ", " abc xyz w")); -} diff --git a/src/libstd/sys/unix/backtrace/printing/dladdr.rs b/src/libstd/sys/unix/backtrace/printing/dladdr.rs index 3a3912af021ce..21f0b3724c130 100644 --- a/src/libstd/sys/unix/backtrace/printing/dladdr.rs +++ b/src/libstd/sys/unix/backtrace/printing/dladdr.rs @@ -22,7 +22,8 @@ pub fn resolve_symname(frame: Frame, { unsafe { let mut info: Dl_info = intrinsics::init(); - let symname = if dladdr(frame.exact_position, &mut info) == 0 { + let symname = if dladdr(frame.exact_position, &mut info) == 0 || + info.dli_sname.is_null() { None } else { CStr::from_ptr(info.dli_sname).to_str().ok() diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 4ee8132f55cee..a53c76a333a99 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -31,6 +31,10 @@ use mem; /// within a thread, and values that implement [`Drop`] get destructed when a /// thread exits. Some caveats apply, which are explained below. /// +/// A `LocalKey`'s initializer cannot recursively depend on itself, and using +/// a `LocalKey` in this way will cause the initializer to infinitely recurse +/// on the first call to `with`. +/// /// # Examples /// /// ``` diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 54d41a030fd77..e9e9c6bf4eaca 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -312,6 +312,9 @@ declare_features! ( // The `i128` type (active, i128_type, "1.16.0", Some(35118)), + // The `repr(i128)` annotation for enums + (active, repr128, "1.16.0", Some(35118)), + // The `unadjusted` ABI. Perma unstable. (active, abi_unadjusted, "1.16.0", None), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1f033b25fe4f6..a52d048830715 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4699,7 +4699,7 @@ impl<'a> Parser<'a> { SeqSep::trailing_allowed(token::Comma), |p| p.parse_fn_block_arg() ); - self.bump(); + self.expect(&token::BinOp(token::Or))?; args } }; diff --git a/src/test/compile-fail/feature-gate-repr128.rs b/src/test/compile-fail/feature-gate-repr128.rs new file mode 100644 index 0000000000000..96fffa6cdd0dc --- /dev/null +++ b/src/test/compile-fail/feature-gate-repr128.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[repr(u128)] +enum A { //~ ERROR repr with 128-bit type is unstable + //~| HELP: add #![feature(repr128)] + A(u64) +} + +fn main() {} diff --git a/src/test/compile-fail/issue-41229-ref-str.rs b/src/test/compile-fail/issue-41229-ref-str.rs new file mode 100644 index 0000000000000..31bc21c23ba5f --- /dev/null +++ b/src/test/compile-fail/issue-41229-ref-str.rs @@ -0,0 +1,16 @@ +// Copyright 2017 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn example(ref s: str) {} +//~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied +//~| `str` does not have a constant size known at compile-time +//~| the trait `std::marker::Sized` is not implemented for `str` + +fn main() {} diff --git a/src/test/compile-fail/issue-44021.rs b/src/test/compile-fail/issue-44021.rs new file mode 100644 index 0000000000000..b6ec21b94c73f --- /dev/null +++ b/src/test/compile-fail/issue-44021.rs @@ -0,0 +1,16 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct MyStruct; +impl MyStruct { + fn f() {|x, y} //~ ERROR expected one of `:`, `@`, or `|`, found `}` +} + +fn main() {}