Auto merge of #113921 - davidtwco:lint-ctypes-issue-113900, r=petrochenkov
lint/ctypes: only try normalize Fixes #113900. Now that this lint runs on any external-ABI fn-ptr, normalization won't always succeed, so use `try_normalize_erasing_regions` instead.
This commit is contained in:
commit
fd56162af0
@ -966,12 +966,12 @@ fn check_field_type_for_ffi(
|
|||||||
args: GenericArgsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> FfiResult<'tcx> {
|
) -> FfiResult<'tcx> {
|
||||||
let field_ty = field.ty(self.cx.tcx, args);
|
let field_ty = field.ty(self.cx.tcx, args);
|
||||||
if field_ty.has_opaque_types() {
|
let field_ty = self
|
||||||
self.check_type_for_ffi(cache, field_ty)
|
.cx
|
||||||
} else {
|
.tcx
|
||||||
let field_ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, field_ty);
|
.try_normalize_erasing_regions(self.cx.param_env, field_ty)
|
||||||
self.check_type_for_ffi(cache, field_ty)
|
.unwrap_or(field_ty);
|
||||||
}
|
self.check_type_for_ffi(cache, field_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the given `VariantDef`'s field types are "ffi-safe".
|
/// Checks if the given `VariantDef`'s field types are "ffi-safe".
|
||||||
@ -1320,7 +1320,8 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|||||||
if let Some(ty) = self
|
if let Some(ty) = self
|
||||||
.cx
|
.cx
|
||||||
.tcx
|
.tcx
|
||||||
.normalize_erasing_regions(self.cx.param_env, ty)
|
.try_normalize_erasing_regions(self.cx.param_env, ty)
|
||||||
|
.unwrap_or(ty)
|
||||||
.visit_with(&mut ProhibitOpaqueTypes)
|
.visit_with(&mut ProhibitOpaqueTypes)
|
||||||
.break_value()
|
.break_value()
|
||||||
{
|
{
|
||||||
@ -1338,16 +1339,12 @@ fn check_type_for_ffi_and_report_errors(
|
|||||||
is_static: bool,
|
is_static: bool,
|
||||||
is_return_type: bool,
|
is_return_type: bool,
|
||||||
) {
|
) {
|
||||||
// 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) {
|
if self.check_for_opaque_ty(sp, ty) {
|
||||||
// We've already emitted an error due to an opaque type.
|
// We've already emitted an error due to an opaque type.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is only OK to use this function because extern fns cannot have
|
let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.param_env, ty).unwrap_or(ty);
|
||||||
// any generic types right now:
|
|
||||||
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
|
|
||||||
|
|
||||||
// C doesn't really support passing arrays by value - the only way to pass an array by value
|
// C doesn't really support passing arrays by value - the only way to pass an array by value
|
||||||
// is through a struct. So, first test that the top level isn't an array, and then
|
// is through a struct. So, first test that the top level isn't an array, and then
|
||||||
|
12
tests/ui/lint/lint-ctypes-113900.rs
Normal file
12
tests/ui/lint/lint-ctypes-113900.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Extending `improper_ctypes` to check external-ABI fn-ptrs means that it can encounter
|
||||||
|
// projections which cannot be normalized - unsurprisingly, this shouldn't crash the compiler.
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Foo<T> = extern "C" fn() -> <T as Bar>::Assoc;
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user