Skip to content

Commit

Permalink
Auto merge of #65454 - tmandry:rollup-0k6jiik, r=tmandry
Browse files Browse the repository at this point in the history
Rollup of 14 pull requests

Successful merges:

 - #64603 (Reducing spurious unused lifetime warnings.)
 - #64623 (Remove last uses of gensyms)
 - #65235 (don't assume we can *always* find a return type hint in async fn)
 - #65242 (Fix suggestion to constrain trait for method to be found)
 - #65265 (Cleanup librustc mir err codes)
 - #65293 (Optimize `try_expand_impl_trait_type`)
 - #65307 (Try fix incorrect "explicit lifetime name needed")
 - #65308 (Add long error explanation for E0574)
 - #65353 (save-analysis: Don't ICE when resolving qualified type paths in struct members)
 - #65389 (Return `false` from `needs_drop` for all zero-sized arrays.)
 - #65402 (Add troubleshooting section to PGO chapter in rustc book.)
 - #65425 (Optimize `BitIter`)
 - #65438 (Organize `never_type`  tests)
 - #65444 (Implement AsRef<[T]> for List<T>)

Failed merges:

 - #65390 (Add long error explanation for E0576)

r? @ghost
  • Loading branch information
bors committed Oct 15, 2019
2 parents 237d54f + 3182f73 commit f54911c
Show file tree
Hide file tree
Showing 99 changed files with 1,095 additions and 507 deletions.
11 changes: 11 additions & 0 deletions src/doc/rustc/src/profile-guided-optimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ RUSTFLAGS="-Cprofile-use=/tmp/pgo-data/merged.profdata" \
cargo build --release --target=x86_64-unknown-linux-gnu
```

### Troubleshooting

- It is recommended to pass `-Cllvm-args=-pgo-warn-missing-function` during the
`-Cprofile-use` phase. LLVM by default does not warn if it cannot find
profiling data for a given function. Enabling this warning will make it
easier to spot errors in your setup.

- There is a [known issue](https://github.com/rust-lang/cargo/issues/7416) in
Cargo prior to version 1.39 that will prevent PGO from working correctly. Be
sure to use Cargo 1.39 or newer when doing PGO.

## Further Reading

`rustc`'s PGO support relies entirely on LLVM's implementation of the feature
Expand Down
12 changes: 8 additions & 4 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3291,10 +3291,14 @@ impl<'a> LoweringContext<'a> {
let id = self.sess.next_node_id();
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
}
// This is the normal case.
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),

AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
// `PassThrough` is the normal case.
// `new_error_lifetime`, which would usually be used in the case of `ReportError`,
// is unsuitable here, as these can occur from missing lifetime parameters in a
// `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
// later, at which point a suitable error will be emitted.
| AnonymousLifetimeMode::PassThrough
| AnonymousLifetimeMode::ReportError => self.new_implicit_lifetime(span),
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,15 +708,22 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
match param.kind {
GenericParamKind::Lifetime { .. } => {
let (name, reg) = Region::early(&self.tcx.hir(), &mut index, &param);
let def_id = if let Region::EarlyBound(_ ,def_id , _) = reg {
def_id
} else {
bug!();
};
if let hir::ParamName::Plain(param_name) = name {
if param_name.name == kw::UnderscoreLifetime {
// Pick the elided lifetime "definition" if one exists
// and use it to make an elision scope.
self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many);
elision = Some(reg);
} else {
lifetimes.insert(name, reg);
}
} else {
self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many);
lifetimes.insert(name, reg);
}
}
Expand Down Expand Up @@ -1615,7 +1622,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
_ => None,
} {
debug!("id = {:?} span = {:?} name = {:?}", id, span, name);

if name.name == kw::UnderscoreLifetime {
continue;
}
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,13 @@ impl<T> Deref for List<T> {
type Target = [T];
#[inline(always)]
fn deref(&self) -> &[T] {
self.as_ref()
}
}

impl<T> AsRef<[T]> for List<T> {
#[inline(always)]
fn as_ref(&self) -> &[T] {
unsafe {
slice::from_raw_parts(self.data.as_ptr(), self.len)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1483,7 +1483,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
}

// Replace any anonymous late-bound regions with named
// variants, using gensym'd identifiers, so that we can
// variants, using new unique identifiers, so that we can
// clearly differentiate between named and unnamed regions in
// the output. We'll probably want to tweak this over time to
// decide just how much information to give.
Expand Down
24 changes: 20 additions & 4 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,9 @@ impl<'tcx> TyCtxt<'tcx> {
// that type, and when we finish expanding that type we remove the
// its DefId.
seen_opaque_tys: FxHashSet<DefId>,
// Cache of all expansions we've seen so far. This is a critical
// optimization for some large types produced by async fn trees.
expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>,
primary_def_id: DefId,
found_recursion: bool,
tcx: TyCtxt<'tcx>,
Expand All @@ -713,9 +716,16 @@ impl<'tcx> TyCtxt<'tcx> {
}
let substs = substs.fold_with(self);
if self.seen_opaque_tys.insert(def_id) {
let generic_ty = self.tcx.type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx, substs);
let expanded_ty = self.fold_ty(concrete_ty);
let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
Some(expanded_ty) => expanded_ty,
None => {
let generic_ty = self.tcx.type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx, substs);
let expanded_ty = self.fold_ty(concrete_ty);
self.expanded_cache.insert((def_id, substs), expanded_ty);
expanded_ty
}
};
self.seen_opaque_tys.remove(&def_id);
Some(expanded_ty)
} else {
Expand All @@ -735,14 +745,17 @@ impl<'tcx> TyCtxt<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Opaque(def_id, substs) = t.kind {
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
} else {
} else if t.has_projections() {
t.super_fold_with(self)
} else {
t
}
}
}

