From e396f992558746689e1d562c5a6bb0b92bf70b93 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 23 May 2019 17:47:53 +1000 Subject: [PATCH 1/5] Don't arena-allocate static symbols. It's just a waste of memory. This also gets rid of the special case for "". --- src/libsyntax_pos/symbol.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index b1e1a056db4..26422e891c5 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -866,20 +866,13 @@ pub struct Interner { } impl Interner { - fn prefill(init: &[&str]) -> Self { - let mut this = Interner::default(); - this.names.reserve(init.len()); - this.strings.reserve(init.len()); - - // We can't allocate empty strings in the arena, so handle this here. - assert!(kw::Invalid.as_u32() == 0 && init[0].is_empty()); - this.names.insert("", kw::Invalid); - this.strings.push(""); - - for string in &init[1..] { - this.intern(string); + fn prefill(init: &[&'static str]) -> Self { + let symbols = (0 .. init.len() as u32).map(Symbol::new); + Interner { + strings: init.to_vec(), + names: init.iter().copied().zip(symbols).collect(), + ..Default::default() } - this } pub fn intern(&mut self, string: &str) -> Symbol { From e8beea701955dcce855d1ac72ccd4c9d54f8382c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 24 May 2019 15:38:42 +0200 Subject: [PATCH 2/5] Make eval_place iterate instead of recurse --- src/librustc_mir/interpret/place.rs | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 65e5e23e384..57d5ab71eca 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -607,42 +607,42 @@ where /// place; for reading, a more efficient alternative is `eval_place_for_read`. pub fn eval_place( &mut self, - mir_place: &mir::Place<'tcx> + mir_place: &mir::Place<'tcx>, ) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> { - use rustc::mir::Place::*; use rustc::mir::PlaceBase; - let place = match mir_place { - Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place { - Some(return_place) => - // We use our layout to verify our assumption; caller will validate - // their layout on return. - PlaceTy { - place: *return_place, - layout: self.layout_of(self.monomorphize(self.frame().mir.return_ty())?)?, - }, - None => return err!(InvalidNullPointerUsage), - }, - Base(PlaceBase::Local(local)) => PlaceTy { - // This works even for dead/uninitialized locals; we check further when writing - place: Place::Local { - frame: self.cur_frame(), - local: *local, + + mir_place.iterate(|place_base, place_projection| { + let mut place = match place_base { + PlaceBase::Local(mir::RETURN_PLACE) => match self.frame().return_place { + Some(return_place) => { + // We use our layout to verify our assumption; caller will validate + // their layout on return. + PlaceTy { + place: *return_place, + layout: self + .layout_of(self.monomorphize(self.frame().mir.return_ty())?)?, + } + } + None => return err!(InvalidNullPointerUsage), }, - layout: self.layout_of_local(self.frame(), *local, None)?, - }, + PlaceBase::Local(local) => PlaceTy { + // This works even for dead/uninitialized locals; we check further when writing + place: Place::Local { + frame: self.cur_frame(), + local: *local, + }, + layout: self.layout_of_local(self.frame(), *local, None)?, + }, + PlaceBase::Static(place_static) => self.eval_static_to_mplace(place_static)?.into(), + }; - Projection(proj) => { - let place = self.eval_place(&proj.base)?; - self.place_projection(place, &proj.elem)? + for proj in place_projection { + place = self.place_projection(place, &proj.elem)? } - Base(PlaceBase::Static(place_static)) => { - self.eval_static_to_mplace(place_static)?.into() - } - }; - - self.dump_place(place.place); - Ok(place) + self.dump_place(place.place); + Ok(place) + }) } /// Write a scalar to a place From a0700d062e242940cf9e5644211f2be38e3d88eb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 24 May 2019 00:40:41 +0200 Subject: [PATCH 3/5] Inline move_path_for_projection inside move_path_for --- .../dataflow/move_paths/builder.rs | 114 ++++++++---------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 7eb4428bf29..507e5a4abab 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -101,7 +101,59 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { Err(MoveError::cannot_move_out_of(self.loc, Static)) } Place::Projection(ref proj) => { - self.move_path_for_projection(place, proj) + let base = self.move_path_for(&proj.base)?; + let mir = self.builder.mir; + let tcx = self.builder.tcx; + let place_ty = proj.base.ty(mir, tcx).ty; + match place_ty.sty { + ty::Ref(..) | ty::RawPtr(..) => + return Err(MoveError::cannot_move_out_of( + self.loc, + BorrowedContent { target_place: place.clone() })), + ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => + return Err(MoveError::cannot_move_out_of(self.loc, + InteriorOfTypeWithDestructor { + container_ty: place_ty + })), + // move out of union - always move the entire union + ty::Adt(adt, _) if adt.is_union() => + return Err(MoveError::UnionMove { path: base }), + ty::Slice(_) => + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { + ty: place_ty, is_index: match proj.elem { + ProjectionElem::Index(..) => true, + _ => false + }, + })), + ty::Array(..) => match proj.elem { + ProjectionElem::Index(..) => + return Err(MoveError::cannot_move_out_of( + self.loc, + InteriorOfSliceOrArray { + ty: place_ty, is_index: true + })), + _ => { + // FIXME: still badly broken + } + }, + _ => {} + }; + match self.builder.data.rev_lookup.projections.entry((base, proj.elem.lift())) { + Entry::Occupied(ent) => Ok(*ent.get()), + Entry::Vacant(ent) => { + let path = MoveDataBuilder::new_move_path( + &mut self.builder.data.move_paths, + &mut self.builder.data.path_map, + &mut self.builder.data.init_path_map, + Some(base), + place.clone() + ); + ent.insert(path); + Ok(path) + } + } } } } @@ -111,66 +163,6 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { // drop), so this not being a valid move path is OK. let _ = self.move_path_for(place); } - - fn move_path_for_projection(&mut self, - place: &Place<'tcx>, - proj: &Projection<'tcx>) - -> Result> - { - let base = self.move_path_for(&proj.base)?; - let mir = self.builder.mir; - let tcx = self.builder.tcx; - let place_ty = proj.base.ty(mir, tcx).ty; - match place_ty.sty { - ty::Ref(..) | ty::RawPtr(..) => - return Err(MoveError::cannot_move_out_of( - self.loc, - BorrowedContent { target_place: place.clone() })), - ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => - return Err(MoveError::cannot_move_out_of(self.loc, - InteriorOfTypeWithDestructor { - container_ty: place_ty - })), - // move out of union - always move the entire union - ty::Adt(adt, _) if adt.is_union() => - return Err(MoveError::UnionMove { path: base }), - ty::Slice(_) => - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfSliceOrArray { - ty: place_ty, is_index: match proj.elem { - ProjectionElem::Index(..) => true, - _ => false - }, - })), - ty::Array(..) => match proj.elem { - ProjectionElem::Index(..) => - return Err(MoveError::cannot_move_out_of( - self.loc, - InteriorOfSliceOrArray { - ty: place_ty, is_index: true - })), - _ => { - // FIXME: still badly broken - } - }, - _ => {} - }; - match self.builder.data.rev_lookup.projections.entry((base, proj.elem.lift())) { - Entry::Occupied(ent) => Ok(*ent.get()), - Entry::Vacant(ent) => { - let path = MoveDataBuilder::new_move_path( - &mut self.builder.data.move_paths, - &mut self.builder.data.path_map, - &mut self.builder.data.init_path_map, - Some(base), - place.clone() - ); - ent.insert(path); - Ok(path) - } - } - } } impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> { From 294dc18208e8338631a30767ed0394066638eabf Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 24 May 2019 00:52:10 +0200 Subject: [PATCH 4/5] Make move_path_for iterate instead of recurse --- .../dataflow/move_paths/builder.rs | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 507e5a4abab..ab0a2d87302 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -95,13 +95,15 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { -> Result> { debug!("lookup({:?})", place); - match *place { - Place::Base(PlaceBase::Local(local)) => Ok(self.builder.data.rev_lookup.locals[local]), - Place::Base(PlaceBase::Static(..)) => { - Err(MoveError::cannot_move_out_of(self.loc, Static)) - } - Place::Projection(ref proj) => { - let base = self.move_path_for(&proj.base)?; + place.iterate(|place_base, place_projection| { + let mut base = match place_base { + PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[*local], + PlaceBase::Static(..) => { + return Err(MoveError::cannot_move_out_of(self.loc, Static)); + } + }; + + for proj in place_projection { let mir = self.builder.mir; let tcx = self.builder.tcx; let place_ty = proj.base.ty(mir, tcx).ty; @@ -109,7 +111,9 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { ty::Ref(..) | ty::RawPtr(..) => return Err(MoveError::cannot_move_out_of( self.loc, - BorrowedContent { target_place: place.clone() })), + BorrowedContent { + target_place: Place::Projection(Box::new(proj.clone())), + })), ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => return Err(MoveError::cannot_move_out_of(self.loc, InteriorOfTypeWithDestructor { @@ -140,22 +144,31 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { }, _ => {} }; - match self.builder.data.rev_lookup.projections.entry((base, proj.elem.lift())) { - Entry::Occupied(ent) => Ok(*ent.get()), + + base = match self + .builder + .data + .rev_lookup + .projections + .entry((base, proj.elem.lift())) + { + Entry::Occupied(ent) => *ent.get(), Entry::Vacant(ent) => { let path = MoveDataBuilder::new_move_path( &mut self.builder.data.move_paths, &mut self.builder.data.path_map, &mut self.builder.data.init_path_map, Some(base), - place.clone() + Place::Projection(Box::new(proj.clone())), ); ent.insert(path); - Ok(path) + path } - } + }; } - } + + Ok(base) + }) } fn create_move_path(&mut self, place: &Place<'tcx>) { From dbf8c6df9dc7f8ac0fe9b16f14f007d2f5bc4a5c Mon Sep 17 00:00:00 2001 From: airt Date: Sun, 26 May 2019 12:17:33 +0800 Subject: [PATCH 5/5] docs: fix typo #61197 --- src/doc/rustdoc/src/the-doc-attribute.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index b165c5a6b3b..80ac405eb2f 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -202,7 +202,7 @@ mod bar { Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere. One special case: In Rust 2018 and later, if you `pub use` one of your dependencies, `rustdoc` will -not eagerly inline it as a module unless you add `#[doc(inline)}`. +not eagerly inline it as a module unless you add `#[doc(inline)]`. ## `#[doc(hidden)]`