Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #70994

Merged
merged 20 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
bd7ea54
Use `PredicateObligation`s instead of `Predicate`s
estebank Mar 3, 2020
d605a9d
Small tweaks to required bound span
estebank Apr 6, 2020
607315b
Kill comment left behind by a last minute change in #70795
ssomers Apr 9, 2020
de39a4f
Respect the comment: no root unless the borrow type is `Mut`
ssomers Apr 9, 2020
0fc0f34
Use tri-color search for unconditional recursion lint
ecstatic-morse Apr 10, 2020
b973cb7
compiletest: let config flags overwrite -A unused
RalfJung Apr 10, 2020
4ade06b
Rearrange BTreeMap::into_iter to match range_mut.
ssomers Apr 10, 2020
1d01ce2
Clean up E0512 explanation
GuillaumeGomez Apr 10, 2020
dc4c3e9
Setup the `@rustbot prioritize` command
LeSeulArtichaut Apr 10, 2020
688697d
Add ThreadSanitizer test case
tmiasko Apr 9, 2020
c728c75
fix rustc-dev-guide url in src/librustc_codegen_ssa
longfangsong Apr 10, 2020
1fe86f4
Rollup merge of #69745 - estebank:predicate-obligations-3, r=nikomats…
Centril Apr 10, 2020
6b2df46
Rollup merge of #70938 - tmiasko:thread-test-case, r=hanna-kruppe
Centril Apr 10, 2020
0d89287
Rollup merge of #70973 - ecstatic-morse:recursion-lint, r=jonas-schie…
Centril Apr 10, 2020
a5e06f2
Rollup merge of #70978 - RalfJung:compiletest-flags, r=Mark-Simulacrum
Centril Apr 10, 2020
277ce9e
Rollup merge of #70979 - ssomers:btreemap_the_alice_merton_variations…
Centril Apr 10, 2020
f699a55
Rollup merge of #70981 - ssomers:btreemap_into_into_iter, r=Mark-Simu…
Centril Apr 10, 2020
d36991a
Rollup merge of #70985 - GuillaumeGomez:cleanup-e0512, r=Dylan-DPC
Centril Apr 10, 2020
6dc77f5
Rollup merge of #70988 - LeSeulArtichaut:triagebot-prioritize, r=Mark…
Centril Apr 10, 2020
178aa6a
Rollup merge of #70991 - longfangsong:master, r=jonas-schievink
Centril Apr 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 13 additions & 15 deletions src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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