mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +00:00
Forbid opaque types in extern blocks
This commit is contained in:
parent
740dd4bf05
commit
df7e496f85
@ -859,7 +859,40 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
|
||||
use crate::rustc::ty::TypeFoldable;
|
||||
|
||||
struct ProhibitOpaqueTypes<'a, 'tcx> {
|
||||
cx: &'a LateContext<'a, 'tcx>,
|
||||
sp: Span,
|
||||
};
|
||||
|
||||
impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||
if let ty::Opaque(..) = ty.sty {
|
||||
self.cx.span_lint(IMPROPER_CTYPES,
|
||||
self.sp,
|
||||
&format!("`extern` block uses type `{}` which is not FFI-safe: \
|
||||
opaque types have no C equivalent", ty));
|
||||
true
|
||||
} else {
|
||||
ty.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = ProhibitOpaqueTypes { cx: self.cx, sp };
|
||||
ty.visit_with(&mut visitor)
|
||||
}
|
||||
|
||||
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
|
||||
// We have to check for opaque types before `normalize_erasing_regions`,
|
||||
// which will replace opaque types with their underlying concrete type.
|
||||
if self.check_for_opaque_ty(sp, ty) {
|
||||
// We've already emitted an error due to an opaque type.
|
||||
return;
|
||||
}
|
||||
|
||||
// it is only OK to use this function because extern fns cannot have
|
||||
// any generic types right now:
|
||||
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||
|
16
src/test/ui/lint/opaque-ty-ffi-unsafe.rs
Normal file
16
src/test/ui/lint/opaque-ty-ffi-unsafe.rs
Normal file
@ -0,0 +1,16 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
#![deny(improper_ctypes)]
|
||||
|
||||
type A = impl Fn();
|
||||
|
||||
pub fn ret_closure() -> A {
|
||||
|| {}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn a(_: A);
|
||||
//~^ ERROR `extern` block uses type `A` which is not FFI-safe: opaque types have no C equivalent
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
Normal file
14
src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: `extern` block uses type `A` which is not FFI-safe: opaque types have no C equivalent
|
||||
--> $DIR/opaque-ty-ffi-unsafe.rs:12:17
|
||||
|
|
||||
LL | pub fn a(_: A);
|
||||
| ^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/opaque-ty-ffi-unsafe.rs:3:9
|
||||
|
|
||||
LL | #![deny(improper_ctypes)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user