auto merge of #11305 : pcwalton/rust/at-patterns, r=pcwalton

r? @nikomatsakis
This commit is contained in:
bors 2014-01-13 14:51:34 -08:00
commit ab66f76254
54 changed files with 1017 additions and 1029 deletions

View File

@ -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.
@ -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, _) => {

View File

@ -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)
}
}

View File

@ -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();

View File

@ -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)) => {

View File

@ -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;
@ -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 {
@ -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) {

View File

@ -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};
@ -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) => {
@ -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) => {
@ -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))
}

View File

@ -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, ());

View File

@ -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;
@ -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 \
{ ... }");
}
_ => {}
}
}
_ => ()
}
@ -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");
}
_ => {}
}
}
_ => ()
}
@ -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
}
@ -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");
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");
}
_ => ()
}
}
(BoxAllocation, Some(ty::AutoPtr(_, ast::MutImmutable))) => {
report("unnecessary allocation, use & instead");
}
(BoxAllocation, Some(ty::AutoPtr(_, ast::MutMutable))) => {
report("unnecessary allocation, use &mut instead");
}
_ => ()
_ => {}
}
}

View File

@ -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)
}
}
}
}
}
@ -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);

View File

@ -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,
}
};

View File

@ -102,10 +102,16 @@ impl<'a> Visitor<&'a ScopeChain<'a>> for LifetimeContext {
fn visit_ty(&mut self, ty: &ast::Ty,
scope: &'a ScopeChain<'a>) {
match ty.node {
ast::TyClosure(@ast::ClosureTy { lifetimes: ref lifetimes, .. }) |
ast::TyBareFn(@ast::BareFnTy { lifetimes: ref lifetimes, .. }) => {
let scope1 = FnScope(ty.id, lifetimes, scope);
self.check_lifetime_names(lifetimes);
ast::TyClosure(closure) => {
let scope1 = FnScope(ty.id, &closure.lifetimes, scope);
self.check_lifetime_names(&closure.lifetimes);
debug!("pushing fn scope id={} due to type", ty.id);
visit::walk_ty(self, ty, &scope1);
debug!("popping fn scope id={} due to type", ty.id);
}
ast::TyBareFn(bare_fn) => {
let scope1 = FnScope(ty.id, &bare_fn.lifetimes, scope);
self.check_lifetime_names(&bare_fn.lifetimes);
debug!("pushing fn scope id={} due to type", ty.id);
visit::walk_ty(self, ty, &scope1);
debug!("popping fn scope id={} due to type", ty.id);

View File

@ -100,7 +100,7 @@ impl<T:Subst> Subst for OptVec<T> {
impl<T:Subst + 'static> Subst for @T {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> @T {
match self {
&@ref t => @t.subst(tcx, substs)
t => @(**t).subst(tcx, substs)
}
}
}

View File

@ -838,34 +838,6 @@ fn enter_tuple_struct<'r,'b>(
})
}
fn enter_box<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap,
m: &[Match<'r,'b>],
col: uint,
val: ValueRef)
-> ~[Match<'r,'b>] {
debug!("enter_box(bcx={}, m={}, col={}, val={})",
bcx.to_str(),
m.repr(bcx.tcx()),
col,
bcx.val_to_str(val));
let _indenter = indenter();
let dummy = @ast::Pat {id: 0, node: ast::PatWild, span: DUMMY_SP};
enter_match(bcx, dm, m, col, val, |p| {
match p.node {
ast::PatBox(sub) => {
Some(~[sub])
}
_ => {
assert_is_binding_or_wild(bcx, p);
Some(~[dummy])
}
}
})
}
fn enter_uniq<'r,'b>(
bcx: &'b Block<'b>,
dm: DefMap,
@ -1146,23 +1118,6 @@ fn pats_require_rooting(bcx: &Block, m: &[Match], col: uint) -> bool {
})
}
fn root_pats_as_necessary<'r,'b>(
mut bcx: &'b Block<'b>,
m: &[Match<'r,'b>],
col: uint,
val: ValueRef)
-> &'b Block<'b> {
for br in m.iter() {
let pat_id = br.pats[col].id;
if pat_id != 0 {
let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
mode: ByRef(ZeroMem)};
bcx = datum.root_and_write_guard(bcx, br.pats[col].span, pat_id, 0);
}
}
return bcx;
}
// Macro for deciding whether any of the remaining matches fit a given kind of
// pattern. Note that, because the macro is well-typed, either ALL of the
// matches should fit that sort of pattern or NONE (however, some of the
@ -1178,10 +1133,6 @@ macro_rules! any_pat (
)
)
fn any_box_pat(m: &[Match], col: uint) -> bool {
any_pat!(m, ast::PatBox(_))
}
fn any_uniq_pat(m: &[Match], col: uint) -> bool {
any_pat!(m, ast::PatUniq(_))
}
@ -1570,7 +1521,7 @@ fn compile_submatch_continue<'r,
// If we are not matching against an `@T`, we should not be
// required to root any values.
assert!(any_box_pat(m, col) || !pats_require_rooting(bcx, m, col));
assert!(!pats_require_rooting(bcx, m, col));
match collect_record_or_struct_fields(bcx, m, col) {
Some(ref rec_fields) => {
@ -1632,16 +1583,6 @@ fn compile_submatch_continue<'r,
return;
}
// Unbox in case of a box field
if any_box_pat(m, col) {
bcx = root_pats_as_necessary(bcx, m, col, val);
let llbox = Load(bcx, val);
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
compile_submatch(bcx, enter_box(bcx, dm, m, col, val),
vec::append(~[unboxed], vals_left), chk);
return;
}
if any_uniq_pat(m, col) {
let pat_ty = node_id_type(bcx, pat_id);
let llbox = Load(bcx, val);
@ -2289,7 +2230,7 @@ fn bind_irrefutable_pat<'a>(
bcx = bind_irrefutable_pat(bcx, *elem, fldptr, binding_mode);
}
}
ast::PatBox(inner) | ast::PatUniq(inner) => {
ast::PatUniq(inner) => {
let pat_ty = node_id_type(bcx, pat.id);
let llbox = Load(bcx, val);
let unboxed = match ty::get(pat_ty).sty {

View File

@ -172,10 +172,13 @@ pub fn get_const_val(cx: @CrateContext,
};
match opt_item {
ast_map::NodeItem(@ast::Item {
node: ast::ItemStatic(_, ast::MutImmutable, _), ..
}, _) => {
trans_const(cx, ast::MutImmutable, def_id.node);
ast_map::NodeItem(item, _) => {
match item.node {
ast::ItemStatic(_, ast::MutImmutable, _) => {
trans_const(cx, ast::MutImmutable, def_id.node);
}
_ => {}
}
}
_ => cx.tcx.sess.bug("expected a const to be an item")
}
@ -198,60 +201,79 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
};
match adjustment {
None => { }
Some(@ty::AutoAddEnv(ty::ReStatic, ast::BorrowedSigil)) => {
llconst = C_struct([llconst, C_null(Type::opaque_box(cx).ptr_to())], false)
}
Some(@ty::AutoAddEnv(ref r, ref s)) => {
cx.sess.span_bug(e.span, format!("unexpected static function: \
region {:?} sigil {:?}", *r, *s))
}
Some(@ty::AutoObject(..)) => {
cx.sess.span_unimpl(e.span, "unimplemented const coercion to trait object");
}
Some(@ty::AutoDerefRef(ref adj)) => {
let mut ty = ety;
let mut maybe_ptr = None;
adj.autoderefs.times(|| {
let (dv, dt) = const_deref(cx, llconst, ty, false);
maybe_ptr = Some(llconst);
llconst = dv;
ty = dt;
});
Some(adj) => {
match *adj {
ty::AutoAddEnv(ty::ReStatic, ast::BorrowedSigil) => {
llconst = C_struct([
llconst,
C_null(Type::opaque_box(cx).ptr_to())
], false)
}
ty::AutoAddEnv(ref r, ref s) => {
cx.sess
.span_bug(e.span,
format!("unexpected static function: region \
{:?} sigil {:?}",
*r,
*s))
}
ty::AutoObject(..) => {
cx.sess
.span_unimpl(e.span,
"unimplemented const coercion to trait \
object");
}
ty::AutoDerefRef(ref adj) => {
let mut ty = ety;
let mut maybe_ptr = None;
adj.autoderefs.times(|| {
let (dv, dt) = const_deref(cx, llconst, ty, false);
maybe_ptr = Some(llconst);
llconst = dv;
ty = dt;
});
match adj.autoref {
None => { }
Some(ref autoref) => {
// Don't copy data to do a deref+ref.
let llptr = match maybe_ptr {
Some(ptr) => ptr,
None => {
inlineable = false;
const_addr_of(cx, llconst)
}
};
match *autoref {
ty::AutoUnsafe(m) |
ty::AutoPtr(ty::ReStatic, m) => {
assert!(m != ast::MutMutable);
llconst = llptr;
}
ty::AutoBorrowVec(ty::ReStatic, m) => {
assert!(m != ast::MutMutable);
assert_eq!(abi::slice_elt_base, 0);
assert_eq!(abi::slice_elt_len, 1);
match ty::get(ty).sty {
ty::ty_vec(_, ty::vstore_fixed(len)) => {
llconst = C_struct([llptr, C_uint(cx, len)], false);
match adj.autoref {
None => { }
Some(ref autoref) => {
// Don't copy data to do a deref+ref.
let llptr = match maybe_ptr {
Some(ptr) => ptr,
None => {
inlineable = false;
const_addr_of(cx, llconst)
}
};
match *autoref {
ty::AutoUnsafe(m) |
ty::AutoPtr(ty::ReStatic, m) => {
assert!(m != ast::MutMutable);
llconst = llptr;
}
ty::AutoBorrowVec(ty::ReStatic, m) => {
assert!(m != ast::MutMutable);
assert_eq!(abi::slice_elt_base, 0);
assert_eq!(abi::slice_elt_len, 1);
match ty::get(ty).sty {
ty::ty_vec(_,
ty::vstore_fixed(len)) => {
llconst = C_struct([
llptr,
C_uint(cx, len)
], false);
}
_ => {}
}
}
_ => {
cx.sess.span_bug(e.span,
format!("unimplemented \
const autoref \
{:?}",
autoref))
}
_ => {}
}
}
_ => {
cx.sess.span_bug(e.span,
format!("unimplemented const \
autoref {:?}", autoref))
}
}
}
}

View File

@ -331,8 +331,21 @@ pub fn create_captured_var_metadata(bcx: &Block,
cx.sess.span_bug(span, "debuginfo::create_captured_var_metadata() - NodeId not found");
}
Some(ast_map::NodeLocal(ident, _)) => ident,
Some(ast_map::NodeArg(@ast::Pat { node: ast::PatIdent(_, ref path, _), .. })) => {
ast_util::path_to_ident(path)
Some(ast_map::NodeArg(pat)) => {
match pat.node {
ast::PatIdent(_, ref path, _) => {
ast_util::path_to_ident(path)
}
_ => {
cx.sess
.span_bug(span,
format!(
"debuginfo::create_captured_var_metadata() - \
Captured var-id refers to unexpected \
ast_map variant: {:?}",
ast_item));
}
}
}
_ => {
cx.sess.span_bug(span, format!("debuginfo::create_captured_var_metadata() - \
@ -415,18 +428,20 @@ pub fn create_self_argument_metadata(bcx: &Block,
items.get().get_copy(&bcx.fcx.id)
};
let span = match fnitem {
ast_map::NodeMethod(@ast::Method { explicit_self: explicit_self, .. }, _, _) => {
explicit_self.span
ast_map::NodeMethod(method, _, _) => {
method.explicit_self.span
}
ast_map::NodeTraitMethod(
@ast::Provided(
@ast::Method {
explicit_self: explicit_self,
..
}),
_,
_) => {
explicit_self.span
ast_map::NodeTraitMethod(trait_method, _, _) => {
match *trait_method {
ast::Provided(method) => method.explicit_self.span,
_ => {
bcx.ccx()
.sess
.bug(format!("create_self_argument_metadata: \
unexpected sort of node: {:?}",
fnitem))
}
}
}
_ => bcx.ccx().sess.bug(
format!("create_self_argument_metadata: unexpected sort of node: {:?}", fnitem))
@ -614,18 +629,13 @@ pub fn create_function_debug_context(cx: &CrateContext,
}
}
}
ast_map::NodeMethod(
@ast::Method {
decl: fn_decl,
ident: ident,
generics: ref generics,
body: top_level_block,
span: span,
..
},
_,
_) => {
(ident, fn_decl, generics, top_level_block, span, true)
ast_map::NodeMethod(method, _, _) => {
(method.ident,
method.decl,
&method.generics,
method.body,
method.span,
true)
}
ast_map::NodeExpr(ref expr) => {
match expr.node {
@ -646,22 +656,29 @@ pub fn create_function_debug_context(cx: &CrateContext,
"create_function_debug_context: expected an expr_fn_block here")
}
}
ast_map::NodeTraitMethod(
@ast::Provided(
@ast::Method {
decl: fn_decl,
ident: ident,
generics: ref generics,
body: top_level_block,
span: span,
..
}),
_,
_) => {
(ident, fn_decl, generics, top_level_block, span, true)
ast_map::NodeTraitMethod(trait_method, _, _) => {
match *trait_method {
ast::Provided(method) => {
(method.ident,
method.decl,
&method.generics,
method.body,
method.span,
true)
}
_ => {
cx.sess
.bug(format!("create_function_debug_context: \
unexpected sort of node: {:?}",
fnitem))
}
}
}
ast_map::NodeForeignItem(..) |
ast_map::NodeVariant(..) |
ast_map::NodeStructCtor(..) => {
return FunctionWithoutDebugInfo;
}
ast_map::NodeForeignItem(..) | ast_map::NodeVariant(..)
| ast_map::NodeStructCtor(..) => { return FunctionWithoutDebugInfo; }
_ => cx.sess.bug(format!("create_function_debug_context: \
unexpected sort of node: {:?}", fnitem))
};
@ -814,7 +831,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
name_to_append_suffix_to: &mut ~str)
-> DIArray {
let self_type = match param_substs {
Some(@param_substs{ self_ty: self_type, .. }) => self_type,
Some(param_substs) => param_substs.self_ty,
_ => None
};
@ -868,7 +885,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
// Handle other generic parameters
let actual_types = match param_substs {
Some(@param_substs { tys: ref types, .. }) => types,
Some(param_substs) => &param_substs.tys,
None => {
return create_DIArray(DIB(cx), template_params);
}
@ -2290,7 +2307,7 @@ fn get_namespace_and_span_for_item(cx: &CrateContext,
{
let items = cx.tcx.items.borrow();
let definition_span = match items.get().find(&def_id.node) {
Some(&ast_map::NodeItem(@ast::Item { span, .. }, _)) => span,
Some(&ast_map::NodeItem(item, _)) => item.span,
ref node => {
cx.sess.span_warn(warning_span,
format!("debuginfo::\
@ -2393,19 +2410,19 @@ fn populate_scope_map(cx: &CrateContext,
scope_map.insert(block.id, scope_stack.last().scope_metadata);
// The interesting things here are statements and the concluding expression.
for &@ ref statement in block.stmts.iter() {
scope_map.insert(ast_util::stmt_id(statement), scope_stack.last().scope_metadata);
for statement in block.stmts.iter() {
scope_map.insert(ast_util::stmt_id(*statement), scope_stack.last().scope_metadata);
match statement.node {
ast::StmtDecl(@ref decl, _) => walk_decl(cx, decl, scope_stack, scope_map),
ast::StmtExpr(@ref exp, _) |
ast::StmtSemi(@ref exp, _) => walk_expr(cx, exp, scope_stack, scope_map),
ast::StmtDecl(decl, _) => walk_decl(cx, decl, scope_stack, scope_map),
ast::StmtExpr(exp, _) |
ast::StmtSemi(exp, _) => walk_expr(cx, exp, scope_stack, scope_map),
ast::StmtMac(..) => () // ignore macros (which should be expanded anyway)
}
}
for &@ref exp in block.expr.iter() {
walk_expr(cx, exp, scope_stack, scope_map);
for exp in block.expr.iter() {
walk_expr(cx, *exp, scope_stack, scope_map);
}
}
@ -2414,13 +2431,13 @@ fn populate_scope_map(cx: &CrateContext,
scope_stack: &mut ~[ScopeStackEntry],
scope_map: &mut HashMap<ast::NodeId, DIScope>) {
match *decl {
codemap::Spanned { node: ast::DeclLocal(@ref local), .. } => {
codemap::Spanned { node: ast::DeclLocal(local), .. } => {
scope_map.insert(local.id, scope_stack.last().scope_metadata);
walk_pattern(cx, local.pat, scope_stack, scope_map);
for &@ref exp in local.init.iter() {
walk_expr(cx, exp, scope_stack, scope_map);
for exp in local.init.iter() {
walk_expr(cx, *exp, scope_stack, scope_map);
}
}
_ => ()
@ -2538,19 +2555,17 @@ fn populate_scope_map(cx: &CrateContext,
}
}
ast::PatBox(sub_pat) |
ast::PatUniq(sub_pat) |
ast::PatRegion(sub_pat) => {
ast::PatUniq(sub_pat) | ast::PatRegion(sub_pat) => {
scope_map.insert(pat.id, scope_stack.last().scope_metadata);
walk_pattern(cx, sub_pat, scope_stack, scope_map);
}
ast::PatLit(@ref exp) => {
ast::PatLit(exp) => {
scope_map.insert(pat.id, scope_stack.last().scope_metadata);
walk_expr(cx, exp, scope_stack, scope_map);
}
ast::PatRange(@ref exp1, @ref exp2) => {
ast::PatRange(exp1, exp2) => {
scope_map.insert(pat.id, scope_stack.last().scope_metadata);
walk_expr(cx, exp1, scope_stack, scope_map);
walk_expr(cx, exp2, scope_stack, scope_map);
@ -2589,30 +2604,30 @@ fn populate_scope_map(cx: &CrateContext,
ast::ExprAgain(_) |
ast::ExprPath(_) => (),
ast::ExprVstore(@ref sub_exp, _) |
ast::ExprCast(@ref sub_exp, _) |
ast::ExprAddrOf(_, @ref sub_exp) |
ast::ExprField(@ref sub_exp, _, _) |
ast::ExprParen(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
ast::ExprVstore(sub_exp, _) |
ast::ExprCast(sub_exp, _) |
ast::ExprAddrOf(_, sub_exp) |
ast::ExprField(sub_exp, _, _) |
ast::ExprParen(sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
ast::ExprBox(@ref place, @ref sub_expr) => {
ast::ExprBox(place, sub_expr) => {
walk_expr(cx, place, scope_stack, scope_map);
walk_expr(cx, sub_expr, scope_stack, scope_map);
}
ast::ExprRet(exp_opt) => match exp_opt {
Some(@ref sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
Some(sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
None => ()
},
ast::ExprUnary(node_id, _, @ref sub_exp) => {
ast::ExprUnary(node_id, _, sub_exp) => {
scope_map.insert(node_id, scope_stack.last().scope_metadata);
walk_expr(cx, sub_exp, scope_stack, scope_map);
}
ast::ExprAssignOp(node_id, _, @ref lhs, @ref rhs) |
ast::ExprIndex(node_id, @ref lhs, @ref rhs) |
ast::ExprBinary(node_id, _, @ref lhs, @ref rhs) => {
ast::ExprAssignOp(node_id, _, lhs, rhs) |
ast::ExprIndex(node_id, lhs, rhs) |
ast::ExprBinary(node_id, _, lhs, rhs) => {
scope_map.insert(node_id, scope_stack.last().scope_metadata);
walk_expr(cx, lhs, scope_stack, scope_map);
walk_expr(cx, rhs, scope_stack, scope_map);
@ -2620,18 +2635,18 @@ fn populate_scope_map(cx: &CrateContext,
ast::ExprVec(ref init_expressions, _) |
ast::ExprTup(ref init_expressions) => {
for &@ref ie in init_expressions.iter() {
walk_expr(cx, ie, scope_stack, scope_map);
for ie in init_expressions.iter() {
walk_expr(cx, *ie, scope_stack, scope_map);
}
}
ast::ExprAssign(@ref sub_exp1, @ref sub_exp2) |
ast::ExprRepeat(@ref sub_exp1, @ref sub_exp2, _) => {
ast::ExprAssign(sub_exp1, sub_exp2) |
ast::ExprRepeat(sub_exp1, sub_exp2, _) => {
walk_expr(cx, sub_exp1, scope_stack, scope_map);
walk_expr(cx, sub_exp2, scope_stack, scope_map);
}
ast::ExprIf(@ref cond_exp, then_block, ref opt_else_exp) => {
ast::ExprIf(cond_exp, then_block, ref opt_else_exp) => {
walk_expr(cx, cond_exp, scope_stack, scope_map);
with_new_scope(cx,
@ -2643,12 +2658,12 @@ fn populate_scope_map(cx: &CrateContext,
});
match *opt_else_exp {
Some(@ref else_exp) => walk_expr(cx, else_exp, scope_stack, scope_map),
Some(else_exp) => walk_expr(cx, else_exp, scope_stack, scope_map),
_ => ()
}
}
ast::ExprWhile(@ref cond_exp, loop_body) => {
ast::ExprWhile(cond_exp, loop_body) => {
walk_expr(cx, cond_exp, scope_stack, scope_map);
with_new_scope(cx,
@ -2696,8 +2711,8 @@ fn populate_scope_map(cx: &CrateContext,
})
}
// ast::expr_loop_body(@ref inner_exp) |
ast::ExprDoBody(@ref inner_exp) => {
// ast::expr_loop_body(inner_exp) |
ast::ExprDoBody(inner_exp) => {
let inner_expr_is_expr_fn_block = match *inner_exp {
ast::Expr { node: ast::ExprFnBlock(..), .. } => true,
_ => false
@ -2711,24 +2726,24 @@ fn populate_scope_map(cx: &CrateContext,
walk_expr(cx, inner_exp, scope_stack, scope_map);
}
ast::ExprCall(@ref fn_exp, ref args, _) => {
ast::ExprCall(fn_exp, ref args, _) => {
walk_expr(cx, fn_exp, scope_stack, scope_map);
for &@ref arg_exp in args.iter() {
walk_expr(cx, arg_exp, scope_stack, scope_map);
for arg_exp in args.iter() {
walk_expr(cx, *arg_exp, scope_stack, scope_map);
}
}
ast::ExprMethodCall(node_id, @ref receiver_exp, _, _, ref args, _) => {
ast::ExprMethodCall(node_id, receiver_exp, _, _, ref args, _) => {
scope_map.insert(node_id, scope_stack.last().scope_metadata);
walk_expr(cx, receiver_exp, scope_stack, scope_map);
for &@ref arg_exp in args.iter() {
walk_expr(cx, arg_exp, scope_stack, scope_map);
for arg_exp in args.iter() {
walk_expr(cx, *arg_exp, scope_stack, scope_map);
}
}
ast::ExprMatch(@ref discriminant_exp, ref arms) => {
ast::ExprMatch(discriminant_exp, ref arms) => {
walk_expr(cx, discriminant_exp, scope_stack, scope_map);
// for each arm we have to first walk the pattern as these might introduce new
@ -2747,8 +2762,8 @@ fn populate_scope_map(cx: &CrateContext,
walk_pattern(cx, pat, scope_stack, scope_map);
}
for &@ref guard_exp in arm_ref.guard.iter() {
walk_expr(cx, guard_exp, scope_stack, scope_map)
for guard_exp in arm_ref.guard.iter() {
walk_expr(cx, *guard_exp, scope_stack, scope_map)
}
walk_block(cx, arm_ref.body, scope_stack, scope_map);
@ -2757,12 +2772,12 @@ fn populate_scope_map(cx: &CrateContext,
}
ast::ExprStruct(_, ref fields, ref base_exp) => {
for &ast::Field { expr: @ref exp, .. } in fields.iter() {
for &ast::Field { expr: exp, .. } in fields.iter() {
walk_expr(cx, exp, scope_stack, scope_map);
}
match *base_exp {
Some(@ref exp) => walk_expr(cx, exp, scope_stack, scope_map),
Some(exp) => walk_expr(cx, exp, scope_stack, scope_map),
None => ()
}
}
@ -2771,11 +2786,11 @@ fn populate_scope_map(cx: &CrateContext,
outputs: ref outputs,
.. }) => {
// inputs, outputs: ~[(@str, @expr)]
for &(_, @ref exp) in inputs.iter() {
for &(_, exp) in inputs.iter() {
walk_expr(cx, exp, scope_stack, scope_map);
}
for &(_, @ref exp) in outputs.iter() {
for &(_, exp) in outputs.iter() {
walk_expr(cx, exp, scope_stack, scope_map);
}
}

View File

@ -756,8 +756,19 @@ fn trans_rvalue_dps_unadjusted<'a>(
args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
return trans_adt(bcx, repr, 0, numbered_fields, None, dest);
}
ast::ExprLit(@codemap::Spanned {node: ast::LitStr(s, _), ..}) => {
return tvec::trans_lit_str(bcx, expr, s, dest);
ast::ExprLit(lit) => {
match lit.node {
ast::LitStr(s, _) => {
return tvec::trans_lit_str(bcx, expr, s, dest);
}
_ => {
bcx.tcx()
.sess
.span_bug(expr.span,
"trans_rvalue_dps_unadjusted shouldn't be \
translating this type of literal")
}
}
}
ast::ExprVstore(contents, ast::ExprVstoreSlice) |
ast::ExprVstore(contents, ast::ExprVstoreMutSlice) => {

View File

@ -109,8 +109,11 @@ pub fn trans_method(ccx: @CrateContext,
let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id);
let self_ty = match param_substs {
None => self_ty,
Some(@param_substs {tys: ref tys, self_ty: ref self_sub, ..}) => {
ty::subst_tps(ccx.tcx, *tys, *self_sub, self_ty)
Some(param_substs) => {
ty::subst_tps(ccx.tcx,
param_substs.tys,
param_substs.self_ty,
self_ty)
}
};
debug!("calling trans_fn with self_ty {}", self_ty.repr(ccx.tcx));

View File

@ -115,17 +115,21 @@ pub fn monomorphic_fn(ccx: @CrateContext,
// Foreign externs don't have to be monomorphized.
return (get_item_val(ccx, fn_id.node), true);
}
ast_map::NodeTraitMethod(@ast::Provided(m), _, pt) => {
// If this is a static provided method, indicate that
// and stash the number of params on the method.
if m.explicit_self.node == ast::SelfStatic {
is_static_provided = Some(m.generics.ty_params.len());
}
ast_map::NodeTraitMethod(method, _, pt) => {
match *method {
ast::Provided(m) => {
// If this is a static provided method, indicate that
// and stash the number of params on the method.
if m.explicit_self.node == ast::SelfStatic {
is_static_provided = Some(m.generics.ty_params.len());
}
(pt, m.ident, m.span)
}
ast_map::NodeTraitMethod(@ast::Required(_), _, _) => {
ccx.tcx.sess.bug("Can't monomorphize a required trait method")
(pt, m.ident, m.span)
}
ast::Required(_) => {
ccx.tcx.sess.bug("Can't monomorphize a required trait method")
}
}
}
ast_map::NodeExpr(..) => {
ccx.tcx.sess.bug("Can't monomorphize an expr")
@ -218,26 +222,30 @@ pub fn monomorphic_fn(ccx: @CrateContext,
};
let lldecl = match map_node {
ast_map::NodeItem(i@@ast::Item {
ast_map::NodeItem(i, _) => {
match *i {
ast::Item {
node: ast::ItemFn(decl, _, _, _, body),
..
}, _) => {
let d = mk_lldecl(None);
set_llvm_fn_attrs(i.attrs, d);
trans_fn(ccx,
pt,
decl,
body,
d,
None,
Some(psubsts),
fn_id.node,
None,
[]);
d
}
ast_map::NodeItem(..) => {
ccx.tcx.sess.bug("Can't monomorphize this kind of item")
} => {
let d = mk_lldecl(None);
set_llvm_fn_attrs(i.attrs, d);
trans_fn(ccx,
pt,
decl,
body,
d,
None,
Some(psubsts),
fn_id.node,
None,
[]);
d
}
_ => {
ccx.tcx.sess.bug("Can't monomorphize this kind of item")
}
}
}
ast_map::NodeForeignItem(i, _, _, _) => {
let d = mk_lldecl(None);
@ -272,12 +280,24 @@ pub fn monomorphic_fn(ccx: @CrateContext,
d
})
}
ast_map::NodeTraitMethod(@ast::Provided(mth), _, pt) => {
meth::trans_method(ccx, (*pt).clone(), mth, Some(psubsts), |self_ty| {
let d = mk_lldecl(self_ty);
set_llvm_fn_attrs(mth.attrs, d);
d
})
ast_map::NodeTraitMethod(method, _, pt) => {
match *method {
ast::Provided(mth) => {
meth::trans_method(ccx,
(*pt).clone(),
mth,
Some(psubsts),
|self_ty| {
let d = mk_lldecl(self_ty);
set_llvm_fn_attrs(mth.attrs, d);
d
})
}
_ => {
ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}",
map_node))
}
}
}
ast_map::NodeStructCtor(struct_def, _, _) => {
let d = mk_lldecl(None);
@ -294,7 +314,6 @@ pub fn monomorphic_fn(ccx: @CrateContext,
// Ugh -- but this ensures any new variants won't be forgotten
ast_map::NodeExpr(..) |
ast_map::NodeStmt(..) |
ast_map::NodeTraitMethod(..) |
ast_map::NodeArg(..) |
ast_map::NodeBlock(..) |
ast_map::NodeCalleeScope(..) |

View File

@ -30,7 +30,6 @@ use util::common::indenter;
use util::ppaux::ty_to_str;
use syntax::ast;
use syntax::codemap;
// Boxed vector types are in some sense currently a "shorthand" for a box
// containing an unboxed vector. This expands a boxed vector type into such an
@ -223,8 +222,13 @@ pub fn trans_slice_vstore<'a>(
// Handle the &"..." case:
match content_expr.node {
ast::ExprLit(@codemap::Spanned {node: ast::LitStr(s, _), span: _}) => {
return trans_lit_str(bcx, content_expr, s, dest);
ast::ExprLit(lit) => {
match lit.node {
ast::LitStr(s, _) => {
return trans_lit_str(bcx, content_expr, s, dest);
}
_ => {}
}
}
_ => {}
}
@ -317,25 +321,30 @@ pub fn trans_uniq_or_managed_vstore<'a>(
match heap {
heap_exchange => {
match content_expr.node {
ast::ExprLit(@codemap::Spanned {
node: ast::LitStr(s, _), span
}) => {
let llptrval = C_cstr(bcx.ccx(), s);
let llptrval = PointerCast(bcx, llptrval, Type::i8p());
let llsizeval = C_uint(bcx.ccx(), s.len());
let typ = ty::mk_str(bcx.tcx(), ty::vstore_uniq);
let lldestval = scratch_datum(bcx, typ, "", false);
let alloc_fn = langcall(bcx, Some(span), "",
StrDupUniqFnLangItem);
let bcx = callee::trans_lang_call(
bcx,
alloc_fn,
[ llptrval, llsizeval ],
Some(expr::SaveIn(lldestval.to_ref_llval(bcx)))).bcx;
return DatumBlock {
bcx: bcx,
datum: lldestval
};
ast::ExprLit(lit) => {
match lit.node {
ast::LitStr(s, _) => {
let llptrval = C_cstr(bcx.ccx(), s);
let llptrval = PointerCast(bcx, llptrval, Type::i8p());
let llsizeval = C_uint(bcx.ccx(), s.len());
let typ = ty::mk_str(bcx.tcx(), ty::vstore_uniq);
let lldestval = scratch_datum(bcx, typ, "", false);
let alloc_fn = langcall(bcx,
Some(lit.span),
"",
StrDupUniqFnLangItem);
let bcx = callee::trans_lang_call(
bcx,
alloc_fn,
[ llptrval, llsizeval ],
Some(expr::SaveIn(lldestval.to_ref_llval(bcx)))).bcx;
return DatumBlock {
bcx: bcx,
datum: lldestval
};
}
_ => {}
}
}
_ => {}
}
@ -380,17 +389,29 @@ pub fn write_content<'a>(
let _indenter = indenter();
match content_expr.node {
ast::ExprLit(@codemap::Spanned { node: ast::LitStr(s, _), .. }) => {
match dest {
Ignore => {
return bcx;
ast::ExprLit(lit) => {
match lit.node {
ast::LitStr(s, _) => {
match dest {
Ignore => {
return bcx;
}
SaveIn(lldest) => {
let bytes = s.len();
let llbytes = C_uint(bcx.ccx(), bytes);
let llcstr = C_cstr(bcx.ccx(), s);
base::call_memcpy(bcx,
lldest,
llcstr,
llbytes,
1);
return bcx;
}
}
}
SaveIn(lldest) => {
let bytes = s.len();
let llbytes = C_uint(bcx.ccx(), bytes);
let llcstr = C_cstr(bcx.ccx(), s);
base::call_memcpy(bcx, lldest, llcstr, llbytes, 1);
return bcx;
_ => {
bcx.tcx().sess.span_bug(content_expr.span,
"Unexpected evec content");
}
}
}
@ -477,8 +498,14 @@ pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint {
//! Figure out the number of elements we need to store this content
match content_expr.node {
ast::ExprLit(@codemap::Spanned { node: ast::LitStr(s, _), .. }) => {
s.len()
ast::ExprLit(lit) => {
match lit.node {
ast::LitStr(s, _) => s.len(),
_ => {
bcx.tcx().sess.span_bug(content_expr.span,
"Unexpected evec content")
}
}
},
ast::ExprVec(ref es, _) => es.len(),
ast::ExprRepeat(_, count_expr, _) => {

View File

@ -38,12 +38,11 @@ use std::to_bytes;
use std::to_str::ToStr;
use std::vec;
use syntax::ast::*;
use syntax::ast_util::is_local;
use syntax::ast_util::{is_local, lit_is_str};
use syntax::ast_util;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span;
use syntax::codemap;
use syntax::parse::token;
use syntax::{ast, ast_map};
use syntax::opt_vec::OptVec;
@ -2864,78 +2863,101 @@ pub fn adjust_ty(cx: ctxt,
return match adjustment {
None => unadjusted_ty,
Some(@AutoAddEnv(r, s)) => {
match ty::get(unadjusted_ty).sty {
ty::ty_bare_fn(ref b) => {
ty::mk_closure(
cx,
ty::ClosureTy {purity: b.purity,
sigil: s,
onceness: ast::Many,
region: r,
bounds: ty::AllBuiltinBounds(),
sig: b.sig.clone()})
}
ref b => {
cx.sess.bug(
format!("add_env adjustment on non-bare-fn: {:?}", b));
}
}
}
Some(@AutoDerefRef(ref adj)) => {
let mut adjusted_ty = unadjusted_ty;
if (!ty::type_is_error(adjusted_ty)) {
for i in range(0, adj.autoderefs) {
match ty::deref(adjusted_ty, true) {
Some(mt) => { adjusted_ty = mt.ty; }
None => {
cx.sess.span_bug(
span,
format!("The {}th autoderef failed: {}",
i, ty_to_str(cx,
adjusted_ty)));
Some(adjustment) => {
match *adjustment {
AutoAddEnv(r, s) => {
match ty::get(unadjusted_ty).sty {
ty::ty_bare_fn(ref b) => {
ty::mk_closure(
cx,
ty::ClosureTy {purity: b.purity,
sigil: s,
onceness: ast::Many,
region: r,
bounds: ty::AllBuiltinBounds(),
sig: b.sig.clone()})
}
ref b => {
cx.sess.bug(
format!("add_env adjustment on non-bare-fn: \
{:?}",
b));
}
}
}
}
match adj.autoref {
None => adjusted_ty,
Some(ref autoref) => {
match *autoref {
AutoPtr(r, m) => {
mk_rptr(cx, r, mt {ty: adjusted_ty, mutbl: m})
AutoDerefRef(ref adj) => {
let mut adjusted_ty = unadjusted_ty;
if (!ty::type_is_error(adjusted_ty)) {
for i in range(0, adj.autoderefs) {
match ty::deref(adjusted_ty, true) {
Some(mt) => { adjusted_ty = mt.ty; }
None => {
cx.sess.span_bug(
span,
format!("The {}th autoderef failed: \
{}",
i,
ty_to_str(cx, adjusted_ty)));
}
}
}
}
AutoBorrowVec(r, m) => {
borrow_vec(cx, span, r, m, adjusted_ty)
}
match adj.autoref {
None => adjusted_ty,
Some(ref autoref) => {
match *autoref {
AutoPtr(r, m) => {
mk_rptr(cx, r, mt {
ty: adjusted_ty,
mutbl: m
})
}
AutoBorrowVecRef(r, m) => {
adjusted_ty = borrow_vec(cx, span, r, m, adjusted_ty);
mk_rptr(cx, r, mt {ty: adjusted_ty, mutbl: ast::MutImmutable})
}
AutoBorrowVec(r, m) => {
borrow_vec(cx, span, r, m, adjusted_ty)
}
AutoBorrowFn(r) => {
borrow_fn(cx, span, r, adjusted_ty)
}
AutoBorrowVecRef(r, m) => {
adjusted_ty = borrow_vec(cx,
span,
r,
m,
adjusted_ty);
mk_rptr(cx, r, mt {
ty: adjusted_ty,
mutbl: ast::MutImmutable
})
}
AutoUnsafe(m) => {
mk_ptr(cx, mt {ty: adjusted_ty, mutbl: m})
}
AutoBorrowFn(r) => {
borrow_fn(cx, span, r, adjusted_ty)
}
AutoBorrowObj(r, m) => {
borrow_obj(cx, span, r, m, adjusted_ty)
AutoUnsafe(m) => {
mk_ptr(cx, mt {ty: adjusted_ty, mutbl: m})
}
AutoBorrowObj(r, m) => {
borrow_obj(cx, span, r, m, adjusted_ty)
}
}
}
}
}
}
}
Some(@AutoObject(ref sigil, ref region, m, b, def_id, ref substs)) => {
trait_adjustment_to_ty(cx, sigil, region, def_id, substs, m, b)
AutoObject(ref sigil, ref region, m, b, def_id, ref substs) => {
trait_adjustment_to_ty(cx,
sigil,
region,
def_id,
substs,
m,
b)
}
}
}
};
@ -3165,13 +3187,16 @@ pub fn expr_kind(tcx: ctxt,
ast::ExprDoBody(..) |
ast::ExprBlock(..) |
ast::ExprRepeat(..) |
ast::ExprLit(@codemap::Spanned {node: LitStr(..), ..}) |
ast::ExprVstore(_, ast::ExprVstoreSlice) |
ast::ExprVstore(_, ast::ExprVstoreMutSlice) |
ast::ExprVec(..) => {
RvalueDpsExpr
}
ast::ExprLit(lit) if lit_is_str(lit) => {
RvalueDpsExpr
}
ast::ExprCast(..) => {
let node_types = tcx.node_types.borrow();
match node_types.get().find(&(expr.id as uint)) {
@ -3546,15 +3571,24 @@ pub fn provided_trait_methods(cx: ctxt, id: ast::DefId) -> ~[@Method] {
{
let items = cx.items.borrow();
match items.get().find(&id.node) {
Some(&ast_map::NodeItem(@ast::Item {
node: ItemTrait(_, _, ref ms),
..
}, _)) =>
match ast_util::split_trait_methods(*ms) {
(_, p) => p.map(|m| method(cx, ast_util::local_def(m.id)))
},
_ => cx.sess.bug(format!("provided_trait_methods: {:?} is not a trait",
id))
Some(&ast_map::NodeItem(item, _)) => {
match item.node {
ItemTrait(_, _, ref ms) => {
let (_, p) = ast_util::split_trait_methods(*ms);
p.map(|m| method(cx, ast_util::local_def(m.id)))
}
_ => {
cx.sess.bug(format!("provided_trait_methods: \
{:?} is not a trait",
id))
}
}
}
_ => {
cx.sess.bug(format!("provided_trait_methods: {:?} is not \
a trait",
id))
}
}
}
} else {
@ -3668,13 +3702,18 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::DefId) -> Option<@TraitRef> {
{
let items = cx.items.borrow();
match items.get().find(&id.node) {
Some(&ast_map::NodeItem(@ast::Item {
node: ast::ItemImpl(_, ref opt_trait, _, _),
..},
_)) => {
match opt_trait {
&Some(ref t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
&None => None
Some(&ast_map::NodeItem(item, _)) => {
match item.node {
ast::ItemImpl(_, ref opt_trait, _, _) => {
match opt_trait {
&Some(ref t) => {
Some(ty::node_id_to_trait_ref(cx,
t.ref_id))
}
&None => None
}
}
_ => None
}
}
_ => None
@ -3931,37 +3970,55 @@ pub fn enum_variants(cx: ctxt, id: ast::DefId) -> @~[@VariantInfo] {
{
let items = cx.items.borrow();
match items.get().get_copy(&id.node) {
ast_map::NodeItem(@ast::Item {
node: ast::ItemEnum(ref enum_definition, _),
..
}, _) => {
let mut last_discriminant: Option<Disr> = None;
@enum_definition.variants.iter().map(|&variant| {
ast_map::NodeItem(item, _) => {
match item.node {
ast::ItemEnum(ref enum_definition, _) => {
let mut last_discriminant: Option<Disr> = None;
@enum_definition.variants.iter().map(|&variant| {
let mut discriminant = match last_discriminant {
Some(val) => val + 1,
None => INITIAL_DISCRIMINANT_VALUE
};
let mut discriminant = match last_discriminant {
Some(val) => val + 1,
None => INITIAL_DISCRIMINANT_VALUE
};
match variant.node.disr_expr {
Some(e) => match const_eval::eval_const_expr_partial(&cx, e) {
Ok(const_eval::const_int(val)) => discriminant = val as Disr,
Ok(const_eval::const_uint(val)) => discriminant = val as Disr,
Ok(_) => {
cx.sess.span_err(e.span, "expected signed integer constant");
}
Err(ref err) => {
cx.sess.span_err(e.span, format!("expected constant: {}", (*err)));
}
},
None => {}
};
match variant.node.disr_expr {
Some(e) => match const_eval::eval_const_expr_partial(&cx, e) {
Ok(const_eval::const_int(val)) => {
discriminant = val as Disr
}
Ok(const_eval::const_uint(val)) => {
discriminant = val as Disr
}
Ok(_) => {
cx.sess
.span_err(e.span,
"expected signed integer \
constant");
}
Err(ref err) => {
cx.sess
.span_err(e.span,
format!("expected \
constant: {}",
(*err)));
}
},
None => {}
};
let variant_info = @VariantInfo::from_ast_variant(cx, variant, discriminant);
last_discriminant = Some(discriminant);
variant_info
let variant_info =
@VariantInfo::from_ast_variant(cx,
variant,
discriminant);
last_discriminant = Some(discriminant);
variant_info
}).collect()
}).collect()
}
_ => {
cx.sess.bug("enum_variants: id not bound to an enum")
}
}
}
_ => cx.sess.bug("enum_variants: id not bound to an enum")
}
@ -4038,11 +4095,9 @@ pub fn each_attr(tcx: ctxt, did: DefId, f: |@MetaItem| -> bool) -> bool {
{
let items = tcx.items.borrow();
match items.get().find(&did.node) {
Some(&ast_map::NodeItem(@ast::Item {
attrs: ref attrs,
..
}, _)) =>
attrs.iter().advance(|attr| f(attr.node.value)),
Some(&ast_map::NodeItem(item, _)) => {
item.attrs.iter().advance(|attr| f(attr.node.value))
}
_ => tcx.sess.bug(format!("has_attr: {:?} is not an item",
did))
}

View File

@ -585,9 +585,6 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
}
}
}
ast::PatBox(inner) => {
check_pointer_pat(pcx, Managed, inner, pat.id, pat.span, expected);
}
ast::PatUniq(inner) => {
check_pointer_pat(pcx, Send, inner, pat.id, pat.span, expected);
}
@ -672,9 +669,6 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
fcx.write_ty(pat_id, expected);
};
match *structure_of(fcx, span, expected) {
ty::ty_box(e_inner) if pointer_kind == Managed => {
check_inner(e_inner);
}
ty::ty_uniq(e_inner) if pointer_kind == Send => {
check_inner(e_inner.ty);
}
@ -692,7 +686,6 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
e, actual)})},
Some(expected),
format!("{} pattern", match pointer_kind {
Managed => "an @-box",
Send => "a ~-box",
Borrowed => "an &-pointer"
}),
@ -703,5 +696,5 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
}
#[deriving(Eq)]
enum PointerKind { Managed, Send, Borrowed }
enum PointerKind { Send, Borrowed }

View File

@ -1309,10 +1309,15 @@ impl<'a> LookupContext<'a> {
{
let items = self.tcx().items.borrow();
match items.get().find(&did.node) {
Some(&ast_map::NodeMethod(m, _, _))
| Some(&ast_map::NodeTraitMethod(@ast::Provided(m),
_, _)) => {
m.span
Some(&ast_map::NodeMethod(m, _, _)) => m.span,
Some(&ast_map::NodeTraitMethod(trait_method, _, _)) => {
match *trait_method {
ast::Provided(m) => m.span,
_ => {
fail!("report_static_candidate, bad item {:?}",
did)
}
}
}
_ => fail!("report_static_candidate: bad item {:?}", did)
}

View File

@ -2627,7 +2627,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
match expr.node {
ast::ExprVstore(ev, vst) => {
let typ = match ev.node {
ast::ExprLit(@codemap::Spanned { node: ast::LitStr(..), .. }) => {
ast::ExprLit(lit) if ast_util::lit_is_str(lit) => {
let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
ty::mk_str(tcx, tt)
}
@ -3487,11 +3487,13 @@ pub fn check_block_with_expected(fcx: @FnCtxt,
let s_id = ast_util::stmt_id(*s);
let s_ty = fcx.node_ty(s_id);
if last_was_bot && !warned && match s.node {
ast::StmtDecl(@codemap::Spanned { node: ast::DeclLocal(_),
..}, _) |
ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => {
true
ast::StmtDecl(decl, _) => {
match decl.node {
ast::DeclLocal(_) => true,
_ => false,
}
}
ast::StmtExpr(_, _) | ast::StmtSemi(_, _) => true,
_ => false
} {
fcx.ccx.tcx.sess.add_lint(UnreachableCode, s_id, s.span,

View File

@ -310,8 +310,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
let r = adjustments.get().find(&expr.id);
for &adjustment in r.iter() {
debug!("adjustment={:?}", adjustment);
match *adjustment {
@ty::AutoDerefRef(
match **adjustment {
ty::AutoDerefRef(
ty::AutoDerefRef {autoderefs: autoderefs, autoref: opt_autoref}) =>
{
let expr_ty = rcx.resolve_node_type(expr.id);
@ -328,7 +328,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
infer::AutoBorrow(expr.span));
}
}
@ty::AutoObject(ast::BorrowedSigil, Some(trait_region), _, _, _, _) => {
ty::AutoObject(ast::BorrowedSigil, Some(trait_region), _, _, _, _) => {
// Determine if we are casting `expr` to an trait
// instance. If so, we have to be sure that the type of
// the source obeys the trait's region bound.
@ -1086,66 +1086,75 @@ pub mod guarantor {
let adjustments = rcx.fcx.inh.adjustments.borrow();
match adjustments.get().find(&expr.id) {
Some(&@ty::AutoAddEnv(..)) => {
// This is basically an rvalue, not a pointer, no regions
// involved.
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: NotPointer
};
}
Some(&@ty::AutoObject(ast::BorrowedSigil, Some(region), _, _, _, _)) => {
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: BorrowedPointer(region)
};
}
Some(&@ty::AutoObject(ast::OwnedSigil, _, _, _, _, _)) => {
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: OwnedPointer
};
}
Some(&@ty::AutoObject(ast::ManagedSigil, _, _, _, _, _)) => {
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: OtherPointer
};
}
Some(&@ty::AutoDerefRef(ref adjustment)) => {
debug!("adjustment={:?}", adjustment);
expr_ct = apply_autoderefs(
rcx, expr, adjustment.autoderefs, expr_ct);
match adjustment.autoref {
None => {
Some(adjustment) => {
match **adjustment {
ty::AutoAddEnv(..) => {
// This is basically an rvalue, not a pointer, no regions
// involved.
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: NotPointer
};
}
Some(ty::AutoUnsafe(_)) => {
expr_ct.cat.guarantor = None;
expr_ct.cat.pointer = OtherPointer;
debug!("autoref, cat={:?}", expr_ct.cat);
ty::AutoObject(ast::BorrowedSigil,
Some(region),
_,
_,
_,
_) => {
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: BorrowedPointer(region)
};
}
Some(ty::AutoPtr(r, _)) |
Some(ty::AutoBorrowVec(r, _)) |
Some(ty::AutoBorrowVecRef(r, _)) |
Some(ty::AutoBorrowFn(r)) |
Some(ty::AutoBorrowObj(r, _)) => {
// If there is an autoref, then the result of this
// expression will be some sort of reference.
expr_ct.cat.guarantor = None;
expr_ct.cat.pointer = BorrowedPointer(r);
debug!("autoref, cat={:?}", expr_ct.cat);
ty::AutoObject(ast::OwnedSigil, _, _, _, _, _) => {
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: OwnedPointer
};
}
ty::AutoObject(ast::ManagedSigil, _, _, _, _, _) => {
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: OtherPointer
};
}
ty::AutoDerefRef(ref adjustment) => {
debug!("adjustment={:?}", adjustment);
expr_ct = apply_autoderefs(
rcx, expr, adjustment.autoderefs, expr_ct);
match adjustment.autoref {
None => {
}
Some(ty::AutoUnsafe(_)) => {
expr_ct.cat.guarantor = None;
expr_ct.cat.pointer = OtherPointer;
debug!("autoref, cat={:?}", expr_ct.cat);
}
Some(ty::AutoPtr(r, _)) |
Some(ty::AutoBorrowVec(r, _)) |
Some(ty::AutoBorrowVecRef(r, _)) |
Some(ty::AutoBorrowFn(r)) |
Some(ty::AutoBorrowObj(r, _)) => {
// If there is an autoref, then the result of
// this expression will be some sort of
// reference.
expr_ct.cat.guarantor = None;
expr_ct.cat.pointer = BorrowedPointer(r);
debug!("autoref, cat={:?}", expr_ct.cat);
}
}
}
_ => fail!("invalid or unhandled adjustment"),
}
}
Some(..) => fail!("invalid or unhandled adjustment"),
None => {}
}
@ -1298,9 +1307,6 @@ pub mod guarantor {
ast::PatTup(ref ps) => {
link_ref_bindings_in_pats(rcx, ps, guarantor)
}
ast::PatBox(p) => {
link_ref_bindings_in_pat(rcx, p, None)
}
ast::PatUniq(p) => {
link_ref_bindings_in_pat(rcx, p, guarantor)
}

View File

@ -741,15 +741,33 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) {
// Search for auto-adjustments to find trait coercions
let adjustments = fcx.inh.adjustments.borrow();
match adjustments.get().find(&ex.id) {
Some(&@AutoObject(ref sigil, ref region, m, b, def_id, ref substs)) => {
debug!("doing trait adjustment for expr {} {} (early? {})",
ex.id, ex.repr(fcx.tcx()), is_early);
Some(adjustment) => {
match **adjustment {
AutoObject(ref sigil,
ref region,
m,
b,
def_id,
ref substs) => {
debug!("doing trait adjustment for expr {} {} \
(early? {})",
ex.id,
ex.repr(fcx.tcx()),
is_early);
let object_ty = ty::trait_adjustment_to_ty(cx.tcx, sigil, region,
def_id, substs, m, b);
resolve_object_cast(ex, object_ty);
let object_ty = ty::trait_adjustment_to_ty(cx.tcx,
sigil,
region,
def_id,
substs,
m,
b);
resolve_object_cast(ex, object_ty);
}
AutoAddEnv(..) | AutoDerefRef(..) => {}
}
}
Some(&@AutoAddEnv(..)) | Some(&@AutoDerefRef(..)) | None => {}
None => {}
}
}

View File

@ -140,55 +140,71 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
match adjustment {
None => (),
Some(@ty::AutoAddEnv(r, s)) => {
match resolve_region(fcx.infcx(), r, resolve_all | force_all) {
Err(e) => {
// This should not, I think, happen:
fcx.ccx.tcx.sess.span_err(
sp, format!("cannot resolve bound for closure: {}",
infer::fixup_err_to_str(e)));
Some(adjustment) => {
match *adjustment {
ty::AutoAddEnv(r, s) => {
match resolve_region(fcx.infcx(),
r,
resolve_all | force_all) {
Err(e) => {
// This should not, I think, happen:
fcx.ccx.tcx.sess.span_err(
sp,
format!("cannot resolve bound for closure: \
{}",
infer::fixup_err_to_str(e)));
}
Ok(r1) => {
let resolved_adj = @ty::AutoAddEnv(r1, s);
debug!("Adjustments for node {}: {:?}",
id,
resolved_adj);
let mut adjustments = fcx.tcx()
.adjustments
.borrow_mut();
adjustments.get().insert(id, resolved_adj);
}
}
}
Ok(r1) => {
let resolved_adj = @ty::AutoAddEnv(r1, s);
ty::AutoDerefRef(adj) => {
let fixup_region = |r| {
match resolve_region(fcx.infcx(),
r,
resolve_all | force_all) {
Ok(r1) => r1,
Err(e) => {
// This should not, I think, happen.
fcx.ccx.tcx.sess.span_err(
sp,
format!("cannot resolve scope of borrow: \
{}",
infer::fixup_err_to_str(e)));
r
}
}
};
let resolved_autoref = match adj.autoref {
None => None,
Some(ref r) => Some(r.map_region(fixup_region))
};
let resolved_adj = @ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adj.autoderefs,
autoref: resolved_autoref,
});
debug!("Adjustments for node {}: {:?}", id, resolved_adj);
let mut adjustments = fcx.tcx().adjustments.borrow_mut();
adjustments.get().insert(id, resolved_adj);
}
}
}
Some(@ty::AutoDerefRef(adj)) => {
let fixup_region = |r| {
match resolve_region(fcx.infcx(), r, resolve_all | force_all) {
Ok(r1) => r1,
Err(e) => {
// This should not, I think, happen.
fcx.ccx.tcx.sess.span_err(
sp, format!("cannot resolve scope of borrow: {}",
infer::fixup_err_to_str(e)));
r
}
ty::AutoObject(..) => {
debug!("Adjustments for node {}: {:?}", id, adjustment);
let mut adjustments = fcx.tcx().adjustments.borrow_mut();
adjustments.get().insert(id, adjustment);
}
};
let resolved_autoref = match adj.autoref {
None => None,
Some(ref r) => Some(r.map_region(fixup_region))
};
let resolved_adj = @ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adj.autoderefs,
autoref: resolved_autoref,
});
debug!("Adjustments for node {}: {:?}", id, resolved_adj);
let mut adjustments = fcx.tcx().adjustments.borrow_mut();
adjustments.get().insert(id, resolved_adj);
}
Some(adjustment @ @ty::AutoObject(..)) => {
debug!("Adjustments for node {}: {:?}", id, adjustment);
let mut adjustments = fcx.tcx().adjustments.borrow_mut();
adjustments.get().insert(id, adjustment);
}
}
}

View File

@ -736,7 +736,7 @@ impl CoherenceChecker {
{
let items = tcx.items.borrow();
match items.get().find(&impl_info.did.node) {
Some(&ast_map::NodeItem(@ref item, _)) => {
Some(&ast_map::NodeItem(item, _)) => {
tcx.sess.span_err((*item).span,
"the Drop trait may \
only be implemented \

View File

@ -183,59 +183,63 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
}
}
pub fn ensure_trait_methods(ccx: &CrateCtxt,
trait_id: ast::NodeId)
{
pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
let tcx = ccx.tcx;
let items = tcx.items.borrow();
match items.get().get_copy(&trait_id) {
ast_map::NodeItem(@ast::Item {
node: ast::ItemTrait(ref generics, _, ref ms),
..
}, _) => {
let trait_ty_generics =
ty_generics(ccx, generics, 0);
ast_map::NodeItem(item, _) => {
match item.node {
ast::ItemTrait(ref generics, _, ref ms) => {
let trait_ty_generics = ty_generics(ccx, generics, 0);
// For each method, construct a suitable ty::Method and
// store it into the `tcx.methods` table:
for m in ms.iter() {
let ty_method = @match m {
&ast::Required(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics,
&m.id, &m.ident, &m.explicit_self,
&m.generics, &m.purity, m.decl)
// For each method, construct a suitable ty::Method and
// store it into the `tcx.methods` table:
for m in ms.iter() {
let ty_method = @match m {
&ast::Required(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics,
&m.id, &m.ident, &m.explicit_self,
&m.generics, &m.purity, m.decl)
}
&ast::Provided(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics,
&m.id, &m.ident, &m.explicit_self,
&m.generics, &m.purity, m.decl)
}
};
if ty_method.explicit_self == ast::SelfStatic {
make_static_method_ty(ccx, trait_id, ty_method,
&trait_ty_generics);
}
let mut methods = tcx.methods.borrow_mut();
methods.get().insert(ty_method.def_id, ty_method);
}
&ast::Provided(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics,
&m.id, &m.ident, &m.explicit_self,
&m.generics, &m.purity, m.decl)
}
};
// Add an entry mapping
let method_def_ids = @ms.map(|m| {
match m {
&ast::Required(ref ty_method) => {
local_def(ty_method.id)
}
&ast::Provided(ref method) => {
local_def(method.id)
}
}
});
if ty_method.explicit_self == ast::SelfStatic {
make_static_method_ty(ccx, trait_id, ty_method,
&trait_ty_generics);
let trait_def_id = local_def(trait_id);
let mut trait_method_def_ids = tcx.trait_method_def_ids
.borrow_mut();
trait_method_def_ids.get().insert(trait_def_id,
method_def_ids);
}
let mut methods = tcx.methods.borrow_mut();
methods.get().insert(ty_method.def_id, ty_method);
_ => {} // Ignore things that aren't traits.
}
// Add an entry mapping
let method_def_ids = @ms.map(|m| {
match m {
&ast::Required(ref ty_method) => local_def(ty_method.id),
&ast::Provided(ref method) => local_def(method.id)
}
});
let trait_def_id = local_def(trait_id);
let mut trait_method_def_ids = tcx.trait_method_def_ids
.borrow_mut();
trait_method_def_ids.get().insert(trait_def_id, method_def_ids);
}
_ => { /* Ignore things that aren't traits */ }
}

View File

@ -1142,7 +1142,6 @@ fn name_from_pat(p: &ast::Pat) -> ~str {
PatStruct(..) => fail!("tried to get argument name from pat_struct, \
which is not allowed in function arguments"),
PatTup(..) => ~"(tuple arg NYI)",
PatBox(p) => name_from_pat(p),
PatUniq(p) => name_from_pat(p),
PatRegion(p) => name_from_pat(p),
PatLit(..) => {

View File

@ -369,7 +369,6 @@ pub enum Pat_ {
* we don't bind the fields to names */
PatStruct(Path, ~[FieldPat], bool),
PatTup(~[@Pat]),
PatBox(@Pat),
PatUniq(@Pat),
PatRegion(@Pat), // reference pattern
PatLit(@Expr),

View File

@ -507,8 +507,12 @@ pub fn node_span(items: Map, id: ast::NodeId) -> Span {
match items.get().find(&id) {
Some(&NodeItem(item, _)) => item.span,
Some(&NodeForeignItem(foreign_item, _, _, _)) => foreign_item.span,
Some(&NodeTraitMethod(@Required(ref type_method), _, _)) => type_method.span,
Some(&NodeTraitMethod(@Provided(ref method), _, _)) => method.span,
Some(&NodeTraitMethod(trait_method, _, _)) => {
match *trait_method {
Required(ref type_method) => type_method.span,
Provided(ref method) => method.span,
}
}
Some(&NodeMethod(method, _, _)) => method.span,
Some(&NodeVariant(variant, _, _)) => variant.span,
Some(&NodeExpr(expr)) => expr.span,

View File

@ -614,7 +614,7 @@ pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().advance(|&p| walk_pat(p, |p| it(p)))
}
PatBox(s) | PatUniq(s) | PatRegion(s) => {
PatUniq(s) | PatRegion(s) => {
walk_pat(s, it)
}
PatVec(ref before, ref slice, ref after) => {
@ -945,6 +945,15 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
}
}
// Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: @Lit) -> bool {
match lit.node {
LitStr(..) => true,
_ => false,
}
}
#[cfg(test)]
mod test {
use ast::*;

View File

@ -324,7 +324,7 @@ impl ExtCtxt {
pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
pub fn call_site(&self) -> Span {
match self.backtrace {
Some(@ExpnInfo {call_site: cs, ..}) => cs,
Some(expn_info) => expn_info.call_site,
None => self.bug("missing top span")
}
}
@ -346,10 +346,7 @@ impl ExtCtxt {
}
pub fn bt_pop(&mut self) {
match self.backtrace {
Some(@ExpnInfo {
call_site: Span {expn_info: prev, ..}, ..}) => {
self.backtrace = prev
}
Some(expn_info) => self.backtrace = expn_info.call_site.expn_info,
_ => self.bug("tried to pop without a push")
}
}

View File

@ -471,63 +471,66 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
-> SmallVector<@Stmt> {
// is it a let?
match s.node {
StmtDecl(@Spanned {
node: DeclLocal(ref local),
span: stmt_span
},
node_id) => {
// take it apart:
let @Local {
ty: _,
pat: pat,
init: init,
id: id,
span: span
} = *local;
// expand the pat (it might contain exprs... #:(o)>
let expanded_pat = fld.fold_pat(pat);
// find the pat_idents in the pattern:
// oh dear heaven... this is going to include the enum names, as well....
// ... but that should be okay, as long as the new names are gensyms
// for the old ones.
let mut name_finder = new_name_finder(~[]);
name_finder.visit_pat(expanded_pat,());
// generate fresh names, push them to a new pending list
let mut new_pending_renames = ~[];
for ident in name_finder.ident_accumulator.iter() {
let new_name = fresh_name(ident);
new_pending_renames.push((*ident,new_name));
StmtDecl(decl, node_id) => {
match *decl {
Spanned {
node: DeclLocal(ref local),
span: stmt_span
} => {
// take it apart:
let Local {
ty: _,
pat: pat,
init: init,
id: id,
span: span
} = **local;
// expand the pat (it might contain exprs... #:(o)>
let expanded_pat = fld.fold_pat(pat);
// find the pat_idents in the pattern:
// oh dear heaven... this is going to include the enum
// names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones.
let mut name_finder = new_name_finder(~[]);
name_finder.visit_pat(expanded_pat,());
// generate fresh names, push them to a new pending list
let mut new_pending_renames = ~[];
for ident in name_finder.ident_accumulator.iter() {
let new_name = fresh_name(ident);
new_pending_renames.push((*ident,new_name));
}
let rewritten_pat = {
let mut rename_fld =
renames_to_fold(&mut new_pending_renames);
// rewrite the pattern using the new names (the old
// ones have already been applied):
rename_fld.fold_pat(expanded_pat)
};
// add them to the existing pending renames:
for pr in new_pending_renames.iter() {
fld.extsbox.info().pending_renames.push(*pr)
}
// also, don't forget to expand the init:
let new_init_opt = init.map(|e| fld.fold_expr(e));
let rewritten_local =
@Local {
ty: local.ty,
pat: rewritten_pat,
init: new_init_opt,
id: id,
span: span,
};
SmallVector::one(@Spanned {
node: StmtDecl(@Spanned {
node: DeclLocal(rewritten_local),
span: stmt_span
},
node_id),
span: span
})
}
_ => noop_fold_stmt(s, fld),
}
let rewritten_pat = {
let mut rename_fld =
renames_to_fold(&mut new_pending_renames);
// rewrite the pattern using the new names (the old ones
// have already been applied):
rename_fld.fold_pat(expanded_pat)
};
// add them to the existing pending renames:
for pr in new_pending_renames.iter() {
fld.extsbox.info().pending_renames.push(*pr)
}
// also, don't forget to expand the init:
let new_init_opt = init.map(|e| fld.fold_expr(e));
let rewritten_local =
@Local {
ty: local.ty,
pat: rewritten_pat,
init: new_init_opt,
id: id,
span: span,
};
SmallVector::one(@Spanned {
node: StmtDecl(@Spanned {
node: DeclLocal(rewritten_local),
span: stmt_span
},
node_id),
span: span
})
},
_ => noop_fold_stmt(s, fld),
}

View File

@ -126,15 +126,15 @@ fn generic_extension(cx: &ExtCtxt,
let s_d = cx.parse_sess().span_diagnostic;
for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers
match *lhs {
@MatchedNonterminal(NtMatchers(ref mtcs)) => {
match **lhs {
MatchedNonterminal(NtMatchers(ref mtcs)) => {
// `none` is because we're not interpolating
let arg_rdr = new_tt_reader(s_d, None, arg.to_owned()) as @Reader;
match parse(cx.parse_sess(), cx.cfg(), arg_rdr, *mtcs) {
Success(named_matches) => {
let rhs = match rhses[i] {
let rhs = match *rhses[i] {
// okay, what's your transcriber?
@MatchedNonterminal(NtTT(@ref tt)) => {
MatchedNonterminal(NtTT(tt)) => {
match (*tt) {
// cut off delimiters; don't parse 'em
TTDelim(ref tts) => {
@ -214,13 +214,13 @@ pub fn add_new_extension(cx: &mut ExtCtxt,
argument_gram);
// Extract the arguments:
let lhses = match *argument_map.get(&lhs_nm) {
@MatchedSeq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(),
let lhses = match **argument_map.get(&lhs_nm) {
MatchedSeq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(),
_ => cx.span_bug(sp, "wrong-structured lhs")
};
let rhses = match *argument_map.get(&rhs_nm) {
@MatchedSeq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(),
let rhses = match **argument_map.get(&rhs_nm) {
MatchedSeq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(),
_ => cx.span_bug(sp, "wrong-structured rhs")
};

View File

@ -687,7 +687,6 @@ pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
PatStruct(pth_, fs, etc)
}
PatTup(ref elts) => PatTup(elts.map(|x| folder.fold_pat(*x))),
PatBox(inner) => PatBox(folder.fold_pat(inner)),
PatUniq(inner) => PatUniq(folder.fold_pat(inner)),
PatRegion(inner) => PatRegion(folder.fold_pat(inner)),
PatRange(e1, e2) => {

View File

@ -44,7 +44,8 @@ pub enum ObsoleteSyntax {
ObsoleteBoxedClosure,
ObsoleteClosureType,
ObsoleteMultipleImport,
ObsoleteExternModAttributesInParens
ObsoleteExternModAttributesInParens,
ObsoleteManagedPattern,
}
impl to_bytes::IterBytes for ObsoleteSyntax {
@ -148,7 +149,12 @@ impl ParserObsoleteMethods for Parser {
"`extern mod` with linkage attribute list",
"use `extern mod foo = \"bar\";` instead of \
`extern mod foo (name = \"bar\")`"
)
),
ObsoleteManagedPattern => (
"managed pointer pattern",
"use a nested `match` expression instead of a managed box \
pattern"
),
};
self.report(sp, kind, kind_str, desc);

View File

@ -40,7 +40,7 @@ use ast::{LitBool, LitFloat, LitFloatUnsuffixed, LitInt, LitChar};
use ast::{LitIntUnsuffixed, LitNil, LitStr, LitUint, Local};
use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatBox, PatEnum};
use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct};
use ast::{PatTup, PatUniq, PatWild, PatWildMulti, Private};
use ast::{BiRem, Required};
@ -60,7 +60,7 @@ use ast::{ViewItem_, ViewItemExternMod, ViewItemUse};
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::Visibility;
use ast;
use ast_util::{as_prec, operator_prec};
use ast_util::{as_prec, lit_is_str, operator_prec};
use ast_util;
use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
use codemap;
@ -2278,10 +2278,10 @@ impl Parser {
hi = e.span.hi;
// HACK: turn &[...] into a &-vec
ex = match e.node {
ExprVec(..) | ExprLit(@codemap::Spanned {
node: LitStr(..), span: _
})
if m == MutImmutable => {
ExprVec(..) if m == MutImmutable => {
ExprVstore(e, ExprVstoreSlice)
}
ExprLit(lit) if lit_is_str(lit) && m == MutImmutable => {
ExprVstore(e, ExprVstoreSlice)
}
ExprVec(..) if m == MutMutable => {
@ -2300,8 +2300,8 @@ impl Parser {
// HACK: turn @[...] into a @-vec
ex = match e.node {
ExprVec(..) |
ExprLit(@codemap::Spanned { node: LitStr(..), span: _}) |
ExprRepeat(..) => ExprVstore(e, ExprVstoreBox),
ExprLit(lit) if lit_is_str(lit) => ExprVstore(e, ExprVstoreBox),
_ => self.mk_unary(UnBox, e)
};
}
@ -2312,9 +2312,10 @@ impl Parser {
hi = e.span.hi;
// HACK: turn ~[...] into a ~-vec
ex = match e.node {
ExprVec(..) |
ExprLit(@codemap::Spanned { node: LitStr(..), span: _}) |
ExprRepeat(..) => ExprVstore(e, ExprVstoreUniq),
ExprVec(..) | ExprRepeat(..) => ExprVstore(e, ExprVstoreUniq),
ExprLit(lit) if lit_is_str(lit) => {
ExprVstore(e, ExprVstoreUniq)
}
_ => self.mk_unary(UnUniq, e)
};
}
@ -2339,12 +2340,12 @@ impl Parser {
hi = subexpression.span.hi;
// HACK: turn `box [...]` into a boxed-vec
ex = match subexpression.node {
ExprVec(..) |
ExprLit(@codemap::Spanned {
node: LitStr(..),
span: _
}) |
ExprRepeat(..) => ExprVstore(subexpression, ExprVstoreUniq),
ExprVec(..) | ExprRepeat(..) => {
ExprVstore(subexpression, ExprVstoreUniq)
}
ExprLit(lit) if lit_is_str(lit) => {
ExprVstore(subexpression, ExprVstoreUniq)
}
_ => self.mk_unary(UnUniq, subexpression)
};
}
@ -2769,8 +2770,8 @@ impl Parser {
})
} else {
let subpat = self.parse_pat();
match subpat {
@ast::Pat { id, node: PatWild, span } => {
match *subpat {
ast::Pat { id, node: PatWild, span } => {
self.obsolete(self.span, ObsoleteVecDotDotWildcard);
slice = Some(@ast::Pat {
id: id,
@ -2778,10 +2779,10 @@ impl Parser {
span: span
})
},
@ast::Pat { node: PatIdent(_, _, _), .. } => {
ast::Pat { node: PatIdent(_, _, _), .. } => {
slice = Some(subpat);
}
@ast::Pat { span, .. } => self.span_fatal(
ast::Pat { span, .. } => self.span_fatal(
span, "expected an identifier or nothing"
)
}
@ -2891,19 +2892,26 @@ impl Parser {
hi = sub.span.hi;
// HACK: parse @"..." as a literal of a vstore @str
pat = match sub.node {
PatLit(e@@Expr {
node: ExprLit(@codemap::Spanned {
node: LitStr(..),
span: _}), ..
}) => {
let vst = @Expr {
id: ast::DUMMY_NODE_ID,
node: ExprVstore(e, ExprVstoreBox),
span: mk_sp(lo, hi),
};
PatLit(vst)
PatLit(e) => {
match e.node {
ExprLit(lit) if lit_is_str(lit) => {
let vst = @Expr {
id: ast::DUMMY_NODE_ID,
node: ExprVstore(e, ExprVstoreBox),
span: mk_sp(lo, hi),
};
PatLit(vst)
}
_ => {
self.obsolete(self.span, ObsoleteManagedPattern);
PatUniq(sub)
}
}
}
_ => {
self.obsolete(self.span, ObsoleteManagedPattern);
PatUniq(sub)
}
_ => PatBox(sub)
};
hi = self.last_span.hi;
return @ast::Pat {
@ -2919,19 +2927,20 @@ impl Parser {
hi = sub.span.hi;
// HACK: parse ~"..." as a literal of a vstore ~str
pat = match sub.node {
PatLit(e@@Expr {
node: ExprLit(@codemap::Spanned {
node: LitStr(..),
span: _}), ..
}) => {
let vst = @Expr {
id: ast::DUMMY_NODE_ID,
node: ExprVstore(e, ExprVstoreUniq),
span: mk_sp(lo, hi),
};
PatLit(vst)
}
_ => PatUniq(sub)
PatLit(e) => {
match e.node {
ExprLit(lit) if lit_is_str(lit) => {
let vst = @Expr {
id: ast::DUMMY_NODE_ID,
node: ExprVstore(e, ExprVstoreUniq),
span: mk_sp(lo, hi),
};
PatLit(vst)
}
_ => PatUniq(sub)
}
}
_ => PatUniq(sub)
};
hi = self.last_span.hi;
return @ast::Pat {
@ -2948,18 +2957,20 @@ impl Parser {
hi = sub.span.hi;
// HACK: parse &"..." as a literal of a borrowed str
pat = match sub.node {
PatLit(e@@Expr {
node: ExprLit(@codemap::Spanned{ node: LitStr(..), .. }),
..
}) => {
let vst = @Expr {
id: ast::DUMMY_NODE_ID,
node: ExprVstore(e, ExprVstoreSlice),
span: mk_sp(lo, hi)
};
PatLit(vst)
PatLit(e) => {
match e.node {
ExprLit(lit) if lit_is_str(lit) => {
let vst = @Expr {
id: ast::DUMMY_NODE_ID,
node: ExprVstore(e, ExprVstoreSlice),
span: mk_sp(lo, hi)
};
PatLit(vst)
}
_ => PatRegion(sub),
}
}
_ => PatRegion(sub)
_ => PatRegion(sub),
};
hi = self.last_span.hi;
return @ast::Pat {

View File

@ -1709,10 +1709,6 @@ pub fn print_pat(s: &mut State, pat: &ast::Pat) {
}
pclose(s);
}
ast::PatBox(inner) => {
word(&mut s.s, "@");
print_pat(s, inner);
}
ast::PatUniq(inner) => {
word(&mut s.s, "~");
print_pat(s, inner);
@ -1733,8 +1729,8 @@ pub fn print_pat(s: &mut State, pat: &ast::Pat) {
commasep(s, Inconsistent, *before, |s, &p| print_pat(s, p));
for &p in slice.iter() {
if !before.is_empty() { word_space(s, ","); }
match p {
@ast::Pat { node: ast::PatWildMulti, .. } => {
match *p {
ast::Pat { node: ast::PatWildMulti, .. } => {
// this case is handled by print_pat
}
_ => word(&mut s.s, ".."),

View File

@ -397,7 +397,6 @@ pub fn walk_pat<E: Clone, V: Visitor<E>>(visitor: &mut V, pattern: &Pat, env: E)
visitor.visit_pat(*tuple_element, env.clone())
}
}
PatBox(subpattern) |
PatUniq(subpattern) |
PatRegion(subpattern) => {
visitor.visit_pat(subpattern, env)

View File

@ -20,10 +20,6 @@ fn main() {
(true, false, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found tuple (expected a tuple with 2 elements but found one with 3 elements)
}
match (true, false) {
@(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found an @-box pattern
}
match (true, false) {
~(true, false) => () //~ ERROR mismatched types: expected `(bool,bool)` but found a ~-box pattern
}

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
enum t { a, b, }
fn main() {
@ -18,8 +16,8 @@ fn main() {
match true { //~ ERROR non-exhaustive patterns
true => {}
}
match @Some(10) { //~ ERROR non-exhaustive patterns
@None => {}
match Some(10) { //~ ERROR non-exhaustive patterns
None => {}
}
match (2, 3, 4) { //~ ERROR non-exhaustive patterns
(_, _, 4) => {}

View File

@ -8,10 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
// error-pattern:unreachable pattern
enum foo { a(@foo, int), b(uint), }
enum foo { a(~foo, int), b(uint), }
fn main() { match b(1u) { b(_) | a(@_, 1) => { } a(_, 1) => { } } }
fn main() { match b(1u) { b(_) | a(~_, 1) => { } a(_, 1) => { } } }

View File

@ -10,8 +10,6 @@
// xfail-android: FIXME(#10381)
#[feature(managed_boxes)];
// compile-flags:-Z extra-debug-info
// debugger:rbreak zzz
// debugger:run
@ -238,7 +236,7 @@ fn complex_nesting(((u, v ), ((w, (x, Struct { a: y, b: z})), Struct { a:
zzz();
}
fn managed_box(@aa: @(int, int)) {
fn managed_box(&aa: &(int, int)) {
zzz();
}
@ -297,7 +295,7 @@ fn main() {
one_struct_destructured_one_not((Struct { a: 19, b: 20 }, Struct { a: 21, b: 22 }));
different_order_of_struct_fields(Struct { a: 23, b: 24 });
complex_nesting(((25, 26), ((27, (28, Struct { a: 29, b: 30})), Struct { a: 31, b: 32 }), 33));
managed_box(@(34, 35));
managed_box(&(34, 35));
borrowed_pointer(&(36, 37));
contained_borrowed_pointer((&38, 39));
unique_pointer(~(40, 41, 42));

View File

@ -125,7 +125,6 @@
// debugger:print *nn
// check:$43 = 56
#[feature(managed_boxes)];
#[allow(unused_variable)];
struct Struct {
@ -172,8 +171,8 @@ fn main() {
let ((u, v), ((w, (x, Struct { a: y, b: z})), Struct { a: ae, b: oe }), ue) =
((25, 26), ((27, (28, Struct { a: 29, b: 30})), Struct { a: 31, b: 32 }), 33);
// managed box
let @aa = @(34, 35);
// reference
let &aa = &(34, 35);
// reference
let &bb = &(36, 37);

View File

@ -1,32 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// exec-env:RUST_POISON_ON_FREE=1
#[feature(managed_boxes)];
use std::cell::RefCell;
pub fn main() {
let x: @RefCell<@Option<~int>> = @RefCell::new(@None);
let mut xb = x.borrow_mut();
match *xb.get() {
@Some(ref _y) => {
// here, the refcount of `*x` is bumped so
// `_y` remains valid even if `*x` is modified.
*xb.get() = @None;
}
@None => {
// here, no bump of the ref count of `*x` is needed, but in
// fact a bump occurs anyway because of how pattern marching
// works.
}
}
}

View File

@ -1,34 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// exec-env:RUST_POISON_ON_FREE=1
#[feature(managed_boxes)];
use std::ptr;
struct F { f: ~int }
pub fn main() {
let mut x = @F {f: ~3};
match x {
@F {f: ref b_x} => {
assert_eq!(**b_x, 3);
assert_eq!(ptr::to_unsafe_ptr(&(*x.f)), ptr::to_unsafe_ptr(&(**b_x)));
x = @F {f: ~4};
info!("ptr::to_unsafe_ptr(*b_x) = {:x}",
ptr::to_unsafe_ptr(&(**b_x)) as uint);
assert_eq!(**b_x, 3);
assert!(ptr::to_unsafe_ptr(&(*x.f)) != ptr::to_unsafe_ptr(&(**b_x)));
}
}
}

View File

@ -1,36 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// exec-env:RUST_POISON_ON_FREE=1
#[feature(managed_boxes)];
use std::cell::RefCell;
use std::ptr;
struct F { f: ~int }
pub fn main() {
let x = @RefCell::new(@F {f: ~3});
let mut xb = x.borrow_mut();
match *xb.get() {
@F{f: ref b_x} => {
assert_eq!(**b_x, 3);
assert_eq!(ptr::to_unsafe_ptr(&(xb.get().f)), ptr::to_unsafe_ptr(b_x));
*xb.get() = @F {f: ~4};
info!("ptr::to_unsafe_ptr(*b_x) = {:x}",
ptr::to_unsafe_ptr(&(**b_x)) as uint);
assert_eq!(**b_x, 3);
assert!(ptr::to_unsafe_ptr(&(*xb.get().f)) != ptr::to_unsafe_ptr(&(**b_x)));
}
}
}

View File

@ -1,27 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// exec-env:RUST_POISON_ON_FREE=1
#[feature(managed_boxes)];
fn switcher(x: Option<@int>) {
let mut x = x;
match x {
Some(@y) => { y.clone(); x = None; }
None => { }
}
assert_eq!(x, None);
}
pub fn main() {
switcher(None);
switcher(Some(@3));
}

View File

@ -1,21 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
struct Foo {a: int, b: uint}
enum bar { u(@Foo), w(int), }
pub fn main() {
assert!(match u(@Foo{a: 10, b: 40u}) {
u(@Foo{a: a, b: b}) => { a + (b as int) }
_ => { 66 }
} == 50);
}

View File

@ -1,28 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
#[allow(dead_assignment)];
struct X { x: int, y: @A }
struct A { a: int }
pub fn main() {
let u = X {x: 10, y: @A {a: 20}};
let X {x: x, y: @A {a: a}} = u;
let mut x = x;
let mut a = a;
x = 100;
a = 100;
assert_eq!(x, 100);
assert_eq!(a, 100);
assert_eq!(u.x, 10);
assert_eq!(u.y.a, 20);
}

View File

@ -1,20 +0,0 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
struct xx(int);
struct X { x: xx, y: int }
pub fn main() {
let @X {x: xx(x), y: y} = @X{x: xx(10), y: 20};
assert_eq!(x + y, 30);
}

View File

@ -8,15 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
struct Foo { foo: bool, bar: Option<int>, baz: int }
pub fn main() {
match @Foo{foo: true, bar: Some(10), baz: 20} {
@Foo{foo: true, bar: Some(_), ..} => {}
@Foo{foo: false, bar: None, ..} => {}
@Foo{foo: true, bar: None, ..} => {}
@Foo{foo: false, bar: Some(_), ..} => {}
match Foo{foo: true, bar: Some(10), baz: 20} {
Foo{foo: true, bar: Some(_), ..} => {}
Foo{foo: false, bar: None, ..} => {}
Foo{foo: true, bar: None, ..} => {}
Foo{foo: false, bar: Some(_), ..} => {}
}
}

View File

@ -8,16 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[feature(managed_boxes)];
struct A { a: int, b: @int }
struct A { a: int, b: int }
struct B { a: int, b: C }
struct D { a: int, d: C }
struct C { c: int }
pub fn main() {
match A {a: 10, b: @20} {
x@A {a, b: @20} => { assert!(x.a == 10); assert!(a == 10); }
match A {a: 10, b: 20} {
x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); }
A {b: _b, ..} => { fail!(); }
}
let mut x@B {b, ..} = B {a: 10, b: C {c: 20}};