@@ -6,14 +6,15 @@ use super::assembly::{self, Candidate, CandidateSource};
6
6
use super :: infcx_ext:: InferCtxtExt ;
7
7
use super :: { EvalCtxt , Goal , QueryResult } ;
8
8
use rustc_hir:: def_id:: DefId ;
9
- use rustc_hir:: { Movability , Mutability } ;
10
9
use rustc_infer:: infer:: InferCtxt ;
11
10
use rustc_infer:: traits:: query:: NoSolution ;
12
11
use rustc_middle:: ty:: fast_reject:: { DeepRejectCtxt , TreatParams } ;
13
12
use rustc_middle:: ty:: TraitPredicate ;
14
13
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
15
14
use rustc_span:: DUMMY_SP ;
16
15
16
+ mod structural_traits;
17
+
17
18
impl < ' tcx > assembly:: GoalKind < ' tcx > for TraitPredicate < ' tcx > {
18
19
fn self_ty ( self ) -> Ty < ' tcx > {
19
20
self . self_ty ( )
@@ -85,11 +86,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
85
86
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
86
87
goal : Goal < ' tcx , Self > ,
87
88
) -> QueryResult < ' tcx > {
88
- ecx. infcx . probe ( |_| {
89
- let constituent_tys =
90
- instantiate_constituent_tys_for_auto_trait ( ecx. infcx , goal. predicate . self_ty ( ) ) ?;
91
- ecx. evaluate_goal_for_constituent_tys_and_make_canonical_response ( goal, constituent_tys)
92
- } )
89
+ ecx. probe_and_evaluate_goal_for_constituent_tys (
90
+ goal,
91
+ structural_traits:: instantiate_constituent_tys_for_auto_trait,
92
+ )
93
93
}
94
94
95
95
fn consider_trait_alias_candidate (
@@ -112,44 +112,46 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
112
112
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
113
113
goal : Goal < ' tcx , Self > ,
114
114
) -> QueryResult < ' tcx > {
115
- ecx. infcx . probe ( |_| {
116
- let constituent_tys =
117
- instantiate_constituent_tys_for_sized_trait ( ecx. infcx , goal. predicate . self_ty ( ) ) ?;
118
- ecx. evaluate_goal_for_constituent_tys_and_make_canonical_response ( goal, constituent_tys)
119
- } )
115
+ ecx. probe_and_evaluate_goal_for_constituent_tys (
116
+ goal,
117
+ structural_traits:: instantiate_constituent_tys_for_sized_trait,
118
+ )
120
119
}
121
120
122
121
fn consider_builtin_copy_clone_candidate (
123
122
ecx : & mut EvalCtxt < ' _ , ' tcx > ,
124
123
goal : Goal < ' tcx , Self > ,
125
124
) -> QueryResult < ' tcx > {
126
- ecx. infcx . probe ( |_| {
127
- let constituent_tys = instantiate_constituent_tys_for_copy_clone_trait (
128
- ecx. infcx ,
129
- goal. predicate . self_ty ( ) ,
130
- ) ?;
131
- ecx. evaluate_goal_for_constituent_tys_and_make_canonical_response ( goal, constituent_tys)
132
- } )
125
+ ecx. probe_and_evaluate_goal_for_constituent_tys (
126
+ goal,
127
+ structural_traits:: instantiate_constituent_tys_for_copy_clone_trait,
128
+ )
133
129
}
134
130
}
135
131
136
132
impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
137
- fn evaluate_goal_for_constituent_tys_and_make_canonical_response (
133
+ /// Convenience function for traits that are structural, i.e. that only
134
+ /// have nested subgoals that only change the self type. Unlike other
135
+ /// evaluate-like helpers, this does a probe, so it doesn't need to be
136
+ /// wrapped in one.
137
+ fn probe_and_evaluate_goal_for_constituent_tys (
138
138
& mut self ,
139
139
goal : Goal < ' tcx , TraitPredicate < ' tcx > > ,
140
- constituent_tys : Vec < Ty < ' tcx > > ,
140
+ constituent_tys : impl Fn ( & InferCtxt < ' tcx > , Ty < ' tcx > ) -> Result < Vec < Ty < ' tcx > > , NoSolution > ,
141
141
) -> QueryResult < ' tcx > {
142
- self . evaluate_all_and_make_canonical_response (
143
- constituent_tys
144
- . into_iter ( )
145
- . map ( |ty| {
146
- goal. with (
147
- self . tcx ( ) ,
148
- ty:: Binder :: dummy ( goal. predicate . with_self_ty ( self . tcx ( ) , ty) ) ,
149
- )
150
- } )
151
- . collect ( ) ,
152
- )
142
+ self . infcx . probe ( |_| {
143
+ self . evaluate_all_and_make_canonical_response (
144
+ constituent_tys ( self . infcx , goal. predicate . self_ty ( ) ) ?
145
+ . into_iter ( )
146
+ . map ( |ty| {
147
+ goal. with (
148
+ self . tcx ( ) ,
149
+ ty:: Binder :: dummy ( goal. predicate . with_self_ty ( self . tcx ( ) , ty) ) ,
150
+ )
151
+ } )
152
+ . collect ( ) ,
153
+ )
154
+ } )
153
155
}
154
156
155
157
pub ( super ) fn compute_trait_goal (
@@ -227,187 +229,3 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
227
229
candidate
228
230
}
229
231
}
230
-
231
- // Calculates the constituent types of a type for `auto trait` purposes.
232
- //
233
- // For types with an "existential" binder, i.e. generator witnesses, we also
234
- // instantiate the binder with placeholders eagerly.
235
- fn instantiate_constituent_tys_for_auto_trait < ' tcx > (
236
- infcx : & InferCtxt < ' tcx > ,
237
- ty : Ty < ' tcx > ,
238
- ) -> Result < Vec < Ty < ' tcx > > , NoSolution > {
239
- let tcx = infcx. tcx ;
240
- match * ty. kind ( ) {
241
- ty:: Uint ( _)
242
- | ty:: Int ( _)
243
- | ty:: Bool
244
- | ty:: Float ( _)
245
- | ty:: FnDef ( ..)
246
- | ty:: FnPtr ( _)
247
- | ty:: Str
248
- | ty:: Error ( _)
249
- | ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
250
- | ty:: Never
251
- | ty:: Char => Ok ( vec ! [ ] ) ,
252
-
253
- ty:: Placeholder ( ..)
254
- | ty:: Dynamic ( ..)
255
- | ty:: Param ( ..)
256
- | ty:: Foreign ( ..)
257
- | ty:: Alias ( ty:: Projection , ..)
258
- | ty:: Bound ( ..)
259
- | ty:: Infer ( ty:: TyVar ( _) ) => {
260
- // FIXME: Do we need to mark anything as ambiguous here? Yeah?
261
- Err ( NoSolution )
262
- }
263
-
264
- ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => bug ! ( ) ,
265
-
266
- ty:: RawPtr ( ty:: TypeAndMut { ty : element_ty, .. } ) | ty:: Ref ( _, element_ty, _) => {
267
- Ok ( vec ! [ element_ty] )
268
- }
269
-
270
- ty:: Array ( element_ty, _) | ty:: Slice ( element_ty) => Ok ( vec ! [ element_ty] ) ,
271
-
272
- ty:: Tuple ( ref tys) => {
273
- // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
274
- Ok ( tys. iter ( ) . collect ( ) )
275
- }
276
-
277
- ty:: Closure ( _, ref substs) => Ok ( vec ! [ substs. as_closure( ) . tupled_upvars_ty( ) ] ) ,
278
-
279
- ty:: Generator ( _, ref substs, _) => {
280
- let generator_substs = substs. as_generator ( ) ;
281
- Ok ( vec ! [ generator_substs. tupled_upvars_ty( ) , generator_substs. witness( ) ] )
282
- }
283
-
284
- ty:: GeneratorWitness ( types) => {
285
- Ok ( infcx. replace_bound_vars_with_placeholders ( types) . to_vec ( ) )
286
- }
287
-
288
- // For `PhantomData<T>`, we pass `T`.
289
- ty:: Adt ( def, substs) if def. is_phantom_data ( ) => Ok ( vec ! [ substs. type_at( 0 ) ] ) ,
290
-
291
- ty:: Adt ( def, substs) => Ok ( def. all_fields ( ) . map ( |f| f. ty ( tcx, substs) ) . collect ( ) ) ,
292
-
293
- ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
294
- // We can resolve the `impl Trait` to its concrete type,
295
- // which enforces a DAG between the functions requiring
296
- // the auto trait bounds in question.
297
- Ok ( vec ! [ tcx. bound_type_of( def_id) . subst( tcx, substs) ] )
298
- }
299
- }
300
- }
301
-
302
- fn instantiate_constituent_tys_for_sized_trait < ' tcx > (
303
- infcx : & InferCtxt < ' tcx > ,
304
- ty : Ty < ' tcx > ,
305
- ) -> Result < Vec < Ty < ' tcx > > , NoSolution > {
306
- match * ty. kind ( ) {
307
- ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
308
- | ty:: Uint ( _)
309
- | ty:: Int ( _)
310
- | ty:: Bool
311
- | ty:: Float ( _)
312
- | ty:: FnDef ( ..)
313
- | ty:: FnPtr ( _)
314
- | ty:: RawPtr ( ..)
315
- | ty:: Char
316
- | ty:: Ref ( ..)
317
- | ty:: Generator ( ..)
318
- | ty:: GeneratorWitness ( ..)
319
- | ty:: Array ( ..)
320
- | ty:: Closure ( ..)
321
- | ty:: Never
322
- | ty:: Dynamic ( _, _, ty:: DynStar )
323
- | ty:: Error ( _) => Ok ( vec ! [ ] ) ,
324
-
325
- ty:: Str
326
- | ty:: Slice ( _)
327
- | ty:: Dynamic ( ..)
328
- | ty:: Foreign ( ..)
329
- | ty:: Alias ( ..)
330
- | ty:: Param ( _) => Err ( NoSolution ) ,
331
-
332
- ty:: Infer ( ty:: TyVar ( _) ) => bug ! ( "FIXME: ambiguous" ) ,
333
-
334
- ty:: Placeholder ( ..)
335
- | ty:: Bound ( ..)
336
- | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => bug ! ( ) ,
337
-
338
- ty:: Tuple ( tys) => Ok ( tys. to_vec ( ) ) ,
339
-
340
- ty:: Adt ( def, substs) => {
341
- let sized_crit = def. sized_constraint ( infcx. tcx ) ;
342
- Ok ( sized_crit
343
- . 0
344
- . iter ( )
345
- . map ( |ty| sized_crit. rebind ( * ty) . subst ( infcx. tcx , substs) )
346
- . collect ( ) )
347
- }
348
- }
349
- }
350
-
351
- fn instantiate_constituent_tys_for_copy_clone_trait < ' tcx > (
352
- infcx : & InferCtxt < ' tcx > ,
353
- ty : Ty < ' tcx > ,
354
- ) -> Result < Vec < Ty < ' tcx > > , NoSolution > {
355
- match * ty. kind ( ) {
356
- ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
357
- | ty:: FnDef ( ..)
358
- | ty:: FnPtr ( _)
359
- | ty:: Error ( _) => Ok ( vec ! [ ] ) ,
360
-
361
- // Implementations are provided in core
362
- ty:: Uint ( _)
363
- | ty:: Int ( _)
364
- | ty:: Bool
365
- | ty:: Float ( _)
366
- | ty:: Char
367
- | ty:: RawPtr ( ..)
368
- | ty:: Never
369
- | ty:: Ref ( _, _, Mutability :: Not )
370
- | ty:: Array ( ..) => Err ( NoSolution ) ,
371
-
372
- ty:: Dynamic ( ..)
373
- | ty:: Str
374
- | ty:: Slice ( _)
375
- | ty:: Generator ( _, _, Movability :: Static )
376
- | ty:: Foreign ( ..)
377
- | ty:: Ref ( _, _, Mutability :: Mut )
378
- | ty:: Adt ( _, _)
379
- | ty:: Alias ( _, _)
380
- | ty:: Param ( _) => Err ( NoSolution ) ,
381
-
382
- ty:: Infer ( ty:: TyVar ( _) ) => bug ! ( "FIXME: ambiguous" ) ,
383
-
384
- ty:: Placeholder ( ..)
385
- | ty:: Bound ( ..)
386
- | ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => bug ! ( ) ,
387
-
388
- ty:: Tuple ( tys) => Ok ( tys. to_vec ( ) ) ,
389
-
390
- ty:: Closure ( _, substs) => match * substs. as_closure ( ) . tupled_upvars_ty ( ) . kind ( ) {
391
- ty:: Tuple ( tys) => Ok ( tys. to_vec ( ) ) ,
392
- ty:: Infer ( ty:: TyVar ( _) ) => bug ! ( "FIXME: ambiguous" ) ,
393
- _ => bug ! ( ) ,
394
- } ,
395
-
396
- ty:: Generator ( _, substs, Movability :: Movable ) => {
397
- if infcx. tcx . features ( ) . generator_clone {
398
- let generator = substs. as_generator ( ) ;
399
- match * generator. tupled_upvars_ty ( ) . kind ( ) {
400
- ty:: Tuple ( tys) => Ok ( tys. iter ( ) . chain ( [ generator. witness ( ) ] ) . collect ( ) ) ,
401
- ty:: Infer ( ty:: TyVar ( _) ) => bug ! ( "FIXME: ambiguous" ) ,
402
- _ => bug ! ( ) ,
403
- }
404
- } else {
405
- Err ( NoSolution )
406
- }
407
- }
408
-
409
- ty:: GeneratorWitness ( types) => {
410
- Ok ( infcx. replace_bound_vars_with_placeholders ( types) . to_vec ( ) )
411
- }
412
- }
413
- }
0 commit comments