From 219ba511c824bc44149d55c570f723dcd0f0217d Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 21 Nov 2017 14:44:25 +0100 Subject: [PATCH 01/10] Document the size of bool --- src/libcore/mem.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index d57fbdf55f80e..486093f261c77 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -189,6 +189,7 @@ pub fn forget(t: T) { /// Type | size_of::\() /// ---- | --------------- /// () | 0 +/// bool | 1 /// u8 | 1 /// u16 | 2 /// u32 | 4 From b7437c56f82cfb643a372a7b10c85b4ed183d886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 28 Jan 2018 11:14:09 -0800 Subject: [PATCH 02/10] Suggest removing value from `break` when invalid --- src/librustc_passes/loops.rs | 5 +++++ src/test/ui/loop-break-value-no-repeat.stderr | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index c23f28fe2205f..008c71cc9ce3d 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -119,6 +119,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { kind.name()) .span_label(e.span, "can only break with a value inside `loop`") + .span_suggestion(e.span, + &format!("instead, use `break` on its own \ + without a value inside this `{}` loop", + kind.name()), + "break".to_string()) .emit(); } } diff --git a/src/test/ui/loop-break-value-no-repeat.stderr b/src/test/ui/loop-break-value-no-repeat.stderr index 296b3b191e319..982de00b4fa7c 100644 --- a/src/test/ui/loop-break-value-no-repeat.stderr +++ b/src/test/ui/loop-break-value-no-repeat.stderr @@ -3,6 +3,10 @@ error[E0571]: `break` with value from a `for` loop | 22 | break 22 //~ ERROR `break` with value from a `for` loop | ^^^^^^^^ can only break with a value inside `loop` +help: instead, use `break` on its own without a value inside this `for` loop + | +22 | break //~ ERROR `break` with value from a `for` loop + | ^^^^^ error: aborting due to previous error From bc8e11b975030c4282f4b76200a104788f8ac5c8 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 30 Jan 2018 21:44:35 -0500 Subject: [PATCH 03/10] Fix ICE when assigning references to a static mut with NLL is_unsafe_place only filters out statics in the rhs, not the lhs. Since it's possible to reach that 'Place::Static', we handle statics the same way as we do locals. Fixes #47789 --- src/librustc_mir/dataflow/impls/borrows.rs | 3 +-- src/test/run-pass/issue-47789.rs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-47789.rs diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 632bb5b34284d..80990bcc08089 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -396,8 +396,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { // Issue #46746: Two-phase borrows handles // stmts of form `Tmp = &mut Borrow` ... match lhs { - Place::Local(..) => {} // okay - Place::Static(..) => unreachable!(), // (filtered by is_unsafe_place) + Place::Local(..) | Place::Static(..) => {} // okay Place::Projection(..) => { // ... can assign into projections, // e.g. `box (&mut _)`. Current diff --git a/src/test/run-pass/issue-47789.rs b/src/test/run-pass/issue-47789.rs new file mode 100644 index 0000000000000..3148939992caf --- /dev/null +++ b/src/test/run-pass/issue-47789.rs @@ -0,0 +1,20 @@ +// Copyright 2018 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. + + +#![feature(nll)] + +static mut x: &'static u32 = &0; + +fn foo() { + unsafe { x = &1; } +} + +fn main() { } From b9441f2428f501de15dcb00af8da255a70302a0d Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Thu, 1 Feb 2018 08:15:38 +1100 Subject: [PATCH 04/10] Improve char escaping in lexer messages Currently ', " and \ are escaped as \', \" and \\ respectively. This leads to confusing messages such as `error: unknown start of token: \\` when encountering a single backslash. Fix by emitting printable ASCII characters directly. This will still escape \r, \n, \t and Unicode characters. Fixes #47902 --- src/libsyntax/parse/lexer/mod.rs | 31 +++++++++++++--------- src/test/parse-fail/bad-char-literals.rs | 2 +- src/test/parse-fail/lex-stray-backslash.rs | 13 +++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 src/test/parse-fail/lex-stray-backslash.rs diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0fd069b76aadc..11ab84a572916 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -246,14 +246,27 @@ impl<'a> StringReader<'a> { self.err_span(self.mk_sp(from_pos, to_pos), m) } + /// Pushes a character to a message string for error reporting + fn push_escaped_char_for_msg(m: &mut String, c: char) { + match c { + '\u{20}'...'\u{7e}' => { + // Don't escape \, ' or " for user-facing messages + m.push(c); + } + _ => { + for c in c.escape_default() { + m.push(c); + } + } + } + } + /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an /// escaped character to the error message fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> FatalError { let mut m = m.to_string(); m.push_str(": "); - for c in c.escape_default() { - m.push(c) - } + Self::push_escaped_char_for_msg(&mut m, c); self.fatal_span_(from_pos, to_pos, &m[..]) } fn struct_fatal_span_char(&self, @@ -264,9 +277,7 @@ impl<'a> StringReader<'a> { -> DiagnosticBuilder<'a> { let mut m = m.to_string(); m.push_str(": "); - for c in c.escape_default() { - m.push(c) - } + Self::push_escaped_char_for_msg(&mut m, c); self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..]) } @@ -275,9 +286,7 @@ impl<'a> StringReader<'a> { fn err_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) { let mut m = m.to_string(); m.push_str(": "); - for c in c.escape_default() { - m.push(c) - } + Self::push_escaped_char_for_msg(&mut m, c); self.err_span_(from_pos, to_pos, &m[..]); } fn struct_err_span_char(&self, @@ -288,9 +297,7 @@ impl<'a> StringReader<'a> { -> DiagnosticBuilder<'a> { let mut m = m.to_string(); m.push_str(": "); - for c in c.escape_default() { - m.push(c) - } + Self::push_escaped_char_for_msg(&mut m, c); self.sess.span_diagnostic.struct_span_err(self.mk_sp(from_pos, to_pos), &m[..]) } diff --git a/src/test/parse-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs index 96311d6de176c..821015ece7712 100644 --- a/src/test/parse-fail/bad-char-literals.rs +++ b/src/test/parse-fail/bad-char-literals.rs @@ -15,7 +15,7 @@ fn main() { // these literals are just silly. '''; - //~^ ERROR: character constant must be escaped: \' + //~^ ERROR: character constant must be escaped: ' // note that this is a literal "\n" byte ' diff --git a/src/test/parse-fail/lex-stray-backslash.rs b/src/test/parse-fail/lex-stray-backslash.rs new file mode 100644 index 0000000000000..b6042bbdc1a26 --- /dev/null +++ b/src/test/parse-fail/lex-stray-backslash.rs @@ -0,0 +1,13 @@ +// 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. + +// compile-flags: -Z parse-only + +\ //~ ERROR: unknown start of token: \ From cf78ff3913f3efeefb2c90dcae18682f460b0d84 Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Thu, 1 Feb 2018 00:21:43 +0100 Subject: [PATCH 05/10] Fix lang items box example code The `exchange_free` lang item is gone in favour of `box_free` [1]. Some warnings are also fixed by this commit. [1]: https://github.com/rust-lang/rust/commit/ca115dd083a1fe1d2b4892c5e50e49eb83ff1f3 --- .../src/language-features/lang-items.md | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index 0137a052a62d8..c51674186146b 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -37,28 +37,23 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { p } -#[lang = "exchange_free"] -unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { - libc::free(ptr as *mut libc::c_void) -} - #[lang = "box_free"] unsafe fn box_free(ptr: *mut T) { - deallocate(ptr as *mut u8, ::core::mem::size_of_val(&*ptr), ::core::mem::align_of_val(&*ptr)); + libc::free(ptr as *mut libc::c_void) } #[start] -fn main(argc: isize, argv: *const *const u8) -> isize { - let x = box 1; +fn main(_argc: isize, _argv: *const *const u8) -> isize { + let _x = box 1; 0 } #[lang = "eh_personality"] extern fn rust_eh_personality() {} #[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } } -# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} -# #[no_mangle] pub extern fn rust_eh_register_frames () {} -# #[no_mangle] pub extern fn rust_eh_unregister_frames () {} +#[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} +#[no_mangle] pub extern fn rust_eh_register_frames () {} +#[no_mangle] pub extern fn rust_eh_unregister_frames () {} ``` Note the use of `abort`: the `exchange_malloc` lang item is assumed to @@ -80,7 +75,7 @@ Other features provided by lang items include: Lang items are loaded lazily by the compiler; e.g. if one never uses `Box` then there is no need to define functions for `exchange_malloc` -and `exchange_free`. `rustc` will emit an error when an item is needed +and `box_free`. `rustc` will emit an error when an item is needed but not found in the current crate or any that it depends on. Most lang items are defined by `libcore`, but if you're trying to build @@ -318,4 +313,4 @@ the source code. - `phantom_data`: `libcore/marker.rs` - `freeze`: `libcore/marker.rs` - `debug_trait`: `libcore/fmt/mod.rs` - - `non_zero`: `libcore/nonzero.rs` \ No newline at end of file + - `non_zero`: `libcore/nonzero.rs` From e34c31bf02eb0f0ff4dd43ae72e0eae53f2ac519 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Feb 2018 18:35:51 +0000 Subject: [PATCH 06/10] =?UTF-8?q?Use=20constant=20for=20180/=CF=80=20in=20?= =?UTF-8?q?to=5Fdegrees?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current `f32|f64.to_degrees` implementation uses a division to calculate 180/π, which causes a loss of precision. Using a constant is still not perfect (implementing a maximally-precise algorithm would come with a high performance cost), but improves precision with a minimal change. --- src/libcore/num/f32.rs | 4 +++- src/libcore/num/f64.rs | 3 +++ src/libstd/f32.rs | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 207df84d080f2..3586fa5442fb4 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -239,7 +239,9 @@ impl Float for f32 { /// Converts to degrees, assuming the number is in radians. #[inline] fn to_degrees(self) -> f32 { - self * (180.0f32 / consts::PI) + // Use a constant for better precision. + const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32; + self * PIS_IN_180 } /// Converts to radians, assuming the number is in degrees. diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 9206132e8b46f..64c0d508b388c 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -237,6 +237,9 @@ impl Float for f64 { /// Converts to degrees, assuming the number is in radians. #[inline] fn to_degrees(self) -> f64 { + // The division here is correctly rounded with respect to the true + // value of 180/π. (This differs from f32, where a constant must be + // used to ensure a correctly rounded result.) self * (180.0f64 / consts::PI) } diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 9810dede61821..ecf68f29d6f1f 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -1531,6 +1531,7 @@ mod tests { assert!(nan.to_degrees().is_nan()); assert_eq!(inf.to_degrees(), inf); assert_eq!(neg_inf.to_degrees(), neg_inf); + assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703); } #[test] From aaec60836761da35a8d0cf6179769eb9bc9f63c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 1 Feb 2018 11:51:49 -0800 Subject: [PATCH 07/10] Minimize weird spans involving macro context Sometimes the parser attempts to synthesize spans from within a macro context with the span for the captured argument, leading to non-sensical spans with very bad output. Given that an incorrect span is worse than a partially incomplete span, when detecting this situation return only one of the spans without mergin them. --- src/libsyntax_pos/lib.rs | 23 ++++++++++++++----- .../ui/macros/span-covering-argument-1.rs | 23 +++++++++++++++++++ .../ui/macros/span-covering-argument-1.stderr | 13 +++++++++++ .../ui/span/macro-span-replacement.stderr | 4 ++-- 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/macros/span-covering-argument-1.rs create mode 100644 src/test/ui/macros/span-covering-argument-1.stderr diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 85f0925b98210..09e2677eed618 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -361,13 +361,24 @@ impl Span { /// Return a `Span` that would enclose both `self` and `end`. pub fn to(self, end: Span) -> Span { - let span = self.data(); - let end = end.data(); + let span_data = self.data(); + let end_data = end.data(); + // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480) + // Return the macro span on its own to avoid weird diagnostic output. It is preferable to + // have an incomplete span than a completely nonsensical one. + if span_data.ctxt != end_data.ctxt { + if span_data.ctxt == SyntaxContext::empty() { + return end; + } else if end_data.ctxt == SyntaxContext::empty() { + return self; + } + // both span fall within a macro + // FIXME(estebank) check if it is the *same* macro + } Span::new( - cmp::min(span.lo, end.lo), - cmp::max(span.hi, end.hi), - // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480) - if span.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt }, + cmp::min(span_data.lo, end_data.lo), + cmp::max(span_data.hi, end_data.hi), + if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt }, ) } diff --git a/src/test/ui/macros/span-covering-argument-1.rs b/src/test/ui/macros/span-covering-argument-1.rs new file mode 100644 index 0000000000000..bfc137fc7b26d --- /dev/null +++ b/src/test/ui/macros/span-covering-argument-1.rs @@ -0,0 +1,23 @@ +// Copyright 2018 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. + +macro_rules! bad { + ($s:ident whatever) => { + { + let $s = 0; + *&mut $s = 0; + //~^ ERROR cannot borrow immutable local variable `foo` as mutable [E0596] + } + } +} + +fn main() { + bad!(foo whatever); +} diff --git a/src/test/ui/macros/span-covering-argument-1.stderr b/src/test/ui/macros/span-covering-argument-1.stderr new file mode 100644 index 0000000000000..677d2f10fd6c9 --- /dev/null +++ b/src/test/ui/macros/span-covering-argument-1.stderr @@ -0,0 +1,13 @@ +error[E0596]: cannot borrow immutable local variable `foo` as mutable + --> $DIR/span-covering-argument-1.rs:15:19 + | +14 | let $s = 0; + | -- consider changing this to `mut $s` +15 | *&mut $s = 0; + | ^^ cannot borrow mutably +... +22 | bad!(foo whatever); + | ------------------- in this macro invocation + +error: aborting due to previous error + diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index 2a0e71e192c62..728cd12e2c685 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -1,8 +1,8 @@ warning: struct is never used: `S` - --> $DIR/macro-span-replacement.rs:17:9 + --> $DIR/macro-span-replacement.rs:17:14 | 17 | $b $a; //~ WARN struct is never used - | ^^^^^^ + | ^ ... 22 | m!(S struct); | ------------- in this macro invocation From 8b8d044026945fd1dd678c9e33c48bf59b35ad6d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Feb 2018 23:40:23 +0100 Subject: [PATCH 08/10] Fix ugly hover in sidebar --- src/librustdoc/html/static/rustdoc.css | 30 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index d2eeb2e15b3dd..2b1f920bba0b3 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -181,15 +181,19 @@ nav.sub { overflow: auto; } -.sidebar .current { +.sidebar .block > ul > li { margin-right: -20px; } -.content, nav { max-width: 960px; } +.content, nav { + max-width: 960px; +} /* Everything else */ -.js-only, .hidden { display: none !important; } +.js-only, .hidden { + display: none !important; +} .sidebar img { margin: 20px auto; @@ -218,7 +222,9 @@ nav.sub { border: none; } -.location a:first-child { font-weight: 500; } +.location a:first-child { + font-weight: 500; +} .block { padding: 0; @@ -299,7 +305,9 @@ nav.sub { -ms-user-select: none; user-select: none; } -.line-numbers span { cursor: pointer; } +.line-numbers span { + cursor: pointer; +} .docblock-short p { display: inline; @@ -317,7 +325,9 @@ nav.sub { text-overflow: ellipsis; margin: 0; } -.docblock-short code { white-space: nowrap; } +.docblock-short code { + white-space: nowrap; +} .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { border-bottom: 1px solid; @@ -384,7 +394,9 @@ h4 > code, h3 > code, .invisible > code { display: inline-block; } -#main { position: relative; } +#main { + position: relative; +} #main > .since { top: inherit; font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; @@ -428,7 +440,9 @@ h4 > code, h3 > code, .invisible > code { padding: 0; } -.content .item-list li { margin-bottom: 1em; } +.content .item-list li { + margin-bottom: 1em; +} .content .multi-column { -moz-column-count: 5; From c7850139517d209ec9f2879e12cd7bb69cc78a9c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 29 Jan 2018 11:14:55 +0530 Subject: [PATCH 09/10] Remove dead code --- src/librustc_errors/snippet.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs index 6035f33c822ce..7d416f13ffc8a 100644 --- a/src/librustc_errors/snippet.rs +++ b/src/librustc_errors/snippet.rs @@ -10,32 +10,8 @@ // Code for annotating snippets. -use syntax_pos::{Span, FileMap}; -use CodeMapper; -use std::rc::Rc; use Level; -#[derive(Clone)] -pub struct SnippetData { - codemap: Rc, - files: Vec, -} - -#[derive(Clone)] -pub struct FileInfo { - file: Rc, - - /// The "primary file", if any, gets a `-->` marker instead of - /// `>>>`, and has a line-number/column printed and not just a - /// filename (other files are not guaranteed to have line numbers - /// or columns). It appears first in the listing. It is known to - /// contain at least one primary span, though primary spans (which - /// are designated with `^^^`) may also occur in other files. - primary_span: Option, - - lines: Vec, -} - #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Line { pub line_index: usize, From 321e429b9f9318dccd93f0bb637be3a6c926daef Mon Sep 17 00:00:00 2001 From: Per Lundberg Date: Fri, 2 Feb 2018 22:44:14 +0200 Subject: [PATCH 10/10] copy_nonoverlapping example: Fixed typo The comment referred to a variable using an incorrect name. (it has probably been renamed since the comment was written, or the comment was copied elsewhere - I noted the example in libcore has the `tmp` name for the temporary variable.) --- src/libcore/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index a611dc02469e8..a05d67a304fa0 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -992,7 +992,7 @@ extern "rust-intrinsic" { /// ptr::copy_nonoverlapping(y, x, 1); /// ptr::copy_nonoverlapping(&t, y, 1); /// - /// // y and t now point to the same thing, but we need to completely forget `tmp` + /// // y and t now point to the same thing, but we need to completely forget `t` /// // because it's no longer relevant. /// mem::forget(t); /// }