Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,11 +611,18 @@ fn get_flow_results<'a, 'tcx>(
) -> Results<'tcx, Borrowck<'a, 'tcx>> {
// We compute these three analyses individually, but them combine them into
// a single results so that `mbcx` can visit them all together.
let borrows = Borrows::new(tcx, body, regioncx, borrow_set).iterate_to_fixpoint(
tcx,
body,
Some("borrowck"),
);
let borrows_analysis = Borrows::new(tcx, body, regioncx, borrow_set);
let borrows = if borrow_set.location_map().is_empty() {
// A body without borrows has an empty dataflow domain: every entry
// state is the bottom value, so skip running the fixpoint engine.
let bottom = borrows_analysis.bottom_value(body);
Results {
analysis: borrows_analysis,
entry_states: IndexVec::from_elem_n(bottom, body.basic_blocks.len()),
}
} else {
borrows_analysis.iterate_to_fixpoint(tcx, body, Some("borrowck"))
};
let uninits = MaybeUninitializedPlaces::new(tcx, body, move_data).iterate_to_fixpoint(
tcx,
body,
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,11 @@ impl<'a> TraitDef<'a> {
_ => unreachable!(),
};
// Keep the lint attributes of the previous item to control how the
// generated implementations are linted
let mut attrs = newitem.attrs.clone();
attrs.extend(
// generated implementations are linted. `newitem` is already
// owned, so extend its attributes in place rather than deep-
// cloning the whole generated impl.
let mut newitem = newitem;
newitem.attrs.extend(
item.attrs
.iter()
.filter(|a| {
Expand All @@ -549,7 +551,7 @@ impl<'a> TraitDef<'a> {
})
.cloned(),
);
push(Annotatable::Item(Box::new(ast::Item { attrs, ..(*newitem).clone() })))
push(Annotatable::Item(newitem))
}
_ => unreachable!(),
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2186,6 +2186,12 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
}
}

// The overwhelming majority of nodes have no cfg or macro attribute
// to strip; skip the mutable attribute pass entirely for them.
if cfg_pos.is_none() && attr_pos.is_none() {
return None;
}

item.visit_attrs(|attrs| {
attr = Some(match (cfg_pos, attr_pos) {
(Some(pos), _) => (attrs.remove(pos), pos, Vec::new()),
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,10 @@ impl<'a> MetaDecoder for &'a MetadataBlob {

fn decoder(self, pos: usize) -> Self::Context {
BlobDecodeContext {
// FIXME: This unwrap should never panic because we check that it won't when creating
// `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of
// it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own
// the data for the decoder so holding onto the `MemDecoder` too would make us a
// self-referential struct which is downright goofy because `MetadataBlob` is already
// self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that
// demands a significant refactoring due to our crate graph.
opaque: MemDecoder::new(self, pos).unwrap(),
// The blob passed full `MemDecoder` validation when the
// `MetadataBlob` was created, so skip re-validating the magic
// suffix here: this runs for every lazily-decoded item.
opaque: MemDecoder::new_prevalidated(self, pos),
lazy_state: LazyState::NoNode,
blob: self.blob(),
}
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_serialize/src/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,18 @@ impl<'a> MemDecoder<'a> {
Ok(MemDecoder { start, current: data[position..].as_ptr(), end, _marker: PhantomData })
}

/// Like [`MemDecoder::new`], but skips re-validating the `MAGIC_END_BYTES`
/// suffix. Callers must have validated `data` before (e.g. with a prior
/// successful `MemDecoder::new`); this is worthwhile because a decoder is
/// constructed for every lazily-decoded metadata item.
#[inline]
pub fn new_prevalidated(data: &'a [u8], position: usize) -> MemDecoder<'a> {
debug_assert!(data.ends_with(MAGIC_END_BYTES));
let data = &data[..data.len() - MAGIC_END_BYTES.len()];
let Range { start, end } = data.as_ptr_range();
MemDecoder { start, current: data[position..].as_ptr(), end, _marker: PhantomData }
}

#[inline]
pub fn split_at(&self, position: usize) -> MemDecoder<'a> {
assert!(position <= self.len());
Expand Down
Loading