librustc: Remove the concept of modes from the compiler.

This commit does not remove `ty::arg`, although that should be
possible to do now.
This commit is contained in:
Patrick Walton 2013-04-24 01:29:46 -07:00
parent a12a3db5b4
commit f30f54e9d0
41 changed files with 556 additions and 1082 deletions

View file

@ -128,7 +128,6 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
tag_table_freevars = 0x59,
tag_table_tcache = 0x5a,
tag_table_param_defs = 0x5b,
tag_table_inferred_modes = 0x5c,
tag_table_mutbl = 0x5d,
tag_table_last_use = 0x5e,
tag_table_spill = 0x5f,

View file

@ -244,8 +244,8 @@ fn doc_transformed_self_ty(doc: ebml::Doc,
}
}
pub fn item_type(_item_id: ast::def_id, item: ebml::Doc,
tcx: ty::ctxt, cdata: cmd) -> ty::t {
pub fn item_type(_: ast::def_id, item: ebml::Doc, tcx: ty::ctxt, cdata: cmd)
-> ty::t {
doc_type(item, tcx, cdata)
}

View file

@ -469,16 +469,9 @@ fn parse_onceness(c: char) -> ast::Onceness {
}
fn parse_arg(st: @mut PState, conv: conv_did) -> ty::arg {
ty::arg { mode: parse_mode(st), ty: parse_ty(st, conv) }
}
fn parse_mode(st: @mut PState) -> ast::mode {
let m = ast::expl(match next(st) {
'+' => ast::by_copy,
'=' => ast::by_ref,
_ => fail!(~"bad mode")
});
return m;
ty::arg {
ty: parse_ty(st, conv)
}
}
fn parse_closure_ty(st: @mut PState, conv: conv_did) -> ty::ClosureTy {
@ -511,8 +504,7 @@ fn parse_sig(st: @mut PState, conv: conv_did) -> ty::FnSig {
assert!((next(st) == '['));
let mut inputs: ~[ty::arg] = ~[];
while peek(st) != ']' {
let mode = parse_mode(st);
inputs.push(ty::arg { mode: mode, ty: parse_ty(st, conv) });
inputs.push(ty::arg { ty: parse_ty(st, conv) });
}
st.pos += 1u; // eat the ']'
let ret_ty = parse_ty(st, conv);

View file

@ -344,17 +344,9 @@ fn enc_sigil(w: @io::Writer, sigil: Sigil) {
}
pub fn enc_arg(w: @io::Writer, cx: @ctxt, arg: ty::arg) {
enc_mode(w, cx, arg.mode);
enc_ty(w, cx, arg.ty);
}
pub fn enc_mode(w: @io::Writer, cx: @ctxt, m: mode) {
match ty::resolved_mode(cx.tcx, m) {
by_copy => w.write_char('+'),
by_ref => w.write_char('='),
}
}
fn enc_purity(w: @io::Writer, p: purity) {
match p {
pure_fn => w.write_char('p'),

View file

@ -410,7 +410,7 @@ impl tr for ast::def {
ast::def_mod(did) => { ast::def_mod(did.tr(xcx)) }
ast::def_foreign_mod(did) => { ast::def_foreign_mod(did.tr(xcx)) }
ast::def_const(did) => { ast::def_const(did.tr(xcx)) }
ast::def_arg(nid, m, b) => { ast::def_arg(xcx.tr_id(nid), m, b) }
ast::def_arg(nid, b) => { ast::def_arg(xcx.tr_id(nid), b) }
ast::def_local(nid, b) => { ast::def_local(xcx.tr_id(nid), b) }
ast::def_variant(e_did, v_did) => {
ast::def_variant(e_did.tr(xcx), v_did.tr(xcx))
@ -571,6 +571,9 @@ fn encode_method_map_entry(ecx: @e::EncodeContext,
do ebml_w.emit_field(~"origin", 1u) {
mme.origin.encode(ebml_w);
}
do ebml_w.emit_field(~"self_mode", 3) {
mme.self_mode.encode(ebml_w);
}
}
}
@ -590,6 +593,9 @@ fn encode_method_map_entry(ecx: @e::EncodeContext,
do ebml_w.emit_struct_field("origin", 1u) {
mme.origin.encode(ebml_w);
}
do ebml_w.emit_struct_field("self_mode", 3) {
mme.self_mode.encode(ebml_w);
}
}
}
@ -611,6 +617,10 @@ impl read_method_map_entry_helper for reader::Decoder {
Decodable::decode(self);
method_origin.tr(xcx)
}),
self_mode: self.read_field(~"self_mode", 3, || {
let self_mode: ty::SelfMode = Decodable::decode(self);
self_mode
}),
}
}
}
@ -625,7 +635,7 @@ impl read_method_map_entry_helper for reader::Decoder {
self_arg: self.read_struct_field("self_arg", 0u, || {
self.read_arg(xcx)
}),
explicit_self: self.read_struct_field("explicit_self", 2u, || {
explicit_self: self.read_struct_field("explicit_self", 2, || {
let self_type: ast::self_ty_ = Decodable::decode(self);
self_type
}),
@ -634,6 +644,10 @@ impl read_method_map_entry_helper for reader::Decoder {
Decodable::decode(self);
method_origin.tr(xcx)
}),
self_mode: self.read_struct_field("self_mode", 3, || {
let self_mode: ty::SelfMode = Decodable::decode(self);
self_mode
}),
}
}
}
@ -978,20 +992,6 @@ fn encode_side_tables_for_id(ecx: @e::EncodeContext,
}
}
// I believe it is not necessary to encode this information. The
// ids will appear in the AST but in the *type* information, which
// is what we actually use in trans, all modes will have been
// resolved.
//
//for tcx.inferred_modes.find(&id).each |m| {
// ebml_w.tag(c::tag_table_inferred_modes) {||
// ebml_w.id(id);
// ebml_w.tag(c::tag_table_val) {||
// tyencode::enc_mode(ebml_w.writer, ty_str_ctxt(), m);
// }
// }
//}
if maps.mutbl_map.contains(&id) {
do ebml_w.tag(c::tag_table_mutbl) {
ebml_w.id(id);

View file

@ -147,38 +147,6 @@ fn req_loans_in_expr(ex: @ast::expr,
visit::visit_expr(ex, self, vt);
}
ast::expr_call(f, ref args, _) => {
let arg_tys = ty::ty_fn_args(ty::expr_ty(self.tcx(), f));
let scope_r = ty::re_scope(ex.id);
for vec::each2(*args, arg_tys) |arg, arg_ty| {
match ty::resolved_mode(self.tcx(), arg_ty.mode) {
ast::by_ref => {
let arg_cmt = self.bccx.cat_expr(*arg);
self.guarantee_valid(arg_cmt, m_imm, scope_r);
}
ast::by_copy => {}
}
}
visit::visit_expr(ex, self, vt);
}
ast::expr_method_call(_, _, _, ref args, _) => {
let arg_tys = ty::ty_fn_args(ty::node_id_to_type(self.tcx(),
ex.callee_id));
let scope_r = ty::re_scope(ex.id);
for vec::each2(*args, arg_tys) |arg, arg_ty| {
match ty::resolved_mode(self.tcx(), arg_ty.mode) {
ast::by_ref => {
let arg_cmt = self.bccx.cat_expr(*arg);
self.guarantee_valid(arg_cmt, m_imm, scope_r);
}
ast::by_copy => {}
}
}
visit::visit_expr(ex, self, vt);
}
ast::expr_match(ex_v, ref arms) => {
let cmt = self.bccx.cat_expr(ex_v);
for (*arms).each |arm| {

View file

@ -19,7 +19,6 @@ use std::smallintmap::SmallIntMap;
use syntax::attr;
use syntax::codemap::span;
use syntax::codemap;
use syntax::print::pprust::mode_to_str;
use syntax::{ast, visit};
/**
@ -53,7 +52,6 @@ pub enum lint {
unrecognized_lint,
non_implicitly_copyable_typarams,
vecs_implicitly_copyable,
deprecated_mode,
deprecated_pattern,
non_camel_case_types,
type_limits,
@ -61,14 +59,11 @@ pub enum lint {
deprecated_mutable_fields,
deprecated_drop,
unused_unsafe,
foreign_mode,
managed_heap_memory,
owned_heap_memory,
heap_memory,
legacy_modes,
unused_variable,
dead_assignment,
unused_mut,
@ -159,20 +154,6 @@ pub fn get_lint_dict() -> LintDict {
default: warn
}),
(~"deprecated_mode",
LintSpec {
lint: deprecated_mode,
desc: "warn about deprecated uses of modes",
default: warn
}),
(~"foreign_mode",
LintSpec {
lint: foreign_mode,
desc: "warn about deprecated uses of modes in foreign fns",
default: warn
}),
(~"deprecated_pattern",
LintSpec {
lint: deprecated_pattern,
@ -208,13 +189,6 @@ pub fn get_lint_dict() -> LintDict {
default: allow
}),
(~"legacy modes",
LintSpec {
lint: legacy_modes,
desc: "allow legacy modes",
default: forbid
}),
(~"type_limits",
LintSpec {
lint: type_limits,
@ -486,7 +460,6 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
check_item_path_statement(cx, i);
check_item_non_camel_case_types(cx, i);
check_item_heap(cx, i);
check_item_deprecated_modes(cx, i);
check_item_type_limits(cx, i);
check_item_default_methods(cx, i);
check_item_deprecated_mutable_fields(cx, i);
@ -719,20 +692,6 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
decl: &ast::fn_decl) {
// warn about `&&` mode on foreign functions, both because it is
// deprecated and because its semantics have changed recently:
for decl.inputs.eachi |i, arg| {
match ty::resolved_mode(cx, arg.mode) {
ast::by_copy => {}
ast::by_ref => {
cx.sess.span_lint(
foreign_mode, fn_id, fn_id, arg.ty.span,
fmt!("foreign function uses `&&` mode \
on argument %u", i));
}
}
}
let tys = vec::map(decl.inputs, |a| a.ty );
for vec::each(vec::append_one(tys, decl.output)) |ty| {
match ty.node {
@ -995,119 +954,13 @@ fn check_item_unused_mut(tcx: ty::ctxt, it: @ast::item) {
visit::visit_item(it, (), visit);
}
fn check_fn(tcx: ty::ctxt, fk: &visit::fn_kind, decl: &ast::fn_decl,
_body: &ast::blk, span: span, id: ast::node_id) {
fn check_fn(_: ty::ctxt,
fk: &visit::fn_kind,
_: &ast::fn_decl,
_: &ast::blk,
_: span,
id: ast::node_id) {
debug!("lint check_fn fk=%? id=%?", fk, id);
// Check for deprecated modes
match *fk {
// don't complain about blocks, since they tend to get their modes
// specified from the outside
visit::fk_fn_block(*) => {}
_ => {
let fn_ty = ty::node_id_to_type(tcx, id);
check_fn_deprecated_modes(tcx, fn_ty, decl, span, id);
}
}
}
fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: &ast::fn_decl,
span: span, id: ast::node_id) {
match ty::get(fn_ty).sty {
ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) |
ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) => {
let mut counter = 0;
for vec::each2(sig.inputs, decl.inputs) |arg_ty, arg_ast| {
counter += 1;
debug!("arg %d, ty=%s, mode=%s",
counter,
ty_to_str(tcx, arg_ty.ty),
mode_to_str(arg_ast.mode));
match arg_ast.mode {
ast::expl(ast::by_copy) => {
if !tcx.legacy_modes {
tcx.sess.span_lint(
deprecated_mode, id, id, span,
fmt!("argument %d uses by-copy mode",
counter));
}
}
ast::expl(_) => {
tcx.sess.span_lint(
deprecated_mode, id, id,
span,
fmt!("argument %d uses an explicit mode", counter));
}
ast::infer(_) => {
if tcx.legacy_modes {
let kind = ty::type_contents(tcx, arg_ty.ty);
if !kind.is_safe_for_default_mode(tcx) {
tcx.sess.span_lint(
deprecated_mode, id, id,
span,
fmt!("argument %d uses the default mode \
but shouldn't",
counter));
}
}
}
}
match ty::get(arg_ty.ty).sty {
ty::ty_closure(*) | ty::ty_bare_fn(*) => {
let span = arg_ast.ty.span;
// Recurse to check fn-type argument
match arg_ast.ty.node {
ast::ty_closure(@ast::TyClosure{decl: ref d, _}) |
ast::ty_bare_fn(@ast::TyBareFn{decl: ref d, _})=>{
check_fn_deprecated_modes(tcx, arg_ty.ty,
d, span, id);
}
ast::ty_path(*) => {
// This is probably a typedef, so we can't
// see the actual fn decl
// e.g. fn foo(f: InitOp<T>)
}
_ => {
tcx.sess.span_warn(span, ~"what");
error!("arg %d, ty=%s, mode=%s",
counter,
ty_to_str(tcx, arg_ty.ty),
mode_to_str(arg_ast.mode));
error!("%?",arg_ast.ty.node);
fail!()
}
};
}
_ => ()
}
}
}
_ => tcx.sess.impossible_case(span, ~"check_fn: function has \
non-fn type")
}
}
fn check_item_deprecated_modes(tcx: ty::ctxt, it: @ast::item) {
match it.node {
ast::item_ty(ty, _) => {
match ty.node {
ast::ty_closure(@ast::TyClosure {decl: ref decl, _}) |
ast::ty_bare_fn(@ast::TyBareFn {decl: ref decl, _}) => {
let fn_ty = ty::node_id_to_type(tcx, it.id);
check_fn_deprecated_modes(
tcx, fn_ty, decl, ty.span, it.id)
}
_ => ()
}
}
_ => ()
}
}
pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) {

View file

@ -236,19 +236,19 @@ struct LocalInfo {
}
enum VarKind {
Arg(node_id, ident, rmode),
Arg(node_id, ident),
Local(LocalInfo),
ImplicitRet
}
fn relevant_def(def: def) -> Option<node_id> {
match def {
def_binding(nid, _) |
def_arg(nid, _, _) |
def_local(nid, _) |
def_self(nid, _) => Some(nid),
def_binding(nid, _) |
def_arg(nid, _) |
def_local(nid, _) |
def_self(nid, _) => Some(nid),
_ => None
_ => None
}
}
@ -321,10 +321,9 @@ pub impl IrMaps {
self.num_vars += 1;
match vk {
Local(LocalInfo {id:node_id, _}) |
Arg(node_id, _, _) => {
Local(LocalInfo { id: node_id, _ }) | Arg(node_id, _) => {
self.variable_map.insert(node_id, v);
}
},
ImplicitRet => {}
}
@ -345,8 +344,9 @@ pub impl IrMaps {
fn variable_name(&mut self, var: Variable) -> @~str {
match self.var_kinds[*var] {
Local(LocalInfo {ident: nm, _}) |
Arg(_, nm, _) => self.tcx.sess.str_of(nm),
Local(LocalInfo { ident: nm, _ }) | Arg(_, nm) => {
self.tcx.sess.str_of(nm)
},
ImplicitRet => @~"<implicit-ret>"
}
}
@ -372,25 +372,22 @@ pub impl IrMaps {
let vk = self.var_kinds[*var];
debug!("Node %d is a last use of variable %?", expr_id, vk);
match vk {
Arg(id, _, by_copy) |
Local(LocalInfo {id: id, kind: FromLetNoInitializer, _}) |
Local(LocalInfo {id: id, kind: FromLetWithInitializer, _}) |
Local(LocalInfo {id: id, kind: FromMatch(_), _}) => {
let v = match self.last_use_map.find(&expr_id) {
Some(&v) => v,
None => {
let v = @mut ~[];
self.last_use_map.insert(expr_id, v);
v
}
};
Arg(id, _) |
Local(LocalInfo { id: id, kind: FromLetNoInitializer, _ }) |
Local(LocalInfo { id: id, kind: FromLetWithInitializer, _ }) |
Local(LocalInfo { id: id, kind: FromMatch(_), _ }) => {
let v = match self.last_use_map.find(&expr_id) {
Some(&v) => v,
None => {
let v = @mut ~[];
self.last_use_map.insert(expr_id, v);
v
}
};
v.push(id);
}
Arg(_, _, by_ref) |
ImplicitRet => {
debug!("--but it is not owned");
}
v.push(id);
}
ImplicitRet => debug!("--but it is not owned"),
}
}
}
@ -424,12 +421,11 @@ fn visit_fn(fk: &visit::fn_kind,
}
for decl.inputs.each |arg| {
let mode = ty::resolved_mode(self.tcx, arg.mode);
do pat_util::pat_bindings(self.tcx.def_map, arg.pat)
|_bm, arg_id, _x, path| {
debug!("adding argument %d", arg_id);
let ident = ast_util::path_to_ident(path);
fn_maps.add_variable(Arg(arg_id, ident, mode));
fn_maps.add_variable(Arg(arg_id, ident));
}
};
@ -439,16 +435,13 @@ fn visit_fn(fk: &visit::fn_kind,
match method.self_ty.node {
sty_value | sty_region(*) | sty_box(_) | sty_uniq(_) => {
fn_maps.add_variable(Arg(method.self_id,
special_idents::self_,
by_copy));
special_idents::self_));
}
sty_static => {}
}
}
fk_dtor(_, _, self_id, _) => {
fn_maps.add_variable(Arg(self_id,
special_idents::self_,
by_copy));
fn_maps.add_variable(Arg(self_id, special_idents::self_));
}
fk_item_fn(*) | fk_anon(*) | fk_fn_block(*) => {}
}
@ -973,30 +966,8 @@ pub impl Liveness {
entry_ln
}
fn propagate_through_fn_block(&self, decl: &fn_decl, blk: &blk)
-> LiveNode {
// inputs passed by & mode should be considered live on exit:
for decl.inputs.each |arg| {
match ty::resolved_mode(self.tcx, arg.mode) {
by_ref => {
// By val and by ref do not own, so register a
// read at the end. This will prevent us from
// moving out of such variables but also prevent
// us from registering last uses and so forth.
do pat_util::pat_bindings(self.tcx.def_map, arg.pat)
|_bm, arg_id, _sp, _path|
{
let var = self.variable(arg_id, blk.span);
self.acc(self.s.exit_ln, var, ACC_READ);
}
}
by_copy => {
// By copy is an owned mode. If we don't use the
// variable, nobody will.
}
}
}
fn propagate_through_fn_block(&self, _: &fn_decl, blk: &blk)
-> LiveNode {
// the fallthrough exit is only for those cases where we do not
// explicitly return:
self.init_from_succ(self.s.fallthrough_ln, self.s.exit_ln);
@ -1771,7 +1742,7 @@ pub impl Liveness {
// borrow checker
let vk = self.ir.var_kinds[*var];
match vk {
Arg(_, name, _) => {
Arg(_, name) => {
self.tcx.sess.span_err(
move_expr.span,
fmt!("illegal move from argument `%s`, which is not \

View file

@ -482,17 +482,14 @@ pub impl mem_categorization_ctxt {
}
}
ast::def_arg(vid, mode, mutbl) => {
ast::def_arg(vid, mutbl) => {
// Idea: make this could be rewritten to model by-ref
// stuff as `&const` and `&mut`?
// m: mutability of the argument
// lp: loan path, must be none for aliasable things
let m = if mutbl {McDeclared} else {McImmutable};
let lp = match ty::resolved_mode(self.tcx, mode) {
ast::by_copy => Some(@lp_arg(vid)),
ast::by_ref => None,
};
let lp = Some(@lp_arg(vid));
@cmt_ {
id:id,
span:span,

View file

@ -718,41 +718,22 @@ pub impl VisitContext {
receiver_expr: @expr,
visitor: vt<VisitContext>)
{
self.use_fn_arg(by_copy, receiver_expr, visitor);
self.use_fn_arg(receiver_expr, visitor);
}
fn use_fn_args(&self,
callee_id: node_id,
_: node_id,
arg_exprs: &[@expr],
visitor: vt<VisitContext>)
{
/*!
*
* Uses the argument expressions according to the function modes.
*/
let arg_tys =
ty::ty_fn_args(ty::node_id_to_type(self.tcx, callee_id));
for vec::each2(arg_exprs, arg_tys) |arg_expr, arg_ty| {
let arg_mode = ty::resolved_mode(self.tcx, arg_ty.mode);
self.use_fn_arg(arg_mode, *arg_expr, visitor);
visitor: vt<VisitContext>) {
//! Uses the argument expressions.
for arg_exprs.each |arg_expr| {
self.use_fn_arg(*arg_expr, visitor);
}
}
fn use_fn_arg(&self,
arg_mode: rmode,
arg_expr: @expr,
visitor: vt<VisitContext>)
{
/*!
*
* Uses the argument according to the given argument mode.
*/
match arg_mode {
by_ref => self.use_expr(arg_expr, Read, visitor),
by_copy => self.consume_expr(arg_expr, visitor)
}
fn use_fn_arg(&self, arg_expr: @expr, visitor: vt<VisitContext>) {
//! Uses the argument.
self.consume_expr(arg_expr, visitor)
}
fn arms_have_by_move_bindings(&self,

View file

@ -42,7 +42,7 @@ use syntax::ast::Generics;
use syntax::ast::{gt, ident, inherited, item, item_struct};
use syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
use syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
use syntax::ast::{local, local_crate, lt, method, mode, mul};
use syntax::ast::{local, local_crate, lt, method, mul};
use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident};
use syntax::ast::{Path, pat_lit, pat_range, pat_struct};
use syntax::ast::{prim_ty, private, provided};
@ -123,7 +123,7 @@ pub struct Export2 {
pub enum PatternBindingMode {
RefutableMode,
LocalIrrefutableMode,
ArgumentIrrefutableMode(mode)
ArgumentIrrefutableMode,
}
#[deriving(Eq)]
@ -3708,8 +3708,7 @@ pub impl Resolver {
}
Some(declaration) => {
for declaration.inputs.each |argument| {
let binding_mode =
ArgumentIrrefutableMode(argument.mode);
let binding_mode = ArgumentIrrefutableMode;
let mutability =
if argument.is_mutbl {Mutable} else {Immutable};
self.resolve_pattern(argument.pat,
@ -4184,10 +4183,9 @@ pub impl Resolver {
// But for locals, we use `def_local`.
def_local(pattern.id, is_mutable)
}
ArgumentIrrefutableMode(argument_mode) => {
ArgumentIrrefutableMode => {
// And for function arguments, `def_arg`.
def_arg(pattern.id, argument_mode,
is_mutable)
def_arg(pattern.id, is_mutable)
}
};

View file

@ -33,11 +33,16 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
constraints.push(copy *c);
let aoutty = ty::arg {
mode: ast::expl(ast::by_copy),
ty: expr_ty(bcx, out)
};
aoutputs.push(unpack_result!(bcx, {
callee::trans_arg_expr(bcx, aoutty, out, &mut cleanups, None, callee::DontAutorefArg)
callee::trans_arg_expr(bcx,
aoutty,
ty::ByCopy,
out,
&mut cleanups,
None,
callee::DontAutorefArg)
}));
let e = match out.node {
@ -46,12 +51,17 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
};
let outty = ty::arg {
mode: ast::expl(ast::by_copy),
ty: expr_ty(bcx, e)
};
unpack_result!(bcx, {
callee::trans_arg_expr(bcx, outty, e, &mut cleanups, None, callee::DontAutorefArg)
callee::trans_arg_expr(bcx,
outty,
ty::ByCopy,
e,
&mut cleanups,
None,
callee::DontAutorefArg)
})
};
@ -66,12 +76,17 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {
constraints.push(copy *c);
let inty = ty::arg {
mode: ast::expl(ast::by_copy),
ty: expr_ty(bcx, in)
};
unpack_result!(bcx, {
callee::trans_arg_expr(bcx, inty, in, &mut cleanups, None, callee::DontAutorefArg)
callee::trans_arg_expr(bcx,
inty,
ty::ByCopy,
in,
&mut cleanups,
None,
callee::DontAutorefArg)
})
};

View file

@ -1728,7 +1728,6 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
raw_llargs: &[ValueRef],
arg_tys: &[ty::arg]) -> block {
let _icx = fcx.insn_ctxt("copy_args_to_allocas");
let tcx = bcx.tcx();
let mut bcx = bcx;
match fcx.llself {
@ -1757,24 +1756,16 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
// the argument would be passed by value, we store it into an alloca.
// This alloca should be optimized away by LLVM's mem-to-reg pass in
// the event it's not truly needed.
let llarg;
match ty::resolved_mode(tcx, arg_ty.mode) {
ast::by_ref => {
llarg = raw_llarg;
}
ast::by_copy => {
// only by value if immediate:
if datum::appropriate_mode(arg_ty.ty).is_by_value() {
let alloc = alloc_ty(bcx, arg_ty.ty);
Store(bcx, raw_llarg, alloc);
llarg = alloc;
} else {
llarg = raw_llarg;
}
// only by value if immediate:
let llarg = if datum::appropriate_mode(arg_ty.ty).is_by_value() {
let alloc = alloc_ty(bcx, arg_ty.ty);
Store(bcx, raw_llarg, alloc);
alloc
} else {
raw_llarg
};
add_clean(bcx, llarg, arg_ty.ty);
}
}
add_clean(bcx, llarg, arg_ty.ty);
bcx = _match::bind_irrefutable_pat(bcx,
args[arg_n].pat,
@ -1966,7 +1957,6 @@ pub fn trans_enum_variant(ccx: @CrateContext,
// Translate variant arguments to function arguments.
let fn_args = do args.map |varg| {
ast::arg {
mode: ast::expl(ast::by_copy),
is_mutbl: false,
ty: varg.ty,
pat: ast_util::ident_to_pat(
@ -2041,7 +2031,6 @@ pub fn trans_tuple_struct(ccx: @CrateContext,
// Translate struct fields to function arguments.
let fn_args = do fields.map |field| {
ast::arg {
mode: ast::expl(ast::by_copy),
is_mutbl: false,
ty: field.node.ty,
pat: ast_util::ident_to_pat(ccx.tcx.sess.next_node_id(),
@ -2408,8 +2397,8 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
} else {
let start_fn_type = csearch::get_type(ccx.tcx,
start_def_id).ty;
trans_external_path(ccx, start_def_id, start_fn_type)
};
trans_external_path(ccx, start_def_id, start_fn_type);
}
let retptr = llvm::LLVMBuildAlloca(bld, T_i8(), noname());

View file

@ -57,7 +57,7 @@ pub struct MethodData {
llfn: ValueRef,
llself: ValueRef,
self_ty: ty::t,
self_mode: ast::rmode
self_mode: ty::SelfMode,
}
pub enum CalleeData {
@ -378,10 +378,20 @@ pub fn trans_lang_call(bcx: block,
csearch::get_type(bcx.ccx().tcx, did).ty
};
let rty = ty::ty_fn_ret(fty);
return callee::trans_call_inner(
bcx, None, fty, rty,
|bcx| trans_fn_ref_with_vtables_to_callee(bcx, did, 0, ~[], None),
ArgVals(args), dest, DontAutorefArg);
callee::trans_call_inner(bcx,
None,
fty,
rty,
|bcx| {
trans_fn_ref_with_vtables_to_callee(bcx,
did,
0,
~[],
None)
},
ArgVals(args),
dest,
DontAutorefArg)
}
pub fn trans_lang_call_with_type_params(bcx: block,
@ -483,7 +493,8 @@ pub fn trans_call_inner(in_cx: block,
}
Method(d) => {
// Weird but true: we pass self in the *environment* slot!
let llself = PointerCast(bcx, d.llself,
let llself = PointerCast(bcx,
d.llself,
T_opaque_box_ptr(ccx));
(d.llfn, llself)
}
@ -520,7 +531,7 @@ pub fn trans_call_inner(in_cx: block,
// Now that the arguments have finished evaluating, we need to revoke
// the cleanup for the self argument, if it exists
match callee.data {
Method(d) if d.self_mode == ast::by_copy => {
Method(d) if d.self_mode == ty::ByCopy => {
revoke_clean(bcx, d.llself);
}
_ => {}
@ -629,7 +640,11 @@ pub fn trans_args(cx: block,
let last = arg_exprs.len() - 1u;
for vec::eachi(arg_exprs) |i, arg_expr| {
let arg_val = unpack_result!(bcx, {
trans_arg_expr(bcx, arg_tys[i], *arg_expr, &mut temp_cleanups,
trans_arg_expr(bcx,
arg_tys[i],
ty::ByCopy,
*arg_expr,
&mut temp_cleanups,
if i == last { ret_flag } else { None },
autoref_arg)
});
@ -660,6 +675,7 @@ pub enum AutorefArg {
// call takes place:
pub fn trans_arg_expr(bcx: block,
formal_ty: ty::arg,
self_mode: ty::SelfMode,
arg_expr: @ast::expr,
temp_cleanups: &mut ~[ValueRef],
ret_flag: Option<ValueRef>,
@ -667,10 +683,10 @@ pub fn trans_arg_expr(bcx: block,
let _icx = bcx.insn_ctxt("trans_arg_expr");
let ccx = bcx.ccx();
debug!("trans_arg_expr(formal_ty=(%?,%s), arg_expr=%s, \
debug!("trans_arg_expr(formal_ty=(%s), self_mode=%?, arg_expr=%s, \
ret_flag=%?)",
formal_ty.mode,
formal_ty.ty.repr(bcx.tcx()),
self_mode,
arg_expr.repr(bcx.tcx()),
ret_flag.map(|v| bcx.val_str(*v)));
let _indenter = indenter();
@ -686,8 +702,7 @@ pub fn trans_arg_expr(bcx: block,
blk @ @ast::expr {
node: ast::expr_fn_block(ref decl, ref body),
_
}) =>
{
}) => {
let scratch_ty = expr_ty(bcx, arg_expr);
let scratch = alloc_ty(bcx, scratch_ty);
let arg_ty = expr_ty(bcx, arg_expr);
@ -714,8 +729,6 @@ pub fn trans_arg_expr(bcx: block,
debug!(" arg datum: %s", arg_datum.to_str(bcx.ccx()));
// finally, deal with the various modes
let arg_mode = ty::resolved_mode(ccx.tcx, formal_ty.mode);
let mut val;
if ty::type_is_bot(arg_datum.ty) {
// For values of type _|_, we generate an
@ -735,24 +748,27 @@ pub fn trans_arg_expr(bcx: block,
val = arg_datum.to_ref_llval(bcx);
}
DontAutorefArg => {
match arg_mode {
ast::by_ref => {
match self_mode {
ty::ByRef => {
// This assertion should really be valid, but because
// the explicit self code currently passes by-ref, it
// does not hold.
//
//assert !bcx.ccx().maps.moves_map.contains_key(
// &arg_expr.id);
debug!("by ref arg with type %s",
bcx.ty_to_str(arg_datum.ty));
val = arg_datum.to_ref_llval(bcx);
}
ast::by_copy => {
ty::ByCopy => {
debug!("by copy arg with type %s, storing to scratch",
bcx.ty_to_str(arg_datum.ty));
let scratch = scratch_datum(bcx, arg_datum.ty, false);
arg_datum.store_to_datum(bcx, arg_expr.id,
INIT, scratch);
arg_datum.store_to_datum(bcx,
arg_expr.id,
INIT,
scratch);
// Technically, ownership of val passes to the callee.
// However, we must cleanup should we fail before the
@ -761,12 +777,8 @@ pub fn trans_arg_expr(bcx: block,
temp_cleanups.push(scratch.val);
match arg_datum.appropriate_mode() {
ByValue => {
val = Load(bcx, scratch.val);
}
ByRef => {
val = scratch.val;
}
ByValue => val = Load(bcx, scratch.val),
ByRef => val = scratch.val,
}
}
}
@ -776,6 +788,10 @@ pub fn trans_arg_expr(bcx: block,
if formal_ty.ty != arg_datum.ty {
// this could happen due to e.g. subtyping
let llformal_ty = type_of::type_of_explicit_arg(ccx, &formal_ty);
let llformal_ty = match self_mode {
ty::ByRef => T_ptr(llformal_ty),
ty::ByCopy => llformal_ty,
};
debug!("casting actual type (%s) to match formal (%s)",
bcx.val_str(val), bcx.llty_str(llformal_ty));
val = PointerCast(bcx, val, llformal_ty);

View file

@ -1072,7 +1072,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
}
}
}
ast::def_arg(nid, _, _) => {
ast::def_arg(nid, _) => {
take_local(bcx, bcx.fcx.llargs, nid)
}
ast::def_local(nid, _) | ast::def_binding(nid, _) => {

View file

@ -791,10 +791,11 @@ pub fn trans_intrinsic(ccx: @CrateContext,
sigil: ast::BorrowedSigil,
onceness: ast::Many,
region: ty::re_bound(ty::br_anon(0)),
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: ~[arg {mode: ast::expl(ast::by_copy),
ty: star_u8}],
output: ty::mk_nil()}
sig: FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: ~[ arg { ty: star_u8 } ],
output: ty::mk_nil()
}
});
let datum = Datum {val: get_param(decl, first_real_arg),
mode: ByRef, ty: fty, source: ZeroMem};

View file

@ -145,14 +145,18 @@ pub fn trans_self_arg(bcx: block,
let _icx = bcx.insn_ctxt("impl::trans_self_arg");
let mut temp_cleanups = ~[];
// Compute the mode and type of self.
// Compute the type of self.
let self_arg = arg {
mode: mentry.self_arg.mode,
ty: monomorphize_type(bcx, mentry.self_arg.ty)
};
let result = trans_arg_expr(bcx, self_arg, base,
&mut temp_cleanups, None, DontAutorefArg);
let result = trans_arg_expr(bcx,
self_arg,
mentry.self_mode,
base,
&mut temp_cleanups,
None,
DontAutorefArg);
// FIXME(#3446)---this is wrong, actually. The temp_cleanups
// should be revoked only after all arguments have been passed.
@ -224,14 +228,13 @@ pub fn trans_method_callee(bcx: block,
typeck::method_static(did) => {
let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
let Result {bcx, val} = trans_self_arg(bcx, self, mentry);
let tcx = bcx.tcx();
Callee {
bcx: bcx,
data: Method(MethodData {
llfn: callee_fn.llfn,
llself: val,
self_ty: node_id_type(bcx, self.id),
self_mode: ty::resolved_mode(tcx, mentry.self_arg.mode)
self_mode: mentry.self_mode,
})
}
}
@ -442,7 +445,7 @@ pub fn trans_monomorphized_callee(bcx: block,
trait_id: ast::def_id,
n_method: uint,
vtbl: typeck::vtable_origin)
-> Callee {
-> Callee {
let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee");
return match vtbl {
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
@ -463,8 +466,11 @@ pub fn trans_monomorphized_callee(bcx: block,
bcx, mth_id, impl_did, callee_id, rcvr_origins);
// translate the function
let callee = trans_fn_ref_with_vtables(
bcx, mth_id, callee_id, callee_substs, Some(callee_origins));
let callee = trans_fn_ref_with_vtables(bcx,
mth_id,
callee_id,
callee_substs,
Some(callee_origins));
// create a llvalue that represents the fn ptr
let fn_ty = node_id_type(bcx, callee_id);
@ -472,14 +478,13 @@ pub fn trans_monomorphized_callee(bcx: block,
let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty);
// combine the self environment with the rest
let tcx = bcx.tcx();
Callee {
bcx: bcx,
data: Method(MethodData {
llfn: llfn_val,
llself: llself_val,
self_ty: node_id_type(bcx, base.id),
self_mode: ty::resolved_mode(tcx, mentry.self_arg.mode)
self_mode: mentry.self_mode,
})
}
}
@ -496,7 +501,7 @@ pub fn combine_impl_and_methods_tps(bcx: block,
impl_did: ast::def_id,
callee_id: ast::node_id,
rcvr_substs: &[ty::t])
-> ~[ty::t] {
-> ~[ty::t] {
/*!
*
* Creates a concatenated set of substitutions which includes
@ -668,7 +673,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
Store(bcx, llself, llscratch);
llself = llscratch;
self_mode = ast::by_ref;
self_mode = ty::ByRef;
}
ast::sty_box(_) => {
// Bump the reference count on the box.
@ -686,7 +691,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
Store(bcx, llself, llscratch);
llself = llscratch;
self_mode = ast::by_ref;
self_mode = ty::ByRef;
}
ast::sty_uniq(_) => {
// Pass the unique pointer.
@ -699,7 +704,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
Store(bcx, llself, llscratch);
llself = llscratch;
self_mode = ast::by_ref;
self_mode = ty::ByRef;
}
}

View file

@ -280,9 +280,15 @@ pub impl Reflector {
let make_get_disr = || {
let sub_path = bcx.fcx.path + ~[path_name(special_idents::anon)];
let sym = mangle_internal_name_by_path_and_seq(ccx, sub_path, ~"get_disr");
let args = [ty::arg { mode: ast::expl(ast::by_copy),
ty: opaqueptrty }];
let sym = mangle_internal_name_by_path_and_seq(ccx,
sub_path,
~"get_disr");
let args = [
ty::arg {
ty: opaqueptrty
}
];
let llfty = type_of_fn(ccx, args, ty::mk_int());
let llfdecl = decl_internal_cdecl_fn(ccx.llmod, sym, llfty);
let arg = unsafe {
@ -347,13 +353,7 @@ pub impl Reflector {
fn visit_sig(&mut self, retval: uint, sig: &ty::FnSig) {
for sig.inputs.eachi |i, arg| {
let modeval = match arg.mode {
ast::infer(_) => 0u,
ast::expl(e) => match e {
ast::by_ref => 1u,
ast::by_copy => 5u
}
};
let modeval = 5u; // "by copy"
let extra = ~[self.c_uint(i),
self.c_uint(modeval),
self.c_tydesc(arg.ty)];

View file

@ -19,11 +19,8 @@ use util::ppaux;
use syntax::ast;
pub fn arg_is_indirect(ccx: @CrateContext, arg: &ty::arg) -> bool {
match ty::resolved_mode(ccx.tcx, arg.mode) {
ast::by_copy => !ty::type_is_immediate(arg.ty),
ast::by_ref => true
}
pub fn arg_is_indirect(_: @CrateContext, arg: &ty::arg) -> bool {
!ty::type_is_immediate(arg.ty)
}
pub fn type_of_explicit_arg(ccx: @CrateContext, arg: &ty::arg) -> TypeRef {

View file

@ -78,12 +78,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) |
ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => {
for vec::each(sig.inputs) |arg| {
match ty::resolved_mode(ccx.tcx, arg.mode) {
by_copy => {
type_needs(cx, use_repr, arg.ty);
}
by_ref => {}
}
type_needs(cx, use_repr, arg.ty);
}
}
_ => ()
@ -332,15 +327,9 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
node_type_needs(cx, use_tydesc, val.id);
}
expr_call(f, _, _) => {
for vec::each(
ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx, f.id))
) |a| {
match a.mode {
expl(by_copy) => {
type_needs(cx, use_repr, a.ty);
}
_ => ()
}
for vec::each(ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx,
f.id))) |a| {
type_needs(cx, use_repr, a.ty);
}
}
expr_method_call(rcvr, _, _, _, _) => {
@ -349,12 +338,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
for ty::ty_fn_args(ty::node_id_to_type(cx.ccx.tcx,
e.callee_id)).each |a| {
match a.mode {
expl(by_copy) => {
type_needs(cx, use_repr, a.ty);
}
_ => ()
}
type_needs(cx, use_repr, a.ty);
}
mark_for_method_call(cx, e.id, e.callee_id);
}

View file

@ -38,7 +38,6 @@ use syntax::ast_util;
use syntax::attr;
use syntax::codemap::span;
use syntax::codemap;
use syntax::print::pprust;
use syntax::parse::token::special_idents;
use syntax::{ast, ast_map};
use syntax::opt_vec::OptVec;
@ -48,11 +47,8 @@ use syntax;
// Data types
// Note: after typeck, you should use resolved_mode() to convert this mode
// into an rmode, which will take into account the results of mode inference.
#[deriving(Eq)]
#[deriving(Eq, IterBytes)]
pub struct arg {
mode: ast::mode,
ty: t
}
@ -99,6 +95,16 @@ pub enum TraitStore {
RegionTraitStore(Region), // &Trait
}
// XXX: This should probably go away at some point. Maybe after destructors
// do?
#[auto_encode]
#[auto_decode]
#[deriving(Eq)]
pub enum SelfMode {
ByCopy,
ByRef,
}
pub struct field_ty {
ident: ident,
id: def_id,
@ -270,7 +276,6 @@ struct ctxt_ {
ast_ty_to_ty_cache: @mut HashMap<node_id, ast_ty_to_ty_cache_entry>,
enum_var_cache: @mut HashMap<def_id, @~[VariantInfo]>,
ty_param_defs: @mut HashMap<ast::node_id, TypeParameterDef>,
inferred_modes: @mut HashMap<ast::node_id, ast::mode>,
adjustments: @mut HashMap<ast::node_id, @AutoAdjustment>,
normalized_cache: @mut HashMap<t, t>,
lang_items: middle::lang_items::LanguageItems,
@ -630,7 +635,6 @@ pub enum type_err {
terr_record_mutability,
terr_record_fields(expected_found<ident>),
terr_arg_count,
terr_mode_mismatch(expected_found<mode>),
terr_regions_does_not_outlive(Region, Region),
terr_regions_not_same(Region, Region),
terr_regions_no_overlap(Region, Region),
@ -919,7 +923,6 @@ pub fn mk_ctxt(s: session::Session,
trait_method_def_ids: @mut HashMap::new(),
trait_methods_cache: @mut HashMap::new(),
ty_param_defs: @mut HashMap::new(),
inferred_modes: @mut HashMap::new(),
adjustments: @mut HashMap::new(),
normalized_cache: new_ty_hash(),
lang_items: lang_items,
@ -1199,15 +1202,17 @@ pub fn mk_bare_fn(cx: ctxt, fty: BareFnTy) -> t {
}
pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
let input_args = input_tys.map(|t| arg {mode: ast::expl(ast::by_copy),
ty: *t});
let input_args = input_tys.map(|t| arg { ty: *t });
mk_bare_fn(cx,
BareFnTy {
purity: ast::pure_fn,
abis: AbiSet::Rust(),
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: input_args,
output: output}})
sig: FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: input_args,
output: output
}
})
}
@ -1258,40 +1263,14 @@ pub fn mach_sty(cfg: @session::config, t: t) -> sty {
}
}
pub fn default_arg_mode_for_ty(tcx: ctxt, ty: ty::t) -> ast::rmode {
return if tcx.legacy_modes {
if type_is_borrowed(ty) {
// the old mode default was ++ for things like &ptr, but to be
// forward-compatible with non-legacy, we should use +
ast::by_copy
} else if ty::type_is_immediate(ty) {
ast::by_copy
} else {
ast::by_ref
}
} else {
ast::by_copy
};
fn type_is_borrowed(ty: t) -> bool {
match ty::get(ty).sty {
ty::ty_rptr(*) => true,
ty_evec(_, vstore_slice(_)) => true,
ty_estr(vstore_slice(_)) => true,
// technically, we prob ought to include
// &fn(), but that is treated specially due to #2202
_ => false
}
}
}
pub fn walk_ty(ty: t, f: &fn(t)) {
maybe_walk_ty(ty, |t| { f(t); true });
}
pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) {
if !f(ty) { return; }
if !f(ty) {
return;
}
match get(ty).sty {
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_estr(_) | ty_type | ty_opaque_box | ty_self(_) |
@ -1323,7 +1302,9 @@ pub fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: &fn(t) -> t) -> t {
pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig {
let args = do sig.inputs.map |arg| {
arg { mode: arg.mode, ty: fldop(arg.ty) }
arg {
ty: fldop(arg.ty)
}
};
FnSig {
@ -2696,13 +2677,6 @@ impl to_bytes::IterBytes for field {
}
}
impl to_bytes::IterBytes for arg {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
to_bytes::iter_bytes_2(&self.mode,
&self.ty, lsb0, f)
}
}
impl to_bytes::IterBytes for FnSig {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
to_bytes::iter_bytes_2(&self.inputs,
@ -3368,78 +3342,6 @@ pub fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) {
}
}
// Maintains a little union-set tree for inferred modes. `canon()` returns
// the current head value for `m0`.
fn canon<T:Copy + cmp::Eq>(tbl: &mut HashMap<ast::node_id, ast::inferable<T>>,
m0: ast::inferable<T>) -> ast::inferable<T> {
match m0 {
ast::infer(id) => {
let m1 = match tbl.find(&id) {
None => return m0,
Some(&m1) => m1
};
let cm1 = canon(tbl, m1);
// path compression:
if cm1 != m1 { tbl.insert(id, cm1); }
cm1
},
_ => m0
}
}
// Maintains a little union-set tree for inferred modes. `resolve_mode()`
// returns the current head value for `m0`.
pub fn canon_mode(cx: ctxt, m0: ast::mode) -> ast::mode {
canon(cx.inferred_modes, m0)
}
// Returns the head value for mode, failing if `m` was a infer(_) that
// was never inferred. This should be safe for use after typeck.
pub fn resolved_mode(cx: ctxt, m: ast::mode) -> ast::rmode {
match canon_mode(cx, m) {
ast::infer(_) => {
cx.sess.bug(fmt!("mode %? was never resolved", m));
}
ast::expl(m0) => m0
}
}
pub fn arg_mode(cx: ctxt, a: arg) -> ast::rmode { resolved_mode(cx, a.mode) }
// Unifies `m1` and `m2`. Returns unified value or failure code.
pub fn unify_mode(cx: ctxt, modes: expected_found<ast::mode>)
-> Result<ast::mode, type_err> {
let m1 = modes.expected;
let m2 = modes.found;
match (canon_mode(cx, m1), canon_mode(cx, m2)) {
(m1, m2) if (m1 == m2) => {
result::Ok(m1)
}
(ast::infer(_), ast::infer(id2)) => {
cx.inferred_modes.insert(id2, m1);
result::Ok(m1)
}
(ast::infer(id), m) | (m, ast::infer(id)) => {
cx.inferred_modes.insert(id, m);
result::Ok(m1)
}
(_, _) => {
result::Err(terr_mode_mismatch(modes))
}
}
}
// If `m` was never unified, unifies it with `m_def`. Returns the final value
// for `m`.
pub fn set_default_mode(cx: ctxt, m: ast::mode, m_def: ast::rmode) {
match canon_mode(cx, m) {
ast::infer(id) => {
cx.inferred_modes.insert(id, ast::expl(m_def));
}
ast::expl(_) => ()
}
}
pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
match get(t).sty {
ty_nil | ty_bot | ty_bool | ty_int(_) |
@ -3537,11 +3439,6 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
*cx.sess.str_of(values.found))
}
terr_arg_count => ~"incorrect number of function parameters",
terr_mode_mismatch(values) => {
fmt!("expected argument mode %s, but found %s",
pprust::mode_to_str(values.expected),
pprust::mode_to_str(values.found))
}
terr_regions_does_not_outlive(*) => {
fmt!("lifetime mismatch")
}

View file

@ -501,52 +501,22 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
return typ;
}
pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
self: &AC,
rscope: &RS,
a: ast::arg,
expected_ty: Option<ty::arg>)
-> ty::arg {
pub fn ty_of_arg<AC:AstConv,
RS:region_scope + Copy + Durable>(
self: &AC,
rscope: &RS,
a: ast::arg,
expected_ty: Option<ty::arg>)
-> ty::arg {
let ty = match a.ty.node {
ast::ty_infer if expected_ty.is_some() => expected_ty.get().ty,
ast::ty_infer => self.ty_infer(a.ty.span),
_ => ast_ty_to_ty(self, rscope, a.ty)
ast::ty_infer if expected_ty.is_some() => expected_ty.get().ty,
ast::ty_infer => self.ty_infer(a.ty.span),
_ => ast_ty_to_ty(self, rscope, a.ty),
};
let mode = {
match a.mode {
ast::infer(_) if expected_ty.is_some() => {
result::get(&ty::unify_mode(
self.tcx(),
ty::expected_found {expected: expected_ty.get().mode,
found: a.mode}))
}
ast::infer(_) => {
match ty::get(ty).sty {
// If the type is not specified, then this must be a fn expr.
// Leave the mode as infer(_), it will get inferred based
// on constraints elsewhere.
ty::ty_infer(_) => a.mode,
// If the type is known, then use the default for that type.
// Here we unify m and the default. This should update the
// tables in tcx but should never fail, because nothing else
// will have been unified with m yet:
_ => {
let m1 = ast::expl(ty::default_arg_mode_for_ty(self.tcx(),
ty));
result::get(&ty::unify_mode(
self.tcx(),
ty::expected_found {expected: m1,
found: a.mode}))
}
}
}
ast::expl(_) => a.mode
}
};
arg {mode: mode, ty: ty}
arg {
ty: ty
}
}
pub fn bound_lifetimes<AC:AstConv>(

View file

@ -96,7 +96,7 @@ use util::common::indenter;
use core::hashmap::HashSet;
use std::list::Nil;
use syntax::ast::{def_id, sty_value, sty_region, sty_box};
use syntax::ast::{sty_uniq, sty_static, node_id, by_copy, by_ref};
use syntax::ast::{sty_uniq, sty_static, node_id};
use syntax::ast::{m_const, m_mutbl, m_imm};
use syntax::ast;
use syntax::ast_map;
@ -1051,9 +1051,9 @@ pub impl<'self> LookupContext<'self> {
self.fcx.write_substs(self.callee_id, all_substs);
method_map_entry {
self_arg: arg {
mode: ast::expl(self_mode),
ty: candidate.rcvr_ty,
},
self_mode: self_mode,
explicit_self: candidate.method_ty.self_ty,
origin: candidate.origin,
}
@ -1298,6 +1298,9 @@ pub impl<'self> LookupContext<'self> {
}
}
pub fn get_mode_from_self_type(self_type: ast::self_ty_) -> ast::rmode {
match self_type { sty_value => by_copy, _ => by_ref }
pub fn get_mode_from_self_type(self_type: ast::self_ty_) -> SelfMode {
match self_type {
sty_value => ty::ByCopy,
_ => ty::ByRef,
}
}

View file

@ -1292,8 +1292,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
}
fn err_args(len: uint) -> ~[ty::arg] {
vec::from_fn(len, |_| ty::arg {mode: ast::expl(ast::by_copy),
ty: ty::mk_err()})
vec::from_fn(len, |_| ty::arg { ty: ty::mk_err() })
}
// A generic function for checking assignment expressions
@ -1694,10 +1693,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
let fty = if error_happened {
fty_sig = FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: fn_ty.sig.inputs.map(|an_arg| {
arg { mode: an_arg.mode,
ty: ty::mk_err()
}}),
inputs: fn_ty.sig.inputs.map(|_| {
arg {
ty: ty::mk_err()
}
}),
output: ty::mk_err()
};
ty::mk_err()
@ -2762,11 +2762,9 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
};
if bot_field {
fcx.write_bot(id);
}
else if err_field {
} else if err_field {
fcx.write_error(id);
}
else {
} else {
let typ = ty::mk_tup(tcx, elt_ts);
fcx.write_ty(id, typ);
}
@ -2796,15 +2794,11 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
check_expr(fcx, idx);
let raw_base_t = fcx.expr_ty(base);
let idx_t = fcx.expr_ty(idx);
if ty::type_is_error(raw_base_t)
|| ty::type_is_bot(raw_base_t) {
if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
fcx.write_ty(id, raw_base_t);
}
else if ty::type_is_error(idx_t)
|| ty::type_is_bot(idx_t) {
} else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
fcx.write_ty(id, idx_t);
}
else {
} else {
let (base_t, derefs) = do_autoderef(fcx, expr.span, raw_base_t);
let base_sty = structure_of(fcx, expr.span, base_t);
match ty::index_sty(&base_sty) {
@ -2815,15 +2809,29 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
}
None => {
let resolved = structurally_resolved_type(fcx,
expr.span, raw_base_t);
let ret_ty = lookup_op_method(fcx, expr, base, resolved,
tcx.sess.ident_of(~"index"),
~[idx], DoDerefArgs, AutoderefReceiver,
|| {
fcx.type_error_message(expr.span, |actual|
fmt!("cannot index a value \
of type `%s`", actual), base_t, None);
}, expected);
expr.span,
raw_base_t);
let index_ident = tcx.sess.ident_of(~"index");
let error_message = || {
fcx.type_error_message(expr.span,
|actual| {
fmt!("cannot index a value \
of type `%s`",
actual)
},
base_t,
None);
};
let ret_ty = lookup_op_method(fcx,
expr,
base,
resolved,
index_ident,
~[idx],
DoDerefArgs,
AutoderefReceiver,
error_message,
expected);
fcx.write_ty(id, ret_ty);
}
}
@ -3180,8 +3188,8 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
-> ty_param_bounds_and_ty {
match defn {
ast::def_arg(nid, _, _) | ast::def_local(nid, _) |
ast::def_self(nid, _) | ast::def_binding(nid, _) => {
ast::def_arg(nid, _) | ast::def_local(nid, _) | ast::def_self(nid, _) |
ast::def_binding(nid, _) => {
let typ = fcx.local_ty(sp, nid);
return no_params(typ);
}
@ -3429,41 +3437,52 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
fn param(ccx: @mut CrateCtxt, n: uint) -> ty::t {
ty::mk_param(ccx.tcx, n, local_def(0))
}
fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
arg {mode: ast::expl(m), ty: ty}
fn arg(ty: ty::t) -> ty::arg {
arg {
ty: ty
}
}
let tcx = ccx.tcx;
let (n_tps, inputs, output) = match *ccx.tcx.sess.str_of(it.ident) {
~"size_of" |
~"pref_align_of" | ~"min_align_of" => (1u, ~[], ty::mk_uint()),
~"init" => (1u, ~[], param(ccx, 0u)),
~"forget" => (1u, ~[arg(ast::by_copy, param(ccx, 0u))],
ty::mk_nil()),
~"transmute" => (2, ~[arg(ast::by_copy, param(ccx, 0))], param(ccx, 1)),
~"forget" => (1u, ~[arg(param(ccx, 0u))], ty::mk_nil()),
~"transmute" => (2, ~[ arg(param(ccx, 0)) ], param(ccx, 1)),
~"move_val" | ~"move_val_init" => {
(1u, ~[arg(ast::by_copy,
ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
param(ccx, 0u))),
arg(ast::by_copy, param(ccx, 0u))],
(1u,
~[
arg(ty::mk_mut_rptr(tcx,
ty::re_bound(ty::br_anon(0)),
param(ccx, 0))),
arg(param(ccx, 0u))
],
ty::mk_nil())
}
~"needs_drop" => (1u, ~[], ty::mk_bool()),
~"atomic_cxchg" | ~"atomic_cxchg_acq"| ~"atomic_cxchg_rel" => {
(0u, ~[arg(ast::by_copy,
ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
ty::mk_int())),
arg(ast::by_copy, ty::mk_int()),
arg(ast::by_copy, ty::mk_int())],
ty::mk_int())
(0,
~[
arg(ty::mk_mut_rptr(tcx,
ty::re_bound(ty::br_anon(0)),
ty::mk_int(tcx))),
arg(ty::mk_int()),
arg(ty::mk_int())
],
ty::mk_int(tcx))
}
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
(0u, ~[arg(ast::by_copy,
ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
ty::mk_int())),
arg(ast::by_copy, ty::mk_int())],
(0,
~[
arg(ty::mk_mut_rptr(tcx,
ty::re_bound(ty::br_anon(0)),
ty::mk_int(tcx))),
arg(ty::mk_int())
],
ty::mk_int())
}
@ -3472,14 +3491,15 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
(1u, ~[], ty::mk_nil_ptr(ccx.tcx))
}
~"visit_tydesc" => {
let tydesc_name = special_idents::tydesc;
assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
let (_, tydesc_ty) = *tcx.intrinsic_defs.get(&tydesc_name);
let (_, visitor_object_ty) = ty::visitor_object_ty(ccx.tcx);
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {ty: tydesc_ty,
mutbl: ast::m_imm});
(0u, ~[arg(ast::by_copy, td_ptr),
arg(ast::by_copy, visitor_object_ty)], ty::mk_nil())
let tydesc_name = special_idents::tydesc;
assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
let (_, tydesc_ty) = *tcx.intrinsic_defs.get(&tydesc_name);
let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
ty: tydesc_ty,
mutbl: ast::m_imm
});
(0, ~[ arg(td_ptr), arg(visitor_object_ty) ], ty::mk_nil())
}
~"frame_address" => {
let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy {
@ -3489,233 +3509,124 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
region: ty::re_bound(ty::br_anon(0)),
sig: ty::FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: ~[arg {mode: ast::expl(ast::by_copy),
ty: ty::mk_imm_ptr(
ccx.tcx,
ty::mk_mach_uint(ast::ty_u8))}],
inputs: ~[
arg {
ty: ty::mk_imm_ptr(ccx.tcx,
ty::mk_mach_uint(ast::ty_u8))
}
],
output: ty::mk_nil()
}
});
(0u, ~[arg(ast::by_copy, fty)], ty::mk_nil())
(0u, ~[ arg(fty) ], ty::mk_nil())
}
~"morestack_addr" => {
(0u, ~[], ty::mk_nil_ptr(ccx.tcx))
}
~"memmove32" => {
(0, ~[arg(ast::by_copy,
ty::mk_ptr(tcx,
ty::mt { ty: ty::mk_u8(), mutbl: ast::m_mutbl })),
arg(ast::by_copy,
ty::mk_ptr(tcx,
ty::mt { ty: ty::mk_u8(), mutbl: ast::m_imm })),
arg(ast::by_copy,
ty::mk_u32())],
(0,
~[
arg(ty::mk_ptr(tcx, ty::mt {
ty: ty::mk_u8(),
mutbl: ast::m_mutbl
})),
arg(ty::mk_ptr(tcx, ty::mt {
ty: ty::mk_u8(),
mutbl: ast::m_imm
})),
arg(ty::mk_u32())
],
ty::mk_nil())
}
~"memmove64" => {
(0, ~[arg(ast::by_copy,
ty::mk_ptr(tcx,
ty::mt { ty: ty::mk_u8(), mutbl: ast::m_mutbl })),
arg(ast::by_copy,
ty::mk_ptr(tcx,
ty::mt { ty: ty::mk_u8(), mutbl: ast::m_imm })),
arg(ast::by_copy,
ty::mk_u64())],
ty::mk_nil())
}
~"sqrtf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"sqrtf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"powif32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32()),
arg(ast::by_copy, ty::mk_i32())],
ty::mk_f32())
}
~"powif64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64()),
arg(ast::by_copy, ty::mk_i32())],
ty::mk_f64())
}
~"sinf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"sinf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"cosf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"cosf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"powf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32()),
arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"powf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64()),
arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"expf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"expf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"exp2f32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"exp2f64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"logf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"logf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"log10f32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"log10f64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"log2f32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"log2f64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"fmaf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32()),
arg(ast::by_copy, ty::mk_f32()),
arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"fmaf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64()),
arg(ast::by_copy, ty::mk_f64()),
arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"fabsf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"fabsf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"floorf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"floorf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"ceilf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"ceilf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"truncf32" => {
(0u, ~[arg(ast::by_copy, ty::mk_f32())],
ty::mk_f32())
}
~"truncf64" => {
(0u, ~[arg(ast::by_copy, ty::mk_f64())],
ty::mk_f64())
}
~"ctpop8" => {
(0u, ~[arg(ast::by_copy, ty::mk_i8())],
ty::mk_i8())
}
~"ctpop16" => {
(0u, ~[arg(ast::by_copy, ty::mk_i16())],
ty::mk_i16())
}
~"ctpop32" => {
(0u, ~[arg(ast::by_copy, ty::mk_i32())],
ty::mk_i32())
}
~"ctpop64" => {
(0u, ~[arg(ast::by_copy, ty::mk_i64())],
ty::mk_i64())
}
~"ctlz8" => {
(0u, ~[arg(ast::by_copy, ty::mk_i8())],
ty::mk_i8())
}
~"ctlz16" => {
(0u, ~[arg(ast::by_copy, ty::mk_i16())],
ty::mk_i16())
}
~"ctlz32" => {
(0u, ~[arg(ast::by_copy, ty::mk_i32())],
ty::mk_i32())
}
~"ctlz64" => {
(0u, ~[arg(ast::by_copy, ty::mk_i64())],
ty::mk_i64())
}
~"cttz8" => {
(0u, ~[arg(ast::by_copy, ty::mk_i8())],
ty::mk_i8())
}
~"cttz16" => {
(0u, ~[arg(ast::by_copy, ty::mk_i16())],
ty::mk_i16())
}
~"cttz32" => {
(0u, ~[arg(ast::by_copy, ty::mk_i32())],
ty::mk_i32())
}
~"cttz64" => {
(0u, ~[arg(ast::by_copy, ty::mk_i64())],
ty::mk_i64())
}
~"bswap16" => {
(0u, ~[arg(ast::by_copy, ty::mk_i16())],
ty::mk_i16())
}
~"bswap32" => {
(0u, ~[arg(ast::by_copy, ty::mk_i32())],
ty::mk_i32())
}
~"bswap64" => {
(0u, ~[arg(ast::by_copy, ty::mk_i64())],
ty::mk_i64())
}
ref other => {
tcx.sess.span_err(it.span, ~"unrecognized intrinsic function: `" +
(*other) + ~"`");
return;
(0,
~[arg(ty::mk_ptr(tcx, ty::mt {
ty: ty::mk_u8(),
mutbl: ast::m_mutbl
})),
arg(ty::mk_ptr(tcx, ty::mt {
ty: ty::mk_u8(),
mutbl: ast::m_imm
})),
arg(ty::mk_u64())
],
ty::mk_nil(tcx))
}
~"sqrtf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"sqrtf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"powif32" => {
(0,
~[ arg(ty::mk_f32()), arg(ty::mk_i32()) ],
ty::mk_f32())
}
~"powif64" => {
(0,
~[ arg(ty::mk_f64()), arg(ty::mk_i32()) ],
ty::mk_f64())
}
~"sinf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"sinf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"cosf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"cosf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"powf32" => {
(0,
~[ arg(ty::mk_f32()), arg(ty::mk_f32()) ],
ty::mk_f32())
}
~"powf64" => {
(0,
~[ arg(ty::mk_f64()), arg(ty::mk_f64()) ],
ty::mk_f64())
}
~"expf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"expf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"exp2f32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"exp2f64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"logf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"logf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"log10f32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"log10f64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"log2f32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"log2f64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"fmaf32" => {
(0,
~[ arg(ty::mk_f32()), arg(ty::mk_f32()), arg(ty::mk_f32()) ],
ty::mk_f32())
}
~"fmaf64" => {
(0,
~[ arg(ty::mk_f64()), arg(ty::mk_f64()), arg(ty::mk_f64()) ],
ty::mk_f64())
}
~"fabsf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"fabsf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"floorf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"floorf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"ceilf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"ceilf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"truncf32" => (0, ~[ arg(ty::mk_f32()) ], ty::mk_f32()),
~"truncf64" => (0, ~[ arg(ty::mk_f64()) ], ty::mk_f64()),
~"ctpop8" => (0, ~[ arg(ty::mk_i8()) ], ty::mk_i8()),
~"ctpop16" => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
~"ctpop32" => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
~"ctpop64" => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
~"ctlz8" => (0, ~[ arg(ty::mk_i8()) ], ty::mk_i8()),
~"ctlz16" => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
~"ctlz32" => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
~"ctlz64" => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
~"cttz8" => (0, ~[ arg(ty::mk_i8()) ], ty::mk_i8()),
~"cttz16" => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
~"cttz32" => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
~"cttz64" => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
~"bswap16" => (0, ~[ arg(ty::mk_i16()) ], ty::mk_i16()),
~"bswap32" => (0, ~[ arg(ty::mk_i32()) ], ty::mk_i32()),
~"bswap64" => (0, ~[ arg(ty::mk_i64()) ], ty::mk_i64()),
ref other => {
tcx.sess.span_err(it.span,
~"unrecognized intrinsic function: `" +
(*other) + ~"`");
return;
}
};
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::unsafe_fn,

View file

@ -55,7 +55,7 @@ pub type rvt = visit::vt<@mut Rcx>;
fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::def) -> ty::Region {
let tcx = fcx.tcx();
match def {
def_local(node_id, _) | def_arg(node_id, _, _) |
def_local(node_id, _) | def_arg(node_id, _) |
def_self(node_id, _) | def_binding(node_id, _) => {
tcx.region_maps.encl_region(node_id)
}

View file

@ -66,7 +66,9 @@ fn resolve_method_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) {
for resolve_type_vars_in_type(fcx, sp, mme.self_arg.ty).each |t| {
let method_map = fcx.ccx.method_map;
let new_entry = method_map_entry {
self_arg: arg {mode: mme.self_arg.mode, ty: *t },
self_arg: arg {
ty: *t
},
..*mme
};
debug!("writeback::resolve_method_map_entry(id=%?, \
@ -213,52 +215,55 @@ fn visit_stmt(s: @ast::stmt, wbcx: @mut WbCtxt, v: wb_vt) {
resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s));
visit::visit_stmt(s, wbcx, v);
}
fn visit_expr(e: @ast::expr, wbcx: @mut WbCtxt, v: wb_vt) {
if !wbcx.success { return; }
if !wbcx.success {
return;
}
resolve_type_vars_for_node(wbcx, e.span, e.id);
resolve_method_map_entry(wbcx.fcx, e.span, e.id);
resolve_method_map_entry(wbcx.fcx, e.span, e.callee_id);
resolve_vtable_map_entry(wbcx.fcx, e.span, e.id);
resolve_vtable_map_entry(wbcx.fcx, e.span, e.callee_id);
match e.node {
ast::expr_fn_block(ref decl, _) => {
for vec::each(decl.inputs) |input| {
let r_ty = resolve_type_vars_for_node(wbcx, e.span, input.id);
ast::expr_fn_block(ref decl, _) => {
for vec::each(decl.inputs) |input| {
let _ = resolve_type_vars_for_node(wbcx, e.span, input.id);
}
}
// Just in case we never constrained the mode to anything,
// constrain it to the default for the type in question.
match (r_ty, input.mode) {
(Some(t), ast::infer(_)) => {
let tcx = wbcx.fcx.ccx.tcx;
let m_def = ty::default_arg_mode_for_ty(tcx, t);
ty::set_default_mode(tcx, input.mode, m_def);
}
_ => ()
}
}
}
ast::expr_binary(*) | ast::expr_unary(*) | ast::expr_assign_op(*) |
ast::expr_index(*) => {
maybe_resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
}
ast::expr_binary(*) | ast::expr_unary(*) | ast::expr_assign_op(*)
| ast::expr_index(*) => {
maybe_resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
}
ast::expr_method_call(*) => {
// We must always have written in a callee ID type for these.
resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
}
ast::expr_method_call(*) => {
// We must always have written in a callee ID type for these.
resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
}
_ => ()
_ => ()
}
visit::visit_expr(e, wbcx, v);
}
fn visit_block(b: &ast::blk, wbcx: @mut WbCtxt, v: wb_vt) {
if !wbcx.success { return; }
if !wbcx.success {
return;
}
resolve_type_vars_for_node(wbcx, b.span, b.node.id);
visit::visit_block(b, wbcx, v);
}
fn visit_pat(p: @ast::pat, wbcx: @mut WbCtxt, v: wb_vt) {
if !wbcx.success { return; }
if !wbcx.success {
return;
}
resolve_type_vars_for_node(wbcx, p.span, p.id);
debug!("Type for pattern binding %s (id %d) resolved to %s",
pat_to_str(p, wbcx.fcx.ccx.tcx.sess.intr()), p.id,
@ -267,6 +272,7 @@ fn visit_pat(p: @ast::pat, wbcx: @mut WbCtxt, v: wb_vt) {
p.id)));
visit::visit_pat(p, wbcx, v);
}
fn visit_local(l: @ast::local, wbcx: @mut WbCtxt, v: wb_vt) {
if !wbcx.success { return; }
let var_ty = wbcx.fcx.local_ty(l.span, l.node.id);

View file

@ -552,10 +552,14 @@ pub fn compare_impl_method(tcx: ty::ctxt,
// represent the self argument (unless this is a static method).
// This argument will have the *transformed* self type.
for trait_m.transformed_self_ty.each |&t| {
trait_fn_args.push(ty::arg {mode: ast::expl(ast::by_copy), ty: t});
trait_fn_args.push(ty::arg {
ty: t
});
}
for impl_m.transformed_self_ty.each |&t| {
impl_fn_args.push(ty::arg {mode: ast::expl(ast::by_copy), ty: t});
impl_fn_args.push(ty::arg {
ty: t
});
}
// Add in the normal arguments.

View file

@ -95,7 +95,6 @@ pub trait Combine {
b: &ty::ClosureTy) -> cres<ty::ClosureTy>;
fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
fn flds(&self, a: ty::field, b: ty::field) -> cres<ty::field>;
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode>;
fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg>;
fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil>;
fn purities(&self, a: purity, b: purity) -> cres<purity>;
@ -312,28 +311,20 @@ pub fn super_flds<C:Combine>(
}
}
pub fn super_modes<C:Combine>(
self: &C, a: ast::mode, b: ast::mode)
-> cres<ast::mode> {
let tcx = self.infcx().tcx;
ty::unify_mode(tcx, expected_found(self, a, b))
}
pub fn super_args<C:Combine>(
self: &C, a: ty::arg, b: ty::arg)
-> cres<ty::arg> {
do self.modes(a.mode, b.mode).chain |m| {
do self.contratys(a.ty, b.ty).chain |t| {
Ok(arg {mode: m, ty: t})
}
pub fn super_args<C:Combine>(self: &C, a: ty::arg, b: ty::arg)
-> cres<ty::arg> {
do self.contratys(a.ty, b.ty).chain |t| {
Ok(arg {
ty: t
})
}
}
pub fn super_vstores<C:Combine>(
self: &C, vk: ty::terr_vstore_kind,
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
pub fn super_vstores<C:Combine>(self: &C,
vk: ty::terr_vstore_kind,
a: ty::vstore,
b: ty::vstore)
-> cres<ty::vstore> {
debug!("%s.super_vstores(a=%?, b=%?)", self.tag(), a, b);
match (a, b) {

View file

@ -152,10 +152,6 @@ impl Combine for Glb {
super_trait_stores(self, vk, a, b)
}
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
super_modes(self, a, b)
}
fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg> {
super_args(self, a, b)
}

View file

@ -234,10 +234,6 @@ impl Combine for Lub {
super_trait_stores(self, vk, a, b)
}
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
super_modes(self, a, b)
}
fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg> {
super_args(self, a, b)
}

View file

@ -241,14 +241,10 @@ impl Combine for Sub {
vk: ty::terr_vstore_kind,
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore> {
-> cres<ty::TraitStore> {
super_trait_stores(self, vk, a, b)
}
fn modes(&self, a: ast::mode, b: ast::mode) -> cres<ast::mode> {
super_modes(self, a, b)
}
fn args(&self, a: ty::arg, b: ty::arg) -> cres<ty::arg> {
super_args(self, a, b)
}

View file

@ -116,10 +116,13 @@ pub struct method_param {
}
pub struct method_map_entry {
// the type and mode of the self parameter, which is not reflected
// in the fn type (FIXME #3446)
// the type of the self parameter, which is not reflected in the fn type
// (FIXME #3446)
self_arg: ty::arg,
// the mode of `self`
self_mode: ty::SelfMode,
// the type of explicit self on the method
explicit_self: ast::self_ty_,
@ -329,7 +332,6 @@ fn check_main_fn_ty(ccx: @mut CrateCtxt,
fn check_start_fn_ty(ccx: @mut CrateCtxt,
start_id: ast::node_id,
start_span: span) {
let tcx = ccx.tcx;
let start_t = ty::node_id_to_type(tcx, start_id);
match ty::get(start_t).sty {
@ -351,19 +353,25 @@ fn check_start_fn_ty(ccx: @mut CrateCtxt,
_ => ()
}
fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
ty::arg {mode: ast::expl(m), ty: ty}
fn arg(ty: ty::t) -> ty::arg {
ty::arg {
ty: ty
}
}
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::impure_fn,
abis: abi::AbiSet::Rust(),
sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: ~[arg(ast::by_copy, ty::mk_int()),
arg(ast::by_copy, ty::mk_imm_ptr(tcx,
ty::mk_imm_ptr(tcx, ty::mk_u8()))),
arg(ast::by_copy, ty::mk_imm_ptr(tcx, ty::mk_u8()))],
output: ty::mk_int()}
sig: ty::FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: ~[
arg(ty::mk_int()),
arg(ty::mk_imm_ptr(tcx,
ty::mk_imm_ptr(tcx, ty::mk_u8()))),
arg(ty::mk_imm_ptr(tcx, ty::mk_u8()))
],
output: ty::mk_int()
}
});
require_same_types(tcx, None, false, start_span, start_t, se_ty,

View file

@ -8,28 +8,25 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use middle::ty;
use middle::typeck;
use middle::ty::canon_mode;
use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid,
br_fresh};
use middle::ty::{ctxt, field, method};
use metadata::encoder;
use middle::ty::{ReSkolemized, ReVar};
use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid};
use middle::ty::{br_fresh, ctxt, field, method};
use middle::ty::{mt, t, param_bound, param_ty};
use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region};
use middle::ty::{ReSkolemized, ReVar};
use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum};
use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_bare_fn, ty_closure};
use middle::ty::{ty_trait, ty_int};
use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq};
use middle::ty::{ty_trait, ty_int};
use middle::ty::{ty_uint, ty_unboxed_vec, ty_infer};
use metadata::encoder;
use middle::ty;
use middle::typeck;
use syntax::abi::AbiSet;
use syntax::ast_map;
use syntax::codemap::span;
use syntax::print::pprust;
use syntax::print::pprust::mode_to_str;
use syntax::{ast, ast_util};
use syntax::ast_map;
use syntax::abi::AbiSet;
pub trait Repr {
fn repr(&self, tcx: ctxt) -> ~str;
@ -293,26 +290,14 @@ pub fn trait_ref_to_str(cx: ctxt, trait_ref: &ty::TraitRef) -> ~str {
pub fn ty_to_str(cx: ctxt, typ: t) -> ~str {
fn fn_input_to_str(cx: ctxt, input: ty::arg) -> ~str {
let ty::arg {mode: mode, ty: ty} = input;
let modestr = match canon_mode(cx, mode) {
ast::infer(_) => ~"",
ast::expl(m) => {
if !ty::type_needs_infer(ty) &&
m == ty::default_arg_mode_for_ty(cx, ty) {
~""
} else {
mode_to_str(ast::expl(m)) + ~":"
}
}
};
fmt!("%s%s", modestr, ty_to_str(cx, ty))
ty_to_str(cx, input.ty)
}
fn bare_fn_to_str(cx: ctxt,
purity: ast::purity,
abis: AbiSet,
ident: Option<ast::ident>,
sig: &ty::FnSig) -> ~str
{
sig: &ty::FnSig)
-> ~str {
let mut s = ~"extern ";
s.push_str(abis.to_str());
@ -701,7 +686,7 @@ impl Repr for typeck::method_map_entry {
impl Repr for ty::arg {
fn repr(&self, tcx: ctxt) -> ~str {
fmt!("%?(%s)", self.mode, self.ty.repr(tcx))
fmt!("(%s)", self.ty.repr(tcx))
}
}

View file

@ -198,7 +198,7 @@ pub enum def {
def_mod(def_id),
def_foreign_mod(def_id),
def_const(def_id),
def_arg(node_id, mode, bool /* is_mutbl */),
def_arg(node_id, bool /* is_mutbl */),
def_local(node_id, bool /* is_mutbl */),
def_variant(def_id /* enum */, def_id /* variant */),
def_ty(def_id),
@ -417,43 +417,6 @@ pub enum unop {
neg
}
// Generally, after typeck you can get the inferred value
// using ty::resolved_T(...).
#[auto_encode]
#[auto_decode]
#[deriving(Eq)]
pub enum inferable<T> {
expl(T),
infer(node_id)
}
impl<T:to_bytes::IterBytes> to_bytes::IterBytes for inferable<T> {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
match *self {
expl(ref t) =>
to_bytes::iter_bytes_2(&0u8, t, lsb0, f),
infer(ref n) =>
to_bytes::iter_bytes_2(&1u8, n, lsb0, f),
}
}
}
// "resolved" mode: the real modes.
#[auto_encode]
#[auto_decode]
#[deriving(Eq)]
pub enum rmode { by_ref, by_copy }
impl to_bytes::IterBytes for rmode {
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
(*self as u8).iter_bytes(lsb0, f)
}
}
// inferable mode.
pub type mode = inferable<rmode>;
pub type stmt = spanned<stmt_>;
#[auto_encode]
@ -941,7 +904,6 @@ pub struct inline_asm {
#[auto_decode]
#[deriving(Eq)]
pub struct arg {
mode: mode,
is_mutbl: bool,
ty: @Ty,
pat: @pat,

View file

@ -58,7 +58,7 @@ pub fn def_id_of_def(d: def) -> def_id {
def_use(id) | def_struct(id) | def_trait(id) => {
id
}
def_arg(id, _, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
def_arg(id, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
| def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
| def_typaram_binder(id) | def_label(id) => {
local_def(id)

View file

@ -608,7 +608,6 @@ fn mk_ser_method(
};
let ser_inputs = ~[ast::arg {
mode: ast::infer(cx.next_id()),
is_mutbl: false,
ty: ty_s,
pat: @ast::pat {
@ -670,20 +669,22 @@ fn mk_deser_method(
span: span,
};
let deser_inputs = ~[ast::arg {
mode: ast::infer(cx.next_id()),
is_mutbl: false,
ty: ty_d,
pat: @ast::pat {
let deser_inputs = ~[
ast::arg {
is_mutbl: false,
ty: ty_d,
pat: @ast::pat {
id: cx.next_id(),
node: ast::pat_ident(ast::bind_by_copy,
ast_util::ident_to_path(span,
cx.ident_of(
~"__d")),
None),
span: span,
},
id: cx.next_id(),
node: ast::pat_ident(
ast::bind_by_copy,
ast_util::ident_to_path(span, cx.ident_of(~"__d")),
None),
span: span,
},
id: cx.next_id(),
}];
}
];
let deser_decl = ast::fn_decl {
inputs: deser_inputs,
@ -1120,7 +1121,6 @@ fn mk_enum_deser_body(
ast::expr_fn_block(
ast::fn_decl {
inputs: ~[ast::arg {
mode: ast::infer(ext_cx.next_id()),
is_mutbl: false,
ty: @ast::Ty {
id: ext_cx.next_id(),

View file

@ -419,7 +419,6 @@ pub fn mk_arg(cx: @ext_ctxt,
-> ast::arg {
let arg_pat = mk_pat_ident(cx, span, ident);
ast::arg {
mode: ast::infer(cx.next_id()),
is_mutbl: false,
ty: ty,
pat: arg_pat,

View file

@ -196,7 +196,6 @@ impl ext_ctxt_ast_builder for @ext_ctxt {
fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg {
ast::arg {
mode: ast::infer(self.next_id()),
is_mutbl: false,
ty: ty,
pat: @ast::pat {

View file

@ -105,7 +105,6 @@ fn fold_attribute_(at: attribute, fld: @ast_fold) -> attribute {
//used in noop_fold_foreign_item and noop_fold_fn_decl
fn fold_arg_(a: arg, fld: @ast_fold) -> arg {
ast::arg {
mode: a.mode,
is_mutbl: a.is_mutbl,
ty: fld.fold_ty(a.ty),
pat: fld.fold_pat(a.pat),

View file

@ -17,10 +17,10 @@ use ast::{RegionTyParamBound, TraitTyParamBound};
use ast::{provided, public, purity};
use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
use ast::{bind_by_copy, bitand, bitor, bitxor, blk};
use ast::{blk_check_mode, box, by_copy, by_ref};
use ast::{blk_check_mode, box};
use ast::{crate, crate_cfg, decl, decl_item};
use ast::{decl_local, default_blk, deref, quot, enum_def};
use ast::{expl, expr, expr_, expr_addr_of, expr_match, expr_again};
use ast::{expr, expr_, expr_addr_of, expr_match, expr_again};
use ast::{expr_assign, expr_assign_op, expr_binary, expr_block};
use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
use ast::{expr_field, expr_fn_block, expr_if, expr_index};
@ -32,13 +32,13 @@ use ast::{expr_vstore_slice, expr_vstore_box};
use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
use ast::{expr_vstore_uniq, TyClosure, TyBareFn, Onceness, Once, Many};
use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod};
use ast::{ident, impure_fn, infer, inherited, item, item_, item_const};
use ast::{ident, impure_fn, inherited, item, item_, item_const};
use ast::{item_const, item_enum, item_fn, item_foreign_mod, item_impl};
use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const};
use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
use ast::{match_seq, match_tok, method, mode, mt, mul, mutability};
use ast::{match_seq, match_tok, method, mt, mul, mutability};
use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum};
use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct};
use ast::{pat_tup, pat_uniq, pat_wild, private};
@ -765,22 +765,22 @@ pub impl Parser {
}
// parse an optional mode.
fn parse_arg_mode(&self) -> mode {
// XXX: Remove after snapshot.
fn parse_arg_mode(&self) {
if self.eat(&token::BINOP(token::MINUS)) {
self.obsolete(*self.span, ObsoleteMode);
expl(by_copy)
} else if self.eat(&token::ANDAND) {
expl(by_ref)
// Ignore.
} else if self.eat(&token::BINOP(token::PLUS)) {
if self.eat(&token::BINOP(token::PLUS)) {
// ++ mode is obsolete, but we need a snapshot
// to stop parsing it.
expl(by_copy)
// Ignore.
} else {
expl(by_copy)
// Ignore.
}
} else {
infer(self.get_id())
// Ignore.
}
}
@ -810,16 +810,14 @@ pub impl Parser {
// This version of parse arg doesn't necessarily require
// identifier names.
fn parse_arg_general(&self, require_name: bool) -> arg {
let m;
let mut is_mutbl = false;
let pat = if require_name || self.is_named_argument() {
m = self.parse_arg_mode();
self.parse_arg_mode();
is_mutbl = self.eat_keyword(&~"mut");
let pat = self.parse_pat(false);
self.expect(&token::COLON);
pat
} else {
m = infer(self.get_id());
ast_util::ident_to_pat(self.get_id(),
*self.last_span,
special_idents::invalid)
@ -827,8 +825,12 @@ pub impl Parser {
let t = self.parse_ty(false);
ast::arg { mode: m, is_mutbl: is_mutbl,
ty: t, pat: pat, id: self.get_id() }
ast::arg {
is_mutbl: is_mutbl,
ty: t,
pat: pat,
id: self.get_id(),
}
}
// parse a single function argument
@ -838,7 +840,7 @@ pub impl Parser {
// parse an argument in a lambda header e.g. |arg, arg|
fn parse_fn_block_arg(&self) -> arg_or_capture_item {
let m = self.parse_arg_mode();
self.parse_arg_mode();
let is_mutbl = self.eat_keyword(&~"mut");
let pat = self.parse_pat(false);
let t = if self.eat(&token::COLON) {
@ -851,7 +853,6 @@ pub impl Parser {
}
};
either::Left(ast::arg {
mode: m,
is_mutbl: is_mutbl,
ty: t,
pat: pat,
@ -2440,18 +2441,21 @@ pub impl Parser {
// used by the copy foo and ref foo patterns to give a good
// error message when parsing mistakes like ref foo(a,b)
fn parse_pat_ident(&self, refutable: bool,
binding_mode: ast::binding_mode) -> ast::pat_ {
fn parse_pat_ident(&self,
refutable: bool,
binding_mode: ast::binding_mode)
-> ast::pat_ {
if !is_plain_ident(&*self.token) {
self.span_fatal(
*self.last_span,
~"expected identifier, found path");
self.span_fatal(*self.last_span,
~"expected identifier, found path");
}
// why a path here, and not just an identifier?
let name = self.parse_path_without_tps();
let sub = if self.eat(&token::AT) {
Some(self.parse_pat(refutable))
} else { None };
} else {
None
};
// just to be friendly, if they write something like
// ref Some(i)
@ -4406,10 +4410,11 @@ pub impl Parser {
// text that can't be parsed as an item
// - mod_items uses extern_mod_allowed = true
// - block_tail_ uses extern_mod_allowed = false
fn parse_items_and_view_items(&self, first_item_attrs: ~[attribute],
fn parse_items_and_view_items(&self,
first_item_attrs: ~[attribute],
mut extern_mod_allowed: bool,
macros_allowed: bool)
-> ParsedItemsAndViewItems {
-> ParsedItemsAndViewItems {
let mut attrs = vec::append(first_item_attrs,
self.parse_outer_attributes());
// First, parse view items.
@ -4539,8 +4544,11 @@ pub impl Parser {
fn parse_str(&self) -> @~str {
match *self.token {
token::LIT_STR(s) => { self.bump(); self.id_to_str(s) }
_ => self.fatal(~"expected string literal")
token::LIT_STR(s) => {
self.bump();
self.id_to_str(s)
}
_ => self.fatal(~"expected string literal")
}
}
}

View file

@ -1718,19 +1718,6 @@ pub fn print_fn_block_args(s: @ps, decl: &ast::fn_decl) {
maybe_print_comment(s, decl.output.span.lo);
}
pub fn mode_to_str(m: ast::mode) -> ~str {
match m {
ast::expl(ast::by_ref) => ~"&&",
ast::expl(ast::by_copy) => ~"+",
ast::infer(_) => ~""
}
}
pub fn print_arg_mode(s: @ps, m: ast::mode) {
let ms = mode_to_str(m);
if ms != ~"" { word(s.s, ms); }
}
pub fn print_bounds(s: @ps, bounds: @OptVec<ast::TyParamBound>) {
if !bounds.is_empty() {
word(s.s, ~":");
@ -1879,7 +1866,6 @@ pub fn print_mt(s: @ps, mt: &ast::mt) {
pub fn print_arg(s: @ps, input: ast::arg) {
ibox(s, indent_unit);
print_arg_mode(s, input.mode);
if input.is_mutbl {
word_space(s, ~"mut");
}