@@ -196,6 +196,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
196196 // Function items are coercible to any closure
197197 // type; function pointers are not (that would
198198 // require double indirection).
199+ // Additionally, we permit coercion of function
200+ // items to drop the unsafe qualifier.
199201 self . coerce_from_fn_item ( a, a_f, b)
200202 }
201203 ty:: TyFnPtr ( a_f) => {
@@ -504,6 +506,24 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
504506 Ok ( ( target, AdjustDerefRef ( adjustment) ) )
505507 }
506508
509+ fn coerce_from_safe_fn ( & self ,
510+ a : Ty < ' tcx > ,
511+ fn_ty_a : & ' tcx ty:: BareFnTy < ' tcx > ,
512+ b : Ty < ' tcx > )
513+ -> CoerceResult < ' tcx > {
514+ if let ty:: TyFnPtr ( fn_ty_b) = b. sty {
515+ match ( fn_ty_a. unsafety , fn_ty_b. unsafety ) {
516+ ( hir:: Unsafety :: Normal , hir:: Unsafety :: Unsafe ) => {
517+ let unsafe_a = self . tcx . safe_to_unsafe_fn_ty ( fn_ty_a) ;
518+ return self . unify_and_identity ( unsafe_a, b)
519+ . map ( |( ty, _) | ( ty, AdjustUnsafeFnPointer ) ) ;
520+ }
521+ _ => { }
522+ }
523+ }
524+ self . unify_and_identity ( a, b)
525+ }
526+
507527 fn coerce_from_fn_pointer ( & self ,
508528 a : Ty < ' tcx > ,
509529 fn_ty_a : & ' tcx ty:: BareFnTy < ' tcx > ,
@@ -516,17 +536,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
516536 let b = self . shallow_resolve ( b) ;
517537 debug ! ( "coerce_from_fn_pointer(a={:?}, b={:?})" , a, b) ;
518538
519- if let ty:: TyFnPtr ( fn_ty_b) = b. sty {
520- match ( fn_ty_a. unsafety , fn_ty_b. unsafety ) {
521- ( hir:: Unsafety :: Normal , hir:: Unsafety :: Unsafe ) => {
522- let unsafe_a = self . tcx . safe_to_unsafe_fn_ty ( fn_ty_a) ;
523- return self . unify_and_identity ( unsafe_a, b)
524- . map ( |( ty, _) | ( ty, AdjustUnsafeFnPointer ) ) ;
525- }
526- _ => { }
527- }
528- }
529- self . unify_and_identity ( a, b)
539+ self . coerce_from_safe_fn ( a, fn_ty_a, b)
530540 }
531541
532542 fn coerce_from_fn_item ( & self ,
@@ -544,7 +554,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
544554 match b. sty {
545555 ty:: TyFnPtr ( _) => {
546556 let a_fn_pointer = self . tcx . mk_fn_ptr ( fn_ty_a) ;
547- self . unify_and_identity ( a_fn_pointer, b) . map ( |( ty, _) | ( ty, AdjustReifyFnPointer ) )
557+ self . coerce_from_safe_fn ( a_fn_pointer, fn_ty_a, b)
558+ . map ( |( ty, _) | ( ty, AdjustReifyFnPointer ) )
548559 }
549560 _ => self . unify_and_identity ( a, b) ,
550561 }
0 commit comments