Make "no implicit copies" diagnostics controllable through lint settings. Closes #2503.
This commit is contained in:
parent
6396e2c3c3
commit
e86214830a
2 changed files with 27 additions and 17 deletions
|
|
@ -9,7 +9,7 @@ import util::ppaux::{ty_to_str, tys_to_str};
|
|||
import syntax::print::pprust::expr_to_str;
|
||||
import freevars::freevar_entry;
|
||||
import dvec::extensions;
|
||||
import lint::non_implicitly_copyable_typarams;
|
||||
import lint::{non_implicitly_copyable_typarams,implicit_copies};
|
||||
|
||||
// Kind analysis pass.
|
||||
//
|
||||
|
|
@ -83,21 +83,22 @@ fn check_crate(tcx: ty::ctxt,
|
|||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
type check_fn = fn@(ctx, option<@freevar_entry>, bool, ty::t, sp: span);
|
||||
type check_fn = fn@(ctx, node_id, option<@freevar_entry>,
|
||||
bool, ty::t, sp: span);
|
||||
|
||||
// Yields the appropriate function to check the kind of closed over
|
||||
// variables. `id` is the node_id for some expression that creates the
|
||||
// closure.
|
||||
fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
|
||||
fn check_for_uniq(cx: ctx, fv: option<@freevar_entry>, is_move: bool,
|
||||
var_t: ty::t, sp: span) {
|
||||
fn check_for_uniq(cx: ctx, id: node_id, fv: option<@freevar_entry>,
|
||||
is_move: bool, var_t: ty::t, sp: span) {
|
||||
// all captured data must be sendable, regardless of whether it is
|
||||
// moved in or copied in
|
||||
check_send(cx, var_t, sp);
|
||||
|
||||
// copied in data must be copyable, but moved in data can be anything
|
||||
let is_implicit = fv.is_some();
|
||||
if !is_move { check_copy(cx, var_t, sp, is_implicit); }
|
||||
if !is_move { check_copy(cx, id, var_t, sp, is_implicit); }
|
||||
|
||||
// check that only immutable variables are implicitly copied in
|
||||
for fv.each { |fv|
|
||||
|
|
@ -105,11 +106,11 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_for_box(cx: ctx, fv: option<@freevar_entry>, is_move: bool,
|
||||
var_t: ty::t, sp: span) {
|
||||
fn check_for_box(cx: ctx, id: node_id, fv: option<@freevar_entry>,
|
||||
is_move: bool, var_t: ty::t, sp: span) {
|
||||
// copied in data must be copyable, but moved in data can be anything
|
||||
let is_implicit = fv.is_some();
|
||||
if !is_move { check_copy(cx, var_t, sp, is_implicit); }
|
||||
if !is_move { check_copy(cx, id, var_t, sp, is_implicit); }
|
||||
|
||||
// check that only immutable variables are implicitly copied in
|
||||
for fv.each { |fv|
|
||||
|
|
@ -117,8 +118,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_for_block(cx: ctx, fv: option<@freevar_entry>, _is_move: bool,
|
||||
_var_t: ty::t, sp: span) {
|
||||
fn check_for_block(cx: ctx, _id: node_id, fv: option<@freevar_entry>,
|
||||
_is_move: bool, _var_t: ty::t, sp: span) {
|
||||
// only restriction: no capture clauses (we would have to take
|
||||
// ownership of the moved/copied in data).
|
||||
if fv.is_none() {
|
||||
|
|
@ -128,8 +129,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_for_bare(cx: ctx, _fv: option<@freevar_entry>, _is_move: bool,
|
||||
_var_t: ty::t, sp: span) {
|
||||
fn check_for_bare(cx: ctx, _id: node_id, _fv: option<@freevar_entry>,
|
||||
_is_move: bool,_var_t: ty::t, sp: span) {
|
||||
cx.tcx.sess.span_err(sp, "attempted dynamic environment capture");
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +166,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
|
|||
let cap_def = cx.tcx.def_map.get(cap_item.id);
|
||||
let cap_def_id = ast_util::def_id_of_def(cap_def).node;
|
||||
let ty = ty::node_id_to_type(cx.tcx, cap_def_id);
|
||||
chk(cx, none, cap_item.is_move, ty, cap_item.span);
|
||||
chk(cx, fn_id, none, cap_item.is_move, ty, cap_item.span);
|
||||
cap_def_id
|
||||
};
|
||||
|
||||
|
|
@ -187,7 +188,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
|
|||
};
|
||||
|
||||
let ty = ty::node_id_to_type(cx.tcx, id);
|
||||
chk(cx, some(fv), is_move, ty, fv.span);
|
||||
chk(cx, fn_id, some(fv), is_move, ty, fv.span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +378,7 @@ fn check_copy_ex(cx: ctx, ex: @expr, implicit_copy: bool) {
|
|||
!cx.last_use_map.contains_key(ex.id) &&
|
||||
!is_nullary_variant(cx, ex) {
|
||||
let ty = ty::expr_ty(cx.tcx, ex);
|
||||
check_copy(cx, ty, ex.span, implicit_copy);
|
||||
check_copy(cx, ex.id, ty, ex.span, implicit_copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -410,12 +411,14 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_copy(cx: ctx, ty: ty::t, sp: span, implicit_copy: bool) {
|
||||
fn check_copy(cx: ctx, id: node_id, ty: ty::t, sp: span,
|
||||
implicit_copy: bool) {
|
||||
let k = ty::type_kind(cx.tcx, ty);
|
||||
if !ty::kind_can_be_copied(k) {
|
||||
cx.tcx.sess.span_err(sp, "copying a noncopyable value");
|
||||
} else if implicit_copy && !ty::kind_can_be_implicitly_copied(k) {
|
||||
cx.tcx.sess.span_warn(
|
||||
cx.tcx.sess.span_lint(
|
||||
implicit_copies, id, cx.current_item,
|
||||
sp,
|
||||
"implicitly copying a non-implicitly-copyable value");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ enum lint {
|
|||
unrecognized_warning,
|
||||
non_implicitly_copyable_typarams,
|
||||
vecs_not_implicitly_copyable,
|
||||
implicit_copies,
|
||||
}
|
||||
|
||||
// This is pretty unfortunate. We really want some sort of "deriving Enum"
|
||||
|
|
@ -60,6 +61,7 @@ fn int_to_lint(i: int) -> lint {
|
|||
5 { unrecognized_warning }
|
||||
6 { non_implicitly_copyable_typarams }
|
||||
7 { vecs_not_implicitly_copyable }
|
||||
8 { implicit_copies }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +120,11 @@ fn get_lint_dict() -> lint_dict {
|
|||
@{lint: vecs_not_implicitly_copyable,
|
||||
desc: "make vecs and strs not implicitly copyable\
|
||||
('err' is ignored; only checked at top level",
|
||||
default: warn}),
|
||||
|
||||
("implicit_copies",
|
||||
@{lint: implicit_copies,
|
||||
desc: "implicit copies of non implicitly copyable data",
|
||||
default: warn})
|
||||
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue