Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1b1b6ea

Browse files
committed
Remove the "lift constant to reference" logic
1 parent f12583a commit 1b1b6ea

File tree

2 files changed

+28
-46
lines changed

2 files changed

+28
-46
lines changed

compiler/rustc_mir_build/src/build/matches/test.rs

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -409,40 +409,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
409409

410410
let deref_ty = match *ty.kind() {
411411
ty::Ref(_, deref_ty, _) => deref_ty,
412-
_ => {
413-
trace!("non_scalar_compare called on non-reference type: {}", ty);
414-
// Backcompat hack: due to non-structural matches not being a hard error, we can
415-
// reach this for types that have manual `Eq` or `PartialEq` impls.
416-
assert!(!ty.is_structural_eq_shallow(self.hir.tcx()));
417-
let ref_ty = self.hir.tcx().mk_imm_ref(self.hir.tcx().lifetimes.re_erased, ty);
418-
// let y = &place;
419-
let y = self.temp(ref_ty, source_info.span);
420-
self.cfg.push_assign(
421-
block,
422-
source_info,
423-
y,
424-
Rvalue::Ref(self.hir.tcx().lifetimes.re_erased, BorrowKind::Shared, place),
425-
);
426-
val = Operand::Move(y);
427-
// let temp = expect;
428-
let temp = self.temp(ty, source_info.span);
429-
self.cfg.push_assign(
430-
block,
431-
source_info,
432-
temp,
433-
Rvalue::Use(expect),
434-
);
435-
// reftemp = &temp;
436-
let reftemp = self.temp(ref_ty, source_info.span);
437-
self.cfg.push_assign(
438-
block,
439-
source_info,
440-
reftemp,
441-
Rvalue::Ref(self.hir.tcx().lifetimes.re_erased, BorrowKind::Shared, temp),
442-
);
443-
expect = Operand::Move(reftemp);
444-
ty
445-
},
412+
_ => bug!("non_scalar_compare called on non-reference type: {}", ty),
446413
};
447414

448415
let eq_def_id = self.hir.tcx().require_lang_item(LangItem::PartialEq, None);

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ struct ConstToPat<'a, 'tcx> {
5858
include_lint_checks: bool,
5959
}
6060

61+
#[derive(Debug)]
62+
struct FallbackToConstRef;
63+
6164
impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
6265
fn new(
6366
pat_ctxt: &PatCtxt<'_, 'tcx>,
@@ -103,7 +106,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
103106
// once indirect_structural_match is a full fledged error, this
104107
// level of indirection can be eliminated
105108

106-
let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation);
109+
let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation).unwrap();
107110

108111
if self.include_lint_checks && !self.saw_const_match_error.get() {
109112
// If we were able to successfully convert the const to some pat,
@@ -216,18 +219,22 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
216219
}
217220

218221
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
219-
fn recur(&self, cv: &'tcx ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> {
222+
fn recur(
223+
&self,
224+
cv: &'tcx ty::Const<'tcx>,
225+
mir_structural_match_violation: bool,
226+
) -> Result<Pat<'tcx>, FallbackToConstRef> {
220227
let id = self.id;
221228
let span = self.span;
222229
let tcx = self.tcx();
223230
let param_env = self.param_env;
224231

225-
let field_pats = |vals: &[&'tcx ty::Const<'tcx>]| {
232+
let field_pats = |vals: &[&'tcx ty::Const<'tcx>]| -> Result<_, _> {
226233
vals.iter()
227234
.enumerate()
228235
.map(|(idx, val)| {
229236
let field = Field::new(idx);
230-
FieldPat { field, pattern: self.recur(val, false) }
237+
Ok(FieldPat { field, pattern: self.recur(val, false)? })
231238
})
232239
.collect()
233240
};
@@ -287,7 +294,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
287294
|lint| lint.build(&msg).emit(),
288295
);
289296
}
290-
PatKind::Constant { value: cv }
297+
// Since we are behind a reference, we can just bubble the error up so we get a
298+
// constant at reference type, making it easy to let the fallback call
299+
// `PartialEq::eq` on it.
300+
return Err(FallbackToConstRef);
291301
}
292302
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
293303
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, cv.ty);
@@ -309,20 +319,20 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
309319
variant_index: destructured
310320
.variant
311321
.expect("destructed const of adt without variant id"),
312-
subpatterns: field_pats(destructured.fields),
322+
subpatterns: field_pats(destructured.fields)?,
313323
}
314324
}
315325
ty::Tuple(_) | ty::Adt(_, _) => {
316326
let destructured = tcx.destructure_const(param_env.and(cv));
317-
PatKind::Leaf { subpatterns: field_pats(destructured.fields) }
327+
PatKind::Leaf { subpatterns: field_pats(destructured.fields)? }
318328
}
319329
ty::Array(..) => PatKind::Array {
320330
prefix: tcx
321331
.destructure_const(param_env.and(cv))
322332
.fields
323333
.iter()
324334
.map(|val| self.recur(val, false))
325-
.collect(),
335+
.collect::<Result<_, _>>()?,
326336
slice: None,
327337
suffix: Vec::new(),
328338
},
@@ -355,7 +365,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
355365
.fields
356366
.iter()
357367
.map(|val| self.recur(val, false))
358-
.collect(),
368+
.collect::<Result<_, _>>()?,
359369
slice: None,
360370
suffix: vec![],
361371
}),
@@ -379,8 +389,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
379389
// deref pattern.
380390
_ => {
381391
let old = self.behind_reference.replace(true);
382-
let val = PatKind::Deref {
383-
subpattern: self.recur(tcx.deref_const(self.param_env.and(cv)), false),
392+
// In case there are structural-match violations somewhere in this subpattern,
393+
// we fall back to a const pattern. If we do not do this, we may end up with
394+
// a !structural-match constant that is not of reference type, which makes it
395+
// very hard to invoke `PartialEq::eq` on it as a fallback.
396+
let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
397+
Ok(subpattern) => PatKind::Deref { subpattern },
398+
Err(FallbackToConstRef) => PatKind::Constant { value: cv },
384399
};
385400
self.behind_reference.set(old);
386401
val
@@ -439,6 +454,6 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
439454
);
440455
}
441456

442-
Pat { span, ty: cv.ty, kind: Box::new(kind) }
457+
Ok(Pat { span, ty: cv.ty, kind: Box::new(kind) })
443458
}
444459
}

0 commit comments

Comments
 (0)