Skip to content

Commit ab617ae

Browse files
committed
interpret: improve assignment type validity check and error messages
1 parent e22c616 commit ab617ae

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,25 +165,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
165165
}
166166

167167
/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
168-
/// This test should be symmetric, as it is primarily about layout compatibility.
169168
pub(super) fn mir_assign_valid_types<'tcx>(
170169
tcx: TyCtxt<'tcx>,
171170
typing_env: TypingEnv<'tcx>,
172171
src: TyAndLayout<'tcx>,
173172
dest: TyAndLayout<'tcx>,
174173
) -> bool {
175-
// Type-changing assignments can happen when subtyping is used. While
176-
// all normal lifetimes are erased, higher-ranked types with their
177-
// late-bound lifetimes are still around and can lead to type
178-
// differences.
174+
// We *could* check `Invariant` here since all subtyping must be explicit post-borrowck.
175+
// However, this check is also used by the interpreter to figure out if a transmute can be
176+
// turned into a regular assignment (which has a more efficient codepath), so we want the check
177+
// to consider as many assignments as possible to be valid. Therefore we are happy to accept
178+
// one-way subtyping.
179179
if util::relate_types(tcx, typing_env, Variance::Covariant, src.ty, dest.ty) {
180-
// Make sure the layout is equal, too -- just to be safe. Miri really
181-
// needs layout equality. For performance reason we skip this check when
182-
// the types are equal. Equal types *can* have different layouts when
183-
// enum downcast is involved (as enum variants carry the type of the
184-
// enum), but those should never occur in assignments.
180+
// Make sure the layout is equal, too -- just to be safe. Miri really needs layout equality.
181+
// For performance reason we skip this check when the types are equal. Equal types *can*
182+
// have different layouts when enum downcast is involved (as enum variants carry the type of
183+
// the enum), but those should never occur in assignments.
185184
if cfg!(debug_assertions) || src.ty != dest.ty {
186-
assert_eq!(src.layout, dest.layout);
185+
assert_eq!(
186+
src.layout,
187+
dest.layout,
188+
"{src} is a subtype of {dest} but they have different layout",
189+
src = src.ty,
190+
dest = dest.ty,
191+
);
187192
}
188193
true
189194
} else {

0 commit comments

Comments
 (0)