Skip to content

Commit 1881a15

Browse files
committed
Fix old FIXMEs referring to rust-lang#19596
1 parent 96834f0 commit 1881a15

File tree

2 files changed

+95
-118
lines changed

2 files changed

+95
-118
lines changed

compiler/rustc_hir/src/hir.rs

+18-28
Original file line numberDiff line numberDiff line change
@@ -990,59 +990,49 @@ pub struct Pat<'hir> {
990990
}
991991

992992
impl<'hir> Pat<'hir> {
993-
// FIXME(#19596) this is a workaround, but there should be a better way
994-
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
993+
/// Walk the pattern in left-to-right order,
994+
/// short circuiting (with `.all(..)`) if `false` is returned.
995+
///
996+
/// Note that when visiting e.g. `Tuple(ps)`,
997+
/// if visiting `ps[0]` returns `false`,
998+
/// then `ps[1]` will not be visited.
999+
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
9951000
if !it(self) {
9961001
return false;
9971002
}
9981003

9991004
use PatKind::*;
10001005
match self.kind {
10011006
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
1002-
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
1003-
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
1004-
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
1007+
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short(it),
1008+
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short(&mut it)),
1009+
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short(&mut it)),
10051010
Slice(before, slice, after) => {
1006-
before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
1011+
before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short(&mut it))
10071012
}
10081013
}
10091014
}
10101015

1011-
/// Walk the pattern in left-to-right order,
1012-
/// short circuiting (with `.all(..)`) if `false` is returned.
1016+
/// Walk the pattern in left-to-right order.
10131017
///
1014-
/// Note that when visiting e.g. `Tuple(ps)`,
1015-
/// if visiting `ps[0]` returns `false`,
1016-
/// then `ps[1]` will not be visited.
1017-
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
1018-
self.walk_short_(&mut it)
1019-
}
1020-
1021-
// FIXME(#19596) this is a workaround, but there should be a better way
1022-
fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
1018+
/// If `it(pat)` returns `false`, the children are not visited.
1019+
pub fn walk<F: FnMut(&Pat<'hir>) -> bool>(&self, mut it: F) {
10231020
if !it(self) {
10241021
return;
10251022
}
10261023

10271024
use PatKind::*;
10281025
match self.kind {
10291026
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
1030-
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
1031-
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
1032-
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
1027+
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk(it),
1028+
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(&mut it)),
1029+
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk(&mut it)),
10331030
Slice(before, slice, after) => {
1034-
before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
1031+
before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk(&mut it))
10351032
}
10361033
}
10371034
}
10381035

1039-
/// Walk the pattern in left-to-right order.
1040-
///
1041-
/// If `it(pat)` returns `false`, the children are not visited.
1042-
pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
1043-
self.walk_(&mut it)
1044-
}
1045-
10461036
/// Walk the pattern in left-to-right order.
10471037
///
10481038
/// If you always want to recurse, prefer this method over `walk`.

compiler/rustc_hir_typeck/src/mem_categorization.rs

+77-90
Original file line numberDiff line numberDiff line change
@@ -524,90 +524,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
524524
}
525525

