Remove the "lift constant to reference" logic
This commit is contained in:
parent
f12583a330
commit
1b1b6eabaa
2 changed files with 28 additions and 46 deletions
|
@ -409,40 +409,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
|
||||||
let deref_ty = match *ty.kind() {
|
let deref_ty = match *ty.kind() {
|
||||||
ty::Ref(_, deref_ty, _) => deref_ty,
|
ty::Ref(_, deref_ty, _) => deref_ty,
|
||||||
_ => {
|
_ => bug!("non_scalar_compare called on non-reference type: {}", ty),
|
||||||
trace!("non_scalar_compare called on non-reference type: {}", ty);
|
|
||||||
// Backcompat hack: due to non-structural matches not being a hard error, we can
|
|
||||||
// reach this for types that have manual `Eq` or `PartialEq` impls.
|
|
||||||
assert!(!ty.is_structural_eq_shallow(self.hir.tcx()));
|
|
||||||
let ref_ty = self.hir.tcx().mk_imm_ref(self.hir.tcx().lifetimes.re_erased, ty);
|
|
||||||
// let y = &place;
|
|
||||||
let y = self.temp(ref_ty, source_info.span);
|
|
||||||
self.cfg.push_assign(
|
|
||||||
block,
|
|
||||||
source_info,
|
|
||||||
y,
|
|
||||||
Rvalue::Ref(self.hir.tcx().lifetimes.re_erased, BorrowKind::Shared, place),
|
|
||||||
);
|
|
||||||
val = Operand::Move(y);
|
|
||||||
// let temp = expect;
|
|
||||||
let temp = self.temp(ty, source_info.span);
|
|
||||||
self.cfg.push_assign(
|
|
||||||
block,
|
|
||||||
source_info,
|
|
||||||
temp,
|
|
||||||
Rvalue::Use(expect),
|
|
||||||
);
|
|
||||||
// reftemp = &temp;
|
|
||||||
let reftemp = self.temp(ref_ty, source_info.span);
|
|
||||||
self.cfg.push_assign(
|
|
||||||
block,
|
|
||||||
source_info,
|
|
||||||
reftemp,
|
|
||||||
Rvalue::Ref(self.hir.tcx().lifetimes.re_erased, BorrowKind::Shared, temp),
|
|
||||||
);
|
|
||||||
expect = Operand::Move(reftemp);
|
|
||||||
ty
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let eq_def_id = self.hir.tcx().require_lang_item(LangItem::PartialEq, None);
|
let eq_def_id = self.hir.tcx().require_lang_item(LangItem::PartialEq, None);
|
||||||
|
|
|
@ -58,6 +58,9 @@ struct ConstToPat<'a, 'tcx> {
|
||||||
include_lint_checks: bool,
|
include_lint_checks: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct FallbackToConstRef;
|
||||||
|
|
||||||
impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
pat_ctxt: &PatCtxt<'_, 'tcx>,
|
pat_ctxt: &PatCtxt<'_, 'tcx>,
|
||||||
|
@ -103,7 +106,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
// once indirect_structural_match is a full fledged error, this
|
// once indirect_structural_match is a full fledged error, this
|
||||||
// level of indirection can be eliminated
|
// level of indirection can be eliminated
|
||||||
|
|
||||||
let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation);
|
let inlined_const_as_pat = self.recur(cv, mir_structural_match_violation).unwrap();
|
||||||
|
|
||||||
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
||||||
// If we were able to successfully convert the const to some pat,
|
// If we were able to successfully convert the const to some pat,
|
||||||
|
@ -216,18 +219,22 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
|
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
|
||||||
fn recur(&self, cv: &'tcx ty::Const<'tcx>, mir_structural_match_violation: bool) -> Pat<'tcx> {
|
fn recur(
|
||||||
|
&self,
|
||||||
|
cv: &'tcx ty::Const<'tcx>,
|
||||||
|
mir_structural_match_violation: bool,
|
||||||
|
) -> Result<Pat<'tcx>, FallbackToConstRef> {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let param_env = self.param_env;
|
let param_env = self.param_env;
|
||||||
|
|
||||||
let field_pats = |vals: &[&'tcx ty::Const<'tcx>]| {
|
let field_pats = |vals: &[&'tcx ty::Const<'tcx>]| -> Result<_, _> {
|
||||||
vals.iter()
|
vals.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, val)| {
|
.map(|(idx, val)| {
|
||||||
let field = Field::new(idx);
|
let field = Field::new(idx);
|
||||||
FieldPat { field, pattern: self.recur(val, false) }
|
Ok(FieldPat { field, pattern: self.recur(val, false)? })
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
@ -287,7 +294,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
|lint| lint.build(&msg).emit(),
|
|lint| lint.build(&msg).emit(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
PatKind::Constant { value: cv }
|
// Since we are behind a reference, we can just bubble the error up so we get a
|
||||||
|
// constant at reference type, making it easy to let the fallback call
|
||||||
|
// `PartialEq::eq` on it.
|
||||||
|
return Err(FallbackToConstRef);
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
|
ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => {
|
||||||
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, cv.ty);
|
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, cv.ty);
|
||||||
|
@ -309,12 +319,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
variant_index: destructured
|
variant_index: destructured
|
||||||
.variant
|
.variant
|
||||||
.expect("destructed const of adt without variant id"),
|
.expect("destructed const of adt without variant id"),
|
||||||
subpatterns: field_pats(destructured.fields),
|
subpatterns: field_pats(destructured.fields)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Tuple(_) | ty::Adt(_, _) => {
|
ty::Tuple(_) | ty::Adt(_, _) => {
|
||||||
let destructured = tcx.destructure_const(param_env.and(cv));
|
let destructured = tcx.destructure_const(param_env.and(cv));
|
||||||
PatKind::Leaf { subpatterns: field_pats(destructured.fields) }
|
PatKind::Leaf { subpatterns: field_pats(destructured.fields)? }
|
||||||
}
|
}
|
||||||
ty::Array(..) => PatKind::Array {
|
ty::Array(..) => PatKind::Array {
|
||||||
prefix: tcx
|
prefix: tcx
|
||||||
|
@ -322,7 +332,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| self.recur(val, false))
|
.map(|val| self.recur(val, false))
|
||||||
.collect(),
|
.collect::<Result<_, _>>()?,
|
||||||
slice: None,
|
slice: None,
|
||||||
suffix: Vec::new(),
|
suffix: Vec::new(),
|
||||||
},
|
},
|
||||||
|
@ -355,7 +365,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| self.recur(val, false))
|
.map(|val| self.recur(val, false))
|
||||||
.collect(),
|
.collect::<Result<_, _>>()?,
|
||||||
slice: None,
|
slice: None,
|
||||||
suffix: vec![],
|
suffix: vec![],
|
||||||
}),
|
}),
|
||||||
|
@ -379,8 +389,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
// deref pattern.
|
// deref pattern.
|
||||||
_ => {
|
_ => {
|
||||||
let old = self.behind_reference.replace(true);
|
let old = self.behind_reference.replace(true);
|
||||||
let val = PatKind::Deref {
|
// In case there are structural-match violations somewhere in this subpattern,
|
||||||
subpattern: self.recur(tcx.deref_const(self.param_env.and(cv)), false),
|
// we fall back to a const pattern. If we do not do this, we may end up with
|
||||||
|
// a !structural-match constant that is not of reference type, which makes it
|
||||||
|
// very hard to invoke `PartialEq::eq` on it as a fallback.
|
||||||
|
let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
|
||||||
|
Ok(subpattern) => PatKind::Deref { subpattern },
|
||||||
|
Err(FallbackToConstRef) => PatKind::Constant { value: cv },
|
||||||
};
|
};
|
||||||
self.behind_reference.set(old);
|
self.behind_reference.set(old);
|
||||||
val
|
val
|
||||||
|
@ -439,6 +454,6 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pat { span, ty: cv.ty, kind: Box::new(kind) }
|
Ok(Pat { span, ty: cv.ty, kind: Box::new(kind) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue