@@ -165,6 +165,23 @@ pub struct GenericArgCountResult {
165
165
pub correct : Result < ( ) , GenericArgCountMismatch > ,
166
166
}
167
167
168
+ pub trait CreateSubstsForGenericArgsCtxt < ' a , ' tcx > {
169
+ fn args_for_def_id ( & mut self , def_id : DefId ) -> ( Option < & ' a GenericArgs < ' a > > , bool ) ;
170
+
171
+ fn provided_kind (
172
+ & mut self ,
173
+ param : & ty:: GenericParamDef ,
174
+ arg : & GenericArg < ' _ > ,
175
+ ) -> subst:: GenericArg < ' tcx > ;
176
+
177
+ fn inferred_kind (
178
+ & mut self ,
179
+ substs : Option < & [ subst:: GenericArg < ' tcx > ] > ,
180
+ param : & ty:: GenericParamDef ,
181
+ infer_args : bool ,
182
+ ) -> subst:: GenericArg < ' tcx > ;
183
+ }
184
+
168
185
impl < ' o , ' tcx > dyn AstConv < ' tcx > + ' o {
169
186
pub fn ast_region_to_region (
170
187
& self ,
@@ -321,81 +338,102 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
321
338
) ;
322
339
323
340
let is_object = self_ty. map_or ( false , |ty| ty == self . tcx ( ) . types . trait_object_dummy_self ) ;
324
- let default_needs_object_self = |param : & ty:: GenericParamDef | {
325
- if let GenericParamDefKind :: Type { has_default, .. } = param. kind {
326
- if is_object && has_default {
327
- let default_ty = tcx. at ( span) . type_of ( param. def_id ) ;
328
- let self_param = tcx. types . self_param ;
329
- if default_ty. walk ( ) . any ( |arg| arg == self_param. into ( ) ) {
330
- // There is no suitable inference default for a type parameter
331
- // that references self, in an object type.
332
- return true ;
341
+
342
+ struct SubstsForAstPathCtxt < ' a , ' tcx > {
343
+ astconv : & ' a ( dyn AstConv < ' tcx > + ' a ) ,
344
+ def_id : DefId ,
345
+ generic_args : & ' a GenericArgs < ' a > ,
346
+ span : Span ,
347
+ missing_type_params : Vec < String > ,
348
+ inferred_params : Vec < Span > ,
349
+ infer_args : bool ,
350
+ is_object : bool ,
351
+ }
352
+
353
+ impl < ' tcx , ' a > SubstsForAstPathCtxt < ' tcx , ' a > {
354
+ fn default_needs_object_self ( & mut self , param : & ty:: GenericParamDef ) -> bool {
355
+ let tcx = self . astconv . tcx ( ) ;
356
+ if let GenericParamDefKind :: Type { has_default, .. } = param. kind {
357
+ if self . is_object && has_default {
358
+ let default_ty = tcx. at ( self . span ) . type_of ( param. def_id ) ;
359
+ let self_param = tcx. types . self_param ;
360
+ if default_ty. walk ( ) . any ( |arg| arg == self_param. into ( ) ) {
361
+ // There is no suitable inference default for a type parameter
362
+ // that references self, in an object type.
363
+ return true ;
364
+ }
333
365
}
334
366
}
335
- }
336
367
337
- false
338
- } ;
368
+ false
369
+ }
370
+ }
339
371
340
- let mut missing_type_params = vec ! [ ] ;
341
- let mut inferred_params = vec ! [ ] ;
342
- let substs = Self :: create_substs_for_generic_args (
343
- tcx,
344
- def_id,
345
- parent_substs,
346
- self_ty. is_some ( ) ,
347
- self_ty,
348
- arg_count. clone ( ) ,
349
- // Provide the generic args, and whether types should be inferred.
350
- |did| {
351
- if did == def_id {
352
- ( Some ( generic_args) , infer_args)
372
+ impl < ' a , ' tcx > CreateSubstsForGenericArgsCtxt < ' a , ' tcx > for SubstsForAstPathCtxt < ' a , ' tcx > {
373
+ fn args_for_def_id ( & mut self , did : DefId ) -> ( Option < & ' a GenericArgs < ' a > > , bool ) {
374
+ if did == self . def_id {
375
+ ( Some ( self . generic_args ) , self . infer_args )
353
376
} else {
354
377
// The last component of this tuple is unimportant.
355
378
( None , false )
356
379
}
357
- } ,
358
- // Provide substitutions for parameters for which (valid) arguments have been provided.
359
- |param, arg| match ( & param. kind , arg) {
360
- ( GenericParamDefKind :: Lifetime , GenericArg :: Lifetime ( lt) ) => {
361
- self . ast_region_to_region ( & lt, Some ( param) ) . into ( )
362
- }
363
- ( GenericParamDefKind :: Type { has_default, .. } , GenericArg :: Type ( ty) ) => {
364
- if * has_default {
365
- tcx. check_optional_stability (
366
- param. def_id ,
367
- Some ( arg. id ( ) ) ,
368
- arg. span ( ) ,
369
- |_, _| {
370
- // Default generic parameters may not be marked
371
- // with stability attributes, i.e. when the
372
- // default parameter was defined at the same time
373
- // as the rest of the type. As such, we ignore missing
374
- // stability attributes.
380
+ }
381
+
382
+ fn provided_kind (
383
+ & mut self ,
384
+ param : & ty:: GenericParamDef ,
385
+ arg : & GenericArg < ' _ > ,
386
+ ) -> subst:: GenericArg < ' tcx > {
387
+ let tcx = self . astconv . tcx ( ) ;
388
+ match ( & param. kind , arg) {
389
+ ( GenericParamDefKind :: Lifetime , GenericArg :: Lifetime ( lt) ) => {
390
+ self . astconv . ast_region_to_region ( & lt, Some ( param) ) . into ( )
391
+ }
392
+ ( & GenericParamDefKind :: Type { has_default, .. } , GenericArg :: Type ( ty) ) => {
393
+ if has_default {
394
+ tcx. check_optional_stability (
395
+ param. def_id ,
396
+ Some ( arg. id ( ) ) ,
397
+ arg. span ( ) ,
398
+ |_, _| {
399
+ // Default generic parameters may not be marked
400
+ // with stability attributes, i.e. when the
401
+ // default parameter was defined at the same time
402
+ // as the rest of the type. As such, we ignore missing
403
+ // stability attributes.
404
+ } ,
405
+ )
406
+ }
407
+ if let ( hir:: TyKind :: Infer , false ) =
408
+ ( & ty. kind , self . astconv . allow_ty_infer ( ) )
409
+ {
410
+ self . inferred_params . push ( ty. span ) ;
411
+ tcx. ty_error ( ) . into ( )
412
+ } else {
413
+ self . astconv . ast_ty_to_ty ( & ty) . into ( )
414
+ }
415
+ }
416
+ ( GenericParamDefKind :: Const , GenericArg :: Const ( ct) ) => {
417
+ ty:: Const :: from_opt_const_arg_anon_const (
418
+ tcx,
419
+ ty:: WithOptConstParam {
420
+ did : tcx. hir ( ) . local_def_id ( ct. value . hir_id ) ,
421
+ const_param_did : Some ( param. def_id ) ,
375
422
} ,
376
423
)
424
+ . into ( )
377
425
}
378
- if let ( hir:: TyKind :: Infer , false ) = ( & ty. kind , self . allow_ty_infer ( ) ) {
379
- inferred_params. push ( ty. span ) ;
380
- tcx. ty_error ( ) . into ( )
381
- } else {
382
- self . ast_ty_to_ty ( & ty) . into ( )
383
- }
384
- }
385
- ( GenericParamDefKind :: Const , GenericArg :: Const ( ct) ) => {
386
- ty:: Const :: from_opt_const_arg_anon_const (
387
- tcx,
388
- ty:: WithOptConstParam {
389
- did : tcx. hir ( ) . local_def_id ( ct. value . hir_id ) ,
390
- const_param_did : Some ( param. def_id ) ,
391
- } ,
392
- )
393
- . into ( )
426
+ _ => unreachable ! ( ) ,
394
427
}
395
- _ => unreachable ! ( ) ,
396
- } ,
397
- // Provide substitutions for parameters for which arguments are inferred.
398
- |substs, param, infer_args| {
428
+ }
429
+
430
+ fn inferred_kind (
431
+ & mut self ,
432
+ substs : Option < & [ subst:: GenericArg < ' tcx > ] > ,
433
+ param : & ty:: GenericParamDef ,
434
+ infer_args : bool ,
435
+ ) -> subst:: GenericArg < ' tcx > {
436
+ let tcx = self . astconv . tcx ( ) ;
399
437
match param. kind {
400
438
GenericParamDefKind :: Lifetime => tcx. lifetimes . re_static . into ( ) ,
401
439
GenericParamDefKind :: Type { has_default, .. } => {
@@ -407,48 +445,72 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
407
445
// other type parameters may reference `Self` in their
408
446
// defaults. This will lead to an ICE if we are not
409
447
// careful!
410
- if default_needs_object_self ( param) {
411
- missing_type_params. push ( param. name . to_string ( ) ) ;
448
+ if self . default_needs_object_self ( param) {
449
+ self . missing_type_params . push ( param. name . to_string ( ) ) ;
412
450
tcx. ty_error ( ) . into ( )
413
451
} else {
414
452
// This is a default type parameter.
415
- self . normalize_ty (
416
- span,
417
- tcx. at ( span) . type_of ( param. def_id ) . subst_spanned (
418
- tcx,
419
- substs. unwrap ( ) ,
420
- Some ( span) ,
421
- ) ,
422
- )
423
- . into ( )
453
+ self . astconv
454
+ . normalize_ty (
455
+ self . span ,
456
+ tcx. at ( self . span ) . type_of ( param. def_id ) . subst_spanned (
457
+ tcx,
458
+ substs. unwrap ( ) ,
459
+ Some ( self . span ) ,
460
+ ) ,
461
+ )
462
+ . into ( )
424
463
}
425
464
} else if infer_args {
426
465
// No type parameters were provided, we can infer all.
427
- let param =
428
- if !default_needs_object_self ( param) { Some ( param) } else { None } ;
429
- self . ty_infer ( param, span) . into ( )
466
+ let param = if !self . default_needs_object_self ( param) {
467
+ Some ( param)
468
+ } else {
469
+ None
470
+ } ;
471
+ self . astconv . ty_infer ( param, self . span ) . into ( )
430
472
} else {
431
473
// We've already errored above about the mismatch.
432
474
tcx. ty_error ( ) . into ( )
433
475
}
434
476
}
435
477
GenericParamDefKind :: Const => {
436
- let ty = tcx. at ( span) . type_of ( param. def_id ) ;
478
+ let ty = tcx. at ( self . span ) . type_of ( param. def_id ) ;
437
479
// FIXME(const_generics:defaults)
438
480
if infer_args {
439
481
// No const parameters were provided, we can infer all.
440
- self . ct_infer ( ty, Some ( param) , span) . into ( )
482
+ self . astconv . ct_infer ( ty, Some ( param) , self . span ) . into ( )
441
483
} else {
442
484
// We've already errored above about the mismatch.
443
485
tcx. const_error ( ty) . into ( )
444
486
}
445
487
}
446
488
}
447
- } ,
489
+ }
490
+ }
491
+
492
+ let mut substs_ctx = SubstsForAstPathCtxt {
493
+ astconv : self ,
494
+ def_id,
495
+ span,
496
+ generic_args,
497
+ missing_type_params : vec ! [ ] ,
498
+ inferred_params : vec ! [ ] ,
499
+ infer_args,
500
+ is_object,
501
+ } ;
502
+ let substs = Self :: create_substs_for_generic_args (
503
+ tcx,
504
+ def_id,
505
+ parent_substs,
506
+ self_ty. is_some ( ) ,
507
+ self_ty,
508
+ arg_count. clone ( ) ,
509
+ & mut substs_ctx,
448
510
) ;
449
511
450
512
self . complain_about_missing_type_params (
451
- missing_type_params,
513
+ substs_ctx . missing_type_params ,
452
514
def_id,
453
515
span,
454
516
generic_args. args . is_empty ( ) ,
0 commit comments