Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4f096f4

Browse files
committedJun 11, 2019
Allow closure to extern fn pointer coercion
1 parent 8e948df commit 4f096f4

File tree

11 files changed

+35
-17
lines changed

11 files changed

+35
-17
lines changed
 

‎src/librustc/ty/adjustment.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::hir::def_id::DefId;
33
use crate::ty::{self, Ty, TyCtxt};
44
use crate::ty::subst::SubstsRef;
55
use rustc_macros::HashStable;
6+
use rustc_target::spec::abi;
67

78

89
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
@@ -15,7 +16,7 @@ pub enum PointerCast {
1516

1617
/// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
1718
/// It cannot convert a closure that requires unsafe.
18-
ClosureFnPointer(hir::Unsafety),
19+
ClosureFnPointer(hir::Unsafety, abi::Abi),
1920

2021
/// Go from a mut raw pointer to a const raw pointer.
2122
MutToConstPointer,

‎src/librustc/ty/context.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -2420,21 +2420,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
24202420
/// `hir::Unsafety::Unsafe` in the previous example, then you would get
24212421
/// an `unsafe fn (u32, i32)`.
24222422
/// It cannot convert a closure that requires unsafe.
2423-
pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>, unsafety: hir::Unsafety) -> Ty<'tcx> {
2423+
pub fn coerce_closure_fn_ty(
2424+
self,
2425+
sig: PolyFnSig<'tcx>,
2426+
unsafety: hir::Unsafety,
2427+
abi: abi::Abi,
2428+
) -> Ty<'tcx> {
24242429
let converted_sig = sig.map_bound(|s| {
24252430
let params_iter = match s.inputs()[0].sty {
24262431
ty::Tuple(params) => {
24272432
params.into_iter().map(|k| k.expect_ty())
24282433
}
24292434
_ => bug!(),
24302435
};
2431-
self.mk_fn_sig(
2432-
params_iter,
2433-
s.output(),
2434-
s.c_variadic,
2435-
unsafety,
2436-
abi::Abi::Rust,
2437-
)
2436+
self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi)
24382437
});
24392438

24402439
self.mk_fn_ptr(converted_sig)

‎src/librustc_codegen_ssa/mir/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
192192
}
193193
}
194194
}
195-
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => {
195+
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_, _)) => {
196196
match operand.layout.ty.sty {
197197
ty::Closure(def_id, substs) => {
198198
let instance = Instance::resolve_closure(

‎src/librustc_mir/borrow_check/nll/type_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2011,14 +2011,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20112011
}
20122012
}
20132013

2014-
CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
2014+
CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety, abi)) => {
20152015
let sig = match op.ty(body, tcx).sty {
20162016
ty::Closure(def_id, substs) => {
20172017
substs.closure_sig_ty(def_id, tcx).fn_sig(tcx)
20182018
}
20192019
_ => bug!(),
20202020
};
2021-
let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);
2021+
let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety, *abi);
20222022

20232023
if let Err(terr) = self.eq_types(
20242024
ty_fn_ptr_from,

‎src/librustc_mir/interpret/cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
104104
}
105105
}
106106

107-
Pointer(PointerCast::ClosureFnPointer(_)) => {
107+
Pointer(PointerCast::ClosureFnPointer(_, _)) => {
108108
// The src operand does not matter, just its type
109109
match src.layout.ty.sty {
110110
ty::Closure(def_id, substs) => {

‎src/librustc_mir/monomorphize/collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
569569
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
570570
}
571571
mir::Rvalue::Cast(
572-
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)), ref operand, _
572+
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_, _)), ref operand, _
573573
) => {
574574
let source_ty = operand.ty(self.body, self.tcx);
575575
let source_ty = self.tcx.subst_and_normalize_erasing_regions(

‎src/librustc_mir/transform/qualify_min_const_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn check_rvalue(
160160
check_operand(operand, span)
161161
}
162162
Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) |
163-
Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), _, _) |
163+
Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_, _)), _, _) |
164164
Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), _, _) => Err((
165165
span,
166166
"function pointer casts are not allowed in const fn".into(),

‎src/librustc_typeck/check/coercion.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -739,11 +739,12 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
739739
// `unsafe fn(arg0,arg1,...) -> _`
740740
let sig = self.closure_sig(def_id_a, substs_a);
741741
let unsafety = fn_ty.unsafety();
742-
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety);
742+
let abi = fn_ty.abi();
743+
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety, abi);
743744
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})",
744745
a, b, pointer_ty);
745746
self.unify_and(pointer_ty, b, simple(
746-
Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety))
747+
Adjust::Pointer(PointerCast::ClosureFnPointer(unsafety, abi))
747748
))
748749
}
749750
_ => self.unify_and(a, b, identity),
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
fn main() {
22
let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
33
//~^ ERROR E0133
4+
let _: unsafe extern "C" fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
5+
//~^ ERROR E0133
46
let _: unsafe fn() = || unsafe { ::std::pin::Pin::new_unchecked(&0_u8); }; // OK
7+
let _: unsafe extern "C" fn() = || unsafe { ::std::pin::Pin::new_unchecked(&0_u8); }; // OK
58
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn call_extern_c(func: extern "C" fn()) {
2+
func()
3+
}
4+
5+
pub fn main() {
6+
call_extern_c(|| {});
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
unsafe fn call_unsafe_extern_c(func: unsafe extern "C" fn()) {
2+
func()
3+
}
4+
5+
pub fn main() {
6+
unsafe { call_unsafe_extern_c(|| {}); }
7+
}

0 commit comments

Comments
 (0)
Please sign in to comment.