Skip to content

Commit 3605306

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 341f603 commit 3605306

32 files changed

+235
-74
lines changed

compiler/rustc_const_eval/src/const_eval/error.rs

Lines changed: 1 addition & 1 deletion
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

Lines changed: 6 additions & 2 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 8 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,12 @@ 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) {
108-
let guar = cx.tcx().dcx().delayed_bug(format!(
107+
if cx.typing_env.param_env.caller_bounds().is_empty() {
108+
cx.tcx().dcx().delayed_bug(format!(
109109
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
110110
));
111-
LayoutError::ReferencesError(guar)
112-
} else {
113-
LayoutError::Unknown(ty)
114111
}
112+
LayoutError::Unknown(ty)
115113
}
116114
LayoutCalculatorError::EmptyUnion => {
117115
// This is always a compile error.
@@ -323,13 +321,25 @@ fn layout_of_uncached<'tcx>(
323321
if count.has_aliases() {
324322
count = tcx.normalize_erasing_regions(cx.typing_env, count);
325323
if count.has_aliases() {
326-
return Err(error(cx, LayoutError::Unknown(ty)));
324+
return Err(error(cx, LayoutError::TooGeneric(ty)));
327325
}
328326
}
329327

330-
let count = count
331-
.try_to_target_usize(tcx)
332-
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
328+
let count = match count.kind() {
329+
ty::ConstKind::Value(..) => count
330+
.try_to_target_usize(tcx)
331+
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
332+
ty::ConstKind::Error(guar) => {
333+
return Err(error(cx, LayoutError::ReferencesError(guar)));
334+
}
335+
_ => {
336+
if !count.has_param() {
337+
bug!("no generic type found in count of array type: {ty:?}");
338+
}
339+
return Err(error(cx, LayoutError::TooGeneric(ty)));
340+
}
341+
};
342+
333343
let element = cx.layout_of(element)?;
334344
let size = element
335345
.size
@@ -687,6 +697,9 @@ fn layout_of_uncached<'tcx>(
687697

688698
// Types with no meaningful known layout.
689699
ty::Alias(..) => {
700+
if ty.has_param() {
701+
return Err(error(cx, LayoutError::TooGeneric(ty)));
702+
}
690703
// NOTE(eddyb) `layout_of` query should've normalized these away,
691704
// if that was possible, so there's no reason to try again here.
692705
return Err(error(cx, LayoutError::Unknown(ty)));
@@ -696,7 +709,11 @@ fn layout_of_uncached<'tcx>(
696709
bug!("Layout::compute: unexpected type `{}`", ty)
697710
}
698711

699-
ty::Placeholder(..) | ty::Param(_) => {
712+
ty::Param(_) => {
713+
return Err(error(cx, LayoutError::TooGeneric(ty)));
714+
}
715+
716+
ty::Placeholder(..) => {
700717
return Err(error(cx, LayoutError::Unknown(ty)));
701718
}
702719
})

src/librustdoc/html/templates/type_layout.html

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,27 @@ <h2 id="layout" class="section-header"> {# #}
2828
{% endfor %}
2929
</ul>
3030
{% endif %}
31-
{# This kind of layout error can occur with valid code, e.g. if you try to
32-
get the layout of a generic type such as `Vec<T>`. #}
31+
{# This kind of layout error can occur with valid code, for example
32+
if there are trivial bounds: `struct Foo(str, str) where str: Sized;`. #}
3333
{% when Err(LayoutError::Unknown(_)) %}
3434
<p> {# #}
35-
<strong>Note:</strong> Unable to compute type layout, {#+ #}
36-
possibly due to this type having generic parameters. {#+ #}
37-
Layout can only be computed for concrete, fully-instantiated types. {# #}
35+
<strong>Note:</strong> Unable to compute type layout {# #}
3836
</p>
3937
{# This kind of error probably can't happen with valid code, but we don't
4038
want to panic and prevent the docs from building, so we just let the
4139
user know that we couldn't compute the layout. #}
4240
{% when Err(LayoutError::SizeOverflow(_)) %}
41+
<p> {# #}
42+
<strong>Note:</strong> Unable to compute type layout, {#+ #}
43+
possibly due to this type having generic parameters. {#+ #}
44+
Layout can only be computed for concrete, fully-instantiated types. {# #}
45+
</p>
46+
{# This kind of layout error can occur with valid code, e.g. if you try to
47+
get the layout of a generic type such as `Vec<T>`. #}
48+
{% when Err(LayoutError::TooGeneric(_)) %}
4349
<p> {# #}
4450
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
45-
the type was too big. {# #}
51+
the type was too generic. {# #}
4652
</p>
4753
{% when Err(LayoutError::ReferencesError(_)) %}
4854
<p> {# #}

tests/crashes/135020.rs

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/rustdoc/type-layout.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,9 @@ pub enum Uninhabited {}
9191
//@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
9292
//@ hasraw - '8 bytes (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)'
9393
pub struct Uninhabited2(std::convert::Infallible, u64);
94+
95+
pub trait Project { type Assoc; }
96+
// We can't compute layout. A `LayoutError::Unknown` is returned.
97+
//@ hasraw type_layout/struct.Unknown.html 'Unable to compute type layout. It can happen for various reasons.'
98+
//@ !hasraw - 'Size: '
99+
pub struct Unknown(<() as Project>::Assoc) where for<'a> (): Project;

tests/ui/const-generics/transmute_no_gate.stderr

Lines changed: 18 additions & 18 deletions
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/enum-discriminant/eval-error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ union Foo {
66

77
enum Bar {
88
Boo = {
9-
let _: Option<Foo> = None;
9+
let _: Option<Foo> = None; //~ ERROR evaluation of constant value failed
1010
0
1111
},
1212
}

tests/ui/enum-discriminant/eval-error.stderr

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ help: wrap the field type in `ManuallyDrop<...>`
4545
LL | a: std::mem::ManuallyDrop<str>,
4646
| +++++++++++++++++++++++ +
4747

48-
error: aborting due to 4 previous errors
48+
error[E0080]: evaluation of constant value failed
49+
--> $DIR/eval-error.rs:9:30
50+
|
51+
LL | let _: Option<Foo> = None;
52+
| ^^^^ the type `Foo` has an unknown layout
53+
54+
error: aborting due to 5 previous errors
4955

50-
Some errors have detailed explanations: E0277, E0517, E0740.
51-
For more information about an error, try `rustc --explain E0277`.
56+
Some errors have detailed explanations: E0080, E0277, E0517, E0740.
57+
For more information about an error, try `rustc --explain E0080`.

tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl<T, const L: u8> VirtualWrapper<T, L> {
2424
impl<T: MyTrait + 'static, const L: u8> MyTrait for VirtualWrapper<T, L> {
2525
fn virtualize(&self) -> &dyn MyTrait {
2626
unsafe { virtualize_my_trait(L, self) }
27-
// unsafe { virtualize_my_trait(L, &self.0) } // <-- this code fixes the problem
27+
// unsafe { virtualize_my_trait(L, &self.0) } // <-- this code fixes the problem
2828
}
2929
}
3030

tests/ui/issues/issue-21174.stderr

Lines changed: 2 additions & 2 deletions
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.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct S {
88
}
99

1010
const C: S = unsafe { std::mem::transmute(()) };
11+
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
1112
const _: [(); {
1213
C;
1314
0

0 commit comments

Comments
 (0)