Replace callee_id with information stored in method_map.
This commit is contained in:
parent
7a588ceff2
commit
05e4d944a9
@ -255,7 +255,7 @@ impl Visitor<()> for Context {
|
||||
|
||||
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
|
||||
match e.node {
|
||||
ast::ExprUnary(_, ast::UnBox, _) => {
|
||||
ast::ExprUnary(ast::UnBox, _) => {
|
||||
self.gate_box(e.span);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -21,7 +21,7 @@ use metadata::tydecode;
|
||||
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
|
||||
RegionParameter};
|
||||
use metadata::tyencode;
|
||||
use middle::typeck::method_origin;
|
||||
use middle::typeck::{MethodCallee, MethodOrigin};
|
||||
use middle::{ty, typeck, moves};
|
||||
use middle;
|
||||
use util::ppaux::ty_to_str;
|
||||
@ -574,10 +574,50 @@ impl tr for moves::CaptureVar {
|
||||
}
|
||||
|
||||
// ______________________________________________________________________
|
||||
// Encoding and decoding of method_origin
|
||||
// Encoding and decoding of MethodCallee
|
||||
|
||||
impl tr for method_origin {
|
||||
fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin {
|
||||
trait read_method_callee_helper {
|
||||
fn read_method_callee(&mut self, xcx: @ExtendedDecodeContext) -> MethodCallee;
|
||||
}
|
||||
|
||||
fn encode_method_callee(ecx: &e::EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
method: &MethodCallee) {
|
||||
ebml_w.emit_struct("MethodCallee", 3, |ebml_w| {
|
||||
ebml_w.emit_struct_field("origin", 0u, |ebml_w| {
|
||||
method.origin.encode(ebml_w);
|
||||
});
|
||||
ebml_w.emit_struct_field("ty", 1u, |ebml_w| {
|
||||
ebml_w.emit_ty(ecx, method.ty);
|
||||
});
|
||||
ebml_w.emit_struct_field("substs", 2u, |ebml_w| {
|
||||
ebml_w.emit_substs(ecx, &method.substs);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> read_method_callee_helper for reader::Decoder<'a> {
|
||||
fn read_method_callee(&mut self, xcx: @ExtendedDecodeContext) -> MethodCallee {
|
||||
self.read_struct("MethodCallee", 3, |this| {
|
||||
MethodCallee {
|
||||
origin: this.read_struct_field("origin", 0, |this| {
|
||||
let method_origin: MethodOrigin =
|
||||
Decodable::decode(this);
|
||||
method_origin.tr(xcx)
|
||||
}),
|
||||
ty: this.read_struct_field("ty", 1, |this| {
|
||||
this.read_ty(xcx)
|
||||
}),
|
||||
substs: this.read_struct_field("substs", 2, |this| {
|
||||
this.read_substs(xcx)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl tr for MethodOrigin {
|
||||
fn tr(&self, xcx: @ExtendedDecodeContext) -> MethodOrigin {
|
||||
match *self {
|
||||
typeck::MethodStatic(did) => typeck::MethodStatic(did.tr(xcx)),
|
||||
typeck::MethodParam(ref mp) => {
|
||||
@ -991,17 +1031,13 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let method_map = maps.method_map.borrow();
|
||||
let r = method_map.get().find(&id);
|
||||
for &origin in r.iter() {
|
||||
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
|
||||
ebml_w.id(id);
|
||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||
origin.encode(ebml_w);
|
||||
})
|
||||
for &method in maps.method_map.borrow().get().find(&id).iter() {
|
||||
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
|
||||
ebml_w.id(id);
|
||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||
encode_method_callee(ecx, ebml_w, method)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
@ -1335,9 +1371,8 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
|
||||
ty_param_defs.get().insert(id, bounds);
|
||||
}
|
||||
c::tag_table_method_map => {
|
||||
let origin: method_origin = Decodable::decode(val_dsr);
|
||||
let mut method_map = dcx.maps.method_map.borrow_mut();
|
||||
method_map.get().insert(id, origin.tr(xcx));
|
||||
let method = val_dsr.read_method_callee(xcx);
|
||||
dcx.maps.method_map.borrow_mut().get().insert(id, method);
|
||||
}
|
||||
c::tag_table_vtable_map => {
|
||||
let vtable_res =
|
||||
|
@ -784,7 +784,6 @@ impl<'a> CheckLoanCtxt<'a> {
|
||||
pub fn check_call(&self,
|
||||
_expr: &ast::Expr,
|
||||
_callee: Option<@ast::Expr>,
|
||||
_callee_id: ast::NodeId,
|
||||
_callee_span: Span,
|
||||
_args: &[@ast::Expr]) {
|
||||
// NB: This call to check for conflicting loans is not truly
|
||||
@ -828,23 +827,22 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
|
||||
this.check_captured_variables(expr.id, expr.span)
|
||||
}
|
||||
ast::ExprAssign(dest, _) |
|
||||
ast::ExprAssignOp(_, _, dest, _) => {
|
||||
ast::ExprAssignOp(_, dest, _) => {
|
||||
this.check_assignment(dest);
|
||||
}
|
||||
ast::ExprCall(f, ref args) => {
|
||||
this.check_call(expr, Some(f), f.id, f.span, *args);
|
||||
this.check_call(expr, Some(f), f.span, *args);
|
||||
}
|
||||
ast::ExprMethodCall(callee_id, _, _, ref args) => {
|
||||
this.check_call(expr, None, callee_id, expr.span, *args);
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
this.check_call(expr, None, expr.span, *args);
|
||||
}
|
||||
ast::ExprIndex(callee_id, _, rval) |
|
||||
ast::ExprBinary(callee_id, _, _, rval)
|
||||
ast::ExprIndex(_, rval) | ast::ExprBinary(_, _, rval)
|
||||
if method_map.get().contains_key(&expr.id) => {
|
||||
this.check_call(expr, None, callee_id, expr.span, [rval]);
|
||||
this.check_call(expr, None, expr.span, [rval]);
|
||||
}
|
||||
ast::ExprUnary(callee_id, _, _) | ast::ExprIndex(callee_id, _, _)
|
||||
ast::ExprUnary(_, _) | ast::ExprIndex(_, _)
|
||||
if method_map.get().contains_key(&expr.id) => {
|
||||
this.check_call(expr, None, callee_id, expr.span, []);
|
||||
this.check_call(expr, None, expr.span, []);
|
||||
}
|
||||
ast::ExprInlineAsm(ref ia) => {
|
||||
for &(_, out) in ia.outputs.iter() {
|
||||
|
@ -181,20 +181,9 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
|
||||
|
||||
this.id_range.add(ex.id);
|
||||
|
||||
{
|
||||
let r = ex.get_callee_id();
|
||||
for callee_id in r.iter() {
|
||||
this.id_range.add(*callee_id);
|
||||
}
|
||||
}
|
||||
|
||||
// If this expression is borrowed, have to ensure it remains valid:
|
||||
{
|
||||
let adjustments = tcx.adjustments.borrow();
|
||||
let r = adjustments.get().find(&ex.id);
|
||||
for &adjustments in r.iter() {
|
||||
this.guarantee_adjustments(ex, *adjustments);
|
||||
}
|
||||
for &adjustments in tcx.adjustments.borrow().get().find(&ex.id).iter() {
|
||||
this.guarantee_adjustments(ex, *adjustments);
|
||||
}
|
||||
|
||||
// If this expression is a move, gather it:
|
||||
@ -225,7 +214,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
|
||||
visit::walk_expr(this, ex, ());
|
||||
}
|
||||
|
||||
ast::ExprAssign(l, _) | ast::ExprAssignOp(_, _, l, _) => {
|
||||
ast::ExprAssign(l, _) | ast::ExprAssignOp(_, l, _) => {
|
||||
let l_cmt = this.bccx.cat_expr(l);
|
||||
match opt_loan_path(l_cmt) {
|
||||
Some(l_lp) => {
|
||||
@ -252,8 +241,8 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
|
||||
visit::walk_expr(this, ex, ());
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, _, arg) |
|
||||
ast::ExprBinary(_, _, _, arg)
|
||||
ast::ExprIndex(_, arg) |
|
||||
ast::ExprBinary(_, _, arg)
|
||||
if method_map.get().contains_key(&ex.id) => {
|
||||
// Arguments in method calls are always passed by ref.
|
||||
//
|
||||
|
@ -305,7 +305,7 @@ impl CFGBuilder {
|
||||
expr_exit
|
||||
}
|
||||
|
||||
ast::ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
|
||||
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
|
||||
//
|
||||
// [pred]
|
||||
// |
|
||||
@ -355,16 +355,16 @@ impl CFGBuilder {
|
||||
self.call(expr, pred, func, *args)
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(_, _, _, ref args) => {
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
self.call(expr, pred, args[0], args.slice_from(1))
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, l, r) |
|
||||
ast::ExprBinary(_, _, l, r) if self.is_method_call(expr) => {
|
||||
ast::ExprIndex(l, r) |
|
||||
ast::ExprBinary(_, l, r) if self.is_method_call(expr) => {
|
||||
self.call(expr, pred, l, [r])
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, _, e) if self.is_method_call(expr) => {
|
||||
ast::ExprUnary(_, e) if self.is_method_call(expr) => {
|
||||
self.call(expr, pred, e, [])
|
||||
}
|
||||
|
||||
@ -384,12 +384,12 @@ impl CFGBuilder {
|
||||
}
|
||||
|
||||
ast::ExprAssign(l, r) |
|
||||
ast::ExprAssignOp(_, _, l, r) => {
|
||||
ast::ExprAssignOp(_, l, r) => {
|
||||
self.straightline(expr, pred, [r, l])
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, l, r) |
|
||||
ast::ExprBinary(_, _, l, r) => { // NB: && and || handled earlier
|
||||
ast::ExprIndex(l, r) |
|
||||
ast::ExprBinary(_, l, r) => { // NB: && and || handled earlier
|
||||
self.straightline(expr, pred, [l, r])
|
||||
}
|
||||
|
||||
@ -399,7 +399,7 @@ impl CFGBuilder {
|
||||
|
||||
ast::ExprAddrOf(_, e) |
|
||||
ast::ExprCast(e, _) |
|
||||
ast::ExprUnary(_, _, e) |
|
||||
ast::ExprUnary(_, e) |
|
||||
ast::ExprParen(e) |
|
||||
ast::ExprVstore(e, _) |
|
||||
ast::ExprField(e, _, _) => {
|
||||
|
@ -108,8 +108,8 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
|
||||
is_const: bool) {
|
||||
if is_const {
|
||||
match e.node {
|
||||
ExprUnary(_, UnDeref, _) => { }
|
||||
ExprUnary(_, UnBox, _) | ExprUnary(_, UnUniq, _) => {
|
||||
ExprUnary(UnDeref, _) => { }
|
||||
ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
|
||||
sess.span_err(e.span,
|
||||
"cannot do allocations in constant expressions");
|
||||
return;
|
||||
|
@ -225,10 +225,10 @@ impl ConstEvalVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, _, inner) | ast::ExprParen(inner) =>
|
||||
ast::ExprUnary(_, inner) | ast::ExprParen(inner) =>
|
||||
self.classify(inner),
|
||||
|
||||
ast::ExprBinary(_, _, a, b) =>
|
||||
ast::ExprBinary(_, a, b) =>
|
||||
join(self.classify(a), self.classify(b)),
|
||||
|
||||
ast::ExprTup(ref es) |
|
||||
@ -262,7 +262,7 @@ impl ConstEvalVisitor {
|
||||
|
||||
ast::ExprField(base, _, _) => self.classify(base),
|
||||
|
||||
ast::ExprIndex(_, base, idx) =>
|
||||
ast::ExprIndex(base, idx) =>
|
||||
join(self.classify(base), self.classify(idx)),
|
||||
|
||||
ast::ExprAddrOf(ast::MutImmutable, base) => self.classify(base),
|
||||
@ -336,7 +336,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
|
||||
use middle::ty;
|
||||
fn fromb(b: bool) -> Result<const_val, ~str> { Ok(const_int(b as i64)) }
|
||||
match e.node {
|
||||
ExprUnary(_, UnNeg, inner) => {
|
||||
ExprUnary(UnNeg, inner) => {
|
||||
match eval_const_expr_partial(tcx, inner) {
|
||||
Ok(const_float(f)) => Ok(const_float(-f)),
|
||||
Ok(const_int(i)) => Ok(const_int(-i)),
|
||||
@ -346,7 +346,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
|
||||
ref err => ((*err).clone())
|
||||
}
|
||||
}
|
||||
ExprUnary(_, UnNot, inner) => {
|
||||
ExprUnary(UnNot, inner) => {
|
||||
match eval_const_expr_partial(tcx, inner) {
|
||||
Ok(const_int(i)) => Ok(const_int(!i)),
|
||||
Ok(const_uint(i)) => Ok(const_uint(!i)),
|
||||
@ -354,7 +354,7 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
|
||||
_ => Err(~"not on float or string")
|
||||
}
|
||||
}
|
||||
ExprBinary(_, op, a, b) => {
|
||||
ExprBinary(op, a, b) => {
|
||||
match (eval_const_expr_partial(tcx, a),
|
||||
eval_const_expr_partial(tcx, b)) {
|
||||
(Ok(const_float(a)), Ok(const_float(b))) => {
|
||||
|
@ -556,7 +556,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
|
||||
}
|
||||
|
||||
ast::ExprAssign(l, r) |
|
||||
ast::ExprAssignOp(_, _, l, r) => {
|
||||
ast::ExprAssignOp(_, l, r) => {
|
||||
self.walk_expr(r, in_out, loop_scopes);
|
||||
self.walk_expr(l, in_out, loop_scopes);
|
||||
}
|
||||
@ -579,35 +579,35 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
|
||||
|
||||
ast::ExprCall(f, ref args) => {
|
||||
self.walk_expr(f, in_out, loop_scopes);
|
||||
self.walk_call(f.id, expr.id, *args, in_out, loop_scopes);
|
||||
self.walk_call(expr.id, *args, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(callee_id, _, _, ref args) => {
|
||||
self.walk_call(callee_id, expr.id, *args, in_out, loop_scopes);
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
self.walk_call(expr.id, *args, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprIndex(callee_id, l, r) |
|
||||
ast::ExprBinary(callee_id, _, l, r) if self.is_method_call(expr) => {
|
||||
self.walk_call(callee_id, expr.id, [l, r], in_out, loop_scopes);
|
||||
ast::ExprIndex(l, r) |
|
||||
ast::ExprBinary(_, l, r) if self.is_method_call(expr) => {
|
||||
self.walk_call(expr.id, [l, r], in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprUnary(callee_id, _, e) if self.is_method_call(expr) => {
|
||||
self.walk_call(callee_id, expr.id, [e], in_out, loop_scopes);
|
||||
ast::ExprUnary(_, e) if self.is_method_call(expr) => {
|
||||
self.walk_call(expr.id, [e], in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprTup(ref exprs) => {
|
||||
self.walk_exprs(*exprs, in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
|
||||
ast::ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
|
||||
self.walk_expr(l, in_out, loop_scopes);
|
||||
let temp = in_out.to_owned();
|
||||
self.walk_expr(r, in_out, loop_scopes);
|
||||
join_bits(&self.dfcx.oper, temp, in_out);
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, l, r) |
|
||||
ast::ExprBinary(_, _, l, r) => {
|
||||
ast::ExprIndex(l, r) |
|
||||
ast::ExprBinary(_, l, r) => {
|
||||
self.walk_exprs([l, r], in_out, loop_scopes);
|
||||
}
|
||||
|
||||
@ -617,7 +617,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
|
||||
|
||||
ast::ExprAddrOf(_, e) |
|
||||
ast::ExprCast(e, _) |
|
||||
ast::ExprUnary(_, _, e) |
|
||||
ast::ExprUnary(_, e) |
|
||||
ast::ExprParen(e) |
|
||||
ast::ExprVstore(e, _) |
|
||||
ast::ExprField(e, _, _) => {
|
||||
@ -715,7 +715,6 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
|
||||
}
|
||||
|
||||
fn walk_call(&mut self,
|
||||
_callee_id: ast::NodeId,
|
||||
call_id: ast::NodeId,
|
||||
args: &[@ast::Expr],
|
||||
in_out: &mut [uint],
|
||||
@ -723,8 +722,8 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
|
||||
self.walk_exprs(args, in_out, loop_scopes);
|
||||
|
||||
// FIXME(#6268) nested method calls
|
||||
// self.merge_with_entry_set(callee_id, in_out);
|
||||
// self.dfcx.apply_gen_kill(callee_id, in_out);
|
||||
// self.merge_with_entry_set(in_out);
|
||||
// self.dfcx.apply_gen_kill(in_out);
|
||||
|
||||
let return_ty = ty::node_id_to_type(self.tcx(), call_id);
|
||||
let fails = ty::type_is_bot(return_ty);
|
||||
|
@ -92,10 +92,9 @@ impl MarkSymbolVisitor {
|
||||
|
||||
fn lookup_and_handle_method(&mut self, id: &ast::NodeId,
|
||||
span: codemap::Span) {
|
||||
let method_map = self.method_map.borrow();
|
||||
match method_map.get().find(id) {
|
||||
Some(&origin) => {
|
||||
match origin {
|
||||
match self.method_map.borrow().get().find(id) {
|
||||
Some(method) => {
|
||||
match method.origin {
|
||||
typeck::MethodStatic(def_id) => {
|
||||
match ty::provided_source(self.tcx, def_id) {
|
||||
Some(p_did) => self.check_def_id(p_did),
|
||||
|
@ -65,7 +65,7 @@ impl EffectCheckVisitor {
|
||||
|
||||
fn check_str_index(&mut self, e: @ast::Expr) {
|
||||
let base_type = match e.node {
|
||||
ast::ExprIndex(_, base, _) => ty::node_id_to_type(self.tcx, base.id),
|
||||
ast::ExprIndex(base, _) => ty::node_id_to_type(self.tcx, base.id),
|
||||
_ => return
|
||||
};
|
||||
debug!("effect: checking index with base type {}",
|
||||
@ -137,8 +137,8 @@ impl Visitor<()> for EffectCheckVisitor {
|
||||
|
||||
fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
|
||||
match expr.node {
|
||||
ast::ExprMethodCall(callee_id, _, _, _) => {
|
||||
let base_type = ty::node_id_to_type(self.tcx, callee_id);
|
||||
ast::ExprMethodCall(_, _, _) => {
|
||||
let base_type = self.method_map.borrow().get().get(&expr.id).ty;
|
||||
debug!("effect: method call case, base type is {}",
|
||||
ppaux::ty_to_str(self.tcx, base_type));
|
||||
if type_is_unsafe_function(base_type) {
|
||||
@ -154,7 +154,7 @@ impl Visitor<()> for EffectCheckVisitor {
|
||||
self.require_unsafe(expr.span, "call to unsafe function")
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(_, ast::UnDeref, base) => {
|
||||
ast::ExprUnary(ast::UnDeref, base) => {
|
||||
let base_type = ty::node_id_to_type(self.tcx, base.id);
|
||||
debug!("effect: unary case, base type is {}",
|
||||
ppaux::ty_to_str(self.tcx, base_type));
|
||||
@ -166,7 +166,7 @@ impl Visitor<()> for EffectCheckVisitor {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
ast::ExprAssign(base, _) | ast::ExprAssignOp(_, _, base, _) => {
|
||||
ast::ExprAssign(base, _) | ast::ExprAssignOp(_, base, _) => {
|
||||
self.check_str_index(base);
|
||||
}
|
||||
ast::ExprAddrOf(ast::MutMutable, base) => {
|
||||
|
@ -264,13 +264,14 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
|
||||
debug!("kind::check_expr({})", expr_to_str(e));
|
||||
|
||||
// Handle any kind bounds on type parameters
|
||||
let type_parameter_id = match e.get_callee_id() {
|
||||
Some(callee_id) => callee_id,
|
||||
None => e.id,
|
||||
};
|
||||
{
|
||||
let method_map = cx.method_map.borrow();
|
||||
let method = method_map.get().find(&e.id);
|
||||
let node_type_substs = cx.tcx.node_type_substs.borrow();
|
||||
let r = node_type_substs.get().find(&type_parameter_id);
|
||||
let r = match method {
|
||||
Some(method) => Some(&method.substs.tps),
|
||||
None => node_type_substs.get().find(&e.id)
|
||||
};
|
||||
for ts in r.iter() {
|
||||
let def_map = cx.tcx.def_map.borrow();
|
||||
let type_param_defs = match e.node {
|
||||
@ -285,9 +286,9 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
|
||||
|
||||
// Even though the callee_id may have been the id with
|
||||
// node_type_substs, e.id is correct here.
|
||||
match cx.method_map.borrow().get().find(&e.id) {
|
||||
Some(origin) => {
|
||||
ty::method_call_type_param_defs(cx.tcx, *origin)
|
||||
match method {
|
||||
Some(method) => {
|
||||
ty::method_call_type_param_defs(cx.tcx, method.origin)
|
||||
}
|
||||
None => {
|
||||
cx.tcx.sess.span_bug(e.span,
|
||||
@ -306,13 +307,13 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
|
||||
type_param_defs.repr(cx.tcx));
|
||||
}
|
||||
for (&ty, type_param_def) in ts.iter().zip(type_param_defs.iter()) {
|
||||
check_typaram_bounds(cx, type_parameter_id, e.span, ty, type_param_def)
|
||||
check_typaram_bounds(cx, e.span, ty, type_param_def)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match e.node {
|
||||
ExprUnary(_, UnBox, interior) => {
|
||||
ExprUnary(UnBox, interior) => {
|
||||
let interior_type = ty::expr_ty(cx.tcx, interior);
|
||||
let _ = check_durable(cx.tcx, interior_type, interior.span);
|
||||
}
|
||||
@ -373,7 +374,7 @@ fn check_ty(cx: &mut Context, aty: &Ty) {
|
||||
let generics = ty::lookup_item_type(cx.tcx, did).generics;
|
||||
let type_param_defs = generics.type_param_defs();
|
||||
for (&ty, type_param_def) in ts.iter().zip(type_param_defs.iter()) {
|
||||
check_typaram_bounds(cx, aty.id, aty.span, ty, type_param_def)
|
||||
check_typaram_bounds(cx, aty.span, ty, type_param_def)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -400,11 +401,9 @@ pub fn check_builtin_bounds(cx: &Context,
|
||||
}
|
||||
|
||||
pub fn check_typaram_bounds(cx: &Context,
|
||||
_type_parameter_id: NodeId,
|
||||
sp: Span,
|
||||
ty: ty::t,
|
||||
type_param_def: &ty::TypeParameterDef)
|
||||
{
|
||||
sp: Span,
|
||||
ty: ty::t,
|
||||
type_param_def: &ty::TypeParameterDef) {
|
||||
check_builtin_bounds(cx,
|
||||
ty,
|
||||
type_param_def.bounds.builtin_bounds,
|
||||
|
@ -674,7 +674,7 @@ fn check_unused_casts(cx: &Context, e: &ast::Expr) {
|
||||
|
||||
fn check_type_limits(cx: &Context, e: &ast::Expr) {
|
||||
return match e.node {
|
||||
ast::ExprBinary(_, binop, l, r) => {
|
||||
ast::ExprBinary(binop, l, r) => {
|
||||
if is_comparison(binop) && !check_limits(cx.tcx, binop, l, r) {
|
||||
cx.span_lint(TypeLimits, e.span,
|
||||
"comparison is useless due to type limits");
|
||||
@ -1176,7 +1176,7 @@ fn check_unnecessary_parens_expr(cx: &Context, e: &ast::Expr) {
|
||||
ast::ExprMatch(head, _) => (head, "`match` head expression"),
|
||||
ast::ExprRet(Some(value)) => (value, "`return` value"),
|
||||
ast::ExprAssign(_, value) => (value, "assigned value"),
|
||||
ast::ExprAssignOp(_, _, _, value) => (value, "assigned value"),
|
||||
ast::ExprAssignOp(_, _, value) => (value, "assigned value"),
|
||||
_ => return
|
||||
};
|
||||
check_unnecessary_parens_core(cx, value, msg);
|
||||
@ -1263,8 +1263,8 @@ fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
|
||||
_ => return
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(_, ast::UnUniq, _) |
|
||||
ast::ExprUnary(_, ast::UnBox, _) => BoxAllocation,
|
||||
ast::ExprUnary(ast::UnUniq, _) |
|
||||
ast::ExprUnary(ast::UnBox, _) => BoxAllocation,
|
||||
|
||||
_ => return
|
||||
};
|
||||
@ -1411,10 +1411,9 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
|
||||
}
|
||||
}
|
||||
ast::ExprMethodCall(..) => {
|
||||
let method_map = cx.method_map.borrow();
|
||||
match method_map.get().find(&e.id) {
|
||||
Some(&origin) => {
|
||||
match origin {
|
||||
match cx.method_map.borrow().get().find(&e.id) {
|
||||
Some(method) => {
|
||||
match method.origin {
|
||||
typeck::MethodStatic(def_id) => {
|
||||
// If this implements a trait method, get def_id
|
||||
// of the method inside trait definition.
|
||||
@ -1531,7 +1530,7 @@ impl<'a> Visitor<()> for Context<'a> {
|
||||
|
||||
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
|
||||
match e.node {
|
||||
ast::ExprUnary(_, ast::UnNeg, expr) => {
|
||||
ast::ExprUnary(ast::UnNeg, expr) => {
|
||||
// propagate negation, if the negation itself isn't negated
|
||||
if self.negated_expr_id != e.id {
|
||||
self.negated_expr_id = expr.id;
|
||||
|
@ -534,7 +534,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
|
||||
ExprBinary(_, op, _, _) if ast_util::lazy_binop(op) => {
|
||||
ExprBinary(op, _, _) if ast_util::lazy_binop(op) => {
|
||||
this.add_live_node_for_node(expr.id, ExprNode(expr.span));
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
@ -1179,7 +1179,7 @@ impl Liveness {
|
||||
self.propagate_through_expr(r, succ)
|
||||
}
|
||||
|
||||
ExprAssignOp(_, _, l, r) => {
|
||||
ExprAssignOp(_, l, r) => {
|
||||
// see comment on lvalues in
|
||||
// propagate_through_lvalue_components()
|
||||
let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ);
|
||||
@ -1219,10 +1219,10 @@ impl Liveness {
|
||||
self.propagate_through_expr(f, succ)
|
||||
}
|
||||
|
||||
ExprMethodCall(callee_id, _, _, ref args) => {
|
||||
ExprMethodCall(_, _, ref args) => {
|
||||
// calling a method with bot return type means that the method
|
||||
// will fail, and hence the successors can be ignored
|
||||
let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.tcx, callee_id));
|
||||
let t_ret = ty::node_id_to_type(self.tcx, expr.id);
|
||||
let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
|
||||
else {succ};
|
||||
self.propagate_through_exprs(*args, succ)
|
||||
@ -1232,7 +1232,7 @@ impl Liveness {
|
||||
self.propagate_through_exprs(*exprs, succ)
|
||||
}
|
||||
|
||||
ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
|
||||
ExprBinary(op, l, r) if ast_util::lazy_binop(op) => {
|
||||
let r_succ = self.propagate_through_expr(r, succ);
|
||||
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
@ -1242,15 +1242,15 @@ impl Liveness {
|
||||
self.propagate_through_expr(l, ln)
|
||||
}
|
||||
|
||||
ExprIndex(_, l, r) |
|
||||
ExprBinary(_, _, l, r) |
|
||||
ExprIndex(l, r) |
|
||||
ExprBinary(_, l, r) |
|
||||
ExprBox(l, r) => {
|
||||
self.propagate_through_exprs([l, r], succ)
|
||||
}
|
||||
|
||||
ExprAddrOf(_, e) |
|
||||
ExprCast(e, _) |
|
||||
ExprUnary(_, _, e) |
|
||||
ExprUnary(_, e) |
|
||||
ExprParen(e) => {
|
||||
self.propagate_through_expr(e, succ)
|
||||
}
|
||||
@ -1508,7 +1508,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
|
||||
visit::walk_expr(this, expr, ());
|
||||
}
|
||||
|
||||
ExprAssignOp(_, _, l, _) => {
|
||||
ExprAssignOp(_, l, _) => {
|
||||
this.check_lvalue(l);
|
||||
|
||||
visit::walk_expr(this, expr, ());
|
||||
|
@ -432,7 +432,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
||||
|
||||
let expr_ty = if_ok!(self.expr_ty(expr));
|
||||
match expr.node {
|
||||
ast::ExprUnary(_, ast::UnDeref, e_base) => {
|
||||
ast::ExprUnary(ast::UnDeref, e_base) => {
|
||||
if self.typer.is_method_call(expr.id) {
|
||||
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
|
||||
}
|
||||
@ -450,7 +450,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
||||
Ok(self.cat_field(expr, base_cmt, f_name, expr_ty))
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, base, _) => {
|
||||
ast::ExprIndex(base, _) => {
|
||||
if self.typer.is_method_call(expr.id) {
|
||||
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ impl VisitContext {
|
||||
}
|
||||
}
|
||||
|
||||
ExprUnary(_, UnDeref, base) => { // *base
|
||||
ExprUnary(UnDeref, base) => { // *base
|
||||
if !self.use_overloaded_operator(expr, base, [])
|
||||
{
|
||||
// Moving out of *base moves out of base.
|
||||
@ -369,12 +369,12 @@ impl VisitContext {
|
||||
}
|
||||
}
|
||||
|
||||
ExprField(base, _, _) => { // base.f
|
||||
ExprField(base, _, _) => { // base.f
|
||||
// Moving out of base.f moves out of base.
|
||||
self.use_expr(base, comp_mode);
|
||||
}
|
||||
|
||||
ExprIndex(_, lhs, rhs) => { // lhs[rhs]
|
||||
ExprIndex(lhs, rhs) => { // lhs[rhs]
|
||||
if !self.use_overloaded_operator(expr, lhs, [rhs])
|
||||
{
|
||||
self.use_expr(lhs, comp_mode);
|
||||
@ -409,11 +409,11 @@ impl VisitContext {
|
||||
}
|
||||
}
|
||||
self.use_expr(callee, mode);
|
||||
self.use_fn_args(callee.id, *args);
|
||||
self.use_fn_args(*args);
|
||||
}
|
||||
|
||||
ExprMethodCall(callee_id, _, _, ref args) => { // callee.m(args)
|
||||
self.use_fn_args(callee_id, *args);
|
||||
ExprMethodCall(_, _, ref args) => { // callee.m(args)
|
||||
self.use_fn_args(*args);
|
||||
}
|
||||
|
||||
ExprStruct(_, ref fields, opt_with) => {
|
||||
@ -521,14 +521,14 @@ impl VisitContext {
|
||||
|
||||
ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
|
||||
|
||||
ExprUnary(_, _, lhs) => {
|
||||
ExprUnary(_, lhs) => {
|
||||
if !self.use_overloaded_operator(expr, lhs, [])
|
||||
{
|
||||
self.consume_expr(lhs);
|
||||
}
|
||||
}
|
||||
|
||||
ExprBinary(_, _, lhs, rhs) => {
|
||||
ExprBinary(_, lhs, rhs) => {
|
||||
if !self.use_overloaded_operator(expr, lhs, [rhs])
|
||||
{
|
||||
self.consume_expr(lhs);
|
||||
@ -555,7 +555,7 @@ impl VisitContext {
|
||||
self.consume_expr(base);
|
||||
}
|
||||
|
||||
ExprAssignOp(_, _, lhs, rhs) => {
|
||||
ExprAssignOp(_, lhs, rhs) => {
|
||||
// FIXME(#4712) --- Overloaded operators?
|
||||
//
|
||||
// if !self.use_overloaded_operator(expr, DoDerefArgs, lhs, [rhs])
|
||||
@ -668,7 +668,6 @@ impl VisitContext {
|
||||
}
|
||||
|
||||
pub fn use_fn_args(&mut self,
|
||||
_: NodeId,
|
||||
arg_exprs: &[@Expr]) {
|
||||
//! Uses the argument expressions.
|
||||
for arg_expr in arg_exprs.iter() {
|
||||
|
@ -785,7 +785,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
ast::ExprMethodCall(_, ident, _, ref args) => {
|
||||
ast::ExprMethodCall(ident, _, ref args) => {
|
||||
// see above
|
||||
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
|
||||
match ty::get(t).sty {
|
||||
@ -796,9 +796,9 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
"method call not in \
|
||||
method map");
|
||||
}
|
||||
Some(origin) => {
|
||||
Some(method) => {
|
||||
debug!("(privacy checking) checking impl method");
|
||||
self.check_method(expr.span, origin, ident);
|
||||
self.check_method(expr.span, method.origin, ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,9 +147,8 @@ impl Visitor<()> for MarkSymbolVisitor {
|
||||
}
|
||||
}
|
||||
ast::ExprMethodCall(..) => {
|
||||
let method_map = self.method_map.borrow();
|
||||
match method_map.get().find(&expr.id) {
|
||||
Some(&typeck::method_static(def_id)) => {
|
||||
match self.method_map.borrow().get().get(&expr.id).origin {
|
||||
typeck::MethodStatic(def_id) => {
|
||||
if is_local(def_id) {
|
||||
if ReachableContext::
|
||||
def_id_represents_local_inlined_item(
|
||||
@ -168,11 +167,7 @@ impl Visitor<()> for MarkSymbolVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(_) => {}
|
||||
None => {
|
||||
self.tcx.sess.span_bug(expr.span,
|
||||
"method call expression not in method map?!")
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -512,8 +512,8 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
|
||||
// scopes, meaning that temporaries cannot outlive them.
|
||||
// This ensures fixed size stacks.
|
||||
|
||||
ast::ExprBinary(_, ast::BiAnd, _, r) |
|
||||
ast::ExprBinary(_, ast::BiOr, _, r) => {
|
||||
ast::ExprBinary(ast::BiAnd, _, r) |
|
||||
ast::ExprBinary(ast::BiOr, _, r) => {
|
||||
// For shortcircuiting operators, mark the RHS as a terminating
|
||||
// scope since it only executes conditionally.
|
||||
visitor.region_maps.mark_as_terminating_scope(r.id);
|
||||
@ -756,7 +756,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
|
||||
visitor, subexpr, blk_id);
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(_, ast::UnUniq, subexpr) => {
|
||||
ast::ExprUnary(ast::UnUniq, subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
|
||||
}
|
||||
ast::ExprCast(subexpr, _) |
|
||||
@ -811,9 +811,9 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
|
||||
|
||||
match expr.node {
|
||||
ast::ExprAddrOf(_, ref subexpr) |
|
||||
ast::ExprUnary(_, ast::UnDeref, ref subexpr) |
|
||||
ast::ExprUnary(ast::UnDeref, ref subexpr) |
|
||||
ast::ExprField(ref subexpr, _, _) |
|
||||
ast::ExprIndex(_, ref subexpr, _) |
|
||||
ast::ExprIndex(ref subexpr, _) |
|
||||
ast::ExprParen(ref subexpr) => {
|
||||
let subexpr: &'a @Expr = subexpr; // FIXME(#11586)
|
||||
expr = &**subexpr;
|
||||
|
@ -5257,7 +5257,7 @@ impl Resolver {
|
||||
let traits = self.search_for_traits_containing_method(ident);
|
||||
self.trait_map.insert(expr.id, traits);
|
||||
}
|
||||
ExprMethodCall(_, ident, _, _) => {
|
||||
ExprMethodCall(ident, _, _) => {
|
||||
debug!("(recording candidate traits for expr) recording \
|
||||
traits for {}",
|
||||
expr.id);
|
||||
|
@ -118,7 +118,7 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
|
||||
match def {
|
||||
ast::DefFn(did, _) |
|
||||
ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
|
||||
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id))
|
||||
fn_callee(bcx, trans_fn_ref(bcx, did, ref_expr.id, false))
|
||||
}
|
||||
ast::DefStaticMethod(impl_did,
|
||||
ast::FromTrait(trait_did),
|
||||
@ -132,10 +132,10 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
|
||||
assert!(ty::enum_variant_with_id(bcx.tcx(),
|
||||
tid,
|
||||
vid).args.len() > 0u);
|
||||
fn_callee(bcx, trans_fn_ref(bcx, vid, ref_expr.id))
|
||||
fn_callee(bcx, trans_fn_ref(bcx, vid, ref_expr.id, false))
|
||||
}
|
||||
ast::DefStruct(def_id) => {
|
||||
fn_callee(bcx, trans_fn_ref(bcx, def_id, ref_expr.id))
|
||||
fn_callee(bcx, trans_fn_ref(bcx, def_id, ref_expr.id, false))
|
||||
}
|
||||
ast::DefStatic(..) |
|
||||
ast::DefArg(..) |
|
||||
@ -158,16 +158,8 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_fn_ref_to_callee<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
def_id: ast::DefId,
|
||||
ref_id: ast::NodeId)
|
||||
-> Callee<'a> {
|
||||
Callee {bcx: bcx,
|
||||
data: Fn(trans_fn_ref(bcx, def_id, ref_id))}
|
||||
}
|
||||
|
||||
pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
|
||||
pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId,
|
||||
ref_id: ast::NodeId, is_method: bool)
|
||||
-> ValueRef {
|
||||
/*!
|
||||
*
|
||||
@ -177,23 +169,22 @@ pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
|
||||
|
||||
let _icx = push_ctxt("trans_fn_ref");
|
||||
|
||||
let type_params = node_id_type_params(bcx, ref_id);
|
||||
let type_params = node_id_type_params(bcx, ref_id, is_method);
|
||||
let vtables = node_vtables(bcx, ref_id);
|
||||
debug!("trans_fn_ref(def_id={}, ref_id={:?}, type_params={}, vtables={})",
|
||||
def_id.repr(bcx.tcx()), ref_id, type_params.repr(bcx.tcx()),
|
||||
vtables.repr(bcx.tcx()));
|
||||
trans_fn_ref_with_vtables(bcx, def_id, ref_id, type_params, vtables)
|
||||
trans_fn_ref_with_vtables(bcx, def_id, ref_id, is_method, type_params, vtables)
|
||||
}
|
||||
|
||||
pub fn trans_fn_ref_with_vtables_to_callee<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>,
|
||||
def_id: ast::DefId,
|
||||
ref_id: ast::NodeId,
|
||||
type_params: &[ty::t],
|
||||
vtables: Option<typeck::vtable_res>)
|
||||
-> Callee<'a> {
|
||||
Callee {bcx: bcx,
|
||||
data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id,
|
||||
data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id, false,
|
||||
type_params, vtables))}
|
||||
}
|
||||
|
||||
@ -243,6 +234,7 @@ pub fn trans_fn_ref_with_vtables(
|
||||
bcx: &Block, //
|
||||
def_id: ast::DefId, // def id of fn
|
||||
ref_id: ast::NodeId, // node id of use of fn; may be zero if N/A
|
||||
is_method: bool,
|
||||
type_params: &[ty::t], // values for fn's ty params
|
||||
vtables: Option<typeck::vtable_res>) // vtables for the call
|
||||
-> ValueRef {
|
||||
@ -388,7 +380,12 @@ pub fn trans_fn_ref_with_vtables(
|
||||
if must_cast && ref_id != 0 {
|
||||
// Monotype of the REFERENCE to the function (type params
|
||||
// are subst'd)
|
||||
let ref_ty = common::node_id_type(bcx, ref_id);
|
||||
let ref_ty = if is_method {
|
||||
let t = bcx.ccx().maps.method_map.borrow().get().get(&ref_id).ty;
|
||||
monomorphize_type(bcx, t)
|
||||
} else {
|
||||
node_id_type(bcx, ref_id)
|
||||
};
|
||||
|
||||
val = PointerCast(
|
||||
bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to());
|
||||
@ -461,41 +458,22 @@ pub fn trans_call<'a>(
|
||||
}
|
||||
|
||||
pub fn trans_method_call<'a>(
|
||||
in_cx: &'a Block<'a>,
|
||||
bcx: &'a Block<'a>,
|
||||
call_ex: &ast::Expr,
|
||||
callee_id: ast::NodeId,
|
||||
rcvr: &ast::Expr,
|
||||
args: CallArgs,
|
||||
dest: expr::Dest)
|
||||
-> &'a Block<'a> {
|
||||
let _icx = push_ctxt("trans_method_call");
|
||||
debug!("trans_method_call(call_ex={})", call_ex.repr(in_cx.tcx()));
|
||||
debug!("trans_method_call(call_ex={})", call_ex.repr(bcx.tcx()));
|
||||
let method_ty = bcx.ccx().maps.method_map.borrow().get().get(&call_ex.id).ty;
|
||||
trans_call_inner(
|
||||
in_cx,
|
||||
bcx,
|
||||
Some(common::expr_info(call_ex)),
|
||||
node_id_type(in_cx, callee_id),
|
||||
expr_ty(in_cx, call_ex),
|
||||
monomorphize_type(bcx, method_ty),
|
||||
expr_ty(bcx, call_ex),
|
||||
|cx, arg_cleanup_scope| {
|
||||
let origin_opt = {
|
||||
let mut method_map = cx.ccx().maps.method_map.borrow_mut();
|
||||
method_map.get().find_copy(&call_ex.id)
|
||||
};
|
||||
match origin_opt {
|
||||
Some(origin) => {
|
||||
debug!("origin for {}: {}",
|
||||
call_ex.repr(in_cx.tcx()),
|
||||
origin.repr(in_cx.tcx()));
|
||||
|
||||
meth::trans_method_callee(cx,
|
||||
callee_id,
|
||||
rcvr,
|
||||
origin,
|
||||
arg_cleanup_scope)
|
||||
}
|
||||
None => {
|
||||
cx.tcx().sess.span_bug(call_ex.span, "method call expr wasn't in method map")
|
||||
}
|
||||
}
|
||||
meth::trans_method_callee(cx, call_ex.id, rcvr, arg_cleanup_scope)
|
||||
},
|
||||
args,
|
||||
Some(dest)).bcx
|
||||
|
@ -673,7 +673,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
|
||||
|
||||
// The exception handling personality function.
|
||||
let def_id = common::langcall(pad_bcx, None, "", EhPersonalityLangItem);
|
||||
let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0);
|
||||
let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0, false);
|
||||
|
||||
// The only landing pad clause will be 'cleanup'
|
||||
let llretval = build::LandingPad(pad_bcx, llretty, llpersonality, 1u);
|
||||
|
@ -807,9 +807,13 @@ pub fn expr_ty_adjusted(bcx: &Block, ex: &ast::Expr) -> ty::t {
|
||||
monomorphize_type(bcx, t)
|
||||
}
|
||||
|
||||
pub fn node_id_type_params(bcx: &Block, id: ast::NodeId) -> ~[ty::t] {
|
||||
pub fn node_id_type_params(bcx: &Block, id: ast::NodeId, is_method: bool) -> ~[ty::t] {
|
||||
let tcx = bcx.tcx();
|
||||
let params = ty::node_id_to_type_params(tcx, id);
|
||||
let params = if is_method {
|
||||
bcx.ccx().maps.method_map.borrow().get().get(&id).substs.tps.clone()
|
||||
} else {
|
||||
ty::node_id_to_type_params(tcx, id)
|
||||
};
|
||||
|
||||
if !params.iter().all(|t| !ty::type_needs_infer(*t)) {
|
||||
bcx.sess().bug(
|
||||
|
@ -310,7 +310,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
|
||||
ast::ExprLit(lit) => {
|
||||
(consts::const_lit(cx, e, (*lit).clone()), true)
|
||||
}
|
||||
ast::ExprBinary(_, b, e1, e2) => {
|
||||
ast::ExprBinary(b, e1, e2) => {
|
||||
let (te1, _) = const_expr(cx, e1, is_local);
|
||||
let (te2, _) = const_expr(cx, e2, is_local);
|
||||
|
||||
@ -392,7 +392,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
|
||||
},
|
||||
}, true)
|
||||
},
|
||||
ast::ExprUnary(_, u, e) => {
|
||||
ast::ExprUnary(u, e) => {
|
||||
let (te, _) = const_expr(cx, e, is_local);
|
||||
let ty = ty::expr_ty(cx.tcx, e);
|
||||
let is_float = ty::type_is_fp(ty);
|
||||
@ -429,7 +429,7 @@ fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
|
||||
})
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, base, index) => {
|
||||
ast::ExprIndex(base, index) => {
|
||||
let bt = ty::expr_ty_adjusted(cx.tcx, base);
|
||||
let (bv, inlineable) = const_expr(cx, base, is_local);
|
||||
let iv = match const_eval::eval_const_expr(cx.tcx, index) {
|
||||
|
@ -2539,15 +2539,13 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
None => ()
|
||||
},
|
||||
|
||||
ast::ExprUnary(node_id, _, sub_exp) => {
|
||||
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
|
||||
ast::ExprUnary(_, sub_exp) => {
|
||||
walk_expr(cx, sub_exp, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
ast::ExprAssignOp(node_id, _, lhs, rhs) |
|
||||
ast::ExprIndex(node_id, lhs, rhs) |
|
||||
ast::ExprBinary(node_id, _, lhs, rhs) => {
|
||||
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
|
||||
ast::ExprAssignOp(_, lhs, rhs) |
|
||||
ast::ExprIndex(lhs, rhs) |
|
||||
ast::ExprBinary(_, lhs, rhs) => {
|
||||
walk_expr(cx, lhs, scope_stack, scope_map);
|
||||
walk_expr(cx, rhs, scope_stack, scope_map);
|
||||
}
|
||||
@ -2638,9 +2636,7 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(node_id, _, _, ref args) => {
|
||||
scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
for arg_exp in args.iter() {
|
||||
walk_expr(cx, *arg_exp, scope_stack, scope_map);
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
ast::ExprField(base, ident, _) => {
|
||||
trans_rec_field(bcx, base, ident)
|
||||
}
|
||||
ast::ExprIndex(_, base, idx) => {
|
||||
ast::ExprIndex(base, idx) => {
|
||||
trans_index(bcx, expr, base, idx)
|
||||
}
|
||||
ast::ExprVstore(contents, ast::ExprVstoreUniq) => {
|
||||
@ -461,20 +461,17 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
return trans_boxed_expr(bcx, box_ty, contents, contents_ty, heap)
|
||||
}
|
||||
ast::ExprLit(lit) => trans_immediate_lit(bcx, expr, (*lit).clone()),
|
||||
ast::ExprBinary(_, op, lhs, rhs) => {
|
||||
ast::ExprBinary(op, lhs, rhs) => {
|
||||
// if overloaded, would be RvalueDpsExpr
|
||||
{
|
||||
let method_map = bcx.ccx().maps.method_map.borrow();
|
||||
assert!(!method_map.get().contains_key(&expr.id));
|
||||
}
|
||||
assert!(!bcx.ccx().maps.method_map.borrow().get().contains_key(&expr.id));
|
||||
|
||||
trans_binary(bcx, expr, op, lhs, rhs)
|
||||
}
|
||||
ast::ExprUnary(_, ast::UnDeref, base) => {
|
||||
ast::ExprUnary(ast::UnDeref, base) => {
|
||||
let basedatum = unpack_datum!(bcx, trans(bcx, base));
|
||||
deref_once(bcx, expr, basedatum, 0)
|
||||
}
|
||||
ast::ExprUnary(_, op, x) => {
|
||||
ast::ExprUnary(op, x) => {
|
||||
trans_unary_datum(bcx, expr, op, x)
|
||||
}
|
||||
ast::ExprAddrOf(_, x) => {
|
||||
@ -698,8 +695,8 @@ fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
src_datum.store_to(bcx, dst_datum.val)
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(callee_id, op, dst, src) => {
|
||||
trans_assign_op(bcx, expr, callee_id, op, dst, src)
|
||||
ast::ExprAssignOp(op, dst, src) => {
|
||||
trans_assign_op(bcx, expr, op, dst, src)
|
||||
}
|
||||
ast::ExprInlineAsm(ref a) => {
|
||||
asm::trans_inline_asm(bcx, a)
|
||||
@ -780,26 +777,24 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
closure::trans_expr_fn(bcx, sigil, decl, body, expr.id, dest)
|
||||
}
|
||||
ast::ExprCall(f, ref args) => {
|
||||
callee::trans_call(bcx, expr, f,
|
||||
callee::ArgExprs(*args), expr.id, dest)
|
||||
callee::trans_call(bcx, expr, f, callee::ArgExprs(*args), expr.id, dest)
|
||||
}
|
||||
ast::ExprMethodCall(callee_id, _, _, ref args) => {
|
||||
callee::trans_method_call(bcx, expr, callee_id, args[0],
|
||||
callee::ArgExprs(*args), dest)
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
callee::trans_method_call(bcx, expr, args[0], callee::ArgExprs(*args), dest)
|
||||
}
|
||||
ast::ExprBinary(callee_id, _, lhs, rhs) => {
|
||||
ast::ExprBinary(_, lhs, rhs) => {
|
||||
// if not overloaded, would be RvalueDatumExpr
|
||||
trans_overloaded_op(bcx, expr, callee_id, lhs,
|
||||
trans_overloaded_op(bcx, expr, lhs,
|
||||
Some(&*rhs), expr_ty(bcx, expr), dest)
|
||||
}
|
||||
ast::ExprUnary(callee_id, _, subexpr) => {
|
||||
ast::ExprUnary(_, subexpr) => {
|
||||
// if not overloaded, would be RvalueDatumExpr
|
||||
trans_overloaded_op(bcx, expr, callee_id, subexpr,
|
||||
trans_overloaded_op(bcx, expr, subexpr,
|
||||
None, expr_ty(bcx, expr), dest)
|
||||
}
|
||||
ast::ExprIndex(callee_id, base, idx) => {
|
||||
ast::ExprIndex(base, idx) => {
|
||||
// if not overloaded, would be RvalueDatumExpr
|
||||
trans_overloaded_op(bcx, expr, callee_id, base,
|
||||
trans_overloaded_op(bcx, expr, base,
|
||||
Some(&*idx), expr_ty(bcx, expr), dest)
|
||||
}
|
||||
ast::ExprCast(val, _) => {
|
||||
@ -815,8 +810,8 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(callee_id, op, dst, src) => {
|
||||
trans_assign_op(bcx, expr, callee_id, op, dst, src)
|
||||
ast::ExprAssignOp(op, dst, src) => {
|
||||
trans_assign_op(bcx, expr, op, dst, src)
|
||||
}
|
||||
ast::ExprBox(_, contents) => {
|
||||
// Special case for `Gc<T>` for now. The other case, for unique
|
||||
@ -851,7 +846,7 @@ fn trans_def_dps_unadjusted<'a>(
|
||||
let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
|
||||
if variant_info.args.len() > 0u {
|
||||
// N-ary variant.
|
||||
let llfn = callee::trans_fn_ref(bcx, vid, ref_expr.id);
|
||||
let llfn = callee::trans_fn_ref(bcx, vid, ref_expr.id, false);
|
||||
Store(bcx, llfn, lldest);
|
||||
return bcx;
|
||||
} else {
|
||||
@ -884,15 +879,14 @@ fn trans_def_dps_unadjusted<'a>(
|
||||
|
||||
fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
ref_expr: &ast::Expr,
|
||||
def: ast::Def) -> DatumBlock<'a, Expr>
|
||||
{
|
||||
def: ast::Def) -> DatumBlock<'a, Expr> {
|
||||
let _icx = push_ctxt("trans_def_datum_unadjusted");
|
||||
|
||||
let llfn = match def {
|
||||
ast::DefFn(did, _) |
|
||||
ast::DefStruct(did) | ast::DefVariant(_, did, _) |
|
||||
ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
|
||||
callee::trans_fn_ref(bcx, did, ref_expr.id)
|
||||
callee::trans_fn_ref(bcx, did, ref_expr.id, false)
|
||||
}
|
||||
ast::DefStaticMethod(impl_did, ast::FromTrait(trait_did), _) => {
|
||||
meth::trans_static_method_callee(bcx, impl_did,
|
||||
@ -1496,26 +1490,20 @@ fn trans_binary<'a>(
|
||||
fn trans_overloaded_op<'a, 'b>(
|
||||
bcx: &'a Block<'a>,
|
||||
expr: &ast::Expr,
|
||||
callee_id: ast::NodeId,
|
||||
rcvr: &'b ast::Expr,
|
||||
arg: Option<&'b ast::Expr>,
|
||||
ret_ty: ty::t,
|
||||
dest: Dest)
|
||||
-> &'a Block<'a> {
|
||||
let origin = {
|
||||
let method_map = bcx.ccx().maps.method_map.borrow();
|
||||
method_map.get().get_copy(&expr.id)
|
||||
};
|
||||
let fty = node_id_type(bcx, callee_id);
|
||||
let method_ty = bcx.ccx().maps.method_map.borrow().get().get(&expr.id).ty;
|
||||
callee::trans_call_inner(bcx,
|
||||
Some(expr_info(expr)),
|
||||
fty,
|
||||
monomorphize_type(bcx, method_ty),
|
||||
ret_ty,
|
||||
|bcx, arg_cleanup_scope| {
|
||||
meth::trans_method_callee(bcx,
|
||||
callee_id,
|
||||
expr.id,
|
||||
rcvr,
|
||||
origin,
|
||||
arg_cleanup_scope)
|
||||
},
|
||||
callee::ArgAutorefSecond(rcvr, arg),
|
||||
@ -1666,7 +1654,6 @@ fn trans_imm_cast<'a>(bcx: &'a Block<'a>,
|
||||
fn trans_assign_op<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
expr: &ast::Expr,
|
||||
_callee_id: ast::NodeId,
|
||||
op: ast::BinOp,
|
||||
dst: &ast::Expr,
|
||||
src: @ast::Expr)
|
||||
|
@ -93,21 +93,29 @@ pub fn trans_method(ccx: @CrateContext, method: &ast::Method,
|
||||
|
||||
pub fn trans_method_callee<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
callee_id: ast::NodeId,
|
||||
expr_id: ast::NodeId,
|
||||
this: &ast::Expr,
|
||||
origin: typeck::method_origin,
|
||||
arg_cleanup_scope: cleanup::ScopeId)
|
||||
-> Callee<'a> {
|
||||
let _icx = push_ctxt("meth::trans_method_callee");
|
||||
|
||||
debug!("trans_method_callee(callee_id={:?}, origin={})",
|
||||
callee_id, origin.repr(bcx.tcx()));
|
||||
let (origin, method_ty) = match bcx.ccx().maps.method_map
|
||||
.borrow().get().find(&expr_id) {
|
||||
Some(method) => {
|
||||
debug!("trans_method_callee(expr_id={:?}, method={})",
|
||||
expr_id, method.repr(bcx.tcx()));
|
||||
(method.origin, method.ty)
|
||||
}
|
||||
None => {
|
||||
bcx.tcx().sess.span_bug(this.span, "method call expr wasn't in method map")
|
||||
}
|
||||
};
|
||||
|
||||
match origin {
|
||||
typeck::MethodStatic(did) => {
|
||||
Callee {
|
||||
bcx: bcx,
|
||||
data: Fn(callee::trans_fn_ref(bcx, did, callee_id))
|
||||
data: Fn(callee::trans_fn_ref(bcx, did, expr_id, true))
|
||||
}
|
||||
}
|
||||
typeck::MethodParam(typeck::MethodParam {
|
||||
@ -123,7 +131,7 @@ pub fn trans_method_callee<'a>(
|
||||
trait_id);
|
||||
|
||||
let vtbl = find_vtable(bcx.tcx(), substs, p, b);
|
||||
trans_monomorphized_callee(bcx, callee_id,
|
||||
trans_monomorphized_callee(bcx, expr_id,
|
||||
trait_id, off, vtbl)
|
||||
}
|
||||
// how to get rid of this?
|
||||
@ -133,7 +141,7 @@ pub fn trans_method_callee<'a>(
|
||||
|
||||
typeck::MethodObject(ref mt) => {
|
||||
trans_trait_callee(bcx,
|
||||
callee_id,
|
||||
monomorphize_type(bcx, method_ty),
|
||||
mt.real_index,
|
||||
this,
|
||||
arg_cleanup_scope)
|
||||
@ -144,16 +152,16 @@ pub fn trans_method_callee<'a>(
|
||||
pub fn trans_static_method_callee(bcx: &Block,
|
||||
method_id: ast::DefId,
|
||||
trait_id: ast::DefId,
|
||||
callee_id: ast::NodeId)
|
||||
expr_id: ast::NodeId)
|
||||
-> ValueRef {
|
||||
let _icx = push_ctxt("meth::trans_static_method_callee");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \
|
||||
callee_id={:?})",
|
||||
expr_id={:?})",
|
||||
method_id,
|
||||
ty::item_path_str(bcx.tcx(), trait_id),
|
||||
callee_id);
|
||||
expr_id);
|
||||
let _indenter = indenter();
|
||||
|
||||
ty::populate_implementations_for_trait_if_necessary(bcx.tcx(), trait_id);
|
||||
@ -188,13 +196,10 @@ pub fn trans_static_method_callee(bcx: &Block,
|
||||
} else {
|
||||
csearch::get_item_path(bcx.tcx(), method_id).last().unwrap().name()
|
||||
};
|
||||
debug!("trans_static_method_callee: method_id={:?}, callee_id={:?}, \
|
||||
name={}", method_id, callee_id, token::get_name(mname));
|
||||
debug!("trans_static_method_callee: method_id={:?}, expr_id={:?}, \
|
||||
name={}", method_id, expr_id, token::get_name(mname));
|
||||
|
||||
let vtbls = {
|
||||
let vtable_map = ccx.maps.vtable_map.borrow();
|
||||
vtable_map.get().get_copy(&callee_id)
|
||||
};
|
||||
let vtbls = ccx.maps.vtable_map.borrow().get().get_copy(&expr_id);
|
||||
let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls);
|
||||
|
||||
match vtbls[bound_index][0] {
|
||||
@ -204,14 +209,14 @@ pub fn trans_static_method_callee(bcx: &Block,
|
||||
let mth_id = method_with_name(ccx, impl_did, mname);
|
||||
let (callee_substs, callee_origins) =
|
||||
combine_impl_and_methods_tps(
|
||||
bcx, mth_id, callee_id,
|
||||
bcx, mth_id, expr_id, false,
|
||||
*rcvr_substs, rcvr_origins);
|
||||
|
||||
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, callee_id,
|
||||
callee_substs,
|
||||
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, expr_id,
|
||||
false, callee_substs,
|
||||
Some(callee_origins));
|
||||
|
||||
let callee_ty = node_id_type(bcx, callee_id);
|
||||
let callee_ty = node_id_type(bcx, expr_id);
|
||||
let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
|
||||
PointerCast(bcx, llfn, llty)
|
||||
}
|
||||
@ -246,13 +251,13 @@ pub fn method_with_name(ccx: &CrateContext,
|
||||
}
|
||||
|
||||
fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
|
||||
callee_id: ast::NodeId,
|
||||
expr_id: ast::NodeId,
|
||||
trait_id: ast::DefId,
|
||||
n_method: uint,
|
||||
vtbl: typeck::vtable_origin)
|
||||
-> Callee<'a> {
|
||||
let _icx = push_ctxt("meth::trans_monomorphized_callee");
|
||||
return match vtbl {
|
||||
match vtbl {
|
||||
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
|
||||
let ccx = bcx.ccx();
|
||||
let mname = ty::trait_method(ccx.tcx, trait_id, n_method).ident;
|
||||
@ -262,13 +267,14 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
|
||||
// those from the impl and those from the method:
|
||||
let (callee_substs, callee_origins) =
|
||||
combine_impl_and_methods_tps(
|
||||
bcx, mth_id, callee_id,
|
||||
bcx, mth_id, expr_id, true,
|
||||
*rcvr_substs, rcvr_origins);
|
||||
|
||||
// translate the function
|
||||
let llfn = trans_fn_ref_with_vtables(bcx,
|
||||
mth_id,
|
||||
callee_id,
|
||||
expr_id,
|
||||
true,
|
||||
callee_substs,
|
||||
Some(callee_origins));
|
||||
|
||||
@ -277,16 +283,16 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
|
||||
typeck::vtable_param(..) => {
|
||||
fail!("vtable_param left in monomorphized function's vtable substs");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn combine_impl_and_methods_tps(bcx: &Block,
|
||||
mth_did: ast::DefId,
|
||||
callee_id: ast::NodeId,
|
||||
rcvr_substs: &[ty::t],
|
||||
rcvr_origins: typeck::vtable_res)
|
||||
-> (~[ty::t], typeck::vtable_res) {
|
||||
fn combine_impl_and_methods_tps(bcx: &Block,
|
||||
mth_did: ast::DefId,
|
||||
expr_id: ast::NodeId,
|
||||
is_method: bool,
|
||||
rcvr_substs: &[ty::t],
|
||||
rcvr_origins: typeck::vtable_res)
|
||||
-> (~[ty::t], typeck::vtable_res) {
|
||||
/*!
|
||||
*
|
||||
* Creates a concatenated set of substitutions which includes
|
||||
@ -307,7 +313,7 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
|
||||
let ccx = bcx.ccx();
|
||||
let method = ty::method(ccx.tcx, mth_did);
|
||||
let n_m_tps = method.generics.type_param_defs().len();
|
||||
let node_substs = node_id_type_params(bcx, callee_id);
|
||||
let node_substs = node_id_type_params(bcx, expr_id, is_method);
|
||||
debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx));
|
||||
let ty_substs
|
||||
= vec::append(rcvr_substs.to_owned(),
|
||||
@ -319,7 +325,7 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
|
||||
|
||||
// Now, do the same work for the vtables. The vtables might not
|
||||
// exist, in which case we need to make them.
|
||||
let r_m_origins = match node_vtables(bcx, callee_id) {
|
||||
let r_m_origins = match node_vtables(bcx, expr_id) {
|
||||
Some(vt) => vt,
|
||||
None => @vec::from_elem(node_substs.len(), @~[])
|
||||
};
|
||||
@ -327,11 +333,11 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
|
||||
= @vec::append(rcvr_origins.to_owned(),
|
||||
r_m_origins.tailn(r_m_origins.len() - n_m_tps));
|
||||
|
||||
return (ty_substs, vtables);
|
||||
(ty_substs, vtables)
|
||||
}
|
||||
|
||||
fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
|
||||
callee_id: ast::NodeId,
|
||||
method_ty: ty::t,
|
||||
n_method: uint,
|
||||
self_expr: &ast::Expr,
|
||||
arg_cleanup_scope: cleanup::ScopeId)
|
||||
@ -371,8 +377,7 @@ fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
|
||||
self_datum.val
|
||||
};
|
||||
|
||||
let callee_ty = node_id_type(bcx, callee_id);
|
||||
trans_trait_callee_from_llval(bcx, callee_ty, n_method, llval)
|
||||
trans_trait_callee_from_llval(bcx, method_ty, n_method, llval)
|
||||
}
|
||||
|
||||
pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
|
||||
@ -540,7 +545,7 @@ fn emit_vtable_methods(bcx: &Block,
|
||||
token::get_ident(ident));
|
||||
C_null(Type::nil().ptr_to())
|
||||
} else {
|
||||
trans_fn_ref_with_vtables(bcx, m_id, 0, substs, Some(vtables))
|
||||
trans_fn_ref_with_vtables(bcx, m_id, 0, false, substs, Some(vtables))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -33,8 +33,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
|
||||
vtables: Option<typeck::vtable_res>,
|
||||
self_vtables: Option<typeck::vtable_param_res>,
|
||||
ref_id: Option<ast::NodeId>)
|
||||
-> (ValueRef, bool)
|
||||
{
|
||||
-> (ValueRef, bool) {
|
||||
debug!("monomorphic_fn(\
|
||||
fn_id={}, \
|
||||
real_substs={}, \
|
||||
@ -280,7 +279,6 @@ pub fn monomorphic_fn(ccx: @CrateContext,
|
||||
ast_map::NodeStmt(..) |
|
||||
ast_map::NodeArg(..) |
|
||||
ast_map::NodeBlock(..) |
|
||||
ast_map::NodeCalleeScope(..) |
|
||||
ast_map::NodeLocal(..) => {
|
||||
ccx.tcx.sess.bug(format!("can't monomorphize a {:?}", map_node))
|
||||
}
|
||||
|
@ -3372,7 +3372,7 @@ pub fn expr_kind(tcx: ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, ast::UnDeref, _) |
|
||||
ast::ExprUnary(ast::UnDeref, _) |
|
||||
ast::ExprField(..) |
|
||||
ast::ExprIndex(..) => {
|
||||
LvalueExpr
|
||||
|
@ -89,6 +89,7 @@ use middle::typeck::check::{structurally_resolved_type};
|
||||
use middle::typeck::check::vtable;
|
||||
use middle::typeck::check;
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::MethodCallee;
|
||||
use middle::typeck::{MethodOrigin, MethodParam};
|
||||
use middle::typeck::{MethodStatic, MethodObject};
|
||||
use middle::typeck::{param_numbered, param_self, param_index};
|
||||
@ -101,7 +102,7 @@ use collections::HashSet;
|
||||
use std::result;
|
||||
use std::vec;
|
||||
use syntax::ast::{DefId, SelfValue, SelfRegion};
|
||||
use syntax::ast::{SelfUniq, SelfStatic, NodeId};
|
||||
use syntax::ast::{SelfUniq, SelfStatic};
|
||||
use syntax::ast::{MutMutable, MutImmutable};
|
||||
use syntax::ast;
|
||||
use syntax::parse::token;
|
||||
@ -124,20 +125,17 @@ pub fn lookup(
|
||||
// In a call `a.b::<X, Y, ...>(...)`:
|
||||
expr: &ast::Expr, // The expression `a.b(...)`.
|
||||
self_expr: &ast::Expr, // The expression `a`.
|
||||
callee_id: NodeId, /* Where to store `a.b`'s type,
|
||||
* also the scope of the call */
|
||||
m_name: ast::Name, // The name `b`.
|
||||
self_ty: ty::t, // The type of `a`.
|
||||
supplied_tps: &[ty::t], // The list of types X, Y, ... .
|
||||
deref_args: check::DerefArgs, // Whether we autopointer first.
|
||||
check_traits: CheckTraitsFlag, // Whether we check traits only.
|
||||
autoderef_receiver: AutoderefReceiverFlag)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
let lcx = LookupContext {
|
||||
fcx: fcx,
|
||||
expr: expr,
|
||||
self_expr: self_expr,
|
||||
callee_id: callee_id,
|
||||
m_name: m_name,
|
||||
supplied_tps: supplied_tps,
|
||||
impl_dups: @RefCell::new(HashSet::new()),
|
||||
@ -173,19 +171,16 @@ pub fn lookup_in_trait(
|
||||
// In a call `a.b::<X, Y, ...>(...)`:
|
||||
expr: &ast::Expr, // The expression `a.b(...)`.
|
||||
self_expr: &ast::Expr, // The expression `a`.
|
||||
callee_id: NodeId, /* Where to store `a.b`'s type,
|
||||
* also the scope of the call */
|
||||
m_name: ast::Name, // The name `b`.
|
||||
trait_did: DefId, // The trait to limit the lookup to.
|
||||
self_ty: ty::t, // The type of `a`.
|
||||
supplied_tps: &[ty::t], // The list of types X, Y, ... .
|
||||
autoderef_receiver: AutoderefReceiverFlag)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
let lcx = LookupContext {
|
||||
fcx: fcx,
|
||||
expr: expr,
|
||||
self_expr: self_expr,
|
||||
callee_id: callee_id,
|
||||
m_name: m_name,
|
||||
supplied_tps: supplied_tps,
|
||||
impl_dups: @RefCell::new(HashSet::new()),
|
||||
@ -210,7 +205,6 @@ pub struct LookupContext<'a> {
|
||||
fcx: @FnCtxt,
|
||||
expr: &'a ast::Expr,
|
||||
self_expr: &'a ast::Expr,
|
||||
callee_id: NodeId,
|
||||
m_name: ast::Name,
|
||||
supplied_tps: &'a [ty::t],
|
||||
impl_dups: @RefCell<HashSet<DefId>>,
|
||||
@ -248,7 +242,7 @@ enum RcvrMatchCondition {
|
||||
}
|
||||
|
||||
impl<'a> LookupContext<'a> {
|
||||
fn search(&self, self_ty: ty::t) -> Option<method_origin> {
|
||||
fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
|
||||
let mut self_ty = self_ty;
|
||||
let mut autoderefs = 0;
|
||||
loop {
|
||||
@ -636,7 +630,7 @@ impl<'a> LookupContext<'a> {
|
||||
fn search_for_autoderefd_method(&self,
|
||||
self_ty: ty::t,
|
||||
autoderefs: uint)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
let (self_ty, autoadjust) =
|
||||
self.consider_reborrow(self_ty, autoderefs);
|
||||
match self.search_for_method(self_ty) {
|
||||
@ -732,7 +726,7 @@ impl<'a> LookupContext<'a> {
|
||||
fn search_for_autosliced_method(&self,
|
||||
self_ty: ty::t,
|
||||
autoderefs: uint)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
/*!
|
||||
*
|
||||
* Searches for a candidate by converting things like
|
||||
@ -807,7 +801,7 @@ impl<'a> LookupContext<'a> {
|
||||
}
|
||||
|
||||
fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
/*!
|
||||
*
|
||||
* Converts any type `T` to `&M T` where `M` is an
|
||||
@ -843,7 +837,7 @@ impl<'a> LookupContext<'a> {
|
||||
autoderefs: uint,
|
||||
mutbls: &[ast::Mutability],
|
||||
mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
// This is hokey. We should have mutability inference as a
|
||||
// variable. But for now, try &const, then &, then &mut:
|
||||
let region =
|
||||
@ -867,7 +861,7 @@ impl<'a> LookupContext<'a> {
|
||||
}
|
||||
|
||||
fn search_for_method(&self, rcvr_ty: ty::t)
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
|
||||
let _indenter = indenter();
|
||||
|
||||
@ -899,7 +893,7 @@ impl<'a> LookupContext<'a> {
|
||||
fn consider_candidates(&self,
|
||||
rcvr_ty: ty::t,
|
||||
candidates: &mut ~[Candidate])
|
||||
-> Option<method_origin> {
|
||||
-> Option<MethodCallee> {
|
||||
// FIXME(pcwalton): Do we need to clone here?
|
||||
let relevant_candidates: ~[Candidate] =
|
||||
candidates.iter().map(|c| (*c).clone()).
|
||||
@ -970,7 +964,7 @@ impl<'a> LookupContext<'a> {
|
||||
}
|
||||
|
||||
fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
|
||||
-> method_origin {
|
||||
-> MethodCallee {
|
||||
// This method performs two sets of substitutions, one after the other:
|
||||
// 1. Substitute values for any type/lifetime parameters from the impl and
|
||||
// method declaration into the method type. This is the function type
|
||||
@ -1079,9 +1073,11 @@ impl<'a> LookupContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
self.fcx.write_ty(self.callee_id, fty);
|
||||
self.fcx.write_substs(self.callee_id, all_substs);
|
||||
candidate.origin
|
||||
MethodCallee {
|
||||
origin: candidate.origin,
|
||||
ty: fty,
|
||||
substs: all_substs
|
||||
}
|
||||
}
|
||||
|
||||
fn construct_transformed_self_ty_for_object(
|
||||
|
@ -1088,8 +1088,7 @@ impl FnCtxt {
|
||||
}
|
||||
|
||||
pub fn node_ty(&self, id: ast::NodeId) -> ty::t {
|
||||
let node_types = self.inh.node_types.borrow();
|
||||
match node_types.get().find(&id) {
|
||||
match self.inh.node_types.borrow().get().find(&id) {
|
||||
Some(&t) => t,
|
||||
None => {
|
||||
self.tcx().sess.bug(
|
||||
@ -1100,9 +1099,20 @@ impl FnCtxt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method_ty(&self, id: ast::NodeId) -> ty::t {
|
||||
match self.inh.method_map.borrow().get().find(&id) {
|
||||
Some(method) => method.ty,
|
||||
None => {
|
||||
self.tcx().sess.bug(
|
||||
format!("no method entry for node {}: {} in fcx {}",
|
||||
id, self.tcx().map.node_to_str(id),
|
||||
self.tag()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_ty_substs(&self, id: ast::NodeId) -> ty::substs {
|
||||
let mut node_type_substs = self.inh.node_type_substs.borrow_mut();
|
||||
match node_type_substs.get().find(&id) {
|
||||
match self.inh.node_type_substs.borrow().get().find(&id) {
|
||||
Some(ts) => (*ts).clone(),
|
||||
None => {
|
||||
self.tcx().sess.bug(
|
||||
@ -1113,6 +1123,18 @@ impl FnCtxt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method_ty_substs(&self, id: ast::NodeId) -> ty::substs {
|
||||
match self.inh.method_map.borrow().get().find(&id) {
|
||||
Some(method) => method.substs.clone(),
|
||||
None => {
|
||||
self.tcx().sess.bug(
|
||||
format!("no method entry for node {}: {} in fcx {}",
|
||||
id, self.tcx().map.node_to_str(id),
|
||||
self.tag()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opt_node_ty_substs(&self,
|
||||
id: ast::NodeId,
|
||||
f: |&ty::substs| -> bool)
|
||||
@ -1776,7 +1798,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
|
||||
// A generic function for doing all of the checking for call expressions
|
||||
fn check_call(fcx: @FnCtxt,
|
||||
callee_id: ast::NodeId,
|
||||
call_expr: &ast::Expr,
|
||||
f: &ast::Expr,
|
||||
args: &[@ast::Expr]) {
|
||||
@ -1787,13 +1808,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
// Store the type of `f` as the type of the callee
|
||||
let fn_ty = fcx.expr_ty(f);
|
||||
|
||||
// FIXME(#6273) should write callee type AFTER regions have
|
||||
// been subst'd. However, it is awkward to deal with this
|
||||
// now. Best thing would I think be to just have a separate
|
||||
// "callee table" that contains the FnSig and not a general
|
||||
// purpose ty::t
|
||||
fcx.write_ty(callee_id, fn_ty);
|
||||
|
||||
// Extract the function signature from `in_fty`.
|
||||
let fn_sty = structure_of(fcx, f.span, fn_ty);
|
||||
|
||||
@ -1834,7 +1848,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
|
||||
// Checks a method call.
|
||||
fn check_method_call(fcx: @FnCtxt,
|
||||
callee_id: ast::NodeId,
|
||||
expr: &ast::Expr,
|
||||
method_name: ast::Ident,
|
||||
args: &[@ast::Expr],
|
||||
@ -1848,20 +1861,16 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
fcx.expr_ty(rcvr));
|
||||
|
||||
let tps = tps.map(|&ast_ty| fcx.to_ty(ast_ty));
|
||||
match method::lookup(fcx,
|
||||
expr,
|
||||
rcvr,
|
||||
callee_id,
|
||||
method_name.name,
|
||||
expr_t,
|
||||
tps,
|
||||
DontDerefArgs,
|
||||
CheckTraitsAndInherentMethods,
|
||||
AutoderefReceiver) {
|
||||
Some(ref entry) => {
|
||||
let method_map = fcx.inh.method_map;
|
||||
let mut method_map = method_map.borrow_mut();
|
||||
method_map.get().insert(expr.id, (*entry));
|
||||
let fn_ty = match method::lookup(fcx, expr, rcvr,
|
||||
method_name.name,
|
||||
expr_t, tps,
|
||||
DontDerefArgs,
|
||||
CheckTraitsAndInherentMethods,
|
||||
AutoderefReceiver) {
|
||||
Some(method) => {
|
||||
let method_ty = method.ty;
|
||||
fcx.inh.method_map.borrow_mut().get().insert(expr.id, method);
|
||||
method_ty
|
||||
}
|
||||
None => {
|
||||
debug!("(checking method call) failing expr is {}", expr.id);
|
||||
@ -1877,12 +1886,11 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
|
||||
// Add error type for the result
|
||||
fcx.write_error(expr.id);
|
||||
fcx.write_error(callee_id);
|
||||
ty::mk_err()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Call the generic checker.
|
||||
let fn_ty = fcx.node_ty(callee_id);
|
||||
let ret_ty = check_method_argument_types(fcx, expr.span,
|
||||
fn_ty, expr, args,
|
||||
DontDerefArgs);
|
||||
@ -1932,7 +1940,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
}
|
||||
|
||||
fn lookup_op_method(fcx: @FnCtxt,
|
||||
callee_id: ast::NodeId,
|
||||
op_ex: &ast::Expr,
|
||||
self_t: ty::t,
|
||||
opname: ast::Name,
|
||||
@ -1940,18 +1947,17 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
args: &[@ast::Expr],
|
||||
autoderef_receiver: AutoderefReceiverFlag,
|
||||
unbound_method: ||) -> ty::t {
|
||||
let origin = match trait_did {
|
||||
let method = match trait_did {
|
||||
Some(trait_did) => {
|
||||
method::lookup_in_trait(fcx, op_ex, args[0], callee_id, opname,
|
||||
trait_did, self_t, [], autoderef_receiver)
|
||||
method::lookup_in_trait(fcx, op_ex, args[0], opname, trait_did,
|
||||
self_t, [], autoderef_receiver)
|
||||
}
|
||||
None => None
|
||||
};
|
||||
match origin {
|
||||
Some(origin) => {
|
||||
let method_ty = fcx.node_ty(callee_id);
|
||||
let method_map = fcx.inh.method_map;
|
||||
method_map.borrow_mut().get().insert(op_ex.id, origin);
|
||||
match method {
|
||||
Some(method) => {
|
||||
let method_ty = method.ty;
|
||||
fcx.inh.method_map.borrow_mut().get().insert(op_ex.id, method);
|
||||
check_method_argument_types(fcx, op_ex.span,
|
||||
method_ty, op_ex,
|
||||
args, DoDerefArgs)
|
||||
@ -1971,7 +1977,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
|
||||
// could be either an expr_binop or an expr_assign_binop
|
||||
fn check_binop(fcx: @FnCtxt,
|
||||
callee_id: ast::NodeId,
|
||||
expr: &ast::Expr,
|
||||
op: ast::BinOp,
|
||||
lhs: @ast::Expr,
|
||||
@ -2023,7 +2028,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
|
||||
// Check for overloaded operators if not an assignment.
|
||||
let result_t = if is_binop_assignment == SimpleBinop {
|
||||
check_user_binop(fcx, callee_id, expr, lhs, lhs_t, op, rhs)
|
||||
check_user_binop(fcx, expr, lhs, lhs_t, op, rhs)
|
||||
} else {
|
||||
fcx.type_error_message(expr.span,
|
||||
|actual| {
|
||||
@ -2045,7 +2050,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
}
|
||||
|
||||
fn check_user_binop(fcx: @FnCtxt,
|
||||
callee_id: ast::NodeId,
|
||||
ex: &ast::Expr,
|
||||
lhs_expr: @ast::Expr,
|
||||
lhs_resolved_t: ty::t,
|
||||
@ -2075,7 +2079,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
return ty::mk_err();
|
||||
}
|
||||
};
|
||||
lookup_op_method(fcx, callee_id, ex, lhs_resolved_t, token::intern(name),
|
||||
lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
|
||||
trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
|
||||
fcx.type_error_message(ex.span, |actual| {
|
||||
format!("binary operation `{}` cannot be applied to type `{}`",
|
||||
@ -2085,14 +2089,13 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
}
|
||||
|
||||
fn check_user_unop(fcx: @FnCtxt,
|
||||
callee_id: ast::NodeId,
|
||||
op_str: &str,
|
||||
mname: &str,
|
||||
trait_did: Option<ast::DefId>,
|
||||
ex: &ast::Expr,
|
||||
rhs_expr: @ast::Expr,
|
||||
rhs_t: ty::t) -> ty::t {
|
||||
lookup_op_method(fcx, callee_id, ex, rhs_t, token::intern(mname),
|
||||
lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
|
||||
trait_did, [rhs_expr], DontAutoderefReceiver, || {
|
||||
fcx.type_error_message(ex.span, |actual| {
|
||||
format!("cannot apply unary operator `{}` to type `{}`", op_str, actual)
|
||||
@ -2264,7 +2267,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
match method::lookup(fcx,
|
||||
expr,
|
||||
base,
|
||||
expr.id,
|
||||
field,
|
||||
expr_t,
|
||||
tps,
|
||||
@ -2620,8 +2622,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
let typ = check_lit(fcx, lit);
|
||||
fcx.write_ty(id, typ);
|
||||
}
|
||||
ast::ExprBinary(callee_id, op, lhs, rhs) => {
|
||||
check_binop(fcx, callee_id, expr, op, lhs, rhs, SimpleBinop);
|
||||
ast::ExprBinary(op, lhs, rhs) => {
|
||||
check_binop(fcx, expr, op, lhs, rhs, SimpleBinop);
|
||||
|
||||
let lhs_ty = fcx.expr_ty(lhs);
|
||||
let rhs_ty = fcx.expr_ty(rhs);
|
||||
@ -2634,8 +2636,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
}
|
||||
ast::ExprAssignOp(callee_id, op, lhs, rhs) => {
|
||||
check_binop(fcx, callee_id, expr, op, lhs, rhs, BinopAssignment);
|
||||
ast::ExprAssignOp(op, lhs, rhs) => {
|
||||
check_binop(fcx, expr, op, lhs, rhs, BinopAssignment);
|
||||
|
||||
let lhs_t = fcx.expr_ty(lhs);
|
||||
let result_t = fcx.expr_ty(expr);
|
||||
@ -2654,7 +2656,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
fcx.write_nil(expr.id);
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(callee_id, unop, oprnd) => {
|
||||
ast::ExprUnary(unop, oprnd) => {
|
||||
let exp_inner = unpack_expected(fcx, expected, |sty| {
|
||||
match unop {
|
||||
ast::UnBox | ast::UnUniq => match *sty {
|
||||
@ -2710,7 +2712,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
oprnd_t);
|
||||
if !(ty::type_is_integral(oprnd_t) ||
|
||||
ty::get(oprnd_t).sty == ty::ty_bool) {
|
||||
oprnd_t = check_user_unop(fcx, callee_id, "!", "not",
|
||||
oprnd_t = check_user_unop(fcx, "!", "not",
|
||||
tcx.lang_items.not_trait(),
|
||||
expr, oprnd, oprnd_t);
|
||||
}
|
||||
@ -2720,7 +2722,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
oprnd_t);
|
||||
if !(ty::type_is_integral(oprnd_t) ||
|
||||
ty::type_is_fp(oprnd_t)) {
|
||||
oprnd_t = check_user_unop(fcx, callee_id, "-", "neg",
|
||||
oprnd_t = check_user_unop(fcx, "-", "neg",
|
||||
tcx.lang_items.neg_trait(),
|
||||
expr, oprnd, oprnd_t);
|
||||
}
|
||||
@ -2883,7 +2885,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
fcx.write_ty(id, fcx.node_ty(b.id));
|
||||
}
|
||||
ast::ExprCall(f, ref args) => {
|
||||
check_call(fcx, expr.id, expr, f, *args);
|
||||
check_call(fcx, expr, f, *args);
|
||||
let f_ty = fcx.expr_ty(f);
|
||||
let (args_bot, args_err) = args.iter().fold((false, false),
|
||||
|(rest_bot, rest_err), a| {
|
||||
@ -2898,8 +2900,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
}
|
||||
ast::ExprMethodCall(callee_id, ident, ref tps, ref args) => {
|
||||
check_method_call(fcx, callee_id, expr, ident, *args, *tps);
|
||||
ast::ExprMethodCall(ident, ref tps, ref args) => {
|
||||
check_method_call(fcx, expr, ident, *args, *tps);
|
||||
let arg_tys = args.map(|a| fcx.expr_ty(*a));
|
||||
let (args_bot, args_err) = arg_tys.iter().fold((false, false),
|
||||
|(rest_bot, rest_err), a| {
|
||||
@ -3100,7 +3102,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
ast::ExprField(base, field, ref tys) => {
|
||||
check_field(fcx, expr, base, field.name, *tys);
|
||||
}
|
||||
ast::ExprIndex(callee_id, base, idx) => {
|
||||
ast::ExprIndex(base, idx) => {
|
||||
check_expr(fcx, base);
|
||||
check_expr(fcx, idx);
|
||||
let raw_base_t = fcx.expr_ty(base);
|
||||
@ -3133,7 +3135,6 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
None);
|
||||
};
|
||||
let ret_ty = lookup_op_method(fcx,
|
||||
callee_id,
|
||||
expr,
|
||||
resolved,
|
||||
token::intern("index"),
|
||||
|
@ -226,6 +226,12 @@ impl Rcx {
|
||||
self.resolve_type(t)
|
||||
}
|
||||
|
||||
/// Try to resolve the callee type for the given method call.
|
||||
pub fn resolve_method_type(&mut self, id: ast::NodeId) -> ty::t {
|
||||
let t = self.fcx.method_ty(id);
|
||||
self.resolve_type(t)
|
||||
}
|
||||
|
||||
/// Try to resolve the type for the given node.
|
||||
pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> ty::t {
|
||||
let ty_unadjusted = self.resolve_node_type(expr.id);
|
||||
@ -378,10 +384,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
debug!("regionck::visit_expr(e={}, repeating_scope={:?})",
|
||||
expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
|
||||
|
||||
let has_method_map = {
|
||||
let method_map = rcx.fcx.inh.method_map;
|
||||
method_map.get().contains_key(&expr.id)
|
||||
};
|
||||
let has_method_map = rcx.fcx.inh.method_map.get().contains_key(&expr.id);
|
||||
|
||||
// Check any autoderefs or autorefs that appear.
|
||||
{
|
||||
@ -434,13 +437,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
match expr.node {
|
||||
ast::ExprCall(callee, ref args) => {
|
||||
constrain_callee(rcx, callee.id, expr, callee);
|
||||
constrain_call(rcx, callee.id, expr, None, *args, false);
|
||||
constrain_call(rcx, Some(callee.id), expr, None, *args, false);
|
||||
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(callee_id, _, _, ref args) => {
|
||||
constrain_call(rcx, callee_id, expr, Some(args[0]),
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
constrain_call(rcx, None, expr, Some(args[0]),
|
||||
args.slice_from(1), false);
|
||||
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
@ -451,9 +454,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprAssignOp(callee_id, _, lhs, rhs) => {
|
||||
ast::ExprAssignOp(_, lhs, rhs) => {
|
||||
if has_method_map {
|
||||
constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true);
|
||||
constrain_call(rcx, None, expr, Some(lhs), [rhs], true);
|
||||
}
|
||||
|
||||
adjust_borrow_kind_for_assignment_lhs(rcx, lhs);
|
||||
@ -461,25 +464,25 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprIndex(callee_id, lhs, rhs) |
|
||||
ast::ExprBinary(callee_id, _, lhs, rhs) if has_method_map => {
|
||||
ast::ExprIndex(lhs, rhs) |
|
||||
ast::ExprBinary(_, lhs, rhs) if has_method_map => {
|
||||
// As `expr_method_call`, but the call is via an
|
||||
// overloaded op. Note that we (sadly) currently use an
|
||||
// implicit "by ref" sort of passing style here. This
|
||||
// should be converted to an adjustment!
|
||||
constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true);
|
||||
constrain_call(rcx, None, expr, Some(lhs), [rhs], true);
|
||||
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprUnary(callee_id, _, lhs) if has_method_map => {
|
||||
ast::ExprUnary(_, lhs) if has_method_map => {
|
||||
// As above.
|
||||
constrain_call(rcx, callee_id, expr, Some(lhs), [], true);
|
||||
constrain_call(rcx, None, expr, Some(lhs), [], true);
|
||||
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, ast::UnDeref, base) => {
|
||||
ast::ExprUnary(ast::UnDeref, base) => {
|
||||
// For *a, the lifetime of a must enclose the deref
|
||||
let base_ty = rcx.resolve_node_type(base.id);
|
||||
constrain_derefs(rcx, expr, 1, base_ty);
|
||||
@ -487,7 +490,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
visit::walk_expr(rcx, expr, ());
|
||||
}
|
||||
|
||||
ast::ExprIndex(_, vec_expr, _) => {
|
||||
ast::ExprIndex(vec_expr, _) => {
|
||||
// For a[b], the lifetime of a must enclose the deref
|
||||
let vec_type = rcx.resolve_expr_type_adjusted(vec_expr);
|
||||
constrain_index(rcx, expr, vec_type);
|
||||
@ -711,8 +714,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
fn constrain_callee(rcx: &mut Rcx,
|
||||
callee_id: ast::NodeId,
|
||||
call_expr: &ast::Expr,
|
||||
callee_expr: &ast::Expr)
|
||||
{
|
||||
callee_expr: &ast::Expr) {
|
||||
let call_region = ty::ReScope(call_expr.id);
|
||||
|
||||
let callee_ty = rcx.resolve_node_type(callee_id);
|
||||
@ -736,12 +738,11 @@ fn constrain_callee(rcx: &mut Rcx,
|
||||
fn constrain_call(rcx: &mut Rcx,
|
||||
// might be expr_call, expr_method_call, or an overloaded
|
||||
// operator
|
||||
callee_id: ast::NodeId,
|
||||
fn_expr_id: Option<ast::NodeId>,
|
||||
call_expr: &ast::Expr,
|
||||
receiver: Option<@ast::Expr>,
|
||||
arg_exprs: &[@ast::Expr],
|
||||
implicitly_ref_args: bool)
|
||||
{
|
||||
implicitly_ref_args: bool) {
|
||||
//! Invoked on every call site (i.e., normal calls, method calls,
|
||||
//! and overloaded operators). Constrains the regions which appear
|
||||
//! in the type of the function. Also constrains the regions that
|
||||
@ -756,7 +757,10 @@ fn constrain_call(rcx: &mut Rcx,
|
||||
receiver.repr(tcx),
|
||||
arg_exprs.repr(tcx),
|
||||
implicitly_ref_args);
|
||||
let callee_ty = rcx.resolve_node_type(callee_id);
|
||||
let callee_ty = match fn_expr_id {
|
||||
Some(id) => rcx.resolve_node_type(id),
|
||||
None => rcx.resolve_method_type(call_expr.id)
|
||||
};
|
||||
if ty::type_is_error(callee_ty) {
|
||||
// Bail, as function type is unknown
|
||||
return;
|
||||
|
@ -537,11 +537,10 @@ fn connect_trait_tps(vcx: &VtableContext,
|
||||
relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref);
|
||||
}
|
||||
|
||||
fn insert_vtables(fcx: &FnCtxt, callee_id: ast::NodeId, vtables: vtable_res) {
|
||||
debug!("insert_vtables(callee_id={}, vtables={:?})",
|
||||
callee_id, vtables.repr(fcx.tcx()));
|
||||
let mut vtable_map = fcx.inh.vtable_map.borrow_mut();
|
||||
vtable_map.get().insert(callee_id, vtables);
|
||||
fn insert_vtables(fcx: &FnCtxt, expr_id: ast::NodeId, vtables: vtable_res) {
|
||||
debug!("insert_vtables(expr_id={}, vtables={:?})",
|
||||
expr_id, vtables.repr(fcx.tcx()));
|
||||
fcx.inh.vtable_map.borrow_mut().get().insert(expr_id, vtables);
|
||||
}
|
||||
|
||||
pub fn location_info_for_expr(expr: &ast::Expr) -> LocationInfo {
|
||||
@ -692,23 +691,23 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
|
||||
}
|
||||
|
||||
// Must resolve bounds on methods with bounded params
|
||||
ast::ExprBinary(callee_id, _, _, _) |
|
||||
ast::ExprUnary(callee_id, _, _) |
|
||||
ast::ExprAssignOp(callee_id, _, _, _) |
|
||||
ast::ExprIndex(callee_id, _, _) |
|
||||
ast::ExprMethodCall(callee_id, _, _, _) => {
|
||||
ast::ExprBinary(_, _, _) |
|
||||
ast::ExprUnary(_, _) |
|
||||
ast::ExprAssignOp(_, _, _) |
|
||||
ast::ExprIndex(_, _) |
|
||||
ast::ExprMethodCall(_, _, _) => {
|
||||
match fcx.inh.method_map.borrow().get().find(&ex.id) {
|
||||
Some(origin) => {
|
||||
Some(method) => {
|
||||
debug!("vtable resolution on parameter bounds for method call {}",
|
||||
ex.repr(fcx.tcx()));
|
||||
let type_param_defs = ty::method_call_type_param_defs(cx.tcx, *origin);
|
||||
let type_param_defs = ty::method_call_type_param_defs(cx.tcx, method.origin);
|
||||
if has_trait_bounds(*type_param_defs.borrow()) {
|
||||
let substs = fcx.node_ty_substs(callee_id);
|
||||
let substs = fcx.method_ty_substs(ex.id);
|
||||
let vcx = fcx.vtable_context();
|
||||
let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex),
|
||||
*type_param_defs.borrow(), &substs, is_early);
|
||||
if !is_early {
|
||||
insert_vtables(fcx, callee_id, vtbls);
|
||||
insert_vtables(fcx, ex.id, vtbls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use middle::typeck::check::FnCtxt;
|
||||
use middle::typeck::infer::{force_all, resolve_all, resolve_region};
|
||||
use middle::typeck::infer::resolve_type;
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::MethodCallee;
|
||||
use middle::typeck::{vtable_res, vtable_origin};
|
||||
use middle::typeck::{vtable_static, vtable_param};
|
||||
use middle::typeck::write_substs_to_tcx;
|
||||
@ -61,39 +62,54 @@ fn resolve_type_vars_in_types(fcx: @FnCtxt, sp: Span, tys: &[ty::t])
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_method_map_entry(fcx: @FnCtxt, id: ast::NodeId) {
|
||||
fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) {
|
||||
let fcx = wbcx.fcx;
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
// Resolve any method map entry
|
||||
let method_map_entry_opt = {
|
||||
let method_map = fcx.inh.method_map.borrow();
|
||||
method_map.get().find_copy(&id)
|
||||
};
|
||||
match method_map_entry_opt {
|
||||
None => {}
|
||||
Some(mme) => {
|
||||
debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})", id, mme);
|
||||
let mut method_map = fcx.ccx.method_map.borrow_mut();
|
||||
method_map.get().insert(id, mme);
|
||||
match fcx.inh.method_map.borrow().get().find(&id) {
|
||||
Some(method) => {
|
||||
debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})",
|
||||
id, method.repr(tcx));
|
||||
let method_ty = match resolve_type_vars_in_type(fcx, sp, method.ty) {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
wbcx.success = false;
|
||||
return;
|
||||
}
|
||||
};
|
||||
let mut new_tps = ~[];
|
||||
for &subst in method.substs.tps.iter() {
|
||||
match resolve_type_vars_in_type(fcx, sp, subst) {
|
||||
Some(t) => new_tps.push(t),
|
||||
None => { wbcx.success = false; return; }
|
||||
}
|
||||
}
|
||||
let new_method = MethodCallee {
|
||||
origin: method.origin,
|
||||
ty: method_ty,
|
||||
substs: ty::substs {
|
||||
tps: new_tps,
|
||||
regions: ty::ErasedRegions,
|
||||
self_ty: None
|
||||
}
|
||||
};
|
||||
fcx.ccx.method_map.borrow_mut().get().insert(id, new_method);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_vtable_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
|
||||
// Resolve any method map entry
|
||||
{
|
||||
let origins_opt = {
|
||||
let vtable_map = fcx.inh.vtable_map.borrow();
|
||||
vtable_map.get().find_copy(&id)
|
||||
};
|
||||
match origins_opt {
|
||||
None => {}
|
||||
Some(origins) => {
|
||||
let r_origins = resolve_origins(fcx, sp, origins);
|
||||
let mut vtable_map = fcx.ccx.vtable_map.borrow_mut();
|
||||
vtable_map.get().insert(id, r_origins);
|
||||
debug!("writeback::resolve_vtable_map_entry(id={}, vtables={:?})",
|
||||
id, r_origins.repr(fcx.tcx()));
|
||||
}
|
||||
// Resolve any vtable map entry
|
||||
match fcx.inh.vtable_map.borrow().get().find_copy(&id) {
|
||||
Some(origins) => {
|
||||
let r_origins = resolve_origins(fcx, sp, origins);
|
||||
fcx.ccx.vtable_map.borrow_mut().get().insert(id, r_origins);
|
||||
debug!("writeback::resolve_vtable_map_entry(id={}, vtables={:?})",
|
||||
id, r_origins.repr(fcx.tcx()));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
fn resolve_origins(fcx: @FnCtxt, sp: Span,
|
||||
@ -241,21 +257,6 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_resolve_type_vars_for_node(wbcx: &mut WbCtxt,
|
||||
sp: Span,
|
||||
id: ast::NodeId)
|
||||
-> Option<ty::t> {
|
||||
let contained = {
|
||||
let node_types = wbcx.fcx.inh.node_types.borrow();
|
||||
node_types.get().contains_key(&id)
|
||||
};
|
||||
if contained {
|
||||
resolve_type_vars_for_node(wbcx, sp, id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
struct WbCtxt {
|
||||
fcx: @FnCtxt,
|
||||
|
||||
@ -276,22 +277,8 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
|
||||
}
|
||||
|
||||
resolve_type_vars_for_node(wbcx, e.span, e.id);
|
||||
|
||||
resolve_method_map_entry(wbcx.fcx, e.id);
|
||||
{
|
||||
let r = e.get_callee_id();
|
||||
for callee_id in r.iter() {
|
||||
resolve_method_map_entry(wbcx.fcx, *callee_id);
|
||||
}
|
||||
}
|
||||
|
||||
resolve_method_map_entry(wbcx, e.span, e.id);
|
||||
resolve_vtable_map_entry(wbcx.fcx, e.span, e.id);
|
||||
{
|
||||
let r = e.get_callee_id();
|
||||
for callee_id in r.iter() {
|
||||
resolve_vtable_map_entry(wbcx.fcx, e.span, *callee_id);
|
||||
}
|
||||
}
|
||||
|
||||
match e.node {
|
||||
ast::ExprFnBlock(ref decl, _) | ast::ExprProc(ref decl, _) => {
|
||||
@ -299,20 +286,7 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
|
||||
let _ = resolve_type_vars_for_node(wbcx, e.span, input.id);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprBinary(callee_id, _, _, _) |
|
||||
ast::ExprUnary(callee_id, _, _) |
|
||||
ast::ExprAssignOp(callee_id, _, _, _) |
|
||||
ast::ExprIndex(callee_id, _, _) => {
|
||||
maybe_resolve_type_vars_for_node(wbcx, e.span, callee_id);
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(callee_id, _, _, _) => {
|
||||
// We must always have written in a callee ID type for these.
|
||||
resolve_type_vars_for_node(wbcx, e.span, callee_id);
|
||||
}
|
||||
|
||||
_ => ()
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_expr(wbcx, e, ());
|
||||
|
@ -142,9 +142,16 @@ pub struct MethodObject {
|
||||
real_index: uint,
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct MethodCallee {
|
||||
origin: MethodOrigin,
|
||||
ty: ty::t,
|
||||
substs: ty::substs
|
||||
}
|
||||
|
||||
// maps from an expression id that corresponds to a method call to the details
|
||||
// of the method to be invoked
|
||||
pub type method_map = @RefCell<HashMap<ast::NodeId, method_origin>>;
|
||||
pub type MethodMap = @RefCell<HashMap<ast::NodeId, MethodCallee>>;
|
||||
|
||||
pub type vtable_param_res = @~[vtable_origin];
|
||||
// Resolutions for bounds of all parameters, left to right, for a given path.
|
||||
|
@ -74,9 +74,6 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region)
|
||||
Some(ast_map::NodeBlock(ref blk)) => {
|
||||
explain_span(cx, "block", blk.span)
|
||||
}
|
||||
Some(ast_map::NodeCalleeScope(expr)) => {
|
||||
explain_span(cx, "callee", expr.span)
|
||||
}
|
||||
Some(ast_map::NodeExpr(expr)) => {
|
||||
match expr.node {
|
||||
ast::ExprCall(..) => explain_span(cx, "call", expr.span),
|
||||
@ -870,6 +867,15 @@ impl Repr for ty::FnSig {
|
||||
}
|
||||
}
|
||||
|
||||
impl Repr for typeck::MethodCallee {
|
||||
fn repr(&self, tcx: ctxt) -> ~str {
|
||||
format!("MethodCallee \\{origin: {}, ty: {}, {}\\}",
|
||||
self.origin.repr(tcx),
|
||||
self.ty.repr(tcx),
|
||||
self.substs.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl Repr for typeck::MethodOrigin {
|
||||
fn repr(&self, tcx: ctxt) -> ~str {
|
||||
match self {
|
||||
|
@ -521,19 +521,6 @@ pub struct Expr {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
pub fn get_callee_id(&self) -> Option<NodeId> {
|
||||
match self.node {
|
||||
ExprMethodCall(callee_id, _, _, _) |
|
||||
ExprIndex(callee_id, _, _) |
|
||||
ExprBinary(callee_id, _, _, _) |
|
||||
ExprAssignOp(callee_id, _, _, _) |
|
||||
ExprUnary(callee_id, _, _) => Some(callee_id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Expr_ {
|
||||
ExprVstore(@Expr, ExprVstore),
|
||||
@ -541,10 +528,10 @@ pub enum Expr_ {
|
||||
ExprBox(@Expr, @Expr),
|
||||
ExprVec(~[@Expr], Mutability),
|
||||
ExprCall(@Expr, ~[@Expr]),
|
||||
ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr]),
|
||||
ExprMethodCall(Ident, ~[P<Ty>], ~[@Expr]),
|
||||
ExprTup(~[@Expr]),
|
||||
ExprBinary(NodeId, BinOp, @Expr, @Expr),
|
||||
ExprUnary(NodeId, UnOp, @Expr),
|
||||
ExprBinary(BinOp, @Expr, @Expr),
|
||||
ExprUnary(UnOp, @Expr),
|
||||
ExprLit(@Lit),
|
||||
ExprCast(@Expr, P<Ty>),
|
||||
ExprIf(@Expr, P<Block>, Option<@Expr>),
|
||||
@ -560,9 +547,9 @@ pub enum Expr_ {
|
||||
ExprBlock(P<Block>),
|
||||
|
||||
ExprAssign(@Expr, @Expr),
|
||||
ExprAssignOp(NodeId, BinOp, @Expr, @Expr),
|
||||
ExprAssignOp(BinOp, @Expr, @Expr),
|
||||
ExprField(@Expr, Ident, ~[P<Ty>]),
|
||||
ExprIndex(NodeId, @Expr, @Expr),
|
||||
ExprIndex(@Expr, @Expr),
|
||||
|
||||
/// Expression that looks like a "name". For example,
|
||||
/// `std::vec::from_elem::<uint>` is an ExprPath that's the "name" part
|
||||
|
@ -107,7 +107,6 @@ pub enum Node {
|
||||
|
||||
/// NodeStructCtor represents a tuple struct.
|
||||
NodeStructCtor(@StructDef),
|
||||
NodeCalleeScope(@Expr),
|
||||
}
|
||||
|
||||
// The odd layout is to bring down the total size.
|
||||
@ -128,7 +127,6 @@ enum MapEntry {
|
||||
EntryLocal(NodeId, @Pat),
|
||||
EntryBlock(NodeId, P<Block>),
|
||||
EntryStructCtor(NodeId, @StructDef),
|
||||
EntryCalleeScope(NodeId, @Expr),
|
||||
|
||||
// Roots for node trees.
|
||||
RootCrate,
|
||||
@ -155,7 +153,6 @@ impl MapEntry {
|
||||
EntryLocal(id, _) => id,
|
||||
EntryBlock(id, _) => id,
|
||||
EntryStructCtor(id, _) => id,
|
||||
EntryCalleeScope(id, _) => id,
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
@ -173,7 +170,6 @@ impl MapEntry {
|
||||
EntryLocal(_, p) => NodeLocal(p),
|
||||
EntryBlock(_, p) => NodeBlock(p),
|
||||
EntryStructCtor(_, p) => NodeStructCtor(p),
|
||||
EntryCalleeScope(_, p) => NodeCalleeScope(p),
|
||||
_ => return None
|
||||
})
|
||||
}
|
||||
@ -368,7 +364,6 @@ impl Map {
|
||||
Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
|
||||
Some(NodeBlock(block)) => block.span,
|
||||
Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
|
||||
Some(NodeCalleeScope(expr)) => expr.span,
|
||||
_ => fail!("node_span: could not find span for id {}", id),
|
||||
}
|
||||
}
|
||||
@ -493,11 +488,6 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
|
||||
|
||||
self.insert(expr.id, EntryExpr(self.parent, expr));
|
||||
|
||||
// Expressions which are or might be calls:
|
||||
for callee_id in expr.get_callee_id().iter() {
|
||||
self.insert(*callee_id, EntryCalleeScope(self.parent, expr));
|
||||
}
|
||||
|
||||
expr
|
||||
}
|
||||
|
||||
@ -650,9 +640,6 @@ fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
|
||||
Some(NodeExpr(expr)) => {
|
||||
format!("expr {} (id={})", pprust::expr_to_str(expr), id)
|
||||
}
|
||||
Some(NodeCalleeScope(expr)) => {
|
||||
format!("callee_scope {} (id={})", pprust::expr_to_str(expr), id)
|
||||
}
|
||||
Some(NodeStmt(stmt)) => {
|
||||
format!("stmt {} (id={})", pprust::stmt_to_str(stmt), id)
|
||||
}
|
||||
|
@ -450,12 +450,6 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
|
||||
|
||||
|
||||
fn visit_expr(&mut self, expression: &Expr, env: ()) {
|
||||
{
|
||||
let optional_callee_id = expression.get_callee_id();
|
||||
for callee_id in optional_callee_id.iter() {
|
||||
self.operation.visit_id(*callee_id)
|
||||
}
|
||||
}
|
||||
self.operation.visit_id(expression.id);
|
||||
visit::walk_expr(self, expression, env)
|
||||
}
|
||||
|
@ -502,15 +502,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
|
||||
fn expr_binary(&self, sp: Span, op: ast::BinOp,
|
||||
lhs: @ast::Expr, rhs: @ast::Expr) -> @ast::Expr {
|
||||
self.expr(sp, ast::ExprBinary(ast::DUMMY_NODE_ID, op, lhs, rhs))
|
||||
self.expr(sp, ast::ExprBinary(op, lhs, rhs))
|
||||
}
|
||||
|
||||
fn expr_deref(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
|
||||
self.expr_unary(sp, ast::UnDeref, e)
|
||||
}
|
||||
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr)
|
||||
-> @ast::Expr {
|
||||
self.expr(sp, ast::ExprUnary(ast::DUMMY_NODE_ID, op, e))
|
||||
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: @ast::Expr) -> @ast::Expr {
|
||||
self.expr(sp, ast::ExprUnary(op, e))
|
||||
}
|
||||
|
||||
fn expr_managed(&self, sp: Span, e: @ast::Expr) -> @ast::Expr {
|
||||
@ -543,7 +542,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
ident: ast::Ident,
|
||||
mut args: ~[@ast::Expr]) -> @ast::Expr {
|
||||
args.unshift(expr);
|
||||
self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args))
|
||||
self.expr(span, ast::ExprMethodCall(ident, ~[], args))
|
||||
}
|
||||
fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
|
||||
self.expr(b.span, ast::ExprBlock(b))
|
||||
|
@ -749,21 +749,19 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
|
||||
ExprCall(folder.fold_expr(f),
|
||||
args.map(|&x| folder.fold_expr(x)))
|
||||
}
|
||||
ExprMethodCall(callee_id, i, ref tps, ref args) => {
|
||||
ExprMethodCall(i, ref tps, ref args) => {
|
||||
ExprMethodCall(
|
||||
folder.new_id(callee_id),
|
||||
folder.fold_ident(i),
|
||||
tps.map(|&x| folder.fold_ty(x)),
|
||||
args.map(|&x| folder.fold_expr(x)))
|
||||
}
|
||||
ExprBinary(callee_id, binop, lhs, rhs) => {
|
||||
ExprBinary(folder.new_id(callee_id),
|
||||
binop,
|
||||
ExprBinary(binop, lhs, rhs) => {
|
||||
ExprBinary(binop,
|
||||
folder.fold_expr(lhs),
|
||||
folder.fold_expr(rhs))
|
||||
}
|
||||
ExprUnary(callee_id, binop, ohs) => {
|
||||
ExprUnary(folder.new_id(callee_id), binop, folder.fold_expr(ohs))
|
||||
ExprUnary(binop, ohs) => {
|
||||
ExprUnary(binop, folder.fold_expr(ohs))
|
||||
}
|
||||
ExprLit(_) => e.node.clone(),
|
||||
ExprCast(expr, ty) => {
|
||||
@ -802,9 +800,8 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
|
||||
ExprAssign(el, er) => {
|
||||
ExprAssign(folder.fold_expr(el), folder.fold_expr(er))
|
||||
}
|
||||
ExprAssignOp(callee_id, op, el, er) => {
|
||||
ExprAssignOp(folder.new_id(callee_id),
|
||||
op,
|
||||
ExprAssignOp(op, el, er) => {
|
||||
ExprAssignOp(op,
|
||||
folder.fold_expr(el),
|
||||
folder.fold_expr(er))
|
||||
}
|
||||
@ -813,10 +810,8 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
|
||||
folder.fold_ident(id),
|
||||
tys.map(|&x| folder.fold_ty(x)))
|
||||
}
|
||||
ExprIndex(callee_id, el, er) => {
|
||||
ExprIndex(folder.new_id(callee_id),
|
||||
folder.fold_expr(el),
|
||||
folder.fold_expr(er))
|
||||
ExprIndex(el, er) => {
|
||||
ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
|
||||
}
|
||||
ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
|
||||
ExprLogLevel => ExprLogLevel,
|
||||
|
@ -1683,11 +1683,11 @@ impl Parser {
|
||||
}
|
||||
|
||||
pub fn mk_unary(&mut self, unop: ast::UnOp, expr: @Expr) -> ast::Expr_ {
|
||||
ExprUnary(ast::DUMMY_NODE_ID, unop, expr)
|
||||
ExprUnary(unop, expr)
|
||||
}
|
||||
|
||||
pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
|
||||
ExprBinary(ast::DUMMY_NODE_ID, binop, lhs, rhs)
|
||||
ExprBinary(binop, lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr]) -> ast::Expr_ {
|
||||
@ -1695,11 +1695,11 @@ impl Parser {
|
||||
}
|
||||
|
||||
fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr]) -> ast::Expr_ {
|
||||
ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args)
|
||||
ExprMethodCall(ident, tps, args)
|
||||
}
|
||||
|
||||
pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
|
||||
ExprIndex(ast::DUMMY_NODE_ID, expr, idx)
|
||||
ExprIndex(expr, idx)
|
||||
}
|
||||
|
||||
pub fn mk_field(&mut self, expr: @Expr, ident: Ident, tys: ~[P<Ty>]) -> ast::Expr_ {
|
||||
@ -1707,7 +1707,7 @@ impl Parser {
|
||||
}
|
||||
|
||||
pub fn mk_assign_op(&mut self, binop: ast::BinOp, lhs: @Expr, rhs: @Expr) -> ast::Expr_ {
|
||||
ExprAssignOp(ast::DUMMY_NODE_ID, binop, lhs, rhs)
|
||||
ExprAssignOp(binop, lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn mk_mac_expr(&mut self, lo: BytePos, hi: BytePos, m: Mac_) -> @Expr {
|
||||
|
@ -1235,7 +1235,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
|
||||
try!(print_expr(s, func));
|
||||
try!(print_call_post(s, *args));
|
||||
}
|
||||
ast::ExprMethodCall(_, ident, ref tys, ref args) => {
|
||||
ast::ExprMethodCall(ident, ref tys, ref args) => {
|
||||
let base_args = args.slice_from(1);
|
||||
try!(print_expr(s, args[0]));
|
||||
try!(word(&mut s.s, "."));
|
||||
@ -1247,13 +1247,13 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
|
||||
}
|
||||
try!(print_call_post(s, base_args));
|
||||
}
|
||||
ast::ExprBinary(_, op, lhs, rhs) => {
|
||||
ast::ExprBinary(op, lhs, rhs) => {
|
||||
try!(print_expr(s, lhs));
|
||||
try!(space(&mut s.s));
|
||||
try!(word_space(s, ast_util::binop_to_str(op)));
|
||||
try!(print_expr(s, rhs));
|
||||
}
|
||||
ast::ExprUnary(_, op, expr) => {
|
||||
ast::ExprUnary(op, expr) => {
|
||||
try!(word(&mut s.s, ast_util::unop_to_str(op)));
|
||||
try!(print_expr(s, expr));
|
||||
}
|
||||
@ -1442,7 +1442,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
|
||||
try!(word_space(s, "="));
|
||||
try!(print_expr(s, rhs));
|
||||
}
|
||||
ast::ExprAssignOp(_, op, lhs, rhs) => {
|
||||
ast::ExprAssignOp(op, lhs, rhs) => {
|
||||
try!(print_expr(s, lhs));
|
||||
try!(space(&mut s.s));
|
||||
try!(word(&mut s.s, ast_util::binop_to_str(op)));
|
||||
@ -1459,7 +1459,7 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
|
||||
try!(word(&mut s.s, ">"));
|
||||
}
|
||||
}
|
||||
ast::ExprIndex(_, expr, index) => {
|
||||
ast::ExprIndex(expr, index) => {
|
||||
try!(print_expr(s, expr));
|
||||
try!(word(&mut s.s, "["));
|
||||
try!(print_expr(s, index));
|
||||
|
@ -658,18 +658,17 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
|
||||
}
|
||||
visitor.visit_expr(callee_expression, env.clone())
|
||||
}
|
||||
ExprMethodCall(_, _, ref types, ref arguments) => {
|
||||
ExprMethodCall(_, ref types, ref arguments) => {
|
||||
walk_exprs(visitor, *arguments, env.clone());
|
||||
for &typ in types.iter() {
|
||||
visitor.visit_ty(typ, env.clone())
|
||||
}
|
||||
}
|
||||
ExprBinary(_, _, left_expression, right_expression) => {
|
||||
ExprBinary(_, left_expression, right_expression) => {
|
||||
visitor.visit_expr(left_expression, env.clone());
|
||||
visitor.visit_expr(right_expression, env.clone())
|
||||
}
|
||||
ExprAddrOf(_, subexpression) |
|
||||
ExprUnary(_, _, subexpression) => {
|
||||
ExprAddrOf(_, subexpression) | ExprUnary(_, subexpression) => {
|
||||
visitor.visit_expr(subexpression, env.clone())
|
||||
}
|
||||
ExprLit(_) => {}
|
||||
@ -719,7 +718,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
|
||||
visitor.visit_expr(right_hand_expression, env.clone());
|
||||
visitor.visit_expr(left_hand_expression, env.clone())
|
||||
}
|
||||
ExprAssignOp(_, _, left_expression, right_expression) => {
|
||||
ExprAssignOp(_, left_expression, right_expression) => {
|
||||
visitor.visit_expr(right_expression, env.clone());
|
||||
visitor.visit_expr(left_expression, env.clone())
|
||||
}
|
||||
@ -729,7 +728,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
|
||||
visitor.visit_ty(typ, env.clone())
|
||||
}
|
||||
}
|
||||
ExprIndex(_, main_expression, index_expression) => {
|
||||
ExprIndex(main_expression, index_expression) => {
|
||||
visitor.visit_expr(main_expression, env.clone());
|
||||
visitor.visit_expr(index_expression, env.clone())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user