@@ -9,7 +9,7 @@ import util::ppaux::{ty_to_str, tys_to_str};
9
9
import syntax:: print:: pprust:: expr_to_str;
10
10
import freevars:: freevar_entry;
11
11
import dvec:: extensions;
12
- import lint:: non_implicitly_copyable_typarams;
12
+ import lint:: { non_implicitly_copyable_typarams, implicit_copies } ;
13
13
14
14
// Kind analysis pass.
15
15
//
@@ -83,42 +83,43 @@ fn check_crate(tcx: ty::ctxt,
83
83
tcx. sess . abort_if_errors ( ) ;
84
84
}
85
85
86
- type check_fn = fn @( ctx , option < @freevar_entry > , bool , ty:: t , sp : span ) ;
86
+ type check_fn = fn @( ctx , node_id , option < @freevar_entry > ,
87
+ bool , ty:: t , sp : span ) ;
87
88
88
89
// Yields the appropriate function to check the kind of closed over
89
90
// variables. `id` is the node_id for some expression that creates the
90
91
// closure.
91
92
fn with_appropriate_checker ( cx : ctx , id : node_id , b : fn ( check_fn ) ) {
92
- fn check_for_uniq ( cx : ctx , fv : option < @freevar_entry > , is_move : bool ,
93
- var_t : ty:: t , sp : span ) {
93
+ fn check_for_uniq ( cx : ctx , id : node_id , fv : option < @freevar_entry > ,
94
+ is_move : bool , var_t : ty:: t , sp : span ) {
94
95
// all captured data must be sendable, regardless of whether it is
95
96
// moved in or copied in
96
97
check_send ( cx, var_t, sp) ;
97
98
98
99
// copied in data must be copyable, but moved in data can be anything
99
100
let is_implicit = fv. is_some ( ) ;
100
- if !is_move { check_copy ( cx, var_t, sp, is_implicit) ; }
101
+ if !is_move { check_copy ( cx, id , var_t, sp, is_implicit) ; }
101
102
102
103
// check that only immutable variables are implicitly copied in
103
104
for fv. each { |fv|
104
105
check_imm_free_var( cx, fv. def, fv. span) ;
105
106
}
106
107
}
107
108
108
- fn check_for_box ( cx : ctx , fv : option < @freevar_entry > , is_move : bool ,
109
- var_t : ty:: t , sp : span ) {
109
+ fn check_for_box ( cx : ctx , id : node_id , fv : option < @freevar_entry > ,
110
+ is_move : bool , var_t : ty:: t , sp : span ) {
110
111
// copied in data must be copyable, but moved in data can be anything
111
112
let is_implicit = fv. is_some ( ) ;
112
- if !is_move { check_copy ( cx, var_t, sp, is_implicit) ; }
113
+ if !is_move { check_copy ( cx, id , var_t, sp, is_implicit) ; }
113
114
114
115
// check that only immutable variables are implicitly copied in
115
116
for fv. each { |fv|
116
117
check_imm_free_var( cx, fv. def, fv. span) ;
117
118
}
118
119
}
119
120
120
- fn check_for_block ( cx : ctx , fv : option < @freevar_entry > , _is_move : bool ,
121
- _var_t : ty:: t , sp : span ) {
121
+ fn check_for_block ( cx : ctx , _id : node_id , fv : option < @freevar_entry > ,
122
+ _is_move : bool , _var_t : ty:: t , sp : span ) {
122
123
// only restriction: no capture clauses (we would have to take
123
124
// ownership of the moved/copied in data).
124
125
if fv. is_none ( ) {
@@ -128,8 +129,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id, b: fn(check_fn)) {
128
129
}
129
130
}
130
131
131
- fn check_for_bare ( cx : ctx , _fv : option < @freevar_entry > , _is_move : bool ,
132
- _var_t : ty:: t , sp : span ) {
132
+ fn check_for_bare ( cx : ctx , _id : node_id , _fv : option < @freevar_entry > ,
133
+ _is_move : bool , _var_t : ty:: t , sp : span ) {
133
134
cx. tcx . sess . span_err ( sp, "attempted dynamic environment capture" ) ;
134
135
}
135
136
@@ -165,7 +166,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
165
166
let cap_def = cx. tcx . def_map . get ( cap_item. id ) ;
166
167
let cap_def_id = ast_util:: def_id_of_def ( cap_def) . node ;
167
168
let ty = ty:: node_id_to_type ( cx. tcx , cap_def_id) ;
168
- chk ( cx, none, cap_item. is_move , ty, cap_item. span ) ;
169
+ chk ( cx, fn_id , none, cap_item. is_move , ty, cap_item. span ) ;
169
170
cap_def_id
170
171
} ;
171
172
@@ -187,7 +188,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
187
188
} ;
188
189
189
190
let ty = ty:: node_id_to_type ( cx. tcx , id) ;
190
- chk ( cx, some ( fv) , is_move, ty, fv. span ) ;
191
+ chk ( cx, fn_id , some ( fv) , is_move, ty, fv. span ) ;
191
192
}
192
193
}
193
194
@@ -377,7 +378,7 @@ fn check_copy_ex(cx: ctx, ex: @expr, implicit_copy: bool) {
377
378
!cx. last_use_map. contains_key( ex. id) &&
378
379
!is_nullary_variant( cx, ex) {
379
380
let ty = ty:: expr_ty( cx. tcx, ex) ;
380
- check_copy( cx, ty, ex. span, implicit_copy) ;
381
+ check_copy( cx, ex . id , ty, ex. span, implicit_copy) ;
381
382
}
382
383
}
383
384
@@ -410,12 +411,14 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
410
411
}
411
412
}
412
413
413
- fn check_copy( cx: ctx, ty: ty:: t, sp: span, implicit_copy: bool ) {
414
+ fn check_copy( cx: ctx, id: node_id, ty: ty:: t, sp: span,
415
+ implicit_copy: bool ) {
414
416
let k = ty:: type_kind( cx. tcx, ty) ;
415
417
if !ty:: kind_can_be_copied( k) {
416
418
cx. tcx. sess. span_err( sp, "copying a noncopyable value" ) ;
417
419
} else if implicit_copy && !ty:: kind_can_be_implicitly_copied( k) {
418
- cx. tcx. sess. span_warn(
420
+ cx. tcx. sess. span_lint(
421
+ implicit_copies, id, cx. current_item,
419
422
sp,
420
423
"implicitly copying a non-implicitly-copyable value" ) ;
421
424
}
0 commit comments