@@ -2,11 +2,11 @@ use rustc_abi::{FieldIdx, VariantIdx};
22use rustc_apfloat:: Float ;
33use rustc_hir as hir;
44use rustc_index:: Idx ;
5- use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
5+ use rustc_infer:: infer:: TyCtxtInferExt ;
66use rustc_infer:: traits:: Obligation ;
77use rustc_middle:: mir:: interpret:: ErrorHandled ;
88use rustc_middle:: thir:: { FieldPat , Pat , PatKind } ;
9- use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt , TypingMode , ValTree } ;
9+ use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt , ValTree } ;
1010use rustc_middle:: { mir, span_bug} ;
1111use rustc_span:: Span ;
1212use rustc_trait_selection:: traits:: ObligationCause ;
@@ -35,10 +35,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
3535 id : hir:: HirId ,
3636 span : Span ,
3737 ) -> Box < Pat < ' tcx > > {
38- // FIXME(#132279): We likely want to be able to reveal the hidden types
39- // of opaques defined in this function here.
40- let infcx = self . tcx . infer_ctxt ( ) . build ( TypingMode :: non_body_analysis ( ) ) ;
41- let mut convert = ConstToPat :: new ( self , id, span, infcx) ;
38+ let mut convert = ConstToPat :: new ( self , id, span) ;
4239
4340 match c. kind ( ) {
4441 ty:: ConstKind :: Unevaluated ( uv) => convert. unevaluated_to_pat ( uv, ty) ,
@@ -49,44 +46,29 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
4946}
5047
5148struct ConstToPat < ' tcx > {
49+ tcx : TyCtxt < ' tcx > ,
50+ typing_env : ty:: TypingEnv < ' tcx > ,
5251 span : Span ,
5352
54- // inference context used for checking `T: Structural` bounds.
55- infcx : InferCtxt < ' tcx > ,
56- param_env : ty:: ParamEnv < ' tcx > ,
57-
5853 treat_byte_string_as_slice : bool ,
5954}
6055
6156impl < ' tcx > ConstToPat < ' tcx > {
62- fn new (
63- pat_ctxt : & PatCtxt < ' _ , ' tcx > ,
64- id : hir:: HirId ,
65- span : Span ,
66- infcx : InferCtxt < ' tcx > ,
67- ) -> Self {
57+ fn new ( pat_ctxt : & PatCtxt < ' _ , ' tcx > , id : hir:: HirId , span : Span ) -> Self {
6858 trace ! ( ?pat_ctxt. typeck_results. hir_owner) ;
6959 ConstToPat {
60+ tcx : pat_ctxt. tcx ,
61+ typing_env : pat_ctxt. typing_env ,
7062 span,
71- infcx,
72- param_env : pat_ctxt. param_env ,
7363 treat_byte_string_as_slice : pat_ctxt
7464 . typeck_results
7565 . treat_byte_string_as_slice
7666 . contains ( & id. local_id ) ,
7767 }
7868 }
7969
80- fn tcx ( & self ) -> TyCtxt < ' tcx > {
81- self . infcx . tcx
82- }
83-
84- fn typing_env ( & self ) -> ty:: TypingEnv < ' tcx > {
85- self . infcx . typing_env ( self . param_env )
86- }
87-
8870 fn type_marked_structural ( & self , ty : Ty < ' tcx > ) -> bool {
89- ty. is_structural_eq_shallow ( self . infcx . tcx )
71+ ty. is_structural_eq_shallow ( self . tcx )
9072 }
9173
9274 fn unevaluated_to_pat (
@@ -105,22 +87,21 @@ impl<'tcx> ConstToPat<'tcx> {
10587 // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
10688 // instead of having this logic here
10789 let typing_env =
108- self . tcx ( ) . erase_regions ( self . typing_env ( ) ) . with_reveal_all_normalized ( self . tcx ( ) ) ;
109- let uv = self . tcx ( ) . erase_regions ( uv) ;
90+ self . tcx . erase_regions ( self . typing_env ) . with_reveal_all_normalized ( self . tcx ) ;
91+ let uv = self . tcx . erase_regions ( uv) ;
11092
11193 // try to resolve e.g. associated constants to their definition on an impl, and then
11294 // evaluate the const.
113- let valtree = match self . infcx . tcx . const_eval_resolve_for_typeck ( typing_env, uv, self . span )
114- {
95+ let valtree = match self . tcx . const_eval_resolve_for_typeck ( typing_env, uv, self . span ) {
11596 Ok ( Ok ( c) ) => c,
11697 Err ( ErrorHandled :: Reported ( _, _) ) => {
11798 // Let's tell the use where this failing const occurs.
118- let e = self . tcx ( ) . dcx ( ) . emit_err ( CouldNotEvalConstPattern { span : self . span } ) ;
99+ let e = self . tcx . dcx ( ) . emit_err ( CouldNotEvalConstPattern { span : self . span } ) ;
119100 return pat_from_kind ( PatKind :: Error ( e) ) ;
120101 }
121102 Err ( ErrorHandled :: TooGeneric ( _) ) => {
122103 let e = self
123- . tcx ( )
104+ . tcx
124105 . dcx ( )
125106 . emit_err ( ConstPatternDependsOnGenericParameter { span : self . span } ) ;
126107 return pat_from_kind ( PatKind :: Error ( e) ) ;
@@ -130,13 +111,13 @@ impl<'tcx> ConstToPat<'tcx> {
130111 let e = match bad_ty. kind ( ) {
131112 ty:: Adt ( def, ..) => {
132113 assert ! ( def. is_union( ) ) ;
133- self . tcx ( ) . dcx ( ) . emit_err ( UnionPattern { span : self . span } )
114+ self . tcx . dcx ( ) . emit_err ( UnionPattern { span : self . span } )
134115 }
135116 ty:: FnPtr ( ..) | ty:: RawPtr ( ..) => {
136- self . tcx ( ) . dcx ( ) . emit_err ( PointerPattern { span : self . span } )
117+ self . tcx . dcx ( ) . emit_err ( PointerPattern { span : self . span } )
137118 }
138119 _ => self
139- . tcx ( )
120+ . tcx
140121 . dcx ( )
141122 . emit_err ( InvalidPattern { span : self . span , non_sm_ty : bad_ty } ) ,
142123 } ;
@@ -151,7 +132,7 @@ impl<'tcx> ConstToPat<'tcx> {
151132 // Always check for `PartialEq` if we had no other errors yet.
152133 if !self . type_has_partial_eq_impl ( ty) {
153134 let err = TypeNotPartialEq { span : self . span , non_peq_ty : ty } ;
154- let e = self . tcx ( ) . dcx ( ) . emit_err ( err) ;
135+ let e = self . tcx . dcx ( ) . emit_err ( err) ;
155136 return pat_from_kind ( PatKind :: Error ( e) ) ;
156137 }
157138 }
@@ -161,18 +142,19 @@ impl<'tcx> ConstToPat<'tcx> {
161142
162143 #[ instrument( level = "trace" , skip( self ) , ret) ]
163144 fn type_has_partial_eq_impl ( & self , ty : Ty < ' tcx > ) -> bool {
164- let tcx = self . tcx ( ) ;
145+ let ( infcx , param_env ) = self . tcx . infer_ctxt ( ) . build_with_typing_env ( self . typing_env ) ;
165146 // double-check there even *is* a semantic `PartialEq` to dispatch to.
166147 //
167148 // (If there isn't, then we can safely issue a hard
168149 // error, because that's never worked, due to compiler
169150 // using `PartialEq::eq` in this scenario in the past.)
170- let partial_eq_trait_id = tcx. require_lang_item ( hir:: LangItem :: PartialEq , Some ( self . span ) ) ;
151+ let partial_eq_trait_id =
152+ self . tcx . require_lang_item ( hir:: LangItem :: PartialEq , Some ( self . span ) ) ;
171153 let partial_eq_obligation = Obligation :: new (
172- tcx,
154+ self . tcx ,
173155 ObligationCause :: dummy ( ) ,
174- self . param_env ,
175- ty:: TraitRef :: new ( tcx, partial_eq_trait_id, [ ty, ty] ) ,
156+ param_env,
157+ ty:: TraitRef :: new ( self . tcx , partial_eq_trait_id, [ ty, ty] ) ,
176158 ) ;
177159
178160 // This *could* accept a type that isn't actually `PartialEq`, because region bounds get
@@ -181,7 +163,7 @@ impl<'tcx> ConstToPat<'tcx> {
181163 // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
182164 // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
183165 // can ensure that the type really implements `PartialEq`.
184- self . infcx . predicate_must_hold_modulo_regions ( & partial_eq_obligation)
166+ infcx. predicate_must_hold_modulo_regions ( & partial_eq_obligation)
185167 }
186168
187169 fn field_pats (
@@ -192,7 +174,7 @@ impl<'tcx> ConstToPat<'tcx> {
192174 . map ( |( idx, ( val, ty) ) | {
193175 let field = FieldIdx :: new ( idx) ;
194176 // Patterns can only use monomorphic types.
195- let ty = self . tcx ( ) . normalize_erasing_regions ( self . typing_env ( ) , ty) ;
177+ let ty = self . tcx . normalize_erasing_regions ( self . typing_env , ty) ;
196178 FieldPat { field, pattern : self . valtree_to_pat ( val, ty) }
197179 } )
198180 . collect ( )
@@ -202,12 +184,12 @@ impl<'tcx> ConstToPat<'tcx> {
202184 #[ instrument( skip( self ) , level = "debug" ) ]
203185 fn valtree_to_pat ( & self , cv : ValTree < ' tcx > , ty : Ty < ' tcx > ) -> Box < Pat < ' tcx > > {
204186 let span = self . span ;
205- let tcx = self . tcx ( ) ;
187+ let tcx = self . tcx ;
206188 let kind = match ty. kind ( ) {
207189 ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
208190 // Extremely important check for all ADTs! Make sure they opted-in to be used in
209191 // patterns.
210- debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty, ) ;
192+ debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" , adt_def, ty) ;
211193 let err = TypeNotStructural { span, non_sm_ty : ty } ;
212194 let e = tcx. dcx ( ) . emit_err ( err) ;
213195 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
@@ -225,22 +207,17 @@ impl<'tcx> ConstToPat<'tcx> {
225207 adt_def. variants ( ) [ variant_index]
226208 . fields
227209 . iter ( )
228- . map ( |field| field. ty ( self . tcx ( ) , args) ) ,
210+ . map ( |field| field. ty ( self . tcx , args) ) ,
229211 ) ,
230212 ) ,
231213 }
232214 }
233215 ty:: Adt ( def, args) => {
234216 assert ! ( !def. is_union( ) ) ; // Valtree construction would never succeed for unions.
235217 PatKind :: Leaf {
236- subpatterns : self . field_pats (
237- cv. unwrap_branch ( ) . iter ( ) . copied ( ) . zip (
238- def. non_enum_variant ( )
239- . fields
240- . iter ( )
241- . map ( |field| field. ty ( self . tcx ( ) , args) ) ,
242- ) ,
243- ) ,
218+ subpatterns : self . field_pats ( cv. unwrap_branch ( ) . iter ( ) . copied ( ) . zip (
219+ def. non_enum_variant ( ) . fields . iter ( ) . map ( |field| field. ty ( self . tcx , args) ) ,
220+ ) ) ,
244221 }
245222 }
246223 ty:: Tuple ( fields) => PatKind :: Leaf {
@@ -274,9 +251,7 @@ impl<'tcx> ConstToPat<'tcx> {
274251 // convert the dereferenced constant to a pattern that is the sub-pattern of the
275252 // deref pattern.
276253 _ => {
277- if !pointee_ty. is_sized ( tcx, self . infcx . typing_env ( self . param_env ) )
278- && !pointee_ty. is_slice ( )
279- {
254+ if !pointee_ty. is_sized ( tcx, self . typing_env ) && !pointee_ty. is_slice ( ) {
280255 let err = UnsizedPattern { span, non_sm_ty : * pointee_ty } ;
281256 let e = tcx. dcx ( ) . emit_err ( err) ;
282257 // We errored. Signal that in the pattern, so that follow up errors can be silenced.
0 commit comments