let mut visitor = OpaqueTypeExpander {
seen_opaque_tys: FxHashSet::default(),
expanded_cache: FxHashMap::default(),
primary_def_id: def_id,
found_recursion: false,
tcx: self,
Expand Down Expand Up @@ -1096,6 +1109,9 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>

ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),

// Zero-length arrays never contain anything to drop.
ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false,

// Structural recursion.
ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty),

Expand Down
63 changes: 42 additions & 21 deletions src/librustc_index/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,7 @@ impl<T: Idx> BitSet<T> {
/// Iterates over the indices of set bits in a sorted order.
#[inline]
pub fn iter(&self) -> BitIter<'_, T> {
BitIter {
cur: None,
iter: self.words.iter().enumerate(),
marker: PhantomData,
}
BitIter::new(&self.words)
}

/// Duplicates the set as a hybrid set.
Expand Down Expand Up @@ -291,26 +287,55 @@ impl<T: Idx> ToString for BitSet<T> {
}

pub struct BitIter<'a, T: Idx> {
cur: Option<(Word, usize)>,
iter: iter::Enumerate<slice::Iter<'a, Word>>,
/// A copy of the current word, but with any already-visited bits cleared.
/// (This lets us use `trailing_zeros()` to find the next set bit.) When it
/// is reduced to 0, we move onto the next word.
word: Word,

/// The offset (measured in bits) of the current word.
offset: usize,

/// Underlying iterator over the words.
iter: slice::Iter<'a, Word>,

marker: PhantomData<T>
}

impl<'a, T: Idx> BitIter<'a, T> {
#[inline]
fn new(words: &'a [Word]) -> BitIter<'a, T> {
// We initialize `word` and `offset` to degenerate values. On the first
// call to `next()` we will fall through to getting the first word from
// `iter`, which sets `word` to the first word (if there is one) and
// `offset` to 0. Doing it this way saves us from having to maintain
// additional state about whether we have started.
BitIter {
word: 0,
offset: std::usize::MAX - (WORD_BITS - 1),
iter: words.iter(),
marker: PhantomData,
}
}
}

impl<'a, T: Idx> Iterator for BitIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
loop {
if let Some((ref mut word, offset)) = self.cur {
let bit_pos = word.trailing_zeros() as usize;
if bit_pos != WORD_BITS {
let bit = 1 << bit_pos;
*word ^= bit;
return Some(T::new(bit_pos + offset))
}
if self.word != 0 {
// Get the position of the next set bit in the current word,
// then clear the bit.
let bit_pos = self.word.trailing_zeros() as usize;
let bit = 1 << bit_pos;
self.word ^= bit;
return Some(T::new(bit_pos + self.offset))
}

let (i, word) = self.iter.next()?;
self.cur = Some((*word, WORD_BITS * i));
// Move onto the next word. `wrapping_add()` is needed to handle
// the degenerate initial value given to `offset` in `new()`.
let word = self.iter.next()?;
self.word = *word;
self.offset = self.offset.wrapping_add(WORD_BITS);
}
}
}
Expand Down Expand Up @@ -851,11 +876,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
pub fn iter(&self, row: R) -> BitIter<'_, C> {
assert!(row.index() < self.num_rows);
let (start, end) = self.range(row);
BitIter {
cur: None,
iter: self.words[start..end].iter().enumerate(),
marker: PhantomData,
}
BitIter::new(&self.words[start..end])
}

/// Returns the number of elements in `row`.
Expand Down
17 changes: 4 additions & 13 deletions src/librustc_mir/dataflow/impls/indirect_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,25 +104,16 @@ impl<'tcx> TransferFunction<'_, '_, 'tcx> {
kind: mir::BorrowKind,
borrowed_place: &mir::Place<'tcx>,
) -> bool {
let borrowed_ty = borrowed_place.ty(self.body, self.tcx).ty;

// Zero-sized types cannot be mutated, since there is nothing inside to mutate.
//
// FIXME: For now, we only exempt arrays of length zero. We need to carefully
// consider the effects before extending this to all ZSTs.
if let ty::Array(_, len) = borrowed_ty.kind {
if len.try_eval_usize(self.tcx, self.param_env) == Some(0) {
return false;
}
}

match kind {
mir::BorrowKind::Mut { .. } => true,

| mir::BorrowKind::Shared
| mir::BorrowKind::Shallow
| mir::BorrowKind::Unique
=> !borrowed_ty.is_freeze(self.tcx, self.param_env, DUMMY_SP),
=> !borrowed_place
.ty(self.body, self.tcx)
.ty
.is_freeze(self.tcx, self.param_env, DUMMY_SP),
}
}
}
Expand Down
Loading

0 comments on commit f54911c

Please sign in to comment.