Skip to content

Commit

Permalink
auto merge of #11305 : pcwalton/rust/at-patterns, r=pcwalton
Browse files Browse the repository at this point in the history
  • Loading branch information
bors committed Jan 13, 2014
2 parents 480b0f4 + 119c614 commit ab66f76
Show file tree
Hide file tree
Showing 54 changed files with 1,025 additions and 1,037 deletions.
14 changes: 7 additions & 7 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -2865,19 +2865,19 @@ In a pattern whose head expression has an `enum` type, a placeholder (`_`) stand
variant. For example:

~~~~
enum List<X> { Nil, Cons(X, @List<X>) }
enum List<X> { Nil, Cons(X, ~List<X>) }
let x: List<int> = Cons(10, @Cons(11, @Nil));
let x: List<int> = Cons(10, ~Cons(11, ~Nil));
match x {
Cons(_, @Nil) => fail!("singleton list"),
Cons(_, ~Nil) => fail!("singleton list"),
Cons(..) => return,
Nil => fail!("empty list")
}
~~~~

The first pattern matches lists constructed by applying `Cons` to any head value, and a
tail value of `@Nil`. The second pattern matches _any_ list constructed with `Cons`,
tail value of `~Nil`. The second pattern matches _any_ list constructed with `Cons`,
ignoring the values of its arguments. The difference between `_` and `*` is that the pattern `C(_)` is only type-correct if
`C` has exactly one argument, while the pattern `C(..)` is type-correct for any enum variant `C`, regardless of how many arguments `C` has.

Expand All @@ -2893,12 +2893,12 @@ An example of an `match` expression:
# fn process_pair(a: int, b: int) { }
# fn process_ten() { }
enum List<X> { Nil, Cons(X, @List<X>) }
enum List<X> { Nil, Cons(X, ~List<X>) }
let x: List<int> = Cons(10, @Cons(11, @Nil));
let x: List<int> = Cons(10, ~Cons(11, ~Nil));
match x {
Cons(a, @Cons(b, _)) => {
Cons(a, ~Cons(b, _)) => {
process_pair(a,b);
}
Cons(10, _) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/front/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ fn method_in_cfg(cx: &Context, meth: &ast::Method) -> bool {
fn trait_method_in_cfg(cx: &Context, meth: &ast::TraitMethod) -> bool {
match *meth {
ast::Required(ref meth) => (cx.in_cfg)(meth.attrs),
ast::Provided(@ref meth) => (cx.in_cfg)(meth.attrs)
ast::Provided(meth) => (cx.in_cfg)(meth.attrs)
}
}

Expand Down
16 changes: 7 additions & 9 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,15 +308,13 @@ impl Folder for NestedItemsDropper {
fn fold_block(&mut self, blk: ast::P<ast::Block>) -> ast::P<ast::Block> {
let stmts_sans_items = blk.stmts.iter().filter_map(|stmt| {
match stmt.node {
ast::StmtExpr(_, _) | ast::StmtSemi(_, _) |
ast::StmtDecl(@codemap::Spanned {
node: ast::DeclLocal(_),
span: _
}, _) => Some(*stmt),
ast::StmtDecl(@codemap::Spanned {
node: ast::DeclItem(_),
span: _
}, _) => None,
ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => Some(*stmt),
ast::StmtDecl(decl, _) => {
match decl.node {
ast::DeclLocal(_) => Some(*stmt),
ast::DeclItem(_) => None,
}
}
ast::StmtMac(..) => fail!("unexpanded macro in astencode")
}
}).collect();
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ impl CFGBuilder {
self.add_node(pat.id, [pred])
}

ast::PatBox(subpat) |
ast::PatUniq(subpat) |
ast::PatRegion(subpat) |
ast::PatIdent(_, _, Some(subpat)) => {
Expand Down
18 changes: 8 additions & 10 deletions src/librustc/middle/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use middle::typeck;
use util::ppaux;

use syntax::ast::*;
use syntax::codemap;
use syntax::{ast_util, ast_map};
use syntax::visit::Visitor;
use syntax::visit;
Expand Down Expand Up @@ -84,14 +83,13 @@ pub fn check_item(v: &mut CheckCrateVisitor,
pub fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) {
fn is_str(e: @Expr) -> bool {
match e.node {
ExprVstore(
@Expr { node: ExprLit(@codemap::Spanned {
node: LitStr(..),
..}),
.. },
ExprVstoreUniq
) => true,
_ => false
ExprVstore(expr, ExprVstoreUniq) => {
match expr.node {
ExprLit(lit) => ast_util::lit_is_str(lit),
_ => false,
}
}
_ => false,
}
}
match p.node {
Expand Down Expand Up @@ -120,7 +118,7 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
"cannot do allocations in constant expressions");
return;
}
ExprLit(@codemap::Spanned {node: LitStr(..), ..}) => { }
ExprLit(lit) if ast_util::lit_is_str(lit) => {}
ExprBinary(..) | ExprUnary(..) => {
let method_map = method_map.borrow();
if method_map.get().contains_key(&e.id) {
Expand Down
24 changes: 15 additions & 9 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::num;
use std::vec;
use syntax::ast::*;
use syntax::ast_util::{unguarded_pat, walk_pat};
use syntax::codemap::{Span, DUMMY_SP, Spanned};
use syntax::codemap::{DUMMY_SP, Span};
use syntax::visit;
use syntax::visit::{Visitor, FnKind};

Expand Down Expand Up @@ -362,7 +362,7 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, p: @Pat) -> Option<ctor> {
_ => Some(single)
}
}
PatBox(_) | PatUniq(_) | PatTup(_) | PatRegion(..) => {
PatUniq(_) | PatTup(_) | PatRegion(..) => {
Some(single)
}
PatVec(ref before, slice, ref after) => {
Expand Down Expand Up @@ -735,7 +735,7 @@ fn specialize(cx: &MatchCheckCtxt,
}
}
PatTup(args) => Some(vec::append(args, r.tail())),
PatBox(a) | PatUniq(a) | PatRegion(a) => {
PatUniq(a) | PatRegion(a) => {
Some(vec::append(~[a], r.tail()))
}
PatLit(expr) => {
Expand Down Expand Up @@ -874,16 +874,22 @@ fn is_refutable(cx: &MatchCheckCtxt, pat: &Pat) -> bool {
}

match pat.node {
PatBox(sub) | PatUniq(sub) | PatRegion(sub) |
PatIdent(_, _, Some(sub)) => {
PatUniq(sub) | PatRegion(sub) | PatIdent(_, _, Some(sub)) => {
is_refutable(cx, sub)
}
PatWild | PatWildMulti | PatIdent(_, _, None) => { false }
PatLit(@Expr {node: ExprLit(@Spanned { node: LitNil, ..}), ..}) => {
// "()"
false
PatLit(lit) => {
match lit.node {
ExprLit(lit) => {
match lit.node {
LitNil => false, // `()`
_ => true,
}
}
_ => true,
}
}
PatLit(_) | PatRange(_, _) => { true }
PatRange(_, _) => { true }
PatStruct(_, ref fields, _) => {
fields.iter().any(|f| is_refutable(cx, f.pat))
}
Expand Down
16 changes: 11 additions & 5 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,18 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
// Search for auto-adjustments to find trait coercions.
let adjustments = cx.tcx.adjustments.borrow();
match adjustments.get().find(&e.id) {
Some(&@ty::AutoObject(..)) => {
let source_ty = ty::expr_ty(cx.tcx, e);
let target_ty = ty::expr_ty_adjusted(cx.tcx, e);
check_trait_cast(cx, source_ty, target_ty, e.span);
Some(adjustment) => {
match **adjustment {
ty::AutoObject(..) => {
let source_ty = ty::expr_ty(cx.tcx, e);
let target_ty = ty::expr_ty_adjusted(cx.tcx, e);
check_trait_cast(cx, source_ty, target_ty, e.span);
}
ty::AutoAddEnv(..) |
ty::AutoDerefRef(..) => {}
}
}
Some(&@ty::AutoAddEnv(..)) | Some(&@ty::AutoDerefRef(..)) | None => {}
None => {}
}

visit::walk_expr(cx, e, ());
Expand Down
63 changes: 42 additions & 21 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ use syntax::ast_map;
use syntax::attr;
use syntax::attr::{AttrMetaMethods, AttributeMethods};
use syntax::codemap::Span;
use syntax::codemap;
use syntax::parse::token;
use syntax::{ast, ast_util, visit};
use syntax::ast_util::IdVisitingOperation;
Expand Down Expand Up @@ -590,11 +589,16 @@ fn check_while_true_expr(cx: &Context, e: &ast::Expr) {
match e.node {
ast::ExprWhile(cond, _) => {
match cond.node {
ast::ExprLit(@codemap::Spanned {
node: ast::LitBool(true), ..}) =>
{
cx.span_lint(WhileTrue, e.span,
"denote infinite loops with loop { ... }");
ast::ExprLit(lit) => {
match lit.node {
ast::LitBool(true) => {
cx.span_lint(WhileTrue,
e.span,
"denote infinite loops with loop \
{ ... }");
}
_ => {}
}
}
_ => ()
}
Expand Down Expand Up @@ -989,9 +993,15 @@ fn check_heap_expr(cx: &Context, e: &ast::Expr) {

fn check_path_statement(cx: &Context, s: &ast::Stmt) {
match s.node {
ast::StmtSemi(@ast::Expr { node: ast::ExprPath(_), .. }, _) => {
cx.span_lint(PathStatement, s.span,
"path statement with no effect");
ast::StmtSemi(expr, _) => {
match expr.node {
ast::ExprPath(_) => {
cx.span_lint(PathStatement,
s.span,
"path statement with no effect");
}
_ => {}
}
}
_ => ()
}
Expand Down Expand Up @@ -1132,7 +1142,9 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
ast::ExprVstore(e2, ast::ExprVstoreUniq) |
ast::ExprVstore(e2, ast::ExprVstoreBox) => {
match e2.node {
ast::ExprLit(@codemap::Spanned{node: ast::LitStr(..), ..}) |
ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
VectorAllocation
}
ast::ExprVec(..) => VectorAllocation,
_ => return
}
Expand All @@ -1152,18 +1164,27 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
adjustments.get().find_copy(&e.id)
};
match adjustment {
Some(@ty::AutoDerefRef(ty::AutoDerefRef { autoref, .. })) => {
match (allocation, autoref) {
(VectorAllocation, Some(ty::AutoBorrowVec(..))) => {
report("unnecessary allocation, the sigil can be removed");
}
(BoxAllocation, Some(ty::AutoPtr(_, ast::MutImmutable))) => {
report("unnecessary allocation, use & instead");
}
(BoxAllocation, Some(ty::AutoPtr(_, ast::MutMutable))) => {
report("unnecessary allocation, use &mut instead");
Some(adjustment) => {
match *adjustment {
ty::AutoDerefRef(ty::AutoDerefRef { autoref, .. }) => {
match (allocation, autoref) {
(VectorAllocation, Some(ty::AutoBorrowVec(..))) => {
report("unnecessary allocation, the sigil can be \
removed");
}
(BoxAllocation,
Some(ty::AutoPtr(_, ast::MutImmutable))) => {
report("unnecessary allocation, use & instead");
}
(BoxAllocation,
Some(ty::AutoPtr(_, ast::MutMutable))) => {
report("unnecessary allocation, use &mut \
instead");
}
_ => ()
}
}
_ => ()
_ => {}
}
}

Expand Down
60 changes: 31 additions & 29 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,36 +341,39 @@ impl mem_categorization_ctxt {
self.cat_expr_unadjusted(expr)
}

Some(&@ty::AutoObject(..)) => {
// Implicity casts a concrete object to trait object
// Result is an rvalue
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
}
Some(adjustment) => {
match **adjustment {
ty::AutoObject(..) => {
// Implicity casts a concrete object to trait object
// Result is an rvalue
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
}

Some(&@ty::AutoAddEnv(..)) => {
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
}
ty::AutoAddEnv(..) => {
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
}

Some(
&@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(_), ..})) => {
// Equivalent to &*expr or something similar.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
}
ty::AutoDerefRef(ty::AutoDerefRef {
autoref: Some(_),
..}) => {
// Equivalent to &*expr or something similar.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
}

Some(
&@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: None, autoderefs: autoderefs})) => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, autoderefs)
ty::AutoDerefRef(ty::AutoDerefRef {
autoref: None,
autoderefs: autoderefs
}) => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, autoderefs)
}
}
}
}
}
Expand Down Expand Up @@ -973,8 +976,7 @@ impl mem_categorization_ctxt {
}
}

ast::PatBox(subpat) | ast::PatUniq(subpat) |
ast::PatRegion(subpat) => {
ast::PatUniq(subpat) | ast::PatRegion(subpat) => {
// @p1, ~p1
let subcmt = self.cat_deref(pat, cmt, 0);
self.cat_pattern(subcmt, subpat, op);
Expand Down
14 changes: 10 additions & 4 deletions src/librustc/middle/moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,16 @@ impl VisitContext {
let comp_mode = {
let adjustments = self.tcx.adjustments.borrow();
match adjustments.get().find(&expr.id) {
Some(&@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(_), ..})) => Read,
_ => expr_mode
Some(adjustment) => {
match **adjustment {
ty::AutoDerefRef(ty::AutoDerefRef {
autoref: Some(_),
..
}) => Read,
_ => expr_mode,
}
}
_ => expr_mode,
}
};

Expand Down
Loading

0 comments on commit ab66f76

Please sign in to comment.