Skip to content

librustc: Remove @ pointer patterns from the language #11305

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

Merged
merged 2 commits into from
Jan 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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