diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index b60c55240140e..d7e789b5a11f7 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -42,11 +42,11 @@ This flag prints out various information about the compiler. ## `-g`: include debug information -A synonym for `-C debug-level=2`. +A synonym for `-C debuginfo=2`, for more see [here](codegen-options/index.html#debuginfo). ## `-O`: optimize your code -A synonym for `-C opt-level=2`. +A synonym for `-C opt-level=2`, for more see [here](codegen-options/index.html#opt-level). ## `-o`: filename of the output diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 072c7585934e8..d315e0f8ca9e5 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -90,7 +90,9 @@ This lint level gives you that. 'forbid' is a special lint level that's stronger than 'deny'. It's the same as 'deny' in that a lint at this level will produce an error, but unlike the 'deny' level, the 'forbid' level can not be overridden to be anything lower -than an error. +than an error. However, lint levels may still be capped with `--cap-lints` +(see below) so `rustc --cap-lints warn` will make lints set to 'forbid' just +warn. ## Configuring warning levels diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index ff9e0235a0435..fa62d1a03f53b 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -149,6 +149,26 @@ error: const items should never be #[no_mangle] | ``` +## overflowing-literals + +This lint detects literal out of range for its type. Some +example code that triggers this lint: + +```rust,compile_fail +let x: u8 = 1000; +``` + +This will produce: + +```text +error: literal out of range for u8 + --> src/main.rs:2:17 + | +2 | let x: u8 = 1000; + | ^^^^ + | +``` + ## parenthesized-params-in-types-and-modules This lint detects incorrect parentheses. Some example code that triggers this diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md index 7fbbe686b5bd0..ba927b1ef3b57 100644 --- a/src/doc/rustc/src/lints/listing/warn-by-default.md +++ b/src/doc/rustc/src/lints/listing/warn-by-default.md @@ -285,26 +285,6 @@ warning: functions generic over types must be mangled | ``` -## overflowing-literals - -This lint detects literal out of range for its type. Some -example code that triggers this lint: - -```rust -let x: u8 = 1000; -``` - -This will produce: - -```text -warning: literal out of range for u8 - --> src/main.rs:2:17 - | -2 | let x: u8 = 1000; - | ^^^^ - | -``` - ## path-statements This lint detects path statements with no effect. Some example code that diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index dcc13f53493f4..242167aa91786 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -236,6 +236,23 @@ appears to the reader as the initial idea but works with doc tests: /// ``` ``` +As of version 1.34.0, one can also omit the `fn main()`, but you will have to +disambiguate the error type: + +```ignore +/// ``` +/// use std::io; +/// let mut input = String::new(); +/// io::stdin().read_line(&mut input)?; +/// # Ok::<(), io:Error>(()) +/// ``` +``` + +This is an unfortunate consequence of the `?` operator adding an implicit +conversion, so type inference fails because the type is not unique. Please note +that you must write the `(())` in one sequence without intermediate whitespace +so that rustdoc understands you want an implicit `Result`-returning function. + ## Documenting macros Here’s an example of documenting a macro: diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 2c53e4832a8cc..03fe1fe5a7cf8 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -40,18 +40,17 @@ fn test() { } #[test] -#[cfg(not(miri))] // This test performs invalid OOB pointer arithmetic fn test_is_null() { let p: *const isize = null(); assert!(p.is_null()); - let q = unsafe { p.offset(1) }; + let q = p.wrapping_offset(1); assert!(!q.is_null()); let mp: *mut isize = null_mut(); assert!(mp.is_null()); - let mq = unsafe { mp.offset(1) }; + let mq = mp.wrapping_offset(1); assert!(!mq.is_null()); // Pointers to unsized types -- slices @@ -208,7 +207,6 @@ fn test_ptr_addition() { } #[test] -#[cfg(not(miri))] // This test performs invalid OOB pointer arithmetic fn test_ptr_subtraction() { unsafe { let xs = vec![0,1,2,3,4,5,6,7,8,9]; @@ -224,8 +222,11 @@ fn test_ptr_subtraction() { let m_start = xs_mut.as_mut_ptr(); let mut m_ptr = m_start.offset(9); - while m_ptr >= m_start { + loop { *m_ptr += *m_ptr; + if m_ptr == m_start { + break; + } m_ptr = m_ptr.offset(-1); } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 9436c600c9fd3..a8fa1f31a55f4 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -951,7 +951,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { visitor.visit_id(statement.id); match statement.node { StmtKind::Local(ref local) => visitor.visit_local(local), - StmtKind::Item(ref item) => visitor.visit_nested_item(**item), + StmtKind::Item(item) => visitor.visit_nested_item(item), StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { visitor.visit_expr(expression) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 84487c40f8745..2341dda676897 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4663,7 +4663,7 @@ impl<'a> LoweringContext<'a> { hir::Stmt { id: node_id, hir_id, - node: hir::StmtKind::Item(P(item_id)), + node: hir::StmtKind::Item(item_id), span: s.span, } }) @@ -4693,7 +4693,7 @@ impl<'a> LoweringContext<'a> { hir::Stmt { id: node_id, hir_id, - node: hir::StmtKind::Item(P(item_id)), + node: hir::StmtKind::Item(item_id), span: s.span, } }) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index d774359fa79ec..f4a9903e559f6 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1159,8 +1159,9 @@ impl fmt::Debug for Stmt { pub enum StmtKind { /// A local (`let`) binding. Local(P), + /// An item binding. - Item(P), + Item(ItemId), /// An expression without a trailing semi-colon (must have unit type). Expr(P), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 9b6fcf259be14..81a67b1a4bcf7 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1007,8 +1007,8 @@ impl<'a> State<'a> { } self.end()? } - hir::StmtKind::Item(ref item) => { - self.ann.nested(self, Nested::Item(**item))? + hir::StmtKind::Item(item) => { + self.ann.nested(self, Nested::Item(item))? } hir::StmtKind::Expr(ref expr) => { self.space_if_not_bol()?; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 34f8fc40597f1..f03f84ba519d6 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -16,7 +16,6 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::{ast, attr}; use syntax::errors::Applicability; use rustc_target::spec::abi::Abi; -use syntax::edition::Edition; use syntax_pos::Span; use syntax::source_map; @@ -34,9 +33,8 @@ declare_lint! { declare_lint! { OVERFLOWING_LITERALS, - Warn, - "literal out of range for its type", - Edition::Edition2018 => Deny + Deny, + "literal out of range for its type" } declare_lint! { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 4d65862375a96..739125729d41a 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -130,6 +130,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); let mut is_loop_move = false; + let is_partial_move = move_site_vec.iter().any(|move_site| { + let move_out = self.move_data.moves[(*move_site).moi]; + let moved_place = &self.move_data.move_paths[move_out.path].place; + used_place != moved_place && used_place.is_prefix_of(moved_place) + }); for move_site in &move_site_vec { let move_out = self.move_data.moves[(*move_site).moi]; let moved_place = &self.move_data.move_paths[move_out.path].place; @@ -175,8 +180,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err.span_label( span, format!( - "value {} here after move", - desired_action.as_verb_in_past_tense() + "value {} here {}", + desired_action.as_verb_in_past_tense(), + if is_partial_move { "after partial move" } else { "after move" }, ), ); } diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index c8b3e2f4e4cf4..cd771d93e00f6 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -259,6 +259,10 @@ impl<'a> Resolver<'a> { format!("{}!", path_str), Applicability::MaybeIncorrect, ); + if path_str == "try" && span.rust_2015() { + err.note("if you want the `try` keyword, \ + you need to be in the 2018 edition"); + } } (Def::TyAlias(..), PathSource::Trait(_)) => { err.span_label(span, "type aliases cannot be used as traits"); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 692d879668877..319caaebbee5b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2786,8 +2786,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, \ {name}{unsafety_flag}\ - {stab_tags}{docs}\ - \ + {stab_tags}{docs}\ ", name = *myitem.name.as_ref().unwrap(), stab_tags = stability_tags(myitem), diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ff28c4f40bcae..1849e53d937ad 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1196,7 +1196,7 @@ if (!DOMTokenList.prototype.remove) { var actives = [[], [], []]; // "current" is used to know which tab we're looking into. var current = 0; - onEachLazy(document.getElementsByClassName("search-results"), function(e) { + onEachLazy(document.getElementById("results").childNodes, function(e) { onEachLazy(e.getElementsByClassName("highlighted"), function(e) { actives[current].push(e); }); @@ -1213,7 +1213,7 @@ if (!DOMTokenList.prototype.remove) { removeClass(actives[currentTab][0], "highlighted"); } else if (e.which === 40) { // down if (!actives[currentTab].length) { - var results = document.getElementsByClassName("search-results"); + var results = document.getElementById("results").childNodes; if (results.length > 0) { var res = results[currentTab].getElementsByClassName("result"); if (res.length > 0) { diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 333fe76a8a4a9..b5200fa36df9e 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -190,15 +190,15 @@ a.test-arrow { box-shadow: 1px 0 0 1px #000, 0 0 0 2px transparent; } -.stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #404040; } -.stab.internal { background: #FFB9B3; border-color: #B71C1C; color: #404040; } -.stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #404040; } -.stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #404040; } - .module-item .stab { color: #ddd; } +.stab.unstable {background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } +.stab.internal { background: #FFB9B3; border-color: #B71C1C; color: #2f2f2f; } +.stab.deprecated { background: #F3DFFF; border-color: #7F0087; color: #2f2f2f; } +.stab.portability { background: #C4ECFF; border-color: #7BA5DB; color: #2f2f2f; } + #help > div { background: #4d4d4d; border-color: #bfbfbf; diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 19ae67b29881f..e712a7d18a9da 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -191,15 +191,15 @@ a.test-arrow { box-shadow: 1px 0 0 1px #e0e0e0, 0 0 0 2px transparent; } +.module-item .stab { + color: #000; +} + .stab.unstable { background: #FFF5D6; border-color: #FFC600; } .stab.internal { background: #FFB9B3; border-color: #B71C1C; } .stab.deprecated { background: #F3DFFF; border-color: #7F0087; } .stab.portability { background: #C4ECFF; border-color: #7BA5DB; } -.module-item .stab { - color: #000; -} - #help > div { background: #e9e9e9; border-color: #bfbfbf; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0b9fbc81da626..3d4dba550b0e8 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -534,13 +534,19 @@ pub fn make_test(s: &str, } } - if dont_insert_main || already_has_main { + // FIXME: This code cannot yet handle no_std test cases yet + if dont_insert_main || already_has_main || prog.contains("![no_std]") { prog.push_str(everything_else); } else { - prog.push_str("fn main() {\n"); + let returns_result = everything_else.trim_end().ends_with("(())"); + let (main_pre, main_post) = if returns_result { + ("fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {", + "}\n_inner().unwrap() }") + } else { + ("fn main() {\n", "\n}") + }; + prog.extend([main_pre, everything_else, main_post].iter().cloned()); line_offset += 1; - prog.push_str(everything_else); - prog.push_str("\n}"); } debug!("final doctest:\n{}", prog); diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f1e8619fc8ffc..def51c79a8562 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -254,10 +254,13 @@ fn initial_buffer_size(file: &File) -> usize { /// ``` #[stable(feature = "fs_read_write_bytes", since = "1.26.0")] pub fn read>(path: P) -> io::Result> { - let mut file = File::open(path)?; - let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); - file.read_to_end(&mut bytes)?; - Ok(bytes) + fn inner(path: &Path) -> io::Result> { + let mut file = File::open(path)?; + let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); + file.read_to_end(&mut bytes)?; + Ok(bytes) + } + inner(path.as_ref()) } /// Read the entire contents of a file into a string. @@ -296,10 +299,13 @@ pub fn read>(path: P) -> io::Result> { /// ``` #[stable(feature = "fs_read_write", since = "1.26.0")] pub fn read_to_string>(path: P) -> io::Result { - let mut file = File::open(path)?; - let mut string = String::with_capacity(initial_buffer_size(&file)); - file.read_to_string(&mut string)?; - Ok(string) + fn inner(path: &Path) -> io::Result { + let mut file = File::open(path)?; + let mut string = String::with_capacity(initial_buffer_size(&file)); + file.read_to_string(&mut string)?; + Ok(string) + } + inner(path.as_ref()) } /// Write a slice as the entire contents of a file. @@ -326,7 +332,10 @@ pub fn read_to_string>(path: P) -> io::Result { /// ``` #[stable(feature = "fs_read_write_bytes", since = "1.26.0")] pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> { - File::create(path)?.write_all(contents.as_ref()) + fn inner(path: &Path, contents: &[u8]) -> io::Result<()> { + File::create(path)?.write_all(contents) + } + inner(path.as_ref(), contents.as_ref()) } impl File { diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index d19cc482c15f9..c856129016814 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -329,6 +329,8 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { + // FIXME: should just be u32::from_be_bytes([a, b, c, d]), + // once that method is no longer rustc_const_unstable Ipv4Addr { inner: c::in_addr { s_addr: u32::to_be( @@ -392,6 +394,7 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn octets(&self) -> [u8; 4] { + // This returns the order we want because s_addr is stored in big-endian. self.inner.s_addr.to_ne_bytes() } @@ -618,9 +621,13 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn to_ipv6_compatible(&self) -> Ipv6Addr { - Ipv6Addr::new(0, 0, 0, 0, 0, 0, - ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16, - ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16) + let octets = self.octets(); + Ipv6Addr::from([ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + octets[0], octets[1], octets[2], octets[3], + ]) } /// Converts this address to an IPv4-mapped [IPv6 address]. @@ -639,9 +646,13 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn to_ipv6_mapped(&self) -> Ipv6Addr { - Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, - ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16, - ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16) + let octets = self.octets(); + Ipv6Addr::from([ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0xFF, 0xFF, + octets[0], octets[1], octets[2], octets[3], + ]) } } @@ -784,7 +795,7 @@ impl From for u32 { /// ``` fn from(ip: Ipv4Addr) -> u32 { let ip = ip.octets(); - ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32) + u32::from_be_bytes(ip) } } @@ -801,7 +812,7 @@ impl From for Ipv4Addr { /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); /// ``` fn from(ip: u32) -> Ipv4Addr { - Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8) + Ipv4Addr::from(ip.to_be_bytes()) } } @@ -909,14 +920,14 @@ impl Ipv6Addr { pub fn segments(&self) -> [u16; 8] { let arr = &self.inner.s6_addr; [ - (arr[0] as u16) << 8 | (arr[1] as u16), - (arr[2] as u16) << 8 | (arr[3] as u16), - (arr[4] as u16) << 8 | (arr[5] as u16), - (arr[6] as u16) << 8 | (arr[7] as u16), - (arr[8] as u16) << 8 | (arr[9] as u16), - (arr[10] as u16) << 8 | (arr[11] as u16), - (arr[12] as u16) << 8 | (arr[13] as u16), - (arr[14] as u16) << 8 | (arr[15] as u16), + u16::from_be_bytes([arr[0], arr[1]]), + u16::from_be_bytes([arr[2], arr[3]]), + u16::from_be_bytes([arr[4], arr[5]]), + u16::from_be_bytes([arr[6], arr[7]]), + u16::from_be_bytes([arr[8], arr[9]]), + u16::from_be_bytes([arr[10], arr[11]]), + u16::from_be_bytes([arr[12], arr[13]]), + u16::from_be_bytes([arr[14], arr[15]]), ] } @@ -1382,21 +1393,43 @@ impl FromInner for Ipv6Addr { #[stable(feature = "i128", since = "1.26.0")] impl From for u128 { + /// Convert an `Ipv6Addr` into a host byte order `u128`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv6Addr; + /// + /// let addr = Ipv6Addr::new( + /// 0x1020, 0x3040, 0x5060, 0x7080, + /// 0x90A0, 0xB0C0, 0xD0E0, 0xF00D, + /// ); + /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr)); + /// ``` fn from(ip: Ipv6Addr) -> u128 { - let ip = ip.segments(); - ((ip[0] as u128) << 112) + ((ip[1] as u128) << 96) + ((ip[2] as u128) << 80) + - ((ip[3] as u128) << 64) + ((ip[4] as u128) << 48) + ((ip[5] as u128) << 32) + - ((ip[6] as u128) << 16) + (ip[7] as u128) + let ip = ip.octets(); + u128::from_be_bytes(ip) } } #[stable(feature = "i128", since = "1.26.0")] impl From for Ipv6Addr { + /// Convert a host byte order `u128` into an `Ipv6Addr`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv6Addr; + /// + /// let addr = Ipv6Addr::from(0x102030405060708090A0B0C0D0E0F00D_u128); + /// assert_eq!( + /// Ipv6Addr::new( + /// 0x1020, 0x3040, 0x5060, 0x7080, + /// 0x90A0, 0xB0C0, 0xD0E0, 0xF00D, + /// ), + /// addr); + /// ``` fn from(ip: u128) -> Ipv6Addr { - Ipv6Addr::new( - (ip >> 112) as u16, (ip >> 96) as u16, (ip >> 80) as u16, - (ip >> 64) as u16, (ip >> 48) as u16, (ip >> 32) as u16, - (ip >> 16) as u16, ip as u16, - ) + Ipv6Addr::from(ip.to_be_bytes()) } } diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index c4b0cd0f17c34..3eb2a332d267b 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -1187,9 +1187,13 @@ mod tests { #[test] fn double_bind() { each_ip(&mut |addr| { - let _listener = t!(TcpListener::bind(&addr)); + let listener1 = t!(TcpListener::bind(&addr)); match TcpListener::bind(&addr) { - Ok(..) => panic!(), + Ok(listener2) => panic!( + "This system (perhaps due to options set by TcpListener::bind) \ + permits double binding: {:?} and {:?}", + listener1, listener2 + ), Err(e) => { assert!(e.kind() == ErrorKind::ConnectionRefused || e.kind() == ErrorKind::Other || diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 0a9796d1a9c20..dcaa65a8fa78e 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1145,6 +1145,33 @@ impl PathBuf { PathBuf { inner: OsString::new() } } + /// Creates a new `PathBuf` with a given capacity used to create the + /// internal [`OsString`]. See [`with_capacity`] defined on [`OsString`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_buf_capacity)] + /// use std::path::PathBuf; + /// + /// let mut path = PathBuf::with_capacity(10); + /// let capacity = path.capacity(); + /// + /// // This push is done without reallocating + /// path.push(r"C:\"); + /// + /// assert_eq!(capacity, path.capacity()); + /// ``` + /// + /// [`with_capacity`]: ../ffi/struct.OsString.html#method.with_capacity + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn with_capacity(capacity: usize) -> PathBuf { + PathBuf { + inner: OsString::with_capacity(capacity) + } + } + /// Coerces to a [`Path`] slice. /// /// [`Path`]: struct.Path.html @@ -1373,6 +1400,60 @@ impl PathBuf { let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path; unsafe { Box::from_raw(rw) } } + + /// Invokes [`capacity`] on the underlying instance of [`OsString`]. + /// + /// [`capacity`]: ../ffi/struct.OsString.html#method.capacity + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn capacity(&self) -> usize { + self.inner.capacity() + } + + /// Invokes [`clear`] on the underlying instance of [`OsString`]. + /// + /// [`clear`]: ../ffi/struct.OsString.html#method.clear + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn clear(&mut self) { + self.inner.clear() + } + + /// Invokes [`reserve`] on the underlying instance of [`OsString`]. + /// + /// [`reserve`]: ../ffi/struct.OsString.html#method.reserve + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn reserve(&mut self, additional: usize) { + self.inner.reserve(additional) + } + + /// Invokes [`reserve_exact`] on the underlying instance of [`OsString`]. + /// + /// [`reserve_exact`]: ../ffi/struct.OsString.html#method.reserve_exact + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn reserve_exact(&mut self, additional: usize) { + self.inner.reserve_exact(additional) + } + + /// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`]. + /// + /// [`shrink_to_fit`]: ../ffi/struct.OsString.html#method.shrink_to_fit + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn shrink_to_fit(&mut self) { + self.inner.shrink_to_fit() + } + + /// Invokes [`shrink_to`] on the underlying instance of [`OsString`]. + /// + /// [`shrink_to`]: ../ffi/struct.OsString.html#method.shrink_to + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } } #[stable(feature = "box_from_path", since = "1.17.0")] diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e22047938e518..10c1bbaf5c4a0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5502,6 +5502,7 @@ impl<'a> Parser<'a> { if is_bound_start { let lo = self.span; let has_parens = self.eat(&token::OpenDelim(token::Paren)); + let inner_lo = self.span; let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None }; if self.token.is_lifetime() { if let Some(question_span) = question { @@ -5510,9 +5511,21 @@ impl<'a> Parser<'a> { } bounds.push(GenericBound::Outlives(self.expect_lifetime())); if has_parens { + let inner_span = inner_lo.to(self.prev_span); self.expect(&token::CloseDelim(token::Paren))?; - self.span_err(self.prev_span, - "parenthesized lifetime bounds are not supported"); + let mut err = self.struct_span_err( + lo.to(self.prev_span), + "parenthesized lifetime bounds are not supported" + ); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(inner_span) { + err.span_suggestion_short( + lo.to(self.prev_span), + "remove the parentheses", + snippet.to_owned(), + Applicability::MachineApplicable + ); + } + err.emit(); } } else { let lifetime_defs = self.parse_late_bound_lifetime_defs()?; diff --git a/src/test/rustdoc/process-termination.rs b/src/test/rustdoc/process-termination.rs new file mode 100644 index 0000000000000..32258792b6e8b --- /dev/null +++ b/src/test/rustdoc/process-termination.rs @@ -0,0 +1,24 @@ +// compile-flags:--test + +/// A check of using various process termination strategies +/// +/// # Examples +/// +/// ```rust +/// assert!(true); // this returns `()`, all is well +/// ``` +/// +/// You can also simply return `Ok(())`, but you'll need to disambiguate the +/// type using turbofish, because we cannot infer the type: +/// +/// ```rust +/// Ok::<(), &'static str>(()) +/// ``` +/// +/// You can err with anything that implements `Debug`: +/// +/// ```rust,should_panic +/// Err("This is returned from `main`, leading to panic")?; +/// Ok::<(), &'static str>(()) +/// ``` +pub fn check_process_termination() {} diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr index bdec94b4f84b0..99cbf64fd5d46 100644 --- a/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr @@ -20,7 +20,7 @@ error[E0382]: use of moved value: `line2` LL | let _moved = (line2.origin, line2.middle); | ------------ value moved here LL | line2.consume(); //[ast]~ ERROR use of partially moved value: `line2` [E0382] - | ^^^^^ value used here after move + | ^^^^^ value used here after partial move | = note: move occurs because `line2.middle` has type `Point`, which does not implement the `Copy` trait diff --git a/src/test/ui/editions/edition-deny-overflowing-literals-2018.rs b/src/test/ui/lint/deny-overflowing-literals.rs similarity index 82% rename from src/test/ui/editions/edition-deny-overflowing-literals-2018.rs rename to src/test/ui/lint/deny-overflowing-literals.rs index 0527d75214a57..ebd6654d39b1f 100644 --- a/src/test/ui/editions/edition-deny-overflowing-literals-2018.rs +++ b/src/test/ui/lint/deny-overflowing-literals.rs @@ -1,5 +1,3 @@ -// edition:2018 - fn main() { let x: u8 = 256; //~^ error: literal out of range for u8 diff --git a/src/test/ui/editions/edition-deny-overflowing-literals-2018.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr similarity index 76% rename from src/test/ui/editions/edition-deny-overflowing-literals-2018.stderr rename to src/test/ui/lint/deny-overflowing-literals.stderr index 6d1d8568bcf8f..7313dd0bfb5a7 100644 --- a/src/test/ui/editions/edition-deny-overflowing-literals-2018.stderr +++ b/src/test/ui/lint/deny-overflowing-literals.stderr @@ -1,5 +1,5 @@ error: literal out of range for u8 - --> $DIR/edition-deny-overflowing-literals-2018.rs:4:17 + --> $DIR/deny-overflowing-literals.rs:2:17 | LL | let x: u8 = 256; | ^^^ diff --git a/src/test/ui/lint/lint-type-limits2.rs b/src/test/ui/lint/lint-type-limits2.rs index 9c69ba12cf79e..c4486e0676887 100644 --- a/src/test/ui/lint/lint-type-limits2.rs +++ b/src/test/ui/lint/lint-type-limits2.rs @@ -1,4 +1,5 @@ #![allow(dead_code)] +#![warn(overflowing_literals)] // compile-flags: -D unused-comparisons fn main() { } diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr index 3118bcec05e85..f88fff62e21fc 100644 --- a/src/test/ui/lint/lint-type-limits2.stderr +++ b/src/test/ui/lint/lint-type-limits2.stderr @@ -1,5 +1,5 @@ error: comparison is useless due to type limits - --> $DIR/lint-type-limits2.rs:12:5 + --> $DIR/lint-type-limits2.rs:13:5 | LL | 128 > bar() //~ ERROR comparison is useless due to type limits | ^^^^^^^^^^^ @@ -7,12 +7,16 @@ LL | 128 > bar() //~ ERROR comparison is useless due to type limits = note: requested on the command line with `-D unused-comparisons` warning: literal out of range for i8 - --> $DIR/lint-type-limits2.rs:12:5 + --> $DIR/lint-type-limits2.rs:13:5 | LL | 128 > bar() //~ ERROR comparison is useless due to type limits | ^^^ | - = note: #[warn(overflowing_literals)] on by default +note: lint level defined here + --> $DIR/lint-type-limits2.rs:2:9 + | +LL | #![warn(overflowing_literals)] + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/lint-type-limits3.rs b/src/test/ui/lint/lint-type-limits3.rs index 3e95ad212eb16..a715c69f7849e 100644 --- a/src/test/ui/lint/lint-type-limits3.rs +++ b/src/test/ui/lint/lint-type-limits3.rs @@ -1,4 +1,5 @@ #![allow(dead_code)] +#![warn(overflowing_literals)] // compile-flags: -D unused-comparisons fn main() { } diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr index 5e30b1646a755..4f47a7ce31665 100644 --- a/src/test/ui/lint/lint-type-limits3.stderr +++ b/src/test/ui/lint/lint-type-limits3.stderr @@ -1,5 +1,5 @@ error: comparison is useless due to type limits - --> $DIR/lint-type-limits3.rs:8:11 + --> $DIR/lint-type-limits3.rs:9:11 | LL | while 200 != i { //~ ERROR comparison is useless due to type limits | ^^^^^^^^ @@ -7,12 +7,16 @@ LL | while 200 != i { //~ ERROR comparison is useless due to type limits = note: requested on the command line with `-D unused-comparisons` warning: literal out of range for i8 - --> $DIR/lint-type-limits3.rs:8:11 + --> $DIR/lint-type-limits3.rs:9:11 | LL | while 200 != i { //~ ERROR comparison is useless due to type limits | ^^^ | - = note: #[warn(overflowing_literals)] on by default +note: lint level defined here + --> $DIR/lint-type-limits3.rs:2:9 + | +LL | #![warn(overflowing_literals)] + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index 2ccc52a0413e0..64e5951207379 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -1,4 +1,5 @@ // compile-pass +#![warn(overflowing_literals)] fn main() { let error = 255i8; //~WARNING literal out of range for i8 diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 3c4a37c4adf56..349d0be016497 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -1,13 +1,17 @@ warning: literal out of range for i8 - --> $DIR/type-overflow.rs:4:17 + --> $DIR/type-overflow.rs:5:17 | LL | let error = 255i8; //~WARNING literal out of range for i8 | ^^^^^ | - = note: #[warn(overflowing_literals)] on by default +note: lint level defined here + --> $DIR/type-overflow.rs:2:9 + | +LL | #![warn(overflowing_literals)] + | ^^^^^^^^^^^^^^^^^^^^ warning: literal out of range for i8 - --> $DIR/type-overflow.rs:9:16 + --> $DIR/type-overflow.rs:10:16 | LL | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8` @@ -15,7 +19,7 @@ LL | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8` warning: literal out of range for i64 - --> $DIR/type-overflow.rs:11:16 + --> $DIR/type-overflow.rs:12:16 | LL | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64` @@ -23,7 +27,7 @@ LL | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range fo = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64` warning: literal out of range for u32 - --> $DIR/type-overflow.rs:13:16 + --> $DIR/type-overflow.rs:14:16 | LL | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 | ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64` @@ -31,7 +35,7 @@ LL | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32` warning: literal out of range for i128 - --> $DIR/type-overflow.rs:15:22 + --> $DIR/type-overflow.rs:16:22 | LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +44,7 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; = help: consider using `u128` instead warning: literal out of range for i32 - --> $DIR/type-overflow.rs:18:16 + --> $DIR/type-overflow.rs:19:16 | LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 | ^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +53,7 @@ LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i = help: consider using `i128` instead warning: literal out of range for i8 - --> $DIR/type-overflow.rs:20:17 + --> $DIR/type-overflow.rs:21:17 | LL | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16` diff --git a/src/test/ui/nll/move-subpaths-moves-root.stderr b/src/test/ui/nll/move-subpaths-moves-root.stderr index 0dd396f855dc5..8b52cc113ccc5 100644 --- a/src/test/ui/nll/move-subpaths-moves-root.stderr +++ b/src/test/ui/nll/move-subpaths-moves-root.stderr @@ -4,7 +4,7 @@ error[E0382]: use of moved value: `x` LL | drop(x.0); | --- value moved here LL | drop(x); //~ ERROR use of moved value - | ^ value used here after move + | ^ value used here after partial move | = note: move occurs because `x.0` has type `std::vec::Vec`, which does not implement the `Copy` trait diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr index a9b542ddcc4d3..94ca66aef729b 100644 --- a/src/test/ui/parser/trait-object-lifetime-parens.stderr +++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr @@ -1,14 +1,14 @@ error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:5:24 + --> $DIR/trait-object-lifetime-parens.rs:5:21 | LL | fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:8:27 + --> $DIR/trait-object-lifetime-parens.rs:8:24 | LL | let _: Box; //~ ERROR parenthesized lifetime bounds are not supported - | ^ + | ^^^^ help: remove the parentheses error: expected type, found `'a` --> $DIR/trait-object-lifetime-parens.rs:9:17 diff --git a/src/test/ui/specialization/issue-39448.rs b/src/test/ui/specialization/issue-39448.rs new file mode 100644 index 0000000000000..8ac6d8e9311fc --- /dev/null +++ b/src/test/ui/specialization/issue-39448.rs @@ -0,0 +1,50 @@ +#![feature(specialization)] + +// Regression test for a specialization-related ICE (#39448). + +trait A: Sized { + fn foo(self, _: Self) -> Self { + self + } +} + +impl A for u8 {} +impl A for u16 {} + +impl FromA for u16 { + fn from(x: u8) -> u16 { + x as u16 + } +} + +trait FromA { + fn from(T) -> Self; +} + +impl> FromA for U { + default fn from(x: T) -> Self { + ToA::to(x) + } +} + +trait ToA { + fn to(self) -> T; +} + +impl ToA for T +where + U: FromA, +{ + fn to(self) -> U { + U::from(self) + } +} + +#[allow(dead_code)] +fn foo(x: T, y: U) -> U { + x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement +} + +fn main() { + let z = foo(8u8, 1u16); +} diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr new file mode 100644 index 0000000000000..0b0fd2c4af591 --- /dev/null +++ b/src/test/ui/specialization/issue-39448.stderr @@ -0,0 +1,12 @@ +error[E0275]: overflow evaluating the requirement `T: FromA` + --> $DIR/issue-39448.rs:45:13 + | +LL | x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement + | ^^ + | + = note: required because of the requirements on the impl of `FromA` for `T` + = note: required because of the requirements on the impl of `ToA` for `U` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index a7b81060d3dc6..7394fec6f3660 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -16,6 +16,8 @@ error[E0574]: expected struct, variant or union type, found macro `try` | LL | let try_result: Option<_> = try { | ^^^ help: use `!` to invoke the macro: `try!` + | + = note: if you want the `try` keyword, you need to be in the 2018 edition error: aborting due to 2 previous errors