Skip to content

Commit

Permalink
Auto merge of rust-lang#70994 - Centril:rollup-lftv0a3, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - rust-lang#69745 (Use `PredicateObligation`s instead of `Predicate`s)
 - rust-lang#70938 (Add ThreadSanitizer test case)
 - rust-lang#70973 (Use forward traversal for unconditional recursion lint)
 - rust-lang#70978 (compiletest: let config flags overwrite -A unused)
 - rust-lang#70979 (Follow up on BTreeMap comments)
 - rust-lang#70981 (Rearrange BTreeMap::into_iter to match range_mut.)
 - rust-lang#70985 (Clean up E0512 explanation)
 - rust-lang#70988 (Setup the `@rustbot prioritize` command)
 - rust-lang#70991 (fix rustc-dev-guide's url in src/librustc_codegen_ssa)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Apr 10, 2020
2 parents 9682f0e + 178aa6a commit 1406186
Show file tree
Hide file tree
Showing 217 changed files with 754 additions and 565 deletions.
28 changes: 13 additions & 15 deletions src/liballoc/collections/btree/map.rs
Expand Up @@ -1544,19 +1544,19 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
type IntoIter = IntoIter<K, V>;

fn into_iter(self) -> IntoIter<K, V> {
let me = ManuallyDrop::new(self);
if me.root.is_none() {
return IntoIter { front: None, back: None, length: 0 };
}

let root1 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
let root2 = unsafe { unwrap_unchecked(ptr::read(&me.root)).into_ref() };
let len = me.length;

IntoIter {
front: Some(root1.first_leaf_edge()),
back: Some(root2.last_leaf_edge()),
length: len,
let mut me = ManuallyDrop::new(self);
if let Some(root) = me.root.as_mut() {
let root1 = unsafe { ptr::read(root).into_ref() };
let root2 = unsafe { ptr::read(root).into_ref() };
let len = me.length;

IntoIter {
front: Some(root1.first_leaf_edge()),
back: Some(root2.last_leaf_edge()),
length: len,
}
} else {
IntoIter { front: None, back: None, length: 0 }
}
}
}
Expand Down Expand Up @@ -2771,8 +2771,6 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInter
pos.next_unchecked();
}
}

// This internal node might be underfull, but only if it's the root.
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/collections/btree/node.rs
Expand Up @@ -161,7 +161,7 @@ impl<K, V> Root<K, V> {
NodeRef {
height: self.height,
node: self.node.as_ptr(),
root: self as *const _ as *mut _,
root: ptr::null(),
_marker: PhantomData,
}
}
Expand All @@ -179,7 +179,7 @@ impl<K, V> Root<K, V> {
NodeRef {
height: self.height,
node: self.node.as_ptr(),
root: ptr::null_mut(), // FIXME: Is there anything better to do here?
root: ptr::null(),
_marker: PhantomData,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/README.md
@@ -1,3 +1,3 @@
Please read the rustc-dev-guide chapter on [Backend Agnostic Codegen][bac].

[bac]: https://rustc-dev-guide.rust-lang.org/codegen/backend-agnostic.html
[bac]: https://rustc-dev-guide.rust-lang.org/backend/backend-agnostic.html
13 changes: 10 additions & 3 deletions src/librustc_data_structures/graph/iterate/mod.rs
Expand Up @@ -209,7 +209,9 @@ where
// schedule its successors for examination.
self.stack.push(Event { node, becomes: Settled });
for succ in self.graph.successors(node) {
self.stack.push(Event { node: succ, becomes: Visited });
if !visitor.ignore_edge(node, succ) {
self.stack.push(Event { node: succ, becomes: Visited });
}
}
}
}
Expand Down Expand Up @@ -255,16 +257,21 @@ where
/// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms
fn node_examined(
&mut self,
_target: G::Node,
_node: G::Node,
_prior_status: Option<NodeStatus>,
) -> ControlFlow<Self::BreakVal> {
ControlFlow::Continue
}

/// Called after all nodes reachable from this one have been examined.
fn node_settled(&mut self, _target: G::Node) -> ControlFlow<Self::BreakVal> {
fn node_settled(&mut self, _node: G::Node) -> ControlFlow<Self::BreakVal> {
ControlFlow::Continue
}

/// Behave as if no edges exist from `source` to `target`.
fn ignore_edge(&mut self, _source: G::Node, _target: G::Node) -> bool {
false
}
}

/// This `TriColorVisitor` looks for back edges in a graph, which indicate that a cycle exists.
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_error_codes/error_codes/E0512.md
@@ -1,5 +1,6 @@
Transmute with two differently sized types was attempted. Erroneous code
example:
Transmute with two differently sized types was attempted.

Erroneous code example:

