1414
1515use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
1616use rustc_data_structures:: array_vec:: ArrayVec ;
17- use hir:: { self , GenericArg } ;
17+ use hir:: { self , GenericArg , GenericArgs } ;
1818use hir:: def:: Def ;
1919use hir:: def_id:: DefId ;
2020use middle:: resolve_lifetime as rl;
2121use namespace:: Namespace ;
2222use rustc:: ty:: subst:: { Kind , Subst , Substs } ;
2323use rustc:: traits;
2424use rustc:: ty:: { self , Ty , TyCtxt , ToPredicate , TypeFoldable } ;
25- use rustc:: ty:: GenericParamDefKind ;
25+ use rustc:: ty:: { GenericParamDef , GenericParamDefKind } ;
2626use rustc:: ty:: wf:: object_region_bounds;
2727use rustc_target:: spec:: abi;
2828use std:: slice;
@@ -192,6 +192,153 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
192192 substs
193193 }
194194
195+ /// Creates the relevant generic argument substitutions
196+ /// corresponding to a set of generic parameters.
197+ pub fn create_substs_for_generic_args < ' a , ' b , A , P , I > (
198+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
199+ span : Span ,
200+ err_if_invalid : bool ,
201+ def_id : DefId ,
202+ parent_substs : & [ Kind < ' tcx > ] ,
203+ has_self : bool ,
204+ self_ty : Option < Ty < ' tcx > > ,
205+ args_for_def_id : A ,
206+ provided_kind : P ,
207+ inferred_kind : I ,
208+ ) -> & ' tcx Substs < ' tcx > where
209+ A : Fn ( DefId ) -> ( Option < & ' b GenericArgs > , bool ) ,
210+ P : Fn ( & GenericParamDef , & GenericArg ) -> Kind < ' tcx > ,
211+ I : Fn ( Option < & [ Kind < ' tcx > ] > , & GenericParamDef , bool ) -> Kind < ' tcx >
212+ {
213+ // Collect the segments of the path: we need to substitute arguments
214+ // for parameters throughout the entire path (wherever there are
215+ // generic parameters).
216+ let mut parent_defs = tcx. generics_of ( def_id) ;
217+ let count = parent_defs. count ( ) ;
218+ let mut stack = vec ! [ ( def_id, parent_defs) ] ;
219+ while let Some ( def_id) = parent_defs. parent {
220+ parent_defs = tcx. generics_of ( def_id) ;
221+ stack. push ( ( def_id, parent_defs) ) ;
222+ }
223+
224+ // We manually build up the substitution, rather than using convenience
225+ // methods in subst.rs so that we can iterate over the arguments and
226+ // parameters in lock-step linearly, rather than trying to match each pair.
227+ let mut substs: AccumulateVec < [ Kind < ' tcx > ; 8 ] > = if count <= 8 {
228+ AccumulateVec :: Array ( ArrayVec :: new ( ) )
229+ } else {
230+ AccumulateVec :: Heap ( Vec :: with_capacity ( count) )
231+ } ;
232+
233+ fn push_kind < ' tcx > ( substs : & mut AccumulateVec < [ Kind < ' tcx > ; 8 ] > , kind : Kind < ' tcx > ) {
234+ match substs {
235+ AccumulateVec :: Array ( ref mut arr) => arr. push ( kind) ,
236+ AccumulateVec :: Heap ( ref mut vec) => vec. push ( kind) ,
237+ }
238+ }
239+
240+ // Iterate over each segment of the path.
241+ while let Some ( ( def_id, defs) ) = stack. pop ( ) {
242+ let mut params = defs. params . iter ( ) ;
243+ let mut next_param = params. next ( ) ;
244+
245+ // If we have already computed substitutions for parents, we can use those directly.
246+ while let Some ( param) = next_param {
247+ if let Some ( & kind) = parent_substs. get ( param. index as usize ) {
248+ push_kind ( & mut substs, kind) ;
249+ next_param = params. next ( ) ;
250+ } else {
251+ break ;
252+ }
253+ }
254+
255+ // (Unless it's been handled in `parent_substs`) `Self` is handled first.
256+ if has_self {
257+ if let Some ( param) = next_param {
258+ if param. index == 0 {
259+ if let GenericParamDefKind :: Type { .. } = param. kind {
260+ push_kind ( & mut substs, self_ty. map ( |ty| ty. into ( ) )
261+ . unwrap_or_else ( || inferred_kind ( None , param, true ) ) ) ;
262+ next_param = params. next ( ) ;
263+ }
264+ }
265+ }
266+ }
267+
268+ // Check whether this segment takes generic arguments and the user has provided any.
269+ let ( generic_args, infer_types) = args_for_def_id ( def_id) ;
270+ if let Some ( ref generic_args) = generic_args {
271+ // We're going to iterate through the generic arguments that the user
272+ // provided, matching them with the generic parameters we expect.
273+ // Mismatches can occur as a result of elided lifetimes, or for malformed
274+ // input. We try to handle both sensibly.
275+ ' args: for arg in & generic_args. args {
276+ while let Some ( param) = next_param {
277+ match param. kind {
278+ GenericParamDefKind :: Lifetime => match arg {
279+ GenericArg :: Lifetime ( _) => {
280+ push_kind ( & mut substs, provided_kind ( param, arg) ) ;
281+ next_param = params. next ( ) ;
282+ continue ' args;
283+ }
284+ GenericArg :: Type ( _) => {
285+ // We expected a lifetime argument, but got a type
286+ // argument. That means we're inferring the lifetimes.
287+ push_kind ( & mut substs, inferred_kind ( None , param, infer_types) ) ;
288+ next_param = params. next ( ) ;
289+ }
290+ }
291+ GenericParamDefKind :: Type { .. } => match arg {
292+ GenericArg :: Type ( _) => {
293+ push_kind ( & mut substs, provided_kind ( param, arg) ) ;
294+ next_param = params. next ( ) ;
295+ continue ' args;
296+ }
297+ GenericArg :: Lifetime ( _) => {
298+ // We expected a type argument, but got a lifetime
299+ // argument. This is an error, but we need to handle it
300+ // gracefully so we can report sensible errors. In this
301+ // case, we're simply going to infer the remaining
302+ // arguments.
303+ if err_if_invalid {
304+ tcx. sess . delay_span_bug ( span,
305+ "found a GenericArg::Lifetime where a \
306+ GenericArg::Type was expected") ;
307+ }
308+ break ' args;
309+ }
310+ }
311+ }
312+ }
313+ // We should never be able to reach this point with well-formed input.
314+ // Getting to this point means the user supplied more arguments than
315+ // there are parameters.
316+ if err_if_invalid {
317+ tcx. sess . delay_span_bug ( span,
318+ "GenericArg did not have matching GenericParamDef" ) ;
319+ }
320+ }
321+ }
322+
323+ // If there are fewer arguments than parameters, it means
324+ // we're inferring the remaining arguments.
325+ while let Some ( param) = next_param {
326+ match param. kind {
327+ GenericParamDefKind :: Lifetime => {
328+ push_kind ( & mut substs, inferred_kind ( None , param, infer_types) ) ;
329+ }
330+ GenericParamDefKind :: Type { .. } => {
331+ let kind = inferred_kind ( Some ( & substs) , param, infer_types) ;
332+ push_kind ( & mut substs, kind) ;
333+ }
334+ }
335+ next_param = params. next ( ) ;
336+ }
337+ }
338+
339+ tcx. intern_substs ( & substs)
340+ }
341+
195342 /// Given the type/region arguments provided to some path (along with
196343 /// an implicit Self, if this is a trait reference) returns the complete
197344 /// set of substitutions. This may involve applying defaulted type parameters.
@@ -271,95 +418,37 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
271418 false
272419 } ;
273420
274- // Collect the segments of the path: we need to substitute arguments
275- // for parameters throughout the entire path (wherever there are
276- // generic parameters).
277- let mut parent_defs = self . tcx ( ) . generics_of ( def_id) ;
278- let count = parent_defs. count ( ) ;
279- let mut stack = vec ! [ ( def_id, parent_defs) ] ;
280- while let Some ( def_id) = parent_defs. parent {
281- parent_defs = self . tcx ( ) . generics_of ( def_id) ;
282- stack. push ( ( def_id, parent_defs) ) ;
283- }
284-
285- // We manually build up the substitution, rather than using convenience
286- // methods in subst.rs so that we can iterate over the arguments and
287- // parameters in lock-step linearly, rather than trying to match each pair.
288- let mut substs: AccumulateVec < [ Kind < ' tcx > ; 8 ] > = if count <= 8 {
289- AccumulateVec :: Array ( ArrayVec :: new ( ) )
290- } else {
291- AccumulateVec :: Heap ( Vec :: with_capacity ( count) )
292- } ;
293- fn push_kind < ' tcx > ( substs : & mut AccumulateVec < [ Kind < ' tcx > ; 8 ] > , kind : Kind < ' tcx > ) {
294- match substs {
295- AccumulateVec :: Array ( ref mut arr) => arr. push ( kind) ,
296- AccumulateVec :: Heap ( ref mut vec) => vec. push ( kind) ,
297- }
298- }
299-
300- // Iterate over each segment of the path.
301- while let Some ( ( _, defs) ) = stack. pop ( ) {
302- let mut params = defs. params . iter ( ) ;
303- let mut next_param = params. next ( ) ;
304-
305- // `Self` is handled first.
306- if let Some ( ty) = self_ty {
307- if let Some ( param) = next_param {
308- if param. index == 0 {
309- if let GenericParamDefKind :: Type { .. } = param. kind {
310- push_kind ( & mut substs, ty. into ( ) ) ;
311- next_param = params. next ( ) ;
421+ let substs = Self :: create_substs_for_generic_args (
422+ self . tcx ( ) ,
423+ span,
424+ false ,
425+ def_id,
426+ & [ ] [ ..] ,
427+ self_ty. is_some ( ) ,
428+ self_ty,
429+ // Provide the generic args, and whether types should be inferred.
430+ |_| ( Some ( generic_args) , infer_types) ,
431+ // Provide substitutions for parameters for which (valid) arguments have been provided.
432+ |param, arg| {
433+ match param. kind {
434+ GenericParamDefKind :: Lifetime => match arg {
435+ GenericArg :: Lifetime ( lt) => {
436+ self . ast_region_to_region ( & lt, Some ( param) ) . into ( )
312437 }
438+ _ => unreachable ! ( ) ,
313439 }
314- }
315- }
316-
317- let args = & generic_args. args ;
318- ' args: for arg in args {
319- while let Some ( param) = next_param {
320- match param. kind {
321- GenericParamDefKind :: Lifetime => match arg {
322- GenericArg :: Lifetime ( lt) => {
323- push_kind ( & mut substs,
324- self . ast_region_to_region ( & lt, Some ( param) ) . into ( ) ) ;
325- next_param = params. next ( ) ;
326- continue ' args;
327- }
328- GenericArg :: Type ( _) => {
329- // We expected a lifetime argument, but got a type
330- // argument. That means we're inferring the lifetimes.
331- push_kind ( & mut substs, tcx. types . re_static . into ( ) ) ;
332- next_param = params. next ( ) ;
333- }
334- }
335- GenericParamDefKind :: Type { .. } => match arg {
336- GenericArg :: Type ( ty) => {
337- push_kind ( & mut substs, self . ast_ty_to_ty ( & ty) . into ( ) ) ;
338- next_param = params. next ( ) ;
339- continue ' args;
340- }
341- GenericArg :: Lifetime ( _) => {
342- break ' args;
343- }
344- }
440+ GenericParamDefKind :: Type { .. } => match arg {
441+ GenericArg :: Type ( ty) => self . ast_ty_to_ty ( & ty) . into ( ) ,
442+ _ => unreachable ! ( ) ,
345443 }
346444 }
347- }
348-
349- while let Some ( param) = next_param {
445+ } ,
446+ // Provide substitutions for parameters for which arguments are inferred.
447+ |substs , param, infer_types| {
350448 match param. kind {
351- GenericParamDefKind :: Lifetime => {
352- push_kind ( & mut substs, tcx. types . re_static . into ( ) ) ;
353- }
449+ GenericParamDefKind :: Lifetime => tcx. types . re_static . into ( ) ,
354450 GenericParamDefKind :: Type { has_default, .. } => {
355- if infer_types {
356- // No type parameters were provided, we can infer all.
357- push_kind ( & mut substs, if !default_needs_object_self ( param) {
358- self . ty_infer_for_def ( param, span) . into ( )
359- } else {
360- self . ty_infer ( span) . into ( )
361- } ) ;
362- } else if has_default {
451+ if !infer_types && has_default {
363452 // No type parameter provided, but a default exists.
364453
365454 // If we are converting an object type, then the
@@ -378,26 +467,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
378467 type parameters must be specified on object \
379468 types") )
380469 . emit ( ) ;
381- push_kind ( & mut substs , tcx. types . err . into ( ) ) ;
470+ tcx. types . err . into ( )
382471 } else {
383472 // This is a default type parameter.
384- let kind = self . normalize_ty (
473+ self . normalize_ty (
385474 span,
386475 tcx. at ( span) . type_of ( param. def_id )
387- . subst_spanned ( tcx, & substs, Some ( span) )
388- ) . into ( ) ;
389- push_kind ( & mut substs, kind) ;
476+ . subst_spanned ( tcx, substs. unwrap ( ) , Some ( span) )
477+ ) . into ( )
478+ }
479+ } else if infer_types {
480+ // No type parameters were provided, we can infer all.
481+ if !default_needs_object_self ( param) {
482+ self . ty_infer_for_def ( param, span) . into ( )
483+ } else {
484+ self . ty_infer ( span) . into ( )
390485 }
391486 } else {
392487 // We've already errored above about the mismatch.
393- push_kind ( & mut substs , tcx. types . err . into ( ) ) ;
488+ tcx. types . err . into ( )
394489 }
395490 }
396- } ;
397- next_param = params. next ( ) ;
398- }
399- }
400- let substs = self . tcx ( ) . intern_substs ( & substs) ;
491+ }
492+ } ,
493+ ) ;
401494
402495 let assoc_bindings = generic_args. bindings . iter ( ) . map ( |binding| {
403496 ConvertedBinding {
0 commit comments