526526
pub(crate) fn cat_pattern<F>(
527-
&self,
528-
place: PlaceWithHirId<'tcx>,
529-
pat: &hir::Pat<'_>,
530-
mut op: F,
531-
) -> McResult<()>
532-
where
533-
F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>),
534-
{
535-
self.cat_pattern_(place, pat, &mut op)
536-
}
537-
538-
/// Returns the variant index for an ADT used within a Struct or TupleStruct pattern
539-
/// Here `pat_hir_id` is the HirId of the pattern itself.
540-
fn variant_index_for_adt(
541-
&self,
542-
qpath: &hir::QPath<'_>,
543-
pat_hir_id: hir::HirId,
544-
span: Span,
545-
) -> McResult<VariantIdx> {
546-
let res = self.typeck_results.qpath_res(qpath, pat_hir_id);
547-
let ty = self.typeck_results.node_type(pat_hir_id);
548-
let ty::Adt(adt_def, _) = ty.kind() else {
549-
self.tcx()
550-
.sess
551-
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
552-
return Err(());
553-
};
554-
555-
match res {
556-
Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)),
557-
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
558-
Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
559-
}
560-
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
561-
| Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
562-
| Res::SelfCtor(..)
563-
| Res::SelfTyParam { .. }
564-
| Res::SelfTyAlias { .. } => {
565-
// Structs and Unions have only have one variant.
566-
Ok(VariantIdx::new(0))
567-
}
568-
_ => bug!("expected ADT path, found={:?}", res),
569-
}
570-
}
571-
572-
/// Returns the total number of fields in an ADT variant used within a pattern.
573-
/// Here `pat_hir_id` is the HirId of the pattern itself.
574-
fn total_fields_in_adt_variant(
575-
&self,
576-
pat_hir_id: hir::HirId,
577-
variant_index: VariantIdx,
578-
span: Span,
579-
) -> McResult<usize> {
580-
let ty = self.typeck_results.node_type(pat_hir_id);
581-
match ty.kind() {
582-
ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
583-
_ => {
584-
self.tcx()
585-
.sess
586-
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
587-
Err(())
588-
}
589-
}
590-
}
591-
592-
/// Returns the total number of fields in a tuple used within a Tuple pattern.
593-
/// Here `pat_hir_id` is the HirId of the pattern itself.
594-
fn total_fields_in_tuple(&self, pat_hir_id: hir::HirId, span: Span) -> McResult<usize> {
595-
let ty = self.typeck_results.node_type(pat_hir_id);
596-
match ty.kind() {
597-
ty::Tuple(substs) => Ok(substs.len()),
598-
_ => {
599-
self.tcx().sess.delay_span_bug(span, "tuple pattern not applied to a tuple");
600-
Err(())
601-
}
602-
}
603-
}
604-
605-
// FIXME(#19596) This is a workaround, but there should be a better way to do this
606-
fn cat_pattern_<F>(
607527
&self,
608528
mut place_with_id: PlaceWithHirId<'tcx>,
609529
pat: &hir::Pat<'_>,
610-
op: &mut F,
530+
mut op: F,
611531
) -> McResult<()>
612532
where
613533
F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>),
@@ -681,7 +601,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
681601
let projection_kind = ProjectionKind::Field(i as u32, VariantIdx::new(0));
682602
let sub_place =
683603
self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
684-
self.cat_pattern_(sub_place, subpat, op)?;
604+
self.cat_pattern(sub_place, subpat, &mut op)?;
685605
}
686606
}
687607

@@ -696,7 +616,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
696616
let projection_kind = ProjectionKind::Field(i as u32, variant_index);
697617
let sub_place =
698618
self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind);
699-
self.cat_pattern_(sub_place, subpat, op)?;
619+
self.cat_pattern(sub_place, subpat, &mut op)?;
700620
}
701621
}
702622

@@ -720,26 +640,26 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
720640
field_ty,
721641
ProjectionKind::Field(field_index as u32, variant_index),
722642
);
723-
self.cat_pattern_(field_place, fp.pat, op)?;
643+
self.cat_pattern(field_place, fp.pat, &mut op)?;
724644
}
725645
}
726646

727647
PatKind::Or(pats) => {
728648
for pat in pats {
729-
self.cat_pattern_(place_with_id.clone(), pat, op)?;
649+
self.cat_pattern(place_with_id.clone(), pat, &mut op)?;
730650
}
731651
}
732652

733653
PatKind::Binding(.., Some(ref subpat)) => {
734-
self.cat_pattern_(place_with_id, subpat, op)?;
654+
self.cat_pattern(place_with_id, subpat, op)?;
735655
}
736656

