diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 12c88ae7198..ea5301af9b2 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1321,13 +1321,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, sugar: ast::CallSugar) { // Index expressions need to be handled separately, to inform them // that they appear in call position. - match f.node { - ast::expr_field(ref base, ref field, ref tys) => { - check_field(fcx, f, true, *base, *field, *tys) - } - _ => check_expr(fcx, f) - }; - + let mut bot = check_expr(fcx, f); check_call_or_method(fcx, sp, call_expr_id, @@ -1689,7 +1683,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // Check field access expressions fn check_field(fcx: @mut FnCtxt, expr: @ast::expr, - is_callee: bool, base: @ast::expr, field: ast::ident, tys: &[@ast::Ty]) { @@ -1723,7 +1716,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } let tps = vec::map(tys, |ty| fcx.to_ty(*ty)); - match method::lookup(fcx, expr, base, @@ -1734,34 +1726,30 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, DontDerefArgs, CheckTraitsAndInherentMethods, AutoderefReceiver) { - Some(ref entry) => { - let method_map = fcx.ccx.method_map; - method_map.insert(expr.id, (*entry)); - - // If we have resolved to a method but this is not in - // a callee position, error - if !is_callee { - tcx.sess.span_err( - expr.span, - ~"attempted to take value of method \ - (try writing an anonymous function)"); - // Add error type for the result - fcx.write_error(expr.id); - } + Some(_) => { + fcx.type_error_message( + expr.span, + |actual| { + fmt!("attempted to take value of method `%s` on type `%s` \ + (try writing an anonymous function)", + *tcx.sess.str_of(field), actual) + }, + expr_t, None); } + None => { - fcx.type_error_message(expr.span, - |actual| { - fmt!("attempted access of field `%s` on type `%s`, but \ - no field or method with that name was found", - *tcx.sess.str_of(field), actual) - }, - expr_t, None); - // Add error type for the result - fcx.write_error(expr.id); + fcx.type_error_message( + expr.span, + |actual| { + fmt!("attempted access of field `%s` on type `%s`, \ + but no field with that name was found", + *tcx.sess.str_of(field), actual) + }, + expr_t, None); } } + fcx.write_error(expr.id); } fn check_struct_or_variant_fields(fcx: @mut FnCtxt, @@ -2750,15 +2738,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } ast::expr_field(base, field, ref tys) => { - check_field(fcx, expr, false, base, field, * tys); - let base_t = fcx.expr_ty(base); - if ty::type_is_error(base_t) { - fcx.write_error(id); - } - else if ty::type_is_bot(base_t) { - fcx.write_bot(id); - } - // Otherwise, type already got written + check_field(fcx, expr, base, field, *tys); } ast::expr_index(base, idx) => { check_expr(fcx, base); diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 54ca5dc0d72..e81e460e832 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -416,6 +416,16 @@ priv impl @ext_ctxt { self.expr(span, ast::expr_call(expr, args, ast::NoSugar)) } + fn expr_method_call( + &self, + span: span, + expr: @ast::expr, + ident: ast::ident, + +args: ~[@ast::expr] + ) -> @ast::expr { + self.expr(span, ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar)) + } + fn lambda_expr(&self, expr: @ast::expr) -> @ast::expr { self.lambda(self.expr_blk(expr)) } @@ -712,30 +722,24 @@ fn mk_struct_ser_impl( let fields = do mk_struct_fields(fields).mapi |idx, field| { // ast for `|| self.$(name).encode(__s)` let expr_lambda = cx.lambda_expr( - cx.expr_call( + cx.expr_method_call( span, cx.expr_field( span, - cx.expr_field( - span, - cx.expr_var(span, ~"self"), - field.ident - ), - cx.ident_of(~"encode") + cx.expr_var(span, ~"self"), + field.ident ), + cx.ident_of(~"encode"), ~[cx.expr_var(span, ~"__s")] ) ); // ast for `__s.emit_field($(name), $(idx), $(expr_lambda))` cx.stmt( - cx.expr_call( + cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_field") - ), + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_field"), ~[ cx.lit_str(span, @cx.str_of(field.ident)), cx.lit_uint(span, idx), @@ -746,13 +750,10 @@ fn mk_struct_ser_impl( }; // ast for `__s.emit_struct($(name), || $(fields))` - let ser_body = cx.expr_call( + let ser_body = cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_struct") - ), + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_struct"), ~[ cx.lit_str(span, @cx.str_of(ident)), cx.lit_uint(span, vec::len(fields)), @@ -788,13 +789,10 @@ fn mk_struct_deser_impl( ); // ast for `__d.read_field($(name), $(idx), $(expr_lambda))` - let expr: @ast::expr = cx.expr_call( + let expr: @ast::expr = cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_field") - ), + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_field"), ~[ cx.lit_str(span, @cx.str_of(field.ident)), cx.lit_uint(span, idx), @@ -813,13 +811,10 @@ fn mk_struct_deser_impl( }; // ast for `read_struct($(name), || $(fields))` - let body = cx.expr_call( + let body = cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_struct") - ), + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_struct"), ~[ cx.lit_str(span, @cx.str_of(ident)), cx.lit_uint(span, vec::len(fields)), @@ -943,13 +938,10 @@ fn ser_variant( // ast for `|| $(v).encode(__s)` let expr_encode = cx.lambda_expr( - cx.expr_call( + cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_path(span, ~[names[a_idx]]), - cx.ident_of(~"encode") - ), + cx.expr_path(span, ~[names[a_idx]]), + cx.ident_of(~"encode"), ~[cx.expr_var(span, ~"__s")] ) ); @@ -965,13 +957,10 @@ fn ser_variant( }; // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))` - let body = cx.expr_call( + let body = cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum_variant") - ), + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum_variant"), ~[ cx.lit_str(span, @cx.str_of(v_name)), cx.lit_uint(span, v_idx), @@ -1019,13 +1008,10 @@ fn mk_enum_ser_body( ); // ast for `__s.emit_enum($(name), || $(match_expr))` - cx.expr_call( + cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum") - ), + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum"), ~[ cx.lit_str(span, @cx.str_of(name)), cx.lambda_expr(match_expr), @@ -1055,13 +1041,10 @@ fn mk_enum_deser_variant_nary( ); // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))` - cx.expr_call( + cx.expr_method_call( span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum_variant_arg") - ), + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum_variant_arg"), ~[cx.lit_uint(span, idx), expr_lambda] ) }; @@ -1171,25 +1154,19 @@ fn mk_enum_deser_body( // ast for `__d.read_enum_variant($(expr_lambda))` let expr_lambda = ext_cx.lambda_expr( - ext_cx.expr_call( + ext_cx.expr_method_call( span, - ext_cx.expr_field( - span, - ext_cx.expr_var(span, ~"__d"), - ext_cx.ident_of(~"read_enum_variant") - ), + ext_cx.expr_var(span, ~"__d"), + ext_cx.ident_of(~"read_enum_variant"), ~[expr_lambda] ) ); // ast for `__d.read_enum($(e_name), $(expr_lambda))` - ext_cx.expr_call( + ext_cx.expr_method_call( span, - ext_cx.expr_field( - span, - ext_cx.expr_var(span, ~"__d"), - ext_cx.ident_of(~"read_enum") - ), + ext_cx.expr_var(span, ~"__d"), + ext_cx.ident_of(~"read_enum"), ~[ ext_cx.lit_str(span, @ext_cx.str_of(name)), expr_lambda diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index c2f4cbf3db2..ad71441e046 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -111,6 +111,13 @@ pub fn mk_addr_of(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { pub fn mk_mut_addr_of(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { return mk_expr(cx, sp, ast::expr_addr_of(ast::m_mutbl, e)); } +pub fn mk_method_call(cx: @ext_ctxt, + sp: span, + rcvr_expr: @ast::expr, + method_ident: ast::ident, + +args: ~[@ast::expr]) -> @ast::expr { + mk_expr(cx, sp, ast::expr_method_call(rcvr_expr, method_ident, ~[], args, ast::NoSugar)) +} pub fn mk_call_(cx: @ext_ctxt, sp: span, fn_expr: @ast::expr, +args: ~[@ast::expr]) -> @ast::expr { mk_expr(cx, sp, ast::expr_call(fn_expr, args, ast::NoSugar)) diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 4ab83cb5f1e..68458bd516e 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -120,8 +120,9 @@ fn call_substructure_clone_method(cx: @ext_ctxt, -> @expr { // Call the substructure method. let clone_ident = cx.ident_of(~"clone"); - let self_method = build::mk_access_(cx, span, self_field, clone_ident); - build::mk_call_(cx, span, self_method, ~[]) + build::mk_method_call(cx, span, + self_field, clone_ident, + ~[]) } fn expand_deriving_clone_struct_def(cx: @ext_ctxt, diff --git a/src/libsyntax/ext/deriving/eq.rs b/src/libsyntax/ext/deriving/eq.rs index 5e94134f70a..8cee6bd7290 100644 --- a/src/libsyntax/ext/deriving/eq.rs +++ b/src/libsyntax/ext/deriving/eq.rs @@ -147,11 +147,9 @@ fn call_substructure_eq_method(cx: @ext_ctxt, junction: Junction, chain_expr: &mut Option<@expr>) { // Call the substructure method. - let self_method = build::mk_access_(cx, span, self_field, method_ident); - let self_call = build::mk_call_(cx, - span, - self_method, - ~[ other_field_ref ]); + let self_call = build::mk_method_call(cx, span, + self_field, method_ident, + ~[ other_field_ref ]); // Connect to the outer expression if necessary. *chain_expr = match *chain_expr { diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 75d7b396c7e..3c1ee7e0296 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -125,14 +125,11 @@ fn call_substructure_iter_bytes_method(cx: @ext_ctxt, // Call the substructure method. let iter_bytes_ident = cx.ident_of(~"iter_bytes"); - let self_method = build::mk_access_(cx, - span, - self_field, - iter_bytes_ident); - let self_call = build::mk_call_(cx, - span, - self_method, - ~[ lsb0_expr, f_expr ]); + let self_call = build::mk_method_call(cx, + span, + self_field, + iter_bytes_ident, + ~[ lsb0_expr, f_expr ]); // Create a statement out of this expression. build::mk_stmt(cx, span, self_call) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 2cf52c47959..6044c3ad3d2 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -270,11 +270,11 @@ fn id_ext(cx: @ext_ctxt, +str: ~str) -> ast::ident { // Lift an ident to the expr that evaluates to that ident. fn mk_ident(cx: @ext_ctxt, sp: span, ident: ast::ident) -> @ast::expr { - let e_meth = build::mk_access(cx, sp, - ids_ext(cx, ~[~"ext_cx"]), - id_ext(cx, ~"ident_of")); let e_str = build::mk_uniq_str(cx, sp, cx.str_of(ident)); - build::mk_call_(cx, sp, e_meth, ~[e_str]) + build::mk_method_call(cx, sp, + build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])), + id_ext(cx, ~"ident_of"), + ~[e_str]) } fn mk_bytepos(cx: @ext_ctxt, sp: span, bpos: BytePos) -> @ast::expr { @@ -462,11 +462,10 @@ fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree) ids_ext(cx, ~[~"tt_tok"]), ~[e_sp, mk_token(cx, sp, *tok)]); let e_push = - build::mk_call_(cx, sp, - build::mk_access(cx, sp, - ids_ext(cx, ~[~"tt"]), - id_ext(cx, ~"push")), - ~[e_tok]); + build::mk_method_call(cx, sp, + build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])), + id_ext(cx, ~"push"), + ~[e_tok]); ~[build::mk_stmt(cx, sp, e_push)] } @@ -479,21 +478,17 @@ fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree) // tt.push_all_move($ident.to_tokens(ext_cx)) let e_to_toks = - build::mk_call_(cx, sp, - build::mk_access - (cx, sp, - ~[ident], - id_ext(cx, ~"to_tokens")), - ~[build::mk_path(cx, sp, - ids_ext(cx, ~[~"ext_cx"]))]); + build::mk_method_call(cx, sp, + build::mk_path(cx, sp, ~[ident]), + id_ext(cx, ~"to_tokens"), + ~[build::mk_path(cx, sp, + ids_ext(cx, ~[~"ext_cx"]))]); let e_push = - build::mk_call_(cx, sp, - build::mk_access - (cx, sp, - ids_ext(cx, ~[~"tt"]), - id_ext(cx, ~"push_all_move")), - ~[e_to_toks]); + build::mk_method_call(cx, sp, + build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])), + id_ext(cx, ~"push_all_move"), + ~[e_to_toks]); ~[build::mk_stmt(cx, sp, e_push)] } @@ -562,11 +557,10 @@ fn expand_tts(cx: @ext_ctxt, // of quotes, for example) but at this point it seems not likely to be // worth the hassle. - let e_sp = build::mk_call_(cx, sp, - build::mk_access(cx, sp, - ids_ext(cx, ~[~"ext_cx"]), - id_ext(cx, ~"call_site")), - ~[]); + let e_sp = build::mk_method_call(cx, sp, + build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])), + id_ext(cx, ~"call_site"), + ~[]); let stmt_let_sp = build::mk_local(cx, sp, false, id_ext(cx, ~"sp"), @@ -590,13 +584,13 @@ fn expand_parse_call(cx: @ext_ctxt, tts: &[ast::token_tree]) -> @ast::expr { let tts_expr = expand_tts(cx, sp, tts); - let cfg_call = || build::mk_call_( - cx, sp, build::mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]), - id_ext(cx, ~"cfg")), ~[]); + let cfg_call = || build::mk_method_call( + cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])), + id_ext(cx, ~"cfg"), ~[]); - let parse_sess_call = || build::mk_call_( - cx, sp, build::mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]), - id_ext(cx, ~"parse_sess")), ~[]); + let parse_sess_call = || build::mk_method_call( + cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])), + id_ext(cx, ~"parse_sess"), ~[]); let new_parser_call = build::mk_call_global(cx, sp, @@ -609,9 +603,9 @@ fn expand_parse_call(cx: @ext_ctxt, cfg_call(), tts_expr]); - build::mk_call_(cx, sp, - build::mk_access_(cx, sp, new_parser_call, - id_ext(cx, parse_method)), - arg_exprs) + build::mk_method_call(cx, sp, + new_parser_call, + id_ext(cx, parse_method), + arg_exprs) }