@@ -2,11 +2,11 @@ use rustc_abi::{FieldIdx, VariantIdx};
2
2
use rustc_apfloat:: Float ;
3
3
use rustc_hir as hir;
4
4
use rustc_index:: Idx ;
5
- use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
5
+ use rustc_infer:: infer:: TyCtxtInferExt ;
6
6
use rustc_infer:: traits:: Obligation ;
7
7
use rustc_middle:: mir:: interpret:: ErrorHandled ;
8
8
use 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 } ;
10
10
use rustc_middle:: { mir, span_bug} ;
11
11
use rustc_span:: Span ;
12
12
use rustc_trait_selection:: traits:: ObligationCause ;
@@ -35,10 +35,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
35
35
id : hir:: HirId ,
36
36
span : Span ,
37
37
) -> 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) ;
42
39
43
40
match c. kind ( ) {
44
41
ty:: ConstKind :: Unevaluated ( uv) => convert. unevaluated_to_pat ( uv, ty) ,
@@ -49,44 +46,29 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
49
46
}
50
47
51
48
struct ConstToPat < ' tcx > {
49
+ tcx : TyCtxt < ' tcx > ,
50
+ typing_env : ty:: TypingEnv < ' tcx > ,
52
51
span : Span ,
53
52
54
- // inference context used for checking `T: Structural` bounds.
55
- infcx : InferCtxt < ' tcx > ,
56
- param_env : ty:: ParamEnv < ' tcx > ,
57
-
58
53
treat_byte_string_as_slice : bool ,
59
54
}
60
55
61
56
impl < ' 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 {
68
58
trace ! ( ?pat_ctxt. typeck_results. hir_owner) ;
69
59
ConstToPat {
60
+ tcx : pat_ctxt. tcx ,
61
+ typing_env : pat_ctxt. typing_env ,
70
62
span,
71
- infcx,
72
- param_env : pat_ctxt. param_env ,
73
63
treat_byte_string_as_slice : pat_ctxt
74
64
. typeck_results
75
65
. treat_byte_string_as_slice
76
66
. contains ( & id. local_id ) ,
77
67
}
78
68
}
79
69
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
-
88
70
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 )
90
72
}
91
73
92
74
fn unevaluated_to_pat (
@@ -105,22 +87,21 @@ impl<'tcx> ConstToPat<'tcx> {
105
87
// FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
106
88
// instead of having this logic here
107
89
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) ;
110
92
111
93
// try to resolve e.g. associated constants to their definition on an impl, and then
112
94
// 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 ) {
115
96
Ok ( Ok ( c) ) => c,
116
97
Err ( ErrorHandled :: Reported ( _, _) ) => {
117
98
// 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 } ) ;
119
100
return pat_from_kind ( PatKind :: Error ( e) ) ;
120
101
}
121
102
Err ( ErrorHandled :: TooGeneric ( _) ) => {
122
103
let e = self
123
- . tcx ( )
104
+ . tcx
124
105
. dcx ( )
125
106
. emit_err ( ConstPatternDependsOnGenericParameter { span : self . span } ) ;
126
107
return pat_from_kind ( PatKind :: Error ( e) ) ;
@@ -130,13 +111,13 @@ impl<'tcx> ConstToPat<'tcx> {
130
111
let e = match bad_ty. kind ( ) {
131
112
ty:: Adt ( def, ..) => {
132
113
assert ! ( def. is_union( ) ) ;
133
- self . tcx ( ) . dcx ( ) . emit_err ( UnionPattern { span : self . span } )
114
+ self . tcx . dcx ( ) . emit_err ( UnionPattern { span : self . span } )
134
115
}
135
116
ty:: FnPtr ( ..) | ty:: RawPtr ( ..) => {
136
- self . tcx ( ) . dcx ( ) . emit_err ( PointerPattern { span : self . span } )
117
+ self . tcx . dcx ( ) . emit_err ( PointerPattern { span : self . span } )
137
118
}
138
119
_ => self
139
- . tcx ( )
120
+ . tcx
140
121
. dcx ( )
141
122
. emit_err ( InvalidPattern { span : self . span , non_sm_ty : bad_ty } ) ,
142
123
} ;
@@ -151,7 +132,7 @@ impl<'tcx> ConstToPat<'tcx> {
151
132
// Always check for `PartialEq` if we had no other errors yet.
152
133
if !self . type_has_partial_eq_impl ( ty) {
153
134
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) ;
155
136
return pat_from_kind ( PatKind :: Error ( e) ) ;
156
137
}
157
138
}
@@ -161,18 +142,19 @@ impl<'tcx> ConstToPat<'tcx> {
161
142
162
143
#[ instrument( level = "trace" , skip( self ) , ret) ]
163
144
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 ) ;
165
146
// double-check there even *is* a semantic `PartialEq` to dispatch to.
166
147
//
167
148
// (If there isn't, then we can safely issue a hard
168
149
// error, because that's never worked, due to compiler
169
150
// 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 ) ) ;
171
153
let partial_eq_obligation = Obligation :: new (
172
- tcx,
154
+ self . tcx ,
173
155
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] ) ,
176
158
) ;
177
159
178
160
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
@@ -181,7 +163,7 @@ impl<'tcx> ConstToPat<'tcx> {
181
163
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
182
164
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
183
165
// 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)
185
167
}
186
168
187
169
fn field_pats (
@@ -192,7 +174,7 @@ impl<'tcx> ConstToPat<'tcx> {
192
174
. map ( |( idx, ( val, ty) ) | {
193
175
let field = FieldIdx :: new ( idx) ;
194
176
// 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) ;
196
178
FieldPat { field, pattern : self . valtree_to_pat ( val, ty) }
197
179
} )
198
180
. collect ( )
@@ -202,12 +184,12 @@ impl<'tcx> ConstToPat<'tcx> {
202
184
#[ instrument( skip( self ) , level = "debug" ) ]
203
185
fn valtree_to_pat ( & self , cv : ValTree < ' tcx > , ty : Ty < ' tcx > ) -> Box < Pat < ' tcx > > {
204
186
let span = self . span ;
205
- let tcx = self . tcx ( ) ;
187
+ let tcx = self . tcx ;
206
188
let kind = match ty. kind ( ) {
207
189
ty:: Adt ( adt_def, _) if !self . type_marked_structural ( ty) => {
208
190
// Extremely important check for all ADTs! Make sure they opted-in to be used in
209
191
// 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) ;
211
193
let err = TypeNotStructural { span, non_sm_ty : ty } ;
212
194
let e = tcx. dcx ( ) . emit_err ( err) ;
213
195
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
@@ -225,22 +207,17 @@ impl<'tcx> ConstToPat<'tcx> {
225
207
adt_def. variants ( ) [ variant_index]
226
208
. fields
227
209
. iter ( )
228
- . map ( |field| field. ty ( self . tcx ( ) , args) ) ,
210
+ . map ( |field| field. ty ( self . tcx , args) ) ,
229
211
) ,
230
212
) ,
231
213
}
232
214
}
233
215
ty:: Adt ( def, args) => {
234
216
assert ! ( !def. is_union( ) ) ; // Valtree construction would never succeed for unions.
235
217
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
+ ) ) ,
244
221
}
245
222
}
246
223
ty:: Tuple ( fields) => PatKind :: Leaf {
@@ -274,9 +251,7 @@ impl<'tcx> ConstToPat<'tcx> {
274
251
// convert the dereferenced constant to a pattern that is the sub-pattern of the
275
252
// deref pattern.
276
253
_ => {
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 ( ) {
280
255
let err = UnsizedPattern { span, non_sm_ty : * pointee_ty } ;
281
256
let e = tcx. dcx ( ) . emit_err ( err) ;
282
257
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
0 commit comments