14
14
15
15
use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
16
16
use rustc_data_structures:: array_vec:: ArrayVec ;
17
- use hir:: { self , GenericArg } ;
17
+ use hir:: { self , GenericArg , GenericArgs } ;
18
18
use hir:: def:: Def ;
19
19
use hir:: def_id:: DefId ;
20
20
use middle:: resolve_lifetime as rl;
21
21
use namespace:: Namespace ;
22
22
use rustc:: ty:: subst:: { Kind , Subst , Substs } ;
23
23
use rustc:: traits;
24
24
use rustc:: ty:: { self , Ty , TyCtxt , ToPredicate , TypeFoldable } ;
25
- use rustc:: ty:: GenericParamDefKind ;
25
+ use rustc:: ty:: { GenericParamDef , GenericParamDefKind } ;
26
26
use rustc:: ty:: wf:: object_region_bounds;
27
27
use rustc_target:: spec:: abi;
28
28
use std:: slice;
@@ -192,6 +192,153 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
192
192
substs
193
193
}
194
194
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
+
195
342
/// Given the type/region arguments provided to some path (along with
196
343
/// an implicit Self, if this is a trait reference) returns the complete
197
344
/// set of substitutions. This may involve applying defaulted type parameters.
@@ -271,95 +418,37 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
271
418
false
272
419
} ;
273
420
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 ( )
312
437
}
438
+ _ => unreachable ! ( ) ,
313
439
}
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 ! ( ) ,
345
443
}
346
444
}
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| {
350
448
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 ( ) ,
354
450
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 {
363
452
// No type parameter provided, but a default exists.
364
453
365
454
// If we are converting an object type, then the
@@ -378,26 +467,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
378
467
type parameters must be specified on object \
379
468
types") )
380
469
. emit ( ) ;
381
- push_kind ( & mut substs , tcx. types . err . into ( ) ) ;
470
+ tcx. types . err . into ( )
382
471
} else {
383
472
// This is a default type parameter.
384
- let kind = self . normalize_ty (
473
+ self . normalize_ty (
385
474
span,
386
475
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 ( )
390
485
}
391
486
} else {
392
487
// We've already errored above about the mismatch.
393
- push_kind ( & mut substs , tcx. types . err . into ( ) ) ;
488
+ tcx. types . err . into ( )
394
489
}
395
490
}
396
- } ;
397
- next_param = params. next ( ) ;
398
- }
399
- }
400
- let substs = self . tcx ( ) . intern_substs ( & substs) ;
491
+ }
492
+ } ,
493
+ ) ;
401
494
402
495
let assoc_bindings = generic_args. bindings . iter ( ) . map ( |binding| {
403
496
ConvertedBinding {
0 commit comments