diff options
| author | Patrick Walton <[email protected]> | 2011-05-09 14:00:02 -0700 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-05-09 14:00:50 -0700 |
| commit | 70c759030ccf27222a04f918e235bc9dbcf88c94 (patch) | |
| tree | e8e0439b47606fe6500df7e9c3e455c4ef35a82c | |
| parent | Alias-ify a variety of fn signatures in ty. Cuts 180kb off rustc. (diff) | |
| download | rust-70c759030ccf27222a04f918e235bc9dbcf88c94.tar.xz rust-70c759030ccf27222a04f918e235bc9dbcf88c94.zip | |
rustc: Alias fix part 2 -- Check that the aliasness of function parameters matches. Add a test case.
| -rw-r--r-- | src/comp/middle/ty.rs | 15 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/aliasness-mismatch.rs | 15 |
3 files changed, 26 insertions, 10 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 9e90d125..4a630af1 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2098,14 +2098,17 @@ mod Unify { auto expected_input = expected_inputs.(i); auto actual_input = actual_inputs.(i); - // This should be safe, I think? - // FIXME: It's not. At all. + // Unify the result modes. "mo_either" unifies with both modes. auto result_mode; - if (expected_input.mode == mo_alias || - actual_input.mode == mo_alias) { - result_mode = mo_alias; + if (expected_input.mode == mo_either) { + result_mode = actual_input.mode; + } else if (actual_input.mode == mo_either) { + result_mode = expected_input.mode; + } else if (expected_input.mode != actual_input.mode) { + ret fn_common_res_err(ures_err(terr_arg_count, + expected, actual)); } else { - result_mode = mo_val; + result_mode = expected_input.mode; } auto result = unify_step(cx, actual_input.ty, expected_input.ty); diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index aeb5f8a2..cdee187d 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1766,17 +1766,15 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { auto a_0 = check_expr(fcx, a); args_0 += vec(some[@ast.expr](a_0)); - // FIXME: this breaks aliases. We need a ty_fn_arg. - auto arg_ty = rec(mode=mo_val, + auto arg_ty = rec(mode=mo_either, ty=expr_ty(fcx.ccx.tcx, a_0)); Vec.push[arg](arg_tys_0, arg_ty); } case (none[@ast.expr]) { args_0 += vec(none[@ast.expr]); - // FIXME: breaks aliases too? auto typ = next_ty_var(fcx.ccx); - Vec.push[arg](arg_tys_0, rec(mode=mo_val, ty=typ)); + Vec.push[arg](arg_tys_0, rec(mode=mo_either, ty=typ)); } } } diff --git a/src/test/compile-fail/aliasness-mismatch.rs b/src/test/compile-fail/aliasness-mismatch.rs new file mode 100644 index 00000000..88b7d938 --- /dev/null +++ b/src/test/compile-fail/aliasness-mismatch.rs @@ -0,0 +1,15 @@ +// -*- rust -*- +// xfail-stage0 + +// error-pattern: mismatched types + +fn f(&int x) { log_err x; } +fn h(int x) { log_err x; } +fn main() { + let fn(int x) g = f; + g(10); + g = h; + g(10); +} + + |