Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf,
LayoutOfHelpers, TyAndLayout,
};
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypingEnv, Variance};
use rustc_middle::ty::{
self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv, Variance,
};
use rustc_middle::{mir, span_bug};
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
Expand Down Expand Up @@ -84,10 +86,31 @@ impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> {
#[inline]
fn handle_layout_err(
&self,
err: LayoutError<'tcx>,
mut err: LayoutError<'tcx>,
_: Span,
_: Ty<'tcx>,
) -> InterpErrorKind<'tcx> {
// FIXME(#149283): This is really hacky and is only used to hide type
// system bugs. We use it as a temporary fix for #149081.
//
// While it's expected that we sometimes get ambiguity errors when
// entering another generic environment while the current environment
// itself is still generic, we should never fail to entirely prove
// something.
match err {
LayoutError::NormalizationFailure(ty, _) => {
if ty.has_non_region_param() {
err = LayoutError::TooGeneric(ty);
}
}

LayoutError::Unknown(_)
| LayoutError::SizeOverflow(_)
| LayoutError::InvalidSimd { .. }
| LayoutError::TooGeneric(_)
| LayoutError::ReferencesError(_)
| LayoutError::Cycle(_) => {}
}
err_inval!(Layout(err))
}
}
Expand All @@ -112,7 +135,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span.
/// See [LayoutOf::layout_of] for the original documentation.
#[inline(always)]
pub fn layout_of(&self, ty: Ty<'tcx>) -> <Self as LayoutOfHelpers<'tcx>>::LayoutOfResult {
pub fn layout_of(&self, ty: Ty<'tcx>) -> Result<TyAndLayout<'tcx>, InterpErrorKind<'tcx>> {
let _trace = enter_trace_span!(M, layouting::layout_of, ty = ?ty.kind());
LayoutOf::layout_of(self, ty)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ compile-flags: -Copt-level=3 --crate-type=rlib
//@ build-pass

// A regression test for #149081. The environment of `size` and `align`
// currently means that the item bound of`T::Assoc` doesn't hold. This can
// result in normalization failures and ICE during MIR optimizations.
//
// This will no longer be an issue once #149283 is implemented.

pub fn align<T: WithAssoc<Assoc = U>, U>() -> usize {
std::mem::align_of::<Wrapper<T>>()
}

pub fn size<T: WithAssoc<Assoc = U>, U>() -> usize {
std::mem::size_of::<Wrapper<T>>()
}

pub struct Wrapper<T: WithAssoc> {
assoc2: <T::Assoc as WithAssoc>::Assoc,
value: T,
}

pub trait WithAssoc {
type Assoc: WithAssoc;
}
Loading