737657
PatKind::Box(ref subpat) | PatKind::Ref(ref subpat, _) => {
738658
// box p1, &p1, &mut p1. we can ignore the mutability of
739659
// PatKind::Ref since that information is already contained
740660
// in the type.
741661
let subplace = self.cat_deref(pat, place_with_id)?;
742-
self.cat_pattern_(subplace, subpat, op)?;
662+
self.cat_pattern(subplace, subpat, op)?;
743663
}
744664

745665
PatKind::Slice(before, ref slice, after) => {
@@ -754,7 +674,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
754674
ProjectionKind::Index,
755675
);
756676
for before_pat in before {
757-
self.cat_pattern_(elt_place.clone(), before_pat, op)?;
677+
self.cat_pattern(elt_place.clone(), before_pat, &mut op)?;
758678
}
759679
if let Some(ref slice_pat) = *slice {
760680
let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?;
@@ -764,10 +684,10 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
764684
slice_pat_ty,
765685
ProjectionKind::Subslice,
766686
);
767-
self.cat_pattern_(slice_place, slice_pat, op)?;
687+
self.cat_pattern(slice_place, slice_pat, &mut op)?;
768688
}
769689
for after_pat in after {
770-
self.cat_pattern_(elt_place.clone(), after_pat, op)?;
690+
self.cat_pattern(elt_place.clone(), after_pat, &mut op)?;
771691
}
772692
}
773693

@@ -782,4 +702,71 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
782702

783703
Ok(())
784704
}
705+
706+
/// Returns the variant index for an ADT used within a Struct or TupleStruct pattern
707+
/// Here `pat_hir_id` is the HirId of the pattern itself.
708+
fn variant_index_for_adt(
709+
&self,
710+
qpath: &hir::QPath<'_>,
711+
pat_hir_id: hir::HirId,
712+
span: Span,
713+
) -> McResult<VariantIdx> {
714+
let res = self.typeck_results.qpath_res(qpath, pat_hir_id);
715+
let ty = self.typeck_results.node_type(pat_hir_id);
716+
let ty::Adt(adt_def, _) = ty.kind() else {
717+
self.tcx()
718+
.sess
719+
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
720+
return Err(());
721+
};
722+
723+
match res {
724+
Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)),
725+
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
726+
Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
727+
}
728+
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
729+
| Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
730+
| Res::SelfCtor(..)
731+
| Res::SelfTyParam { .. }
732+
| Res::SelfTyAlias { .. } => {
733+
// Structs and Unions have only have one variant.
734+
Ok(VariantIdx::new(0))
735+
}
736+
_ => bug!("expected ADT path, found={:?}", res),
737+
}
738+
}
739+
740+
/// Returns the total number of fields in an ADT variant used within a pattern.
741+
/// Here `pat_hir_id` is the HirId of the pattern itself.
742+
fn total_fields_in_adt_variant(
743+
&self,
744+
pat_hir_id: hir::HirId,
745+
variant_index: VariantIdx,
746+
span: Span,
747+
) -> McResult<usize> {
748+
let ty = self.typeck_results.node_type(pat_hir_id);
749+
match ty.kind() {
750+
ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
751+
_ => {
752+
self.tcx()
753+
.sess
754+
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
755+
Err(())
756+
}
757+
}
758+
}
759+
760+
/// Returns the total number of fields in a tuple used within a Tuple pattern.
761+
/// Here `pat_hir_id` is the HirId of the pattern itself.
762+
fn total_fields_in_tuple(&self, pat_hir_id: hir::HirId, span: Span) -> McResult<usize> {
763+
let ty = self.typeck_results.node_type(pat_hir_id);
764+
match ty.kind() {
765+
ty::Tuple(substs) => Ok(substs.len()),
766+
_ => {
767+
self.tcx().sess.delay_span_bug(span, "tuple pattern not applied to a tuple");
768+
Err(())
769+
}
770+
}
771+
}
785772
}

0 commit comments

Comments
 (0)