From 1fd2f1687c6483fd3386f838c30332215c3f32b2 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Mon, 25 Feb 2019 16:44:04 +0100 Subject: [PATCH 01/28] Have all methods of Filter and FilterMap use internal iteration --- src/libcore/iter/adapters/mod.rs | 37 ++++++-------------------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index bca1b76dbb975..d4ad22c16bbfa 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -681,12 +681,7 @@ impl Iterator for Filter where P: FnMut(&I::Item) -> bool #[inline] fn next(&mut self) -> Option { - for x in &mut self.iter { - if (self.predicate)(&x) { - return Some(x); - } - } - None + self.try_for_each(Err).err() } #[inline] @@ -707,12 +702,9 @@ impl Iterator for Filter where P: FnMut(&I::Item) -> bool // Using the branchless version will also simplify the LLVM byte code, thus // leaving more budget for LLVM optimizations. #[inline] - fn count(mut self) -> usize { - let mut count = 0; - for x in &mut self.iter { - count += (self.predicate)(&x) as usize; - } - count + fn count(self) -> usize { + let mut predicate = self.predicate; + self.iter.map(|x| predicate(&x) as usize).sum() } #[inline] @@ -746,12 +738,7 @@ impl DoubleEndedIterator for Filter { #[inline] fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if (self.predicate)(&x) { - return Some(x); - } - } - None + self.try_rfold((), |_, x| Err(x)).err() } #[inline] @@ -820,12 +807,7 @@ impl Iterator for FilterMap #[inline] fn next(&mut self) -> Option { - for x in self.iter.by_ref() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None + self.try_for_each(Err).err() } #[inline] @@ -863,12 +845,7 @@ impl DoubleEndedIterator for FilterMap { #[inline] fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None + self.try_rfold((), |_, x| Err(x)).err() } #[inline] From d89c2f67e9a8452ebd3bc2150dd05c160e8a360d Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 20 Feb 2019 22:27:00 +0200 Subject: [PATCH 02/28] Use informational target machine for metadata Since there is nothing to optimise there... --- src/librustc_codegen_llvm/back/write.rs | 10 ---------- src/librustc_codegen_llvm/context.rs | 2 +- src/librustc_codegen_llvm/lib.rs | 10 +++++----- src/librustc_codegen_ssa/back/write.rs | 8 +++++++- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index db5430a4219a0..8f991a9ef490b 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -13,10 +13,8 @@ use crate::common; use crate::LlvmCodegenBackend; use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, run_assembler}; use rustc_codegen_ssa::traits::*; -use rustc::hir::def_id::LOCAL_CRATE; use rustc::session::config::{self, OutputType, Passes, Lto}; use rustc::session::Session; -use rustc::ty::TyCtxt; use rustc_codegen_ssa::{ModuleCodegen, CompiledModule}; use rustc::util::common::time_ext; use rustc_fs_util::{path_to_c_string, link_or_copy}; @@ -82,14 +80,6 @@ pub fn write_output_file( } } -pub fn create_target_machine( - tcx: TyCtxt<'_, '_, '_>, - find_features: bool, -) -> &'static mut llvm::TargetMachine { - target_machine_factory(tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE), find_features)() - .unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise() ) -} - pub fn create_informational_target_machine( sess: &Session, find_features: bool, diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 23e3a8425d370..619304ad9afd0 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -154,7 +154,7 @@ pub unsafe fn create_module( // Ensure the data-layout values hardcoded remain the defaults. if sess.target.target.options.is_builtin { - let tm = crate::back::write::create_target_machine(tcx, false); + let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false); llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm); llvm::LLVMRustDisposeTargetMachine(tm); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 5b8c7461bcb60..38b16078a7d38 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -24,7 +24,7 @@ #![deny(rust_2018_idioms)] #![allow(explicit_outlives_requirements)] -use back::write::create_target_machine; +use back::write::create_informational_target_machine; use syntax_pos::symbol::Symbol; extern crate flate2; @@ -114,8 +114,9 @@ pub struct LlvmCodegenBackend(()); impl ExtraBackendMethods for LlvmCodegenBackend { fn new_metadata(&self, tcx: TyCtxt<'_, '_, '_>, mod_name: &str) -> ModuleLlvm { - ModuleLlvm::new(tcx, mod_name) + ModuleLlvm::new_metadata(tcx, mod_name) } + fn write_metadata<'b, 'gcx>( &self, tcx: TyCtxt<'b, 'gcx, 'gcx>, @@ -366,15 +367,14 @@ unsafe impl Send for ModuleLlvm { } unsafe impl Sync for ModuleLlvm { } impl ModuleLlvm { - fn new(tcx: TyCtxt<'_, '_, '_>, mod_name: &str) -> Self { + fn new_metadata(tcx: TyCtxt<'_, '_, '_>, mod_name: &str) -> Self { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { llmod_raw, llcx, - tm: create_target_machine(tcx, false), + tm: create_informational_target_machine(&tcx.sess, false), } } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 908ee95efcba3..2bade64ddbd34 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1022,7 +1022,13 @@ fn start_executing_work( None }; - let ol = tcx.backend_optimization_level(LOCAL_CRATE); + let ol = if tcx.sess.opts.debugging_opts.no_codegen + || !tcx.sess.opts.output_types.should_codegen() { + // If we know that we won’t be doing codegen, create target machines without optimisation. + config::OptLevel::No + } else { + tcx.backend_optimization_level(LOCAL_CRATE) + }; let cgcx = CodegenContext:: { backend: backend.clone(), crate_types: sess.crate_types.borrow().clone(), From 88847718f0cca57124cbd1bce12fc938c5bde088 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 27 Feb 2019 11:44:30 +0100 Subject: [PATCH 03/28] Add relevant benchmarks --- src/libcore/benches/iter.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index fe852e42b5cd3..5cc2bce846d87 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -306,3 +306,31 @@ fn bench_skip_then_zip(b: &mut Bencher) { assert_eq!(s, 2009900); }); } + +#[bench] +fn bench_filter_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count() + }) +} + +#[bench] +fn bench_filter_ref_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count() + }) +} + +#[bench] +fn bench_filter_chain_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count() + }) +} + +#[bench] +fn bench_filter_chain_ref_count(b: &mut Bencher) { + b.iter(|| { + (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count() + }) +} \ No newline at end of file From ec2e4ba919a65a972019925b5b33d0f309f467fc Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 27 Feb 2019 11:46:37 +0100 Subject: [PATCH 04/28] Improve existing benchmarks to prevent extreme optimizations --- src/libcore/benches/iter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index 5cc2bce846d87..4f3d6f379022b 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -185,13 +185,13 @@ bench_sums! { bench_sums! { bench_filter_sum, bench_filter_ref_sum, - (0i64..1000000).filter(|x| x % 2 == 0) + (0i64..1000000).filter(|x| x % 3 == 0) } bench_sums! { bench_filter_chain_sum, bench_filter_chain_ref_sum, - (0i64..1000000).chain(0..1000000).filter(|x| x % 2 == 0) + (0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0) } bench_sums! { From 88bd624a88692dd4bbda5f3f324f0035dc041534 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 27 Feb 2019 13:22:18 +0100 Subject: [PATCH 05/28] Add trailing newline --- src/libcore/benches/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs index 4f3d6f379022b..1dd2bd3ee78aa 100644 --- a/src/libcore/benches/iter.rs +++ b/src/libcore/benches/iter.rs @@ -333,4 +333,4 @@ fn bench_filter_chain_ref_count(b: &mut Bencher) { b.iter(|| { (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count() }) -} \ No newline at end of file +} From 932fe17c41845c610e193c84b6947581190d782e Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Thu, 21 Feb 2019 20:21:50 -0500 Subject: [PATCH 06/28] rust-lldb: fix crash when printing empty string --- src/etc/lldb_rust_formatters.py | 2 ++ src/test/debuginfo/empty-string.rs | 34 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/test/debuginfo/empty-string.rs diff --git a/src/etc/lldb_rust_formatters.py b/src/etc/lldb_rust_formatters.py index 2c651c90f82eb..fdc1c4fa0cc38 100644 --- a/src/etc/lldb_rust_formatters.py +++ b/src/etc/lldb_rust_formatters.py @@ -290,6 +290,8 @@ def render_element(i): def read_utf8_string(ptr_val, byte_count): + if byte_count == 0: + return '""' error = lldb.SBError() process = ptr_val.get_wrapped_value().GetProcess() data = process.ReadMemory(ptr_val.as_integer(), byte_count, error) diff --git a/src/test/debuginfo/empty-string.rs b/src/test/debuginfo/empty-string.rs new file mode 100644 index 0000000000000..46df427cf829b --- /dev/null +++ b/src/test/debuginfo/empty-string.rs @@ -0,0 +1,34 @@ +// ignore-windows failing on win32 bot +// compile-flags:-g +// min-gdb-version: 7.7 +// min-lldb-version: 310 + +// === GDB TESTS =================================================================================== + +// gdb-command: run + +// gdb-command: print empty_string +// gdb-check:$1 = "" + +// gdb-command: print empty_str +// gdb-check:$2 = "" + +// === LLDB TESTS ================================================================================== + +// lldb-command: run + +// lldb-command: fr v empty_string +// lldb-check:[...]empty_string = "" + +// lldb-command: fr v empty_str +// lldb-check:[...]empty_str = "" + +fn main() { + let empty_string = String::new(); + + let empty_str = ""; + + zzz(); // #break +} + +fn zzz() {} From 4e7d4c7778a00371ba707fb8f9022bcbb443bb29 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 27 Feb 2019 15:32:32 +0100 Subject: [PATCH 07/28] ManuallyDrop != MaybeUninit --- src/libcore/mem.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index f41d293e80ad3..6b1b91d00faa7 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -900,10 +900,16 @@ pub fn discriminant(v: &T) -> Discriminant { } } +// FIXME: Reference `MaybeUninit` from these docs, once that is stable. /// A wrapper to inhibit compiler from automatically calling `T`’s destructor. /// /// This wrapper is 0-cost. /// +/// `ManuallyDrop` is subject to the same layout optimizations as `T`. +/// As a consequence, it has *no effect* on the assumptions that the compiler makes +/// about all values being initialized at their type. In particular, initializing +/// a `ManuallyDrop<&T>` with [`mem::zeroed`] is undefined behavior. +/// /// # Examples /// /// This wrapper helps with explicitly documenting the drop order dependencies between fields of @@ -935,6 +941,8 @@ pub fn discriminant(v: &T) -> Discriminant { /// } /// } /// ``` +/// +/// [`mem::zeroed']: fn.zeroed.html #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] From b70a9532a9d3e2ae4b9bf7bc4a4a0bfc7dbe134b Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Wed, 20 Feb 2019 15:11:22 +0100 Subject: [PATCH 08/28] Replace `s` with `self` in docs for str methods taking self. --- src/libcore/str/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 8b51d8465141a..53334adadb856 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3965,7 +3965,7 @@ impl str { me.make_ascii_lowercase() } - /// Return an iterator that escapes each char in `s` with [`char::escape_debug`]. + /// Return an iterator that escapes each char in `self` with [`char::escape_debug`]. /// /// Note: only extended grapheme codepoints that begin the string will be /// escaped. @@ -4013,7 +4013,7 @@ impl str { } } - /// Return an iterator that escapes each char in `s` with [`char::escape_default`]. + /// Return an iterator that escapes each char in `self` with [`char::escape_default`]. /// /// [`char::escape_default`]: ../std/primitive.char.html#method.escape_default /// @@ -4051,7 +4051,7 @@ impl str { EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) } } - /// Return an iterator that escapes each char in `s` with [`char::escape_unicode`]. + /// Return an iterator that escapes each char in `self` with [`char::escape_unicode`]. /// /// [`char::escape_unicode`]: ../std/primitive.char.html#method.escape_unicode /// From f92c20426ea5f5ddcc6dcf73dbe0739d3d76b614 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 27 Feb 2019 18:58:19 +0100 Subject: [PATCH 09/28] improve readability --- src/libcore/mem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 6b1b91d00faa7..f78213ba9f672 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -908,7 +908,7 @@ pub fn discriminant(v: &T) -> Discriminant { /// `ManuallyDrop` is subject to the same layout optimizations as `T`. /// As a consequence, it has *no effect* on the assumptions that the compiler makes /// about all values being initialized at their type. In particular, initializing -/// a `ManuallyDrop<&T>` with [`mem::zeroed`] is undefined behavior. +/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior. /// /// # Examples /// From a046c38d387f598ee38160ea2e7d5089af4c7c97 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 27 Feb 2019 21:01:42 +0000 Subject: [PATCH 10/28] Make migrate mode work at item level granularity --- src/librustc/middle/expr_use_visitor.rs | 8 +++-- src/librustc_borrowck/borrowck/check_loans.rs | 16 ++++++++++ src/librustc_mir/borrow_check/mod.rs | 28 +++------------- ...e-58776-borrowck-scans-children.ast.stderr | 15 +++++++++ ...776-borrowck-scans-children.migrate.stderr | 32 +++++++++++++++++++ ...e-58776-borrowck-scans-children.nll.stderr | 32 +++++++++++++++++++ .../issue-58776-borrowck-scans-children.rs | 21 ++++++++++++ 7 files changed, 127 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/borrowck/issue-58776-borrowck-scans-children.ast.stderr create mode 100644 src/test/ui/borrowck/issue-58776-borrowck-scans-children.migrate.stderr create mode 100644 src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr create mode 100644 src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 7fc01e302a7d2..9217ac9276fac 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -83,6 +83,9 @@ pub trait Delegate<'tcx> { assignment_span: Span, assignee_cmt: &mc::cmt_<'tcx>, mode: MutateMode); + + // A nested closure or generator - only one layer deep. + fn nested_body(&mut self, _body_id: hir::BodyId) {} } #[derive(Copy, Clone, PartialEq, Debug)] @@ -532,8 +535,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.consume_expr(&base); } - hir::ExprKind::Closure(.., fn_decl_span, _) => { - self.walk_captures(expr, fn_decl_span) + hir::ExprKind::Closure(_, _, body_id, fn_decl_span, _) => { + self.delegate.nested_body(body_id); + self.walk_captures(expr, fn_decl_span); } hir::ExprKind::Box(ref base) => { diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index c74d7f00cf516..11a03f940243f 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -178,6 +178,22 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { } fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) { } + + fn nested_body(&mut self, body_id: hir::BodyId) { + // rust-lang/rust#58776: MIR and AST borrow check disagree on where + // certain closure errors are reported. As such migrate borrowck has to + // operate at the level of items, rather than bodies. Check if the + // contained closure had any errors and set `signalled_any_error` if it + // has. + let bccx = self.bccx; + if bccx.tcx.migrate_borrowck() { + if let SignalledError::NoErrorsSeen = bccx.signalled_any_error.get() { + let closure_def_id = bccx.tcx.hir().body_owner_def_id(body_id); + + bccx.signalled_any_error.set(bccx.tcx.borrowck(closure_def_id).signalled_any_error); + } + } + } } pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 1091646bdd5c6..edd71058dbd02 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -329,30 +329,12 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( // When borrowck=migrate, check if AST-borrowck would // error on the given code. - // rust-lang/rust#55492: loop over parents to ensure that - // errors that AST-borrowck only detects in some parent of - // a closure still allows NLL to signal an error. - let mut curr_def_id = def_id; - let signalled_any_error = loop { - match tcx.borrowck(curr_def_id).signalled_any_error { - SignalledError::NoErrorsSeen => { - // keep traversing (and borrow-checking) parents - } - SignalledError::SawSomeError => { - // stop search here - break SignalledError::SawSomeError; - } - } - - if tcx.is_closure(curr_def_id) { - curr_def_id = tcx.parent_def_id(curr_def_id) - .expect("a closure must have a parent_def_id"); - } else { - break SignalledError::NoErrorsSeen; - } - }; + // rust-lang/rust#55492, rust-lang/rust#58776 check the base def id + // for errors. AST borrowck is responsible for aggregating + // `signalled_any_error` from all of the nested closures here. + let base_def_id = tcx.closure_base_def_id(def_id); - match signalled_any_error { + match tcx.borrowck(base_def_id).signalled_any_error { SignalledError::NoErrorsSeen => { // if AST-borrowck signalled no errors, then // downgrade all the buffered MIR-borrowck errors diff --git a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.ast.stderr b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.ast.stderr new file mode 100644 index 0000000000000..9e0b0aac1e3c6 --- /dev/null +++ b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.ast.stderr @@ -0,0 +1,15 @@ +error[E0597]: `**greeting` does not live long enough + --> $DIR/issue-58776-borrowck-scans-children.rs:10:24 + | +LL | let res = (|| (|| &greeting)())(); + | -- ^^^^^^^^ - borrowed value only lives until here + | | | + | | borrowed value does not live long enough + | capture occurs here +... +LL | } + | - borrowed value needs to live until here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.migrate.stderr b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.migrate.stderr new file mode 100644 index 0000000000000..bd8f2286f170c --- /dev/null +++ b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.migrate.stderr @@ -0,0 +1,32 @@ +error[E0506]: cannot assign to `greeting` because it is borrowed + --> $DIR/issue-58776-borrowck-scans-children.rs:13:5 + | +LL | let res = (|| (|| &greeting)())(); + | -- -------- borrow occurs due to use in closure + | | + | borrow of `greeting` occurs here +... +LL | greeting = "DEALLOCATED".to_string(); + | ^^^^^^^^ assignment to borrowed `greeting` occurs here +... +LL | println!("thread result: {:?}", res); + | --- borrow later used here + +error[E0505]: cannot move out of `greeting` because it is borrowed + --> $DIR/issue-58776-borrowck-scans-children.rs:16:10 + | +LL | let res = (|| (|| &greeting)())(); + | -- -------- borrow occurs due to use in closure + | | + | borrow of `greeting` occurs here +... +LL | drop(greeting); + | ^^^^^^^^ move out of `greeting` occurs here +... +LL | println!("thread result: {:?}", res); + | --- borrow later used here + +error: aborting due to 2 previous errors + +Some errors occurred: E0505, E0506. +For more information about an error, try `rustc --explain E0505`. diff --git a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr new file mode 100644 index 0000000000000..bd8f2286f170c --- /dev/null +++ b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.nll.stderr @@ -0,0 +1,32 @@ +error[E0506]: cannot assign to `greeting` because it is borrowed + --> $DIR/issue-58776-borrowck-scans-children.rs:13:5 + | +LL | let res = (|| (|| &greeting)())(); + | -- -------- borrow occurs due to use in closure + | | + | borrow of `greeting` occurs here +... +LL | greeting = "DEALLOCATED".to_string(); + | ^^^^^^^^ assignment to borrowed `greeting` occurs here +... +LL | println!("thread result: {:?}", res); + | --- borrow later used here + +error[E0505]: cannot move out of `greeting` because it is borrowed + --> $DIR/issue-58776-borrowck-scans-children.rs:16:10 + | +LL | let res = (|| (|| &greeting)())(); + | -- -------- borrow occurs due to use in closure + | | + | borrow of `greeting` occurs here +... +LL | drop(greeting); + | ^^^^^^^^ move out of `greeting` occurs here +... +LL | println!("thread result: {:?}", res); + | --- borrow later used here + +error: aborting due to 2 previous errors + +Some errors occurred: E0505, E0506. +For more information about an error, try `rustc --explain E0505`. diff --git a/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs new file mode 100644 index 0000000000000..378969f9a1867 --- /dev/null +++ b/src/test/ui/borrowck/issue-58776-borrowck-scans-children.rs @@ -0,0 +1,21 @@ +// ignore-compare-mode-nll + +// revisions: ast migrate nll + +//[migrate]compile-flags: -Z borrowck=migrate +#![cfg_attr(nll, feature(nll))] + +fn main() { + let mut greeting = "Hello world!".to_string(); + let res = (|| (|| &greeting)())(); + //[ast]~^ ERROR does not live long enough + + greeting = "DEALLOCATED".to_string(); + //[migrate]~^ ERROR cannot assign + //[nll]~^^ ERROR cannot assign + drop(greeting); + //[migrate]~^ ERROR cannot move + //[nll]~^^ ERROR cannot move + + println!("thread result: {:?}", res); +} From a998b1f425bc13d891ed5b28f1b708970f9db4b4 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 27 Feb 2019 10:56:58 -0500 Subject: [PATCH 11/28] allow specifying attributes for tool lints --- src/librustc/lint/mod.rs | 20 +++++++++++++------ .../ui-fulldeps/auxiliary/lint_tool_test.rs | 6 +++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index dd003e44bea09..496ff568b31b4 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -132,14 +132,22 @@ macro_rules! declare_lint { #[macro_export] macro_rules! declare_tool_lint { - ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr) => ( - declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, false} + ( + $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr + ) => ( + declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false} ); - ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr, - report_in_external_macro: $rep: expr) => ( - declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, $rep} + ( + $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr, + report_in_external_macro: $rep:expr + ) => ( + declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep} ); - ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr, $external: expr) => ( + ( + $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr, + $external:expr + ) => ( + $(#[$attr])* $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: &concat!(stringify!($tool), "::", stringify!($NAME)), default_level: $crate::lint::$Level, diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs index 1a9bd9e66dbac..d25a5ea374627 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs @@ -13,7 +13,11 @@ use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, use rustc_plugin::Registry; use syntax::ast; declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); -declare_tool_lint!(pub clippy::TEST_GROUP, Warn, "Warn about other stuff"); +declare_tool_lint!( + /// Some docs + pub clippy::TEST_GROUP, + Warn, "Warn about other stuff" +); struct Pass; From fc4b916b187b3a57226d9be95276372fe55c3f4b Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:07:12 +0000 Subject: [PATCH 12/28] Add a test for #10876 --- src/test/ui/borrowck/issue-10876.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/ui/borrowck/issue-10876.rs diff --git a/src/test/ui/borrowck/issue-10876.rs b/src/test/ui/borrowck/issue-10876.rs new file mode 100644 index 0000000000000..d8fff5f17760a --- /dev/null +++ b/src/test/ui/borrowck/issue-10876.rs @@ -0,0 +1,19 @@ +// run-pass + +#![feature(nll)] + +enum Nat { + S(Box), + Z +} +fn test(x: &mut Nat) { + let mut p = &mut *x; + loop { + match p { + &mut Nat::Z => break, + &mut Nat::S(ref mut n) => p = &mut *n + } + } +} + +fn main() {} From e206d4e6126eee4e0619b7b99edd03449f90907c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:54:49 +0000 Subject: [PATCH 13/28] Add tests for #26448 --- src/test/ui/issues/issue-26448-1.rs | 13 +++++++++++++ src/test/ui/issues/issue-26448-2.rs | 21 +++++++++++++++++++++ src/test/ui/issues/issue-26448-3.rs | 25 +++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 src/test/ui/issues/issue-26448-1.rs create mode 100644 src/test/ui/issues/issue-26448-2.rs create mode 100644 src/test/ui/issues/issue-26448-3.rs diff --git a/src/test/ui/issues/issue-26448-1.rs b/src/test/ui/issues/issue-26448-1.rs new file mode 100644 index 0000000000000..7d2d75bf2e878 --- /dev/null +++ b/src/test/ui/issues/issue-26448-1.rs @@ -0,0 +1,13 @@ +// run-pass + +pub trait Foo { + fn foo(self) -> T; +} + +impl<'a, T> Foo for &'a str where &'a str: Into { + fn foo(self) -> T { + panic!(); + } +} + +fn main() {} diff --git a/src/test/ui/issues/issue-26448-2.rs b/src/test/ui/issues/issue-26448-2.rs new file mode 100644 index 0000000000000..17e7c1f977a6d --- /dev/null +++ b/src/test/ui/issues/issue-26448-2.rs @@ -0,0 +1,21 @@ +// run-pass + +pub struct Bar { + items: Vec<&'static str>, + inner: T, +} + +pub trait IntoBar { + fn into_bar(self) -> Bar; +} + +impl<'a, T> IntoBar for &'a str where &'a str: Into { + fn into_bar(self) -> Bar { + Bar { + items: Vec::new(), + inner: self.into(), + } + } +} + +fn main() {} diff --git a/src/test/ui/issues/issue-26448-3.rs b/src/test/ui/issues/issue-26448-3.rs new file mode 100644 index 0000000000000..e57352e57f4fc --- /dev/null +++ b/src/test/ui/issues/issue-26448-3.rs @@ -0,0 +1,25 @@ +// run-pass + +pub struct Item { + _inner: &'static str, +} + +pub struct Bar { + items: Vec, + inner: T, +} + +pub trait IntoBar { + fn into_bar(self) -> Bar; +} + +impl<'a, T> IntoBar for &'a str where &'a str: Into { + fn into_bar(self) -> Bar { + Bar { + items: Vec::new(), + inner: self.into(), + } + } +} + +fn main() {} From 93ff7dc25ff7e5146e2bc47bc915a7cd87278c13 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:55:00 +0000 Subject: [PATCH 14/28] Add a test for #26619 --- src/test/ui/issues/issue-26619.rs | 24 ++++++++++++++++++++++++ src/test/ui/issues/issue-26619.stderr | 12 ++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/test/ui/issues/issue-26619.rs create mode 100644 src/test/ui/issues/issue-26619.stderr diff --git a/src/test/ui/issues/issue-26619.rs b/src/test/ui/issues/issue-26619.rs new file mode 100644 index 0000000000000..cd89c674e4996 --- /dev/null +++ b/src/test/ui/issues/issue-26619.rs @@ -0,0 +1,24 @@ +#![feature(slice_patterns)] + +pub struct History<'a> { pub _s: &'a str } + +impl<'a> History<'a> { + pub fn get_page(&self) { + for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) { + //~^ ERROR borrowed value does not live long enough + println!("{:?}", s); + } + } + + fn make_entry(&self, s: &'a String) -> Option<&str> { + let parts: Vec<_> = s.split('|').collect(); + println!("{:?} -> {:?}", s, parts); + + if let [commit, ..] = &parts[..] { Some(commit) } else { None } + } +} + +fn main() { + let h = History{ _s: "" }; + h.get_page(); +} diff --git a/src/test/ui/issues/issue-26619.stderr b/src/test/ui/issues/issue-26619.stderr new file mode 100644 index 0000000000000..3ac6c4e308d21 --- /dev/null +++ b/src/test/ui/issues/issue-26619.stderr @@ -0,0 +1,12 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/issue-26619.rs:7:66 + | +LL | for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) { + | ^^^^^^^^ -- temporary value needs to live until here + | | | + | | temporary value dropped here while still borrowed + | temporary value does not live long enough + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. From 987d71f8f6655e0f79ff3bec1074bcd8793b4b89 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:55:08 +0000 Subject: [PATCH 15/28] Add a test for #44127 --- src/test/ui/issues/issue-44127.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/ui/issues/issue-44127.rs diff --git a/src/test/ui/issues/issue-44127.rs b/src/test/ui/issues/issue-44127.rs new file mode 100644 index 0000000000000..21b2e68264a14 --- /dev/null +++ b/src/test/ui/issues/issue-44127.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(decl_macro)] + +pub struct Foo { + bar: u32, +} +pub macro pattern($a:pat) { + Foo { bar: $a } +} + +fn main() { + match (Foo { bar: 3 }) { + pattern!(3) => println!("Test OK"), + _ => unreachable!(), + } +} From bdd38263c03a7166f550811247902a624c07749f Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:55:16 +0000 Subject: [PATCH 16/28] Add a test for #44255 --- src/test/ui/issues/issue-44255.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/ui/issues/issue-44255.rs diff --git a/src/test/ui/issues/issue-44255.rs b/src/test/ui/issues/issue-44255.rs new file mode 100644 index 0000000000000..2245032043257 --- /dev/null +++ b/src/test/ui/issues/issue-44255.rs @@ -0,0 +1,29 @@ +// run-pass + +use std::marker::PhantomData; + +fn main() { + let _arr = [1; >::VAL]; +} + +trait TypeVal { + const VAL: T; +} + +struct Five; + +impl TypeVal for Five { + const VAL: usize = 5; +} + +struct Multiply { + _n: PhantomData, + _m: PhantomData, +} + +impl TypeVal for Multiply + where N: TypeVal, + M: TypeVal, +{ + const VAL: usize = N::VAL * M::VAL; +} From 36b1326a26959c0dc9e7c06b6b3849653a9b265c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:55:25 +0000 Subject: [PATCH 17/28] Add a test for #46101 --- src/test/ui/issues/issue-46101.rs | 4 ++++ src/test/ui/issues/issue-46101.stderr | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/ui/issues/issue-46101.rs create mode 100644 src/test/ui/issues/issue-46101.stderr diff --git a/src/test/ui/issues/issue-46101.rs b/src/test/ui/issues/issue-46101.rs new file mode 100644 index 0000000000000..2d9111e9b3a98 --- /dev/null +++ b/src/test/ui/issues/issue-46101.rs @@ -0,0 +1,4 @@ +#![feature(use_extern_macros)] +trait Foo {} +#[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro +struct S; diff --git a/src/test/ui/issues/issue-46101.stderr b/src/test/ui/issues/issue-46101.stderr new file mode 100644 index 0000000000000..f8b95d7a23bf2 --- /dev/null +++ b/src/test/ui/issues/issue-46101.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: partially resolved path in a derive macro + --> $DIR/issue-46101.rs:3:10 + | +LL | #[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro + | ^^^^^^^^^^^^^ partially resolved path in a derive macro + +error[E0601]: `main` function not found in crate `issue_46101` + | + = note: consider adding a `main` function to `$DIR/issue-46101.rs` + +error: aborting due to 2 previous errors + +Some errors occurred: E0433, E0601. +For more information about an error, try `rustc --explain E0433`. From 1068424cbfc98fc0d61f8100e31b5361ea008b34 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:55:34 +0000 Subject: [PATCH 18/28] Add a test for #55731 --- src/test/ui/issues/issue-55731.rs | 52 +++++++++++++++++++++++++++ src/test/ui/issues/issue-55731.stderr | 12 +++++++ 2 files changed, 64 insertions(+) create mode 100644 src/test/ui/issues/issue-55731.rs create mode 100644 src/test/ui/issues/issue-55731.stderr diff --git a/src/test/ui/issues/issue-55731.rs b/src/test/ui/issues/issue-55731.rs new file mode 100644 index 0000000000000..7b4f4e2cd3b40 --- /dev/null +++ b/src/test/ui/issues/issue-55731.rs @@ -0,0 +1,52 @@ +use std::marker::PhantomData; + +trait DistributedIterator { + fn reduce(self) + where + Self: Sized, + { + unreachable!() + } +} + +trait DistributedIteratorMulti { + type Item; +} + +struct Connect(PhantomData); +impl DistributedIteratorMulti<&'a ()>> DistributedIterator for Connect where {} + +struct Cloned(PhantomData); +impl<'a, Source> DistributedIteratorMulti<&'a Source> for Cloned<&'a Source> { + type Item = (); +} + +struct Map { + i: I, + f: F, +} +impl, F, Source> DistributedIteratorMulti for Map +where + F: A<>::Item>, +{ + type Item = (); +} + +trait A {} + +struct X; +impl A<()> for X {} + +fn multi(_reducer: I) +where + I: for<'a> DistributedIteratorMulti<&'a ()>, +{ + DistributedIterator::reduce(Connect::(PhantomData)) +} + +fn main() { + multi(Map { //~ ERROR implementation of `DistributedIteratorMulti` is not general enough + i: Cloned(PhantomData), + f: X, + }); +} diff --git a/src/test/ui/issues/issue-55731.stderr b/src/test/ui/issues/issue-55731.stderr new file mode 100644 index 0000000000000..67f2053de1ebe --- /dev/null +++ b/src/test/ui/issues/issue-55731.stderr @@ -0,0 +1,12 @@ +error: implementation of `DistributedIteratorMulti` is not general enough + --> $DIR/issue-55731.rs:48:5 + | +LL | multi(Map { //~ ERROR implementation of `DistributedIteratorMulti` is not general enough + | ^^^^^ + | + = note: Due to a where-clause on `multi`, + = note: `Map, X>` must implement `DistributedIteratorMulti<&'0 ()>`, for any lifetime `'0` + = note: but `Map, X>` actually implements `DistributedIteratorMulti<&'1 ()>`, for some specific lifetime `'1` + +error: aborting due to previous error + From 525dc46018232197f8b4412e3c615f5659e0c567 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:55:43 +0000 Subject: [PATCH 19/28] Add a test for #57781 --- src/test/ui/issues/issue-57781.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/ui/issues/issue-57781.rs diff --git a/src/test/ui/issues/issue-57781.rs b/src/test/ui/issues/issue-57781.rs new file mode 100644 index 0000000000000..f5015aaf5d81f --- /dev/null +++ b/src/test/ui/issues/issue-57781.rs @@ -0,0 +1,20 @@ +// run-pass + +use std::cell::UnsafeCell; +use std::collections::HashMap; + +struct OnceCell { + _value: UnsafeCell>, +} + +impl OnceCell { + const INIT: OnceCell = OnceCell { + _value: UnsafeCell::new(None), + }; +} + +pub fn crash() { + let _ = OnceCell::>::INIT; +} + +fn main() {} From 5fb2d8b68f6efc48db7594ac107acf9f2da4e5bd Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:56:10 +0000 Subject: [PATCH 20/28] Add a test for #22892 --- src/test/ui/asm/invalid-inline-asm.rs | 9 +++++++++ src/test/ui/asm/invalid-inline-asm.stderr | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/ui/asm/invalid-inline-asm.rs create mode 100644 src/test/ui/asm/invalid-inline-asm.stderr diff --git a/src/test/ui/asm/invalid-inline-asm.rs b/src/test/ui/asm/invalid-inline-asm.rs new file mode 100644 index 0000000000000..1dcded0be0b74 --- /dev/null +++ b/src/test/ui/asm/invalid-inline-asm.rs @@ -0,0 +1,9 @@ +#![feature(asm)] + +fn main() { + let byte = 0; + let port = 0x80; + + unsafe { asm!("out %al, %dx" :: "a" (byte), "d" (port) :: "volatile"); } + //~^ ERROR couldn't allocate input reg for constraint 'a' +} diff --git a/src/test/ui/asm/invalid-inline-asm.stderr b/src/test/ui/asm/invalid-inline-asm.stderr new file mode 100644 index 0000000000000..11a32d3141e08 --- /dev/null +++ b/src/test/ui/asm/invalid-inline-asm.stderr @@ -0,0 +1,8 @@ +error: couldn't allocate input reg for constraint 'a' + --> $DIR/invalid-inline-asm.rs:7:14 + | +LL | unsafe { asm!("out %al, %dx" :: "a" (byte), "d" (port) :: "volatile"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 0976e5e7fe8bd7cb072b9392e64081881874ee44 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:56:27 +0000 Subject: [PATCH 21/28] Add a test for #28587 --- src/test/ui/asm/invalid-inline-asm-2.rs | 10 ++++++++++ src/test/ui/asm/invalid-inline-asm-2.stderr | 8 ++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/ui/asm/invalid-inline-asm-2.rs create mode 100644 src/test/ui/asm/invalid-inline-asm-2.stderr diff --git a/src/test/ui/asm/invalid-inline-asm-2.rs b/src/test/ui/asm/invalid-inline-asm-2.rs new file mode 100644 index 0000000000000..7b3f1cdd67949 --- /dev/null +++ b/src/test/ui/asm/invalid-inline-asm-2.rs @@ -0,0 +1,10 @@ +#![feature(asm)] + +fn main() { + let a: usize; + + unsafe { + asm!("" : "=d"(a) : : : ); + //~^ ERROR couldn't allocate output register for constraint 'd' + } +} diff --git a/src/test/ui/asm/invalid-inline-asm-2.stderr b/src/test/ui/asm/invalid-inline-asm-2.stderr new file mode 100644 index 0000000000000..3534a2ea58c7a --- /dev/null +++ b/src/test/ui/asm/invalid-inline-asm-2.stderr @@ -0,0 +1,8 @@ +error: couldn't allocate output register for constraint 'd' + --> $DIR/invalid-inline-asm-2.rs:7:9 + | +LL | asm!("" : "=d"(a) : : : ); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 42a89c6b1794cf6ebe3578a7233c9b6497e87c61 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:56:53 +0000 Subject: [PATCH 22/28] Add a test for #26577 --- .../ui/block-expression-remove-semicolon.rs | 10 ++++++++++ .../ui/block-expression-remove-semicolon.stderr | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/ui/block-expression-remove-semicolon.rs create mode 100644 src/test/ui/block-expression-remove-semicolon.stderr diff --git a/src/test/ui/block-expression-remove-semicolon.rs b/src/test/ui/block-expression-remove-semicolon.rs new file mode 100644 index 0000000000000..afa10b38b9144 --- /dev/null +++ b/src/test/ui/block-expression-remove-semicolon.rs @@ -0,0 +1,10 @@ +fn foo() -> i32 { + 0 +} + +fn main() { + let x: i32 = { + //~^ ERROR mismatched types + foo(); //~ HELP consider removing this semicolon + }; +} diff --git a/src/test/ui/block-expression-remove-semicolon.stderr b/src/test/ui/block-expression-remove-semicolon.stderr new file mode 100644 index 0000000000000..aa4889fc5a577 --- /dev/null +++ b/src/test/ui/block-expression-remove-semicolon.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/block-expression-remove-semicolon.rs:6:18 + | +LL | let x: i32 = { + | __________________^ +LL | | //~^ ERROR mismatched types +LL | | foo(); //~ HELP consider removing this semicolon + | | - help: consider removing this semicolon +LL | | }; + | |_____^ expected i32, found () + | + = note: expected type `i32` + found type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 0df193f39e3c38422452d689fd2e0ef6ce53c1eb Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 25 Feb 2019 23:57:08 +0000 Subject: [PATCH 23/28] Add a test for #27054 --- src/test/ui/primitive-binop-lhs-mut.rs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/ui/primitive-binop-lhs-mut.rs diff --git a/src/test/ui/primitive-binop-lhs-mut.rs b/src/test/ui/primitive-binop-lhs-mut.rs new file mode 100644 index 0000000000000..4f1c456ace354 --- /dev/null +++ b/src/test/ui/primitive-binop-lhs-mut.rs @@ -0,0 +1,6 @@ +// run-pass + +fn main() { + let x = Box::new(0); + assert_eq!(0, *x + { drop(x); let _ = Box::new(main); 0 }); +} From 70b853d6cb964c74d5444e0d7284a49604dfa413 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 26 Feb 2019 20:56:52 +0000 Subject: [PATCH 24/28] Update test for issue #55731 --- src/test/ui/issues/issue-55731.stderr | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/ui/issues/issue-55731.stderr b/src/test/ui/issues/issue-55731.stderr index 67f2053de1ebe..f490b45bf9767 100644 --- a/src/test/ui/issues/issue-55731.stderr +++ b/src/test/ui/issues/issue-55731.stderr @@ -4,9 +4,8 @@ error: implementation of `DistributedIteratorMulti` is not general enough LL | multi(Map { //~ ERROR implementation of `DistributedIteratorMulti` is not general enough | ^^^^^ | - = note: Due to a where-clause on `multi`, - = note: `Map, X>` must implement `DistributedIteratorMulti<&'0 ()>`, for any lifetime `'0` - = note: but `Map, X>` actually implements `DistributedIteratorMulti<&'1 ()>`, for some specific lifetime `'1` + = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0` + = note: but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1` error: aborting due to previous error From 797d8ea4789c64bb20869fa7fb0c15e2c09432cf Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 28 Feb 2019 07:32:13 +0100 Subject: [PATCH 25/28] Make `Unique::as_ptr`, `NonNull::dangling` and `NonNull::cast` const Make `Unique::as_ptr` const without feature attribute as it's unstable Make `NonNull::dangling` and `NonNull::cast` const with `feature = "const_ptr_nonnull"` --- src/libcore/ptr.rs | 8 +++--- src/test/run-pass/consts/const-ptr-nonnull.rs | 17 +++++++++++++ src/test/run-pass/consts/const-ptr-unique.rs | 15 +++++++++++ src/test/ui/consts/const-ptr-nonnull.rs | 11 ++++++++ src/test/ui/consts/const-ptr-nonnull.stderr | 25 +++++++++++++++++++ src/test/ui/consts/const-ptr-unique.rs | 10 ++++++++ src/test/ui/consts/const-ptr-unique.stderr | 14 +++++++++++ 7 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/consts/const-ptr-nonnull.rs create mode 100644 src/test/run-pass/consts/const-ptr-unique.rs create mode 100644 src/test/ui/consts/const-ptr-nonnull.rs create mode 100644 src/test/ui/consts/const-ptr-nonnull.stderr create mode 100644 src/test/ui/consts/const-ptr-unique.rs create mode 100644 src/test/ui/consts/const-ptr-unique.stderr diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 866c8d0896b3c..3e1773ff9d25c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2790,7 +2790,7 @@ impl Unique { } /// Acquires the underlying `*mut` pointer. - pub fn as_ptr(self) -> *mut T { + pub const fn as_ptr(self) -> *mut T { self.pointer as *mut T } @@ -2903,7 +2903,8 @@ impl NonNull { /// some other means. #[stable(feature = "nonnull", since = "1.25.0")] #[inline] - pub fn dangling() -> Self { + #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_ptr_nonnull"))] + pub const fn dangling() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; NonNull::new_unchecked(ptr) @@ -2966,7 +2967,8 @@ impl NonNull { /// Cast to a pointer of another type #[stable(feature = "nonnull_cast", since = "1.27.0")] #[inline] - pub fn cast(self) -> NonNull { + #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_ptr_nonnull"))] + pub const fn cast(self) -> NonNull { unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) } diff --git a/src/test/run-pass/consts/const-ptr-nonnull.rs b/src/test/run-pass/consts/const-ptr-nonnull.rs new file mode 100644 index 0000000000000..91624e92fbe75 --- /dev/null +++ b/src/test/run-pass/consts/const-ptr-nonnull.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(const_ptr_nonnull)] + +use std::ptr::NonNull; + +const DANGLING: NonNull = NonNull::dangling(); +const CASTED: NonNull = NonNull::cast(NonNull::::dangling()); + +fn ident(ident: T) -> T { + ident +} + +pub fn main() { + assert_eq!(DANGLING, ident(NonNull::dangling())); + assert_eq!(CASTED, ident(NonNull::dangling())); +} diff --git a/src/test/run-pass/consts/const-ptr-unique.rs b/src/test/run-pass/consts/const-ptr-unique.rs new file mode 100644 index 0000000000000..eb371ab184166 --- /dev/null +++ b/src/test/run-pass/consts/const-ptr-unique.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(ptr_internals)] + +use std::ptr::Unique; + +const PTR: *mut u32 = Unique::empty().as_ptr(); + +fn ident(ident: T) -> T { + ident +} + +pub fn main() { + assert_eq!(PTR, ident(Unique::::empty().as_ptr())); +} diff --git a/src/test/ui/consts/const-ptr-nonnull.rs b/src/test/ui/consts/const-ptr-nonnull.rs new file mode 100644 index 0000000000000..54e743aa32e23 --- /dev/null +++ b/src/test/ui/consts/const-ptr-nonnull.rs @@ -0,0 +1,11 @@ +use std::ptr::NonNull; + +fn main() { + let x: &'static NonNull = &(NonNull::dangling()); + //~^ ERROR borrowed value does not live long enough + + let mut i: i32 = 10; + let non_null = NonNull::new(&mut i).unwrap(); + let x: &'static NonNull = &(non_null.cast()); + //~^ ERROR borrowed value does not live long enough +} diff --git a/src/test/ui/consts/const-ptr-nonnull.stderr b/src/test/ui/consts/const-ptr-nonnull.stderr new file mode 100644 index 0000000000000..a9476dda6d320 --- /dev/null +++ b/src/test/ui/consts/const-ptr-nonnull.stderr @@ -0,0 +1,25 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/const-ptr-nonnull.rs:4:37 + | +LL | let x: &'static NonNull = &(NonNull::dangling()); + | ^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +... +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error[E0597]: borrowed value does not live long enough + --> $DIR/const-ptr-nonnull.rs:9:37 + | +LL | let x: &'static NonNull = &(non_null.cast()); + | ^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | //~^ ERROR borrowed value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/const-ptr-unique.rs b/src/test/ui/consts/const-ptr-unique.rs new file mode 100644 index 0000000000000..be44a24181606 --- /dev/null +++ b/src/test/ui/consts/const-ptr-unique.rs @@ -0,0 +1,10 @@ +#![feature(ptr_internals)] + +use std::ptr::Unique; + +fn main() { + let mut i: u32 = 10; + let unique = Unique::new(&mut i).unwrap(); + let x: &'static *mut u32 = &(unique.as_ptr()); + //~^ ERROR borrowed value does not live long enough +} diff --git a/src/test/ui/consts/const-ptr-unique.stderr b/src/test/ui/consts/const-ptr-unique.stderr new file mode 100644 index 0000000000000..141465bf184d0 --- /dev/null +++ b/src/test/ui/consts/const-ptr-unique.stderr @@ -0,0 +1,14 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/const-ptr-unique.rs:8:33 + | +LL | let x: &'static *mut u32 = &(unique.as_ptr()); + | ^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | //~^ ERROR borrowed value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. From 0c1a38ce3b281ce23b9ba84312f58ba6ac82af57 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 28 Feb 2019 09:24:35 +0100 Subject: [PATCH 26/28] Update src/libcore/mem.rs Co-Authored-By: RalfJung --- src/libcore/mem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index f78213ba9f672..94f342e7e8efc 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -942,7 +942,7 @@ pub fn discriminant(v: &T) -> Discriminant { /// } /// ``` /// -/// [`mem::zeroed']: fn.zeroed.html +/// [`mem::zeroed`]: fn.zeroed.html #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] From 96be181c7ed004b2892addc22c285b321e029fd9 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Thu, 28 Feb 2019 16:34:03 -0500 Subject: [PATCH 27/28] Fixed a syntax error in the pin docs --- src/libcore/pin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index f9f20dcea9e2e..835357b4e017c 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -215,7 +215,7 @@ //! had a method `fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>`. //! Then we could do the following: //! ```compile_fail -//! fn exploit_ref_cell(rc: Pin<&mut RefCell) { +//! fn exploit_ref_cell(rc: Pin<&mut RefCell>) { //! { let p = rc.as_mut().get_pin_mut(); } // Here we get pinned access to the `T`. //! let rc_shr: &RefCell = rc.into_ref().get_ref(); //! let b = rc_shr.borrow_mut(); From 3391f6ce8083ea860009caa99b415b402feeddd1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 1 Mar 2019 10:14:09 +0100 Subject: [PATCH 28/28] tidy: deny(rust_2018_idioms) --- src/tools/tidy/src/deps.rs | 12 ++++++------ src/tools/tidy/src/features.rs | 2 +- src/tools/tidy/src/lib.rs | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 94dd5478e5297..0169725fa2968 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -49,13 +49,13 @@ const EXCEPTIONS: &[&str] = &[ ]; /// Which crates to check against the whitelist? -const WHITELIST_CRATES: &[CrateVersion] = &[ +const WHITELIST_CRATES: &[CrateVersion<'_>] = &[ CrateVersion("rustc", "0.0.0"), CrateVersion("rustc_codegen_llvm", "0.0.0"), ]; /// Whitelist of crates rustc is allowed to depend on. Avoid adding to the list if possible. -const WHITELIST: &[Crate] = &[ +const WHITELIST: &[Crate<'_>] = &[ Crate("adler32"), Crate("aho-corasick"), Crate("arrayvec"), @@ -183,7 +183,7 @@ struct Crate<'a>(&'a str); // (name) #[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug, Hash)] struct CrateVersion<'a>(&'a str, &'a str); // (name, version) -impl<'a> Crate<'a> { +impl Crate<'_> { pub fn id_str(&self) -> String { format!("{} ", self.0) } @@ -330,10 +330,10 @@ fn get_deps(path: &Path, cargo: &Path) -> Resolve { /// Checks the dependencies of the given crate from the given cargo metadata to see if they are on /// the whitelist. Returns a list of illegal dependencies. -fn check_crate_whitelist<'a, 'b>( - whitelist: &'a HashSet, +fn check_crate_whitelist<'a>( + whitelist: &'a HashSet>, resolve: &'a Resolve, - visited: &'b mut BTreeSet>, + visited: &mut BTreeSet>, krate: CrateVersion<'a>, must_be_on_whitelist: bool, ) -> BTreeSet> { diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 7126c0c2f6ecf..1eab217027c8a 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -22,7 +22,7 @@ pub enum Status { } impl fmt::Display for Status { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let as_str = match *self { Status::Stable => "stable", Status::Unstable => "unstable", diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 022c53f909c75..c4a1246ffdf55 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -3,7 +3,8 @@ //! This library contains the tidy lints and exposes it //! to be used by tools. -extern crate serde; +#![deny(rust_2018_idioms)] + extern crate serde_json; #[macro_use] extern crate serde_derive;