Skip to content

Commit a10cfd6

Browse files
Add TooGeneric variant to LayoutError and emit Unknown one
- `check-pass` test for a MRE of rust-lang#135020 - fail test for rust-lang#135138 - switch to `TooGeneric` for checking CMSE fn signatures - switch to `TooGeneric` for compute `SizeSkeleton` (for transmute) - fix broken tests
1 parent e491cae commit a10cfd6

32 files changed

+230
-65
lines changed

compiler/rustc_const_eval/src/const_eval/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ where
140140
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
141141
// should remain silent.
142142
err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span),
143-
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
143+
err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => {
144144
ErrorHandled::TooGeneric(span)
145145
}
146146
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {

compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
201201
use LayoutError::*;
202202

203203
match layout_err {
204-
Unknown(ty) => {
204+
TooGeneric(ty) => {
205205
match abi {
206206
ExternAbi::CCmseNonSecureCall => {
207207
// prevent double reporting of this error
@@ -211,7 +211,11 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError
211211
_ => bug!("invalid ABI: {abi}"),
212212
}
213213
}
214-
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
214+
Unknown(..)
215+
| SizeOverflow(..)
216+
| NormalizationFailure(..)
217+
| ReferencesError(..)
218+
| Cycle(..) => {
215219
false // not our job to report these
216220
}
217221
}

compiler/rustc_middle/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,14 @@ middle_strict_coherence_needs_negative_coherence =
100100
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
101101
.label = due to this attribute
102102
103+
middle_too_generic = `{$ty}` does not have a fixed size
104+
103105
middle_type_length_limit = reached the type-length limit while instantiating `{$shrunk}`
104106
105107
middle_unknown_layout =
106108
the type `{$ty}` has an unknown layout
107109
108110
middle_values_too_big =
109111
values of the type `{$ty}` are too big for the target architecture
112+
110113
middle_written_to_path = the full type name has been written to '{$path}'

compiler/rustc_middle/src/error.rs

+3
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ pub enum LayoutError<'tcx> {
129129
#[diag(middle_unknown_layout)]
130130
Unknown { ty: Ty<'tcx> },
131131

132+
#[diag(middle_too_generic)]
133+
TooGeneric { ty: Ty<'tcx> },
134+
132135
#[diag(middle_values_too_big)]
133136
Overflow { ty: Ty<'tcx> },
134137

compiler/rustc_middle/src/ty/layout.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ impl fmt::Display for ValidityRequirement {
231231
pub enum LayoutError<'tcx> {
232232
Unknown(Ty<'tcx>),
233233
SizeOverflow(Ty<'tcx>),
234+
TooGeneric(Ty<'tcx>),
234235
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
235236
ReferencesError(ErrorGuaranteed),
236237
Cycle(ErrorGuaranteed),
@@ -244,6 +245,7 @@ impl<'tcx> LayoutError<'tcx> {
244245
match self {
245246
Unknown(_) => middle_unknown_layout,
246247
SizeOverflow(_) => middle_values_too_big,
248+
TooGeneric(_) => middle_too_generic,
247249
NormalizationFailure(_, _) => middle_cannot_be_normalized,
248250
Cycle(_) => middle_cycle,
249251
ReferencesError(_) => middle_layout_references_error,
@@ -257,6 +259,7 @@ impl<'tcx> LayoutError<'tcx> {
257259
match self {
258260
Unknown(ty) => E::Unknown { ty },
259261
SizeOverflow(ty) => E::Overflow { ty },
262+
TooGeneric(ty) => E::TooGeneric { ty },
260263
NormalizationFailure(ty, e) => {
261264
E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() }
262265
}
@@ -272,6 +275,9 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
272275
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
273276
match *self {
274277
LayoutError::Unknown(ty) => write!(f, "the type `{ty}` has an unknown layout"),
278+
LayoutError::TooGeneric(ty) => {
279+
write!(f, "`{ty}` does not have a fixed size")
280+
}
275281
LayoutError::SizeOverflow(ty) => {
276282
write!(f, "values of the type `{ty}` are too big for the target architecture")
277283
}
@@ -350,10 +356,11 @@ impl<'tcx> SizeSkeleton<'tcx> {
350356
return Err(tcx.arena.alloc(LayoutError::Unknown(ty)));
351357
}
352358
}
353-
Err(err @ LayoutError::Unknown(_)) => err,
359+
Err(err @ LayoutError::TooGeneric(_)) => err,
354360
// We can't extract SizeSkeleton info from other layout errors
355361
Err(
356362
e @ LayoutError::Cycle(_)
363+
| e @ LayoutError::Unknown(_)
357364
| e @ LayoutError::SizeOverflow(_)
358365
| e @ LayoutError::NormalizationFailure(..)
359366
| e @ LayoutError::ReferencesError(_),

compiler/rustc_transmute/src/layout/tree.rs

+1
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ pub(crate) mod rustc {
197197
match err {
198198
LayoutError::Unknown(..)
199199
| LayoutError::ReferencesError(..)
200+
| LayoutError::TooGeneric(..)
200201
| LayoutError::NormalizationFailure(..) => Self::UnknownLayout,
201202
LayoutError::SizeOverflow(..) => Self::SizeOverflow,
202203
LayoutError::Cycle(err) => Self::TypeError(*err),

compiler/rustc_ty_utils/src/layout.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn map_error<'tcx>(
104104
// This is sometimes not a compile error if there are trivially false where clauses.
105105
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
106106
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
107-
if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
107+
if cx.typing_env.param_env.caller_bounds().is_empty() {
108108
cx.tcx().dcx().delayed_bug(format!(
109109
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
110110
));
@@ -317,13 +317,25 @@ fn layout_of_uncached<'tcx>(
317317
if count.has_aliases() {
318318
count = tcx.normalize_erasing_regions(cx.typing_env, count);
319319
if count.has_aliases() {
320-
return Err(error(cx, LayoutError::Unknown(ty)));
320+
return Err(error(cx, LayoutError::TooGeneric(ty)));
321321
}
322322
}
323323

324-
let count = count
325-
.try_to_target_usize(tcx)
326-
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
324+
let count = match count.kind() {
325+
ty::ConstKind::Value(..) => count
326+
.try_to_target_usize(tcx)
327+
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
328+
ty::ConstKind::Error(guar) => {
329+
return Err(error(cx, LayoutError::ReferencesError(guar)));
330+
}
331+
_ => {
332+
if !count.has_param() {
333+
bug!("no generic type found in count of array type: {ty:?}");
334+
}
335+
return Err(error(cx, LayoutError::TooGeneric(ty)));
336+
}
337+
};
338+
327339
let element = cx.layout_of(element)?;
328340
let size = element
329341
.size
@@ -679,6 +691,9 @@ fn layout_of_uncached<'tcx>(
679691

680692
// Types with no meaningful known layout.
681693
ty::Alias(..) => {
694+
if ty.has_param() {
695+
return Err(error(cx, LayoutError::TooGeneric(ty)));
696+
}
682697
// NOTE(eddyb) `layout_of` query should've normalized these away,
683698
// if that was possible, so there's no reason to try again here.
684699
return Err(error(cx, LayoutError::Unknown(ty)));
@@ -688,7 +703,11 @@ fn layout_of_uncached<'tcx>(
688703
bug!("Layout::compute: unexpected type `{}`", ty)
689704
}
690705

691-
ty::Placeholder(..) | ty::Param(_) => {
706+
ty::Param(_) => {
707+
return Err(error(cx, LayoutError::TooGeneric(ty)));
708+
}
709+
710+
ty::Placeholder(..) => {
692711
return Err(error(cx, LayoutError::Unknown(ty)));
693712
}
694713
})

src/librustdoc/html/templates/type_layout.html

+8
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ <h2 id="layout" class="section-header"> {# #}
4444
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
4545
the type was too big. {# #}
4646
</p>
47+
{# This kind of error probably can't happen with valid code, but we don't
48+
want to panic and prevent the docs from building, so we just let the
49+
user know that we couldn't compute the layout. #}
50+
{% when Err(LayoutError::TooGeneric(_)) %}
51+
<p> {# #}
52+
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
53+
the type was too generic. {# #}
54+
</p>
4755
{% when Err(LayoutError::ReferencesError(_)) %}
4856
<p> {# #}
4957
<strong>Note:</strong> Encountered an error during type layout; {#+ #}

tests/crashes/135020.rs

-11
This file was deleted.

tests/ui/const-generics/transmute_no_gate.stderr

+18-18
Original file line numberDiff line numberDiff line change
@@ -4,80 +4,80 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
44
LL | std::mem::transmute(v)
55
| ^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: source type: `[[u32; H]; W]` (this type does not have a fixed size)
8-
= note: target type: `[[u32; W]; H]` (this type does not have a fixed size)
7+
= note: source type: `[[u32; H]; W]` (`[[u32; H]; W]` does not have a fixed size)
8+
= note: target type: `[[u32; W]; H]` (`[[u32; W]; H]` does not have a fixed size)
99

1010
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
1111
--> $DIR/transmute_no_gate.rs:20:5
1212
|
1313
LL | std::mem::transmute(v)
1414
| ^^^^^^^^^^^^^^^^^^^
1515
|
16-
= note: source type: `[[u32; H]; W]` (this type does not have a fixed size)
17-
= note: target type: `[u32; W * H]` (this type does not have a fixed size)
16+
= note: source type: `[[u32; H]; W]` (`[[u32; H]; W]` does not have a fixed size)
17+
= note: target type: `[u32; W * H]` (`[u32; W * H]` does not have a fixed size)
1818

1919
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
2020
--> $DIR/transmute_no_gate.rs:27:5
2121
|
2222
LL | std::mem::transmute(v)
2323
| ^^^^^^^^^^^^^^^^^^^
2424
|
25-
= note: source type: `[u32; H*W]` (this type does not have a fixed size)
26-
= note: target type: `[[u32; W]; H]` (this type does not have a fixed size)
25+
= note: source type: `[u32; H*W]` (`[u32; H*W]` does not have a fixed size)
26+
= note: target type: `[[u32; W]; H]` (`[[u32; W]; H]` does not have a fixed size)
2727

2828
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
2929
--> $DIR/transmute_no_gate.rs:36:5
3030
|
3131
LL | std::mem::transmute(v)
3232
| ^^^^^^^^^^^^^^^^^^^
3333
|
34-
= note: source type: `[[[u32; D]; H]; W]` (this type does not have a fixed size)
35-
= note: target type: `[u32; D * W * H]` (this type does not have a fixed size)
34+
= note: source type: `[[[u32; D]; H]; W]` (`[[[u32; D]; H]; W]` does not have a fixed size)
35+
= note: target type: `[u32; D * W * H]` (`[u32; D * W * H]` does not have a fixed size)
3636

3737
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3838
--> $DIR/transmute_no_gate.rs:45:5
3939
|
4040
LL | std::mem::transmute(v)
4141
| ^^^^^^^^^^^^^^^^^^^
4242
|
43-
= note: source type: `[[[u32; D]; H]; W]` (this type does not have a fixed size)
44-
= note: target type: `[[u32; D * W]; H]` (this type does not have a fixed size)
43+
= note: source type: `[[[u32; D]; H]; W]` (`[[[u32; D]; H]; W]` does not have a fixed size)
44+
= note: target type: `[[u32; D * W]; H]` (`[[u32; D * W]; H]` does not have a fixed size)
4545

4646
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
4747
--> $DIR/transmute_no_gate.rs:52:5
4848
|
4949
LL | std::mem::transmute(v)
5050
| ^^^^^^^^^^^^^^^^^^^
5151
|
52-
= note: source type: `[u16; L]` (this type does not have a fixed size)
53-
= note: target type: `[u8; L * 2]` (this type does not have a fixed size)
52+
= note: source type: `[u16; L]` (`[u16; L]` does not have a fixed size)
53+
= note: target type: `[u8; L * 2]` (`[u8; L * 2]` does not have a fixed size)
5454

5555
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
5656
--> $DIR/transmute_no_gate.rs:59:5
5757
|
5858
LL | std::mem::transmute(v)
5959
| ^^^^^^^^^^^^^^^^^^^
6060
|
61-
= note: source type: `[u8; L * 2]` (this type does not have a fixed size)
62-
= note: target type: `[u16; L]` (this type does not have a fixed size)
61+
= note: source type: `[u8; L * 2]` (`[u8; L * 2]` does not have a fixed size)
62+
= note: target type: `[u16; L]` (`[u16; L]` does not have a fixed size)
6363

6464
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
6565
--> $DIR/transmute_no_gate.rs:66:5
6666
|
6767
LL | std::mem::transmute(v)
6868
| ^^^^^^^^^^^^^^^^^^^
6969
|
70-
= note: source type: `[u8; L]` (this type does not have a fixed size)
71-
= note: target type: `[[u8; 1]; L]` (this type does not have a fixed size)
70+
= note: source type: `[u8; L]` (`[u8; L]` does not have a fixed size)
71+
= note: target type: `[[u8; 1]; L]` (`[[u8; 1]; L]` does not have a fixed size)
7272

7373
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
7474
--> $DIR/transmute_no_gate.rs:75:5
7575
|
7676
LL | std::mem::transmute(v)
7777
| ^^^^^^^^^^^^^^^^^^^
7878
|
79-
= note: source type: `[[u32; 2 * H]; W + W]` (this type does not have a fixed size)
80-
= note: target type: `[[u32; W + W]; 2 * H]` (this type does not have a fixed size)
79+
= note: source type: `[[u32; 2 * H]; W + W]` (`[[u32; 2 * H]; W + W]` does not have a fixed size)
80+
= note: target type: `[[u32; W + W]; 2 * H]` (`[[u32; W + W]; 2 * H]` does not have a fixed size)
8181

8282
error: aborting due to 9 previous errors
8383

tests/ui/issues/issue-21174.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
44
LL | let new: T::B = unsafe { std::mem::transmute(value) };
55
| ^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: source type: `<T as Trait<'_>>::A` (this type does not have a fixed size)
8-
= note: target type: `<T as Trait<'_>>::B` (this type does not have a fixed size)
7+
= note: source type: `<T as Trait<'_>>::A` (`<T as Trait<'_>>::A` does not have a fixed size)
8+
= note: target type: `<T as Trait<'_>>::B` (`<T as Trait<'_>>::B` does not have a fixed size)
99

1010
error: aborting due to 1 previous error
1111

tests/ui/layout/base-layout-is-sized-ice-123078.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ LL | const C: S = unsafe { std::mem::transmute(()) };
2323
| ^^^^^^^^^^^^^^^^^^^
2424
|
2525
= note: source type: `()` (0 bits)
26-
= note: target type: `S` (size can vary because of [u8])
26+
= note: target type: `S` (this type does not have a fixed size)
2727

2828
error: aborting due to 2 previous errors
2929

tests/ui/layout/invalid-unsized-const-eval.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ struct LazyLock {
1010
}
1111

1212
static EMPTY_SET: LazyLock = todo!();
13+
//~^ ERROR could not evaluate static initializer
1314

1415
fn main() {}

tests/ui/layout/invalid-unsized-const-eval.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ LL | data: (dyn Sync, ()),
77
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
88
= note: only the last element of a tuple may have a dynamically sized type
99

10-
error: aborting due to 1 previous error
10+
error[E0080]: could not evaluate static initializer
11+
--> $DIR/invalid-unsized-const-eval.rs:12:1
12+
|
13+
LL | static EMPTY_SET: LazyLock = todo!();
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `(dyn Sync, ())` has an unknown layout
15+
16+
error: aborting due to 2 previous errors
1117

12-
For more information about this error, try `rustc --explain E0277`.
18+
Some errors have detailed explanations: E0080, E0277.
19+
For more information about an error, try `rustc --explain E0080`.

tests/ui/layout/invalid-unsized-in-always-sized-tail.stderr

+16-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ LL | struct MySlice<T>(T);
1818
| |
1919
| this could be changed to `T: ?Sized`...
2020

21-
error: aborting due to 1 previous error
21+
error[E0080]: could not evaluate static initializer
22+
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
23+
|
24+
= note: the type `MySlice<[bool]>` has an unknown layout
25+
|
26+
note: inside `align_of::<P2>`
27+
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
28+
note: inside `CHECK`
29+
--> $DIR/invalid-unsized-in-always-sized-tail.rs:15:28
30+
|
31+
LL | static CHECK: () = assert!(align_of::<P2>() == 1);
32+
| ^^^^^^^^^^^^^^^^
33+
34+
error: aborting due to 2 previous errors
2235

23-
For more information about this error, try `rustc --explain E0277`.
36+
Some errors have detailed explanations: E0080, E0277.
37+
For more information about an error, try `rustc --explain E0080`.

tests/ui/layout/issue-unsized-tail-restatic-ice-122488.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ struct ArenaSet<U: Deref, V: ?Sized = <U as Deref>::Target>(V, U);
66
//~^ ERROR the size for values of type `V` cannot be known at compilation time
77

88
const DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut();
9+
//~^ ERROR evaluation of constant value failed
910

1011
pub fn main() {}

tests/ui/layout/issue-unsized-tail-restatic-ice-122488.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ help: the `Box` type always has a statically known size and allocates its conten
2222
LL | struct ArenaSet<U: Deref, V: ?Sized = <U as Deref>::Target>(Box<V>, U);
2323
| ++++ +
2424

25-
error: aborting due to 1 previous error
25+
error[E0080]: evaluation of constant value failed
26+
--> $DIR/issue-unsized-tail-restatic-ice-122488.rs:8:1
27+
|
28+
LL | const DATA: *const ArenaSet<Vec<u8>> = std::ptr::null_mut();
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `ArenaSet<Vec<u8>, [u8]>` has an unknown layout
30+
31+
error: aborting due to 2 previous errors
2632

27-
For more information about this error, try `rustc --explain E0277`.
33+
Some errors have detailed explanations: E0080, E0277.
34+
For more information about an error, try `rustc --explain E0080`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(trivial_bounds)]
2+
3+
fn return_str()
4+
where
5+
str: Sized,
6+
{
7+
[(); { let _a: Option<str> = None; 0 }];
8+
//~^ ERROR evaluation of constant value failed
9+
}
10+
11+
fn main() {}

0 commit comments

Comments
 (0)