@@ -70,6 +70,7 @@ pub mod intrinsic;
70
70
mod region;
71
71
pub mod wfcheck;
72
72
73
+ use std:: borrow:: Cow ;
73
74
use std:: num:: NonZero ;
74
75
75
76
pub use check:: { check_abi, check_custom_abi} ;
@@ -86,7 +87,7 @@ use rustc_middle::query::Providers;
86
87
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
87
88
use rustc_middle:: ty:: print:: with_types_for_signature;
88
89
use rustc_middle:: ty:: {
89
- self , GenericArgs , GenericArgsRef , GenericParamDefKind , Ty , TyCtxt , TypingMode ,
90
+ self , GenericArgs , GenericArgsRef , OutlivesPredicate , Region , Ty , TyCtxt , TypingMode ,
90
91
} ;
91
92
use rustc_middle:: { bug, span_bug} ;
92
93
use rustc_session:: parse:: feature_err;
@@ -335,6 +336,7 @@ fn bounds_from_generic_predicates<'tcx>(
335
336
assoc : ty:: AssocItem ,
336
337
) -> ( String , String ) {
337
338
let mut types: FxIndexMap < Ty < ' tcx > , Vec < DefId > > = FxIndexMap :: default ( ) ;
339
+ let mut regions: FxIndexMap < Region < ' tcx > , Vec < Region < ' tcx > > > = FxIndexMap :: default ( ) ;
338
340
let mut projections = vec ! [ ] ;
339
341
for ( predicate, _) in predicates {
340
342
debug ! ( "predicate {:?}" , predicate) ;
@@ -351,20 +353,23 @@ fn bounds_from_generic_predicates<'tcx>(
351
353
ty:: ClauseKind :: Projection ( projection_pred) => {
352
354
projections. push ( bound_predicate. rebind ( projection_pred) ) ;
353
355
}
356
+ ty:: ClauseKind :: RegionOutlives ( OutlivesPredicate ( a, b) ) => {
357
+ regions. entry ( a) . or_default ( ) . push ( b) ;
358
+ }
354
359
_ => { }
355
360
}
356
361
}
357
362
358
363
let mut where_clauses = vec ! [ ] ;
359
364
let generics = tcx. generics_of ( assoc. def_id ) ;
360
- let types_str = generics
365
+ let params = generics
361
366
. own_params
362
367
. iter ( )
363
- . filter ( |p| matches ! ( p. kind, GenericParamDefKind :: Type { synthetic : false , .. } ) )
364
- . map ( |p| {
365
- // we just checked that it's a type, so the unwrap can't fail
366
- let ty = tcx . mk_param_from_def ( p ) . as_type ( ) . unwrap ( ) ;
367
- if let Some ( bounds ) = types. get ( & ty) {
368
+ . filter ( |p| ! p. kind . is_synthetic ( ) )
369
+ . map ( |p| match tcx . mk_param_from_def ( p ) . kind ( ) {
370
+ ty :: GenericArgKind :: Type ( ty ) => {
371
+ let bounds =
372
+ types. get ( & ty) . map ( Cow :: Borrowed ) . unwrap_or_else ( || Cow :: Owned ( Vec :: new ( ) ) ) ;
368
373
let mut bounds_str = vec ! [ ] ;
369
374
for bound in bounds. iter ( ) . copied ( ) {
370
375
let mut projections_str = vec ! [ ] ;
@@ -377,7 +382,11 @@ fn bounds_from_generic_predicates<'tcx>(
377
382
projections_str. push ( format ! ( "{} = {}" , name, p. term) ) ;
378
383
}
379
384
}
380
- let bound_def_path = tcx. def_path_str ( bound) ;
385
+ let bound_def_path = if tcx. is_lang_item ( bound, LangItem :: MetaSized ) {
386
+ String :: from ( "?Sized" )
387
+ } else {
388
+ tcx. def_path_str ( bound)
389
+ } ;
381
390
if projections_str. is_empty ( ) {
382
391
where_clauses. push ( format ! ( "{}: {}" , ty, bound_def_path) ) ;
383
392
} else {
@@ -393,8 +402,21 @@ fn bounds_from_generic_predicates<'tcx>(
393
402
} else {
394
403
format ! ( "{}: {}" , ty, bounds_str. join( " + " ) )
395
404
}
396
- } else {
397
- ty. to_string ( )
405
+ }
406
+ ty:: GenericArgKind :: Const ( ct) => {
407
+ format ! ( "const {ct}: {}" , tcx. type_of( p. def_id) . skip_binder( ) )
408
+ }
409
+ ty:: GenericArgKind :: Lifetime ( region) => {
410
+ if let Some ( v) = regions. get ( & region)
411
+ && !v. is_empty ( )
412
+ {
413
+ format ! (
414
+ "{region}: {}" ,
415
+ v. into_iter( ) . map( Region :: to_string) . collect:: <Vec <_>>( ) . join( " + " )
416
+ )
417
+ } else {
418
+ region. to_string ( )
419
+ }
398
420
}
399
421
} )
400
422
. collect :: < Vec < _ > > ( ) ;
@@ -409,7 +431,7 @@ fn bounds_from_generic_predicates<'tcx>(
409
431
}
410
432
411
433
let generics =
412
- if types_str . is_empty ( ) { "" . to_string ( ) } else { format ! ( "<{}>" , types_str . join( ", " ) ) } ;
434
+ if params . is_empty ( ) { "" . to_string ( ) } else { format ! ( "<{}>" , params . join( ", " ) ) } ;
413
435
414
436
let where_clauses = if where_clauses. is_empty ( ) {
415
437
"" . to_string ( )
0 commit comments