Skip to content

Commit 0426c1f

Browse files
davidtwcocuviper
authored andcommitted
lint/ctypes: only try normalize
Now that this lint runs on any external-ABI fn-ptr, normalization won't always succeed, so use `try_normalize_erasing_regions` instead. Signed-off-by: David Wood <[email protected]> (cherry picked from commit 09434a2)
1 parent fc3ed7c commit 0426c1f

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

compiler/rustc_lint/src/types.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -963,12 +963,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
963963
substs: SubstsRef<'tcx>,
964964
) -> FfiResult<'tcx> {
965965
let field_ty = field.ty(self.cx.tcx, substs);
966-
if field_ty.has_opaque_types() {
967-
self.check_type_for_ffi(cache, field_ty)
968-
} else {
969-
let field_ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, field_ty);
970-
self.check_type_for_ffi(cache, field_ty)
971-
}
966+
let field_ty = self
967+
.cx
968+
.tcx
969+
.try_normalize_erasing_regions(self.cx.param_env, field_ty)
970+
.unwrap_or(field_ty);
971+
self.check_type_for_ffi(cache, field_ty)
972972
}
973973

974974
/// Checks if the given `VariantDef`'s field types are "ffi-safe".
@@ -1315,7 +1315,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13151315
if let Some(ty) = self
13161316
.cx
13171317
.tcx
1318-
.normalize_erasing_regions(self.cx.param_env, ty)
1318+
.try_normalize_erasing_regions(self.cx.param_env, ty)
1319+
.unwrap_or(ty)
13191320
.visit_with(&mut ProhibitOpaqueTypes)
13201321
.break_value()
13211322
{
@@ -1333,16 +1334,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13331334
is_static: bool,
13341335
is_return_type: bool,
13351336
) {
1336-
// We have to check for opaque types before `normalize_erasing_regions`,
1337-
// which will replace opaque types with their underlying concrete type.
13381337
if self.check_for_opaque_ty(sp, ty) {
13391338
// We've already emitted an error due to an opaque type.
13401339
return;
13411340
}
13421341

1343-
// it is only OK to use this function because extern fns cannot have
1344-
// any generic types right now:
1345-
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
1342+
let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.param_env, ty).unwrap_or(ty);
13461343

13471344
// C doesn't really support passing arrays by value - the only way to pass an array by value
13481345
// is through a struct. So, first test that the top level isn't an array, and then

tests/ui/lint/lint-ctypes-113900.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// check-pass
2+
3+
// Extending `improper_ctypes` to check external-ABI fn-ptrs means that it can encounter
4+
// projections which cannot be normalized - unsurprisingly, this shouldn't crash the compiler.
5+
6+
trait Bar {
7+
type Assoc;
8+
}
9+
10+
type Foo<T> = extern "C" fn() -> <T as Bar>::Assoc;
11+
12+
fn main() {}

0 commit comments

Comments
 (0)