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, _: ()) { fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
match e.node { match e.node {
ast::ExprUnary(_, ast::UnBox, _) => { ast::ExprUnary(ast::UnBox, _) => {
self.gate_box(e.span); self.gate_box(e.span);
} }
_ => {} _ => {}

View file

@ -21,7 +21,7 @@ use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter, use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
RegionParameter}; RegionParameter};
use metadata::tyencode; use metadata::tyencode;
use middle::typeck::method_origin; use middle::typeck::{MethodCallee, MethodOrigin};
use middle::{ty, typeck, moves}; use middle::{ty, typeck, moves};
use middle; use middle;
use util::ppaux::ty_to_str; 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 { trait read_method_callee_helper {
fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin { 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 { match *self {
typeck::MethodStatic(did) => typeck::MethodStatic(did.tr(xcx)), typeck::MethodStatic(did) => typeck::MethodStatic(did.tr(xcx)),
typeck::MethodParam(ref mp) => { typeck::MethodParam(ref mp) => {
@ -991,17 +1031,13 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
} }
} }
{ for &method in maps.method_map.borrow().get().find(&id).iter() {
let method_map = maps.method_map.borrow(); ebml_w.tag(c::tag_table_method_map, |ebml_w| {
let r = method_map.get().find(&id); ebml_w.id(id);
for &origin in r.iter() { ebml_w.tag(c::tag_table_val, |ebml_w| {
ebml_w.tag(c::tag_table_method_map, |ebml_w| { encode_method_callee(ecx, ebml_w, method)
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
origin.encode(ebml_w);
})
}) })
} })
} }
{ {
@ -1335,9 +1371,8 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
ty_param_defs.get().insert(id, bounds); ty_param_defs.get().insert(id, bounds);
} }
c::tag_table_method_map => { c::tag_table_method_map => {
let origin: method_origin = Decodable::decode(val_dsr); let method = val_dsr.read_method_callee(xcx);
let mut method_map = dcx.maps.method_map.borrow_mut(); dcx.maps.method_map.borrow_mut().get().insert(id, method);
method_map.get().insert(id, origin.tr(xcx));
} }
c::tag_table_vtable_map => { c::tag_table_vtable_map => {
let vtable_res = let vtable_res =

View file

@ -784,7 +784,6 @@ impl<'a> CheckLoanCtxt<'a> {
pub fn check_call(&self, pub fn check_call(&self,
_expr: &ast::Expr, _expr: &ast::Expr,
_callee: Option<@ast::Expr>, _callee: Option<@ast::Expr>,
_callee_id: ast::NodeId,
_callee_span: Span, _callee_span: Span,
_args: &[@ast::Expr]) { _args: &[@ast::Expr]) {
// NB: This call to check for conflicting loans is not truly // 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) this.check_captured_variables(expr.id, expr.span)
} }
ast::ExprAssign(dest, _) | ast::ExprAssign(dest, _) |
ast::ExprAssignOp(_, _, dest, _) => { ast::ExprAssignOp(_, dest, _) => {
this.check_assignment(dest); this.check_assignment(dest);
} }
ast::ExprCall(f, ref args) => { 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) => { ast::ExprMethodCall(_, _, ref args) => {
this.check_call(expr, None, callee_id, expr.span, *args); this.check_call(expr, None, expr.span, *args);
} }
ast::ExprIndex(callee_id, _, rval) | ast::ExprIndex(_, rval) | ast::ExprBinary(_, _, rval)
ast::ExprBinary(callee_id, _, _, rval)
if method_map.get().contains_key(&expr.id) => { 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) => { 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) => { ast::ExprInlineAsm(ref ia) => {
for &(_, out) in ia.outputs.iter() { 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); 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: // If this expression is borrowed, have to ensure it remains valid:
{ for &adjustments in tcx.adjustments.borrow().get().find(&ex.id).iter() {
let adjustments = tcx.adjustments.borrow(); this.guarantee_adjustments(ex, *adjustments);
let r = adjustments.get().find(&ex.id);
for &adjustments in r.iter() {
this.guarantee_adjustments(ex, *adjustments);
}
} }
// If this expression is a move, gather it: // 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, ()); 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); let l_cmt = this.bccx.cat_expr(l);
match opt_loan_path(l_cmt) { match opt_loan_path(l_cmt) {
Some(l_lp) => { Some(l_lp) => {
@ -252,8 +241,8 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
visit::walk_expr(this, ex, ()); visit::walk_expr(this, ex, ());
} }
ast::ExprIndex(_, _, arg) | ast::ExprIndex(_, arg) |
ast::ExprBinary(_, _, _, arg) ast::ExprBinary(_, _, arg)
if method_map.get().contains_key(&ex.id) => { if method_map.get().contains_key(&ex.id) => {
// Arguments in method calls are always passed by ref. // Arguments in method calls are always passed by ref.
// //

View file

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

View file

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

View file

@ -225,10 +225,10 @@ impl ConstEvalVisitor {
} }
} }
ast::ExprUnary(_, _, inner) | ast::ExprParen(inner) => ast::ExprUnary(_, inner) | ast::ExprParen(inner) =>
self.classify(inner), self.classify(inner),
ast::ExprBinary(_, _, a, b) => ast::ExprBinary(_, a, b) =>
join(self.classify(a), self.classify(b)), join(self.classify(a), self.classify(b)),
ast::ExprTup(ref es) | ast::ExprTup(ref es) |
@ -262,7 +262,7 @@ impl ConstEvalVisitor {
ast::ExprField(base, _, _) => self.classify(base), ast::ExprField(base, _, _) => self.classify(base),
ast::ExprIndex(_, base, idx) => ast::ExprIndex(base, idx) =>
join(self.classify(base), self.classify(idx)), join(self.classify(base), self.classify(idx)),
ast::ExprAddrOf(ast::MutImmutable, base) => self.classify(base), 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; use middle::ty;
fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) } fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
match e.node { match e.node {
ExprUnary(_, UnNeg, inner) => { ExprUnary(UnNeg, inner) => {
match eval_const_expr_partial(tcx, inner) { match eval_const_expr_partial(tcx, inner) {
Ok(const_float(f)) => Ok(const_float(-f)), Ok(const_float(f)) => Ok(const_float(-f)),
Ok(const_int(i)) => Ok(const_int(-i)), 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()) ref err => ((*err).clone())
} }
} }
ExprUnary(_, UnNot, inner) => { ExprUnary(UnNot, inner) => {
match eval_const_expr_partial(tcx, inner) { match eval_const_expr_partial(tcx, inner) {
Ok(const_int(i)) => Ok(const_int(!i)), Ok(const_int(i)) => Ok(const_int(!i)),
Ok(const_uint(i)) => Ok(const_uint(!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") _ => Err(~"not on float or string")
} }
} }
ExprBinary(_, op, a, b) => { ExprBinary(op, a, b) => {
match (eval_const_expr_partial(tcx, a), match (eval_const_expr_partial(tcx, a),
eval_const_expr_partial(tcx, b)) { eval_const_expr_partial(tcx, b)) {
(Ok(const_float(a)), Ok(const_float(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::ExprAssign(l, r) |
ast::ExprAssignOp(_, _, l, r) => { ast::ExprAssignOp(_, l, r) => {
self.walk_expr(r, in_out, loop_scopes); self.walk_expr(r, in_out, loop_scopes);
self.walk_expr(l, 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) => { ast::ExprCall(f, ref args) => {
self.walk_expr(f, in_out, loop_scopes); 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) => { ast::ExprMethodCall(_, _, ref args) => {
self.walk_call(callee_id, expr.id, *args, in_out, loop_scopes); self.walk_call(expr.id, *args, in_out, loop_scopes);
} }
ast::ExprIndex(callee_id, l, r) | ast::ExprIndex(l, r) |
ast::ExprBinary(callee_id, _, l, r) if self.is_method_call(expr) => { ast::ExprBinary(_, l, r) if self.is_method_call(expr) => {
self.walk_call(callee_id, expr.id, [l, r], in_out, loop_scopes); self.walk_call(expr.id, [l, r], in_out, loop_scopes);
} }
ast::ExprUnary(callee_id, _, e) if self.is_method_call(expr) => { ast::ExprUnary(_, e) if self.is_method_call(expr) => {
self.walk_call(callee_id, expr.id, [e], in_out, loop_scopes); self.walk_call(expr.id, [e], in_out, loop_scopes);
} }
ast::ExprTup(ref exprs) => { ast::ExprTup(ref exprs) => {
self.walk_exprs(*exprs, in_out, loop_scopes); 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); self.walk_expr(l, in_out, loop_scopes);
let temp = in_out.to_owned(); let temp = in_out.to_owned();
self.walk_expr(r, in_out, loop_scopes); self.walk_expr(r, in_out, loop_scopes);
join_bits(&self.dfcx.oper, temp, in_out); join_bits(&self.dfcx.oper, temp, in_out);
} }
ast::ExprIndex(_, l, r) | ast::ExprIndex(l, r) |
ast::ExprBinary(_, _, l, r) => { ast::ExprBinary(_, l, r) => {
self.walk_exprs([l, r], in_out, loop_scopes); self.walk_exprs([l, r], in_out, loop_scopes);
} }
@ -617,7 +617,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
ast::ExprAddrOf(_, e) | ast::ExprAddrOf(_, e) |
ast::ExprCast(e, _) | ast::ExprCast(e, _) |
ast::ExprUnary(_, _, e) | ast::ExprUnary(_, e) |
ast::ExprParen(e) | ast::ExprParen(e) |
ast::ExprVstore(e, _) | ast::ExprVstore(e, _) |
ast::ExprField(e, _, _) => { ast::ExprField(e, _, _) => {
@ -715,7 +715,6 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
} }
fn walk_call(&mut self, fn walk_call(&mut self,
_callee_id: ast::NodeId,
call_id: ast::NodeId, call_id: ast::NodeId,
args: &[@ast::Expr], args: &[@ast::Expr],
in_out: &mut [uint], in_out: &mut [uint],
@ -723,8 +722,8 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
self.walk_exprs(args, in_out, loop_scopes); self.walk_exprs(args, in_out, loop_scopes);
// FIXME(#6268) nested method calls // FIXME(#6268) nested method calls
// self.merge_with_entry_set(callee_id, in_out); // self.merge_with_entry_set(in_out);
// self.dfcx.apply_gen_kill(callee_id, in_out); // self.dfcx.apply_gen_kill(in_out);
let return_ty = ty::node_id_to_type(self.tcx(), call_id); let return_ty = ty::node_id_to_type(self.tcx(), call_id);
let fails = ty::type_is_bot(return_ty); 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, fn lookup_and_handle_method(&mut self, id: &ast::NodeId,
span: codemap::Span) { span: codemap::Span) {
let method_map = self.method_map.borrow(); match self.method_map.borrow().get().find(id) {
match method_map.get().find(id) { Some(method) => {
Some(&origin) => { match method.origin {
match origin {
typeck::MethodStatic(def_id) => { typeck::MethodStatic(def_id) => {
match ty::provided_source(self.tcx, def_id) { match ty::provided_source(self.tcx, def_id) {
Some(p_did) => self.check_def_id(p_did), 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) { fn check_str_index(&mut self, e: @ast::Expr) {
let base_type = match e.node { 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 _ => return
}; };
debug!("effect: checking index with base type {}", debug!("effect: checking index with base type {}",
@ -137,8 +137,8 @@ impl Visitor<()> for EffectCheckVisitor {
fn visit_expr(&mut self, expr: &ast::Expr, _:()) { fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
match expr.node { match expr.node {
ast::ExprMethodCall(callee_id, _, _, _) => { ast::ExprMethodCall(_, _, _) => {
let base_type = ty::node_id_to_type(self.tcx, callee_id); let base_type = self.method_map.borrow().get().get(&expr.id).ty;
debug!("effect: method call case, base type is {}", debug!("effect: method call case, base type is {}",
ppaux::ty_to_str(self.tcx, base_type)); ppaux::ty_to_str(self.tcx, base_type));
if type_is_unsafe_function(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") 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); let base_type = ty::node_id_to_type(self.tcx, base.id);
debug!("effect: unary case, base type is {}", debug!("effect: unary case, base type is {}",
ppaux::ty_to_str(self.tcx, base_type)); 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); self.check_str_index(base);
} }
ast::ExprAddrOf(ast::MutMutable, 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)); debug!("kind::check_expr({})", expr_to_str(e));
// Handle any kind bounds on type parameters // 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 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() { for ts in r.iter() {
let def_map = cx.tcx.def_map.borrow(); let def_map = cx.tcx.def_map.borrow();
let type_param_defs = match e.node { 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 // Even though the callee_id may have been the id with
// node_type_substs, e.id is correct here. // node_type_substs, e.id is correct here.
match cx.method_map.borrow().get().find(&e.id) { match method {
Some(origin) => { Some(method) => {
ty::method_call_type_param_defs(cx.tcx, *origin) ty::method_call_type_param_defs(cx.tcx, method.origin)
} }
None => { None => {
cx.tcx.sess.span_bug(e.span, 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)); type_param_defs.repr(cx.tcx));
} }
for (&ty, type_param_def) in ts.iter().zip(type_param_defs.iter()) { 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 { match e.node {
ExprUnary(_, UnBox, interior) => { ExprUnary(UnBox, interior) => {
let interior_type = ty::expr_ty(cx.tcx, interior); let interior_type = ty::expr_ty(cx.tcx, interior);
let _ = check_durable(cx.tcx, interior_type, interior.span); 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 generics = ty::lookup_item_type(cx.tcx, did).generics;
let type_param_defs = generics.type_param_defs(); let type_param_defs = generics.type_param_defs();
for (&ty, type_param_def) in ts.iter().zip(type_param_defs.iter()) { 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, pub fn check_typaram_bounds(cx: &Context,
_type_parameter_id: NodeId, sp: Span,
sp: Span, ty: ty::t,
ty: ty::t, type_param_def: &ty::TypeParameterDef) {
type_param_def: &ty::TypeParameterDef)
{
check_builtin_bounds(cx, check_builtin_bounds(cx,
ty, ty,
type_param_def.bounds.builtin_bounds, 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) { fn check_type_limits(cx: &Context, e: &ast::Expr) {
return match e.node { 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) { if is_comparison(binop) && !check_limits(cx.tcx, binop, l, r) {
cx.span_lint(TypeLimits, e.span, cx.span_lint(TypeLimits, e.span,
"comparison is useless due to type limits"); "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::ExprMatch(head, _) => (head, "`match` head expression"),
ast::ExprRet(Some(value)) => (value, "`return` value"), ast::ExprRet(Some(value)) => (value, "`return` value"),
ast::ExprAssign(_, value) => (value, "assigned value"), ast::ExprAssign(_, value) => (value, "assigned value"),
ast::ExprAssignOp(_, _, _, value) => (value, "assigned value"), ast::ExprAssignOp(_, _, value) => (value, "assigned value"),
_ => return _ => return
}; };
check_unnecessary_parens_core(cx, value, msg); check_unnecessary_parens_core(cx, value, msg);
@ -1263,8 +1263,8 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
_ => return _ => return
} }
} }
ast::ExprUnary(_, ast::UnUniq, _) | ast::ExprUnary(ast::UnUniq, _) |
ast::ExprUnary(_, ast::UnBox, _) => BoxAllocation, ast::ExprUnary(ast::UnBox, _) => BoxAllocation,
_ => return _ => return
}; };
@ -1411,10 +1411,9 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
} }
} }
ast::ExprMethodCall(..) => { ast::ExprMethodCall(..) => {
let method_map = cx.method_map.borrow(); match cx.method_map.borrow().get().find(&e.id) {
match method_map.get().find(&e.id) { Some(method) => {
Some(&origin) => { match method.origin {
match origin {
typeck::MethodStatic(def_id) => { typeck::MethodStatic(def_id) => {
// If this implements a trait method, get def_id // If this implements a trait method, get def_id
// of the method inside trait definition. // of the method inside trait definition.
@ -1531,7 +1530,7 @@ impl<'a> Visitor<()> for Context<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) { fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
match e.node { match e.node {
ast::ExprUnary(_, ast::UnNeg, expr) => { ast::ExprUnary(ast::UnNeg, expr) => {
// propagate negation, if the negation itself isn't negated // propagate negation, if the negation itself isn't negated
if self.negated_expr_id != e.id { if self.negated_expr_id != e.id {
self.negated_expr_id = expr.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); visit::walk_expr(v, expr, this);
} }
ExprForLoop(..) => fail!("non-desugared expr_for_loop"), 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)); this.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(v, expr, this); visit::walk_expr(v, expr, this);
} }
@ -1179,7 +1179,7 @@ impl Liveness {
self.propagate_through_expr(r, succ) self.propagate_through_expr(r, succ)
} }
ExprAssignOp(_, _, l, r) => { ExprAssignOp(_, l, r) => {
// see comment on lvalues in // see comment on lvalues in
// propagate_through_lvalue_components() // propagate_through_lvalue_components()
let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ); let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ);
@ -1219,10 +1219,10 @@ impl Liveness {
self.propagate_through_expr(f, succ) 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 // calling a method with bot return type means that the method
// will fail, and hence the successors can be ignored // 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} let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
else {succ}; else {succ};
self.propagate_through_exprs(*args, succ) self.propagate_through_exprs(*args, succ)
@ -1232,7 +1232,7 @@ impl Liveness {
self.propagate_through_exprs(*exprs, succ) 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 r_succ = self.propagate_through_expr(r, succ);
let ln = self.live_node(expr.id, expr.span); let ln = self.live_node(expr.id, expr.span);
@ -1242,15 +1242,15 @@ impl Liveness {
self.propagate_through_expr(l, ln) self.propagate_through_expr(l, ln)
} }
ExprIndex(_, l, r) | ExprIndex(l, r) |
ExprBinary(_, _, l, r) | ExprBinary(_, l, r) |
ExprBox(l, r) => { ExprBox(l, r) => {
self.propagate_through_exprs([l, r], succ) self.propagate_through_exprs([l, r], succ)
} }
ExprAddrOf(_, e) | ExprAddrOf(_, e) |
ExprCast(e, _) | ExprCast(e, _) |
ExprUnary(_, _, e) | ExprUnary(_, e) |
ExprParen(e) => { ExprParen(e) => {
self.propagate_through_expr(e, succ) self.propagate_through_expr(e, succ)
} }
@ -1508,7 +1508,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr, ());
} }
ExprAssignOp(_, _, l, _) => { ExprAssignOp(_, l, _) => {
this.check_lvalue(l); this.check_lvalue(l);
visit::walk_expr(this, expr, ()); 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)); let expr_ty = if_ok!(self.expr_ty(expr));
match expr.node { match expr.node {
ast::ExprUnary(_, ast::UnDeref, e_base) => { ast::ExprUnary(ast::UnDeref, e_base) => {
if self.typer.is_method_call(expr.id) { if self.typer.is_method_call(expr.id) {
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)); 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)) 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) { if self.typer.is_method_call(expr.id) {
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)); 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, []) if !self.use_overloaded_operator(expr, base, [])
{ {
// Moving out of *base moves out of 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. // Moving out of base.f moves out of base.
self.use_expr(base, comp_mode); self.use_expr(base, comp_mode);
} }
ExprIndex(_, lhs, rhs) => { // lhs[rhs] ExprIndex(lhs, rhs) => { // lhs[rhs]
if !self.use_overloaded_operator(expr, lhs, [rhs]) if !self.use_overloaded_operator(expr, lhs, [rhs])
{ {
self.use_expr(lhs, comp_mode); self.use_expr(lhs, comp_mode);
@ -409,11 +409,11 @@ impl VisitContext {
} }
} }
self.use_expr(callee, mode); 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) ExprMethodCall(_, _, ref args) => { // callee.m(args)
self.use_fn_args(callee_id, *args); self.use_fn_args(*args);
} }
ExprStruct(_, ref fields, opt_with) => { ExprStruct(_, ref fields, opt_with) => {
@ -521,14 +521,14 @@ impl VisitContext {
ExprForLoop(..) => fail!("non-desugared expr_for_loop"), ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
ExprUnary(_, _, lhs) => { ExprUnary(_, lhs) => {
if !self.use_overloaded_operator(expr, lhs, []) if !self.use_overloaded_operator(expr, lhs, [])
{ {
self.consume_expr(lhs); self.consume_expr(lhs);
} }
} }
ExprBinary(_, _, lhs, rhs) => { ExprBinary(_, lhs, rhs) => {
if !self.use_overloaded_operator(expr, lhs, [rhs]) if !self.use_overloaded_operator(expr, lhs, [rhs])
{ {
self.consume_expr(lhs); self.consume_expr(lhs);
@ -555,7 +555,7 @@ impl VisitContext {
self.consume_expr(base); self.consume_expr(base);
} }
ExprAssignOp(_, _, lhs, rhs) => { ExprAssignOp(_, lhs, rhs) => {
// FIXME(#4712) --- Overloaded operators? // FIXME(#4712) --- Overloaded operators?
// //
// if !self.use_overloaded_operator(expr, DoDerefArgs, lhs, [rhs]) // if !self.use_overloaded_operator(expr, DoDerefArgs, lhs, [rhs])
@ -668,7 +668,6 @@ impl VisitContext {
} }
pub fn use_fn_args(&mut self, pub fn use_fn_args(&mut self,
_: NodeId,
arg_exprs: &[@Expr]) { arg_exprs: &[@Expr]) {
//! Uses the argument expressions. //! Uses the argument expressions.
for arg_expr in arg_exprs.iter() { 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 // see above
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0])); let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
match ty::get(t).sty { match ty::get(t).sty {
@ -796,9 +796,9 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
"method call not in \ "method call not in \
method map"); method map");
} }
Some(origin) => { Some(method) => {
debug!("(privacy checking) checking impl 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(..) => { ast::ExprMethodCall(..) => {
let method_map = self.method_map.borrow(); match self.method_map.borrow().get().get(&expr.id).origin {
match method_map.get().find(&expr.id) { typeck::MethodStatic(def_id) => {
Some(&typeck::method_static(def_id)) => {
if is_local(def_id) { if is_local(def_id) {
if ReachableContext:: if ReachableContext::
def_id_represents_local_inlined_item( 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. // scopes, meaning that temporaries cannot outlive them.
// This ensures fixed size stacks. // This ensures fixed size stacks.
ast::ExprBinary(_, ast::BiAnd, _, r) | ast::ExprBinary(ast::BiAnd, _, r) |
ast::ExprBinary(_, ast::BiOr, _, r) => { ast::ExprBinary(ast::BiOr, _, r) => {
// For shortcircuiting operators, mark the RHS as a terminating // For shortcircuiting operators, mark the RHS as a terminating
// scope since it only executes conditionally. // scope since it only executes conditionally.
visitor.region_maps.mark_as_terminating_scope(r.id); visitor.region_maps.mark_as_terminating_scope(r.id);
@ -756,7 +756,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
visitor, subexpr, blk_id); visitor, subexpr, blk_id);
} }
} }
ast::ExprUnary(_, ast::UnUniq, subexpr) => { ast::ExprUnary(ast::UnUniq, subexpr) => {
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id); record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
} }
ast::ExprCast(subexpr, _) | ast::ExprCast(subexpr, _) |
@ -811,9 +811,9 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
match expr.node { match expr.node {
ast::ExprAddrOf(_, ref subexpr) | ast::ExprAddrOf(_, ref subexpr) |
ast::ExprUnary(_, ast::UnDeref, ref subexpr) | ast::ExprUnary(ast::UnDeref, ref subexpr) |
ast::ExprField(ref subexpr, _, _) | ast::ExprField(ref subexpr, _, _) |
ast::ExprIndex(_, ref subexpr, _) | ast::ExprIndex(ref subexpr, _) |
ast::ExprParen(ref subexpr) => { ast::ExprParen(ref subexpr) => {
let subexpr: &'a @Expr = subexpr; // FIXME(#11586) let subexpr: &'a @Expr = subexpr; // FIXME(#11586)
expr = &**subexpr; expr = &**subexpr;

View file

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

View file

@ -118,7 +118,7 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
match def { match def {
ast::DefFn(did, _) | ast::DefFn(did, _) |
ast::DefStaticMethod(did, ast::FromImpl(_), _) => { 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::DefStaticMethod(impl_did,
ast::FromTrait(trait_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(), assert!(ty::enum_variant_with_id(bcx.tcx(),
tid, tid,
vid).args.len() > 0u); 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) => { 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::DefStatic(..) |
ast::DefArg(..) | 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>( pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId,
bcx: &'a Block<'a>, ref_id: ast::NodeId, is_method: bool)
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)
-> ValueRef { -> 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 _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); let vtables = node_vtables(bcx, ref_id);
debug!("trans_fn_ref(def_id={}, ref_id={:?}, type_params={}, vtables={})", debug!("trans_fn_ref(def_id={}, ref_id={:?}, type_params={}, vtables={})",
def_id.repr(bcx.tcx()), ref_id, type_params.repr(bcx.tcx()), def_id.repr(bcx.tcx()), ref_id, type_params.repr(bcx.tcx()),
vtables.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>( fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>,
bcx: &'a Block<'a>,
def_id: ast::DefId, def_id: ast::DefId,
ref_id: ast::NodeId, ref_id: ast::NodeId,
type_params: &[ty::t], type_params: &[ty::t],
vtables: Option<typeck::vtable_res>) vtables: Option<typeck::vtable_res>)
-> Callee<'a> { -> Callee<'a> {
Callee {bcx: bcx, 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))} type_params, vtables))}
} }
@ -243,6 +234,7 @@ pub fn trans_fn_ref_with_vtables(
bcx: &Block, // bcx: &Block, //
def_id: ast::DefId, // def id of fn def_id: ast::DefId, // def id of fn
ref_id: ast::NodeId, // node id of use of fn; may be zero if N/A 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 type_params: &[ty::t], // values for fn's ty params
vtables: Option<typeck::vtable_res>) // vtables for the call vtables: Option<typeck::vtable_res>) // vtables for the call
-> ValueRef { -> ValueRef {
@ -388,7 +380,12 @@ pub fn trans_fn_ref_with_vtables(
if must_cast && ref_id != 0 { if must_cast && ref_id != 0 {
// Monotype of the REFERENCE to the function (type params // Monotype of the REFERENCE to the function (type params
// are subst'd) // 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( val = PointerCast(
bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to()); 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>( pub fn trans_method_call<'a>(
in_cx: &'a Block<'a>, bcx: &'a Block<'a>,
call_ex: &ast::Expr, call_ex: &ast::Expr,
callee_id: ast::NodeId,
rcvr: &ast::Expr, rcvr: &ast::Expr,
args: CallArgs, args: CallArgs,
dest: expr::Dest) dest: expr::Dest)
-> &'a Block<'a> { -> &'a Block<'a> {
let _icx = push_ctxt("trans_method_call"); 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( trans_call_inner(
in_cx, bcx,
Some(common::expr_info(call_ex)), Some(common::expr_info(call_ex)),
node_id_type(in_cx, callee_id), monomorphize_type(bcx, method_ty),
expr_ty(in_cx, call_ex), expr_ty(bcx, call_ex),
|cx, arg_cleanup_scope| { |cx, arg_cleanup_scope| {
let origin_opt = { meth::trans_method_callee(cx, call_ex.id, rcvr, arg_cleanup_scope)
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")
}
}
}, },
args, args,
Some(dest)).bcx Some(dest)).bcx

View file

@ -673,7 +673,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
// The exception handling personality function. // The exception handling personality function.
let def_id = common::langcall(pad_bcx, None, "", EhPersonalityLangItem); 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' // The only landing pad clause will be 'cleanup'
let llretval = build::LandingPad(pad_bcx, llretty, llpersonality, 1u); 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) 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 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)) { if !params.iter().all(|t| !ty::type_needs_infer(*t)) {
bcx.sess().bug( bcx.sess().bug(

View file

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

View file

@ -2539,15 +2539,13 @@ fn populate_scope_map(cx: &CrateContext,
None => () None => ()
}, },
ast::ExprUnary(node_id, _, sub_exp) => { ast::ExprUnary(_, sub_exp) => {
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
walk_expr(cx, sub_exp, scope_stack, scope_map); walk_expr(cx, sub_exp, scope_stack, scope_map);
} }
ast::ExprAssignOp(node_id, _, lhs, rhs) | ast::ExprAssignOp(_, lhs, rhs) |
ast::ExprIndex(node_id, lhs, rhs) | ast::ExprIndex(lhs, rhs) |
ast::ExprBinary(node_id, _, lhs, rhs) => { ast::ExprBinary(_, lhs, rhs) => {
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
walk_expr(cx, lhs, scope_stack, scope_map); walk_expr(cx, lhs, scope_stack, scope_map);
walk_expr(cx, rhs, 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) => { ast::ExprMethodCall(_, _, ref args) => {
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
for arg_exp in args.iter() { for arg_exp in args.iter() {
walk_expr(cx, *arg_exp, scope_stack, scope_map); 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, _) => { ast::ExprField(base, ident, _) => {
trans_rec_field(bcx, base, ident) trans_rec_field(bcx, base, ident)
} }
ast::ExprIndex(_, base, idx) => { ast::ExprIndex(base, idx) => {
trans_index(bcx, expr, base, idx) trans_index(bcx, expr, base, idx)
} }
ast::ExprVstore(contents, ast::ExprVstoreUniq) => { 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) return trans_boxed_expr(bcx, box_ty, contents, contents_ty, heap)
} }
ast::ExprLit(lit) => trans_immediate_lit(bcx, expr, (*lit).clone()), 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 // if overloaded, would be RvalueDpsExpr
{ assert!(!bcx.ccx().maps.method_map.borrow().get().contains_key(&expr.id));
let method_map = bcx.ccx().maps.method_map.borrow();
assert!(!method_map.get().contains_key(&expr.id));
}
trans_binary(bcx, expr, op, lhs, rhs) 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)); let basedatum = unpack_datum!(bcx, trans(bcx, base));
deref_once(bcx, expr, basedatum, 0) deref_once(bcx, expr, basedatum, 0)
} }
ast::ExprUnary(_, op, x) => { ast::ExprUnary(op, x) => {
trans_unary_datum(bcx, expr, op, x) trans_unary_datum(bcx, expr, op, x)
} }
ast::ExprAddrOf(_, 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) src_datum.store_to(bcx, dst_datum.val)
} }
} }
ast::ExprAssignOp(callee_id, op, dst, src) => { ast::ExprAssignOp(op, dst, src) => {
trans_assign_op(bcx, expr, callee_id, op, dst, src) trans_assign_op(bcx, expr, op, dst, src)
} }
ast::ExprInlineAsm(ref a) => { ast::ExprInlineAsm(ref a) => {
asm::trans_inline_asm(bcx, 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) closure::trans_expr_fn(bcx, sigil, decl, body, expr.id, dest)
} }
ast::ExprCall(f, ref args) => { ast::ExprCall(f, ref args) => {
callee::trans_call(bcx, expr, f, callee::trans_call(bcx, expr, f, callee::ArgExprs(*args), expr.id, dest)
callee::ArgExprs(*args), expr.id, dest)
} }
ast::ExprMethodCall(callee_id, _, _, ref args) => { ast::ExprMethodCall(_, _, ref args) => {
callee::trans_method_call(bcx, expr, callee_id, args[0], callee::trans_method_call(bcx, expr, args[0], callee::ArgExprs(*args), dest)
callee::ArgExprs(*args), dest)
} }
ast::ExprBinary(callee_id, _, lhs, rhs) => { ast::ExprBinary(_, lhs, rhs) => {
// if not overloaded, would be RvalueDatumExpr // 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) Some(&*rhs), expr_ty(bcx, expr), dest)
} }
ast::ExprUnary(callee_id, _, subexpr) => { ast::ExprUnary(_, subexpr) => {
// if not overloaded, would be RvalueDatumExpr // 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) None, expr_ty(bcx, expr), dest)
} }
ast::ExprIndex(callee_id, base, idx) => { ast::ExprIndex(base, idx) => {
// if not overloaded, would be RvalueDatumExpr // 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) Some(&*idx), expr_ty(bcx, expr), dest)
} }
ast::ExprCast(val, _) => { ast::ExprCast(val, _) => {
@ -815,8 +810,8 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
} }
} }
} }
ast::ExprAssignOp(callee_id, op, dst, src) => { ast::ExprAssignOp(op, dst, src) => {
trans_assign_op(bcx, expr, callee_id, op, dst, src) trans_assign_op(bcx, expr, op, dst, src)
} }
ast::ExprBox(_, contents) => { ast::ExprBox(_, contents) => {
// Special case for `Gc<T>` for now. The other case, for unique // 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); let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
if variant_info.args.len() > 0u { if variant_info.args.len() > 0u {
// N-ary variant. // 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); Store(bcx, llfn, lldest);
return bcx; return bcx;
} else { } else {
@ -884,15 +879,14 @@ fn trans_def_dps_unadjusted<'a>(
fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>, fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
ref_expr: &ast::Expr, 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 _icx = push_ctxt("trans_def_datum_unadjusted");
let llfn = match def { let llfn = match def {
ast::DefFn(did, _) | ast::DefFn(did, _) |
ast::DefStruct(did) | ast::DefVariant(_, did, _) | ast::DefStruct(did) | ast::DefVariant(_, did, _) |
ast::DefStaticMethod(did, ast::FromImpl(_), _) => { 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), _) => { ast::DefStaticMethod(impl_did, ast::FromTrait(trait_did), _) => {
meth::trans_static_method_callee(bcx, impl_did, meth::trans_static_method_callee(bcx, impl_did,
@ -1496,26 +1490,20 @@ fn trans_binary<'a>(
fn trans_overloaded_op<'a, 'b>( fn trans_overloaded_op<'a, 'b>(
bcx: &'a Block<'a>, bcx: &'a Block<'a>,
expr: &ast::Expr, expr: &ast::Expr,
callee_id: ast::NodeId,
rcvr: &'b ast::Expr, rcvr: &'b ast::Expr,
arg: Option<&'b ast::Expr>, arg: Option<&'b ast::Expr>,
ret_ty: ty::t, ret_ty: ty::t,
dest: Dest) dest: Dest)
-> &'a Block<'a> { -> &'a Block<'a> {
let origin = { let method_ty = bcx.ccx().maps.method_map.borrow().get().get(&expr.id).ty;
let method_map = bcx.ccx().maps.method_map.borrow();
method_map.get().get_copy(&expr.id)
};
let fty = node_id_type(bcx, callee_id);
callee::trans_call_inner(bcx, callee::trans_call_inner(bcx,
Some(expr_info(expr)), Some(expr_info(expr)),
fty, monomorphize_type(bcx, method_ty),
ret_ty, ret_ty,
|bcx, arg_cleanup_scope| { |bcx, arg_cleanup_scope| {
meth::trans_method_callee(bcx, meth::trans_method_callee(bcx,
callee_id, expr.id,
rcvr, rcvr,
origin,
arg_cleanup_scope) arg_cleanup_scope)
}, },
callee::ArgAutorefSecond(rcvr, arg), callee::ArgAutorefSecond(rcvr, arg),
@ -1666,7 +1654,6 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
fn trans_assign_op<'a>( fn trans_assign_op<'a>(
bcx: &'a Block<'a>, bcx: &'a Block<'a>,
expr: &ast::Expr, expr: &ast::Expr,
_callee_id: ast::NodeId,
op: ast::BinOp, op: ast::BinOp,
dst: &ast::Expr, dst: &ast::Expr,
src: @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>( pub fn trans_method_callee<'a>(
bcx: &'a Block<'a>, bcx: &'a Block<'a>,
callee_id: ast::NodeId, expr_id: ast::NodeId,
this: &ast::Expr, this: &ast::Expr,
origin: typeck::method_origin,
arg_cleanup_scope: cleanup::ScopeId) arg_cleanup_scope: cleanup::ScopeId)
-> Callee<'a> { -> Callee<'a> {
let _icx = push_ctxt("meth::trans_method_callee"); let _icx = push_ctxt("meth::trans_method_callee");
debug!("trans_method_callee(callee_id={:?}, origin={})", let (origin, method_ty) = match bcx.ccx().maps.method_map
callee_id, origin.repr(bcx.tcx())); .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 { match origin {
typeck::MethodStatic(did) => { typeck::MethodStatic(did) => {
Callee { Callee {
bcx: bcx, 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 { typeck::MethodParam(typeck::MethodParam {
@ -123,7 +131,7 @@ pub fn trans_method_callee<'a>(
trait_id); trait_id);
let vtbl = find_vtable(bcx.tcx(), substs, p, b); 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) trait_id, off, vtbl)
} }
// how to get rid of this? // how to get rid of this?
@ -133,7 +141,7 @@ pub fn trans_method_callee<'a>(
typeck::MethodObject(ref mt) => { typeck::MethodObject(ref mt) => {
trans_trait_callee(bcx, trans_trait_callee(bcx,
callee_id, monomorphize_type(bcx, method_ty),
mt.real_index, mt.real_index,
this, this,
arg_cleanup_scope) arg_cleanup_scope)
@ -144,16 +152,16 @@ pub fn trans_method_callee<'a>(
pub fn trans_static_method_callee(bcx: &Block, pub fn trans_static_method_callee(bcx: &Block,
method_id: ast::DefId, method_id: ast::DefId,
trait_id: ast::DefId, trait_id: ast::DefId,
callee_id: ast::NodeId) expr_id: ast::NodeId)
-> ValueRef { -> ValueRef {
let _icx = push_ctxt("meth::trans_static_method_callee"); let _icx = push_ctxt("meth::trans_static_method_callee");
let ccx = bcx.ccx(); let ccx = bcx.ccx();
debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \ debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \
callee_id={:?})", expr_id={:?})",
method_id, method_id,
ty::item_path_str(bcx.tcx(), trait_id), ty::item_path_str(bcx.tcx(), trait_id),
callee_id); expr_id);
let _indenter = indenter(); let _indenter = indenter();
ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trait_id); ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trait_id);
@ -188,13 +196,10 @@ pub fn trans_static_method_callee(bcx: &Block,
} else { } else {
csearch::get_item_path(bcx.tcx(), method_id).last().unwrap().name() csearch::get_item_path(bcx.tcx(), method_id).last().unwrap().name()
}; };
debug!("trans_static_method_callee: method_id={:?}, callee_id={:?}, \ debug!("trans_static_method_callee: method_id={:?}, expr_id={:?}, \
name={}", method_id, callee_id, token::get_name(mname)); name={}", method_id, expr_id, token::get_name(mname));
let vtbls = { let vtbls = ccx.maps.vtable_map.borrow().get().get_copy(&expr_id);
let vtable_map = ccx.maps.vtable_map.borrow();
vtable_map.get().get_copy(&callee_id)
};
let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls); let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls);
match vtbls[bound_index][0] { 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 mth_id = method_with_name(ccx, impl_did, mname);
let (callee_substs, callee_origins) = let (callee_substs, callee_origins) =
combine_impl_and_methods_tps( combine_impl_and_methods_tps(
bcx, mth_id, callee_id, bcx, mth_id, expr_id, false,
*rcvr_substs, rcvr_origins); *rcvr_substs, rcvr_origins);
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, callee_id, let llfn = trans_fn_ref_with_vtables(bcx, mth_id, expr_id,
callee_substs, false, callee_substs,
Some(callee_origins)); 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(); let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
PointerCast(bcx, llfn, llty) PointerCast(bcx, llfn, llty)
} }
@ -246,13 +251,13 @@ pub fn method_with_name(ccx: &CrateContext,
} }
fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>, fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
callee_id: ast::NodeId, expr_id: ast::NodeId,
trait_id: ast::DefId, trait_id: ast::DefId,
n_method: uint, n_method: uint,
vtbl: typeck::vtable_origin) vtbl: typeck::vtable_origin)
-> Callee<'a> { -> Callee<'a> {
let _icx = push_ctxt("meth::trans_monomorphized_callee"); let _icx = push_ctxt("meth::trans_monomorphized_callee");
return match vtbl { match vtbl {
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
let ccx = bcx.ccx(); let ccx = bcx.ccx();
let mname = ty::trait_method(ccx.tcx, trait_id, n_method).ident; 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: // those from the impl and those from the method:
let (callee_substs, callee_origins) = let (callee_substs, callee_origins) =
combine_impl_and_methods_tps( combine_impl_and_methods_tps(
bcx, mth_id, callee_id, bcx, mth_id, expr_id, true,
*rcvr_substs, rcvr_origins); *rcvr_substs, rcvr_origins);
// translate the function // translate the function
let llfn = trans_fn_ref_with_vtables(bcx, let llfn = trans_fn_ref_with_vtables(bcx,
mth_id, mth_id,
callee_id, expr_id,
true,
callee_substs, callee_substs,
Some(callee_origins)); Some(callee_origins));
@ -277,16 +283,16 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
typeck::vtable_param(..) => { typeck::vtable_param(..) => {
fail!("vtable_param left in monomorphized function's vtable substs"); fail!("vtable_param left in monomorphized function's vtable substs");
} }
}; }
} }
pub fn combine_impl_and_methods_tps(bcx: &Block, fn combine_impl_and_methods_tps(bcx: &Block,
mth_did: ast::DefId, mth_did: ast::DefId,
callee_id: ast::NodeId, expr_id: ast::NodeId,
rcvr_substs: &[ty::t], is_method: bool,
rcvr_origins: typeck::vtable_res) rcvr_substs: &[ty::t],
-> (~[ty::t], typeck::vtable_res) { rcvr_origins: typeck::vtable_res)
-> (~[ty::t], typeck::vtable_res) {
/*! /*!
* *
* Creates a concatenated set of substitutions which includes * 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 ccx = bcx.ccx();
let method = ty::method(ccx.tcx, mth_did); let method = ty::method(ccx.tcx, mth_did);
let n_m_tps = method.generics.type_param_defs().len(); 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)); debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx));
let ty_substs let ty_substs
= vec::append(rcvr_substs.to_owned(), = 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 // Now, do the same work for the vtables. The vtables might not
// exist, in which case we need to make them. // 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, Some(vt) => vt,
None => @vec::from_elem(node_substs.len(), @~[]) 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(), = @vec::append(rcvr_origins.to_owned(),
r_m_origins.tailn(r_m_origins.len() - n_m_tps)); 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>, fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
callee_id: ast::NodeId, method_ty: ty::t,
n_method: uint, n_method: uint,
self_expr: &ast::Expr, self_expr: &ast::Expr,
arg_cleanup_scope: cleanup::ScopeId) arg_cleanup_scope: cleanup::ScopeId)
@ -371,8 +377,7 @@ fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
self_datum.val self_datum.val
}; };
let callee_ty = node_id_type(bcx, callee_id); trans_trait_callee_from_llval(bcx, method_ty, n_method, llval)
trans_trait_callee_from_llval(bcx, callee_ty, n_method, llval)
} }
pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>, 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)); token::get_ident(ident));
C_null(Type::nil().ptr_to()) C_null(Type::nil().ptr_to())
} else { } 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>, vtables: Option<typeck::vtable_res>,
self_vtables: Option<typeck::vtable_param_res>, self_vtables: Option<typeck::vtable_param_res>,
ref_id: Option<ast::NodeId>) ref_id: Option<ast::NodeId>)
-> (ValueRef, bool) -> (ValueRef, bool) {
{
debug!("monomorphic_fn(\ debug!("monomorphic_fn(\
fn_id={}, \ fn_id={}, \
real_substs={}, \ real_substs={}, \
@ -280,7 +279,6 @@ pub fn monomorphic_fn(ccx: @CrateContext,
ast_map::NodeStmt(..) | ast_map::NodeStmt(..) |
ast_map::NodeArg(..) | ast_map::NodeArg(..) |
ast_map::NodeBlock(..) | ast_map::NodeBlock(..) |
ast_map::NodeCalleeScope(..) |
ast_map::NodeLocal(..) => { ast_map::NodeLocal(..) => {
ccx.tcx.sess.bug(format!("can't monomorphize a {:?}", map_node)) 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::ExprField(..) |
ast::ExprIndex(..) => { ast::ExprIndex(..) => {
LvalueExpr LvalueExpr

View file

@ -89,6 +89,7 @@ use middle::typeck::check::{structurally_resolved_type};
use middle::typeck::check::vtable; use middle::typeck::check::vtable;
use middle::typeck::check; use middle::typeck::check;
use middle::typeck::infer; use middle::typeck::infer;
use middle::typeck::MethodCallee;
use middle::typeck::{MethodOrigin, MethodParam}; use middle::typeck::{MethodOrigin, MethodParam};
use middle::typeck::{MethodStatic, MethodObject}; use middle::typeck::{MethodStatic, MethodObject};
use middle::typeck::{param_numbered, param_self, param_index}; use middle::typeck::{param_numbered, param_self, param_index};
@ -101,7 +102,7 @@ use collections::HashSet;
use std::result; use std::result;
use std::vec; use std::vec;
use syntax::ast::{DefId, SelfValue, SelfRegion}; 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::{MutMutable, MutImmutable};
use syntax::ast; use syntax::ast;
use syntax::parse::token; use syntax::parse::token;
@ -124,20 +125,17 @@ pub fn lookup(
// In a call `a.b::<X, Y, ...>(...)`: // In a call `a.b::<X, Y, ...>(...)`:
expr: &ast::Expr, // The expression `a.b(...)`. expr: &ast::Expr, // The expression `a.b(...)`.
self_expr: &ast::Expr, // The expression `a`. 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`. m_name: ast::Name, // The name `b`.
self_ty: ty::t, // The type of `a`. self_ty: ty::t, // The type of `a`.
supplied_tps: &[ty::t], // The list of types X, Y, ... . supplied_tps: &[ty::t], // The list of types X, Y, ... .
deref_args: check::DerefArgs, // Whether we autopointer first. deref_args: check::DerefArgs, // Whether we autopointer first.
check_traits: CheckTraitsFlag, // Whether we check traits only. check_traits: CheckTraitsFlag, // Whether we check traits only.
autoderef_receiver: AutoderefReceiverFlag) autoderef_receiver: AutoderefReceiverFlag)
-> Option<method_origin> { -> Option<MethodCallee> {
let lcx = LookupContext { let lcx = LookupContext {
fcx: fcx, fcx: fcx,
expr: expr, expr: expr,
self_expr: self_expr, self_expr: self_expr,
callee_id: callee_id,
m_name: m_name, m_name: m_name,
supplied_tps: supplied_tps, supplied_tps: supplied_tps,
impl_dups: @RefCell::new(HashSet::new()), impl_dups: @RefCell::new(HashSet::new()),
@ -173,19 +171,16 @@ pub fn lookup_in_trait(
// In a call `a.b::<X, Y, ...>(...)`: // In a call `a.b::<X, Y, ...>(...)`:
expr: &ast::Expr, // The expression `a.b(...)`. expr: &ast::Expr, // The expression `a.b(...)`.
self_expr: &ast::Expr, // The expression `a`. 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`. m_name: ast::Name, // The name `b`.
trait_did: DefId, // The trait to limit the lookup to. trait_did: DefId, // The trait to limit the lookup to.
self_ty: ty::t, // The type of `a`. self_ty: ty::t, // The type of `a`.
supplied_tps: &[ty::t], // The list of types X, Y, ... . supplied_tps: &[ty::t], // The list of types X, Y, ... .
autoderef_receiver: AutoderefReceiverFlag) autoderef_receiver: AutoderefReceiverFlag)
-> Option<method_origin> { -> Option<MethodCallee> {
let lcx = LookupContext { let lcx = LookupContext {
fcx: fcx, fcx: fcx,
expr: expr, expr: expr,
self_expr: self_expr, self_expr: self_expr,
callee_id: callee_id,
m_name: m_name, m_name: m_name,
supplied_tps: supplied_tps, supplied_tps: supplied_tps,
impl_dups: @RefCell::new(HashSet::new()), impl_dups: @RefCell::new(HashSet::new()),
@ -210,7 +205,6 @@ pub struct LookupContext<'a> {
fcx: @FnCtxt, fcx: @FnCtxt,
expr: &'a ast::Expr, expr: &'a ast::Expr,
self_expr: &'a ast::Expr, self_expr: &'a ast::Expr,
callee_id: NodeId,
m_name: ast::Name, m_name: ast::Name,
supplied_tps: &'a [ty::t], supplied_tps: &'a [ty::t],
impl_dups: @RefCell<HashSet<DefId>>, impl_dups: @RefCell<HashSet<DefId>>,
@ -248,7 +242,7 @@ enum RcvrMatchCondition {
} }
impl<'a> LookupContext<'a> { 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 self_ty = self_ty;
let mut autoderefs = 0; let mut autoderefs = 0;
loop { loop {
@ -636,7 +630,7 @@ impl<'a> LookupContext<'a> {
fn search_for_autoderefd_method(&self, fn search_for_autoderefd_method(&self,
self_ty: ty::t, self_ty: ty::t,
autoderefs: uint) autoderefs: uint)
-> Option<method_origin> { -> Option<MethodCallee> {
let (self_ty, autoadjust) = let (self_ty, autoadjust) =
self.consider_reborrow(self_ty, autoderefs); self.consider_reborrow(self_ty, autoderefs);
match self.search_for_method(self_ty) { match self.search_for_method(self_ty) {
@ -732,7 +726,7 @@ impl<'a> LookupContext<'a> {
fn search_for_autosliced_method(&self, fn search_for_autosliced_method(&self,
self_ty: ty::t, self_ty: ty::t,
autoderefs: uint) autoderefs: uint)
-> Option<method_origin> { -> Option<MethodCallee> {
/*! /*!
* *
* Searches for a candidate by converting things like * 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) 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 * Converts any type `T` to `&M T` where `M` is an
@ -843,7 +837,7 @@ impl<'a> LookupContext<'a> {
autoderefs: uint, autoderefs: uint,
mutbls: &[ast::Mutability], mutbls: &[ast::Mutability],
mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t) mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
-> Option<method_origin> { -> Option<MethodCallee> {
// This is hokey. We should have mutability inference as a // This is hokey. We should have mutability inference as a
// variable. But for now, try &const, then &, then &mut: // variable. But for now, try &const, then &, then &mut:
let region = let region =
@ -867,7 +861,7 @@ impl<'a> LookupContext<'a> {
} }
fn search_for_method(&self, rcvr_ty: ty::t) 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)); debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
let _indenter = indenter(); let _indenter = indenter();
@ -899,7 +893,7 @@ impl<'a> LookupContext<'a> {
fn consider_candidates(&self, fn consider_candidates(&self,
rcvr_ty: ty::t, rcvr_ty: ty::t,
candidates: &mut ~[Candidate]) candidates: &mut ~[Candidate])
-> Option<method_origin> { -> Option<MethodCallee> {
// FIXME(pcwalton): Do we need to clone here? // FIXME(pcwalton): Do we need to clone here?
let relevant_candidates: ~[Candidate] = let relevant_candidates: ~[Candidate] =
candidates.iter().map(|c| (*c).clone()). candidates.iter().map(|c| (*c).clone()).
@ -970,7 +964,7 @@ impl<'a> LookupContext<'a> {
} }
fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate) fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
-> method_origin { -> MethodCallee {
// This method performs two sets of substitutions, one after the other: // This method performs two sets of substitutions, one after the other:
// 1. Substitute values for any type/lifetime parameters from the impl and // 1. Substitute values for any type/lifetime parameters from the impl and
// method declaration into the method type. This is the function type // 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); MethodCallee {
self.fcx.write_substs(self.callee_id, all_substs); origin: candidate.origin,
candidate.origin ty: fty,
substs: all_substs
}
} }
fn construct_transformed_self_ty_for_object( 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 { pub fn node_ty(&self, id: ast::NodeId) -> ty::t {
let node_types = self.inh.node_types.borrow(); match self.inh.node_types.borrow().get().find(&id) {
match node_types.get().find(&id) {
Some(&t) => t, Some(&t) => t,
None => { None => {
self.tcx().sess.bug( 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 { pub fn node_ty_substs(&self, id: ast::NodeId) -> ty::substs {
let mut node_type_substs = self.inh.node_type_substs.borrow_mut(); match self.inh.node_type_substs.borrow().get().find(&id) {
match node_type_substs.get().find(&id) {
Some(ts) => (*ts).clone(), Some(ts) => (*ts).clone(),
None => { None => {
self.tcx().sess.bug( 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, pub fn opt_node_ty_substs(&self,
id: ast::NodeId, id: ast::NodeId,
f: |&ty::substs| -> bool) 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 // A generic function for doing all of the checking for call expressions
fn check_call(fcx: @FnCtxt, fn check_call(fcx: @FnCtxt,
callee_id: ast::NodeId,
call_expr: &ast::Expr, call_expr: &ast::Expr,
f: &ast::Expr, f: &ast::Expr,
args: &[@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 // Store the type of `f` as the type of the callee
let fn_ty = fcx.expr_ty(f); 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`. // Extract the function signature from `in_fty`.
let fn_sty = structure_of(fcx, f.span, fn_ty); 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. // Checks a method call.
fn check_method_call(fcx: @FnCtxt, fn check_method_call(fcx: @FnCtxt,
callee_id: ast::NodeId,
expr: &ast::Expr, expr: &ast::Expr,
method_name: ast::Ident, method_name: ast::Ident,
args: &[@ast::Expr], args: &[@ast::Expr],
@ -1848,20 +1861,16 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.expr_ty(rcvr)); fcx.expr_ty(rcvr));
let tps = tps.map(|&ast_ty| fcx.to_ty(ast_ty)); let tps = tps.map(|&ast_ty| fcx.to_ty(ast_ty));
match method::lookup(fcx, let fn_ty = match method::lookup(fcx, expr, rcvr,
expr, method_name.name,
rcvr, expr_t, tps,
callee_id, DontDerefArgs,
method_name.name, CheckTraitsAndInherentMethods,
expr_t, AutoderefReceiver) {
tps, Some(method) => {
DontDerefArgs, let method_ty = method.ty;
CheckTraitsAndInherentMethods, fcx.inh.method_map.borrow_mut().get().insert(expr.id, method);
AutoderefReceiver) { method_ty
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));
} }
None => { None => {
debug!("(checking method call) failing expr is {}", expr.id); 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 // Add error type for the result
fcx.write_error(expr.id); fcx.write_error(expr.id);
fcx.write_error(callee_id); ty::mk_err()
} }
} };
// Call the generic checker. // Call the generic checker.
let fn_ty = fcx.node_ty(callee_id);
let ret_ty = check_method_argument_types(fcx, expr.span, let ret_ty = check_method_argument_types(fcx, expr.span,
fn_ty, expr, args, fn_ty, expr, args,
DontDerefArgs); DontDerefArgs);
@ -1932,7 +1940,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
} }
fn lookup_op_method(fcx: @FnCtxt, fn lookup_op_method(fcx: @FnCtxt,
callee_id: ast::NodeId,
op_ex: &ast::Expr, op_ex: &ast::Expr,
self_t: ty::t, self_t: ty::t,
opname: ast::Name, opname: ast::Name,
@ -1940,18 +1947,17 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
args: &[@ast::Expr], args: &[@ast::Expr],
autoderef_receiver: AutoderefReceiverFlag, autoderef_receiver: AutoderefReceiverFlag,
unbound_method: ||) -> ty::t { unbound_method: ||) -> ty::t {
let origin = match trait_did { let method = match trait_did {
Some(trait_did) => { Some(trait_did) => {
method::lookup_in_trait(fcx, op_ex, args[0], callee_id, opname, method::lookup_in_trait(fcx, op_ex, args[0], opname, trait_did,
trait_did, self_t, [], autoderef_receiver) self_t, [], autoderef_receiver)
} }
None => None None => None
}; };
match origin { match method {
Some(origin) => { Some(method) => {
let method_ty = fcx.node_ty(callee_id); let method_ty = method.ty;
let method_map = fcx.inh.method_map; fcx.inh.method_map.borrow_mut().get().insert(op_ex.id, method);
method_map.borrow_mut().get().insert(op_ex.id, origin);
check_method_argument_types(fcx, op_ex.span, check_method_argument_types(fcx, op_ex.span,
method_ty, op_ex, method_ty, op_ex,
args, DoDerefArgs) 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 // could be either an expr_binop or an expr_assign_binop
fn check_binop(fcx: @FnCtxt, fn check_binop(fcx: @FnCtxt,
callee_id: ast::NodeId,
expr: &ast::Expr, expr: &ast::Expr,
op: ast::BinOp, op: ast::BinOp,
lhs: @ast::Expr, lhs: @ast::Expr,
@ -2023,7 +2028,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
// Check for overloaded operators if not an assignment. // Check for overloaded operators if not an assignment.
let result_t = if is_binop_assignment == SimpleBinop { 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 { } else {
fcx.type_error_message(expr.span, fcx.type_error_message(expr.span,
|actual| { |actual| {
@ -2045,7 +2050,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
} }
fn check_user_binop(fcx: @FnCtxt, fn check_user_binop(fcx: @FnCtxt,
callee_id: ast::NodeId,
ex: &ast::Expr, ex: &ast::Expr,
lhs_expr: @ast::Expr, lhs_expr: @ast::Expr,
lhs_resolved_t: ty::t, lhs_resolved_t: ty::t,
@ -2075,7 +2079,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
return ty::mk_err(); 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, || { trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
fcx.type_error_message(ex.span, |actual| { fcx.type_error_message(ex.span, |actual| {
format!("binary operation `{}` cannot be applied to type `{}`", 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, fn check_user_unop(fcx: @FnCtxt,
callee_id: ast::NodeId,
op_str: &str, op_str: &str,
mname: &str, mname: &str,
trait_did: Option<ast::DefId>, trait_did: Option<ast::DefId>,
ex: &ast::Expr, ex: &ast::Expr,
rhs_expr: @ast::Expr, rhs_expr: @ast::Expr,
rhs_t: ty::t) -> ty::t { 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, || { trait_did, [rhs_expr], DontAutoderefReceiver, || {
fcx.type_error_message(ex.span, |actual| { fcx.type_error_message(ex.span, |actual| {
format!("cannot apply unary operator `{}` to type `{}`", op_str, 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, match method::lookup(fcx,
expr, expr,
base, base,
expr.id,
field, field,
expr_t, expr_t,
tps, tps,
@ -2620,8 +2622,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
let typ = check_lit(fcx, lit); let typ = check_lit(fcx, lit);
fcx.write_ty(id, typ); fcx.write_ty(id, typ);
} }
ast::ExprBinary(callee_id, op, lhs, rhs) => { ast::ExprBinary(op, lhs, rhs) => {
check_binop(fcx, callee_id, expr, op, lhs, rhs, SimpleBinop); check_binop(fcx, expr, op, lhs, rhs, SimpleBinop);
let lhs_ty = fcx.expr_ty(lhs); let lhs_ty = fcx.expr_ty(lhs);
let rhs_ty = fcx.expr_ty(rhs); let rhs_ty = fcx.expr_ty(rhs);
@ -2634,8 +2636,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_bot(id); fcx.write_bot(id);
} }
} }
ast::ExprAssignOp(callee_id, op, lhs, rhs) => { ast::ExprAssignOp(op, lhs, rhs) => {
check_binop(fcx, callee_id, expr, op, lhs, rhs, BinopAssignment); check_binop(fcx, expr, op, lhs, rhs, BinopAssignment);
let lhs_t = fcx.expr_ty(lhs); let lhs_t = fcx.expr_ty(lhs);
let result_t = fcx.expr_ty(expr); let result_t = fcx.expr_ty(expr);
@ -2654,7 +2656,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_nil(expr.id); fcx.write_nil(expr.id);
} }
} }
ast::ExprUnary(callee_id, unop, oprnd) => { ast::ExprUnary(unop, oprnd) => {
let exp_inner = unpack_expected(fcx, expected, |sty| { let exp_inner = unpack_expected(fcx, expected, |sty| {
match unop { match unop {
ast::UnBox | ast::UnUniq => match *sty { ast::UnBox | ast::UnUniq => match *sty {
@ -2710,7 +2712,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
oprnd_t); oprnd_t);
if !(ty::type_is_integral(oprnd_t) || if !(ty::type_is_integral(oprnd_t) ||
ty::get(oprnd_t).sty == ty::ty_bool) { 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(), tcx.lang_items.not_trait(),
expr, oprnd, oprnd_t); expr, oprnd, oprnd_t);
} }
@ -2720,7 +2722,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
oprnd_t); oprnd_t);
if !(ty::type_is_integral(oprnd_t) || if !(ty::type_is_integral(oprnd_t) ||
ty::type_is_fp(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(), tcx.lang_items.neg_trait(),
expr, oprnd, oprnd_t); 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)); fcx.write_ty(id, fcx.node_ty(b.id));
} }
ast::ExprCall(f, ref args) => { 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 f_ty = fcx.expr_ty(f);
let (args_bot, args_err) = args.iter().fold((false, false), let (args_bot, args_err) = args.iter().fold((false, false),
|(rest_bot, rest_err), a| { |(rest_bot, rest_err), a| {
@ -2898,8 +2900,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
fcx.write_bot(id); fcx.write_bot(id);
} }
} }
ast::ExprMethodCall(callee_id, ident, ref tps, ref args) => { ast::ExprMethodCall(ident, ref tps, ref args) => {
check_method_call(fcx, callee_id, expr, ident, *args, *tps); check_method_call(fcx, expr, ident, *args, *tps);
let arg_tys = args.map(|a| fcx.expr_ty(*a)); let arg_tys = args.map(|a| fcx.expr_ty(*a));
let (args_bot, args_err) = arg_tys.iter().fold((false, false), let (args_bot, args_err) = arg_tys.iter().fold((false, false),
|(rest_bot, rest_err), a| { |(rest_bot, rest_err), a| {
@ -3100,7 +3102,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
ast::ExprField(base, field, ref tys) => { ast::ExprField(base, field, ref tys) => {
check_field(fcx, expr, base, field.name, *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, base);
check_expr(fcx, idx); check_expr(fcx, idx);
let raw_base_t = fcx.expr_ty(base); let raw_base_t = fcx.expr_ty(base);
@ -3133,7 +3135,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
None); None);
}; };
let ret_ty = lookup_op_method(fcx, let ret_ty = lookup_op_method(fcx,
callee_id,
expr, expr,
resolved, resolved,
token::intern("index"), token::intern("index"),

View file

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

View file

@ -537,11 +537,10 @@ fn connect_trait_tps(vcx: &VtableContext,
relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref); relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref);
} }
fn insert_vtables(fcx: &FnCtxt, callee_id: ast::NodeId, vtables: vtable_res) { fn insert_vtables(fcx: &FnCtxt, expr_id: ast::NodeId, vtables: vtable_res) {
debug!("insert_vtables(callee_id={}, vtables={:?})", debug!("insert_vtables(expr_id={}, vtables={:?})",
callee_id, vtables.repr(fcx.tcx())); expr_id, vtables.repr(fcx.tcx()));
let mut vtable_map = fcx.inh.vtable_map.borrow_mut(); fcx.inh.vtable_map.borrow_mut().get().insert(expr_id, vtables);
vtable_map.get().insert(callee_id, vtables);
} }
pub fn location_info_for_expr(expr: &ast::Expr) -> LocationInfo { 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 // Must resolve bounds on methods with bounded params
ast::ExprBinary(callee_id, _, _, _) | ast::ExprBinary(_, _, _) |
ast::ExprUnary(callee_id, _, _) | ast::ExprUnary(_, _) |
ast::ExprAssignOp(callee_id, _, _, _) | ast::ExprAssignOp(_, _, _) |
ast::ExprIndex(callee_id, _, _) | ast::ExprIndex(_, _) |
ast::ExprMethodCall(callee_id, _, _, _) => { ast::ExprMethodCall(_, _, _) => {
match fcx.inh.method_map.borrow().get().find(&ex.id) { match fcx.inh.method_map.borrow().get().find(&ex.id) {
Some(origin) => { Some(method) => {
debug!("vtable resolution on parameter bounds for method call {}", debug!("vtable resolution on parameter bounds for method call {}",
ex.repr(fcx.tcx())); 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()) { 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 vcx = fcx.vtable_context();
let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex), let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex),
*type_param_defs.borrow(), &substs, is_early); *type_param_defs.borrow(), &substs, is_early);
if !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::{force_all, resolve_all, resolve_region};
use middle::typeck::infer::resolve_type; use middle::typeck::infer::resolve_type;
use middle::typeck::infer; use middle::typeck::infer;
use middle::typeck::MethodCallee;
use middle::typeck::{vtable_res, vtable_origin}; use middle::typeck::{vtable_res, vtable_origin};
use middle::typeck::{vtable_static, vtable_param}; use middle::typeck::{vtable_static, vtable_param};
use middle::typeck::write_substs_to_tcx; 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 // Resolve any method map entry
let method_map_entry_opt = { match fcx.inh.method_map.borrow().get().find(&id) {
let method_map = fcx.inh.method_map.borrow(); Some(method) => {
method_map.get().find_copy(&id) debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})",
}; id, method.repr(tcx));
match method_map_entry_opt { let method_ty = match resolve_type_vars_in_type(fcx, sp, method.ty) {
None => {} Some(t) => t,
Some(mme) => { None => {
debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})", id, mme); wbcx.success = false;
let mut method_map = fcx.ccx.method_map.borrow_mut(); return;
method_map.get().insert(id, mme); }
};
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) { fn resolve_vtable_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
// Resolve any method map entry // Resolve any vtable map entry
{ match fcx.inh.vtable_map.borrow().get().find_copy(&id) {
let origins_opt = { Some(origins) => {
let vtable_map = fcx.inh.vtable_map.borrow(); let r_origins = resolve_origins(fcx, sp, origins);
vtable_map.get().find_copy(&id) fcx.ccx.vtable_map.borrow_mut().get().insert(id, r_origins);
}; debug!("writeback::resolve_vtable_map_entry(id={}, vtables={:?})",
match origins_opt { id, r_origins.repr(fcx.tcx()));
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()));
}
} }
None => {}
} }
fn resolve_origins(fcx: @FnCtxt, sp: Span, 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 { struct WbCtxt {
fcx: @FnCtxt, 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_type_vars_for_node(wbcx, e.span, e.id);
resolve_method_map_entry(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_vtable_map_entry(wbcx.fcx, 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 { match e.node {
ast::ExprFnBlock(ref decl, _) | ast::ExprProc(ref decl, _) => { 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); 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, ()); visit::walk_expr(wbcx, e, ());

View file

@ -142,9 +142,16 @@ pub struct MethodObject {
real_index: uint, 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 // maps from an expression id that corresponds to a method call to the details
// of the method to be invoked // 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]; pub type vtable_param_res = @~[vtable_origin];
// Resolutions for bounds of all parameters, left to right, for a given path. // 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)) => { Some(ast_map::NodeBlock(ref blk)) => {
explain_span(cx, "block", blk.span) explain_span(cx, "block", blk.span)
} }
Some(ast_map::NodeCalleeScope(expr)) => {
explain_span(cx, "callee", expr.span)
}
Some(ast_map::NodeExpr(expr)) => { Some(ast_map::NodeExpr(expr)) => {
match expr.node { match expr.node {
ast::ExprCall(..) => explain_span(cx, "call", expr.span), 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 { impl Repr for typeck::MethodOrigin {
fn repr(&self, tcx: ctxt) -> ~str { fn repr(&self, tcx: ctxt) -> ~str {
match self { match self {

View file

@ -521,19 +521,6 @@ pub struct Expr {
span: Span, 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)] #[deriving(Clone, Eq, Encodable, Decodable, Hash)]
pub enum Expr_ { pub enum Expr_ {
ExprVstore(@Expr, ExprVstore), ExprVstore(@Expr, ExprVstore),
@ -541,10 +528,10 @@ pub enum Expr_ {
ExprBox(@Expr, @Expr), ExprBox(@Expr, @Expr),
ExprVec(~[@Expr], Mutability), ExprVec(~[@Expr], Mutability),
ExprCall(@Expr, ~[@Expr]), ExprCall(@Expr, ~[@Expr]),
ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr]), ExprMethodCall(Ident, ~[P<Ty>], ~[@Expr]),
ExprTup(~[@Expr]), ExprTup(~[@Expr]),
ExprBinary(NodeId, BinOp, @Expr, @Expr), ExprBinary(BinOp, @Expr, @Expr),
ExprUnary(NodeId, UnOp, @Expr), ExprUnary(UnOp, @Expr),
ExprLit(@Lit), ExprLit(@Lit),
ExprCast(@Expr, P<Ty>), ExprCast(@Expr, P<Ty>),
ExprIf(@Expr, P<Block>, Option<@Expr>), ExprIf(@Expr, P<Block>, Option<@Expr>),
@ -560,9 +547,9 @@ pub enum Expr_ {
ExprBlock(P<Block>), ExprBlock(P<Block>),
ExprAssign(@Expr, @Expr), ExprAssign(@Expr, @Expr),
ExprAssignOp(NodeId, BinOp, @Expr, @Expr), ExprAssignOp(BinOp, @Expr, @Expr),
ExprField(@Expr, Ident, ~[P<Ty>]), ExprField(@Expr, Ident, ~[P<Ty>]),
ExprIndex(NodeId, @Expr, @Expr), ExprIndex(@Expr, @Expr),
/// Expression that looks like a "name". For example, /// Expression that looks like a "name". For example,
/// `std::vec::from_elem::<uint>` is an ExprPath that's the "name" part /// `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 represents a tuple struct.
NodeStructCtor(@StructDef), NodeStructCtor(@StructDef),
NodeCalleeScope(@Expr),
} }
// The odd layout is to bring down the total size. // The odd layout is to bring down the total size.
@ -128,7 +127,6 @@ enum MapEntry {
EntryLocal(NodeId, @Pat), EntryLocal(NodeId, @Pat),
EntryBlock(NodeId, P<Block>), EntryBlock(NodeId, P<Block>),
EntryStructCtor(NodeId, @StructDef), EntryStructCtor(NodeId, @StructDef),
EntryCalleeScope(NodeId, @Expr),
// Roots for node trees. // Roots for node trees.
RootCrate, RootCrate,
@ -155,7 +153,6 @@ impl MapEntry {
EntryLocal(id, _) => id, EntryLocal(id, _) => id,
EntryBlock(id, _) => id, EntryBlock(id, _) => id,
EntryStructCtor(id, _) => id, EntryStructCtor(id, _) => id,
EntryCalleeScope(id, _) => id,
_ => return None _ => return None
}) })
} }
@ -173,7 +170,6 @@ impl MapEntry {
EntryLocal(_, p) => NodeLocal(p), EntryLocal(_, p) => NodeLocal(p),
EntryBlock(_, p) => NodeBlock(p), EntryBlock(_, p) => NodeBlock(p),
EntryStructCtor(_, p) => NodeStructCtor(p), EntryStructCtor(_, p) => NodeStructCtor(p),
EntryCalleeScope(_, p) => NodeCalleeScope(p),
_ => return None _ => return None
}) })
} }
@ -368,7 +364,6 @@ impl Map {
Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span, Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
Some(NodeBlock(block)) => block.span, Some(NodeBlock(block)) => block.span,
Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).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), _ => 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)); 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 expr
} }
@ -650,9 +640,6 @@ fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
Some(NodeExpr(expr)) => { Some(NodeExpr(expr)) => {
format!("expr {} (id={})", pprust::expr_to_str(expr), id) 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)) => { Some(NodeStmt(stmt)) => {
format!("stmt {} (id={})", pprust::stmt_to_str(stmt), id) 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: ()) { 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); self.operation.visit_id(expression.id);
visit::walk_expr(self, expression, env) 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, fn expr_binary(&self, sp: Span, op: ast::BinOp,
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr { 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 { fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
self.expr_unary(sp, ast::UnDeref, e) self.expr_unary(sp, ast::UnDeref, e)
} }
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr {
-> @ast::Expr { self.expr(sp, ast::ExprUnary(op, e))
self.expr(sp, ast::ExprUnary(ast::DUMMY_NODE_ID, op, e))
} }
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr { fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
@ -543,7 +542,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ident: ast::Ident, ident: ast::Ident,
mut args: ~[@ast::Expr]) -> @ast::Expr { mut args: ~[@ast::Expr]) -> @ast::Expr {
args.unshift(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 { fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
self.expr(b.span, ast::ExprBlock(b)) 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), ExprCall(folder.fold_expr(f),
args.map(|&x| folder.fold_expr(x))) args.map(|&x| folder.fold_expr(x)))
} }
ExprMethodCall(callee_id, i, ref tps, ref args) => { ExprMethodCall(i, ref tps, ref args) => {
ExprMethodCall( ExprMethodCall(
folder.new_id(callee_id),
folder.fold_ident(i), folder.fold_ident(i),
tps.map(|&x| folder.fold_ty(x)), tps.map(|&x| folder.fold_ty(x)),
args.map(|&x| folder.fold_expr(x))) args.map(|&x| folder.fold_expr(x)))
} }
ExprBinary(callee_id, binop, lhs, rhs) => { ExprBinary(binop, lhs, rhs) => {
ExprBinary(folder.new_id(callee_id), ExprBinary(binop,
binop,
folder.fold_expr(lhs), folder.fold_expr(lhs),
folder.fold_expr(rhs)) folder.fold_expr(rhs))
} }
ExprUnary(callee_id, binop, ohs) => { ExprUnary(binop, ohs) => {
ExprUnary(folder.new_id(callee_id), binop, folder.fold_expr(ohs)) ExprUnary(binop, folder.fold_expr(ohs))
} }
ExprLit(_) => e.node.clone(), ExprLit(_) => e.node.clone(),
ExprCast(expr, ty) => { ExprCast(expr, ty) => {
@ -802,9 +800,8 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
ExprAssign(el, er) => { ExprAssign(el, er) => {
ExprAssign(folder.fold_expr(el), folder.fold_expr(er)) ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
} }
ExprAssignOp(callee_id, op, el, er) => { ExprAssignOp(op, el, er) => {
ExprAssignOp(folder.new_id(callee_id), ExprAssignOp(op,
op,
folder.fold_expr(el), folder.fold_expr(el),
folder.fold_expr(er)) 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), folder.fold_ident(id),
tys.map(|&x| folder.fold_ty(x))) tys.map(|&x| folder.fold_ty(x)))
} }
ExprIndex(callee_id, el, er) => { ExprIndex(el, er) => {
ExprIndex(folder.new_id(callee_id), ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
folder.fold_expr(el),
folder.fold_expr(er))
} }
ExprPath(ref pth) => ExprPath(folder.fold_path(pth)), ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
ExprLogLevel => ExprLogLevel, ExprLogLevel => ExprLogLevel,

View file

@ -1683,11 +1683,11 @@ impl Parser {
} }
pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ { 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_ { 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_ { 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_ { 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_ { 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_ { 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_ { 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 { 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_expr(s, func));
try!(print_call_post(s, *args)); 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); let base_args = args.slice_from(1);
try!(print_expr(s, args[0])); try!(print_expr(s, args[0]));
try!(word(&mut s.s, ".")); 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)); try!(print_call_post(s, base_args));
} }
ast::ExprBinary(_, op, lhs, rhs) => { ast::ExprBinary(op, lhs, rhs) => {
try!(print_expr(s, lhs)); try!(print_expr(s, lhs));
try!(space(&mut s.s)); try!(space(&mut s.s));
try!(word_space(s, ast_util::binop_to_str(op))); try!(word_space(s, ast_util::binop_to_str(op)));
try!(print_expr(s, rhs)); 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!(word(&mut s.s, ast_util::unop_to_str(op)));
try!(print_expr(s, expr)); 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!(word_space(s, "="));
try!(print_expr(s, rhs)); try!(print_expr(s, rhs));
} }
ast::ExprAssignOp(_, op, lhs, rhs) => { ast::ExprAssignOp(op, lhs, rhs) => {
try!(print_expr(s, lhs)); try!(print_expr(s, lhs));
try!(space(&mut s.s)); try!(space(&mut s.s));
try!(word(&mut s.s, ast_util::binop_to_str(op))); 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, ">")); try!(word(&mut s.s, ">"));
} }
} }
ast::ExprIndex(_, expr, index) => { ast::ExprIndex(expr, index) => {
try!(print_expr(s, expr)); try!(print_expr(s, expr));
try!(word(&mut s.s, "[")); try!(word(&mut s.s, "["));
try!(print_expr(s, index)); 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()) visitor.visit_expr(callee_expression, env.clone())
} }
ExprMethodCall(_, _, ref types, ref arguments) => { ExprMethodCall(_, ref types, ref arguments) => {
walk_exprs(visitor, *arguments, env.clone()); walk_exprs(visitor, *arguments, env.clone());
for &typ in types.iter() { for &typ in types.iter() {
visitor.visit_ty(typ, env.clone()) 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(left_expression, env.clone());
visitor.visit_expr(right_expression, env.clone()) visitor.visit_expr(right_expression, env.clone())
} }
ExprAddrOf(_, subexpression) | ExprAddrOf(_, subexpression) | ExprUnary(_, subexpression) => {
ExprUnary(_, _, subexpression) => {
visitor.visit_expr(subexpression, env.clone()) visitor.visit_expr(subexpression, env.clone())
} }
ExprLit(_) => {} 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(right_hand_expression, env.clone());
visitor.visit_expr(left_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(right_expression, env.clone());
visitor.visit_expr(left_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()) 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(main_expression, env.clone());
visitor.visit_expr(index_expression, env.clone()) visitor.visit_expr(index_expression, env.clone())
} }