diff options
| author | bors <bors@rust-lang.org> | 2023-07-24 19:40:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-07-24 19:40:01 +0000 |
| commit | fd56162af035fbbbd08e87826ed14e9539aedcb6 (patch) | |
| tree | 7db11f18157cf7c04ccc63ebfb41930b8676333c | |
| parent | fc8a3e357a0a5e317132e5ff8858ec70970fb07a (diff) | |
| parent | 09434a2575cee12b241c516ad91f21d4b4f9c3fd (diff) | |
| download | rust-fd56162af035fbbbd08e87826ed14e9539aedcb6.tar.gz rust-fd56162af035fbbbd08e87826ed14e9539aedcb6.zip | |
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.
| -rw-r--r-- | compiler/rustc_lint/src/types.rs | 21 | ||||
| -rw-r--r-- | tests/ui/lint/lint-ctypes-113900.rs | 12 |
2 files changed, 21 insertions, 12 deletions
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index cc8a3408004..3379479b174 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -966,12 +966,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { args: GenericArgsRef<'tcx>, ) -> FfiResult<'tcx> { let field_ty = field.ty(self.cx.tcx, args); - if field_ty.has_opaque_types() { - self.check_type_for_ffi(cache, field_ty) - } else { - let field_ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, field_ty); - self.check_type_for_ffi(cache, field_ty) - } + let field_ty = self + .cx + .tcx + .try_normalize_erasing_regions(self.cx.param_env, 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". @@ -1320,7 +1320,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if let Some(ty) = self .cx .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) .break_value() { @@ -1338,16 +1339,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { is_static: 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) { // 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(self.cx.param_env, ty); + let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.param_env, ty).unwrap_or(ty); // 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 diff --git a/tests/ui/lint/lint-ctypes-113900.rs b/tests/ui/lint/lint-ctypes-113900.rs new file mode 100644 index 00000000000..ac4ff1ae2df --- /dev/null +++ b/tests/ui/lint/lint-ctypes-113900.rs @@ -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() {} |
