Replace callee_id with information stored in method_map.

This commit is contained in:
Eduard Burtescu 2014-02-26 16:06:45 +02:00
parent 7a588ceff2
commit 05e4d944a9
43 changed files with 478 additions and 550 deletions

View File

@ -255,7 +255,7 @@ impl Visitor<()> for Context {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
match e.node {
ast::ExprUnary(_, ast::UnBox, _) => {
ast::ExprUnary(ast::UnBox, _) => {
self.gate_box(e.span);
}
_ => {}

View File

@ -21,7 +21,7 @@ use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
RegionParameter};
use metadata::tyencode;
use middle::typeck::method_origin;
use middle::typeck::{MethodCallee, MethodOrigin};
use middle::{ty, typeck, moves};
use middle;
use util::ppaux::ty_to_str;
@ -574,10 +574,50 @@ impl tr for moves::CaptureVar {
}
// ______________________________________________________________________
// Encoding and decoding of method_origin
// Encoding and decoding of MethodCallee
impl tr for method_origin {
fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin {
trait read_method_callee_helper {
fn read_method_callee(&mut self, xcx: @ExtendedDecodeContext) -> MethodCallee;
}
fn encode_method_callee(ecx: &e::EncodeContext,
ebml_w: &mut writer::Encoder,
method: &MethodCallee) {
ebml_w.emit_struct("MethodCallee", 3, |ebml_w| {
ebml_w.emit_struct_field("origin", 0u, |ebml_w| {
method.origin.encode(ebml_w);
});
ebml_w.emit_struct_field("ty", 1u, |ebml_w| {
ebml_w.emit_ty(ecx, method.ty);
});
ebml_w.emit_struct_field("substs", 2u, |ebml_w| {
ebml_w.emit_substs(ecx, &method.substs);
});
})
}
impl<'a> read_method_callee_helper for reader::Decoder<'a> {
fn read_method_callee(&mut self, xcx: @ExtendedDecodeContext) -> MethodCallee {
self.read_struct("MethodCallee", 3, |this| {
MethodCallee {
origin: this.read_struct_field("origin", 0, |this| {
let method_origin: MethodOrigin =
Decodable::decode(this);
method_origin.tr(xcx)
}),
ty: this.read_struct_field("ty", 1, |this| {
this.read_ty(xcx)
}),
substs: this.read_struct_field("substs", 2, |this| {
this.read_substs(xcx)
})
}
})
}
}
impl tr for MethodOrigin {
fn tr(&self, xcx: @ExtendedDecodeContext) -> MethodOrigin {
match *self {
typeck::MethodStatic(did) => typeck::MethodStatic(did.tr(xcx)),
typeck::MethodParam(ref mp) => {
@ -991,17 +1031,13 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
}
}
{
let method_map = maps.method_map.borrow();
let r = method_map.get().find(&id);
for &origin in r.iter() {
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
origin.encode(ebml_w);
})
for &method in maps.method_map.borrow().get().find(&id).iter() {
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
encode_method_callee(ecx, ebml_w, method)
})
}
})
}
{
@ -1335,9 +1371,8 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
ty_param_defs.get().insert(id, bounds);
}
c::tag_table_method_map => {
let origin: method_origin = Decodable::decode(val_dsr);
let mut method_map = dcx.maps.method_map.borrow_mut();
method_map.get().insert(id, origin.tr(xcx));
let method = val_dsr.read_method_callee(xcx);
dcx.maps.method_map.borrow_mut().get().insert(id, method);
}
c::tag_table_vtable_map => {
let vtable_res =

View File

@ -784,7 +784,6 @@ impl<'a> CheckLoanCtxt<'a> {
pub fn check_call(&self,
_expr: &ast::Expr,
_callee: Option<@ast::Expr>,
_callee_id: ast::NodeId,
_callee_span: Span,
_args: &[@ast::Expr]) {
// NB: This call to check for conflicting loans is not truly
@ -828,23 +827,22 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
this.check_captured_variables(expr.id, expr.span)
}
ast::ExprAssign(dest, _) |
ast::ExprAssignOp(_, _, dest, _) => {
ast::ExprAssignOp(_, dest, _) => {
this.check_assignment(dest);
}
ast::ExprCall(f, ref args) => {
this.check_call(expr, Some(f), f.id, f.span, *args);
this.check_call(expr, Some(f), f.span, *args);
}
ast::ExprMethodCall(callee_id, _, _, ref args) => {
this.check_call(expr, None, callee_id, expr.span, *args);
ast::ExprMethodCall(_, _, ref args) => {
this.check_call(expr, None, expr.span, *args);
}
ast::ExprIndex(callee_id, _, rval) |
ast::ExprBinary(callee_id, _, _, rval)
ast::ExprIndex(_, rval) | ast::ExprBinary(_, _, rval)
if method_map.get().contains_key(&expr.id) => {
this.check_call(expr, None, callee_id, expr.span, [rval]);
this.check_call(expr, None, expr.span, [rval]);
}
ast::ExprUnary(callee_id, _, _) | ast::ExprIndex(callee_id, _, _)
ast::ExprUnary(_, _) | ast::ExprIndex(_, _)
if method_map.get().contains_key(&expr.id) => {
this.check_call(expr, None, callee_id, expr.span, []);
this.check_call(expr, None, expr.span, []);
}
ast::ExprInlineAsm(ref ia) => {
for &(_, out) in ia.outputs.iter() {

View File

@ -181,20 +181,9 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
this.id_range.add(ex.id);
{
let r = ex.get_callee_id();
for callee_id in r.iter() {
this.id_range.add(*callee_id);
}
}
// If this expression is borrowed, have to ensure it remains valid:
{
let adjustments = tcx.adjustments.borrow();
let r = adjustments.get().find(&ex.id);
for &adjustments in r.iter() {
this.guarantee_adjustments(ex, *adjustments);
}
for &adjustments in tcx.adjustments.borrow().get().find(&ex.id).iter() {
this.guarantee_adjustments(ex, *adjustments);
}
// If this expression is a move, gather it:
@ -225,7 +214,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
visit::walk_expr(this, ex, ());
}
ast::ExprAssign(l, _) | ast::ExprAssignOp(_, _, l, _) => {
ast::ExprAssign(l, _) | ast::ExprAssignOp(_, l, _) => {
let l_cmt = this.bccx.cat_expr(l);
match opt_loan_path(l_cmt) {
Some(l_lp) => {
@ -252,8 +241,8 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
visit::walk_expr(this, ex, ());
}
ast::ExprIndex(_, _, arg) |
ast::ExprBinary(_, _, _, arg)
ast::ExprIndex(_, arg) |
ast::ExprBinary(_, _, arg)
if method_map.get().contains_key(&ex.id) => {
// Arguments in method calls are always passed by ref.
//

View File

@ -305,7 +305,7 @@ impl CFGBuilder {
expr_exit
}
ast::ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
//
// [pred]
// |
@ -355,16 +355,16 @@ impl CFGBuilder {
self.call(expr, pred, func, *args)
}
ast::ExprMethodCall(_, _, _, ref args) => {
ast::ExprMethodCall(_, _, ref args) => {
self.call(expr, pred, args[0], args.slice_from(1))
}
ast::ExprIndex(_, l, r) |
ast::ExprBinary(_, _, l, r) if self.is_method_call(expr) => {
ast::ExprIndex(l, r) |
ast::ExprBinary(_, l, r) if self.is_method_call(expr) => {
self.call(expr, pred, l, [r])
}
ast::ExprUnary(_, _, e) if self.is_method_call(expr) => {
ast::ExprUnary(_, e) if self.is_method_call(expr) => {
self.call(expr, pred, e, [])
}
@ -384,12 +384,12 @@ impl CFGBuilder {
}
ast::ExprAssign(l, r) |
ast::ExprAssignOp(_, _, l, r) => {
ast::ExprAssignOp(_, l, r) => {
self.straightline(expr, pred, [r, l])
}
ast::ExprIndex(_, l, r) |
ast::ExprBinary(_, _, l, r) => { // NB: && and || handled earlier
ast::ExprIndex(l, r) |
ast::ExprBinary(_, l, r) => { // NB: && and || handled earlier
self.straightline(expr, pred, [l, r])
}
@ -399,7 +399,7 @@ impl CFGBuilder {
ast::ExprAddrOf(_, e) |
ast::ExprCast(e, _) |
ast::ExprUnary(_, _, e) |
ast::ExprUnary(_, e) |
ast::ExprParen(e) |
ast::ExprVstore(e, _) |
ast::ExprField(e, _, _) => {

View File

@ -108,8 +108,8 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
is_const: bool) {
if is_const {
match e.node {
ExprUnary(_, UnDeref, _) => { }
ExprUnary(_, UnBox, _) | ExprUnary(_, UnUniq, _) => {
ExprUnary(UnDeref, _) => { }
ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
sess.span_err(e.span,
"cannot do allocations in constant expressions");
return;

View File

@ -225,10 +225,10 @@ impl ConstEvalVisitor {
}
}
ast::ExprUnary(_, _, inner) | ast::ExprParen(inner) =>
ast::ExprUnary(_, inner) | ast::ExprParen(inner) =>
self.classify(inner),
ast::ExprBinary(_, _, a, b) =>
ast::ExprBinary(_, a, b) =>
join(self.classify(a), self.classify(b)),
ast::ExprTup(ref es) |
@ -262,7 +262,7 @@ impl ConstEvalVisitor {
ast::ExprField(base, _, _) => self.classify(base),
ast::ExprIndex(_, base, idx) =>
ast::ExprIndex(base, idx) =>
join(self.classify(base), self.classify(idx)),
ast::ExprAddrOf(ast::MutImmutable, base) => self.classify(base),
@ -336,7 +336,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
use middle::ty;
fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
match e.node {
ExprUnary(_, UnNeg, inner) => {
ExprUnary(UnNeg, inner) => {
match eval_const_expr_partial(tcx, inner) {
Ok(const_float(f)) => Ok(const_float(-f)),
Ok(const_int(i)) => Ok(const_int(-i)),
@ -346,7 +346,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
ref err => ((*err).clone())
}
}
ExprUnary(_, UnNot, inner) => {
ExprUnary(UnNot, inner) => {
match eval_const_expr_partial(tcx, inner) {
Ok(const_int(i)) => Ok(const_int(!i)),
Ok(const_uint(i)) => Ok(const_uint(!i)),
@ -354,7 +354,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
_ => Err(~"not on float or string")
}
}
ExprBinary(_, op, a, b) => {
ExprBinary(op, a, b) => {
match (eval_const_expr_partial(tcx, a),
eval_const_expr_partial(tcx, b)) {
(Ok(const_float(a)), Ok(const_float(b))) => {

View File

@ -556,7 +556,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
}
ast::ExprAssign(l, r) |
ast::ExprAssignOp(_, _, l, r) => {
ast::ExprAssignOp(_, l, r) => {
self.walk_expr(r, in_out, loop_scopes);
self.walk_expr(l, in_out, loop_scopes);
}
@ -579,35 +579,35 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
ast::ExprCall(f, ref args) => {
self.walk_expr(f, in_out, loop_scopes);
self.walk_call(f.id, expr.id, *args, in_out, loop_scopes);
self.walk_call(expr.id, *args, in_out, loop_scopes);
}
ast::ExprMethodCall(callee_id, _, _, ref args) => {
self.walk_call(callee_id, expr.id, *args, in_out, loop_scopes);
ast::ExprMethodCall(_, _, ref args) => {
self.walk_call(expr.id, *args, in_out, loop_scopes);
}
ast::ExprIndex(callee_id, l, r) |
ast::ExprBinary(callee_id, _, l, r) if self.is_method_call(expr) => {
self.walk_call(callee_id, expr.id, [l, r], in_out, loop_scopes);
ast::ExprIndex(l, r) |
ast::ExprBinary(_, l, r) if self.is_method_call(expr) => {
self.walk_call(expr.id, [l, r], in_out, loop_scopes);
}
ast::ExprUnary(callee_id, _, e) if self.is_method_call(expr) => {
self.walk_call(callee_id, expr.id, [e], in_out, loop_scopes);
ast::ExprUnary(_, e) if self.is_method_call(expr) => {
self.walk_call(expr.id, [e], in_out, loop_scopes);
}
ast::ExprTup(ref exprs) => {
self.walk_exprs(*exprs, in_out, loop_scopes);
}
ast::ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
self.walk_expr(l, in_out, loop_scopes);
let temp = in_out.to_owned();
self.walk_expr(r, in_out, loop_scopes);
join_bits(&self.dfcx.oper, temp, in_out);
}
ast::ExprIndex(_, l, r) |
ast::ExprBinary(_, _, l, r) => {
ast::ExprIndex(l, r) |
ast::ExprBinary(_, l, r) => {
self.walk_exprs([l, r], in_out, loop_scopes);
}
@ -617,7 +617,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
ast::ExprAddrOf(_, e) |
ast::ExprCast(e, _) |
ast::ExprUnary(_, _, e) |
ast::ExprUnary(_, e) |
ast::ExprParen(e) |
ast::ExprVstore(e, _) |
ast::ExprField(e, _, _) => {
@ -715,7 +715,6 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
}
fn walk_call(&mut self,
_callee_id: ast::NodeId,
call_id: ast::NodeId,
args: &[@ast::Expr],
in_out: &mut [uint],
@ -723,8 +722,8 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
self.walk_exprs(args, in_out, loop_scopes);
// FIXME(#6268) nested method calls
// self.merge_with_entry_set(callee_id, in_out);
// self.dfcx.apply_gen_kill(callee_id, in_out);
// self.merge_with_entry_set(in_out);
// self.dfcx.apply_gen_kill(in_out);
let return_ty = ty::node_id_to_type(self.tcx(), call_id);
let fails = ty::type_is_bot(return_ty);

View File

@ -92,10 +92,9 @@ impl MarkSymbolVisitor {
fn lookup_and_handle_method(&mut self, id: &ast::NodeId,
span: codemap::Span) {
let method_map = self.method_map.borrow();
match method_map.get().find(id) {
Some(&origin) => {
match origin {
match self.method_map.borrow().get().find(id) {
Some(method) => {
match method.origin {
typeck::MethodStatic(def_id) => {
match ty::provided_source(self.tcx, def_id) {
Some(p_did) => self.check_def_id(p_did),

View File

@ -65,7 +65,7 @@ impl EffectCheckVisitor {
fn check_str_index(&mut self, e: @ast::Expr) {
let base_type = match e.node {
ast::ExprIndex(_, base, _) => ty::node_id_to_type(self.tcx, base.id),
ast::ExprIndex(base, _) => ty::node_id_to_type(self.tcx, base.id),
_ => return
};
debug!("effect: checking index with base type {}",
@ -137,8 +137,8 @@ impl Visitor<()> for EffectCheckVisitor {
fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
match expr.node {
ast::ExprMethodCall(callee_id, _, _, _) => {
let base_type = ty::node_id_to_type(self.tcx, callee_id);
ast::ExprMethodCall(_, _, _) => {
let base_type = self.method_map.borrow().get().get(&expr.id).ty;
debug!("effect: method call case, base type is {}",
ppaux::ty_to_str(self.tcx, base_type));
if type_is_unsafe_function(base_type) {
@ -154,7 +154,7 @@ impl Visitor<()> for EffectCheckVisitor {
self.require_unsafe(expr.span, "call to unsafe function")
}
}
ast::ExprUnary(_, ast::UnDeref, base) => {
ast::ExprUnary(ast::UnDeref, base) => {
let base_type = ty::node_id_to_type(self.tcx, base.id);
debug!("effect: unary case, base type is {}",
ppaux::ty_to_str(self.tcx, base_type));
@ -166,7 +166,7 @@ impl Visitor<()> for EffectCheckVisitor {
_ => {}
}
}
ast::ExprAssign(base, _) | ast::ExprAssignOp(_, _, base, _) => {
ast::ExprAssign(base, _) | ast::ExprAssignOp(_, base, _) => {
self.check_str_index(base);
}
ast::ExprAddrOf(ast::MutMutable, base) => {

View File

@ -264,13 +264,14 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
debug!("kind::check_expr({})", expr_to_str(e));
// Handle any kind bounds on type parameters
let type_parameter_id = match e.get_callee_id() {
Some(callee_id) => callee_id,
None => e.id,
};
{
let method_map = cx.method_map.borrow();
let method = method_map.get().find(&e.id);
let node_type_substs = cx.tcx.node_type_substs.borrow();
let r = node_type_substs.get().find(&type_parameter_id);
let r = match method {
Some(method) => Some(&method.substs.tps),
None => node_type_substs.get().find(&e.id)
};
for ts in r.iter() {
let def_map = cx.tcx.def_map.borrow();
let type_param_defs = match e.node {
@ -285,9 +286,9 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
// Even though the callee_id may have been the id with
// node_type_substs, e.id is correct here.
match cx.method_map.borrow().get().find(&e.id) {
Some(origin) => {
ty::method_call_type_param_defs(cx.tcx, *origin)
match method {
Some(method) => {
ty::method_call_type_param_defs(cx.tcx, method.origin)
}
None => {
cx.tcx.sess.span_bug(e.span,
@ -306,13 +307,13 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
type_param_defs.repr(cx.tcx));
}
for (&ty, type_param_def) in ts.iter().zip(type_param_defs.iter()) {
check_typaram_bounds(cx, type_parameter_id, e.span, ty, type_param_def)
check_typaram_bounds(cx, e.span, ty, type_param_def)
}
}
}
match e.node {
ExprUnary(_, UnBox, interior) => {
ExprUnary(UnBox, interior) => {
let interior_type = ty::expr_ty(cx.tcx, interior);
let _ = check_durable(cx.tcx, interior_type, interior.span);
}
@ -373,7 +374,7 @@ fn check_ty(cx: &mut Context, aty: &Ty) {
let generics = ty::lookup_item_type(cx.tcx, did).generics;
let type_param_defs = generics.type_param_defs();
for (&ty, type_param_def) in ts.iter().zip(type_param_defs.iter()) {
check_typaram_bounds(cx, aty.id, aty.span, ty, type_param_def)
check_typaram_bounds(cx, aty.span, ty, type_param_def)
}
}
}
@ -400,11 +401,9 @@ pub fn check_builtin_bounds(cx: &Context,
}
pub fn check_typaram_bounds(cx: &Context,
_type_parameter_id: NodeId,
sp: Span,
ty: ty::t,
type_param_def: &ty::TypeParameterDef)
{
sp: Span,
ty: ty::t,
type_param_def: &ty::TypeParameterDef) {
check_builtin_bounds(cx,
ty,
type_param_def.bounds.builtin_bounds,

View File

@ -674,7 +674,7 @@ fn check_unused_casts(cx: &Context, e: &ast::Expr) {
fn check_type_limits(cx: &Context, e: &ast::Expr) {
return match e.node {
ast::ExprBinary(_, binop, l, r) => {
ast::ExprBinary(binop, l, r) => {
if is_comparison(binop) && !check_limits(cx.tcx, binop, l, r) {
cx.span_lint(TypeLimits, e.span,
"comparison is useless due to type limits");
@ -1176,7 +1176,7 @@ fn check_unnecessary_parens_expr(cx: &Context, e: &ast::Expr) {
ast::ExprMatch(head, _) => (head, "`match` head expression"),
ast::ExprRet(Some(value)) => (value, "`return` value"),
ast::ExprAssign(_, value) => (value, "assigned value"),
ast::ExprAssignOp(_, _, _, value) => (value, "assigned value"),
ast::ExprAssignOp(_, _, value) => (value, "assigned value"),
_ => return
};
check_unnecessary_parens_core(cx, value, msg);
@ -1263,8 +1263,8 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
_ => return
}
}
ast::ExprUnary(_, ast::UnUniq, _) |
ast::ExprUnary(_, ast::UnBox, _) => BoxAllocation,
ast::ExprUnary(ast::UnUniq, _) |
ast::ExprUnary(ast::UnBox, _) => BoxAllocation,
_ => return
};
@ -1411,10 +1411,9 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
}
}
ast::ExprMethodCall(..) => {
let method_map = cx.method_map.borrow();
match method_map.get().find(&e.id) {
Some(&origin) => {
match origin {
match cx.method_map.borrow().get().find(&e.id) {
Some(method) => {
match method.origin {
typeck::MethodStatic(def_id) => {
// If this implements a trait method, get def_id
// of the method inside trait definition.
@ -1531,7 +1530,7 @@ impl<'a> Visitor<()> for Context<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
match e.node {
ast::ExprUnary(_, ast::UnNeg, expr) => {
ast::ExprUnary(ast::UnNeg, expr) => {
// propagate negation, if the negation itself isn't negated
if self.negated_expr_id != e.id {
self.negated_expr_id = expr.id;

View File

@ -534,7 +534,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
visit::walk_expr(v, expr, this);
}
ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
ExprBinary(_, op, _, _) if ast_util::lazy_binop(op) => {
ExprBinary(op, _, _) if ast_util::lazy_binop(op) => {
this.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(v, expr, this);
}
@ -1179,7 +1179,7 @@ impl Liveness {
self.propagate_through_expr(r, succ)
}
ExprAssignOp(_, _, l, r) => {
ExprAssignOp(_, l, r) => {
// see comment on lvalues in
// propagate_through_lvalue_components()
let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ);
@ -1219,10 +1219,10 @@ impl Liveness {
self.propagate_through_expr(f, succ)
}
ExprMethodCall(callee_id, _, _, ref args) => {
ExprMethodCall(_, _, ref args) => {
// calling a method with bot return type means that the method
// will fail, and hence the successors can be ignored
let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.tcx, callee_id));
let t_ret = ty::node_id_to_type(self.tcx, expr.id);
let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
else {succ};
self.propagate_through_exprs(*args, succ)
@ -1232,7 +1232,7 @@ impl Liveness {
self.propagate_through_exprs(*exprs, succ)
}
ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
let r_succ = self.propagate_through_expr(r, succ);
let ln = self.live_node(expr.id, expr.span);
@ -1242,15 +1242,15 @@ impl Liveness {
self.propagate_through_expr(l, ln)
}
ExprIndex(_, l, r) |
ExprBinary(_, _, l, r) |
ExprIndex(l, r) |
ExprBinary(_, l, r) |
ExprBox(l, r) => {
self.propagate_through_exprs([l, r], succ)
}
ExprAddrOf(_, e) |
ExprCast(e, _) |
ExprUnary(_, _, e) |
ExprUnary(_, e) |
ExprParen(e) => {
self.propagate_through_expr(e, succ)
}
@ -1508,7 +1508,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
visit::walk_expr(this, expr, ());
}
ExprAssignOp(_, _, l, _) => {
ExprAssignOp(_, l, _) => {
this.check_lvalue(l);
visit::walk_expr(this, expr, ());

View File

@ -432,7 +432,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
let expr_ty = if_ok!(self.expr_ty(expr));
match expr.node {
ast::ExprUnary(_, ast::UnDeref, e_base) => {
ast::ExprUnary(ast::UnDeref, e_base) => {
if self.typer.is_method_call(expr.id) {
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
}
@ -450,7 +450,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
Ok(self.cat_field(expr, base_cmt, f_name, expr_ty))
}
ast::ExprIndex(_, base, _) => {
ast::ExprIndex(base, _) => {
if self.typer.is_method_call(expr.id) {
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
}

View File

@ -361,7 +361,7 @@ impl VisitContext {
}
}
ExprUnary(_, UnDeref, base) => { // *base
ExprUnary(UnDeref, base) => { // *base
if !self.use_overloaded_operator(expr, base, [])
{
// Moving out of *base moves out of base.
@ -369,12 +369,12 @@ impl VisitContext {
}
}
ExprField(base, _, _) => { // base.f
ExprField(base, _, _) => { // base.f
// Moving out of base.f moves out of base.
self.use_expr(base, comp_mode);
}
ExprIndex(_, lhs, rhs) => { // lhs[rhs]
ExprIndex(lhs, rhs) => { // lhs[rhs]
if !self.use_overloaded_operator(expr, lhs, [rhs])
{
self.use_expr(lhs, comp_mode);
@ -409,11 +409,11 @@ impl VisitContext {
}
}
self.use_expr(callee, mode);
self.use_fn_args(callee.id, *args);
self.use_fn_args(*args);
}
ExprMethodCall(callee_id, _, _, ref args) => { // callee.m(args)
self.use_fn_args(callee_id, *args);
ExprMethodCall(_, _, ref args) => { // callee.m(args)
self.use_fn_args(*args);
}
ExprStruct(_, ref fields, opt_with) => {
@ -521,14 +521,14 @@ impl VisitContext {
ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
ExprUnary(_, _, lhs) => {
ExprUnary(_, lhs) => {
if !self.use_overloaded_operator(expr, lhs, [])
{
self.consume_expr(lhs);
}
}
ExprBinary(_, _, lhs, rhs) => {
ExprBinary(_, lhs, rhs) => {
if !self.use_overloaded_operator(expr, lhs, [rhs])
{
self.consume_expr(lhs);
@ -555,7 +555,7 @@ impl VisitContext {
self.consume_expr(base);
}
ExprAssignOp(_, _, lhs, rhs) => {
ExprAssignOp(_, lhs, rhs) => {
// FIXME(#4712) --- Overloaded operators?
//
// if !self.use_overloaded_operator(expr, DoDerefArgs, lhs, [rhs])
@ -668,7 +668,6 @@ impl VisitContext {
}
pub fn use_fn_args(&mut self,
_: NodeId,
arg_exprs: &[@Expr]) {
//! Uses the argument expressions.
for arg_expr in arg_exprs.iter() {

View File

@ -785,7 +785,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
_ => {}
}
}
ast::ExprMethodCall(_, ident, _, ref args) => {
ast::ExprMethodCall(ident, _, ref args) => {
// see above
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
match ty::get(t).sty {
@ -796,9 +796,9 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
"method call not in \
method map");
}
Some(origin) => {
Some(method) => {
debug!("(privacy checking) checking impl method");
self.check_method(expr.span, origin, ident);
self.check_method(expr.span, method.origin, ident);
}
}
}

View File

@ -147,9 +147,8 @@ impl Visitor<()> for MarkSymbolVisitor {
}
}
ast::ExprMethodCall(..) => {
let method_map = self.method_map.borrow();
match method_map.get().find(&expr.id) {
Some(&typeck::method_static(def_id)) => {
match self.method_map.borrow().get().get(&expr.id).origin {
typeck::MethodStatic(def_id) => {
if is_local(def_id) {
if ReachableContext::
def_id_represents_local_inlined_item(
@ -168,11 +167,7 @@ impl Visitor<()> for MarkSymbolVisitor {
}
}
}
Some(_) => {}
None => {
self.tcx.sess.span_bug(expr.span,
"method call expression not in method map?!")
}
_ => {}
}
}
_ => {}

View File

@ -512,8 +512,8 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
// scopes, meaning that temporaries cannot outlive them.
// This ensures fixed size stacks.
ast::ExprBinary(_, ast::BiAnd, _, r) |
ast::ExprBinary(_, ast::BiOr, _, r) => {
ast::ExprBinary(ast::BiAnd, _, r) |
ast::ExprBinary(ast::BiOr, _, r) => {
// For shortcircuiting operators, mark the RHS as a terminating
// scope since it only executes conditionally.
visitor.region_maps.mark_as_terminating_scope(r.id);
@ -756,7 +756,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
visitor, subexpr, blk_id);
}
}
ast::ExprUnary(_, ast::UnUniq, subexpr) => {
ast::ExprUnary(ast::UnUniq, subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
}
ast::ExprCast(subexpr, _) |
@ -811,9 +811,9 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
match expr.node {
ast::ExprAddrOf(_, ref subexpr) |
ast::ExprUnary(_, ast::UnDeref, ref subexpr) |
ast::ExprUnary(ast::UnDeref, ref subexpr) |
ast::ExprField(ref subexpr, _, _) |
ast::ExprIndex(_, ref subexpr, _) |
ast::ExprIndex(ref subexpr, _) |
ast::ExprParen(ref subexpr) => {
let subexpr: &'a @Expr = subexpr; // FIXME(#11586)
expr = &**subexpr;

View File

@ -5257,7 +5257,7 @@ impl Resolver {
let traits = self.search_for_traits_containing_method(ident);
self.trait_map.insert(expr.id, traits);
}
ExprMethodCall(_, ident, _, _) => {
ExprMethodCall(ident, _, _) => {
debug!("(recording candidate traits for expr) recording \
traits for {}",
expr.id);

View File

@ -118,7 +118,7 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
match def {
ast::DefFn(did, _) |
ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id))
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id, false))
}
ast::DefStaticMethod(impl_did,
ast::FromTrait(trait_did),
@ -132,10 +132,10 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
assert!(ty::enum_variant_with_id(bcx.tcx(),
tid,
vid).args.len() > 0u);
fn_callee(bcx, trans_fn_ref(bcx, vid, ref_expr.id))
fn_callee(bcx, trans_fn_ref(bcx, vid, ref_expr.id, false))
}
ast::DefStruct(def_id) => {
fn_callee(bcx, trans_fn_ref(bcx, def_id, ref_expr.id))
fn_callee(bcx, trans_fn_ref(bcx, def_id, ref_expr.id, false))
}
ast::DefStatic(..) |
ast::DefArg(..) |
@ -158,16 +158,8 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
}
}
pub fn trans_fn_ref_to_callee<'a>(
bcx: &'a Block<'a>,
def_id: ast::DefId,
ref_id: ast::NodeId)
-> Callee<'a> {
Callee {bcx: bcx,
data: Fn(trans_fn_ref(bcx, def_id, ref_id))}
}
pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId,
ref_id: ast::NodeId, is_method: bool)
-> ValueRef {
/*!
*
@ -177,23 +169,22 @@ pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
let _icx = push_ctxt("trans_fn_ref");
let type_params = node_id_type_params(bcx, ref_id);
let type_params = node_id_type_params(bcx, ref_id, is_method);
let vtables = node_vtables(bcx, ref_id);
debug!("trans_fn_ref(def_id={}, ref_id={:?}, type_params={}, vtables={})",
def_id.repr(bcx.tcx()), ref_id, type_params.repr(bcx.tcx()),
vtables.repr(bcx.tcx()));
trans_fn_ref_with_vtables(bcx, def_id, ref_id, type_params, vtables)
trans_fn_ref_with_vtables(bcx, def_id, ref_id, is_method, type_params, vtables)
}
pub fn trans_fn_ref_with_vtables_to_callee<'a>(
bcx: &'a Block<'a>,
fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>,
def_id: ast::DefId,
ref_id: ast::NodeId,
type_params: &[ty::t],
vtables: Option<typeck::vtable_res>)
-> Callee<'a> {
Callee {bcx: bcx,
data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id,
data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id, false,
type_params, vtables))}
}
@ -243,6 +234,7 @@ pub fn trans_fn_ref_with_vtables(
bcx: &Block, //
def_id: ast::DefId, // def id of fn
ref_id: ast::NodeId, // node id of use of fn; may be zero if N/A
is_method: bool,
type_params: &[ty::t], // values for fn's ty params
vtables: Option<typeck::vtable_res>) // vtables for the call
-> ValueRef {
@ -388,7 +380,12 @@ pub fn trans_fn_ref_with_vtables(
if must_cast && ref_id != 0 {
// Monotype of the REFERENCE to the function (type params
// are subst'd)
let ref_ty = common::node_id_type(bcx, ref_id);
let ref_ty = if is_method {
let t = bcx.ccx().maps.method_map.borrow().get().get(&ref_id).ty;
monomorphize_type(bcx, t)
} else {
node_id_type(bcx, ref_id)
};
val = PointerCast(
bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to());
@ -461,41 +458,22 @@ pub fn trans_call<'a>(
}
pub fn trans_method_call<'a>(
in_cx: &'a Block<'a>,
bcx: &'a Block<'a>,
call_ex: &ast::Expr,
callee_id: ast::NodeId,
rcvr: &ast::Expr,
args: CallArgs,
dest: expr::Dest)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_ex={})", call_ex.repr(in_cx.tcx()));
debug!("trans_method_call(call_ex={})", call_ex.repr(bcx.tcx()));
let method_ty = bcx.ccx().maps.method_map.borrow().get().get(&call_ex.id).ty;
trans_call_inner(
in_cx,
bcx,
Some(common::expr_info(call_ex)),
node_id_type(in_cx, callee_id),
expr_ty(in_cx, call_ex),
monomorphize_type(bcx, method_ty),
expr_ty(bcx, call_ex),
|cx, arg_cleanup_scope| {
let origin_opt = {
let mut method_map = cx.ccx().maps.method_map.borrow_mut();
method_map.get().find_copy(&call_ex.id)
};
match origin_opt {
Some(origin) => {
debug!("origin for {}: {}",
call_ex.repr(in_cx.tcx()),
origin.repr(in_cx.tcx()));
meth::trans_method_callee(cx,
callee_id,
rcvr,
origin,
arg_cleanup_scope)
}
None => {
cx.tcx().sess.span_bug(call_ex.span, "method call expr wasn't in method map")
}
}
meth::trans_method_callee(cx, call_ex.id, rcvr, arg_cleanup_scope)
},
args,
Some(dest)).bcx

View File

@ -673,7 +673,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
// The exception handling personality function.
let def_id = common::langcall(pad_bcx, None, "", EhPersonalityLangItem);
let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0);
let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0, false);
// The only landing pad clause will be 'cleanup'
let llretval = build::LandingPad(pad_bcx, llretty, llpersonality, 1u);

View File

@ -807,9 +807,13 @@ pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t {
monomorphize_type(bcx, t)
}
pub fn node_id_type_params(bcx: &Block, id: ast::NodeId) -> ~[ty::t] {
pub fn node_id_type_params(bcx: &Block, id: ast::NodeId, is_method: bool) -> ~[ty::t] {
let tcx = bcx.tcx();
let params = ty::node_id_to_type_params(tcx, id);
let params = if is_method {
bcx.ccx().maps.method_map.borrow().get().get(&id).substs.tps.clone()
} else {
ty::node_id_to_type_params(tcx, id)
};
if !params.iter().all(|t| !ty::type_needs_infer(*t)) {
bcx.sess().bug(

View File

@ -310,7 +310,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
ast::ExprLit(lit) => {
(consts::const_lit(cx, e, (*lit).clone()), true)
}
ast::ExprBinary(_, b, e1, e2) => {
ast::ExprBinary(b, e1, e2) => {
let (te1, _) = const_expr(cx, e1, is_local);
let (te2, _) = const_expr(cx, e2, is_local);
@ -392,7 +392,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
},
}, true)
},
ast::ExprUnary(_, u, e) => {
ast::ExprUnary(u, e) => {
let (te, _) = const_expr(cx, e, is_local);
let ty = ty::expr_ty(cx.tcx, e);
let is_float = ty::type_is_fp(ty);
@ -429,7 +429,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
})
}
ast::ExprIndex(_, base, index) => {
ast::ExprIndex(base, index) => {
let bt = ty::expr_ty_adjusted(cx.tcx, base);
let (bv, inlineable) = const_expr(cx, base, is_local);
let iv = match const_eval::eval_const_expr(cx.tcx, index) {

View File

@ -2539,15 +2539,13 @@ fn populate_scope_map(cx: &CrateContext,
None => ()
},
ast::ExprUnary(node_id, _, sub_exp) => {
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
ast::ExprUnary(_, sub_exp) => {
walk_expr(cx, sub_exp, scope_stack, scope_map);
}
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().unwrap().scope_metadata);
ast::ExprAssignOp(_, lhs, rhs) |
ast::ExprIndex(lhs, rhs) |
ast::ExprBinary(_, lhs, rhs) => {
walk_expr(cx, lhs, scope_stack, scope_map);
walk_expr(cx, rhs, scope_stack, scope_map);
}
@ -2638,9 +2636,7 @@ fn populate_scope_map(cx: &CrateContext,
}
}
ast::ExprMethodCall(node_id, _, _, ref args) => {
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
ast::ExprMethodCall(_, _, ref args) => {
for arg_exp in args.iter() {
walk_expr(cx, *arg_exp, scope_stack, scope_map);
}

View File

@ -442,7 +442,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
ast::ExprField(base, ident, _) => {
trans_rec_field(bcx, base, ident)
}
ast::ExprIndex(_, base, idx) => {
ast::ExprIndex(base, idx) => {
trans_index(bcx, expr, base, idx)
}
ast::ExprVstore(contents, ast::ExprVstoreUniq) => {
@ -461,20 +461,17 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
return trans_boxed_expr(bcx, box_ty, contents, contents_ty, heap)
}
ast::ExprLit(lit) => trans_immediate_lit(bcx, expr, (*lit).clone()),
ast::ExprBinary(_, op, lhs, rhs) => {
ast::ExprBinary(op, lhs, rhs) => {
// if overloaded, would be RvalueDpsExpr
{
let method_map = bcx.ccx().maps.method_map.borrow();
assert!(!method_map.get().contains_key(&expr.id));
}
assert!(!bcx.ccx().maps.method_map.borrow().get().contains_key(&expr.id));
trans_binary(bcx, expr, op, lhs, rhs)
}
ast::ExprUnary(_, ast::UnDeref, base) => {
ast::ExprUnary(ast::UnDeref, base) => {
let basedatum = unpack_datum!(bcx, trans(bcx, base));
deref_once(bcx, expr, basedatum, 0)
}
ast::ExprUnary(_, op, x) => {
ast::ExprUnary(op, x) => {
trans_unary_datum(bcx, expr, op, x)
}
ast::ExprAddrOf(_, x) => {
@ -698,8 +695,8 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
src_datum.store_to(bcx, dst_datum.val)
}
}
ast::ExprAssignOp(callee_id, op, dst, src) => {
trans_assign_op(bcx, expr, callee_id, op, dst, src)
ast::ExprAssignOp(op, dst, src) => {
trans_assign_op(bcx, expr, op, dst, src)
}
ast::ExprInlineAsm(ref a) => {
asm::trans_inline_asm(bcx, a)
@ -780,26 +777,24 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
closure::trans_expr_fn(bcx, sigil, decl, body, expr.id, dest)
}
ast::ExprCall(f, ref args) => {
callee::trans_call(bcx, expr, f,
callee::ArgExprs(*args), expr.id, dest)
callee::trans_call(bcx, expr, f, callee::ArgExprs(*args), expr.id, dest)
}
ast::ExprMethodCall(callee_id, _, _, ref args) => {
callee::trans_method_call(bcx, expr, callee_id, args[0],
callee::ArgExprs(*args), dest)
ast::ExprMethodCall(_, _, ref args) => {
callee::trans_method_call(bcx, expr, args[0], callee::ArgExprs(*args), dest)
}
ast::ExprBinary(callee_id, _, lhs, rhs) => {
ast::ExprBinary(_, lhs, rhs) => {
// if not overloaded, would be RvalueDatumExpr
trans_overloaded_op(bcx, expr, callee_id, lhs,
trans_overloaded_op(bcx, expr, lhs,
Some(&*rhs), expr_ty(bcx, expr), dest)
}
ast::ExprUnary(callee_id, _, subexpr) => {
ast::ExprUnary(_, subexpr) => {
// if not overloaded, would be RvalueDatumExpr
trans_overloaded_op(bcx, expr, callee_id, subexpr,
trans_overloaded_op(bcx, expr, subexpr,
None, expr_ty(bcx, expr), dest)
}
ast::ExprIndex(callee_id, base, idx) => {
ast::ExprIndex(base, idx) => {
// if not overloaded, would be RvalueDatumExpr
trans_overloaded_op(bcx, expr, callee_id, base,
trans_overloaded_op(bcx, expr, base,
Some(&*idx), expr_ty(bcx, expr), dest)
}
ast::ExprCast(val, _) => {
@ -815,8 +810,8 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
}
}
}
ast::ExprAssignOp(callee_id, op, dst, src) => {
trans_assign_op(bcx, expr, callee_id, op, dst, src)
ast::ExprAssignOp(op, dst, src) => {
trans_assign_op(bcx, expr, op, dst, src)
}
ast::ExprBox(_, contents) => {
// Special case for `Gc<T>` for now. The other case, for unique
@ -851,7 +846,7 @@ fn trans_def_dps_unadjusted<'a>(
let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
if variant_info.args.len() > 0u {
// N-ary variant.
let llfn = callee::trans_fn_ref(bcx, vid, ref_expr.id);
let llfn = callee::trans_fn_ref(bcx, vid, ref_expr.id, false);
Store(bcx, llfn, lldest);
return bcx;
} else {
@ -884,15 +879,14 @@ fn trans_def_dps_unadjusted<'a>(
fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
ref_expr: &ast::Expr,
def: ast::Def) -> DatumBlock<'a, Expr>
{
def: ast::Def) -> DatumBlock<'a, Expr> {
let _icx = push_ctxt("trans_def_datum_unadjusted");
let llfn = match def {
ast::DefFn(did, _) |
ast::DefStruct(did) | ast::DefVariant(_, did, _) |
ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
callee::trans_fn_ref(bcx, did, ref_expr.id)
callee::trans_fn_ref(bcx, did, ref_expr.id, false)
}
ast::DefStaticMethod(impl_did, ast::FromTrait(trait_did), _) => {
meth::trans_static_method_callee(bcx, impl_did,
@ -1496,26 +1490,20 @@ fn trans_binary<'a>(
fn trans_overloaded_op<'a, 'b>(
bcx: &'a Block<'a>,
expr: &ast::Expr,
callee_id: ast::NodeId,
rcvr: &'b ast::Expr,
arg: Option<&'b ast::Expr>,
ret_ty: ty::t,
dest: Dest)
-> &'a Block<'a> {
let origin = {
let method_map = bcx.ccx().maps.method_map.borrow();
method_map.get().get_copy(&expr.id)
};
let fty = node_id_type(bcx, callee_id);
let method_ty = bcx.ccx().maps.method_map.borrow().get().get(&expr.id).ty;
callee::trans_call_inner(bcx,
Some(expr_info(expr)),
fty,
monomorphize_type(bcx, method_ty),
ret_ty,
|bcx, arg_cleanup_scope| {
meth::trans_method_callee(bcx,
callee_id,
expr.id,
rcvr,
origin,
arg_cleanup_scope)
},
callee::ArgAutorefSecond(rcvr, arg),
@ -1666,7 +1654,6 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
fn trans_assign_op<'a>(
bcx: &'a Block<'a>,
expr: &ast::Expr,
_callee_id: ast::NodeId,
op: ast::BinOp,
dst: &ast::Expr,
src: @ast::Expr)

View File

@ -93,21 +93,29 @@ pub fn trans_method(ccx: @CrateContext, method: &ast::Method,
pub fn trans_method_callee<'a>(
bcx: &'a Block<'a>,
callee_id: ast::NodeId,
expr_id: ast::NodeId,
this: &ast::Expr,
origin: typeck::method_origin,
arg_cleanup_scope: cleanup::ScopeId)
-> Callee<'a> {
let _icx = push_ctxt("meth::trans_method_callee");
debug!("trans_method_callee(callee_id={:?}, origin={})",
callee_id, origin.repr(bcx.tcx()));
let (origin, method_ty) = match bcx.ccx().maps.method_map
.borrow().get().find(&expr_id) {
Some(method) => {
debug!("trans_method_callee(expr_id={:?}, method={})",
expr_id, method.repr(bcx.tcx()));
(method.origin, method.ty)
}
None => {
bcx.tcx().sess.span_bug(this.span, "method call expr wasn't in method map")
}
};
match origin {
typeck::MethodStatic(did) => {
Callee {
bcx: bcx,
data: Fn(callee::trans_fn_ref(bcx, did, callee_id))
data: Fn(callee::trans_fn_ref(bcx, did, expr_id, true))
}
}
typeck::MethodParam(typeck::MethodParam {
@ -123,7 +131,7 @@ pub fn trans_method_callee<'a>(
trait_id);
let vtbl = find_vtable(bcx.tcx(), substs, p, b);
trans_monomorphized_callee(bcx, callee_id,
trans_monomorphized_callee(bcx, expr_id,
trait_id, off, vtbl)
}
// how to get rid of this?
@ -133,7 +141,7 @@ pub fn trans_method_callee<'a>(
typeck::MethodObject(ref mt) => {
trans_trait_callee(bcx,
callee_id,
monomorphize_type(bcx, method_ty),
mt.real_index,
this,
arg_cleanup_scope)
@ -144,16 +152,16 @@ pub fn trans_method_callee<'a>(
pub fn trans_static_method_callee(bcx: &Block,
method_id: ast::DefId,
trait_id: ast::DefId,
callee_id: ast::NodeId)
expr_id: ast::NodeId)
-> ValueRef {
let _icx = push_ctxt("meth::trans_static_method_callee");
let ccx = bcx.ccx();
debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \
callee_id={:?})",
expr_id={:?})",
method_id,
ty::item_path_str(bcx.tcx(), trait_id),
callee_id);
expr_id);
let _indenter = indenter();
ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trait_id);
@ -188,13 +196,10 @@ pub fn trans_static_method_callee(bcx: &Block,
} else {
csearch::get_item_path(bcx.tcx(), method_id).last().unwrap().name()
};
debug!("trans_static_method_callee: method_id={:?}, callee_id={:?}, \
name={}", method_id, callee_id, token::get_name(mname));
debug!("trans_static_method_callee: method_id={:?}, expr_id={:?}, \
name={}", method_id, expr_id, token::get_name(mname));
let vtbls = {
let vtable_map = ccx.maps.vtable_map.borrow();
vtable_map.get().get_copy(&callee_id)
};
let vtbls = ccx.maps.vtable_map.borrow().get().get_copy(&expr_id);
let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls);
match vtbls[bound_index][0] {
@ -204,14 +209,14 @@ pub fn trans_static_method_callee(bcx: &Block,
let mth_id = method_with_name(ccx, impl_did, mname);
let (callee_substs, callee_origins) =
combine_impl_and_methods_tps(
bcx, mth_id, callee_id,
bcx, mth_id, expr_id, false,
*rcvr_substs, rcvr_origins);
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, callee_id,
callee_substs,
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, expr_id,
false, callee_substs,
Some(callee_origins));
let callee_ty = node_id_type(bcx, callee_id);
let callee_ty = node_id_type(bcx, expr_id);
let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
PointerCast(bcx, llfn, llty)
}
@ -246,13 +251,13 @@ pub fn method_with_name(ccx: &CrateContext,
}
fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
callee_id: ast::NodeId,
expr_id: ast::NodeId,
trait_id: ast::DefId,
n_method: uint,
vtbl: typeck::vtable_origin)
-> Callee<'a> {
let _icx = push_ctxt("meth::trans_monomorphized_callee");
return match vtbl {
match vtbl {
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
let ccx = bcx.ccx();
let mname = ty::trait_method(ccx.tcx, trait_id, n_method).ident;
@ -262,13 +267,14 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
// those from the impl and those from the method:
let (callee_substs, callee_origins) =
combine_impl_and_methods_tps(
bcx, mth_id, callee_id,
bcx, mth_id, expr_id, true,
*rcvr_substs, rcvr_origins);
// translate the function
let llfn = trans_fn_ref_with_vtables(bcx,
mth_id,
callee_id,
expr_id,
true,
callee_substs,
Some(callee_origins));
@ -277,16 +283,16 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
typeck::vtable_param(..) => {
fail!("vtable_param left in monomorphized function's vtable substs");
}
};
}
}
pub fn combine_impl_and_methods_tps(bcx: &Block,
mth_did: ast::DefId,
callee_id: ast::NodeId,
rcvr_substs: &[ty::t],
rcvr_origins: typeck::vtable_res)
-> (~[ty::t], typeck::vtable_res) {
fn combine_impl_and_methods_tps(bcx: &Block,
mth_did: ast::DefId,
expr_id: ast::NodeId,
is_method: bool,
rcvr_substs: &[ty::t],
rcvr_origins: typeck::vtable_res)
-> (~[ty::t], typeck::vtable_res) {
/*!
*
* Creates a concatenated set of substitutions which includes
@ -307,7 +313,7 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
let ccx = bcx.ccx();
let method = ty::method(ccx.tcx, mth_did);
let n_m_tps = method.generics.type_param_defs().len();
let node_substs = node_id_type_params(bcx, callee_id);
let node_substs = node_id_type_params(bcx, expr_id, is_method);
debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx));
let ty_substs
= vec::append(rcvr_substs.to_owned(),
@ -319,7 +325,7 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
// Now, do the same work for the vtables. The vtables might not
// exist, in which case we need to make them.
let r_m_origins = match node_vtables(bcx, callee_id) {
let r_m_origins = match node_vtables(bcx, expr_id) {
Some(vt) => vt,
None => @vec::from_elem(node_substs.len(), @~[])
};
@ -327,11 +333,11 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
= @vec::append(rcvr_origins.to_owned(),
r_m_origins.tailn(r_m_origins.len() - n_m_tps));
return (ty_substs, vtables);
(ty_substs, vtables)
}
fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
callee_id: ast::NodeId,
method_ty: ty::t,
n_method: uint,
self_expr: &ast::Expr,
arg_cleanup_scope: cleanup::ScopeId)
@ -371,8 +377,7 @@ fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
self_datum.val
};
let callee_ty = node_id_type(bcx, callee_id);
trans_trait_callee_from_llval(bcx, callee_ty, n_method, llval)
trans_trait_callee_from_llval(bcx, method_ty, n_method, llval)
}
pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
@ -540,7 +545,7 @@ fn emit_vtable_methods(bcx: &Block,
token::get_ident(ident));
C_null(Type::nil().ptr_to())
} else {
trans_fn_ref_with_vtables(bcx, m_id, 0, substs, Some(vtables))
trans_fn_ref_with_vtables(bcx, m_id, 0, false, substs, Some(vtables))
}
})
}

View File

@ -33,8 +33,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
vtables: Option<typeck::vtable_res>,
self_vtables: Option<typeck::vtable_param_res>,
ref_id: Option<ast::NodeId>)
-> (ValueRef, bool)
{
-> (ValueRef, bool) {
debug!("monomorphic_fn(\
fn_id={}, \
real_substs={}, \
@ -280,7 +279,6 @@ pub fn monomorphic_fn(ccx: @CrateContext,
ast_map::NodeStmt(..) |
ast_map::NodeArg(..) |
ast_map::NodeBlock(..) |
ast_map::NodeCalleeScope(..) |
ast_map::NodeLocal(..) => {
ccx.tcx.sess.bug(format!("can't monomorphize a {:?}", map_node))
}

View File

@ -3372,7 +3372,7 @@ pub fn expr_kind(tcx: ctxt,
}
}
ast::ExprUnary(_, ast::UnDeref, _) |
ast::ExprUnary(ast::UnDeref, _) |
ast::ExprField(..) |
ast::ExprIndex(..) => {
LvalueExpr

View File

@ -89,6 +89,7 @@ use middle::typeck::check::{structurally_resolved_type};
use middle::typeck::check::vtable;
use middle::typeck::check;
use middle::typeck::infer;
use middle::typeck::MethodCallee;
use middle::typeck::{MethodOrigin, MethodParam};
use middle::typeck::{MethodStatic, MethodObject};
use middle::typeck::{param_numbered, param_self, param_index};
@ -101,7 +102,7 @@ use collections::HashSet;
use std::result;
use std::vec;
use syntax::ast::{DefId, SelfValue, SelfRegion};
use syntax::ast::{SelfUniq, SelfStatic, NodeId};
use syntax::ast::{SelfUniq, SelfStatic};
use syntax::ast::{MutMutable, MutImmutable};
use syntax::ast;
use syntax::parse::token;
@ -124,20 +125,17 @@ pub fn lookup(
// In a call `a.b::<X, Y, ...>(...)`:
expr: &ast::Expr, // The expression `a.b(...)`.
self_expr: &ast::Expr, // The expression `a`.
callee_id: NodeId, /* Where to store `a.b`'s type,
* also the scope of the call */
m_name: ast::Name, // The name `b`.
self_ty: ty::t, // The type of `a`.
supplied_tps: &[ty::t], // The list of types X, Y, ... .
deref_args: check::DerefArgs, // Whether we autopointer first.
check_traits: CheckTraitsFlag, // Whether we check traits only.
autoderef_receiver: AutoderefReceiverFlag)
-> Option<method_origin> {
-> Option<MethodCallee> {
let lcx = LookupContext {
fcx: fcx,
expr: expr,
self_expr: self_expr,
callee_id: callee_id,
m_name: m_name,
supplied_tps: supplied_tps,
impl_dups: @RefCell::new(HashSet::new()),
@ -173,19 +171,16 @@ pub fn lookup_in_trait(
// In a call `a.b::<X, Y, ...>(...)`:
expr: &ast::Expr, // The expression `a.b(...)`.
self_expr: &ast::Expr, // The expression `a`.
callee_id: NodeId, /* Where to store `a.b`'s type,
* also the scope of the call */
m_name: ast::Name, // The name `b`.
trait_did: DefId, // The trait to limit the lookup to.
self_ty: ty::t, // The type of `a`.
supplied_tps: &[ty::t], // The list of types X, Y, ... .
autoderef_receiver: AutoderefReceiverFlag)
-> Option<method_origin> {
-> Option<MethodCallee> {
let lcx = LookupContext {
fcx: fcx,
expr: expr,
self_expr: self_expr,
callee_id: callee_id,
m_name: m_name,
supplied_tps: supplied_tps,
impl_dups: @RefCell::new(HashSet::new()),
@ -210,7 +205,6 @@ pub struct LookupContext<'a> {
fcx: @FnCtxt,
expr: &'a ast::Expr,
self_expr: &'a ast::Expr,
callee_id: NodeId,
m_name: ast::Name,
supplied_tps: &'a [ty::t],
impl_dups: @RefCell<HashSet<DefId>>,
@ -248,7 +242,7 @@ enum RcvrMatchCondition {
}
impl<'a> LookupContext<'a> {
fn search(&self, self_ty: ty::t) -> Option<method_origin> {
fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
let mut self_ty = self_ty;
let mut autoderefs = 0;
loop {
@ -636,7 +630,7 @@ impl<'a> LookupContext<'a> {
fn search_for_autoderefd_method(&self,
self_ty: ty::t,
autoderefs: uint)
-> Option<method_origin> {
-> Option<MethodCallee> {
let (self_ty, autoadjust) =
self.consider_reborrow(self_ty, autoderefs);
match self.search_for_method(self_ty) {
@ -732,7 +726,7 @@ impl<'a> LookupContext<'a> {
fn search_for_autosliced_method(&self,
self_ty: ty::t,
autoderefs: uint)
-> Option<method_origin> {
-> Option<MethodCallee> {
/*!
*
* Searches for a candidate by converting things like
@ -807,7 +801,7 @@ impl<'a> LookupContext<'a> {
}
fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
-> Option<method_origin> {
-> Option<MethodCallee> {
/*!
*
* Converts any type `T` to `&M T` where `M` is an
@ -843,7 +837,7 @@ impl<'a> LookupContext<'a> {
autoderefs: uint,
mutbls: &[ast::Mutability],
mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
-> Option<method_origin> {
-> Option<MethodCallee> {
// This is hokey. We should have mutability inference as a
// variable. But for now, try &const, then &, then &mut:
let region =
@ -867,7 +861,7 @@ impl<'a> LookupContext<'a> {
}
fn search_for_method(&self, rcvr_ty: ty::t)
-> Option<method_origin> {
-> Option<MethodCallee> {
debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
let _indenter = indenter();
@ -899,7 +893,7 @@ impl<'a> LookupContext<'a> {
fn consider_candidates(&self,
rcvr_ty: ty::t,
candidates: &mut ~[Candidate])
-> Option<method_origin> {
-> Option<MethodCallee> {
// FIXME(pcwalton): Do we need to clone here?
let relevant_candidates: ~[Candidate] =
candidates.iter().map(|c| (*c).clone()).
@ -970,7 +964,7 @@ impl<'a> LookupContext<'a> {
}
fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
-> method_origin {
-> MethodCallee {
// This method performs two sets of substitutions, one after the other:
// 1. Substitute values for any type/lifetime parameters from the impl and
// method declaration into the method type. This is the function type
@ -1079,9 +1073,11 @@ impl<'a> LookupContext<'a> {
}
}
self.fcx.write_ty(self.callee_id, fty);
self.fcx.write_substs(self.callee_id, all_substs);
candidate.origin
MethodCallee {
origin: candidate.origin,
ty: fty,
substs: all_substs
}
}
fn construct_transformed_self_ty_for_object(

View File

@ -1088,8 +1088,7 @@ impl FnCtxt {
}
pub fn node_ty(&self, id: ast::NodeId) -> ty::t {
let node_types = self.inh.node_types.borrow();
match node_types.get().find(&id) {
match self.inh.node_types.borrow().get().find(&id) {
Some(&t) => t,
None => {
self.tcx().sess.bug(
@ -1100,9 +1099,20 @@ impl FnCtxt {
}
}
pub fn method_ty(&self, id: ast::NodeId) -> ty::t {
match self.inh.method_map.borrow().get().find(&id) {
Some(method) => method.ty,
None => {
self.tcx().sess.bug(
format!("no method entry for node {}: {} in fcx {}",
id, self.tcx().map.node_to_str(id),
self.tag()));
}
}
}
pub fn node_ty_substs(&self, id: ast::NodeId) -> ty::substs {
let mut node_type_substs = self.inh.node_type_substs.borrow_mut();
match node_type_substs.get().find(&id) {
match self.inh.node_type_substs.borrow().get().find(&id) {
Some(ts) => (*ts).clone(),
None => {
self.tcx().sess.bug(
@ -1113,6 +1123,18 @@ impl FnCtxt {
}
}
pub fn method_ty_substs(&self, id: ast::NodeId) -> ty::substs {
match self.inh.method_map.borrow().get().find(&id) {
Some(method) => method.substs.clone(),
None => {
self.tcx().sess.bug(
format!("no method entry for node {}: {} in fcx {}",
id, self.tcx().map.node_to_str(id),
self.tag()));
}
}
}
pub fn opt_node_ty_substs(&self,
id: ast::NodeId,
f: |&ty::substs| -> bool)
@ -1776,7 +1798,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// A generic function for doing all of the checking for call expressions
fn check_call(fcx: @FnCtxt,
callee_id: ast::NodeId,
call_expr: &ast::Expr,
f: &ast::Expr,
args: &[@ast::Expr]) {
@ -1787,13 +1808,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Store the type of `f` as the type of the callee
let fn_ty = fcx.expr_ty(f);
// FIXME(#6273) should write callee type AFTER regions have
// been subst'd. However, it is awkward to deal with this
// now. Best thing would I think be to just have a separate
// "callee table" that contains the FnSig and not a general
// purpose ty::t
fcx.write_ty(callee_id, fn_ty);
// Extract the function signature from `in_fty`.
let fn_sty = structure_of(fcx, f.span, fn_ty);
@ -1834,7 +1848,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Checks a method call.
fn check_method_call(fcx: @FnCtxt,
callee_id: ast::NodeId,
expr: &ast::Expr,
method_name: ast::Ident,
args: &[@ast::Expr],
@ -1848,20 +1861,16 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.expr_ty(rcvr));
let tps = tps.map(|&ast_ty| fcx.to_ty(ast_ty));
match method::lookup(fcx,
expr,
rcvr,
callee_id,
method_name.name,
expr_t,
tps,
DontDerefArgs,
CheckTraitsAndInherentMethods,
AutoderefReceiver) {
Some(ref entry) => {
let method_map = fcx.inh.method_map;
let mut method_map = method_map.borrow_mut();
method_map.get().insert(expr.id, (*entry));
let fn_ty = match method::lookup(fcx, expr, rcvr,
method_name.name,
expr_t, tps,
DontDerefArgs,
CheckTraitsAndInherentMethods,
AutoderefReceiver) {
Some(method) => {
let method_ty = method.ty;
fcx.inh.method_map.borrow_mut().get().insert(expr.id, method);
method_ty
}
None => {
debug!("(checking method call) failing expr is {}", expr.id);
@ -1877,12 +1886,11 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Add error type for the result
fcx.write_error(expr.id);
fcx.write_error(callee_id);
ty::mk_err()
}
}
};
// Call the generic checker.
let fn_ty = fcx.node_ty(callee_id);
let ret_ty = check_method_argument_types(fcx, expr.span,
fn_ty, expr, args,
DontDerefArgs);
@ -1932,7 +1940,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
}
fn lookup_op_method(fcx: @FnCtxt,
callee_id: ast::NodeId,
op_ex: &ast::Expr,
self_t: ty::t,
opname: ast::Name,
@ -1940,18 +1947,17 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
args: &[@ast::Expr],
autoderef_receiver: AutoderefReceiverFlag,
unbound_method: ||) -> ty::t {
let origin = match trait_did {
let method = match trait_did {
Some(trait_did) => {
method::lookup_in_trait(fcx, op_ex, args[0], callee_id, opname,
trait_did, self_t, [], autoderef_receiver)
method::lookup_in_trait(fcx, op_ex, args[0], opname, trait_did,
self_t, [], autoderef_receiver)
}
None => None
};
match origin {
Some(origin) => {
let method_ty = fcx.node_ty(callee_id);
let method_map = fcx.inh.method_map;
method_map.borrow_mut().get().insert(op_ex.id, origin);
match method {
Some(method) => {
let method_ty = method.ty;
fcx.inh.method_map.borrow_mut().get().insert(op_ex.id, method);
check_method_argument_types(fcx, op_ex.span,
method_ty, op_ex,
args, DoDerefArgs)
@ -1971,7 +1977,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// could be either an expr_binop or an expr_assign_binop
fn check_binop(fcx: @FnCtxt,
callee_id: ast::NodeId,
expr: &ast::Expr,
op: ast::BinOp,
lhs: @ast::Expr,
@ -2023,7 +2028,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Check for overloaded operators if not an assignment.
let result_t = if is_binop_assignment == SimpleBinop {
check_user_binop(fcx, callee_id, expr, lhs, lhs_t, op, rhs)
check_user_binop(fcx, expr, lhs, lhs_t, op, rhs)
} else {
fcx.type_error_message(expr.span,
|actual| {
@ -2045,7 +2050,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
}
fn check_user_binop(fcx: @FnCtxt,
callee_id: ast::NodeId,
ex: &ast::Expr,
lhs_expr: @ast::Expr,
lhs_resolved_t: ty::t,
@ -2075,7 +2079,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
return ty::mk_err();
}
};
lookup_op_method(fcx, callee_id, ex, lhs_resolved_t, token::intern(name),
lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
fcx.type_error_message(ex.span, |actual| {
format!("binary operation `{}` cannot be applied to type `{}`",
@ -2085,14 +2089,13 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
}
fn check_user_unop(fcx: @FnCtxt,
callee_id: ast::NodeId,
op_str: &str,
mname: &str,
trait_did: Option<ast::DefId>,
ex: &ast::Expr,
rhs_expr: @ast::Expr,
rhs_t: ty::t) -> ty::t {
lookup_op_method(fcx, callee_id, ex, rhs_t, token::intern(mname),
lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
trait_did, [rhs_expr], DontAutoderefReceiver, || {
fcx.type_error_message(ex.span, |actual| {
format!("cannot apply unary operator `{}` to type `{}`", op_str, actual)
@ -2264,7 +2267,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
match method::lookup(fcx,
expr,
base,
expr.id,
field,
expr_t,
tps,
@ -2620,8 +2622,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
let typ = check_lit(fcx, lit);
fcx.write_ty(id, typ);
}
ast::ExprBinary(callee_id, op, lhs, rhs) => {
check_binop(fcx, callee_id, expr, op, lhs, rhs, SimpleBinop);
ast::ExprBinary(op, lhs, rhs) => {
check_binop(fcx, expr, op, lhs, rhs, SimpleBinop);
let lhs_ty = fcx.expr_ty(lhs);
let rhs_ty = fcx.expr_ty(rhs);
@ -2634,8 +2636,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_bot(id);
}
}
ast::ExprAssignOp(callee_id, op, lhs, rhs) => {
check_binop(fcx, callee_id, expr, op, lhs, rhs, BinopAssignment);
ast::ExprAssignOp(op, lhs, rhs) => {
check_binop(fcx, expr, op, lhs, rhs, BinopAssignment);
let lhs_t = fcx.expr_ty(lhs);
let result_t = fcx.expr_ty(expr);
@ -2654,7 +2656,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_nil(expr.id);
}
}
ast::ExprUnary(callee_id, unop, oprnd) => {
ast::ExprUnary(unop, oprnd) => {
let exp_inner = unpack_expected(fcx, expected, |sty| {
match unop {
ast::UnBox | ast::UnUniq => match *sty {
@ -2710,7 +2712,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
oprnd_t);
if !(ty::type_is_integral(oprnd_t) ||
ty::get(oprnd_t).sty == ty::ty_bool) {
oprnd_t = check_user_unop(fcx, callee_id, "!", "not",
oprnd_t = check_user_unop(fcx, "!", "not",
tcx.lang_items.not_trait(),
expr, oprnd, oprnd_t);
}
@ -2720,7 +2722,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
oprnd_t);
if !(ty::type_is_integral(oprnd_t) ||
ty::type_is_fp(oprnd_t)) {
oprnd_t = check_user_unop(fcx, callee_id, "-", "neg",
oprnd_t = check_user_unop(fcx, "-", "neg",
tcx.lang_items.neg_trait(),
expr, oprnd, oprnd_t);
}
@ -2883,7 +2885,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_ty(id, fcx.node_ty(b.id));
}
ast::ExprCall(f, ref args) => {
check_call(fcx, expr.id, expr, f, *args);
check_call(fcx, expr, f, *args);
let f_ty = fcx.expr_ty(f);
let (args_bot, args_err) = args.iter().fold((false, false),
|(rest_bot, rest_err), a| {
@ -2898,8 +2900,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_bot(id);
}
}
ast::ExprMethodCall(callee_id, ident, ref tps, ref args) => {
check_method_call(fcx, callee_id, expr, ident, *args, *tps);
ast::ExprMethodCall(ident, ref tps, ref args) => {
check_method_call(fcx, expr, ident, *args, *tps);
let arg_tys = args.map(|a| fcx.expr_ty(*a));
let (args_bot, args_err) = arg_tys.iter().fold((false, false),
|(rest_bot, rest_err), a| {
@ -3100,7 +3102,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
ast::ExprField(base, field, ref tys) => {
check_field(fcx, expr, base, field.name, *tys);
}
ast::ExprIndex(callee_id, base, idx) => {
ast::ExprIndex(base, idx) => {
check_expr(fcx, base);
check_expr(fcx, idx);
let raw_base_t = fcx.expr_ty(base);
@ -3133,7 +3135,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
None);
};
let ret_ty = lookup_op_method(fcx,
callee_id,
expr,
resolved,
token::intern("index"),

View File

@ -226,6 +226,12 @@ impl Rcx {
self.resolve_type(t)
}
/// Try to resolve the callee type for the given method call.
pub fn resolve_method_type(&mut self, id: ast::NodeId) -> ty::t {
let t = self.fcx.method_ty(id);
self.resolve_type(t)
}
/// Try to resolve the type for the given node.
pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> ty::t {
let ty_unadjusted = self.resolve_node_type(expr.id);
@ -378,10 +384,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
debug!("regionck::visit_expr(e={}, repeating_scope={:?})",
expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
let has_method_map = {
let method_map = rcx.fcx.inh.method_map;
method_map.get().contains_key(&expr.id)
};
let has_method_map = rcx.fcx.inh.method_map.get().contains_key(&expr.id);
// Check any autoderefs or autorefs that appear.
{
@ -434,13 +437,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
match expr.node {
ast::ExprCall(callee, ref args) => {
constrain_callee(rcx, callee.id, expr, callee);
constrain_call(rcx, callee.id, expr, None, *args, false);
constrain_call(rcx, Some(callee.id), expr, None, *args, false);
visit::walk_expr(rcx, expr, ());
}
ast::ExprMethodCall(callee_id, _, _, ref args) => {
constrain_call(rcx, callee_id, expr, Some(args[0]),
ast::ExprMethodCall(_, _, ref args) => {
constrain_call(rcx, None, expr, Some(args[0]),
args.slice_from(1), false);
visit::walk_expr(rcx, expr, ());
@ -451,9 +454,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ());
}
ast::ExprAssignOp(callee_id, _, lhs, rhs) => {
ast::ExprAssignOp(_, lhs, rhs) => {
if has_method_map {
constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true);
constrain_call(rcx, None, expr, Some(lhs), [rhs], true);
}
adjust_borrow_kind_for_assignment_lhs(rcx, lhs);
@ -461,25 +464,25 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ());
}
ast::ExprIndex(callee_id, lhs, rhs) |
ast::ExprBinary(callee_id, _, lhs, rhs) if has_method_map => {
ast::ExprIndex(lhs, rhs) |
ast::ExprBinary(_, lhs, rhs) if has_method_map => {
// As `expr_method_call`, but the call is via an
// overloaded op. Note that we (sadly) currently use an
// implicit "by ref" sort of passing style here. This
// should be converted to an adjustment!
constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true);
constrain_call(rcx, None, expr, Some(lhs), [rhs], true);
visit::walk_expr(rcx, expr, ());
}
ast::ExprUnary(callee_id, _, lhs) if has_method_map => {
ast::ExprUnary(_, lhs) if has_method_map => {
// As above.
constrain_call(rcx, callee_id, expr, Some(lhs), [], true);
constrain_call(rcx, None, expr, Some(lhs), [], true);
visit::walk_expr(rcx, expr, ());
}
ast::ExprUnary(_, ast::UnDeref, base) => {
ast::ExprUnary(ast::UnDeref, base) => {
// For *a, the lifetime of a must enclose the deref
let base_ty = rcx.resolve_node_type(base.id);
constrain_derefs(rcx, expr, 1, base_ty);
@ -487,7 +490,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
visit::walk_expr(rcx, expr, ());
}
ast::ExprIndex(_, vec_expr, _) => {
ast::ExprIndex(vec_expr, _) => {
// For a[b], the lifetime of a must enclose the deref
let vec_type = rcx.resolve_expr_type_adjusted(vec_expr);
constrain_index(rcx, expr, vec_type);
@ -711,8 +714,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
fn constrain_callee(rcx: &mut Rcx,
callee_id: ast::NodeId,
call_expr: &ast::Expr,
callee_expr: &ast::Expr)
{
callee_expr: &ast::Expr) {
let call_region = ty::ReScope(call_expr.id);
let callee_ty = rcx.resolve_node_type(callee_id);
@ -736,12 +738,11 @@ fn constrain_callee(rcx: &mut Rcx,
fn constrain_call(rcx: &mut Rcx,
// might be expr_call, expr_method_call, or an overloaded
// operator
callee_id: ast::NodeId,
fn_expr_id: Option<ast::NodeId>,
call_expr: &ast::Expr,
receiver: Option<@ast::Expr>,
arg_exprs: &[@ast::Expr],
implicitly_ref_args: bool)
{
implicitly_ref_args: bool) {
//! Invoked on every call site (i.e., normal calls, method calls,
//! and overloaded operators). Constrains the regions which appear
//! in the type of the function. Also constrains the regions that
@ -756,7 +757,10 @@ fn constrain_call(rcx: &mut Rcx,
receiver.repr(tcx),
arg_exprs.repr(tcx),
implicitly_ref_args);
let callee_ty = rcx.resolve_node_type(callee_id);
let callee_ty = match fn_expr_id {
Some(id) => rcx.resolve_node_type(id),
None => rcx.resolve_method_type(call_expr.id)
};
if ty::type_is_error(callee_ty) {
// Bail, as function type is unknown
return;

View File

@ -537,11 +537,10 @@ fn connect_trait_tps(vcx: &VtableContext,
relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref);
}
fn insert_vtables(fcx: &FnCtxt, callee_id: ast::NodeId, vtables: vtable_res) {
debug!("insert_vtables(callee_id={}, vtables={:?})",
callee_id, vtables.repr(fcx.tcx()));
let mut vtable_map = fcx.inh.vtable_map.borrow_mut();
vtable_map.get().insert(callee_id, vtables);
fn insert_vtables(fcx: &FnCtxt, expr_id: ast::NodeId, vtables: vtable_res) {
debug!("insert_vtables(expr_id={}, vtables={:?})",
expr_id, vtables.repr(fcx.tcx()));
fcx.inh.vtable_map.borrow_mut().get().insert(expr_id, vtables);
}
pub fn location_info_for_expr(expr: &ast::Expr) -> LocationInfo {
@ -692,23 +691,23 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
}
// Must resolve bounds on methods with bounded params
ast::ExprBinary(callee_id, _, _, _) |
ast::ExprUnary(callee_id, _, _) |
ast::ExprAssignOp(callee_id, _, _, _) |
ast::ExprIndex(callee_id, _, _) |
ast::ExprMethodCall(callee_id, _, _, _) => {
ast::ExprBinary(_, _, _) |
ast::ExprUnary(_, _) |
ast::ExprAssignOp(_, _, _) |
ast::ExprIndex(_, _) |
ast::ExprMethodCall(_, _, _) => {
match fcx.inh.method_map.borrow().get().find(&ex.id) {
Some(origin) => {
Some(method) => {
debug!("vtable resolution on parameter bounds for method call {}",
ex.repr(fcx.tcx()));
let type_param_defs = ty::method_call_type_param_defs(cx.tcx, *origin);
let type_param_defs = ty::method_call_type_param_defs(cx.tcx, method.origin);
if has_trait_bounds(*type_param_defs.borrow()) {
let substs = fcx.node_ty_substs(callee_id);
let substs = fcx.method_ty_substs(ex.id);
let vcx = fcx.vtable_context();
let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex),
*type_param_defs.borrow(), &substs, is_early);
if !is_early {
insert_vtables(fcx, callee_id, vtbls);
insert_vtables(fcx, ex.id, vtbls);
}
}
}

View File

@ -20,6 +20,7 @@ use middle::typeck::check::FnCtxt;
use middle::typeck::infer::{force_all, resolve_all, resolve_region};
use middle::typeck::infer::resolve_type;
use middle::typeck::infer;
use middle::typeck::MethodCallee;
use middle::typeck::{vtable_res, vtable_origin};
use middle::typeck::{vtable_static, vtable_param};
use middle::typeck::write_substs_to_tcx;
@ -61,39 +62,54 @@ fn resolve_type_vars_in_types(fcx: @FnCtxt, sp: Span, tys: &[ty::t])
})
}
fn resolve_method_map_entry(fcx: @FnCtxt, id: ast::NodeId) {
fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) {
let fcx = wbcx.fcx;
let tcx = fcx.ccx.tcx;
// Resolve any method map entry
let method_map_entry_opt = {
let method_map = fcx.inh.method_map.borrow();
method_map.get().find_copy(&id)
};
match method_map_entry_opt {
None => {}
Some(mme) => {
debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})", id, mme);
let mut method_map = fcx.ccx.method_map.borrow_mut();
method_map.get().insert(id, mme);
match fcx.inh.method_map.borrow().get().find(&id) {
Some(method) => {
debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})",
id, method.repr(tcx));
let method_ty = match resolve_type_vars_in_type(fcx, sp, method.ty) {
Some(t) => t,
None => {
wbcx.success = false;
return;
}
};
let mut new_tps = ~[];
for &subst in method.substs.tps.iter() {
match resolve_type_vars_in_type(fcx, sp, subst) {
Some(t) => new_tps.push(t),
None => { wbcx.success = false; return; }
}
}
let new_method = MethodCallee {
origin: method.origin,
ty: method_ty,
substs: ty::substs {
tps: new_tps,
regions: ty::ErasedRegions,
self_ty: None
}
};
fcx.ccx.method_map.borrow_mut().get().insert(id, new_method);
}
None => {}
}
}
fn resolve_vtable_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
// Resolve any method map entry
{
let origins_opt = {
let vtable_map = fcx.inh.vtable_map.borrow();
vtable_map.get().find_copy(&id)
};
match origins_opt {
None => {}
Some(origins) => {
let r_origins = resolve_origins(fcx, sp, origins);
let mut vtable_map = fcx.ccx.vtable_map.borrow_mut();
vtable_map.get().insert(id, r_origins);
debug!("writeback::resolve_vtable_map_entry(id={}, vtables={:?})",
id, r_origins.repr(fcx.tcx()));
}
// Resolve any vtable map entry
match fcx.inh.vtable_map.borrow().get().find_copy(&id) {
Some(origins) => {
let r_origins = resolve_origins(fcx, sp, origins);
fcx.ccx.vtable_map.borrow_mut().get().insert(id, r_origins);
debug!("writeback::resolve_vtable_map_entry(id={}, vtables={:?})",
id, r_origins.repr(fcx.tcx()));
}
None => {}
}
fn resolve_origins(fcx: @FnCtxt, sp: Span,
@ -241,21 +257,6 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
}
}
fn maybe_resolve_type_vars_for_node(wbcx: &mut WbCtxt,
sp: Span,
id: ast::NodeId)
-> Option<ty::t> {
let contained = {
let node_types = wbcx.fcx.inh.node_types.borrow();
node_types.get().contains_key(&id)
};
if contained {
resolve_type_vars_for_node(wbcx, sp, id)
} else {
None
}
}
struct WbCtxt {
fcx: @FnCtxt,
@ -276,22 +277,8 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
}
resolve_type_vars_for_node(wbcx, e.span, e.id);
resolve_method_map_entry(wbcx.fcx, e.id);
{
let r = e.get_callee_id();
for callee_id in r.iter() {
resolve_method_map_entry(wbcx.fcx, *callee_id);
}
}
resolve_method_map_entry(wbcx, e.span, e.id);
resolve_vtable_map_entry(wbcx.fcx, e.span, e.id);
{
let r = e.get_callee_id();
for callee_id in r.iter() {
resolve_vtable_map_entry(wbcx.fcx, e.span, *callee_id);
}
}
match e.node {
ast::ExprFnBlock(ref decl, _) | ast::ExprProc(ref decl, _) => {
@ -299,20 +286,7 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
let _ = resolve_type_vars_for_node(wbcx, e.span, input.id);
}
}
ast::ExprBinary(callee_id, _, _, _) |
ast::ExprUnary(callee_id, _, _) |
ast::ExprAssignOp(callee_id, _, _, _) |
ast::ExprIndex(callee_id, _, _) => {
maybe_resolve_type_vars_for_node(wbcx, e.span, callee_id);
}
ast::ExprMethodCall(callee_id, _, _, _) => {
// We must always have written in a callee ID type for these.
resolve_type_vars_for_node(wbcx, e.span, callee_id);
}
_ => ()
_ => {}
}
visit::walk_expr(wbcx, e, ());

View File

@ -142,9 +142,16 @@ pub struct MethodObject {
real_index: uint,
}
#[deriving(Clone)]
pub struct MethodCallee {
origin: MethodOrigin,
ty: ty::t,
substs: ty::substs
}
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
pub type method_map = @RefCell<HashMap<ast::NodeId, method_origin>>;
pub type MethodMap = @RefCell<HashMap<ast::NodeId, MethodCallee>>;
pub type vtable_param_res = @~[vtable_origin];
// Resolutions for bounds of all parameters, left to right, for a given path.

View File

@ -74,9 +74,6 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region)
Some(ast_map::NodeBlock(ref blk)) => {
explain_span(cx, "block", blk.span)
}
Some(ast_map::NodeCalleeScope(expr)) => {
explain_span(cx, "callee", expr.span)
}
Some(ast_map::NodeExpr(expr)) => {
match expr.node {
ast::ExprCall(..) => explain_span(cx, "call", expr.span),
@ -870,6 +867,15 @@ impl Repr for ty::FnSig {
}
}
impl Repr for typeck::MethodCallee {
fn repr(&self, tcx: ctxt) -> ~str {
format!("MethodCallee \\{origin: {}, ty: {}, {}\\}",
self.origin.repr(tcx),
self.ty.repr(tcx),
self.substs.repr(tcx))
}
}
impl Repr for typeck::MethodOrigin {
fn repr(&self, tcx: ctxt) -> ~str {
match self {

View File

@ -521,19 +521,6 @@ pub struct Expr {
span: Span,
}
impl Expr {
pub fn get_callee_id(&self) -> Option<NodeId> {
match self.node {
ExprMethodCall(callee_id, _, _, _) |
ExprIndex(callee_id, _, _) |
ExprBinary(callee_id, _, _, _) |
ExprAssignOp(callee_id, _, _, _) |
ExprUnary(callee_id, _, _) => Some(callee_id),
_ => None,
}
}
}
#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
pub enum Expr_ {
ExprVstore(@Expr, ExprVstore),
@ -541,10 +528,10 @@ pub enum Expr_ {
ExprBox(@Expr, @Expr),
ExprVec(~[@Expr], Mutability),
ExprCall(@Expr, ~[@Expr]),
ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr]),
ExprMethodCall(Ident, ~[P<Ty>], ~[@Expr]),
ExprTup(~[@Expr]),
ExprBinary(NodeId, BinOp, @Expr, @Expr),
ExprUnary(NodeId, UnOp, @Expr),
ExprBinary(BinOp, @Expr, @Expr),
ExprUnary(UnOp, @Expr),
ExprLit(@Lit),
ExprCast(@Expr, P<Ty>),
ExprIf(@Expr, P<Block>, Option<@Expr>),
@ -560,9 +547,9 @@ pub enum Expr_ {
ExprBlock(P<Block>),
ExprAssign(@Expr, @Expr),
ExprAssignOp(NodeId, BinOp, @Expr, @Expr),
ExprAssignOp(BinOp, @Expr, @Expr),
ExprField(@Expr, Ident, ~[P<Ty>]),
ExprIndex(NodeId, @Expr, @Expr),
ExprIndex(@Expr, @Expr),
/// Expression that looks like a "name". For example,
/// `std::vec::from_elem::<uint>` is an ExprPath that's the "name" part

View File

@ -107,7 +107,6 @@ pub enum Node {
/// NodeStructCtor represents a tuple struct.
NodeStructCtor(@StructDef),
NodeCalleeScope(@Expr),
}
// The odd layout is to bring down the total size.
@ -128,7 +127,6 @@ enum MapEntry {
EntryLocal(NodeId, @Pat),
EntryBlock(NodeId, P<Block>),
EntryStructCtor(NodeId, @StructDef),
EntryCalleeScope(NodeId, @Expr),
// Roots for node trees.
RootCrate,
@ -155,7 +153,6 @@ impl MapEntry {
EntryLocal(id, _) => id,
EntryBlock(id, _) => id,
EntryStructCtor(id, _) => id,
EntryCalleeScope(id, _) => id,
_ => return None
})
}
@ -173,7 +170,6 @@ impl MapEntry {
EntryLocal(_, p) => NodeLocal(p),
EntryBlock(_, p) => NodeBlock(p),
EntryStructCtor(_, p) => NodeStructCtor(p),
EntryCalleeScope(_, p) => NodeCalleeScope(p),
_ => return None
})
}
@ -368,7 +364,6 @@ impl Map {
Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
Some(NodeBlock(block)) => block.span,
Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
Some(NodeCalleeScope(expr)) => expr.span,
_ => fail!("node_span: could not find span for id {}", id),
}
}
@ -493,11 +488,6 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
self.insert(expr.id, EntryExpr(self.parent, expr));
// Expressions which are or might be calls:
for callee_id in expr.get_callee_id().iter() {
self.insert(*callee_id, EntryCalleeScope(self.parent, expr));
}
expr
}
@ -650,9 +640,6 @@ fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
Some(NodeExpr(expr)) => {
format!("expr {} (id={})", pprust::expr_to_str(expr), id)
}
Some(NodeCalleeScope(expr)) => {
format!("callee_scope {} (id={})", pprust::expr_to_str(expr), id)
}
Some(NodeStmt(stmt)) => {
format!("stmt {} (id={})", pprust::stmt_to_str(stmt), id)
}

View File

@ -450,12 +450,6 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
fn visit_expr(&mut self, expression: &Expr, env: ()) {
{
let optional_callee_id = expression.get_callee_id();
for callee_id in optional_callee_id.iter() {
self.operation.visit_id(*callee_id)
}
}
self.operation.visit_id(expression.id);
visit::walk_expr(self, expression, env)
}

View File

@ -502,15 +502,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn expr_binary(&self, sp: Span, op: ast::BinOp,
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr {
self.expr(sp, ast::ExprBinary(ast::DUMMY_NODE_ID, op, lhs, rhs))
self.expr(sp, ast::ExprBinary(op, lhs, rhs))
}
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
self.expr_unary(sp, ast::UnDeref, e)
}
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr)
-> @ast::Expr {
self.expr(sp, ast::ExprUnary(ast::DUMMY_NODE_ID, op, e))
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr {
self.expr(sp, ast::ExprUnary(op, e))
}
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
@ -543,7 +542,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ident: ast::Ident,
mut args: ~[@ast::Expr]) -> @ast::Expr {
args.unshift(expr);
self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args))
self.expr(span, ast::ExprMethodCall(ident, ~[], args))
}
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
self.expr(b.span, ast::ExprBlock(b))

View File

@ -749,21 +749,19 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
ExprCall(folder.fold_expr(f),
args.map(|&x| folder.fold_expr(x)))
}
ExprMethodCall(callee_id, i, ref tps, ref args) => {
ExprMethodCall(i, ref tps, ref args) => {
ExprMethodCall(
folder.new_id(callee_id),
folder.fold_ident(i),
tps.map(|&x| folder.fold_ty(x)),
args.map(|&x| folder.fold_expr(x)))
}
ExprBinary(callee_id, binop, lhs, rhs) => {
ExprBinary(folder.new_id(callee_id),
binop,
ExprBinary(binop, lhs, rhs) => {
ExprBinary(binop,
folder.fold_expr(lhs),
folder.fold_expr(rhs))
}
ExprUnary(callee_id, binop, ohs) => {
ExprUnary(folder.new_id(callee_id), binop, folder.fold_expr(ohs))
ExprUnary(binop, ohs) => {
ExprUnary(binop, folder.fold_expr(ohs))
}
ExprLit(_) => e.node.clone(),
ExprCast(expr, ty) => {
@ -802,9 +800,8 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
ExprAssign(el, er) => {
ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
}
ExprAssignOp(callee_id, op, el, er) => {
ExprAssignOp(folder.new_id(callee_id),
op,
ExprAssignOp(op, el, er) => {
ExprAssignOp(op,
folder.fold_expr(el),
folder.fold_expr(er))
}
@ -813,10 +810,8 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
folder.fold_ident(id),
tys.map(|&x| folder.fold_ty(x)))
}
ExprIndex(callee_id, el, er) => {
ExprIndex(folder.new_id(callee_id),
folder.fold_expr(el),
folder.fold_expr(er))
ExprIndex(el, er) => {
ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
}
ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
ExprLogLevel => ExprLogLevel,

View File

@ -1683,11 +1683,11 @@ impl Parser {
}
pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ {
ExprUnary(ast::DUMMY_NODE_ID, unop, expr)
ExprUnary(unop, expr)
}
pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs)
ExprBinary(binop, lhs, rhs)
}
pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr]) -> ast::Expr_ {
@ -1695,11 +1695,11 @@ impl Parser {
}
fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr]) -> ast::Expr_ {
ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args)
ExprMethodCall(ident, tps, args)
}
pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
ExprIndex(ast::DUMMY_NODE_ID, expr, idx)
ExprIndex(expr, idx)
}
pub fn mk_field(&mut self, expr: @Expr, ident: Ident, tys: ~[P<Ty>]) -> ast::Expr_ {
@ -1707,7 +1707,7 @@ impl Parser {
}
pub fn mk_assign_op(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
ExprAssignOp(ast::DUMMY_NODE_ID, binop, lhs, rhs)
ExprAssignOp(binop, lhs, rhs)
}
pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> @Expr {

View File

@ -1235,7 +1235,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
try!(print_expr(s, func));
try!(print_call_post(s, *args));
}
ast::ExprMethodCall(_, ident, ref tys, ref args) => {
ast::ExprMethodCall(ident, ref tys, ref args) => {
let base_args = args.slice_from(1);
try!(print_expr(s, args[0]));
try!(word(&mut s.s, "."));
@ -1247,13 +1247,13 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
}
try!(print_call_post(s, base_args));
}
ast::ExprBinary(_, op, lhs, rhs) => {
ast::ExprBinary(op, lhs, rhs) => {
try!(print_expr(s, lhs));
try!(space(&mut s.s));
try!(word_space(s, ast_util::binop_to_str(op)));
try!(print_expr(s, rhs));
}
ast::ExprUnary(_, op, expr) => {
ast::ExprUnary(op, expr) => {
try!(word(&mut s.s, ast_util::unop_to_str(op)));
try!(print_expr(s, expr));
}
@ -1442,7 +1442,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
try!(word_space(s, "="));
try!(print_expr(s, rhs));
}
ast::ExprAssignOp(_, op, lhs, rhs) => {
ast::ExprAssignOp(op, lhs, rhs) => {
try!(print_expr(s, lhs));
try!(space(&mut s.s));
try!(word(&mut s.s, ast_util::binop_to_str(op)));
@ -1459,7 +1459,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
try!(word(&mut s.s, ">"));
}
}
ast::ExprIndex(_, expr, index) => {
ast::ExprIndex(expr, index) => {
try!(print_expr(s, expr));
try!(word(&mut s.s, "["));
try!(print_expr(s, index));

View File

@ -658,18 +658,17 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
}
visitor.visit_expr(callee_expression, env.clone())
}
ExprMethodCall(_, _, ref types, ref arguments) => {
ExprMethodCall(_, ref types, ref arguments) => {
walk_exprs(visitor, *arguments, env.clone());
for &typ in types.iter() {
visitor.visit_ty(typ, env.clone())
}
}
ExprBinary(_, _, left_expression, right_expression) => {
ExprBinary(_, left_expression, right_expression) => {
visitor.visit_expr(left_expression, env.clone());
visitor.visit_expr(right_expression, env.clone())
}
ExprAddrOf(_, subexpression) |
ExprUnary(_, _, subexpression) => {
ExprAddrOf(_, subexpression) | ExprUnary(_, subexpression) => {
visitor.visit_expr(subexpression, env.clone())
}
ExprLit(_) => {}
@ -719,7 +718,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
visitor.visit_expr(right_hand_expression, env.clone());
visitor.visit_expr(left_hand_expression, env.clone())
}
ExprAssignOp(_, _, left_expression, right_expression) => {
ExprAssignOp(_, left_expression, right_expression) => {
visitor.visit_expr(right_expression, env.clone());
visitor.visit_expr(left_expression, env.clone())
}
@ -729,7 +728,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
visitor.visit_ty(typ, env.clone())
}
}
ExprIndex(_, main_expression, index_expression) => {
ExprIndex(main_expression, index_expression) => {
visitor.visit_expr(main_expression, env.clone());
visitor.visit_expr(index_expression, env.clone())
}