@@ -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.
169168pub ( 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