@@ -6,14 +6,15 @@ use super::assembly::{self, Candidate, CandidateSource};
66use super :: infcx_ext:: InferCtxtExt ;
77use super :: { EvalCtxt , Goal , QueryResult } ;
88use rustc_hir:: def_id:: DefId ;
9- use rustc_hir:: { Movability , Mutability } ;
109use rustc_infer:: infer:: InferCtxt ;
1110use rustc_infer:: traits:: query:: NoSolution ;
1211use rustc_middle:: ty:: fast_reject:: { DeepRejectCtxt , TreatParams } ;
1312use rustc_middle:: ty:: TraitPredicate ;
1413use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1514use rustc_span:: DUMMY_SP ;
1615
16+ mod structural_traits;
17+
1718impl < ' tcx > assembly:: GoalKind < ' tcx > for TraitPredicate < ' tcx > {
1819 fn self_ty ( self ) -> Ty < ' tcx > {
1920 self . self_ty ( )
@@ -85,11 +86,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
8586 ecx : & mut EvalCtxt < ' _ , ' tcx > ,
8687 goal : Goal < ' tcx , Self > ,
8788 ) -> 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+ )
9393 }
9494
9595 fn consider_trait_alias_candidate (
@@ -112,44 +112,46 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
112112 ecx : & mut EvalCtxt < ' _ , ' tcx > ,
113113 goal : Goal < ' tcx , Self > ,
114114 ) -> 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+ )
120119 }
121120
122121 fn consider_builtin_copy_clone_candidate (
123122 ecx : & mut EvalCtxt < ' _ , ' tcx > ,
124123 goal : Goal < ' tcx , Self > ,
125124 ) -> 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+ )
133129 }
134130}
135131
136132impl < ' 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 (
138138 & mut self ,
139139 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 > ,
141141 ) -> 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+ } )
153155 }
154156
155157 pub ( super ) fn compute_trait_goal (
@@ -227,187 +229,3 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
227229 candidate
228230 }
229231}
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