From 72a4e33d69d982c6d26d19d65e136f21bded3184 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 18 May 2025 14:39:28 +0200 Subject: [PATCH] Fix ICE while computing type layout If a type is incomplete, for example if generic parameters are not available yet, although they are not escaping, its layout may not be computable. Calling `TyCtxt::layout_of()` would create a delayed bug in the compiler. --- clippy_lints/src/zero_sized_map_values.rs | 8 +++++--- tests/ui/crashes/ice-6840.rs | 1 + tests/ui/zero_sized_hashmap_values.rs | 21 +++++++++++++++++++++ tests/ui/zero_sized_hashmap_values.stderr | 16 ++++++++++++---- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs index 24b1381ba458..1550872bca2b 100644 --- a/clippy_lints/src/zero_sized_map_values.rs +++ b/clippy_lints/src/zero_sized_map_values.rs @@ -51,9 +51,11 @@ impl LateLintPass<'_> for ZeroSizedMapValues { && (is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap)) && let ty::Adt(_, args) = ty.kind() && let ty = args.type_at(1) - // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of - // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968 - && !ty.has_escaping_bound_vars() + // Ensure that no type information is missing, to avoid a delayed bug in the compiler if this is not the case. + // This might happen when computing a reference/pointer metadata on a type for which we + // cannot check if it is `Sized` or not, such as an incomplete associated type in a + // type alias. See an example in `issue14822()` of `tests/ui/zero_sized_hashmap_values.rs`. + && !ty.has_non_region_param() && let Ok(layout) = cx.layout_of(ty) && layout.is_zst() { diff --git a/tests/ui/crashes/ice-6840.rs b/tests/ui/crashes/ice-6840.rs index 94481f248998..f30d83e1eeec 100644 --- a/tests/ui/crashes/ice-6840.rs +++ b/tests/ui/crashes/ice-6840.rs @@ -2,6 +2,7 @@ //! This is a reproducer for the ICE 6840: https://github.com/rust-lang/rust-clippy/issues/6840. //! The ICE is caused by `TyCtxt::layout_of` and `is_normalizable` not being strict enough #![allow(dead_code)] +#![deny(clippy::zero_sized_map_values)] // For ICE 14822 use std::collections::HashMap; pub trait Rule { diff --git a/tests/ui/zero_sized_hashmap_values.rs b/tests/ui/zero_sized_hashmap_values.rs index 4beeef421f30..dcbfd16843de 100644 --- a/tests/ui/zero_sized_hashmap_values.rs +++ b/tests/ui/zero_sized_hashmap_values.rs @@ -71,6 +71,27 @@ fn test2(map: HashMap, key: &str) -> HashMap { todo!(); } +fn issue14822() { + trait Trait { + type T; + } + struct S(T::T); + + // The `delay_bug` happens when evaluating the pointer metadata of `S` which depends on + // whether `T::T` is `Sized`. Since the type alias doesn't have a trait bound of `T: Trait` + // evaluating `T::T: Sized` ultimately fails with `NoSolution`. + type A = HashMap>; + type B = HashMap>; + + enum E {} + impl Trait for E { + type T = (); + } + type C = HashMap>; + type D = HashMap>; + //~^ zero_sized_map_values +} + fn main() { let _: HashMap = HashMap::new(); //~^ zero_sized_map_values diff --git a/tests/ui/zero_sized_hashmap_values.stderr b/tests/ui/zero_sized_hashmap_values.stderr index ed8536acfe8f..d29491fa05c7 100644 --- a/tests/ui/zero_sized_hashmap_values.stderr +++ b/tests/ui/zero_sized_hashmap_values.stderr @@ -81,7 +81,15 @@ LL | fn test(map: HashMap, key: &str) -> HashMap { = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:75:34 + --> tests/ui/zero_sized_hashmap_values.rs:91:14 + | +LL | type D = HashMap>; + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider using a set instead + +error: map with zero-sized value type + --> tests/ui/zero_sized_hashmap_values.rs:96:34 | LL | let _: HashMap = HashMap::new(); | ^^^^^^^ @@ -89,7 +97,7 @@ LL | let _: HashMap = HashMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:75:12 + --> tests/ui/zero_sized_hashmap_values.rs:96:12 | LL | let _: HashMap = HashMap::new(); | ^^^^^^^^^^^^^^^^^^^ @@ -97,12 +105,12 @@ LL | let _: HashMap = HashMap::new(); = help: consider using a set instead error: map with zero-sized value type - --> tests/ui/zero_sized_hashmap_values.rs:81:12 + --> tests/ui/zero_sized_hashmap_values.rs:102:12 | LL | let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect(); | ^^^^^^^^^^^^^ | = help: consider using a set instead -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors