Skip to content

Commit 6753e16

Browse files
authored
Fix ICE while computing type layout (#14837)
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. changelog: [`zero_sized_map_values`]: fix ICE Fixes #14822 r? @Jarcho
2 parents 66697e8 + 72a4e33 commit 6753e16

File tree

4 files changed

+39
-7
lines changed

4 files changed

+39
-7
lines changed

clippy_lints/src/zero_sized_map_values.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ impl LateLintPass<'_> for ZeroSizedMapValues {
5151
&& (is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap))
5252
&& let ty::Adt(_, args) = ty.kind()
5353
&& let ty = args.type_at(1)
54-
// Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of
55-
// https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968
56-
&& !ty.has_escaping_bound_vars()
54+
// Ensure that no type information is missing, to avoid a delayed bug in the compiler if this is not the case.
55+
// This might happen when computing a reference/pointer metadata on a type for which we
56+
// cannot check if it is `Sized` or not, such as an incomplete associated type in a
57+
// type alias. See an example in `issue14822()` of `tests/ui/zero_sized_hashmap_values.rs`.
58+
&& !ty.has_non_region_param()
5759
&& let Ok(layout) = cx.layout_of(ty)
5860
&& layout.is_zst()
5961
{

tests/ui/crashes/ice-6840.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! This is a reproducer for the ICE 6840: https://github.com/rust-lang/rust-clippy/issues/6840.
33
//! The ICE is caused by `TyCtxt::layout_of` and `is_normalizable` not being strict enough
44
#![allow(dead_code)]
5+
#![deny(clippy::zero_sized_map_values)] // For ICE 14822
56
use std::collections::HashMap;
67

78
pub trait Rule {

tests/ui/zero_sized_hashmap_values.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,27 @@ fn test2(map: HashMap<String, usize>, key: &str) -> HashMap<String, usize> {
7171
todo!();
7272
}
7373

74+
fn issue14822() {
75+
trait Trait {
76+
type T;
77+
}
78+
struct S<T: Trait>(T::T);
79+
80+
// The `delay_bug` happens when evaluating the pointer metadata of `S<T>` which depends on
81+
// whether `T::T` is `Sized`. Since the type alias doesn't have a trait bound of `T: Trait`
82+
// evaluating `T::T: Sized` ultimately fails with `NoSolution`.
83+
type A<T> = HashMap<u32, *const S<T>>;
84+
type B<T> = HashMap<u32, S<T>>;
85+
86+
enum E {}
87+
impl Trait for E {
88+
type T = ();
89+
}
90+
type C = HashMap<u32, *const S<E>>;
91+
type D = HashMap<u32, S<E>>;
92+
//~^ zero_sized_map_values
93+
}
94+
7495
fn main() {
7596
let _: HashMap<String, ()> = HashMap::new();
7697
//~^ zero_sized_map_values

tests/ui/zero_sized_hashmap_values.stderr

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,28 +81,36 @@ LL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {
8181
= help: consider using a set instead
8282

8383
error: map with zero-sized value type
84-
--> tests/ui/zero_sized_hashmap_values.rs:75:34
84+
--> tests/ui/zero_sized_hashmap_values.rs:91:14
85+
|
86+
LL | type D = HashMap<u32, S<E>>;
87+
| ^^^^^^^^^^^^^^^^^^
88+
|
89+
= help: consider using a set instead
90+
91+
error: map with zero-sized value type
92+
--> tests/ui/zero_sized_hashmap_values.rs:96:34
8593
|
8694
LL | let _: HashMap<String, ()> = HashMap::new();
8795
| ^^^^^^^
8896
|
8997
= help: consider using a set instead
9098

9199
error: map with zero-sized value type
92-
--> tests/ui/zero_sized_hashmap_values.rs:75:12
100+
--> tests/ui/zero_sized_hashmap_values.rs:96:12
93101
|
94102
LL | let _: HashMap<String, ()> = HashMap::new();
95103
| ^^^^^^^^^^^^^^^^^^^
96104
|
97105
= help: consider using a set instead
98106

99107
error: map with zero-sized value type
100-
--> tests/ui/zero_sized_hashmap_values.rs:81:12
108+
--> tests/ui/zero_sized_hashmap_values.rs:102:12
101109
|
102110
LL | let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();
103111
| ^^^^^^^^^^^^^
104112
|
105113
= help: consider using a set instead
106114

107-
error: aborting due to 13 previous errors
115+
error: aborting due to 14 previous errors
108116

0 commit comments

Comments
 (0)