Skip to content

Commit 04732d4

Browse files
committed
Auto merge of #151295 - Zalathar:const-to-pat, r=<try>
THIR patterns: Use `ty::Value` in more places throughout `const_to_pat`
2 parents 3d087e6 + 97603c0 commit 04732d4

File tree

1 file changed

+39
-46
lines changed

1 file changed

+39
-46
lines changed

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

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use rustc_infer::traits::Obligation;
1313
use rustc_middle::mir::interpret::ErrorHandled;
1414
use rustc_middle::span_bug;
1515
use rustc_middle::thir::{FieldPat, Pat, PatKind};
16-
use rustc_middle::ty::{
17-
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, ValTree,
18-
};
16+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitableExt, TypeVisitor};
1917
use rustc_span::def_id::DefId;
2018
use rustc_span::{DUMMY_SP, Span};
2119
use rustc_trait_selection::traits::ObligationCause;
@@ -48,7 +46,7 @@ impl<'tcx> PatCtxt<'tcx> {
4846

4947
match c.kind() {
5048
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
51-
ty::ConstKind::Value(cv) => convert.valtree_to_pat(cv.valtree, cv.ty),
49+
ty::ConstKind::Value(value) => convert.valtree_to_pat(value),
5250
_ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c),
5351
}
5452
}
@@ -175,7 +173,7 @@ impl<'tcx> ConstToPat<'tcx> {
175173
};
176174

177175
// Lower the valtree to a THIR pattern.
178-
let mut thir_pat = self.valtree_to_pat(valtree, ty);
176+
let mut thir_pat = self.valtree_to_pat(ty::Value { ty, valtree });
179177

180178
if !thir_pat.references_error() {
181179
// Always check for `PartialEq` if we had no other errors yet.
@@ -192,31 +190,32 @@ impl<'tcx> ConstToPat<'tcx> {
192190
thir_pat
193191
}
194192

195-
fn field_pats(
193+
fn lower_field_values_to_fieldpats(
196194
&self,
197-
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
195+
values: impl Iterator<Item = ty::Value<'tcx>>,
198196
) -> Vec<FieldPat<'tcx>> {
199-
vals.enumerate()
200-
.map(|(idx, (val, ty))| {
201-
let field = FieldIdx::new(idx);
202-
// Patterns can only use monomorphic types.
203-
let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);
204-
FieldPat { field, pattern: *self.valtree_to_pat(val, ty) }
197+
values
198+
.enumerate()
199+
.map(|(index, value)| FieldPat {
200+
field: FieldIdx::new(index),
201+
pattern: *self.valtree_to_pat(value),
205202
})
206203
.collect()
207204
}
208205

209206
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
210-
// FIXME(valtrees): Accept `ty::Value` instead of `Ty` and `ty::ValTree` separately.
211207
#[instrument(skip(self), level = "debug")]
212-
fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
208+
fn valtree_to_pat(&self, value: ty::Value<'tcx>) -> Box<Pat<'tcx>> {
213209
let span = self.span;
214210
let tcx = self.tcx;
211+
let ty::Value { ty, valtree } = value;
212+
215213
let kind = match ty.kind() {
214+
// Extremely important check for all ADTs!
215+
// Make sure they are eligible to be used in patterns, and if not, emit an error.
216216
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
217-
// Extremely important check for all ADTs! Make sure they opted-in to be used in
218-
// patterns.
219-
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
217+
// This ADT cannot be used as a constant in patterns.
218+
debug!(?adt_def, ?value.ty, "ADT type in pattern is not `type_marked_structural`");
220219
let PartialEqImplStatus {
221220
is_derived, structural_partial_eq, non_blanket_impl, ..
222221
} = type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
@@ -239,51 +238,43 @@ impl<'tcx> ConstToPat<'tcx> {
239238
return self.mk_err(tcx.dcx().create_err(err), ty);
240239
}
241240
ty::Adt(adt_def, args) if adt_def.is_enum() => {
242-
let (&variant_index, fields) = cv.to_branch().split_first().unwrap();
241+
let (&variant_index, fields) = valtree.to_branch().split_first().unwrap();
243242
let variant_index = VariantIdx::from_u32(variant_index.to_leaf().to_u32());
244243
PatKind::Variant {
245244
adt_def: *adt_def,
246245
args,
247246
variant_index,
248-
subpatterns: self.field_pats(
249-
fields.iter().map(|ct| ct.to_value().valtree).zip(
250-
adt_def.variants()[variant_index]
251-
.fields
252-
.iter()
253-
.map(|field| field.ty(tcx, args)),
254-
),
255-
),
247+
subpatterns: self
248+
.lower_field_values_to_fieldpats(fields.iter().map(|ct| ct.to_value())),
256249
}
257250
}
258-
ty::Adt(def, args) => {
251+
ty::Adt(def, _) => {
259252
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
260253
PatKind::Leaf {
261-
subpatterns: self.field_pats(
262-
cv.to_branch().iter().map(|ct| ct.to_value().valtree).zip(
263-
def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)),
264-
),
254+
subpatterns: self.lower_field_values_to_fieldpats(
255+
valtree.to_branch().iter().map(|ct| ct.to_value()),
265256
),
266257
}
267258
}
268-
ty::Tuple(fields) => PatKind::Leaf {
269-
subpatterns: self.field_pats(
270-
cv.to_branch().iter().map(|ct| ct.to_value().valtree).zip(fields.iter()),
259+
ty::Tuple(_) => PatKind::Leaf {
260+
subpatterns: self.lower_field_values_to_fieldpats(
261+
valtree.to_branch().iter().map(|ct| ct.to_value()),
271262
),
272263
},
273-
ty::Slice(elem_ty) => PatKind::Slice {
274-
prefix: cv
264+
ty::Slice(_) => PatKind::Slice {
265+
prefix: valtree
275266
.to_branch()
276267
.iter()
277-
.map(|val| *self.valtree_to_pat(val.to_value().valtree, *elem_ty))
268+
.map(|val| *self.valtree_to_pat(val.to_value()))
278269
.collect(),
279270
slice: None,
280271
suffix: Box::new([]),
281272
},
282-
ty::Array(elem_ty, _) => PatKind::Array {
283-
prefix: cv
273+
ty::Array(_, _) => PatKind::Array {
274+
prefix: valtree
284275
.to_branch()
285276
.iter()
286-
.map(|val| *self.valtree_to_pat(val.to_value().valtree, *elem_ty))
277+
.map(|val| *self.valtree_to_pat(val.to_value()))
287278
.collect(),
288279
slice: None,
289280
suffix: Box::new([]),
@@ -296,15 +287,17 @@ impl<'tcx> ConstToPat<'tcx> {
296287
// Under `feature(deref_patterns)`, string literal patterns can also
297288
// have type `str` directly, without the `&`, in order to allow things
298289
// like `deref!("...")` to work when the scrutinee is `String`.
299-
PatKind::Constant { value: ty::Value { ty, valtree: cv } }
290+
PatKind::Constant { value }
300291
}
301292
ty::Ref(_, pointee_ty, ..) => {
302293
if pointee_ty.is_str()
303294
|| pointee_ty.is_slice()
304295
|| pointee_ty.is_sized(tcx, self.typing_env)
305296
{
306297
// References have the same valtree representation as their pointee.
307-
PatKind::Deref { subpattern: self.valtree_to_pat(cv, *pointee_ty) }
298+
PatKind::Deref {
299+
subpattern: self.valtree_to_pat(ty::Value { ty: *pointee_ty, valtree }),
300+
}
308301
} else {
309302
return self.mk_err(
310303
tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }),
@@ -313,7 +306,7 @@ impl<'tcx> ConstToPat<'tcx> {
313306
}
314307
}
315308
ty::Float(flt) => {
316-
let v = cv.to_leaf();
309+
let v = valtree.to_leaf();
317310
let is_nan = match flt {
318311
ty::FloatTy::F16 => v.to_f16().is_nan(),
319312
ty::FloatTy::F32 => v.to_f32().is_nan(),
@@ -325,13 +318,13 @@ impl<'tcx> ConstToPat<'tcx> {
325318
// Also see <https://github.com/rust-lang/rfcs/pull/3535>.
326319
return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty);
327320
} else {
328-
PatKind::Constant { value: ty::Value { ty, valtree: cv } }
321+
PatKind::Constant { value }
329322
}
330323
}
331324
ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
332325
// The raw pointers we see here have been "vetted" by valtree construction to be
333326
// just integers, so we simply allow them.
334-
PatKind::Constant { value: ty::Value { ty, valtree: cv } }
327+
PatKind::Constant { value }
335328
}
336329
ty::FnPtr(..) => {
337330
unreachable!(

0 commit comments

Comments
 (0)