diff options
| author | FedericoBruzzone <federico.bruzzone.i@gmail.com> | 2025-01-06 11:39:07 +0100 |
|---|---|---|
| committer | FedericoBruzzone <federico.bruzzone.i@gmail.com> | 2025-01-27 00:37:34 +0100 |
| commit | cef97bce7b2a0e6ef2208aaa1ec267b800d646af (patch) | |
| tree | 3bc712129173e067edf350690dac3b3ade8f2f63 /compiler | |
| parent | 15c6f7e1a3a0e51c9b18ce5b9a391e0c324b751c (diff) | |
Add `TooGeneric` variant to `LayoutError` and emit `Unknown` one
- `check-pass` test for a MRE of #135020 - fail test for #135138 - switch to `TooGeneric` for checking CMSE fn signatures - switch to `TooGeneric` for compute `SizeSkeleton` (for transmute) - fix broken tests
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/error.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/intrinsicck.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/error.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_transmute/src/layout/tree.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/layout.rs | 69 |
8 files changed, 75 insertions, 27 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index fee7287951d..cc21a18af3a 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -140,7 +140,7 @@ where // Don't emit a new diagnostic for these errors, they are already reported elsewhere or // should remain silent. err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span), - err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { + err_inval!(Layout(LayoutError::TooGeneric(_))) | err_inval!(TooGeneric) => { ErrorHandled::TooGeneric(span) } err_inval!(Layout(LayoutError::ReferencesError(guar))) => { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 39471931461..4c8f2735b97 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -201,7 +201,7 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError use LayoutError::*; match layout_err { - Unknown(ty) => { + TooGeneric(ty) => { match abi { ExternAbi::CCmseNonSecureCall => { // prevent double reporting of this error @@ -211,7 +211,11 @@ fn should_emit_generic_error<'tcx>(abi: ExternAbi, layout_err: &'tcx LayoutError _ => bug!("invalid ABI: {abi}"), } } - SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => { + Unknown(..) + | SizeOverflow(..) + | NormalizationFailure(..) + | ReferencesError(..) + | Cycle(..) => { false // not our job to report these } } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index f4929aae599..54e9e699353 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("generic size {size}") } } - Err(LayoutError::Unknown(bad)) => { + Err(LayoutError::TooGeneric(bad)) => { if *bad == ty { "this type does not have a fixed size".to_owned() } else { diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 5dd85978f00..8dc529b4d7a 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -100,6 +100,8 @@ middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute +middle_too_generic = `{$ty}` does not have a fixed size + middle_type_length_limit = reached the type-length limit while instantiating `{$shrunk}` middle_unknown_layout = @@ -107,4 +109,5 @@ middle_unknown_layout = middle_values_too_big = values of the type `{$ty}` are too big for the target architecture + middle_written_to_path = the full type name has been written to '{$path}' diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 6300d856393..b0187a1848c 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -129,6 +129,9 @@ pub enum LayoutError<'tcx> { #[diag(middle_unknown_layout)] Unknown { ty: Ty<'tcx> }, + #[diag(middle_too_generic)] + TooGeneric { ty: Ty<'tcx> }, + #[diag(middle_values_too_big)] Overflow { ty: Ty<'tcx> }, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 1e67cdfc32a..0d41a1d7dbf 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -231,6 +231,7 @@ impl fmt::Display for ValidityRequirement { pub enum LayoutError<'tcx> { Unknown(Ty<'tcx>), SizeOverflow(Ty<'tcx>), + TooGeneric(Ty<'tcx>), NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), ReferencesError(ErrorGuaranteed), Cycle(ErrorGuaranteed), @@ -244,6 +245,7 @@ impl<'tcx> LayoutError<'tcx> { match self { Unknown(_) => middle_unknown_layout, SizeOverflow(_) => middle_values_too_big, + TooGeneric(_) => middle_too_generic, NormalizationFailure(_, _) => middle_cannot_be_normalized, Cycle(_) => middle_cycle, ReferencesError(_) => middle_layout_references_error, @@ -257,6 +259,7 @@ impl<'tcx> LayoutError<'tcx> { match self { Unknown(ty) => E::Unknown { ty }, SizeOverflow(ty) => E::Overflow { ty }, + TooGeneric(ty) => E::TooGeneric { ty }, NormalizationFailure(ty, e) => { E::NormalizationFailure { ty, failure_ty: e.get_type_for_failure() } } @@ -272,6 +275,9 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { LayoutError::Unknown(ty) => write!(f, "the type `{ty}` has an unknown layout"), + LayoutError::TooGeneric(ty) => { + write!(f, "`{ty}` does not have a fixed size") + } LayoutError::SizeOverflow(ty) => { write!(f, "values of the type `{ty}` are too big for the target architecture") } @@ -350,10 +356,11 @@ impl<'tcx> SizeSkeleton<'tcx> { return Err(tcx.arena.alloc(LayoutError::Unknown(ty))); } } - Err(err @ LayoutError::Unknown(_)) => err, + Err(err @ LayoutError::TooGeneric(_)) => err, // We can't extract SizeSkeleton info from other layout errors Err( e @ LayoutError::Cycle(_) + | e @ LayoutError::Unknown(_) | e @ LayoutError::SizeOverflow(_) | e @ LayoutError::NormalizationFailure(..) | e @ LayoutError::ReferencesError(_), @@ -413,10 +420,9 @@ impl<'tcx> SizeSkeleton<'tcx> { // Alignment is unchanged by arrays. return Ok(SizeSkeleton::Known(Size::from_bytes(size), a)); } - Err(tcx.arena.alloc(LayoutError::Unknown(ty))) + Err(err) } - SizeSkeleton::Pointer { .. } => Err(err), - SizeSkeleton::Generic(_) => Err(tcx.arena.alloc(LayoutError::Unknown(ty))), + SizeSkeleton::Pointer { .. } | SizeSkeleton::Generic(_) => Err(err), } } diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 6ce9969aefe..b00585d2922 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -197,6 +197,7 @@ pub(crate) mod rustc { match err { LayoutError::Unknown(..) | LayoutError::ReferencesError(..) + | LayoutError::TooGeneric(..) | LayoutError::NormalizationFailure(..) => Self::UnknownLayout, LayoutError::SizeOverflow(..) => Self::SizeOverflow, LayoutError::Cycle(err) => Self::TypeError(*err), diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 17be0bd0ab9..a04c7536118 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -104,14 +104,12 @@ fn map_error<'tcx>( // This is sometimes not a compile error if there are trivially false where clauses. // See `tests/ui/layout/trivial-bounds-sized.rs` for an example. assert!(field.layout.is_unsized(), "invalid layout error {err:#?}"); - if !field.ty.is_sized(cx.tcx(), cx.typing_env) { - let guar = cx.tcx().dcx().delayed_bug(format!( + if cx.typing_env.param_env.caller_bounds().is_empty() { + cx.tcx().dcx().delayed_bug(format!( "encountered unexpected unsized field in layout of {ty:?}: {field:#?}" )); - LayoutError::ReferencesError(guar) - } else { - LayoutError::Unknown(ty) } + LayoutError::Unknown(ty) } LayoutCalculatorError::EmptyUnion => { // This is always a compile error. @@ -146,6 +144,35 @@ fn univariant_uninterned<'tcx>( cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err)) } +fn validate_const_with_value<'tcx>( + const_: ty::Const<'tcx>, + ty: Ty<'tcx>, + cx: &LayoutCx<'tcx>, +) -> Result<ty::Const<'tcx>, &'tcx LayoutError<'tcx>> { + match const_.kind() { + ty::ConstKind::Value(..) => Ok(const_), + ty::ConstKind::Error(guar) => { + return Err(error(cx, LayoutError::ReferencesError(guar))); + } + ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) => { + if !const_.has_param() { + bug!("no generic type found in the type: {ty:?}"); + } + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + ty::ConstKind::Unevaluated(_) => { + if !const_.has_param() { + return Err(error(cx, LayoutError::Unknown(ty))); + } else { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + } + ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { + bug!("unexpected type: {ty:?}"); + } + } +} + fn layout_of_uncached<'tcx>( cx: &LayoutCx<'tcx>, ty: Ty<'tcx>, @@ -182,12 +209,13 @@ fn layout_of_uncached<'tcx>( &mut layout.backend_repr { if let Some(start) = start { - scalar.valid_range_mut().start = start - .try_to_bits(tcx, cx.typing_env) - .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + scalar.valid_range_mut().start = + validate_const_with_value(start, ty, cx)? + .try_to_bits(tcx, cx.typing_env) + .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { - let mut end = end + let mut end = validate_const_with_value(end, ty, cx)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { @@ -319,17 +347,13 @@ fn layout_of_uncached<'tcx>( } // Arrays and slices. - ty::Array(element, mut count) => { - if count.has_aliases() { - count = tcx.normalize_erasing_regions(cx.typing_env, count); - if count.has_aliases() { - return Err(error(cx, LayoutError::Unknown(ty))); - } - } - - let count = count + ty::Array(element, count) => { + let count = validate_const_with_value(count, ty, cx)? + .to_valtree() + .0 .try_to_target_usize(tcx) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; + let element = cx.layout_of(element)?; let size = element .size @@ -687,6 +711,9 @@ fn layout_of_uncached<'tcx>( // Types with no meaningful known layout. ty::Alias(..) => { + if ty.has_param() { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } // NOTE(eddyb) `layout_of` query should've normalized these away, // if that was possible, so there's no reason to try again here. return Err(error(cx, LayoutError::Unknown(ty))); @@ -696,7 +723,11 @@ fn layout_of_uncached<'tcx>( bug!("Layout::compute: unexpected type `{}`", ty) } - ty::Placeholder(..) | ty::Param(_) => { + ty::Param(_) => { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + + ty::Placeholder(..) => { return Err(error(cx, LayoutError::Unknown(ty))); } }) |
