@@ -8,7 +8,7 @@ use ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr};
8
8
use ty:: { Param , Bound , RawPtr , Ref , Never , Tuple } ;
9
9
use ty:: { Closure , Generator , GeneratorWitness , Foreign , Projection , Opaque } ;
10
10
use ty:: { Placeholder , UnnormalizedProjection , Dynamic , Int , Uint , Infer } ;
11
- use ty:: { self , Ty , TypeFoldable , GenericParamCount , GenericParamDefKind } ;
11
+ use ty:: { self , Ty , TypeFoldable } ;
12
12
use ty:: print:: { PrintCx , Print } ;
13
13
14
14
use std:: cell:: Cell ;
@@ -314,215 +314,125 @@ impl PrintCx<'a, 'gcx, 'tcx> {
314
314
fn parameterized < F : fmt:: Write > (
315
315
& mut self ,
316
316
f : & mut F ,
317
- did : DefId ,
317
+ mut def_id : DefId ,
318
318
substs : & Substs < ' tcx > ,
319
- projections : impl Iterator < Item = ty:: ExistentialProjection < ' tcx > > + Clone ,
319
+ projections : impl Iterator < Item = ty:: ExistentialProjection < ' tcx > > ,
320
320
) -> fmt:: Result {
321
- let key = self . tcx . def_key ( did) ;
322
-
323
- let verbose = self . is_verbose ;
324
- let mut num_supplied_defaults = 0 ;
325
- let has_self;
326
- let mut own_counts: GenericParamCount = Default :: default ( ) ;
327
- let mut is_value_path = false ;
328
- let mut item_name = Some ( key. disambiguated_data . data . as_interned_str ( ) ) ;
329
- let mut path_def_id = did;
330
- {
331
- // Unfortunately, some kinds of items (e.g., closures) don't have
332
- // generics. So walk back up the find the closest parent that DOES
333
- // have them.
334
- let mut item_def_id = did;
335
- loop {
336
- let key = self . tcx . def_key ( item_def_id) ;
337
- match key. disambiguated_data . data {
338
- DefPathData :: AssocTypeInTrait ( _) |
339
- DefPathData :: AssocTypeInImpl ( _) |
340
- DefPathData :: AssocExistentialInImpl ( _) |
341
- DefPathData :: Trait ( _) |
342
- DefPathData :: TraitAlias ( _) |
343
- DefPathData :: Impl |
344
- DefPathData :: TypeNs ( _) => {
345
- break ;
346
- }
347
- DefPathData :: ValueNs ( _) |
348
- DefPathData :: EnumVariant ( _) => {
349
- is_value_path = true ;
350
- break ;
351
- }
352
- DefPathData :: CrateRoot |
353
- DefPathData :: Misc |
354
- DefPathData :: Module ( _) |
355
- DefPathData :: MacroDef ( _) |
356
- DefPathData :: ClosureExpr |
357
- DefPathData :: TypeParam ( _) |
358
- DefPathData :: LifetimeParam ( _) |
359
- DefPathData :: Field ( _) |
360
- DefPathData :: StructCtor |
361
- DefPathData :: AnonConst |
362
- DefPathData :: ImplTrait |
363
- DefPathData :: GlobalMetaData ( _) => {
364
- // if we're making a symbol for something, there ought
365
- // to be a value or type-def or something in there
366
- // *somewhere*
367
- item_def_id. index = key. parent . unwrap_or_else ( || {
368
- bug ! ( "finding type for {:?}, encountered def-id {:?} with no \
369
- parent", did, item_def_id) ;
370
- } ) ;
371
- }
372
- }
321
+ let mut key = self . tcx . def_key ( def_id) ;
322
+ let is_value_ns = match key. disambiguated_data . data {
323
+ DefPathData :: ValueNs ( _) |
324
+ DefPathData :: EnumVariant ( _) => true ,
325
+
326
+ // Skip `StructCtor` so that `Struct::<T>` will be printed,
327
+ // instead of the less pretty `Struct<T>::{{constructor}}`.
328
+ DefPathData :: StructCtor => {
329
+ def_id. index = key. parent . unwrap ( ) ;
330
+ key = self . tcx . def_key ( def_id) ;
331
+ true
373
332
}
374
- let mut generics = self . tcx . generics_of ( item_def_id) ;
375
- let child_own_counts = generics. own_counts ( ) ;
376
- has_self = generics. has_self ;
377
-
378
- let mut child_types = 0 ;
379
- if let Some ( def_id) = generics. parent {
380
- // Methods.
381
- assert ! ( is_value_path) ;
382
- child_types = child_own_counts. types ;
383
- generics = self . tcx . generics_of ( def_id) ;
384
- own_counts = generics. own_counts ( ) ;
385
-
386
- if has_self {
387
- print ! ( f, self , write( "<" ) , print_display( substs. type_at( 0 ) ) , write( " as " ) ) ?;
388
- }
389
333
390
- path_def_id = def_id;
391
- } else {
392
- item_name = None ;
393
-
394
- if is_value_path {
395
- // Functions.
396
- assert_eq ! ( has_self, false ) ;
397
- } else {
398
- // Types and traits.
399
- own_counts = child_own_counts;
400
- }
401
- }
334
+ _ => false ,
335
+ } ;
402
336
403
- if !verbose {
404
- let mut type_params =
405
- generics. params . iter ( ) . rev ( ) . filter_map ( |param| match param. kind {
406
- GenericParamDefKind :: Lifetime => None ,
407
- GenericParamDefKind :: Type { has_default, .. } => {
408
- Some ( ( param. def_id , has_default) )
409
- }
410
- } ) . peekable ( ) ;
411
- let has_default = {
412
- let has_default = type_params. peek ( ) . map ( |( _, has_default) | has_default) ;
413
- * has_default. unwrap_or ( & false )
414
- } ;
415
- if has_default {
416
- let types = substs. types ( ) . rev ( ) . skip ( child_types) ;
417
- for ( ( def_id, has_default) , actual) in type_params. zip ( types) {
418
- if !has_default {
419
- break ;
420
- }
421
- if self . tcx . type_of ( def_id) . subst ( self . tcx , substs) != actual {
422
- break ;
423
- }
424
- num_supplied_defaults += 1 ;
425
- }
426
- }
337
+ let generics = self . tcx . generics_of ( def_id) ;
338
+
339
+ if let Some ( parent_def_id) = generics. parent {
340
+ assert_eq ! ( parent_def_id, DefId { index: key. parent. unwrap( ) , ..def_id } ) ;
341
+
342
+ let parent_generics = self . tcx . generics_of ( parent_def_id) ;
343
+ let parent_has_own_self =
344
+ parent_generics. has_self && parent_generics. parent_count == 0 ;
345
+ if parent_has_own_self {
346
+ print ! ( f, self , write( "<" ) , print_display( substs. type_at( 0 ) ) , write( " as " ) ) ?;
427
347
}
428
- }
429
- print ! ( f, self , write( "{}" , self . tcx. item_path_str( path_def_id) ) ) ?;
430
- let fn_trait_kind = self . tcx . lang_items ( ) . fn_trait_kind ( path_def_id) ;
431
-
432
- if !verbose && fn_trait_kind. is_some ( ) {
433
- if let Tuple ( ref args) = substs. type_at ( 1 ) . sty {
434
- let mut projections = projections. clone ( ) ;
435
- if let ( Some ( proj) , None ) = ( projections. next ( ) , projections. next ( ) ) {
436
- return self . fn_sig ( f, args, false , proj. ty ) ;
437
- }
348
+ self . parameterized ( f, parent_def_id, substs, iter:: empty ( ) ) ?;
349
+ if parent_has_own_self {
350
+ write ! ( f, ">" ) ?;
438
351
}
352
+
353
+ write ! ( f, "::{}" , key. disambiguated_data. data. as_interned_str( ) ) ?;
354
+ } else {
355
+ print ! ( f, self , write( "{}" , self . tcx. item_path_str( def_id) ) ) ?;
439
356
}
440
357
441
- let empty = Cell :: new ( true ) ;
442
- let start_or_continue = |f : & mut F , start : & str , cont : & str | {
443
- if empty. get ( ) {
444
- empty. set ( false ) ;
358
+ let mut empty = true ;
359
+ let mut start_or_continue = |f : & mut F , start : & str , cont : & str | {
360
+ if empty {
361
+ empty = false ;
445
362
write ! ( f, "{}" , start)
446
363
} else {
447
364
write ! ( f, "{}" , cont)
448
365
}
449
366
} ;
450
367
451
- let print_regions = |f : & mut F , start : & str , skip, count| {
452
- // Don't print any regions if they're all erased.
453
- let regions = || substs. regions ( ) . skip ( skip) . take ( count) ;
454
- if regions ( ) . all ( |r : ty:: Region < ' _ > | * r == ty:: ReErased ) {
455
- return Ok ( ( ) ) ;
368
+ let start = if is_value_ns { "::<" } else { "<" } ;
369
+
370
+ let has_own_self = generics. has_self && generics. parent_count == 0 ;
371
+ let params = & generics. params [ has_own_self as usize ..] ;
372
+
373
+ // Don't print any regions if they're all erased.
374
+ let print_regions = params. iter ( ) . any ( |param| {
375
+ match substs[ param. index as usize ] . unpack ( ) {
376
+ UnpackedKind :: Lifetime ( r) => * r != ty:: ReErased ,
377
+ _ => false ,
456
378
}
379
+ } ) ;
380
+
381
+ // Don't print args that are the defaults of their respective parameters.
382
+ let num_supplied_defaults = if self . is_verbose {
383
+ 0
384
+ } else {
385
+ params. iter ( ) . rev ( ) . take_while ( |param| {
386
+ match param. kind {
387
+ ty:: GenericParamDefKind :: Lifetime => false ,
388
+ ty:: GenericParamDefKind :: Type { has_default, .. } => {
389
+ has_default && substs[ param. index as usize ] == Kind :: from (
390
+ self . tcx . type_of ( param. def_id ) . subst ( self . tcx , substs)
391
+ )
392
+ }
393
+ }
394
+ } ) . count ( )
395
+ } ;
457
396
458
- for region in regions ( ) {
459
- let region: ty:: Region < ' _ > = region;
460
- start_or_continue ( f, start, ", " ) ?;
461
- if verbose {
462
- write ! ( f, "{:?}" , region) ?;
463
- } else {
464
- let s = region. to_string ( ) ;
465
- if s. is_empty ( ) {
466
- // This happens when the value of the region
467
- // parameter is not easily serialized. This may be
468
- // because the user omitted it in the first place,
469
- // or because it refers to some block in the code,
470
- // etc. I'm not sure how best to serialize this.
471
- write ! ( f, "'_" ) ?;
397
+ for param in & params[ ..params. len ( ) - num_supplied_defaults] {
398
+ match substs[ param. index as usize ] . unpack ( ) {
399
+ UnpackedKind :: Lifetime ( region) => {
400
+ if !print_regions {
401
+ continue ;
402
+ }
403
+ start_or_continue ( f, start, ", " ) ?;
404
+ if self . is_verbose {
405
+ write ! ( f, "{:?}" , region) ?;
472
406
} else {
473
- write ! ( f, "{}" , s) ?;
407
+ let s = region. to_string ( ) ;
408
+ if s. is_empty ( ) {
409
+ // This happens when the value of the region
410
+ // parameter is not easily serialized. This may be
411
+ // because the user omitted it in the first place,
412
+ // or because it refers to some block in the code,
413
+ // etc. I'm not sure how best to serialize this.
414
+ write ! ( f, "'_" ) ?;
415
+ } else {
416
+ write ! ( f, "{}" , s) ?;
417
+ }
474
418
}
475
419
}
420
+ UnpackedKind :: Type ( ty) => {
421
+ start_or_continue ( f, start, ", " ) ?;
422
+ ty. print_display ( f, self ) ?;
423
+ }
476
424
}
477
-
478
- Ok ( ( ) )
479
- } ;
480
-
481
- print_regions ( f, "<" , 0 , own_counts. lifetimes ) ?;
482
-
483
- let tps = substs. types ( )
484
- . take ( own_counts. types - num_supplied_defaults)
485
- . skip ( has_self as usize ) ;
486
-
487
- for ty in tps {
488
- start_or_continue ( f, "<" , ", " ) ?;
489
- ty. print_display ( f, self ) ?;
490
425
}
491
426
492
427
for projection in projections {
493
- start_or_continue ( f, "<" , ", " ) ?;
428
+ start_or_continue ( f, start , ", " ) ?;
494
429
print ! ( f, self ,
495
430
write( "{}=" ,
496
431
self . tcx. associated_item( projection. item_def_id) . ident) ,
497
432
print_display( projection. ty) ) ?;
498
433
}
499
434
500
- start_or_continue ( f, "" , ">" ) ?;
501
-
502
- // For values, also print their name and type parameters.
503
- if is_value_path {
504
- empty. set ( true ) ;
505
-
506
- if has_self {
507
- write ! ( f, ">" ) ?;
508
- }
509
-
510
- if let Some ( item_name) = item_name {
511
- write ! ( f, "::{}" , item_name) ?;
512
- }
513
-
514
- print_regions ( f, "::<" , own_counts. lifetimes , usize:: MAX ) ?;
515
-
516
- // FIXME: consider being smart with defaults here too
517
- for ty in substs. types ( ) . skip ( own_counts. types ) {
518
- start_or_continue ( f, "::<" , ", " ) ?;
519
- ty. print_display ( f, self ) ?;
520
- }
521
-
522
- start_or_continue ( f, "" , ">" ) ?;
523
- }
524
-
525
- Ok ( ( ) )
435
+ start_or_continue ( f, "" , ">" )
526
436
}
527
437
528
438
fn in_binder < T , F > ( & mut self , f : & mut F , value : & ty:: Binder < T > ) -> fmt:: Result
@@ -616,19 +526,34 @@ define_print! {
616
526
( ' tcx) & ' tcx ty:: List <ty:: ExistentialPredicate <' tcx>>, ( self , f, cx) {
617
527
display {
618
528
// Generate the main trait ref, including associated types.
619
-
620
- // Use a type that can't appear in defaults of type parameters.
621
- let dummy_self = cx. tcx. mk_infer( ty:: FreshTy ( 0 ) ) ;
622
529
let mut first = true ;
623
530
624
531
if let Some ( principal) = self . principal( ) {
625
- let principal = principal. with_self_ty( cx. tcx, dummy_self) ;
626
- cx. parameterized(
627
- f,
628
- principal. def_id,
629
- principal. substs,
630
- self . projection_bounds( ) ,
631
- ) ?;
532
+ let mut resugared_principal = false ;
533
+
534
+ // Special-case `Fn(...) -> ...` and resugar it.
535
+ if !cx. is_verbose && cx. tcx. lang_items( ) . fn_trait_kind( principal. def_id) . is_some( ) {
536
+ if let Tuple ( ref args) = principal. substs. type_at( 0 ) . sty {
537
+ let mut projections = self . projection_bounds( ) ;
538
+ if let ( Some ( proj) , None ) = ( projections. next( ) , projections. next( ) ) {
539
+ print!( f, cx, write( "{}" , cx. tcx. item_path_str( principal. def_id) ) ) ?;
540
+ cx. fn_sig( f, args, false , proj. ty) ?;
541
+ resugared_principal = true ;
542
+ }
543
+ }
544
+ }
545
+
546
+ if !resugared_principal {
547
+ // Use a type that can't appear in defaults of type parameters.
548
+ let dummy_self = cx. tcx. mk_infer( ty:: FreshTy ( 0 ) ) ;
549
+ let principal = principal. with_self_ty( cx. tcx, dummy_self) ;
550
+ cx. parameterized(
551
+ f,
552
+ principal. def_id,
553
+ principal. substs,
554
+ self . projection_bounds( ) ,
555
+ ) ?;
556
+ }
632
557
first = false ;
633
558
}
634
559
@@ -1393,12 +1318,7 @@ define_print! {
1393
1318
define_print ! {
1394
1319
( ' tcx) ty:: ProjectionTy <' tcx>, ( self , f, cx) {
1395
1320
display {
1396
- // FIXME(tschottdorf): use something like
1397
- // parameterized(f, self.substs, self.item_def_id, &[])
1398
- // (which currently ICEs).
1399
- let trait_ref = self . trait_ref( cx. tcx) ;
1400
- let item_name = cx. tcx. associated_item( self . item_def_id) . ident;
1401
- print!( f, cx, print_debug( trait_ref) , write( "::{}" , item_name) )
1321
+ cx. parameterized( f, self . item_def_id, self . substs, iter:: empty( ) )
1402
1322
}
1403
1323
}
1404
1324
}
0 commit comments