@@ -93,7 +93,7 @@ use middle::typeck::check::method::TransformTypeNormally;
9393use middle:: typeck:: check:: regionmanip:: replace_bound_regions_in_fn_sig;
9494use middle:: typeck:: check:: vtable:: { LocationInfo , VtableContext } ;
9595use middle:: typeck:: CrateCtxt ;
96- use middle:: typeck:: infer:: { resolve_type, force_tvar} ;
96+ use middle:: typeck:: infer:: { resolve_type, force_tvar, mk_eqty } ;
9797use middle:: typeck:: infer;
9898use middle:: typeck:: rscope:: { binding_rscope, bound_self_region} ;
9999use middle:: typeck:: rscope:: { RegionError } ;
@@ -2452,6 +2452,44 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
24522452 let t_1_is_scalar = type_is_scalar ( fcx, expr. span , t_1) ;
24532453 if type_is_c_like_enum ( fcx, expr. span , t_e) && t_1_is_scalar {
24542454 /* this case is allowed */
2455+ } else if type_is_region_ptr ( fcx, expr. span , t_e) &&
2456+ type_is_unsafe_ptr ( fcx, expr. span , t_1) {
2457+
2458+ fn is_vec ( t : ty:: t ) -> bool {
2459+ match ty:: get ( t) . sty {
2460+ ty:: ty_evec( _, _) => true ,
2461+ _ => false
2462+ }
2463+ }
2464+ fn types_compatible ( fcx : @mut FnCtxt , sp : span , t1 : ty:: t ,
2465+ t2 : ty:: t ) -> bool {
2466+ if !is_vec ( t1) {
2467+ false
2468+ } else {
2469+ let el = ty:: sequence_element_type ( fcx. tcx ( ) , t1) ;
2470+ infer:: mk_eqty ( fcx. infcx ( ) , false , sp, el, t2) . is_ok ( )
2471+ }
2472+ }
2473+
2474+ // Due to the limitations of LLVM global constants,
2475+ // region pointers end up pointing at copies of
2476+ // vector elements instead of the original values.
2477+ // To allow unsafe pointers to work correctly, we
2478+ // need to special-case obtaining an unsafe pointer
2479+ // from a region pointer to a vector.
2480+
2481+ /* this cast is only allowed from &[T] to *T or
2482+ &T to *T. */
2483+ let te = structurally_resolved_type ( fcx, e. span , t_e) ;
2484+ match ( & ty:: get ( te) . sty , & ty:: get ( t_1) . sty ) {
2485+ ( & ty:: ty_rptr( _, mt1) , & ty:: ty_ptr( mt2) )
2486+ if types_compatible ( fcx, e. span , mt1. ty , mt2. ty ) => {
2487+ /* this case is allowed */
2488+ }
2489+ _ => {
2490+ demand:: coerce ( fcx, e. span , t_1, e) ;
2491+ }
2492+ }
24552493 } else if !( type_is_scalar ( fcx, expr. span , t_e) && t_1_is_scalar) {
24562494 /*
24572495 If more type combinations should be supported than are
@@ -3081,6 +3119,16 @@ pub fn type_is_scalar(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> bool {
30813119 return ty:: type_is_scalar( typ_s) ;
30823120}
30833121
3122+ pub fn type_is_unsafe_ptr( fcx: @mut FnCtxt , sp: span, typ: ty:: t) -> bool {
3123+ let typ_s = structurally_resolved_type( fcx, sp, typ) ;
3124+ return ty:: type_is_unsafe_ptr( typ_s) ;
3125+ }
3126+
3127+ pub fn type_is_region_ptr( fcx: @mut FnCtxt , sp: span, typ: ty:: t) -> bool {
3128+ let typ_s = structurally_resolved_type( fcx, sp, typ) ;
3129+ return ty:: type_is_region_ptr( typ_s) ;
3130+ }
3131+
30843132pub fn type_is_c_like_enum( fcx: @mut FnCtxt , sp: span, typ: ty:: t) -> bool {
30853133 let typ_s = structurally_resolved_type( fcx, sp, typ) ;
30863134 return ty:: type_is_c_like_enum( fcx. ccx. tcx, typ_s) ;
0 commit comments