]> git.lizzy.rs Git - rust.git/commitdiff
Add type argument field to expr_path
authorMarijn Haverbeke <marijnh@gmail.com>
Mon, 19 Dec 2011 09:21:31 +0000 (10:21 +0100)
committerMarijn Haverbeke <marijnh@gmail.com>
Mon, 19 Dec 2011 09:43:23 +0000 (10:43 +0100)
This way, you can explicitly provide type parameters when calling a
generic method.

Issue #1227

13 files changed:
src/comp/middle/mut.rs
src/comp/middle/resolve.rs
src/comp/middle/trans.rs
src/comp/middle/tstate/pre_post_conditions.rs
src/comp/middle/tstate/states.rs
src/comp/middle/ty.rs
src/comp/middle/typeck.rs
src/comp/syntax/ast.rs
src/comp/syntax/fold.rs
src/comp/syntax/parse/parser.rs
src/comp/syntax/print/pprust.rs
src/comp/syntax/visit.rs
src/test/run-pass/static-impl.rs

index d3856f4bd2d2c23daa160033e8a39c766ad791c9..d9b78d27cfbbb7d3185b39332bd953ceae7c4e02 100644 (file)
@@ -47,7 +47,7 @@ fn maybe_auto_unbox(tcx: ty::ctxt, t: ty::t) -> {t: ty::t, ds: [deref]} {
     let ds: [deref] = [], ex = ex;
     while true {
         alt copy ex.node {
-          expr_field(base, ident) {
+          expr_field(base, ident, _) {
             let auto_unbox = maybe_auto_unbox(tcx, ty::expr_ty(tcx, base));
             let is_mut = false;
             alt ty::struct(tcx, auto_unbox.t) {
index c00bd711eb0e1a1e583950563dc81ead5c55209f..fa0e67fa22ae43dfcf7e9d221235906214a30a48 100644 (file)
@@ -1771,7 +1771,7 @@ fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, sc: iscopes,
 
 fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) {
     alt x.node {
-      ast::expr_field(_, _) { e.impl_map.insert(x.id, sc); }
+      ast::expr_field(_, _, _) { e.impl_map.insert(x.id, sc); }
       _ {}
     }
     visit::visit_expr(x, sc, v);
index 8a37d27d973c9e40f46294267a5d084334c48bc9..f9237199ba16675ce249b78243e8675c3f4e65c5 100644 (file)
@@ -2858,7 +2858,7 @@ fn trans_method_callee(bcx: @block_ctxt, e: @ast::expr, base: @ast::expr,
 fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
     alt e.node {
       ast::expr_path(p) { ret trans_path(bcx, p, e.id); }
-      ast::expr_field(base, ident) {
+      ast::expr_field(base, ident, _) {
         // Lval means this is a record field, so not a method
         if !expr_is_lval(bcx, e) {
             alt bcx_ccx(bcx).method_map.find(e.id) {
@@ -2889,7 +2889,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
         let v = trans_path(cx, p, e.id);
         ret lval_maybe_callee_to_lval(v, ty::expr_ty(bcx_tcx(cx), e));
       }
-      ast::expr_field(base, ident) {
+      ast::expr_field(base, ident, _) {
         ret trans_rec_field(cx, base, ident);
       }
       ast::expr_index(base, idx) {
@@ -3580,7 +3580,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
       ast::expr_call(f, args, _) {
         ret trans_call(bcx, f, args, e.id, dest);
       }
-      ast::expr_field(_, _) {
+      ast::expr_field(_, _, _) {
         fail "Taking the value of a method does not work yet (issue #435)";
       }
 
index d341e90f8166ac4ad4ef93190d498b821ca6f894..33ab3da4f39e02adb36098c05f6a8012b460a398 100644 (file)
@@ -476,7 +476,7 @@ fn combine_pp(antec: pre_and_post, fcx: fn_ctxt, &&pp: pre_and_post,
         set_pre_and_post(fcx.ccx, e.id, alts_overall_pp.precondition,
                          alts_overall_pp.postcondition);
       }
-      expr_field(operator, _) {
+      expr_field(operator, _, _) {
         find_pre_post_expr(fcx, operator);
         copy_pre_post(fcx.ccx, e.id, operator);
       }
index db020ec1bb07a23926c94e3af5e503e7394994b3..701ac5e04b01419d838001a64531f5b0dee663c1 100644 (file)
@@ -551,7 +551,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
         }
         ret changed | set_poststate_ann(fcx.ccx, e.id, a_post);
       }
-      expr_field(val, _) {
+      expr_field(val, _, _) {
         ret find_pre_post_state_sub(fcx, pres, val, e.id, none);
       }
       expr_unary(_, operand) {
index 521b73f3c11d2845edb5482af64c3e48f0b2ee66..bf317b3b59007ff7113d6febc18c8587a06461da 100644 (file)
@@ -1678,7 +1678,7 @@ fn expr_is_lval(method_map: typeck::method_map, tcx: ty::ctxt,
     alt e.node {
       ast::expr_path(_) | ast::expr_index(_, _) |
       ast::expr_unary(ast::deref., _) { true }
-      ast::expr_field(base, ident) {
+      ast::expr_field(base, ident, _) {
         method_map.contains_key(e.id) ? false : {
             let basety = type_autoderef(tcx, expr_ty(tcx, base));
             alt struct(tcx, basety) {
index 0dbd052241f054fd7e30a94b6f28040fbb290386..4beb93d0bfabddde95f66bf5de82bc520c6829fc 100644 (file)
@@ -2132,15 +2132,20 @@ fn get_node(f: spanned<field>) -> field { f.node }
           }
         }
       }
-      ast::expr_field(base, field) {
+      ast::expr_field(base, field, tys) {
         bot |= check_expr(fcx, base);
         let expr_t = expr_ty(tcx, base);
         let base_t = do_autoderef(fcx, expr.span, expr_t);
-        let handled = false;
+        let handled = false, n_tys = vec::len(tys);
         alt structure_of(fcx, expr.span, base_t) {
           ty::ty_rec(fields) {
             alt ty::field_idx(field, fields) {
               some(ix) {
+                if n_tys > 0u {
+                    tcx.sess.span_err(expr.span,
+                                      "can't provide type parameters \
+                                       to a field access");
+                }
                 write::ty_only_fixup(fcx, id, fields[ix].mt.ty);
                 handled = true;
               }
@@ -2150,6 +2155,11 @@ fn get_node(f: spanned<field>) -> field { f.node }
           ty::ty_obj(methods) {
             alt ty::method_idx(field, methods) {
               some(ix) {
+                if n_tys > 0u {
+                    tcx.sess.span_err(expr.span,
+                                      "can't provide type parameters \
+                                       to an obj method");
+                }
                 let meth = methods[ix];
                 let t = ty::mk_fn(tcx, meth.proto, meth.inputs,
                                   meth.output, meth.cf, meth.constrs);
@@ -2181,6 +2191,25 @@ fn get_node(f: spanned<field>) -> field { f.node }
                                                 fty, method.n_tps);
                     ids += b.ids;
                     fty = b.ty;
+                    if n_tys > 0u {
+                        if n_tys != method.n_tps {
+                            tcx.sess.span_fatal
+                                (expr.span, "incorrect number of type \
+                                           parameters given for this method");
+
+                        }
+                        let i = 0u;
+                        for ty in tys {
+                            let tvar = ty::mk_var(fcx.ccx.tcx, b.ids[i]);
+                            let t_subst = ast_ty_to_ty_crate(fcx.ccx, ty);
+                            demand::simple(fcx, expr.span, tvar, t_subst);
+                            i += 1u;
+                        }
+                    }
+                } else if n_tys > 0u {
+                    tcx.sess.span_fatal(expr.span,
+                                        "this method does not take type \
+                                         parameters");
                 }
                 let substs = vec::map(ids, {|id| ty::mk_var(tcx, id)});
                 write::ty_fixup(fcx, id, {substs: some(substs), ty: fty});
index b7af23e9dd5c1de1e23f24022ffe9a9f8ab8d3e7..0b3a03c6b1acd99f36aebe9c8be3f603224c61f9 100644 (file)
@@ -238,7 +238,7 @@ fn proto_kind(p: proto) -> kind {
     expr_assign(@expr, @expr);
     expr_swap(@expr, @expr);
     expr_assign_op(binop, @expr, @expr);
-    expr_field(@expr, ident);
+    expr_field(@expr, ident, [@ty]);
     expr_index(@expr, @expr);
     expr_path(@path);
     expr_fail(option::t<@expr>);
index 5f4ebbf3da3d83108a2ef1143a8f4ef832f972d3..e55326dbdcead1a82869d3cef3f55a19c3f1525e 100644 (file)
@@ -401,8 +401,9 @@ fn fold_anon_obj_field_(aof: anon_obj_field, fld: ast_fold) ->
           expr_assign_op(op, el, er) {
             expr_assign_op(op, fld.fold_expr(el), fld.fold_expr(er))
           }
-          expr_field(el, id) {
-            expr_field(fld.fold_expr(el), fld.fold_ident(id))
+          expr_field(el, id, tys) {
+            expr_field(fld.fold_expr(el), fld.fold_ident(id),
+                       vec::map(tys, fld.fold_ty))
           }
           expr_index(el, er) {
             expr_index(fld.fold_expr(el), fld.fold_expr(er))
index 752a433e9536070afebaa8342713681cb0582631..f1db62e24e2001451bd3cdd72dad7cd0a97bfab7 100644 (file)
@@ -1025,7 +1025,12 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
               token::IDENT(i, _) {
                 hi = p.get_hi_pos();
                 p.bump();
-                e = mk_expr(p, lo, hi, ast::expr_field(e, p.get_str(i)));
+                let tys = if eat(p, token::MOD_SEP) {
+                    expect(p, token::LT);
+                    parse_seq_to_gt(some(token::COMMA),
+                                    {|p| parse_ty(p, false)}, p)
+                } else { [] };
+                e = mk_expr(p, lo, hi, ast::expr_field(e, p.get_str(i), tys));
               }
               t { unexpected(p, t); }
             }
index 9b3d047d43575f9b793501c04c9495d078865b24..92a5d228c26e0ddf5b2b8a5d096e526899e89b5c 100644 (file)
@@ -879,7 +879,7 @@ fn print_opt(s: ps, expr: option::t<@ast::expr>) {
         word_space(s, "=");
         print_expr(s, rhs);
       }
-      ast::expr_field(expr, id) {
+      ast::expr_field(expr, id, tys) {
         // Deal with '10.x'
         if ends_in_lit_int(expr) {
             popen(s); print_expr(s, expr); pclose(s);
@@ -888,6 +888,11 @@ fn print_opt(s: ps, expr: option::t<@ast::expr>) {
         }
         word(s.s, ".");
         word(s.s, id);
+        if vec::len(tys) > 0u {
+            word(s.s, "::<");
+            commasep(s, inconsistent, tys, print_type);
+            word(s.s, ">");
+        }
       }
       ast::expr_index(expr, index) {
         print_expr_parens_if_not_bot(s, expr);
index a1feec5bec9144a036859060142d4947f11a1a04..7ca54272edf3b280a9f26b6aef0f4b21a1bb4ed8 100644 (file)
@@ -295,7 +295,10 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         v.visit_expr(b, e, v);
         v.visit_expr(a, e, v);
       }
-      expr_field(x, _) { v.visit_expr(x, e, v); }
+      expr_field(x, _, tys) {
+        v.visit_expr(x, e, v);
+        for tp in tys { v.visit_ty(tp, e, v); }
+      }
       expr_index(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
       expr_path(p) { visit_path(p, e, v); }
       expr_fail(eo) { visit_expr_opt(eo, e, v); }
index 9d245a22bb7a7c5c1908cadc67c4e57d75f6d39b..8f9acab6128d05454a788f1978f6015c1fe081bf 100644 (file)
@@ -35,6 +35,7 @@ impl foo for int { fn plus() -> int { self + 10 } }
 
     assert [1].len().str() == "1";
     assert [3, 4].map({|a| a + 4})[0] == 7;
+    assert [3, 4].map::<uint>({|a| a as uint + 4u})[0] == 7u;
     let x = 0u;
     10u.times {|_n| x += 2u;}
     assert x == 20u;