@@ -196,6 +196,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
196
196
// Function items are coercible to any closure
197
197
// type; function pointers are not (that would
198
198
// require double indirection).
199
+ // Additionally, we permit coercion of function
200
+ // items to drop the unsafe qualifier.
199
201
self . coerce_from_fn_item ( a, a_f, b)
200
202
}
201
203
ty:: TyFnPtr ( a_f) => {
@@ -504,6 +506,24 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
504
506
Ok ( ( target, AdjustDerefRef ( adjustment) ) )
505
507
}
506
508
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
+
507
527
fn coerce_from_fn_pointer ( & self ,
508
528
a : Ty < ' tcx > ,
509
529
fn_ty_a : & ' tcx ty:: BareFnTy < ' tcx > ,
@@ -516,17 +536,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
516
536
let b = self . shallow_resolve ( b) ;
517
537
debug ! ( "coerce_from_fn_pointer(a={:?}, b={:?})" , a, b) ;
518
538
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)
530
540
}
531
541
532
542
fn coerce_from_fn_item ( & self ,
@@ -544,7 +554,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
544
554
match b. sty {
545
555
ty:: TyFnPtr ( _) => {
546
556
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 ) )
548
559
}
549
560
_ => self . unify_and_identity ( a, b) ,
550
561
}
0 commit comments