@@ -15,7 +15,6 @@ use middle::freevars;
1515use middle:: lint:: { non_implicitly_copyable_typarams, implicit_copies} ;
1616use middle:: liveness;
1717use middle:: pat_util;
18- use middle:: ty:: { Kind , kind_copyable, kind_noncopyable, kind_const} ;
1918use middle:: ty;
2019use middle:: typeck;
2120use middle;
@@ -61,26 +60,6 @@ use syntax::{visit, ast_util};
6160
6261pub const try_adding: & str = "Try adding a move" ;
6362
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-
8463pub type rval_map = HashMap < node_id , ( ) > ;
8564
8665pub type ctx = {
@@ -119,11 +98,11 @@ type check_fn = fn@(ctx, @freevar_entry);
11998// closure.
12099fn with_appropriate_checker ( cx : ctx , id : node_id , b : fn ( check_fn ) ) {
121100 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.
124103 let id = ast_util:: def_id_of_def ( fv. def ) . node ;
125104 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 ; }
127106
128107 // check that only immutable variables are implicitly copied in
129108 check_imm_free_var ( cx, fv. def , fv. span ) ;
@@ -281,30 +260,54 @@ fn check_ty(aty: @Ty, cx: ctx, v: visit::vt<ctx>) {
281260 visit:: visit_ty ( aty, cx, v) ;
282261}
283262
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+ }
306300 }
307301 }
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+ }
308311}
309312
310313fn is_nullary_variant ( cx : ctx , ex: @expr) -> bool {
@@ -342,16 +345,22 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
342345}
343346
344347fn 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) ) ) ;
348355 cx. tcx . sess . span_note ( sp, fmt ! ( "%s" , reason) ) ;
349356 }
350357}
351358
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) ) ) ;
355364 false
356365 } else {
357366 true
@@ -360,7 +369,7 @@ pub fn check_send(cx: ctx, ty: ty::t, sp: span) -> bool {
360369
361370// note: also used from middle::typeck::regionck!
362371pub 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) {
364373 match ty:: get ( ty) . sty {
365374 ty:: ty_param( * ) => {
366375 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 {
403412pub fn check_cast_for_escaping_regions (
404413 cx : ctx ,
405414 source: @expr,
406- target: @expr) {
407-
415+ target: @expr)
416+ {
408417 // Determine what type we are casting to; if it is not an trait, then no
409418 // worries.
410419 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) {
450459 match ty:: get ( target_ty) . sty {
451460 ty:: ty_trait( _, _, ty:: vstore_uniq) => {
452461 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 ,
460465 ~"uniquely-owned trait objects must be sendable") ;
461466 }
462467 }
0 commit comments