Skip to content

Commit a593728

Browse files
committed
make layout check a mere sanity check
1 parent 5e5ae8b commit a593728

File tree

2 files changed

+13
-22
lines changed

2 files changed

+13
-22
lines changed

src/librustc_mir/interpret/eval_context.rs

+7-18
Original file line numberDiff line numberDiff line change
@@ -225,28 +225,17 @@ pub(super) fn mir_assign_valid_types<'tcx>(
225225
src: TyAndLayout<'tcx>,
226226
dest: TyAndLayout<'tcx>,
227227
) -> bool {
228-
if src.ty == dest.ty {
229-
// Equal types, all is good. Layout will also be equal.
230-
// (Enum variants would be an exception here as they have the type of the enum but different layout.
231-
// However, those are never the type of an assignment.)
232-
return true;
233-
}
234-
if src.layout != dest.layout {
235-
// Layout differs, definitely not equal.
236-
// We do this here because Miri would *do the wrong thing* if we allowed layout-changing
237-
// assignments.
238-
return false;
239-
}
240-
241228
// Type-changing assignments can happen when subtyping is used. While
242229
// all normal lifetimes are erased, higher-ranked types with their
243230
// late-bound lifetimes are still around and can lead to type
244231
// differences. So we compare ignoring lifetimes.
245-
//
246-
// Note that this is not fully correct (FIXME):
247-
// lifetimes in invariant positions could matter (e.g. through associated types).
248-
// We rely on the fact that layout was confirmed to be equal above.
249-
equal_up_to_regions(tcx, param_env, src.ty, dest.ty)
232+
if equal_up_to_regions(tcx, param_env, src.ty, dest.ty) {
233+
// Make sure the layout is equal, too -- just to be safe. Miri really needs layout equality.
234+
assert_eq!(src.layout, dest.layout);
235+
true
236+
} else {
237+
false
238+
}
250239
}
251240

252241
/// Use the already known layout if given (but sanity check in debug mode),

src/librustc_mir/transform/validate.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ pub fn equal_up_to_regions(
4444
src: Ty<'tcx>,
4545
dest: Ty<'tcx>,
4646
) -> bool {
47+
// Fast path.
48+
if src == dest {
49+
return true;
50+
}
51+
4752
struct LifetimeIgnoreRelation<'tcx> {
4853
tcx: TyCtxt<'tcx>,
4954
param_env: ty::ParamEnv<'tcx>,
@@ -176,6 +181,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
176181
/// Check if src can be assigned into dest.
177182
/// This is not precise, it will accept some incorrect assignments.
178183
fn mir_assign_valid_types(&self, src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
184+
// Fast path before we normalize.
179185
if src == dest {
180186
// Equal types, all is good.
181187
return true;
@@ -186,10 +192,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
186192
let param_env = self.param_env.with_reveal_all();
187193
let src = self.tcx.normalize_erasing_regions(param_env, src);
188194
let dest = self.tcx.normalize_erasing_regions(param_env, dest);
189-
// It's worth checking equality again.
190-
if src == dest {
191-
return true;
192-
}
193195

194196
// Type-changing assignments can happen when subtyping is used. While
195197
// all normal lifetimes are erased, higher-ranked types with their

0 commit comments

Comments
 (0)