diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 2f115b8e836e..e18e5c2c63ea 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -193,7 +193,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t { } -// Returns the one-level-deep structure of the given type. +// Returns the one-level-deep structure of the given type.f fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty { ret ty::struct(fcx.ccx.tcx, structurally_resolved_type(fcx, sp, typ)); } @@ -1530,7 +1530,7 @@ fn require_unsafe(sess: session::session, f_purity: ast::purity, sp: span) { _ { sess.span_fatal( sp, - "Found unsafe expression in safe function decl"); + "unsafe operation requires unsafe function or block"); } } } @@ -1591,6 +1591,23 @@ fn check_expr_with(fcx: @fn_ctxt, expr: @ast::expr, expected: ty::t) -> bool { ret check_expr_with_unifier(fcx, expr, demand::simple, expected); } +fn check_for_unsafe_assignments(fcx: @fn_ctxt, lhs: @ast::expr) { + alt lhs.node { + ast::expr_unary(ast::deref., ptr) { + let ty = expr_ty(fcx.ccx.tcx, ptr); + let sty = structure_of(fcx, ptr.span, ty); + alt sty { + ty::ty_ptr(_) { + require_unsafe(fcx.ccx.tcx.sess, fcx.purity, lhs.span); + } + _ {} + } + } + _ { + } + } +} + fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, expected: ty::t) -> bool { //log_err "typechecking expr " + syntax::print::pprust::expr_to_str(expr); @@ -1702,6 +1719,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, rhs: @ast::expr, id: ast::node_id) -> bool { let t = next_ty_var(fcx); let bot = check_expr_with(fcx, lhs, t) | check_expr_with(fcx, rhs, t); + check_for_unsafe_assignments(fcx, lhs); write::ty_only_fixup(fcx, id, ty::mk_nil(fcx.ccx.tcx)); ret bot; } diff --git a/src/test/compile-fail/unsafe-fn-deref-ptr.rs b/src/test/compile-fail/unsafe-fn-deref-ptr.rs new file mode 100644 index 000000000000..cf5dac3ff89f --- /dev/null +++ b/src/test/compile-fail/unsafe-fn-deref-ptr.rs @@ -0,0 +1,11 @@ +// -*- rust -*- +// error-pattern: unsafe operation requires unsafe function or block + +fn f(p: *u8) { + *p = 0u8; + ret; +} + +fn main() { + f(); +}