Auto merge of #37289 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 7 pull requests - Successful merges: #37165, #37187, #37241, #37283, #37285, #37287, #37288 - Failed merges:
This commit is contained in:
commit
dfd98ebd3e
25 changed files with 190 additions and 252 deletions
|
|
@ -380,9 +380,9 @@ the `tests` directory.
|
|||
|
||||
# The `tests` directory
|
||||
|
||||
Each file in `tests/*.rs` directory is treated as individual crate.
|
||||
So, to write an integration test, let's make a `tests` directory, and
|
||||
put a `tests/integration_test.rs` file inside, with this as its contents:
|
||||
Each file in `tests/*.rs` directory is treated as an individual crate.
|
||||
To write an integration test, let's make a `tests` directory and
|
||||
put a `tests/integration_test.rs` file inside with this as its contents:
|
||||
|
||||
```rust,ignore
|
||||
extern crate adder;
|
||||
|
|
|
|||
|
|
@ -86,16 +86,29 @@ impl<T> ToOwned for T where T: Clone {
|
|||
/// ```
|
||||
/// use std::borrow::Cow;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// fn abs_all(input: &mut Cow<[i32]>) {
|
||||
/// for i in 0..input.len() {
|
||||
/// let v = input[i];
|
||||
/// if v < 0 {
|
||||
/// // clones into a vector the first time (if not already owned)
|
||||
/// // Clones into a vector if not already owned.
|
||||
/// input.to_mut()[i] = -v;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // No clone occurs because `input` doesn't need to be mutated.
|
||||
/// let slice = [0, 1, 2];
|
||||
/// let mut input = Cow::from(&slice[..]);
|
||||
/// abs_all(&mut input);
|
||||
///
|
||||
/// // Clone occurs because `input` needs to be mutated.
|
||||
/// let slice = [-1, 0, 1];
|
||||
/// let mut input = Cow::from(&slice[..]);
|
||||
/// abs_all(&mut input);
|
||||
///
|
||||
/// // No clone occurs because `input` is already owned.
|
||||
/// let mut input = Cow::from(vec![-1, 0, 1]);
|
||||
/// abs_all(&mut input);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub enum Cow<'a, B: ?Sized + 'a>
|
||||
|
|
|
|||
|
|
@ -61,9 +61,8 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
|
|||
-> Ty<'tcx> where
|
||||
F: FnOnce(u32) -> ty::InferTy,
|
||||
{
|
||||
match opt_ty {
|
||||
Some(ty) => { return ty.fold_with(self); }
|
||||
None => { }
|
||||
if let Some(ty) = opt_ty {
|
||||
return ty.fold_with(self);
|
||||
}
|
||||
|
||||
match self.freshen_map.entry(key) {
|
||||
|
|
|
|||
|
|
@ -478,12 +478,9 @@ impl RegionMaps {
|
|||
//! Returns the scope when temp created by expr_id will be cleaned up
|
||||
|
||||
// check for a designated rvalue scope
|
||||
match self.rvalue_scopes.borrow().get(&expr_id) {
|
||||
Some(&s) => {
|
||||
debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s);
|
||||
return Some(s);
|
||||
}
|
||||
None => { }
|
||||
if let Some(&s) = self.rvalue_scopes.borrow().get(&expr_id) {
|
||||
debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s);
|
||||
return Some(s);
|
||||
}
|
||||
|
||||
let scope_map : &[CodeExtent] = &self.scope_map.borrow();
|
||||
|
|
@ -928,19 +925,15 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
|
|||
//
|
||||
// FIXME(#6308) -- Note that `[]` patterns work more smoothly post-DST.
|
||||
|
||||
match local.init {
|
||||
Some(ref expr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &expr, blk_scope);
|
||||
if let Some(ref expr) = local.init {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &expr, blk_scope);
|
||||
|
||||
let is_borrow =
|
||||
if let Some(ref ty) = local.ty { is_borrowed_ty(&ty) } else { false };
|
||||
let is_borrow =
|
||||
if let Some(ref ty) = local.ty { is_borrowed_ty(&ty) } else { false };
|
||||
|
||||
if is_binding_pat(&local.pat) || is_borrow {
|
||||
record_rvalue_scope(visitor, &expr, blk_scope);
|
||||
}
|
||||
if is_binding_pat(&local.pat) || is_borrow {
|
||||
record_rvalue_scope(visitor, &expr, blk_scope);
|
||||
}
|
||||
|
||||
None => { }
|
||||
}
|
||||
|
||||
intravisit::walk_local(visitor, local);
|
||||
|
|
@ -1023,16 +1016,12 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
|
|||
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id)
|
||||
}
|
||||
hir::ExprBlock(ref block) => {
|
||||
match block.expr {
|
||||
Some(ref subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(
|
||||
visitor, &subexpr, blk_id);
|
||||
}
|
||||
None => { }
|
||||
if let Some(ref subexpr) = block.expr {
|
||||
record_rvalue_scope_if_borrow_expr(
|
||||
visitor, &subexpr, blk_id);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1405,9 +1405,8 @@ impl<'tcx> ProjectionCache<'tcx> {
|
|||
/// cache hit, so it's actually a good thing).
|
||||
fn try_start(&mut self, key: ty::ProjectionTy<'tcx>)
|
||||
-> Result<(), ProjectionCacheEntry<'tcx>> {
|
||||
match self.map.get(&key) {
|
||||
Some(entry) => return Err(entry.clone()),
|
||||
None => { }
|
||||
if let Some(entry) = self.map.get(&key) {
|
||||
return Err(entry.clone());
|
||||
}
|
||||
|
||||
self.map.insert(key, ProjectionCacheEntry::InProgress);
|
||||
|
|
|
|||
|
|
@ -788,14 +788,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
stack);
|
||||
assert!(!stack.obligation.predicate.has_escaping_regions());
|
||||
|
||||
match self.check_candidate_cache(&cache_fresh_trait_pred) {
|
||||
Some(c) => {
|
||||
debug!("CACHE HIT: SELECT({:?})={:?}",
|
||||
cache_fresh_trait_pred,
|
||||
c);
|
||||
return c;
|
||||
}
|
||||
None => { }
|
||||
if let Some(c) = self.check_candidate_cache(&cache_fresh_trait_pred) {
|
||||
debug!("CACHE HIT: SELECT({:?})={:?}",
|
||||
cache_fresh_trait_pred,
|
||||
c);
|
||||
return c;
|
||||
}
|
||||
|
||||
// If no match, compute result and insert into cache.
|
||||
|
|
|
|||
|
|
@ -135,15 +135,12 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
|
|||
borrow_id, cmt, loan_region,
|
||||
bk, loan_cause);
|
||||
|
||||
match opt_loan_path(&cmt) {
|
||||
Some(lp) => {
|
||||
let moved_value_use_kind = match loan_cause {
|
||||
euv::ClosureCapture(_) => MovedInCapture,
|
||||
_ => MovedInUse,
|
||||
};
|
||||
self.check_if_path_is_moved(borrow_id, borrow_span, moved_value_use_kind, &lp);
|
||||
}
|
||||
None => { }
|
||||
if let Some(lp) = opt_loan_path(&cmt) {
|
||||
let moved_value_use_kind = match loan_cause {
|
||||
euv::ClosureCapture(_) => MovedInCapture,
|
||||
_ => MovedInUse,
|
||||
};
|
||||
self.check_if_path_is_moved(borrow_id, borrow_span, moved_value_use_kind, &lp);
|
||||
}
|
||||
|
||||
self.check_for_conflicting_loans(borrow_id);
|
||||
|
|
@ -158,33 +155,29 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
|
|||
debug!("mutate(assignment_id={}, assignee_cmt={:?})",
|
||||
assignment_id, assignee_cmt);
|
||||
|
||||
match opt_loan_path(&assignee_cmt) {
|
||||
Some(lp) => {
|
||||
match mode {
|
||||
MutateMode::Init | MutateMode::JustWrite => {
|
||||
// In a case like `path = 1`, then path does not
|
||||
// have to be *FULLY* initialized, but we still
|
||||
// must be careful lest it contains derefs of
|
||||
// pointers.
|
||||
self.check_if_assigned_path_is_moved(assignee_cmt.id,
|
||||
assignment_span,
|
||||
MovedInUse,
|
||||
&lp);
|
||||
}
|
||||
MutateMode::WriteAndRead => {
|
||||
// In a case like `path += 1`, then path must be
|
||||
// fully initialized, since we will read it before
|
||||
// we write it.
|
||||
self.check_if_path_is_moved(assignee_cmt.id,
|
||||
assignment_span,
|
||||
MovedInUse,
|
||||
&lp);
|
||||
}
|
||||
if let Some(lp) = opt_loan_path(&assignee_cmt) {
|
||||
match mode {
|
||||
MutateMode::Init | MutateMode::JustWrite => {
|
||||
// In a case like `path = 1`, then path does not
|
||||
// have to be *FULLY* initialized, but we still
|
||||
// must be careful lest it contains derefs of
|
||||
// pointers.
|
||||
self.check_if_assigned_path_is_moved(assignee_cmt.id,
|
||||
assignment_span,
|
||||
MovedInUse,
|
||||
&lp);
|
||||
}
|
||||
MutateMode::WriteAndRead => {
|
||||
// In a case like `path += 1`, then path must be
|
||||
// fully initialized, since we will read it before
|
||||
// we write it.
|
||||
self.check_if_path_is_moved(assignee_cmt.id,
|
||||
assignment_span,
|
||||
MovedInUse,
|
||||
&lp);
|
||||
}
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
|
||||
self.check_assignment(assignment_id, assignment_span, assignee_cmt);
|
||||
}
|
||||
|
||||
|
|
@ -601,39 +594,36 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
|||
span: Span,
|
||||
cmt: mc::cmt<'tcx>,
|
||||
mode: euv::ConsumeMode) {
|
||||
match opt_loan_path(&cmt) {
|
||||
Some(lp) => {
|
||||
let moved_value_use_kind = match mode {
|
||||
euv::Copy => {
|
||||
self.check_for_copy_of_frozen_path(id, span, &lp);
|
||||
MovedInUse
|
||||
}
|
||||
euv::Move(_) => {
|
||||
match self.move_data.kind_of_move_of_path(id, &lp) {
|
||||
None => {
|
||||
// Sometimes moves don't have a move kind;
|
||||
// this either means that the original move
|
||||
// was from something illegal to move,
|
||||
// or was moved from referent of an unsafe
|
||||
// pointer or something like that.
|
||||
if let Some(lp) = opt_loan_path(&cmt) {
|
||||
let moved_value_use_kind = match mode {
|
||||
euv::Copy => {
|
||||
self.check_for_copy_of_frozen_path(id, span, &lp);
|
||||
MovedInUse
|
||||
}
|
||||
euv::Move(_) => {
|
||||
match self.move_data.kind_of_move_of_path(id, &lp) {
|
||||
None => {
|
||||
// Sometimes moves don't have a move kind;
|
||||
// this either means that the original move
|
||||
// was from something illegal to move,
|
||||
// or was moved from referent of an unsafe
|
||||
// pointer or something like that.
|
||||
MovedInUse
|
||||
}
|
||||
Some(move_kind) => {
|
||||
self.check_for_move_of_borrowed_path(id, span,
|
||||
&lp, move_kind);
|
||||
if move_kind == move_data::Captured {
|
||||
MovedInCapture
|
||||
} else {
|
||||
MovedInUse
|
||||
}
|
||||
Some(move_kind) => {
|
||||
self.check_for_move_of_borrowed_path(id, span,
|
||||
&lp, move_kind);
|
||||
if move_kind == move_data::Captured {
|
||||
MovedInCapture
|
||||
} else {
|
||||
MovedInUse
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
self.check_if_path_is_moved(id, span, moved_value_use_kind, &lp);
|
||||
}
|
||||
None => { }
|
||||
self.check_if_path_is_moved(id, span, moved_value_use_kind, &lp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
|
|||
// (*)
|
||||
// (*) dominators for `pred` have been calculated
|
||||
new_idom = intersect_opt(&post_order_rank,
|
||||
&immediate_dominators,
|
||||
new_idom,
|
||||
Some(pred));
|
||||
&immediate_dominators,
|
||||
new_idom,
|
||||
Some(pred));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,10 +77,10 @@ pub fn dominators_given_rpo<G: ControlFlowGraph>(graph: &G,
|
|||
}
|
||||
|
||||
fn intersect_opt<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
node1: Option<Node>,
|
||||
node2: Option<Node>)
|
||||
-> Option<Node> {
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
node1: Option<Node>,
|
||||
node2: Option<Node>)
|
||||
-> Option<Node> {
|
||||
match (node1, node2) {
|
||||
(None, None) => None,
|
||||
(Some(n), None) | (None, Some(n)) => Some(n),
|
||||
|
|
@ -89,10 +89,10 @@ fn intersect_opt<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
|
|||
}
|
||||
|
||||
fn intersect<Node: Idx>(post_order_rank: &IndexVec<Node, usize>,
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
mut node1: Node,
|
||||
mut node2: Node)
|
||||
-> Node {
|
||||
immediate_dominators: &IndexVec<Node, Option<Node>>,
|
||||
mut node1: Node,
|
||||
mut node2: Node)
|
||||
-> Node {
|
||||
while node1 != node2 {
|
||||
while post_order_rank[node1] < post_order_rank[node2] {
|
||||
node1 = immediate_dominators[node1].unwrap();
|
||||
|
|
@ -142,9 +142,9 @@ impl<Node: Idx> Dominators<Node> {
|
|||
"node {:?} is not reachable",
|
||||
node2);
|
||||
intersect::<Node>(&self.post_order_rank,
|
||||
&self.immediate_dominators,
|
||||
node1,
|
||||
node2)
|
||||
&self.immediate_dominators,
|
||||
node1,
|
||||
node2)
|
||||
}
|
||||
|
||||
pub fn mutual_dominator<I>(&self, iter: I) -> Option<Node>
|
||||
|
|
|
|||
|
|
@ -14,12 +14,7 @@ use super::*;
|
|||
|
||||
#[test]
|
||||
fn diamond() {
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
]);
|
||||
let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]);
|
||||
|
||||
let dominators = dominators(&graph);
|
||||
let immediate_dominators = dominators.all_immediate_dominators();
|
||||
|
|
@ -32,17 +27,9 @@ fn diamond() {
|
|||
#[test]
|
||||
fn paper() {
|
||||
// example from the paper:
|
||||
let graph = TestGraph::new(6, &[
|
||||
(6, 5),
|
||||
(6, 4),
|
||||
(5, 1),
|
||||
(4, 2),
|
||||
(4, 3),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 2),
|
||||
(2, 1),
|
||||
]);
|
||||
let graph = TestGraph::new(6,
|
||||
&[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2),
|
||||
(2, 1)]);
|
||||
|
||||
let dominators = dominators(&graph);
|
||||
let immediate_dominators = dominators.all_immediate_dominators();
|
||||
|
|
@ -54,4 +41,3 @@ fn paper() {
|
|||
assert_eq!(immediate_dominators[5], Some(6));
|
||||
assert_eq!(immediate_dominators[6], Some(6));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,7 @@ use super::*;
|
|||
|
||||
#[test]
|
||||
fn diamond_post_order() {
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(0, 2),
|
||||
(1, 3),
|
||||
(2, 3),
|
||||
]);
|
||||
let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]);
|
||||
|
||||
let result = post_order_from(&graph, 0);
|
||||
assert_eq!(result, vec![3, 1, 2, 0]);
|
||||
|
|
@ -33,16 +28,8 @@ fn rev_post_order_inner_loop() {
|
|||
// ^ ^ v |
|
||||
// | 6 <- 4 |
|
||||
// +-----------------+
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(3, 5),
|
||||
(3, 1),
|
||||
(2, 4),
|
||||
(4, 6),
|
||||
(6, 2),
|
||||
]);
|
||||
let graph = TestGraph::new(0,
|
||||
&[(0, 1), (1, 2), (2, 3), (3, 5), (3, 1), (2, 4), (4, 6), (6, 2)]);
|
||||
|
||||
let rev_graph = TransposedGraph::new(&graph);
|
||||
|
||||
|
|
@ -52,4 +39,3 @@ fn rev_post_order_inner_loop() {
|
|||
let result = post_order_from_to(&rev_graph, 3, Some(1));
|
||||
assert_eq!(result, vec![4, 6, 2, 3]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ pub trait ControlFlowGraph
|
|||
|
||||
pub trait GraphPredecessors<'graph> {
|
||||
type Item;
|
||||
type Iter: Iterator<Item=Self::Item>;
|
||||
type Iter: Iterator<Item = Self::Item>;
|
||||
}
|
||||
|
||||
pub trait GraphSuccessors<'graph> {
|
||||
type Item;
|
||||
type Iter: Iterator<Item=Self::Item>;
|
||||
}
|
||||
type Iter: Iterator<Item = Self::Item>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ use super::super::indexed_vec::{IndexVec, Idx};
|
|||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub fn reachable<G: ControlFlowGraph>(graph: &G)
|
||||
-> Reachability<G::Node> {
|
||||
pub fn reachable<G: ControlFlowGraph>(graph: &G) -> Reachability<G::Node> {
|
||||
let reverse_post_order = reverse_post_order(graph, graph.start_node());
|
||||
reachable_given_rpo(graph, &reverse_post_order)
|
||||
}
|
||||
|
|
@ -53,12 +52,10 @@ pub struct Reachability<Node: Idx> {
|
|||
impl<Node: Idx> Reachability<Node> {
|
||||
fn new<G: ControlFlowGraph>(graph: &G) -> Self {
|
||||
let num_nodes = graph.num_nodes();
|
||||
Reachability {
|
||||
bits: IndexVec::from_elem_n(BitVector::new(num_nodes), num_nodes),
|
||||
}
|
||||
Reachability { bits: IndexVec::from_elem_n(BitVector::new(num_nodes), num_nodes) }
|
||||
}
|
||||
|
||||
pub fn can_reach(&self, source: Node, target: Node)-> bool {
|
||||
pub fn can_reach(&self, source: Node, target: Node) -> bool {
|
||||
let bit: usize = target.index();
|
||||
self.bits[source].contains(bit)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,15 +17,7 @@ fn test1() {
|
|||
// 0 -> 1 -> 2 -> 3
|
||||
// ^ v
|
||||
// 6 <- 4 -> 5
|
||||
let graph = TestGraph::new(0, &[
|
||||
(0, 1),
|
||||
(1, 2),
|
||||
(2, 3),
|
||||
(2, 4),
|
||||
(4, 5),
|
||||
(4, 6),
|
||||
(6, 1),
|
||||
]);
|
||||
let graph = TestGraph::new(0, &[(0, 1), (1, 2), (2, 3), (2, 4), (4, 5), (4, 6), (6, 1)]);
|
||||
let reachable = reachable(&graph);
|
||||
assert!((0..6).all(|i| reachable.can_reach(0, i)));
|
||||
assert!((1..6).all(|i| reachable.can_reach(1, i)));
|
||||
|
|
@ -43,15 +35,9 @@ fn test2() {
|
|||
// 30 -> 31 -> 32 -> 33
|
||||
// ^ v
|
||||
// 36 <- 34 -> 35
|
||||
let graph = TestGraph::new(30, &[
|
||||
(30, 31),
|
||||
(31, 32),
|
||||
(32, 33),
|
||||
(32, 34),
|
||||
(34, 35),
|
||||
(34, 36),
|
||||
(36, 31),
|
||||
]);
|
||||
let graph = TestGraph::new(30,
|
||||
&[(30, 31), (31, 32), (32, 33), (32, 34), (34, 35), (34, 36),
|
||||
(36, 31)]);
|
||||
let reachable = reachable(&graph);
|
||||
assert!((30..36).all(|i| reachable.can_reach(30, i)));
|
||||
assert!((31..36).all(|i| reachable.can_reach(31, i)));
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ impl<'graph, G: ControlFlowGraph> ControlFlowGraph for &'graph G {
|
|||
(**self).start_node()
|
||||
}
|
||||
|
||||
fn predecessors<'iter>(&'iter self, node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'iter>>::Iter {
|
||||
fn predecessors<'iter>(&'iter self,
|
||||
node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'iter>>::Iter {
|
||||
(**self).predecessors(node)
|
||||
}
|
||||
|
||||
fn successors<'iter>(&'iter self, node: Self::Node)
|
||||
-> <Self as GraphSuccessors<'iter>>::Iter {
|
||||
fn successors<'iter>(&'iter self, node: Self::Node) -> <Self as GraphSuccessors<'iter>>::Iter {
|
||||
(**self).successors(node)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ impl TestGraph {
|
|||
num_nodes: start_node + 1,
|
||||
start_node: start_node,
|
||||
successors: HashMap::new(),
|
||||
predecessors: HashMap::new()
|
||||
predecessors: HashMap::new(),
|
||||
};
|
||||
for &(source, target) in edges {
|
||||
graph.num_nodes = max(graph.num_nodes, source + 1);
|
||||
|
|
@ -55,13 +55,13 @@ impl ControlFlowGraph for TestGraph {
|
|||
self.num_nodes
|
||||
}
|
||||
|
||||
fn predecessors<'graph>(&'graph self, node: usize)
|
||||
fn predecessors<'graph>(&'graph self,
|
||||
node: usize)
|
||||
-> <Self as GraphPredecessors<'graph>>::Iter {
|
||||
self.predecessors[&node].iter().cloned()
|
||||
self.predecessors[&node].iter().cloned()
|
||||
}
|
||||
|
||||
fn successors<'graph>(&'graph self, node: usize)
|
||||
-> <Self as GraphSuccessors<'graph>>::Iter {
|
||||
fn successors<'graph>(&'graph self, node: usize) -> <Self as GraphSuccessors<'graph>>::Iter {
|
||||
self.successors[&node].iter().cloned()
|
||||
}
|
||||
}
|
||||
|
|
@ -75,4 +75,3 @@ impl<'graph> GraphSuccessors<'graph> for TestGraph {
|
|||
type Item = usize;
|
||||
type Iter = iter::Cloned<slice::Iter<'graph, usize>>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,10 @@ impl<G: ControlFlowGraph> TransposedGraph<G> {
|
|||
}
|
||||
|
||||
pub fn with_start(base_graph: G, start_node: G::Node) -> Self {
|
||||
TransposedGraph { base_graph: base_graph, start_node: start_node }
|
||||
TransposedGraph {
|
||||
base_graph: base_graph,
|
||||
start_node: start_node,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,12 +40,14 @@ impl<G: ControlFlowGraph> ControlFlowGraph for TransposedGraph<G> {
|
|||
self.start_node
|
||||
}
|
||||
|
||||
fn predecessors<'graph>(&'graph self, node: Self::Node)
|
||||
fn predecessors<'graph>(&'graph self,
|
||||
node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'graph>>::Iter {
|
||||
self.base_graph.successors(node)
|
||||
}
|
||||
|
||||
fn successors<'graph>(&'graph self, node: Self::Node)
|
||||
fn successors<'graph>(&'graph self,
|
||||
node: Self::Node)
|
||||
-> <Self as GraphSuccessors<'graph>>::Iter {
|
||||
self.base_graph.predecessors(node)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub struct SnapshotMap<K, V>
|
|||
}
|
||||
|
||||
pub struct Snapshot {
|
||||
len: usize
|
||||
len: usize,
|
||||
}
|
||||
|
||||
enum UndoLog<K, V> {
|
||||
|
|
@ -39,7 +39,7 @@ impl<K, V> SnapshotMap<K, V>
|
|||
pub fn new() -> Self {
|
||||
SnapshotMap {
|
||||
map: FnvHashMap(),
|
||||
undo_log: vec![]
|
||||
undo_log: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,9 +68,7 @@ impl<K, V> SnapshotMap<K, V>
|
|||
}
|
||||
true
|
||||
}
|
||||
None => {
|
||||
false
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +86,7 @@ impl<K, V> SnapshotMap<K, V>
|
|||
assert!(snapshot.len < self.undo_log.len());
|
||||
assert!(match self.undo_log[snapshot.len] {
|
||||
UndoLog::OpenSnapshot => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +108,7 @@ impl<K, V> SnapshotMap<K, V>
|
|||
panic!("cannot rollback an uncommitted snapshot");
|
||||
}
|
||||
|
||||
UndoLog::CommittedSnapshot => { }
|
||||
UndoLog::CommittedSnapshot => {}
|
||||
|
||||
UndoLog::Inserted(key) => {
|
||||
self.map.remove(&key);
|
||||
|
|
@ -123,7 +121,10 @@ impl<K, V> SnapshotMap<K, V>
|
|||
}
|
||||
|
||||
let v = self.undo_log.pop().unwrap();
|
||||
assert!(match v { UndoLog::OpenSnapshot => true, _ => false });
|
||||
assert!(match v {
|
||||
UndoLog::OpenSnapshot => true,
|
||||
_ => false,
|
||||
});
|
||||
assert!(self.undo_log.len() == snapshot.len);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ mod tests;
|
|||
///
|
||||
/// Clients are expected to provide implementations of this trait; you
|
||||
/// can see some examples in the `test` module.
|
||||
pub trait UnifyKey : Copy + Clone + Debug + PartialEq {
|
||||
pub trait UnifyKey: Copy + Clone + Debug + PartialEq {
|
||||
type Value: Clone + PartialEq + Debug;
|
||||
|
||||
fn index(&self) -> u32;
|
||||
|
|
@ -115,11 +115,7 @@ impl<K: UnifyKey> VarValue<K> {
|
|||
}
|
||||
|
||||
fn if_not_self(&self, key: K, self_key: K) -> Option<K> {
|
||||
if key == self_key {
|
||||
None
|
||||
} else {
|
||||
Some(key)
|
||||
}
|
||||
if key == self_key { None } else { Some(key) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +232,8 @@ impl<K: UnifyKey> UnificationTable<K> {
|
|||
new_rank: u32,
|
||||
old_root: VarValue<K>,
|
||||
new_root: VarValue<K>,
|
||||
new_value: K::Value) -> K {
|
||||
new_value: K::Value)
|
||||
-> K {
|
||||
let old_root_key = old_root.key();
|
||||
let new_root_key = new_root.key();
|
||||
self.set(old_root_key, old_root.redirect(new_root_key));
|
||||
|
|
@ -306,7 +303,8 @@ impl<'tcx, K, V> UnificationTable<K>
|
|||
let combined = {
|
||||
match (&node_a.value, &node_b.value) {
|
||||
(&None, &None) => None,
|
||||
(&Some(ref v), &None) | (&None, &Some(ref v)) => Some(v.clone()),
|
||||
(&Some(ref v), &None) |
|
||||
(&None, &Some(ref v)) => Some(v.clone()),
|
||||
(&Some(ref v1), &Some(ref v2)) => {
|
||||
if *v1 != *v2 {
|
||||
return Err((v1.clone(), v2.clone()));
|
||||
|
|
|
|||
|
|
@ -302,9 +302,8 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
|
|||
};
|
||||
|
||||
// Check if we already trans'd this shim.
|
||||
match ccx.fn_pointer_shims().borrow().get(&bare_fn_ty_maybe_ref) {
|
||||
Some(&llval) => { return llval; }
|
||||
None => { }
|
||||
if let Some(&llval) = ccx.fn_pointer_shims().borrow().get(&bare_fn_ty_maybe_ref) {
|
||||
return llval;
|
||||
}
|
||||
|
||||
debug!("trans_fn_pointer_shim(bare_fn_ty={:?})",
|
||||
|
|
|
|||
|
|
@ -119,9 +119,8 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
debug!("get_vtable(trait_ref={:?})", trait_ref);
|
||||
|
||||
// Check the cache.
|
||||
match ccx.vtables().borrow().get(&trait_ref) {
|
||||
Some(&val) => { return val }
|
||||
None => { }
|
||||
if let Some(&val) = ccx.vtables().borrow().get(&trait_ref) {
|
||||
return val;
|
||||
}
|
||||
|
||||
// Not in the cache. Build it.
|
||||
|
|
|
|||
|
|
@ -1629,9 +1629,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
let tcx = self.tcx();
|
||||
|
||||
let cache = self.ast_ty_to_ty_cache();
|
||||
match cache.borrow().get(&ast_ty.id) {
|
||||
Some(ty) => { return ty; }
|
||||
None => { }
|
||||
if let Some(ty) = cache.borrow().get(&ast_ty.id) {
|
||||
return ty;
|
||||
}
|
||||
|
||||
let result_ty = match ast_ty.node {
|
||||
|
|
|
|||
|
|
@ -742,17 +742,14 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
|||
hir::ItemImpl(.., ref impl_items) => {
|
||||
debug!("ItemImpl {} with id {}", it.name, it.id);
|
||||
let impl_def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
match ccx.tcx.impl_trait_ref(impl_def_id) {
|
||||
Some(impl_trait_ref) => {
|
||||
check_impl_items_against_trait(ccx,
|
||||
it.span,
|
||||
impl_def_id,
|
||||
&impl_trait_ref,
|
||||
impl_items);
|
||||
let trait_def_id = impl_trait_ref.def_id;
|
||||
check_on_unimplemented(ccx, trait_def_id, it);
|
||||
}
|
||||
None => { }
|
||||
if let Some(impl_trait_ref) = ccx.tcx.impl_trait_ref(impl_def_id) {
|
||||
check_impl_items_against_trait(ccx,
|
||||
it.span,
|
||||
impl_def_id,
|
||||
&impl_trait_ref,
|
||||
impl_items);
|
||||
let trait_def_id = impl_trait_ref.def_id;
|
||||
check_on_unimplemented(ccx, trait_def_id, it);
|
||||
}
|
||||
}
|
||||
hir::ItemTrait(..) => {
|
||||
|
|
@ -1812,9 +1809,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
f: F) where
|
||||
F: FnOnce(&ty::ItemSubsts<'tcx>),
|
||||
{
|
||||
match self.tables.borrow().item_substs.get(&id) {
|
||||
Some(s) => { f(s) }
|
||||
None => { }
|
||||
if let Some(s) = self.tables.borrow().item_substs.get(&id) {
|
||||
f(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,13 +156,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
|
|||
{
|
||||
{
|
||||
let mut stack = self.stack.borrow_mut();
|
||||
match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
|
||||
None => { }
|
||||
Some((i, _)) => {
|
||||
let cycle = &stack[i..];
|
||||
self.report_cycle(span, cycle);
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
if let Some((i, _)) = stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
|
||||
let cycle = &stack[i..];
|
||||
self.report_cycle(span, cycle);
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
stack.push(request);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,22 +15,28 @@ use cmp;
|
|||
use io::{self, SeekFrom, Error, ErrorKind};
|
||||
|
||||
/// A `Cursor` wraps another type and provides it with a
|
||||
/// [`Seek`](trait.Seek.html) implementation.
|
||||
/// [`Seek`] implementation.
|
||||
///
|
||||
/// Cursors are typically used with in-memory buffers to allow them to
|
||||
/// implement `Read` and/or `Write`, allowing these buffers to be used
|
||||
/// `Cursor`s are typically used with in-memory buffers to allow them to
|
||||
/// implement [`Read`] and/or [`Write`], allowing these buffers to be used
|
||||
/// anywhere you might use a reader or writer that does actual I/O.
|
||||
///
|
||||
/// The standard library implements some I/O traits on various types which
|
||||
/// are commonly used as a buffer, like `Cursor<Vec<u8>>` and `Cursor<&[u8]>`.
|
||||
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
|
||||
/// `Cursor<`[`&[u8]`]`>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// We may want to write bytes to a [`File`][file] in our production
|
||||
/// We may want to write bytes to a [`File`] in our production
|
||||
/// code, but use an in-memory buffer in our tests. We can do this with
|
||||
/// `Cursor`:
|
||||
///
|
||||
/// [file]: ../fs/struct.File.html
|
||||
/// [`Seek`]: trait.Seek.html
|
||||
/// [`Read`]: ../../std/io/trait.Read.html
|
||||
/// [`Write`]: ../../std/io/trait.Write.html
|
||||
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
||||
/// [`&[u8]`]: ../../std/primitive.slice.html
|
||||
/// [`File`]: ../fs/struct.File.html
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::io::prelude::*;
|
||||
|
|
|
|||
|
|
@ -2449,13 +2449,10 @@ impl<'a> State<'a> {
|
|||
|s, ty| s.print_type(&ty)));
|
||||
try!(word(&mut self.s, ")"));
|
||||
|
||||
match data.output {
|
||||
None => { }
|
||||
Some(ref ty) => {
|
||||
try!(self.space_if_not_bol());
|
||||
try!(self.word_space("->"));
|
||||
try!(self.print_type(&ty));
|
||||
}
|
||||
if let Some(ref ty) = data.output {
|
||||
try!(self.space_if_not_bol());
|
||||
try!(self.word_space("->"));
|
||||
try!(self.print_type(&ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue