Skip to content

Commit 335743e

Browse files
authored
Unrolled build for rust-lang#135158
Rollup merge of rust-lang#135158 - FedericoBruzzone:master, r=lukas-code Add `TooGeneric` variant to `LayoutError` and emit `Unknown` What's in this PR? - Add `TooGeneric` variant to `LayoutError` and emit `Unknown` one With this PR these issues and their respective ICEs are resolved: - fixes rust-lang#135020 - fixes rust-lang#135138
2 parents 633a3fe + cef97bc commit 335743e

29 files changed

+233
-58
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_hir_typeck/src/intrinsicck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
122122
format!("generic size {size}")
123123
}
124124
}
125-
Err(LayoutError::Unknown(bad)) => {
125+
Err(LayoutError::TooGeneric(bad)) => {
126126
if *bad == ty {
127127
"this type does not have a fixed size".to_owned()
128128
} else {

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

+10-4
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(_),
@@ -413,10 +420,9 @@ impl<'tcx> SizeSkeleton<'tcx> {
413420
// Alignment is unchanged by arrays.
414421
return Ok(SizeSkeleton::Known(Size::from_bytes(size), a));
415422
}
416-
Err(tcx.arena.alloc(LayoutError::Unknown(ty)))
423+
Err(err)
417424
}
418-
SizeSkeleton::Pointer { .. } => Err(err),
419-
SizeSkeleton::Generic(_) => Err(tcx.arena.alloc(LayoutError::Unknown(ty))),
425+
SizeSkeleton::Pointer { .. } | SizeSkeleton::Generic(_) => Err(err),
420426
}
421427
}
422428

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

+50-19
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.
@@ -146,6 +144,35 @@ fn univariant_uninterned<'tcx>(
146144
cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err))
147145
}
148146

147+
fn validate_const_with_value<'tcx>(
148+
const_: ty::Const<'tcx>,
149+
ty: Ty<'tcx>,
150+
cx: &LayoutCx<'tcx>,
151+
) -> Result<ty::Const<'tcx>, &'tcx LayoutError<'tcx>> {
152+
match const_.kind() {
153+
ty::ConstKind::Value(..) => Ok(const_),
154+
ty::ConstKind::Error(guar) => {
155+
return Err(error(cx, LayoutError::ReferencesError(guar)));
156+
}
157+
ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) => {
158+
if !const_.has_param() {
159+
bug!("no generic type found in the type: {ty:?}");
160+
}
161+
return Err(error(cx, LayoutError::TooGeneric(ty)));
162+
}
163+
ty::ConstKind::Unevaluated(_) => {
164+
if !const_.has_param() {
165+
return Err(error(cx, LayoutError::Unknown(ty)));
166+
} else {
167+
return Err(error(cx, LayoutError::TooGeneric(ty)));
168+
}
169+
}
170+
ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
171+
bug!("unexpected type: {ty:?}");
172+
}
173+
}
174+
}
175+
149176
fn layout_of_uncached<'tcx>(
150177
cx: &LayoutCx<'tcx>,
151178
ty: Ty<'tcx>,
@@ -182,12 +209,13 @@ fn layout_of_uncached<'tcx>(
182209
&mut layout.backend_repr
183210
{
184211
if let Some(start) = start {
185-
scalar.valid_range_mut().start = start
186-
.try_to_bits(tcx, cx.typing_env)
187-
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
212+
scalar.valid_range_mut().start =
213+
validate_const_with_value(start, ty, cx)?
214+
.try_to_bits(tcx, cx.typing_env)
215+
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
188216
}
189217
if let Some(end) = end {
190-
let mut end = end
218+
let mut end = validate_const_with_value(end, ty, cx)?
191219
.try_to_bits(tcx, cx.typing_env)
192220
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
193221
if !include_end {
@@ -319,17 +347,13 @@ fn layout_of_uncached<'tcx>(
319347
}
320348

321349
// Arrays and slices.
322-
ty::Array(element, mut count) => {
323-
if count.has_aliases() {
324-
count = tcx.normalize_erasing_regions(cx.typing_env, count);
325-
if count.has_aliases() {
326-
return Err(error(cx, LayoutError::Unknown(ty)));
327-
}
328-
}
329-
330-
let count = count
350+
ty::Array(element, count) => {
351+
let count = validate_const_with_value(count, ty, cx)?
352+
.to_valtree()
353+
.0
331354
.try_to_target_usize(tcx)
332355
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
356+
333357
let element = cx.layout_of(element)?;
334358
let size = element
335359
.size
@@ -687,6 +711,9 @@ fn layout_of_uncached<'tcx>(
687711

688712
// Types with no meaningful known layout.
689713
ty::Alias(..) => {
714+
if ty.has_param() {
715+
return Err(error(cx, LayoutError::TooGeneric(ty)));
716+
}
690717
// NOTE(eddyb) `layout_of` query should've normalized these away,
691718
// if that was possible, so there's no reason to try again here.
692719
return Err(error(cx, LayoutError::Unknown(ty)));
@@ -696,7 +723,11 @@ fn layout_of_uncached<'tcx>(
696723
bug!("Layout::compute: unexpected type `{}`", ty)
697724
}
698725

699-
ty::Placeholder(..) | ty::Param(_) => {
726+
ty::Param(_) => {
727+
return Err(error(cx, LayoutError::TooGeneric(ty)));
728+
}
729+
730+
ty::Placeholder(..) => {
700731
return Err(error(cx, LayoutError::Unknown(ty)));
701732
}
702733
})

src/librustdoc/html/templates/type_layout.html

+11-5
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,11 @@ <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
@@ -44,6 +42,14 @@ <h2 id="layout" class="section-header"> {# #}
4442
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
4543
the type was too big. {# #}
4644
</p>
45+
{# This kind of layout error can occur with valid code, e.g. if you try to
46+
get the layout of a generic type such as `Vec<T>`. #}
47+
{% when Err(LayoutError::TooGeneric(_)) %}
48+
<p> {# #}
49+
<strong>Note:</strong> Unable to compute type layout, {#+ #}
50+
possibly due to this type having generic parameters. {#+ #}
51+
Layout can only be computed for concrete, fully-instantiated types. {# #}
52+
</p>
4753
{% when Err(LayoutError::ReferencesError(_)) %}
4854
<p> {# #}
4955
<strong>Note:</strong> Encountered an error during type layout; {#+ #}

tests/crashes/135020.rs

-11
This file was deleted.

tests/rustdoc/type-layout.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ pub struct Y(u8);
3737
pub struct Z;
3838

3939
// We can't compute layout for generic types.
40-
//@ hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters'
40+
//@ hasraw type_layout/struct.Generic.html 'Unable to compute type layout, possibly due to this type having generic parameters.'
41+
//@ hasraw type_layout/struct.Generic.html 'Layout can only be computed for concrete, fully-instantiated types.'
4142
//@ !hasraw - 'Size: '
4243
pub struct Generic<T>(T);
4344

@@ -91,3 +92,9 @@ pub enum Uninhabited {}
9192
//@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
9293
//@ hasraw - '8 bytes (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)'
9394
pub struct Uninhabited2(std::convert::Infallible, u64);
95+
96+
pub trait Project { type Assoc; }
97+
// We can't compute layout. A `LayoutError::Unknown` is returned.
98+
//@ hasraw type_layout/struct.Unknown.html 'Unable to compute type layout.'
99+
//@ !hasraw - 'Size: '
100+
pub struct Unknown(<() as Project>::Assoc) where for<'a> (): Project;

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

+1-1
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

+9-3
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

+1-1
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/layout/base-layout-is-sized-ice-123078.rs

+1
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

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

+12-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ help: the `Box` type always has a statically known size and allocates its conten
1616
LL | a: Box<[u8]>,
1717
| ++++ +
1818

19-
error: aborting due to 1 previous error
19+
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
20+
--> $DIR/base-layout-is-sized-ice-123078.rs:10:23
21+
|
22+
LL | const C: S = unsafe { std::mem::transmute(()) };
23+
| ^^^^^^^^^^^^^^^^^^^
24+
|
25+
= note: source type: `()` (0 bits)
26+
= note: target type: `S` (the type `S` has an unknown layout)
27+
28+
error: aborting due to 2 previous errors
2029

21-
For more information about this error, try `rustc --explain E0277`.
30+
Some errors have detailed explanations: E0277, E0512.
31+
For more information about an error, try `rustc --explain E0277`.

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`.

0 commit comments

Comments
 (0)