@@ -221,27 +221,19 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
221221 let slice = match ctor {
222222 Struct | Variant ( _) | UnionField => match ty. kind ( ) {
223223 ty:: Tuple ( fs) => reveal_and_alloc ( cx, fs. iter ( ) ) ,
224- ty:: Adt ( adt, args) => {
225- if adt. is_box ( ) {
226- // The only legal patterns of type `Box` (outside `std`) are `_` and box
227- // patterns. If we're here we can assume this is a box pattern.
228- reveal_and_alloc ( cx, once ( args. type_at ( 0 ) ) )
229- } else {
230- let variant =
231- & adt. variant ( RustcPatCtxt :: variant_index_for_adt ( & ctor, * adt) ) ;
232- let tys = cx. variant_sub_tys ( ty, variant) . map ( |( field, ty) | {
233- let is_visible =
234- adt. is_enum ( ) || field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
235- let is_uninhabited = cx. is_uninhabited ( * ty) ;
236- let is_unstable =
237- cx. tcx . lookup_stability ( field. did ) . is_some_and ( |stab| {
238- stab. is_unstable ( ) && stab. feature != sym:: rustc_private
239- } ) ;
240- let skip = is_uninhabited && ( !is_visible || is_unstable) ;
241- ( ty, PrivateUninhabitedField ( skip) )
224+ ty:: Adt ( adt, _) => {
225+ let variant = & adt. variant ( RustcPatCtxt :: variant_index_for_adt ( & ctor, * adt) ) ;
226+ let tys = cx. variant_sub_tys ( ty, variant) . map ( |( field, ty) | {
227+ let is_visible =
228+ adt. is_enum ( ) || field. vis . is_accessible_from ( cx. module , cx. tcx ) ;
229+ let is_uninhabited = cx. is_uninhabited ( * ty) ;
230+ let is_unstable = cx. tcx . lookup_stability ( field. did ) . is_some_and ( |stab| {
231+ stab. is_unstable ( ) && stab. feature != sym:: rustc_private
242232 } ) ;
243- cx. dropless_arena . alloc_from_iter ( tys)
244- }
233+ let skip = is_uninhabited && ( !is_visible || is_unstable) ;
234+ ( ty, PrivateUninhabitedField ( skip) )
235+ } ) ;
236+ cx. dropless_arena . alloc_from_iter ( tys)
245237 }
246238 _ => bug ! ( "Unexpected type for constructor `{ctor:?}`: {ty:?}" ) ,
247239 } ,
@@ -273,14 +265,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
273265 Struct | Variant ( _) | UnionField => match ty. kind ( ) {
274266 ty:: Tuple ( fs) => fs. len ( ) ,
275267 ty:: Adt ( adt, ..) => {
276- if adt. is_box ( ) {
277- // The only legal patterns of type `Box` (outside `std`) are `_` and box
278- // patterns. If we're here we can assume this is a box pattern.
279- 1
280- } else {
281- let variant_idx = RustcPatCtxt :: variant_index_for_adt ( & ctor, * adt) ;
282- adt. variant ( variant_idx) . fields . len ( )
283- }
268+ let variant_idx = RustcPatCtxt :: variant_index_for_adt ( & ctor, * adt) ;
269+ adt. variant ( variant_idx) . fields . len ( )
284270 }
285271 _ => bug ! ( "Unexpected type for constructor `{ctor:?}`: {ty:?}" ) ,
286272 } ,
@@ -470,8 +456,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
470456 fields = vec ! [ self . lower_pat( subpattern) . at_index( 0 ) ] ;
471457 arity = 1 ;
472458 ctor = match ty. kind ( ) {
473- // This is a box pattern.
474- ty:: Adt ( adt, ..) if adt. is_box ( ) => Struct ,
475459 ty:: Ref ( ..) => Ref ,
476460 _ => span_bug ! (
477461 pat. span,
@@ -501,28 +485,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
501485 . map ( |ipat| self . lower_pat ( & ipat. pattern ) . at_index ( ipat. field . index ( ) ) )
502486 . collect ( ) ;
503487 }
504- ty:: Adt ( adt, _) if adt. is_box ( ) => {
505- // The only legal patterns of type `Box` (outside `std`) are `_` and box
506- // patterns. If we're here we can assume this is a box pattern.
507- // FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_,
508- // _)` or a box pattern. As a hack to avoid an ICE with the former, we
509- // ignore other fields than the first one. This will trigger an error later
510- // anyway.
511- // See https://github.com/rust-lang/rust/issues/82772,
512- // explanation: https://github.com/rust-lang/rust/pull/82789#issuecomment-796921977
513- // The problem is that we can't know from the type whether we'll match
514- // normally or through box-patterns. We'll have to figure out a proper
515- // solution when we introduce generalized deref patterns. Also need to
516- // prevent mixing of those two options.
517- let pattern = subpatterns. into_iter ( ) . find ( |pat| pat. field . index ( ) == 0 ) ;
518- if let Some ( pat) = pattern {
519- fields = vec ! [ self . lower_pat( & pat. pattern) . at_index( 0 ) ] ;
520- } else {
521- fields = vec ! [ ] ;
522- }
523- ctor = Struct ;
524- arity = 1 ;
525- }
526488 ty:: Adt ( adt, _) => {
527489 ctor = match pat. kind {
528490 PatKind :: Leaf { .. } if adt. is_union ( ) => UnionField ,
@@ -825,11 +787,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
825787 Bool ( b) => b. to_string ( ) ,
826788 Str ( s) => s. to_string ( ) ,
827789 IntRange ( range) => return self . print_pat_range ( range, * pat. ty ( ) ) ,
828- Struct if pat. ty ( ) . is_box ( ) => {
829- // Outside of the `alloc` crate, the only way to create a struct pattern
830- // of type `Box` is to use a `box` pattern via #[feature(box_patterns)].
831- format ! ( "box {}" , print( & pat. fields[ 0 ] ) )
832- }
833790 Struct | Variant ( _) | UnionField => {
834791 let enum_info = match * pat. ty ( ) . kind ( ) {
835792 ty:: Adt ( adt_def, _) if adt_def. is_enum ( ) => EnumInfo :: Enum {
@@ -866,6 +823,14 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
866823 print:: write_ref_like ( & mut s, pat. ty ( ) . inner ( ) , & print ( & pat. fields [ 0 ] ) ) . unwrap ( ) ;
867824 s
868825 }
826+ DerefPattern ( _) if pat. ty ( ) . is_box ( ) && !self . tcx . features ( ) . deref_patterns ( ) => {
827+ // FIXME(deref_patterns): Remove this special handling once `box_patterns` is gone.
828+ // HACK(@dianne): `box _` syntax is exposed on stable in diagnostics, e.g. to
829+ // witness non-exhaustiveness of `match Box::new(0) { Box { .. } if false => {} }`.
830+ // To avoid changing diagnostics before deref pattern syntax is finalized, let's use
831+ // `box _` syntax unless `deref_patterns` is enabled.
832+ format ! ( "box {}" , print( & pat. fields[ 0 ] ) )
833+ }
869834 DerefPattern ( _) => format ! ( "deref!({})" , print( & pat. fields[ 0 ] ) ) ,
870835 Slice ( slice) => {
871836 let ( prefix_len, has_dot_dot) = match slice. kind {
@@ -964,12 +929,8 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
964929 ty : & Self :: Ty ,
965930 ) -> fmt:: Result {
966931 if let ty:: Adt ( adt, _) = ty. kind ( ) {
967- if adt. is_box ( ) {
968- write ! ( f, "Box" ) ?
969- } else {
970- let variant = adt. variant ( Self :: variant_index_for_adt ( ctor, * adt) ) ;
971- write ! ( f, "{}" , variant. name) ?;
972- }
932+ let variant = adt. variant ( Self :: variant_index_for_adt ( ctor, * adt) ) ;
933+ write ! ( f, "{}" , variant. name) ?;
973934 }
974935 Ok ( ( ) )
975936 }
0 commit comments