Skip to content

Commit 56627c8

Browse files
authored
Normalize raw pointers (#13833)
Consider raw pointers fields as normalizable. This is only used to determine the layout, and the layout of a raw pointer is known, whatever the designated type is. As a side effect, this makes the layout of `Box<T>` known, even inside `T`, and enables recursive types. Would there be a drawback in doing this? I have included the new tests in a separate commit, so that the effect of the change can be seen in the second commit. It can also be seen on the lintcheck diff result. Close #9798.
2 parents 968669b + cbfa74b commit 56627c8

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

clippy_utils/src/ty/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ fn is_normalizable_helper<'tcx>(
375375
.iter()
376376
.all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, args), cache))
377377
}),
378+
ty::RawPtr(..) => true,
378379
_ => ty.walk().all(|generic_arg| match generic_arg.unpack() {
379380
GenericArgKind::Type(inner_ty) if inner_ty != ty => {
380381
is_normalizable_helper(cx, param_env, inner_ty, cache)

tests/ui/large_enum_variant.64bit.stderr

+33-1
Original file line numberDiff line numberDiff line change
@@ -276,5 +276,37 @@ help: consider boxing the large fields to reduce the total size of the enum
276276
LL | Error(Box<PossiblyLargeEnumWithConst<256>>),
277277
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278278

279-
error: aborting due to 16 previous errors
279+
error: large size difference between variants
280+
--> tests/ui/large_enum_variant.rs:158:1
281+
|
282+
LL | / enum WithRecursion {
283+
LL | | Large([u64; 64]),
284+
| | ---------------- the largest variant contains at least 512 bytes
285+
LL | | Recursive(Box<WithRecursion>),
286+
| | ----------------------------- the second-largest variant contains at least 8 bytes
287+
LL | | }
288+
| |_^ the entire enum is at least 520 bytes
289+
|
290+
help: consider boxing the large fields to reduce the total size of the enum
291+
|
292+
LL | Large(Box<[u64; 64]>),
293+
| ~~~~~~~~~~~~~~
294+
295+
error: large size difference between variants
296+
--> tests/ui/large_enum_variant.rs:168:1
297+
|
298+
LL | / enum LargeEnumWithGenericsAndRecursive {
299+
LL | | Ok(),
300+
| | ---- the second-largest variant carries no data at all
301+
LL | | Error(WithRecursionAndGenerics<u64>),
302+
| | ------------------------------------ the largest variant contains at least 520 bytes
303+
LL | | }
304+
| |_^ the entire enum is at least 520 bytes
305+
|
306+
help: consider boxing the large fields to reduce the total size of the enum
307+
|
308+
LL | Error(Box<WithRecursionAndGenerics<u64>>),
309+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310+
311+
error: aborting due to 18 previous errors
280312

tests/ui/large_enum_variant.rs

+15
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,21 @@ enum LargeEnumOfConst {
155155
Error(PossiblyLargeEnumWithConst<256>),
156156
}
157157

158+
enum WithRecursion {
159+
Large([u64; 64]),
160+
Recursive(Box<WithRecursion>),
161+
}
162+
163+
enum WithRecursionAndGenerics<T> {
164+
Large([T; 64]),
165+
Recursive(Box<WithRecursionAndGenerics<T>>),
166+
}
167+
168+
enum LargeEnumWithGenericsAndRecursive {
169+
Ok(),
170+
Error(WithRecursionAndGenerics<u64>),
171+
}
172+
158173
fn main() {
159174
external!(
160175
enum LargeEnumInMacro {

0 commit comments

Comments
 (0)