```compile_fail,E0512
fn takes_u8(_: u8) {}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_infer/infer/outlives/verify.rs
Expand Up @@ -296,7 +296,10 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
self.collect_outlives_from_predicate_list(
move |ty| ty == identity_proj,
traits::elaborate_predicates(tcx, trait_predicates),
traits::elaborate_predicates(tcx, trait_predicates)
.into_iter()
.map(|o| o.predicate)
.collect::<Vec<_>>(),
)
.map(|b| b.1)
}
Expand Down
68 changes: 48 additions & 20 deletions src/librustc_infer/traits/util.rs
@@ -1,8 +1,10 @@
use smallvec::smallvec;

use crate::traits::{Obligation, ObligationCause, PredicateObligation};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::outlives::Component;
use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness};
use rustc_span::Span;

pub fn anonymize_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
Expand Down Expand Up @@ -87,7 +89,7 @@ impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'tcx> {
/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
/// `T: Foo`, then we know that `T: 'static`.
pub struct Elaborator<'tcx> {
stack: Vec<ty::Predicate<'tcx>>,
stack: Vec<PredicateObligation<'tcx>>,
visited: PredicateSet<'tcx>,
}

Expand All @@ -112,35 +114,60 @@ pub fn elaborate_predicates<'tcx>(
) -> Elaborator<'tcx> {
let mut visited = PredicateSet::new(tcx);
predicates.retain(|pred| visited.insert(pred));
Elaborator { stack: predicates, visited }
let obligations: Vec<_> =
predicates.into_iter().map(|predicate| predicate_obligation(predicate, None)).collect();
elaborate_obligations(tcx, obligations)
}

pub fn elaborate_obligations<'tcx>(
tcx: TyCtxt<'tcx>,
mut obligations: Vec<PredicateObligation<'tcx>>,
) -> Elaborator<'tcx> {
let mut visited = PredicateSet::new(tcx);
obligations.retain(|obligation| visited.insert(&obligation.predicate));
Elaborator { stack: obligations, visited }
}

fn predicate_obligation<'tcx>(
predicate: ty::Predicate<'tcx>,
span: Option<Span>,
) -> PredicateObligation<'tcx> {
let mut cause = ObligationCause::dummy();
if let Some(span) = span {
cause.span = span;
}
Obligation { cause, param_env: ty::ParamEnv::empty(), recursion_depth: 0, predicate }
}

impl Elaborator<'tcx> {
pub fn filter_to_traits(self) -> FilterToTraits<Self> {
FilterToTraits::new(self)
}

fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
let tcx = self.visited.tcx;
match *predicate {
match obligation.predicate {
ty::Predicate::Trait(ref data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());

let predicates = predicates
.predicates
.iter()
.map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref()));
debug!("super_predicates: data={:?} predicates={:?}", data, predicates.clone());
let obligations = predicates.predicates.iter().map(|(pred, span)| {
predicate_obligation(
pred.subst_supertrait(tcx, &data.to_poly_trait_ref()),
Some(*span),
)
});
debug!("super_predicates: data={:?} predicates={:?}", data, &obligations);

// Only keep those bounds that we haven't already seen.
// This is necessary to prevent infinite recursion in some
// cases. One common case is when people define
// `trait Sized: Sized { }` rather than `trait Sized { }`.
let visited = &mut self.visited;
let predicates = predicates.filter(|pred| visited.insert(pred));
let obligations =
obligations.filter(|obligation| visited.insert(&obligation.predicate));

self.stack.extend(predicates);
self.stack.extend(obligations);
}
ty::Predicate::WellFormed(..) => {
// Currently, we do not elaborate WF predicates,
Expand Down Expand Up @@ -221,25 +248,26 @@ impl Elaborator<'tcx> {
None
}
})
.filter(|p| visited.insert(p)),
.filter(|p| visited.insert(p))
.map(|p| predicate_obligation(p, None)),
);
}
}
}
}

impl Iterator for Elaborator<'tcx> {
type Item = ty::Predicate<'tcx>;
type Item = PredicateObligation<'tcx>;

fn size_hint(&self) -> (usize, Option<usize>) {
(self.stack.len(), None)
}

fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
fn next(&mut self) -> Option<Self::Item> {
// Extract next item from top-most stack frame, if any.
if let Some(pred) = self.stack.pop() {
self.elaborate(&pred);
Some(pred)
if let Some(obligation) = self.stack.pop() {
self.elaborate(&obligation);
Some(obligation)
} else {
None
}
Expand Down Expand Up @@ -282,12 +310,12 @@ impl<I> FilterToTraits<I> {
}
}

impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<I> {
type Item = ty::PolyTraitRef<'tcx>;

fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(pred) = self.base_iterator.next() {
if let ty::Predicate::Trait(data, _) = pred {
while let Some(obligation) = self.base_iterator.next() {
if let ty::Predicate::Trait(data, _) = obligation.predicate {
return Some(data.to_poly_trait_ref());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/const_prop.rs
Expand Up @@ -126,7 +126,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
.collect();
if !traits::normalize_and_test_predicates(
tcx,
traits::elaborate_predicates(tcx, predicates).collect(),
traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(),
) {
trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", source.def_id());
return;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir_build/build/mod.rs
Expand Up @@ -178,11 +178,11 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
build::construct_const(cx, body_id, return_ty, return_ty_span)
};

lints::check(tcx, &body, def_id);

let mut body = BodyAndCache::new(body);
body.ensure_predecessors();

lints::check(tcx, &body.unwrap_read_only(), def_id);

// The borrow checker will replace all the regions here with its own
// inference variables. There's no point having non-erased regions here.
// The exception is `body.user_type_annotations`, which is used unmodified
Expand Down

0 comments on commit 1406186

Please sign in to comment.