diff options
| author | bors <bors@rust-lang.org> | 2014-01-17 07:56:45 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-01-17 07:56:45 -0800 |
| commit | 4098327b1fe1112ddf661b587be9eeec1d80adde (patch) | |
| tree | 3d1a8d2613c1101d46657fd5de25d32403e9626b /src/libsyntax | |
| parent | 1e1871f35eb83ae6a63952a145e5132deffded2c (diff) | |
| parent | b520c2f28002db0e4120797d823380914871bac4 (diff) | |
| download | rust-4098327b1fe1112ddf661b587be9eeec1d80adde.tar.gz rust-4098327b1fe1112ddf661b587be9eeec1d80adde.zip | |
auto merge of #11585 : nikomatsakis/rust/issue-3511-rvalue-lifetimes, r=pcwalton
Major changes: - Define temporary scopes in a syntax-based way that basically defaults to the innermost statement or conditional block, except for in a `let` initializer, where we default to the innermost block. Rules are documented in the code, but not in the manual (yet). See new test run-pass/cleanup-value-scopes.rs for examples. - Refactors Datum to better define cleanup roles. - Refactor cleanup scopes to not be tied to basic blocks, permitting us to have a very large number of scopes (one per AST node). - Introduce nascent documentation in trans/doc.rs covering datums and cleanup in a more comprehensive way. r? @pcwalton
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast_util.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 30 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/opt_vec.rs | 47 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 11 |
5 files changed, 78 insertions, 31 deletions
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 89aa03a46ba..598e30957e4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -567,11 +567,7 @@ pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem, visited_outermost: false, }; - match *item { - IIItem(i) => id_visitor.visit_item(i, ()), - IIForeign(i) => id_visitor.visit_foreign_item(i, ()), - IIMethod(_, _, m) => visit::walk_method_helper(&mut id_visitor, m, ()), - } + visit::walk_inlined_item(&mut id_visitor, item, ()); } struct IdRangeComputingVisitor { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b1b38d6dc90..7d46f6e4594 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -138,15 +138,16 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { // to: // - // { - // let _i = &mut <src_expr>; - // ['<ident>:] loop { - // match i.next() { + // match &mut <src_expr> { + // i => { + // ['<ident>:] loop { + // match i.next() { // None => break, // Some(<src_pat>) => <src_loop_block> + // } // } + // } // } - // } let local_ident = token::gensym_ident("i"); let next_ident = fld.cx.ident_of("next"); @@ -155,10 +156,6 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { let local_path = fld.cx.path_ident(span, local_ident); let some_path = fld.cx.path_ident(span, fld.cx.ident_of("Some")); - // `let i = &mut <src_expr>` - let iter_decl_stmt = fld.cx.stmt_let(span, false, local_ident, - fld.cx.expr_mut_addr_of(span, src_expr)); - // `None => break ['<ident>];` let none_arm = { // FIXME #6993: this map goes away: @@ -186,16 +183,13 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { ast::ExprLoop(fld.cx.block_expr(match_expr), opt_ident)); - // `{ let ... ; loop { ... } }` - let block = fld.cx.block(span, - ~[iter_decl_stmt], - Some(loop_expr)); + // `i => loop { ... }` - @ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprBlock(block), - span: span, - } + // `match &mut <src_expr> { i => loop { ... } }` + let discrim = fld.cx.expr_mut_addr_of(span, src_expr); + let i_pattern = fld.cx.pat_ident(span, local_ident); + let arm = fld.cx.arm(span, ~[i_pattern], loop_expr); + fld.cx.expr_match(span, discrim, ~[arm]) } _ => noop_fold_expr(e, fld) diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 9ae13ddeb02..33832a8c62d 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -634,17 +634,24 @@ impl<'a> Context<'a> { self.ecx.expr_ident(e.span, lname))); } + // Now create a vector containing all the arguments + let slicename = self.ecx.ident_of("__args_vec"); + { + let args = names.move_iter().map(|a| a.unwrap()); + let mut args = locals.move_iter().chain(args); + let args = self.ecx.expr_vec_slice(self.fmtsp, args.collect()); + lets.push(self.ecx.stmt_let(self.fmtsp, false, slicename, args)); + } + // Now create the fmt::Arguments struct with all our locals we created. - let args = names.move_iter().map(|a| a.unwrap()); - let mut args = locals.move_iter().chain(args); let fmt = self.ecx.expr_ident(self.fmtsp, static_name); - let args = self.ecx.expr_vec_slice(self.fmtsp, args.collect()); + let args_slice = self.ecx.expr_ident(self.fmtsp, slicename); let result = self.ecx.expr_call_global(self.fmtsp, ~[ self.ecx.ident_of("std"), self.ecx.ident_of("fmt"), self.ecx.ident_of("Arguments"), self.ecx.ident_of("new"), - ], ~[fmt, args]); + ], ~[fmt, args_slice]); // We did all the work of making sure that the arguments // structure is safe, so we can safely have an unsafe block. diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 247962e0b94..326f712d5b2 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -42,12 +42,31 @@ impl<T> OptVec<T> { v.push(t); return; } - Empty => {} + Empty => { + *self = Vec(~[t]); + } } + } + + pub fn pop(&mut self) -> T { + match *self { + Vec(ref mut v) => v.pop(), + Empty => fail!("pop from empty opt_vec") + } + } - // FIXME(#5074): flow insensitive means we can't move - // assignment inside `match` - *self = Vec(~[t]); + pub fn last<'a>(&'a self) -> &'a T { + match *self { + Vec(ref v) => v.last(), + Empty => fail!("last on empty opt_vec") + } + } + + pub fn mut_last<'a>(&'a mut self) -> &'a mut T { + match *self { + Vec(ref mut v) => v.mut_last(), + Empty => fail!("mut_last on empty opt_vec") + } } pub fn map<U>(&self, op: |&T| -> U) -> OptVec<U> { @@ -82,6 +101,16 @@ impl<T> OptVec<T> { } } + pub fn swap_remove(&mut self, index: uint) { + match *self { + Empty => { fail!("Index out of bounds"); } + Vec(ref mut v) => { + assert!(index < v.len()); + v.swap_remove(index); + } + } + } + #[inline] pub fn iter<'r>(&'r self) -> OptVecIterator<'r, T> { match *self { @@ -166,6 +195,16 @@ impl<'a, T> Iterator<&'a T> for OptVecIterator<'a, T> { } } +impl<'a, T> DoubleEndedIterator<&'a T> for OptVecIterator<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a T> { + match self.iter { + Some(ref mut x) => x.next_back(), + None => None + } + } +} + impl<A> FromIterator<A> for OptVec<A> { fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> OptVec<A> { let mut r = Empty; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d79522b7103..484f8dce1f7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -121,6 +121,17 @@ pub trait Visitor<E: Clone> { } } +pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V, + item: &ast::InlinedItem, + env: E) { + match *item { + IIItem(i) => visitor.visit_item(i, env), + IIForeign(i) => visitor.visit_foreign_item(i, env), + IIMethod(_, _, m) => walk_method_helper(visitor, m, env), + } +} + + pub fn walk_crate<E: Clone, V: Visitor<E>>(visitor: &mut V, crate: &Crate, env: E) { visitor.visit_mod(&crate.module, crate.span, CRATE_NODE_ID, env) } |
