mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
auto merge of #11305 : pcwalton/rust/at-patterns, r=pcwalton
r? @nikomatsakis
This commit is contained in:
commit
ab66f76254
14
doc/rust.md
14
doc/rust.md
@ -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, _) => {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)) => {
|
||||
|
@ -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) {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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, ());
|
||||
|
@ -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");
|
||||
}
|
||||
_ => ()
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) => ¶m_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);
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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));
|
||||
|
@ -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(..) |
|
||||
|
@ -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, _) => {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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 */ }
|
||||
}
|
||||
|
@ -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(..) => {
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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::*;
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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")
|
||||
};
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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, ".."),
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) => {}
|
||||
|
@ -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) => { } } }
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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(_), ..} => {}
|
||||
}
|
||||
}
|
||||
|
@ -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}};
|
||||
|
Loading…
Reference in New Issue
Block a user