diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 201129b92df05..e9c27a3f3cf31 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -697,9 +697,6 @@ impl Step for Rustc { return; } - // Build libstd docs so that we generate relative links. - builder.ensure(Std { stage, target }); - // Build rustc. builder.ensure(compile::Rustc { compiler, target }); @@ -718,12 +715,16 @@ impl Step for Rustc { // Find dependencies for top level crates. let mut compiler_crates = HashSet::new(); - for root_crate in &["rustc", "rustc_driver", "rustc_codegen_llvm"] { + for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] { let interned_root_crate = INTERNER.intern_str(root_crate); find_compiler_crates(builder, &interned_root_crate, &mut compiler_crates); } for krate in &compiler_crates { + // Create all crate output directories first to make sure rustdoc uses + // relative links. + // FIXME: Cargo should probably do this itself. + t!(fs::create_dir_all(out_dir.join(krate))); cargo.arg("-p").arg(krate); } @@ -797,8 +798,8 @@ impl Step for Rustdoc { return; } - // Build libstd docs so that we generate relative links. - builder.ensure(Std { stage, target }); + // Build rustc docs so that we generate relative links. + builder.ensure(Rustc { stage, target }); // Build rustdoc. builder.ensure(tool::Rustdoc { host: compiler.host }); @@ -822,6 +823,10 @@ impl Step for Rustdoc { &[] ); + // Only include compiler crates, no dependencies of those, such as `libc`. + cargo.arg("--no-deps"); + cargo.arg("-p").arg("rustdoc"); + cargo.env("RUSTDOCFLAGS", "--document-private-items"); builder.run(&mut cargo); } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 3ca6de191de2d..c0a947e701108 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1187,8 +1187,9 @@ impl, U: ?Sized> DispatchFromDyn> for Weak {} impl Weak { /// Constructs a new `Weak`, without allocating any memory. - /// Calling [`upgrade`][Weak::upgrade] on the return value always gives [`None`]. + /// Calling [`upgrade`] on the return value always gives [`None`]. /// + /// [`upgrade`]: #method.upgrade /// [`None`]: ../../std/option/enum.Option.html /// /// # Examples @@ -1260,6 +1261,52 @@ impl Weak { Some(unsafe { self.ptr.as_ref() }) } } + + /// Returns true if the two `Weak`s point to the same value (not just values + /// that compare as equal). + /// + /// # Notes + /// + /// Since this compares pointers it means that `Weak::new()` will equal each + /// other, even though they don't point to any value. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::rc::{Rc, Weak}; + /// + /// let first_rc = Rc::new(5); + /// let first = Rc::downgrade(&first_rc); + /// let second = Rc::downgrade(&first_rc); + /// + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Rc::new(5); + /// let third = Rc::downgrade(&third_rc); + /// + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + /// + /// Comparing `Weak::new`. + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::rc::{Rc, Weak}; + /// + /// let first = Weak::new(); + /// let second = Weak::new(); + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Rc::new(()); + /// let third = Rc::downgrade(&third_rc); + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + #[inline] + #[unstable(feature = "weak_ptr_eq", issue = "55981")] + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + this.ptr.as_ptr() == other.ptr.as_ptr() + } } #[stable(feature = "rc_weak", since = "1.4.0")] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 4f4031e3c4e32..0a397f79103db 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1130,6 +1130,53 @@ impl Weak { Some(unsafe { self.ptr.as_ref() }) } } + + /// Returns true if the two `Weak`s point to the same value (not just values + /// that compare as equal). + /// + /// # Notes + /// + /// Since this compares pointers it means that `Weak::new()` will equal each + /// other, even though they don't point to any value. + /// + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::sync::{Arc, Weak}; + /// + /// let first_rc = Arc::new(5); + /// let first = Arc::downgrade(&first_rc); + /// let second = Arc::downgrade(&first_rc); + /// + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Arc::new(5); + /// let third = Arc::downgrade(&third_rc); + /// + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + /// + /// Comparing `Weak::new`. + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::sync::{Arc, Weak}; + /// + /// let first = Weak::new(); + /// let second = Weak::new(); + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Arc::new(()); + /// let third = Arc::downgrade(&third_rc); + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + #[inline] + #[unstable(feature = "weak_ptr_eq", issue = "55981")] + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + this.ptr.as_ptr() == other.ptr.as_ptr() + } } #[stable(feature = "arc_weak", since = "1.4.0")] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 8b1855800c2fd..5ba0e949483ae 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -238,6 +238,10 @@ macro_rules! debug_assert_ne { /// with converting downstream errors. /// /// The `?` operator was added to replace `try!` and should be used instead. +/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use +/// it, you will need to use the [raw-identifier syntax][ris]: `r#try`. +/// +/// [ris]: https://doc.rust-lang.org/nightly/rust-by-example/compatibility/raw_identifiers.html /// /// `try!` matches the given [`Result`]. In case of the `Ok` variant, the /// expression has the value of the wrapped value. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index d3a74ed2a6856..c56e91bbe4d2d 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2516,6 +2516,36 @@ pub fn eq(a: *const T, b: *const T) -> bool { a == b } +/// Hash the raw pointer address behind a reference, rather than the value +/// it points to. +/// +/// # Examples +/// +/// ``` +/// #![feature(ptr_hash)] +/// use std::collections::hash_map::DefaultHasher; +/// use std::hash::{Hash, Hasher}; +/// use std::ptr; +/// +/// let five = 5; +/// let five_ref = &five; +/// +/// let mut hasher = DefaultHasher::new(); +/// ptr::hash(five_ref, &mut hasher); +/// let actual = hasher.finish(); +/// +/// let mut hasher = DefaultHasher::new(); +/// (five_ref as *const i32).hash(&mut hasher); +/// let expected = hasher.finish(); +/// +/// assert_eq!(actual, expected); +/// ``` +#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")] +pub fn hash(hashee: *const T, into: &mut S) { + use hash::Hash; + hashee.hash(into); +} + // Impls for function pointers macro_rules! fnptr_impls_safety_abi { ($FnTy: ty, $($Arg: ident),*) => { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 89efa120a6fab..6c953d1b9a0ac 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -536,10 +536,9 @@ fn next_code_point_reverse<'a, I>(bytes: &mut I) -> Option where I: DoubleEndedIterator, { // Decode UTF-8 - let w = match bytes.next_back() { - None => return None, - Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32), - Some(&back_byte) => back_byte, + let w = match *bytes.next_back()? { + next_byte if next_byte < 128 => return Some(next_byte as u32), + back_byte => back_byte, }; // Multibyte case follows diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 282b5d13e2c61..bb7a6a6ee7b72 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -166,6 +166,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) | hir::ItemKind::Static(..) + | hir::ItemKind::Existential(..) | hir::ItemKind::Const(..) => { intravisit::walk_item(self, &item); } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 35d1a4dd2cb7c..3c2551f5cd436 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -592,10 +592,7 @@ impl<'tcx> ScopeTree { return Some(scope.item_local_id()); } - match self.opt_encl_scope(scope) { - None => return None, - Some(parent) => scope = parent, - } + scope = self.opt_encl_scope(scope)?; } } diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 768d4f1e5fb65..6b0a8a0af2b9d 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -67,14 +67,13 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option<(&'a Path, PathKind)> { loop { - match self.iter.next() { - Some(&(kind, ref p)) if self.kind == PathKind::All || - kind == PathKind::All || - kind == self.kind => { + match *self.iter.next()? { + (kind, ref p) if self.kind == PathKind::All || + kind == PathKind::All || + kind == self.kind => { return Some((p, kind)) } - Some(..) => {} - None => return None, + _ => {} } } } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index a802729e3fbdb..e47e95afb1643 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -615,7 +615,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { let new_loan_str = &new_loan.kind.to_user_str(); self.bccx.cannot_reborrow_already_uniquely_borrowed( new_loan.span, "closure", &nl, &new_loan_msg, new_loan_str, - old_loan.span, &old_loan_msg, previous_end_span, Origin::Ast) + old_loan.span, &old_loan_msg, previous_end_span, "", Origin::Ast) } (..) => self.bccx.cannot_reborrow_already_borrowed( diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 96cb235a93362..8e0ecb70c6896 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -81,7 +81,6 @@ pub mod sync; pub mod tiny_list; pub mod thin_vec; pub mod transitive_relation; -pub mod tuple_slice; pub use ena::unify; pub mod vec_linked_list; pub mod work_queue; diff --git a/src/librustc_data_structures/tuple_slice.rs b/src/librustc_data_structures/tuple_slice.rs deleted file mode 100644 index b7c71dd366469..0000000000000 --- a/src/librustc_data_structures/tuple_slice.rs +++ /dev/null @@ -1,70 +0,0 @@ -// 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. - -use std::slice; - -/// Allows to view uniform tuples as slices -pub trait TupleSlice { - fn as_slice(&self) -> &[T]; - fn as_mut_slice(&mut self) -> &mut [T]; -} - -macro_rules! impl_tuple_slice { - ($tuple_type:ty, $size:expr) => { - impl TupleSlice for $tuple_type { - fn as_slice(&self) -> &[T] { - unsafe { - let ptr = &self.0 as *const T; - slice::from_raw_parts(ptr, $size) - } - } - - fn as_mut_slice(&mut self) -> &mut [T] { - unsafe { - let ptr = &mut self.0 as *mut T; - slice::from_raw_parts_mut(ptr, $size) - } - } - } - } -} - -impl_tuple_slice!((T, T), 2); -impl_tuple_slice!((T, T, T), 3); -impl_tuple_slice!((T, T, T, T), 4); -impl_tuple_slice!((T, T, T, T, T), 5); -impl_tuple_slice!((T, T, T, T, T, T), 6); -impl_tuple_slice!((T, T, T, T, T, T, T), 7); -impl_tuple_slice!((T, T, T, T, T, T, T, T), 8); - -#[test] -fn test_sliced_tuples() { - let t2 = (100, 101); - assert_eq!(t2.as_slice(), &[100, 101]); - - let t3 = (102, 103, 104); - assert_eq!(t3.as_slice(), &[102, 103, 104]); - - let t4 = (105, 106, 107, 108); - assert_eq!(t4.as_slice(), &[105, 106, 107, 108]); - - let t5 = (109, 110, 111, 112, 113); - assert_eq!(t5.as_slice(), &[109, 110, 111, 112, 113]); - - let t6 = (114, 115, 116, 117, 118, 119); - assert_eq!(t6.as_slice(), &[114, 115, 116, 117, 118, 119]); - - let t7 = (120, 121, 122, 123, 124, 125, 126); - assert_eq!(t7.as_slice(), &[120, 121, 122, 123, 124, 125, 126]); - - let t8 = (127, 128, 129, 130, 131, 132, 133, 134); - assert_eq!(t8.as_slice(), &[127, 128, 129, 130, 131, 132, 133, 134]); - -} diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index cfe59b1f67262..ddd28eb5393ec 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -29,7 +29,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( return None } - let saved_files: Option> = + let saved_files = files.iter() .map(|&(kind, ref path)| { let extension = match kind { @@ -51,11 +51,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( } } }) - .collect(); - let saved_files = match saved_files { - None => return None, - Some(v) => v, - }; + .collect::>>()?; let work_product = WorkProduct { cgu_name: cgu_name.to_string(), diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index fd7dc7fc4bd3a..947c32df0f6a3 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -16,7 +16,7 @@ use rustc::mir::traversal; use rustc::mir::visit::{ PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext }; -use rustc::mir::{self, Location, Mir, Place, Local}; +use rustc::mir::{self, Location, Mir, Local}; use rustc::ty::{RegionVid, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; @@ -41,10 +41,6 @@ crate struct BorrowSet<'tcx> { /// only need to store one borrow index crate activation_map: FxHashMap>, - /// Every borrow has a region; this maps each such regions back to - /// its borrow-indexes. - crate region_map: FxHashMap>, - /// Map from local to all the borrows on that local crate local_map: FxHashMap>, @@ -149,7 +145,6 @@ impl<'tcx> BorrowSet<'tcx> { idx_vec: IndexVec::new(), location_map: Default::default(), activation_map: Default::default(), - region_map: Default::default(), local_map: Default::default(), pending_activations: Default::default(), locals_state_at_exit: @@ -164,7 +159,6 @@ impl<'tcx> BorrowSet<'tcx> { borrows: visitor.idx_vec, location_map: visitor.location_map, activation_map: visitor.activation_map, - region_map: visitor.region_map, local_map: visitor.local_map, locals_state_at_exit: visitor.locals_state_at_exit, } @@ -184,7 +178,6 @@ struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> { idx_vec: IndexVec>, location_map: FxHashMap, activation_map: FxHashMap>, - region_map: FxHashMap>, local_map: FxHashMap>, /// When we encounter a 2-phase borrow statement, it will always @@ -229,7 +222,6 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); - self.region_map.entry(region).or_default().insert(idx); if let Some(local) = borrowed_place.root_local() { self.local_map.entry(local).or_default().insert(idx); } @@ -238,68 +230,68 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { self.super_assign(block, assigned_place, rvalue, location) } - fn visit_place( + fn visit_local( &mut self, - place: &mir::Place<'tcx>, + temp: &Local, context: PlaceContext<'tcx>, location: Location, ) { - self.super_place(place, context, location); - - // We found a use of some temporary TEMP... - if let Place::Local(temp) = place { - // ... check whether we (earlier) saw a 2-phase borrow like - // - // TMP = &mut place - if let Some(&borrow_index) = self.pending_activations.get(temp) { - let borrow_data = &mut self.idx_vec[borrow_index]; - - // Watch out: the use of TMP in the borrow itself - // doesn't count as an activation. =) - if borrow_data.reserve_location == location && - context == PlaceContext::MutatingUse(MutatingUseContext::Store) - { - return; - } + if !context.is_use() { + return; + } - if let TwoPhaseActivation::ActivatedAt(other_location) = - borrow_data.activation_location { - span_bug!( - self.mir.source_info(location).span, - "found two uses for 2-phase borrow temporary {:?}: \ - {:?} and {:?}", - temp, - location, - other_location, - ); - } + // We found a use of some temporary TMP + // check whether we (earlier) saw a 2-phase borrow like + // + // TMP = &mut place + if let Some(&borrow_index) = self.pending_activations.get(temp) { + let borrow_data = &mut self.idx_vec[borrow_index]; - // Otherwise, this is the unique later use - // that we expect. - borrow_data.activation_location = match context { - // The use of TMP in a shared borrow does not - // count as an actual activation. - PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) => - TwoPhaseActivation::NotActivated, - _ => { - // Double check: This borrow is indeed a two-phase borrow (that is, - // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and - // we've not found any other activations (checked above). - assert_eq!( - borrow_data.activation_location, - TwoPhaseActivation::NotActivated, - "never found an activation for this borrow!", - ); - - self.activation_map - .entry(location) - .or_default() - .push(borrow_index); - TwoPhaseActivation::ActivatedAt(location) - } - }; + // Watch out: the use of TMP in the borrow itself + // doesn't count as an activation. =) + if borrow_data.reserve_location == location && + context == PlaceContext::MutatingUse(MutatingUseContext::Store) + { + return; + } + + if let TwoPhaseActivation::ActivatedAt(other_location) = + borrow_data.activation_location { + span_bug!( + self.mir.source_info(location).span, + "found two uses for 2-phase borrow temporary {:?}: \ + {:?} and {:?}", + temp, + location, + other_location, + ); } + + // Otherwise, this is the unique later use + // that we expect. + borrow_data.activation_location = match context { + // The use of TMP in a shared borrow does not + // count as an actual activation. + PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) => + TwoPhaseActivation::NotActivated, + _ => { + // Double check: This borrow is indeed a two-phase borrow (that is, + // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and + // we've not found any other activations (checked above). + assert_eq!( + borrow_data.activation_location, + TwoPhaseActivation::NotActivated, + "never found an activation for this borrow!", + ); + + self.activation_map + .entry(location) + .or_default() + .push(borrow_index); + TwoPhaseActivation::ActivatedAt(location) + } + }; } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 4ccd26bee8b88..ba26ed36c20f4 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -344,6 +344,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let first_borrow_desc; + let explanation = self.explain_why_borrow_contains_point(context, issued_borrow, None); + let second_borrow_desc = if explanation.is_explained() { + "second " + } else { + "" + }; + // FIXME: supply non-"" `opt_via` when appropriate let mut err = match ( gen_borrow_kind, @@ -454,6 +461,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { issued_span, "", None, + second_borrow_desc, Origin::Mir, ) } @@ -469,6 +477,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { issued_span, "", None, + second_borrow_desc, Origin::Mir, ) } @@ -513,7 +522,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); } - self.explain_why_borrow_contains_point(context, issued_borrow, None) + explanation .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc); err.buffer(&mut self.errors_buffer); diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index bb9a29b055b7f..477b78926084e 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -52,6 +52,12 @@ pub(in borrow_check) enum LaterUseKind { } impl BorrowExplanation { + pub(in borrow_check) fn is_explained(&self) -> bool { + match self { + BorrowExplanation::Unexplained => false, + _ => true, + } + } pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>( &self, tcx: TyCtxt<'cx, 'gcx, 'tcx>, diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index f73e08eb13521..7d583b4f54191 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -87,10 +87,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> { type Item = &'cx Place<'tcx>; fn next(&mut self) -> Option { - let mut cursor = match self.next { - None => return None, - Some(place) => place, - }; + let mut cursor = self.next?; // Post-processing `place`: Enqueue any remaining // work. Also, `place` may not be a prefix itself, but diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 27bc28ac81d84..3a9e4fc9e4ab9 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { // re-consider the current implementations of the // propagate_call_return method. - if let mir::Rvalue::Ref(region, _, ref place) = **rhs { + if let mir::Rvalue::Ref(_, _, ref place) = **rhs { if place.ignore_borrow( self.tcx, self.mir, @@ -258,13 +258,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { panic!("could not find BorrowIndex for location {:?}", location); }); - assert!(self.borrow_set.region_map - .get(®ion.to_region_vid()) - .unwrap_or_else(|| { - panic!("could not find BorrowIndexs for RegionVid {:?}", region); - }) - .contains(&index) - ); sets.gen(*index); // Issue #46746: Two-phase borrows handles diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 3a6ee6da42215..528942df29fee 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -585,7 +585,7 @@ fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, // smallest into each other) we're sure to start off with a deterministic // order (sorted by name). This'll mean that if two cgus have the same size // the stable sort below will keep everything nice and deterministic. - codegen_units.sort_by_key(|cgu| cgu.name().clone()); + codegen_units.sort_by_key(|cgu| *cgu.name()); // Merge the two smallest codegen units until the target size is reached. while codegen_units.len() > target_cgu_count { @@ -985,7 +985,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); - cgus.as_mut_slice().sort_by_cached_key(|&(ref name, _)| name.clone()); + cgus.sort_by_key(|(name, _)| *name); cgus.dedup(); for &(ref cgu_name, (linkage, _)) in cgus.iter() { output.push_str(" "); diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index c0edd3926d32d..6d7fc404edbb1 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -10,17 +10,25 @@ //! This module provides two passes: //! -//! - [CleanAscribeUserType], that replaces all -//! [StatementKind::AscribeUserType] statements with [StatementKind::Nop]. -//! - [CleanFakeReadsAndBorrows], that replaces all [FakeRead] statements and -//! borrows that are read by [FakeReadCause::ForMatchGuard] fake reads with -//! [StatementKind::Nop]. +//! - [`CleanAscribeUserType`], that replaces all [`AscribeUserType`] +//! statements with [`Nop`]. +//! - [`CleanFakeReadsAndBorrows`], that replaces all [`FakeRead`] statements +//! and borrows that are read by [`ForMatchGuard`] fake reads with [`Nop`]. //! -//! The [CleanFakeReadsAndBorrows] "pass" is actually implemented as two +//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two //! traversals (aka visits) of the input MIR. The first traversal, -//! [DeleteAndRecordFakeReads], deletes the fake reads and finds the temporaries -//! read by [ForMatchGuard] reads, and [DeleteFakeBorrows] deletes the -//! initialization of those temporaries. +//! [`DeleteAndRecordFakeReads`], deletes the fake reads and finds the +//! temporaries read by [`ForMatchGuard`] reads, and [`DeleteFakeBorrows`] +//! deletes the initialization of those temporaries. +//! +//! [`CleanAscribeUserType`]: cleanup_post_borrowck::CleanAscribeUserType +//! [`CleanFakeReadsAndBorrows`]: cleanup_post_borrowck::CleanFakeReadsAndBorrows +//! [`DeleteAndRecordFakeReads`]: cleanup_post_borrowck::DeleteAndRecordFakeReads +//! [`DeleteFakeBorrows`]: cleanup_post_borrowck::DeleteFakeBorrows +//! [`AscribeUserType`]: rustc::mir::StatementKind::AscribeUserType +//! [`Nop`]: rustc::mir::StatementKind::Nop +//! [`FakeRead`]: rustc::mir::StatementKind::FakeRead +//! [`ForMatchGuard`]: rustc::mir::FakeReadCause::ForMatchGuard use rustc_data_structures::fx::FxHashSet; diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index ae0483e3c140c..8566f845f23e3 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -261,6 +261,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { old_loan_span: Span, old_opt_via: &str, previous_end_span: Option, + second_borrow_desc: &str, o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( @@ -274,7 +275,10 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { kind_new, OGN = o ); - err.span_label(new_loan_span, format!("borrow occurs here{}", opt_via)); + err.span_label( + new_loan_span, + format!("{}borrow occurs here{}", second_borrow_desc, opt_via), + ); err.span_label( old_loan_span, format!("{} construction occurs here{}", container_name, old_opt_via), diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0fa41cb484fc9..da4cd73923ede 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -318,7 +318,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // This particular use tree &tree, id, &prefix, true, // The whole `use` item - parent_scope.clone(), item, ty::Visibility::Invisible, root_span, + parent_scope, item, ty::Visibility::Invisible, root_span, ); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fd8f70b19e7ec..b0f3dcbd72ebb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -708,8 +708,6 @@ impl> NestedAttributesExt for I { /// kept separate because of issue #42760. #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] pub enum DocFragment { - // FIXME #44229 (misdreavus): sugared and raw doc comments can be brought back together once - // hoedown is completely removed from rustdoc. /// A doc fragment created from a `///` or `//!` doc comment. SugaredDoc(usize, syntax_pos::Span, String), /// A doc fragment created from a "raw" `#[doc=""]` attribute. @@ -3948,10 +3946,7 @@ pub fn path_to_def_local(tcx: &TyCtxt, path: &[&str]) -> Option { let mut path_it = path.iter().peekable(); loop { - let segment = match path_it.next() { - Some(segment) => segment, - None => return None, - }; + let segment = path_it.next()?; for item_id in mem::replace(&mut items, HirVec::new()).iter() { let item = tcx.hir.expect_item(item_id.id); @@ -3986,10 +3981,7 @@ pub fn path_to_def(tcx: &TyCtxt, path: &[&str]) -> Option { let mut path_it = path.iter().skip(1).peekable(); loop { - let segment = match path_it.next() { - Some(segment) => segment, - None => return None, - }; + let segment = path_it.next()?; for item in mem::replace(&mut items, Lrc::new(vec![])).iter() { if item.ident.name == *segment { diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 5263cfe7b0e4f..fa5d015e5b72d 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -57,6 +57,9 @@ pub fn render( {css_extension}\ {favicon}\ {in_header}\ + \ \ \ $DIR/intra-links-warning.rs:61:30 + | +LL | * time to introduce a link [error]*/ + | ^^^^^ cannot be resolved, ignoring + | + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + +warning: `[error]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:67:30 + | +LL | * time to introduce a link [error] + | ^^^^^ cannot be resolved, ignoring + | + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + +warning: `[error]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:71:1 + | +LL | #[doc = "single line [error]"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + single line [error] + ^^^^^ + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + +warning: `[error]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:74:1 + | +LL | #[doc = "single line with /"escaping/" [error]"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + single line with "escaping" [error] + ^^^^^ + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + +warning: `[error]` cannot be resolved, ignoring it... + --> $DIR/intra-links-warning.rs:77:1 + | +LL | / /// Item docs. +LL | | #[doc="Hello there!"] +LL | | /// [error] + | |___________^ + | + = note: the link appears in this line: + + [error] + ^^^^^ + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + warning: `[BarA]` cannot be resolved, ignoring it... --> $DIR/intra-links-warning.rs:24:10 | @@ -64,37 +118,19 @@ LL | /// bar [BarA] bar = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` warning: `[BarB]` cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:28:1 + --> $DIR/intra-links-warning.rs:30:9 | -LL | / /** -LL | | * Foo -LL | | * bar [BarB] bar -LL | | * baz -LL | | */ - | |___^ +LL | * bar [BarB] bar + | ^^^^ cannot be resolved, ignoring | - = note: the link appears in this line: - - bar [BarB] bar - ^^^^ = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` warning: `[BarC]` cannot be resolved, ignoring it... - --> $DIR/intra-links-warning.rs:35:1 + --> $DIR/intra-links-warning.rs:37:6 | -LL | / /** Foo -LL | | -LL | | bar [BarC] bar -LL | | baz -... | -LL | | -LL | | */ - | |__^ +LL | bar [BarC] bar + | ^^^^ cannot be resolved, ignoring | - = note: the link appears in this line: - - bar [BarC] bar - ^^^^ = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` warning: `[BarD]` cannot be resolved, ignoring it... diff --git a/src/test/ui/E0501.ast.nll.stderr b/src/test/ui/E0501.ast.nll.stderr index 72fda9079d636..8a3fce3a554eb 100644 --- a/src/test/ui/E0501.ast.nll.stderr +++ b/src/test/ui/E0501.ast.nll.stderr @@ -7,7 +7,7 @@ LL | inside_closure(a) | - first borrow occurs due to use of `a` in closure LL | }; LL | outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access - | ^ borrow occurs here + | ^ second borrow occurs here ... LL | drop(bar); | --- first borrow later used here @@ -21,7 +21,7 @@ LL | inside_closure(a) | - first borrow occurs due to use of `a` in closure ... LL | outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access - | ^ borrow occurs here + | ^ second borrow occurs here ... LL | drop(bar); | --- first borrow later used here diff --git a/src/test/ui/E0501.mir.stderr b/src/test/ui/E0501.mir.stderr index 72fda9079d636..8a3fce3a554eb 100644 --- a/src/test/ui/E0501.mir.stderr +++ b/src/test/ui/E0501.mir.stderr @@ -7,7 +7,7 @@ LL | inside_closure(a) | - first borrow occurs due to use of `a` in closure LL | }; LL | outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access - | ^ borrow occurs here + | ^ second borrow occurs here ... LL | drop(bar); | --- first borrow later used here @@ -21,7 +21,7 @@ LL | inside_closure(a) | - first borrow occurs due to use of `a` in closure ... LL | outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access - | ^ borrow occurs here + | ^ second borrow occurs here ... LL | drop(bar); | --- first borrow later used here diff --git a/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr b/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr index 123d475f1c09f..84fc69465cb4a 100644 --- a/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr +++ b/src/test/ui/borrowck/borrowck-insert-during-each.nll.stderr @@ -10,7 +10,7 @@ LL | | |a| { //~ ERROR closure requires unique access to `f` LL | | f.n.insert(*a); | | - first borrow occurs due to use of `f` in closure LL | | }) - | |__________^ borrow occurs here + | |__________^ second borrow occurs here error[E0500]: closure requires unique access to `f` but it is already borrowed --> $DIR/borrowck-insert-during-each.rs:27:9 diff --git a/src/test/ui/existential_types/private_unused.rs b/src/test/ui/existential_types/private_unused.rs new file mode 100644 index 0000000000000..736d812bc0aff --- /dev/null +++ b/src/test/ui/existential_types/private_unused.rs @@ -0,0 +1,13 @@ +// compile-pass + +#[deny(warnings)] + +enum Empty { } +trait Bar {} +impl Bar for () {} + +fn boo() -> impl Bar {} + +fn main() { + boo(); +} diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr index 8dabb3c2505b6..60163d78e78f9 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr @@ -7,7 +7,7 @@ LL | let a = &mut *x; | - first borrow occurs due to use of `x` in generator ... LL | println!("{}", x); //~ ERROR - | ^ borrow occurs here + | ^ second borrow occurs here LL | b.resume(); | - first borrow later used here diff --git a/src/test/ui/nll/closure-borrow-spans.stderr b/src/test/ui/nll/closure-borrow-spans.stderr index 3e423dadd192c..98a261657b1e7 100644 --- a/src/test/ui/nll/closure-borrow-spans.stderr +++ b/src/test/ui/nll/closure-borrow-spans.stderr @@ -126,7 +126,7 @@ LL | let f = || *x = 0; | | | closure construction occurs here LL | let y = &x; //~ ERROR - | ^^ borrow occurs here + | ^^ second borrow occurs here LL | f.use_ref(); | - first borrow later used here @@ -138,7 +138,7 @@ LL | let f = || *x = 0; | | | closure construction occurs here LL | let y = &mut x; //~ ERROR - | ^^^^^^ borrow occurs here + | ^^^^^^ second borrow occurs here LL | f.use_ref(); | - first borrow later used here diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index dd2e5557c16d4..8d20a9e271705 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -119,10 +119,7 @@ fn parse_expected( line: &str, tag: &str, ) -> Option<(WhichLine, Error)> { - let start = match line.find(tag) { - Some(i) => i, - None => return None, - }; + let start = line.find(tag)?; let (follow, adjusts) = if line[start + tag.len()..].chars().next().unwrap() == '|' { (true, 0) } else { diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index ed2114b653015..f4a82aeb307dc 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -707,14 +707,8 @@ impl Config { fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> { if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match { - let from = match parse_normalization_string(&mut line) { - Some(s) => s, - None => return None, - }; - let to = match parse_normalization_string(&mut line) { - Some(s) => s, - None => return None, - }; + let from = parse_normalization_string(&mut line)?; + let to = parse_normalization_string(&mut line)?; Some((from, to)) } else { None @@ -873,14 +867,8 @@ fn expand_variables(mut value: String, config: &Config) -> String { /// ``` fn parse_normalization_string(line: &mut &str) -> Option { // FIXME support escapes in strings. - let begin = match line.find('"') { - Some(i) => i + 1, - None => return None, - }; - let end = match line[begin..].find('"') { - Some(i) => i + begin, - None => return None, - }; + let begin = line.find('"')? + 1; + let end = line[begin..].find('"')? + begin; let result = line[begin..end].to_owned(); *line = &line[end + 1..]; Some(result) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 11c83819eaa93..e6bf9a285723b 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -332,10 +332,7 @@ fn maybe_redirect(source: &str) -> Option { const REDIRECT: &'static str = "

Redirecting to