@@ -13,9 +13,7 @@ use rustc_infer::traits::Obligation;
1313use rustc_middle:: mir:: interpret:: ErrorHandled ;
1414use rustc_middle:: span_bug;
1515use 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 } ;
1917use rustc_span:: def_id:: DefId ;
2018use rustc_span:: { DUMMY_SP , Span } ;
2119use 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