From 0a777090d80747fc841784c5a6944f2a792f845c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:26:17 +1000 Subject: [PATCH 01/11] Avoid matching on `PatKind::Wild` in `write_struct_like` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +++++- compiler/rustc_pattern_analysis/src/rustc/print.rs | 9 +++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 10b7968a1a7e3..22b7ca18f840a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -847,7 +847,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let subpatterns = pat .iter_fields() .enumerate() - .map(|(i, pat)| FieldPat { field: FieldIdx::new(i), pattern: hoist(pat) }) + .map(|(i, pat)| FieldPat { + field: FieldIdx::new(i), + pattern: hoist(pat), + is_wildcard: would_print_as_wildcard(cx.tcx, pat), + }) .collect::>(); PatKind::StructLike { enum_info, subpatterns } diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index 7d6387146054e..94f625e015326 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -21,6 +21,7 @@ use rustc_target::abi::{FieldIdx, VariantIdx}; pub(crate) struct FieldPat<'tcx> { pub(crate) field: FieldIdx, pub(crate) pattern: Box>, + pub(crate) is_wildcard: bool, } #[derive(Clone, Debug)] @@ -139,12 +140,12 @@ fn write_struct_like<'tcx>( write!(f, " {{ ")?; let mut printed = 0; - for p in subpatterns { - if let PatKind::Wild = p.pattern.kind { + for &FieldPat { field, ref pattern, is_wildcard } in subpatterns { + if is_wildcard { continue; } - let name = variant.fields[p.field].name; - write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?; + let field_name = variant.fields[field].name; + write!(f, "{}{field_name}: {pattern}", start_or_comma())?; printed += 1; } From f53eb2724de4e1a7ec0985d035c208c55c37dd78 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:30:25 +1000 Subject: [PATCH 02/11] Add `print::PatKind::Print` This will allow for the gradual removal of all other variants. --- compiler/rustc_pattern_analysis/src/rustc/print.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index 94f625e015326..c929b9b808ab9 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -62,6 +62,8 @@ pub(crate) enum PatKind<'tcx> { }, Never, + + Print(String), } impl<'tcx> fmt::Display for Pat<'tcx> { @@ -79,6 +81,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { write_slice_like(f, prefix, has_dot_dot, suffix) } + PatKind::Print(ref string) => write!(f, "{string}"), } } } From 92eb159d04f8fd6009899d978c504ee8522baccb Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:45:12 +1000 Subject: [PATCH 03/11] Remove `PatKind::Wild` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 ++++-- compiler/rustc_pattern_analysis/src/rustc/print.rs | 3 --- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 22b7ca18f840a..6cf3680b3e8dd 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -780,7 +780,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { use MaybeInfiniteInt::*; let cx = self; let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) { - PatKind::Wild + PatKind::Print("_".to_string()) } else if range.is_singleton() { let lo = cx.hoist_pat_range_bdy(range.lo, ty); let value = lo.as_finite().unwrap(); @@ -890,7 +890,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } &Str(value) => PatKind::Constant { value }, Never if self.tcx.features().never_patterns => PatKind::Never, - Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => PatKind::Wild, + Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { + PatKind::Print("_".to_string()) + } Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, `Missing` should have been processed in `apply_constructors`" diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index c929b9b808ab9..d8e282ae326a9 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,8 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Wild, - StructLike { enum_info: EnumInfo<'tcx>, subpatterns: Vec>, @@ -69,7 +67,6 @@ pub(crate) enum PatKind<'tcx> { impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { - PatKind::Wild => write!(f, "_"), PatKind::Never => write!(f, "!"), PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"), PatKind::StructLike { ref enum_info, ref subpatterns } => { From ed3e38f33697efd2272b2df6a31b450e1e6ee12b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:47:21 +1000 Subject: [PATCH 04/11] Remove `PatKind::StructLike` --- compiler/rustc_pattern_analysis/src/rustc.rs | 11 ++++++++++- compiler/rustc_pattern_analysis/src/rustc/print.rs | 10 +--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 6cf3680b3e8dd..1d687cc1065dc 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -854,7 +854,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { }) .collect::>(); - PatKind::StructLike { enum_info, subpatterns } + let mut s = String::new(); + print::write_struct_like( + &mut s, + self.tcx, + pat.ty().inner(), + &enum_info, + &subpatterns, + ) + .unwrap(); + PatKind::Print(s) } Ref => PatKind::Deref { subpattern: hoist(&pat.fields[0]) }, Slice(slice) => { diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index d8e282ae326a9..dd37cd80ad262 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,11 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - StructLike { - enum_info: EnumInfo<'tcx>, - subpatterns: Vec>, - }, - Box { subpattern: Box>, }, @@ -69,9 +64,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { match self.kind { PatKind::Never => write!(f, "!"), PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"), - PatKind::StructLike { ref enum_info, ref subpatterns } => { - ty::tls::with(|tcx| write_struct_like(f, tcx, self.ty, enum_info, subpatterns)) - } PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern), PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), @@ -104,7 +96,7 @@ pub(crate) enum EnumInfo<'tcx> { NotEnum, } -fn write_struct_like<'tcx>( +pub(crate) fn write_struct_like<'tcx>( f: &mut impl fmt::Write, tcx: TyCtxt<'_>, ty: Ty<'tcx>, From 15cc0e1b5cb9cc84ce017b656a75d9954f394f03 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:48:52 +1000 Subject: [PATCH 05/11] Remove `PatKind::Box` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc/print.rs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 1d687cc1065dc..91650c7531a91 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -832,7 +832,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { Struct if pat.ty().is_box() => { // Outside of the `alloc` crate, the only way to create a struct pattern // of type `Box` is to use a `box` pattern via #[feature(box_patterns)]. - PatKind::Box { subpattern: hoist(&pat.fields[0]) } + PatKind::Print(format!("box {}", hoist(&pat.fields[0]))) } Struct | Variant(_) | UnionField => { let enum_info = match *pat.ty().kind() { diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index dd37cd80ad262..d03c68442cd5e 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,10 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Box { - subpattern: Box>, - }, - Deref { subpattern: Box>, }, @@ -63,7 +59,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Box { ref subpattern } => write!(f, "box {subpattern}"), PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern), PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), From 283243ac5a3bcf68627491ea64b0d725db8c62f3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:51:32 +1000 Subject: [PATCH 06/11] Remove `PatKind::Ref` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +++++- compiler/rustc_pattern_analysis/src/rustc/print.rs | 8 ++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 91650c7531a91..97d4a94756dae 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -865,7 +865,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { .unwrap(); PatKind::Print(s) } - Ref => PatKind::Deref { subpattern: hoist(&pat.fields[0]) }, + Ref => { + let mut s = String::new(); + print::write_ref_like(&mut s, pat.ty().inner(), &hoist(&pat.fields[0])).unwrap(); + PatKind::Print(s) + } Slice(slice) => { let (prefix_len, has_dot_dot) = match slice.kind { SliceKind::FixedLen(len) => (len, false), diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index d03c68442cd5e..f147d62ed9bbc 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -26,16 +26,13 @@ pub(crate) struct FieldPat<'tcx> { #[derive(Clone, Debug)] pub(crate) struct Pat<'tcx> { + #[allow(dead_code)] pub(crate) ty: Ty<'tcx>, pub(crate) kind: PatKind<'tcx>, } #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Deref { - subpattern: Box>, - }, - Constant { value: mir::Const<'tcx>, }, @@ -59,7 +56,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Deref { ref subpattern } => write_ref_like(f, self.ty, subpattern), PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { @@ -172,7 +168,7 @@ pub(crate) fn write_struct_like<'tcx>( Ok(()) } -fn write_ref_like<'tcx>( +pub(crate) fn write_ref_like<'tcx>( f: &mut impl fmt::Write, ty: Ty<'tcx>, subpattern: &Pat<'tcx>, From 9952e4d4c8ba5def2861e1a39af61506f0a91655 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:55:50 +1000 Subject: [PATCH 07/11] Remove `PatKind::Constant` --- compiler/rustc_pattern_analysis/src/rustc.rs | 6 +++--- compiler/rustc_pattern_analysis/src/rustc/print.rs | 7 +------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 97d4a94756dae..9bd17b822af35 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -784,7 +784,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } else if range.is_singleton() { let lo = cx.hoist_pat_range_bdy(range.lo, ty); let value = lo.as_finite().unwrap(); - PatKind::Constant { value } + PatKind::Print(value.to_string()) } else { // We convert to an inclusive range for diagnostics. let mut end = rustc_hir::RangeEnd::Included; @@ -827,7 +827,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let cx = self; let hoist = |p| Box::new(cx.hoist_witness_pat(p)); let kind = match pat.ctor() { - Bool(b) => PatKind::Constant { value: mir::Const::from_bool(cx.tcx, *b) }, + Bool(b) => PatKind::Print(b.to_string()), + Str(s) => PatKind::Print(s.to_string()), IntRange(range) => return self.hoist_pat_range(range, *pat.ty()), Struct if pat.ty().is_box() => { // Outside of the `alloc` crate, the only way to create a struct pattern @@ -901,7 +902,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { PatKind::Slice { prefix, has_dot_dot, suffix } } - &Str(value) => PatKind::Constant { value }, Never if self.tcx.features().never_patterns => PatKind::Never, Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { PatKind::Print("_".to_string()) diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index f147d62ed9bbc..9e24ef58e8bc0 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -11,9 +11,9 @@ use std::fmt; +use rustc_middle::bug; use rustc_middle::thir::PatRange; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; -use rustc_middle::{bug, mir}; use rustc_span::sym; use rustc_target::abi::{FieldIdx, VariantIdx}; @@ -33,10 +33,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Constant { - value: mir::Const<'tcx>, - }, - Range(Box>), Slice { @@ -56,7 +52,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Constant { value } => write!(f, "{value}"), PatKind::Range(ref range) => write!(f, "{range}"), PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { write_slice_like(f, prefix, has_dot_dot, suffix) From 2b6f4386ebdedd62a093577dafe5082e4f63b316 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 20:59:02 +1000 Subject: [PATCH 08/11] Remove `PatKind::Range` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc/print.rs | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 9bd17b822af35..d7c14348b1b7b 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -807,7 +807,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { range.hi }; let hi = cx.hoist_pat_range_bdy(hi, ty); - PatKind::Range(Box::new(PatRange { lo, hi, end, ty: ty.inner() })) + PatKind::Print(PatRange { lo, hi, end, ty: ty.inner() }.to_string()) }; Pat { ty: ty.inner(), kind } diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index 9e24ef58e8bc0..fab71b421f8b6 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -12,7 +12,6 @@ use std::fmt; use rustc_middle::bug; -use rustc_middle::thir::PatRange; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_span::sym; use rustc_target::abi::{FieldIdx, VariantIdx}; @@ -33,8 +32,6 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind<'tcx> { - Range(Box>), - Slice { prefix: Box<[Box>]>, /// True if this slice-like pattern should include a `..` between the @@ -52,7 +49,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Range(ref range) => write!(f, "{range}"), PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { write_slice_like(f, prefix, has_dot_dot, suffix) } From ec1483bf2e317b4a8d073881c3e942f7a011ff1a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 21:02:00 +1000 Subject: [PATCH 09/11] Remove `PatKind::Slice` --- compiler/rustc_pattern_analysis/src/rustc.rs | 8 +++++--- .../rustc_pattern_analysis/src/rustc/print.rs | 17 +++-------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d7c14348b1b7b..653097314f7fa 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -897,10 +897,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } - let prefix = prefix.iter().map(hoist).collect(); - let suffix = suffix.iter().map(hoist).collect(); + let prefix = prefix.iter().map(hoist).collect::>(); + let suffix = suffix.iter().map(hoist).collect::>(); - PatKind::Slice { prefix, has_dot_dot, suffix } + let mut s = String::new(); + print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); + PatKind::Print(s) } Never if self.tcx.features().never_patterns => PatKind::Never, Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index fab71b421f8b6..adda21a8b2582 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -27,19 +27,11 @@ pub(crate) struct FieldPat<'tcx> { pub(crate) struct Pat<'tcx> { #[allow(dead_code)] pub(crate) ty: Ty<'tcx>, - pub(crate) kind: PatKind<'tcx>, + pub(crate) kind: PatKind, } #[derive(Clone, Debug)] -pub(crate) enum PatKind<'tcx> { - Slice { - prefix: Box<[Box>]>, - /// True if this slice-like pattern should include a `..` between the - /// prefix and suffix. - has_dot_dot: bool, - suffix: Box<[Box>]>, - }, - +pub(crate) enum PatKind { Never, Print(String), @@ -49,9 +41,6 @@ impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { PatKind::Never => write!(f, "!"), - PatKind::Slice { ref prefix, has_dot_dot, ref suffix } => { - write_slice_like(f, prefix, has_dot_dot, suffix) - } PatKind::Print(ref string) => write!(f, "{string}"), } } @@ -173,7 +162,7 @@ pub(crate) fn write_ref_like<'tcx>( write!(f, "{subpattern}") } -fn write_slice_like<'tcx>( +pub(crate) fn write_slice_like<'tcx>( f: &mut impl fmt::Write, prefix: &[Box>], has_dot_dot: bool, From bfe88a3bd0d0af92405655495a40aefbbed29b23 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 21:04:51 +1000 Subject: [PATCH 10/11] Remove `PatKind::Never` --- compiler/rustc_pattern_analysis/src/rustc.rs | 2 +- compiler/rustc_pattern_analysis/src/rustc/print.rs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 653097314f7fa..35391ebec822a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -904,7 +904,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); PatKind::Print(s) } - Never if self.tcx.features().never_patterns => PatKind::Never, + Never if self.tcx.features().never_patterns => PatKind::Print("!".to_string()), Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { PatKind::Print("_".to_string()) } diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index adda21a8b2582..b2ecfa2ae28c2 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -32,15 +32,12 @@ pub(crate) struct Pat<'tcx> { #[derive(Clone, Debug)] pub(crate) enum PatKind { - Never, - Print(String), } impl<'tcx> fmt::Display for Pat<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { - PatKind::Never => write!(f, "!"), PatKind::Print(ref string) => write!(f, "{string}"), } } From fc55129774c8209d46d89b8a27b13fb7d8ce2b44 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 3 Aug 2024 21:20:22 +1000 Subject: [PATCH 11/11] Remove `print::Pat` entirely, replacing it with `String` --- compiler/rustc_pattern_analysis/src/rustc.rs | 70 ++++++++----------- .../rustc_pattern_analysis/src/rustc/print.rs | 34 ++------- 2 files changed, 35 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 35391ebec822a..4ad6da5535071 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -774,17 +774,16 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } - /// Convert to a [`print::Pat`] for diagnostic purposes. - fn hoist_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> print::Pat<'tcx> { - use print::{Pat, PatKind}; + /// Prints an [`IntRange`] to a string for diagnostic purposes. + fn print_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> String { use MaybeInfiniteInt::*; let cx = self; - let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) { - PatKind::Print("_".to_string()) + if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) { + "_".to_string() } else if range.is_singleton() { let lo = cx.hoist_pat_range_bdy(range.lo, ty); let value = lo.as_finite().unwrap(); - PatKind::Print(value.to_string()) + value.to_string() } else { // We convert to an inclusive range for diagnostics. let mut end = rustc_hir::RangeEnd::Included; @@ -807,33 +806,24 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { range.hi }; let hi = cx.hoist_pat_range_bdy(hi, ty); - PatKind::Print(PatRange { lo, hi, end, ty: ty.inner() }.to_string()) - }; - - Pat { ty: ty.inner(), kind } + PatRange { lo, hi, end, ty: ty.inner() }.to_string() + } } /// Prints a [`WitnessPat`] to an owned string, for diagnostic purposes. + /// + /// This panics for patterns that don't appear in diagnostics, like float ranges. pub fn print_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> String { - // This works by converting the witness pattern to a `print::Pat` - // and then printing that, but callers don't need to know that. - self.hoist_witness_pat(pat).to_string() - } - - /// Convert to a [`print::Pat`] for diagnostic purposes. This panics for patterns that don't - /// appear in diagnostics, like float ranges. - fn hoist_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> print::Pat<'tcx> { - use print::{FieldPat, Pat, PatKind}; let cx = self; - let hoist = |p| Box::new(cx.hoist_witness_pat(p)); - let kind = match pat.ctor() { - Bool(b) => PatKind::Print(b.to_string()), - Str(s) => PatKind::Print(s.to_string()), - IntRange(range) => return self.hoist_pat_range(range, *pat.ty()), + let print = |p| cx.print_witness_pat(p); + match pat.ctor() { + Bool(b) => b.to_string(), + Str(s) => s.to_string(), + IntRange(range) => return self.print_pat_range(range, *pat.ty()), Struct if pat.ty().is_box() => { // Outside of the `alloc` crate, the only way to create a struct pattern // of type `Box` is to use a `box` pattern via #[feature(box_patterns)]. - PatKind::Print(format!("box {}", hoist(&pat.fields[0]))) + format!("box {}", print(&pat.fields[0])) } Struct | Variant(_) | UnionField => { let enum_info = match *pat.ty().kind() { @@ -848,9 +838,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let subpatterns = pat .iter_fields() .enumerate() - .map(|(i, pat)| FieldPat { + .map(|(i, pat)| print::FieldPat { field: FieldIdx::new(i), - pattern: hoist(pat), + pattern: print(pat), is_wildcard: would_print_as_wildcard(cx.tcx, pat), }) .collect::>(); @@ -864,12 +854,12 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { &subpatterns, ) .unwrap(); - PatKind::Print(s) + s } Ref => { let mut s = String::new(); - print::write_ref_like(&mut s, pat.ty().inner(), &hoist(&pat.fields[0])).unwrap(); - PatKind::Print(s) + print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap(); + s } Slice(slice) => { let (prefix_len, has_dot_dot) = match slice.kind { @@ -897,17 +887,15 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { } } - let prefix = prefix.iter().map(hoist).collect::>(); - let suffix = suffix.iter().map(hoist).collect::>(); + let prefix = prefix.iter().map(print).collect::>(); + let suffix = suffix.iter().map(print).collect::>(); let mut s = String::new(); print::write_slice_like(&mut s, &prefix, has_dot_dot, &suffix).unwrap(); - PatKind::Print(s) - } - Never if self.tcx.features().never_patterns => PatKind::Print("!".to_string()), - Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => { - PatKind::Print("_".to_string()) + s } + Never if self.tcx.features().never_patterns => "!".to_string(), + Never | Wildcard | NonExhaustive | Hidden | PrivateUninhabited => "_".to_string(), Missing { .. } => bug!( "trying to convert a `Missing` constructor into a `Pat`; this is probably a bug, `Missing` should have been processed in `apply_constructors`" @@ -915,9 +903,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { F16Range(..) | F32Range(..) | F64Range(..) | F128Range(..) | Opaque(..) | Or => { bug!("can't convert to pattern: {:?}", pat) } - }; - - Pat { ty: pat.ty().inner(), kind } + } } } @@ -993,7 +979,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { overlaps_on: IntRange, overlaps_with: &[&crate::pat::DeconstructedPat], ) { - let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty()); + let overlap_as_pat = self.print_pat_range(&overlaps_on, *pat.ty()); let overlaps: Vec<_> = overlaps_with .iter() .map(|pat| pat.data().span) @@ -1033,7 +1019,7 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { suggested_range.end = rustc_hir::RangeEnd::Included; suggested_range.to_string() }; - let gap_as_pat = self.hoist_pat_range(&gap, *pat.ty()); + let gap_as_pat = self.print_pat_range(&gap, *pat.ty()); if gapped_with.is_empty() { // If `gapped_with` is empty, `gap == T::MAX`. self.tcx.emit_node_span_lint( diff --git a/compiler/rustc_pattern_analysis/src/rustc/print.rs b/compiler/rustc_pattern_analysis/src/rustc/print.rs index b2ecfa2ae28c2..17e389df17ed2 100644 --- a/compiler/rustc_pattern_analysis/src/rustc/print.rs +++ b/compiler/rustc_pattern_analysis/src/rustc/print.rs @@ -17,32 +17,12 @@ use rustc_span::sym; use rustc_target::abi::{FieldIdx, VariantIdx}; #[derive(Clone, Debug)] -pub(crate) struct FieldPat<'tcx> { +pub(crate) struct FieldPat { pub(crate) field: FieldIdx, - pub(crate) pattern: Box>, + pub(crate) pattern: String, pub(crate) is_wildcard: bool, } -#[derive(Clone, Debug)] -pub(crate) struct Pat<'tcx> { - #[allow(dead_code)] - pub(crate) ty: Ty<'tcx>, - pub(crate) kind: PatKind, -} - -#[derive(Clone, Debug)] -pub(crate) enum PatKind { - Print(String), -} - -impl<'tcx> fmt::Display for Pat<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.kind { - PatKind::Print(ref string) => write!(f, "{string}"), - } - } -} - /// Returns a closure that will return `""` when called the first time, /// and then return `", "` when called any subsequent times. /// Useful for printing comma-separated lists. @@ -69,7 +49,7 @@ pub(crate) fn write_struct_like<'tcx>( tcx: TyCtxt<'_>, ty: Ty<'tcx>, enum_info: &EnumInfo<'tcx>, - subpatterns: &[FieldPat<'tcx>], + subpatterns: &[FieldPat], ) -> fmt::Result { let variant_and_name = match *enum_info { EnumInfo::Enum { adt_def, variant_index } => { @@ -148,7 +128,7 @@ pub(crate) fn write_struct_like<'tcx>( pub(crate) fn write_ref_like<'tcx>( f: &mut impl fmt::Write, ty: Ty<'tcx>, - subpattern: &Pat<'tcx>, + subpattern: &str, ) -> fmt::Result { match ty.kind() { ty::Ref(_, _, mutbl) => { @@ -159,11 +139,11 @@ pub(crate) fn write_ref_like<'tcx>( write!(f, "{subpattern}") } -pub(crate) fn write_slice_like<'tcx>( +pub(crate) fn write_slice_like( f: &mut impl fmt::Write, - prefix: &[Box>], + prefix: &[String], has_dot_dot: bool, - suffix: &[Box>], + suffix: &[String], ) -> fmt::Result { let mut start_or_comma = start_or_comma(); write!(f, "[")?;