@@ -15,7 +15,6 @@ use middle::freevars;
15
15
use middle:: lint:: { non_implicitly_copyable_typarams, implicit_copies} ;
16
16
use middle:: liveness;
17
17
use middle:: pat_util;
18
- use middle:: ty:: { Kind , kind_copyable, kind_noncopyable, kind_const} ;
19
18
use middle:: ty;
20
19
use middle:: typeck;
21
20
use middle;
@@ -61,26 +60,6 @@ use syntax::{visit, ast_util};
61
60
62
61
pub const try_adding: & str = "Try adding a move" ;
63
62
64
- pub fn kind_to_str ( k : Kind ) -> ~str {
65
- let mut kinds = ~[ ] ;
66
-
67
- if ty:: kind_lteq ( kind_const ( ) , k) {
68
- kinds. push ( ~"const ") ;
69
- }
70
-
71
- if ty:: kind_can_be_copied ( k) {
72
- kinds. push ( ~"copy") ;
73
- }
74
-
75
- if ty:: kind_can_be_sent ( k) {
76
- kinds. push ( ~"owned") ;
77
- } else if ty:: kind_is_durable ( k) {
78
- kinds. push ( ~"& static ") ;
79
- }
80
-
81
- str:: connect ( kinds, ~" ")
82
- }
83
-
84
63
pub type rval_map = HashMap < node_id , ( ) > ;
85
64
86
65
pub type ctx = {
@@ -119,11 +98,11 @@ type check_fn = fn@(ctx, @freevar_entry);
119
98
// closure.
120
99
fn with_appropriate_checker ( cx : ctx , id : node_id , b : fn ( check_fn ) ) {
121
100
fn check_for_uniq ( cx : ctx , fv : @freevar_entry ) {
122
- // all captured data must be sendable , regardless of whether it is
123
- // moved in or copied in. Note that send implies owned.
101
+ // all captured data must be owned , regardless of whether it is
102
+ // moved in or copied in.
124
103
let id = ast_util:: def_id_of_def ( fv. def ) . node ;
125
104
let var_t = ty:: node_id_to_type ( cx. tcx , id) ;
126
- if !check_send (cx, var_t, fv.span) { return; }
105
+ if !check_owned ( cx, var_t, fv. span ) { return ; }
127
106
128
107
// check that only immutable variables are implicitly copied in
129
108
check_imm_free_var ( cx, fv. def , fv. span ) ;
@@ -281,30 +260,54 @@ fn check_ty(aty: @Ty, cx: ctx, v: visit::vt<ctx>) {
281
260
visit:: visit_ty ( aty, cx, v) ;
282
261
}
283
262
284
- pub fn check_bounds( cx : ctx , id : node_id , sp : span ,
285
- ty : ty:: t , bounds : ty:: param_bounds ) {
286
- let kind = ty:: type_kind ( cx. tcx , ty) ;
287
- let p_kind = ty:: param_bounds_to_kind ( bounds) ;
288
- if !ty:: kind_lteq ( p_kind, kind) {
289
- // If the only reason the kind check fails is because the
290
- // argument type isn't implicitly copyable, consult the warning
291
- // settings to figure out what to do.
292
- let implicit = ty:: kind_implicitly_copyable ( ) - ty:: kind_copyable ( ) ;
293
- if ty:: kind_lteq ( p_kind, kind | implicit) {
294
- cx. tcx . sess . span_lint (
295
- non_implicitly_copyable_typarams,
296
- id, cx. current_item , sp,
297
- ~"instantiating copy type parameter with a \
298
- not implicitly copyable type") ;
299
- } else {
300
- cx. tcx . sess . span_err (
301
- sp,
302
- ~"instantiating a type parameter with an incompatible type " +
303
- ~" ( needs `" + kind_to_str ( p_kind) +
304
- ~"`, got `" + kind_to_str ( kind) +
305
- ~"`, missing `" + kind_to_str ( p_kind - kind) + ~"`) ") ;
263
+ pub fn check_bounds ( cx : ctx ,
264
+ _type_parameter_id : node_id ,
265
+ sp : span ,
266
+ ty : ty:: t ,
267
+ bounds : ty:: param_bounds )
268
+ {
269
+ let kind = ty:: type_contents ( cx. tcx , ty) ;
270
+ let mut missing = ~[ ] ;
271
+ for bounds. each |bound| {
272
+ match * bound {
273
+ ty:: bound_trait( _) => {
274
+ /* Not our job, checking in typeck */
275
+ }
276
+
277
+ ty:: bound_copy => {
278
+ if !kind. is_copy ( cx. tcx ) {
279
+ missing. push ( "Copy" ) ;
280
+ }
281
+ }
282
+
283
+ ty:: bound_durable => {
284
+ if !kind. is_durable ( cx. tcx ) {
285
+ missing. push ( "&static" ) ;
286
+ }
287
+ }
288
+
289
+ ty:: bound_owned => {
290
+ if !kind. is_owned ( cx. tcx ) {
291
+ missing. push ( "Owned" ) ;
292
+ }
293
+ }
294
+
295
+ ty:: bound_const => {
296
+ if !kind. is_const ( cx. tcx ) {
297
+ missing. push ( "Const" ) ;
298
+ }
299
+ }
306
300
}
307
301
}
302
+
303
+ if !missing. is_empty ( ) {
304
+ cx. tcx . sess . span_err (
305
+ sp,
306
+ fmt ! ( "instantiating a type parameter with an incompatible type \
307
+ `%s`, which does not fulfill `%s`",
308
+ ty_to_str( cx. tcx, ty) ,
309
+ str :: connect_slices( missing, " " ) ) ) ;
310
+ }
308
311
}
309
312
310
313
fn is_nullary_variant ( cx : ctx , ex: @expr) -> bool {
@@ -342,16 +345,22 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
342
345
}
343
346
344
347
fn check_copy ( cx : ctx , ty : ty:: t , sp : span , reason : & str ) {
345
- let k = ty:: type_kind ( cx. tcx , ty) ;
346
- if !ty:: kind_can_be_copied ( k) {
347
- cx. tcx . sess . span_err ( sp, ~"copying a noncopyable value") ;
348
+ debug ! ( "type_contents(%s)=%s" ,
349
+ ty_to_str( cx. tcx, ty) ,
350
+ ty:: type_contents( cx. tcx, ty) . to_str( ) ) ;
351
+ if !ty:: type_is_copyable ( cx. tcx , ty) {
352
+ cx. tcx . sess . span_err (
353
+ sp, fmt ! ( "copying a value of non-copyable type `%s`" ,
354
+ ty_to_str( cx. tcx, ty) ) ) ;
348
355
cx. tcx . sess . span_note ( sp, fmt ! ( "%s" , reason) ) ;
349
356
}
350
357
}
351
358
352
- pub fn check_send ( cx : ctx , ty : ty:: t , sp : span ) -> bool {
353
- if !ty:: kind_can_be_sent ( ty:: type_kind ( cx. tcx , ty) ) {
354
- cx. tcx . sess . span_err ( sp, ~"not a sendable value") ;
359
+ pub fn check_owned ( cx : ctx , ty : ty:: t , sp : span ) -> bool {
360
+ if !ty:: type_is_owned ( cx. tcx , ty) {
361
+ cx. tcx . sess . span_err (
362
+ sp, fmt ! ( "value has non-owned type `%s`" ,
363
+ ty_to_str( cx. tcx, ty) ) ) ;
355
364
false
356
365
} else {
357
366
true
@@ -360,7 +369,7 @@ pub fn check_send(cx: ctx, ty: ty::t, sp: span) -> bool {
360
369
361
370
// note: also used from middle::typeck::regionck!
362
371
pub fn check_durable ( tcx : ty:: ctxt , ty : ty:: t , sp : span ) -> bool {
363
- if !ty:: kind_is_durable ( ty :: type_kind ( tcx, ty) ) {
372
+ if !ty:: type_is_durable ( tcx, ty) {
364
373
match ty:: get ( ty) . sty {
365
374
ty:: ty_param( * ) => {
366
375
tcx. sess . span_err ( sp, ~"value may contain borrowed \
@@ -403,8 +412,8 @@ pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool {
403
412
pub fn check_cast_for_escaping_regions (
404
413
cx : ctx ,
405
414
source: @expr,
406
- target: @expr) {
407
-
415
+ target: @expr)
416
+ {
408
417
// Determine what type we are casting to; if it is not an trait, then no
409
418
// worries.
410
419
let target_ty = ty:: expr_ty ( cx. tcx , target) ;
@@ -450,13 +459,9 @@ pub fn check_kind_bounds_of_cast(cx: ctx, source: @expr, target: @expr) {
450
459
match ty:: get ( target_ty) . sty {
451
460
ty:: ty_trait( _, _, ty:: vstore_uniq) => {
452
461
let source_ty = ty:: expr_ty ( cx. tcx , source) ;
453
- let source_kind = ty:: type_kind ( cx. tcx , source_ty) ;
454
- if !ty:: kind_can_be_copied ( source_kind) {
455
- cx. tcx . sess . span_err ( target. span ,
456
- ~"uniquely-owned trait objects must be copyable") ;
457
- }
458
- if !ty:: kind_can_be_sent ( source_kind) {
459
- cx. tcx . sess . span_err ( target. span ,
462
+ if !ty:: type_is_owned ( cx. tcx , source_ty) {
463
+ cx. tcx . sess . span_err (
464
+ target. span ,
460
465
~"uniquely-owned trait objects must be sendable") ;
461
466
}
462
467
}
0 commit comments