@@ -16,8 +16,8 @@ use rustc_hir::definitions::{DefKey, DefPathDataName};
16
16
use rustc_macros:: { Lift , extension} ;
17
17
use rustc_session:: Limit ;
18
18
use rustc_session:: cstore:: { ExternCrate , ExternCrateSource } ;
19
- use rustc_span:: FileNameDisplayPreference ;
20
19
use rustc_span:: symbol:: { Ident , Symbol , kw} ;
20
+ use rustc_span:: { FileNameDisplayPreference , sym} ;
21
21
use rustc_type_ir:: { Upcast as _, elaborate} ;
22
22
use smallvec:: SmallVec ;
23
23
@@ -26,8 +26,8 @@ use super::*;
26
26
use crate :: mir:: interpret:: { AllocRange , GlobalAlloc , Pointer , Provenance , Scalar } ;
27
27
use crate :: query:: { IntoQueryParam , Providers } ;
28
28
use crate :: ty:: {
29
- ConstInt , Expr , GenericArgKind , ParamConst , ScalarInt , Term , TermKind , TypeFoldable ,
30
- TypeSuperFoldable , TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
29
+ ConstInt , Expr , GenericArgKind , ParamConst , ScalarInt , Term , TermKind , TraitPredicate ,
30
+ TypeFoldable , TypeSuperFoldable , TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
31
31
} ;
32
32
33
33
macro_rules! p {
@@ -993,10 +993,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
993
993
994
994
match bound_predicate. skip_binder ( ) {
995
995
ty:: ClauseKind :: Trait ( pred) => {
996
- let trait_ref = bound_predicate. rebind ( pred. trait_ref ) ;
997
-
998
996
// Don't print `+ Sized`, but rather `+ ?Sized` if absent.
999
- if tcx. is_lang_item ( trait_ref . def_id ( ) , LangItem :: Sized ) {
997
+ if tcx. is_lang_item ( pred . def_id ( ) , LangItem :: Sized ) {
1000
998
match pred. polarity {
1001
999
ty:: PredicatePolarity :: Positive => {
1002
1000
has_sized_bound = true ;
@@ -1007,24 +1005,22 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
1007
1005
}
1008
1006
1009
1007
self . insert_trait_and_projection (
1010
- trait_ref,
1011
- pred. polarity ,
1008
+ bound_predicate. rebind ( pred) ,
1012
1009
None ,
1013
1010
& mut traits,
1014
1011
& mut fn_traits,
1015
1012
) ;
1016
1013
}
1017
1014
ty:: ClauseKind :: Projection ( pred) => {
1018
- let proj_ref = bound_predicate. rebind ( pred) ;
1019
- let trait_ref = proj_ref . required_poly_trait_ref ( tcx ) ;
1020
-
1021
- // Projection type entry -- the def-id for naming, and the ty.
1022
- let proj_ty = ( proj_ref . projection_def_id ( ) , proj_ref . term ( ) ) ;
1015
+ let proj = bound_predicate. rebind ( pred) ;
1016
+ let trait_ref = proj . map_bound ( |proj| TraitPredicate {
1017
+ trait_ref : proj . projection_term . trait_ref ( tcx ) ,
1018
+ polarity : ty :: PredicatePolarity :: Positive ,
1019
+ } ) ;
1023
1020
1024
1021
self . insert_trait_and_projection (
1025
1022
trait_ref,
1026
- ty:: PredicatePolarity :: Positive ,
1027
- Some ( proj_ty) ,
1023
+ Some ( ( proj. projection_def_id ( ) , proj. term ( ) ) ) ,
1028
1024
& mut traits,
1029
1025
& mut fn_traits,
1030
1026
) ;
@@ -1042,88 +1038,66 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
1042
1038
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
1043
1039
let paren_needed = fn_traits. len ( ) > 1 || traits. len ( ) > 0 || !has_sized_bound;
1044
1040
1045
- for ( fn_once_trait_ref , entry) in fn_traits {
1041
+ for ( ( bound_args , is_async ) , entry) in fn_traits {
1046
1042
write ! ( self , "{}" , if first { "" } else { " + " } ) ?;
1047
1043
write ! ( self , "{}" , if paren_needed { "(" } else { "" } ) ?;
1048
1044
1049
- self . wrap_binder ( & fn_once_trait_ref, |trait_ref, cx| {
1050
- define_scoped_cx ! ( cx) ;
1051
- // Get the (single) generic ty (the args) of this FnOnce trait ref.
1052
- let generics = tcx. generics_of ( trait_ref. def_id ) ;
1053
- let own_args = generics. own_args_no_defaults ( tcx, trait_ref. args ) ;
1054
-
1055
- match ( entry. return_ty , own_args[ 0 ] . expect_ty ( ) ) {
1056
- // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
1057
- // a return type.
1058
- ( Some ( return_ty) , arg_tys) if matches ! ( arg_tys. kind( ) , ty:: Tuple ( _) ) => {
1059
- let name = if entry. fn_trait_ref . is_some ( ) {
1060
- "Fn"
1061
- } else if entry. fn_mut_trait_ref . is_some ( ) {
1062
- "FnMut"
1063
- } else {
1064
- "FnOnce"
1065
- } ;
1066
-
1067
- p ! ( write( "{}(" , name) ) ;
1045
+ let trait_def_id = if is_async {
1046
+ tcx. async_fn_trait_kind_to_def_id ( entry. kind ) . expect ( "expected AsyncFn lang items" )
1047
+ } else {
1048
+ tcx. fn_trait_kind_to_def_id ( entry. kind ) . expect ( "expected Fn lang items" )
1049
+ } ;
1068
1050
1069
- for ( idx, ty) in arg_tys. tuple_fields ( ) . iter ( ) . enumerate ( ) {
1070
- if idx > 0 {
1071
- p ! ( ", " ) ;
1072
- }
1073
- p ! ( print( ty) ) ;
1074
- }
1051
+ if let Some ( return_ty) = entry. return_ty {
1052
+ self . wrap_binder ( & bound_args, |args, cx| {
1053
+ define_scoped_cx ! ( cx) ;
1054
+ p ! ( write( "{}" , tcx. item_name( trait_def_id) ) ) ;
1055
+ p ! ( "(" ) ;
1075
1056
1076
- p ! ( ")" ) ;
1077
- if let Some ( ty) = return_ty. skip_binder ( ) . as_type ( ) {
1078
- if !ty. is_unit ( ) {
1079
- p ! ( " -> " , print( return_ty) ) ;
1080
- }
1057
+ for ( idx, ty) in args. iter ( ) . enumerate ( ) {
1058
+ if idx > 0 {
1059
+ p ! ( ", " ) ;
1081
1060
}
1082
- p ! ( write( "{}" , if paren_needed { ")" } else { "" } ) ) ;
1083
-
1084
- first = false ;
1061
+ p ! ( print( ty) ) ;
1085
1062
}
1086
- // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
1087
- // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
1088
- _ => {
1089
- if entry. has_fn_once {
1090
- traits
1091
- . entry ( ( fn_once_trait_ref, ty:: PredicatePolarity :: Positive ) )
1092
- . or_default ( )
1093
- . extend (
1094
- // Group the return ty with its def id, if we had one.
1095
- entry. return_ty . map ( |ty| {
1096
- ( tcx. require_lang_item ( LangItem :: FnOnceOutput , None ) , ty)
1097
- } ) ,
1098
- ) ;
1099
- }
1100
- if let Some ( trait_ref) = entry. fn_mut_trait_ref {
1101
- traits. entry ( ( trait_ref, ty:: PredicatePolarity :: Positive ) ) . or_default ( ) ;
1102
- }
1103
- if let Some ( trait_ref) = entry. fn_trait_ref {
1104
- traits. entry ( ( trait_ref, ty:: PredicatePolarity :: Positive ) ) . or_default ( ) ;
1063
+
1064
+ p ! ( ")" ) ;
1065
+ if let Some ( ty) = return_ty. skip_binder ( ) . as_type ( ) {
1066
+ if !ty. is_unit ( ) {
1067
+ p ! ( " -> " , print( return_ty) ) ;
1105
1068
}
1106
1069
}
1107
- }
1070
+ p ! ( write ( "{}" , if paren_needed { ")" } else { "" } ) ) ;
1108
1071
1109
- Ok ( ( ) )
1110
- } ) ?;
1072
+ first = false ;
1073
+ Ok ( ( ) )
1074
+ } ) ?;
1075
+ } else {
1076
+ // Otherwise, render this like a regular trait.
1077
+ traits. insert (
1078
+ bound_args. map_bound ( |args| ty:: TraitPredicate {
1079
+ polarity : ty:: PredicatePolarity :: Positive ,
1080
+ trait_ref : ty:: TraitRef :: new ( tcx, trait_def_id, [ Ty :: new_tup ( tcx, args) ] ) ,
1081
+ } ) ,
1082
+ FxIndexMap :: default ( ) ,
1083
+ ) ;
1084
+ }
1111
1085
}
1112
1086
1113
1087
// Print the rest of the trait types (that aren't Fn* family of traits)
1114
- for ( ( trait_ref , polarity ) , assoc_items) in traits {
1088
+ for ( trait_pred , assoc_items) in traits {
1115
1089
write ! ( self , "{}" , if first { "" } else { " + " } ) ?;
1116
1090
1117
- self . wrap_binder ( & trait_ref , |trait_ref , cx| {
1091
+ self . wrap_binder ( & trait_pred , |trait_pred , cx| {
1118
1092
define_scoped_cx ! ( cx) ;
1119
1093
1120
- if polarity == ty:: PredicatePolarity :: Negative {
1094
+ if trait_pred . polarity == ty:: PredicatePolarity :: Negative {
1121
1095
p ! ( "!" ) ;
1122
1096
}
1123
- p ! ( print( trait_ref. print_only_trait_name( ) ) ) ;
1097
+ p ! ( print( trait_pred . trait_ref. print_only_trait_name( ) ) ) ;
1124
1098
1125
- let generics = tcx. generics_of ( trait_ref . def_id ) ;
1126
- let own_args = generics. own_args_no_defaults ( tcx, trait_ref. args ) ;
1099
+ let generics = tcx. generics_of ( trait_pred . def_id ( ) ) ;
1100
+ let own_args = generics. own_args_no_defaults ( tcx, trait_pred . trait_ref . args ) ;
1127
1101
1128
1102
if !own_args. is_empty ( ) || !assoc_items. is_empty ( ) {
1129
1103
let mut first = true ;
@@ -1230,51 +1204,48 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
1230
1204
/// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits.
1231
1205
fn insert_trait_and_projection (
1232
1206
& mut self ,
1233
- trait_ref : ty:: PolyTraitRef < ' tcx > ,
1234
- polarity : ty:: PredicatePolarity ,
1207
+ trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
1235
1208
proj_ty : Option < ( DefId , ty:: Binder < ' tcx , Term < ' tcx > > ) > ,
1236
1209
traits : & mut FxIndexMap <
1237
- ( ty:: PolyTraitRef < ' tcx > , ty :: PredicatePolarity ) ,
1210
+ ty:: PolyTraitPredicate < ' tcx > ,
1238
1211
FxIndexMap < DefId , ty:: Binder < ' tcx , Term < ' tcx > > > ,
1239
1212
> ,
1240
- fn_traits : & mut FxIndexMap < ty:: PolyTraitRef < ' tcx > , OpaqueFnEntry < ' tcx > > ,
1213
+ fn_traits : & mut FxIndexMap <
1214
+ ( ty:: Binder < ' tcx , & ' tcx ty:: List < Ty < ' tcx > > > , bool ) ,
1215
+ OpaqueFnEntry < ' tcx > ,
1216
+ > ,
1241
1217
) {
1242
- let trait_def_id = trait_ref. def_id ( ) ;
1243
-
1244
- // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
1245
- // super-trait ref and record it there.
1246
- // We skip negative Fn* bounds since they can't use parenthetical notation anyway.
1247
- if polarity == ty:: PredicatePolarity :: Positive
1248
- && let Some ( fn_once_trait) = self . tcx ( ) . lang_items ( ) . fn_once_trait ( )
1249
- {
1250
- // If we have a FnOnce, then insert it into
1251
- if trait_def_id == fn_once_trait {
1252
- let entry = fn_traits. entry ( trait_ref) . or_default ( ) ;
1253
- // Optionally insert the return_ty as well.
1254
- if let Some ( ( _, ty) ) = proj_ty {
1255
- entry. return_ty = Some ( ty) ;
1256
- }
1257
- entry. has_fn_once = true ;
1258
- return ;
1259
- } else if self . tcx ( ) . is_lang_item ( trait_def_id, LangItem :: FnMut ) {
1260
- let super_trait_ref = elaborate:: supertraits ( self . tcx ( ) , trait_ref)
1261
- . find ( |super_trait_ref| super_trait_ref. def_id ( ) == fn_once_trait)
1262
- . unwrap ( ) ;
1218
+ let tcx = self . tcx ( ) ;
1219
+ let trait_def_id = trait_pred. def_id ( ) ;
1263
1220
1264
- fn_traits. entry ( super_trait_ref) . or_default ( ) . fn_mut_trait_ref = Some ( trait_ref) ;
1265
- return ;
1266
- } else if self . tcx ( ) . is_lang_item ( trait_def_id, LangItem :: Fn ) {
1267
- let super_trait_ref = elaborate:: supertraits ( self . tcx ( ) , trait_ref)
1268
- . find ( |super_trait_ref| super_trait_ref. def_id ( ) == fn_once_trait)
1269
- . unwrap ( ) ;
1221
+ let fn_trait_and_async = if let Some ( kind) = tcx. fn_trait_kind_from_def_id ( trait_def_id) {
1222
+ Some ( ( kind, false ) )
1223
+ } else if let Some ( kind) = tcx. async_fn_trait_kind_from_def_id ( trait_def_id) {
1224
+ Some ( ( kind, true ) )
1225
+ } else {
1226
+ None
1227
+ } ;
1270
1228
1271
- fn_traits. entry ( super_trait_ref) . or_default ( ) . fn_trait_ref = Some ( trait_ref) ;
1272
- return ;
1229
+ if trait_pred. polarity ( ) == ty:: PredicatePolarity :: Positive
1230
+ && let Some ( ( kind, is_async) ) = fn_trait_and_async
1231
+ && let ty:: Tuple ( types) = * trait_pred. skip_binder ( ) . trait_ref . args . type_at ( 1 ) . kind ( )
1232
+ {
1233
+ let entry = fn_traits
1234
+ . entry ( ( trait_pred. rebind ( types) , is_async) )
1235
+ . or_insert_with ( || OpaqueFnEntry { kind, return_ty : None } ) ;
1236
+ if kind. extends ( entry. kind ) {
1237
+ entry. kind = kind;
1238
+ }
1239
+ if let Some ( ( proj_def_id, proj_ty) ) = proj_ty
1240
+ && tcx. item_name ( proj_def_id) == sym:: Output
1241
+ {
1242
+ entry. return_ty = Some ( proj_ty) ;
1273
1243
}
1244
+ return ;
1274
1245
}
1275
1246
1276
1247
// Otherwise, just group our traits and projection types.
1277
- traits. entry ( ( trait_ref , polarity ) ) . or_default ( ) . extend ( proj_ty) ;
1248
+ traits. entry ( trait_pred ) . or_default ( ) . extend ( proj_ty) ;
1278
1249
}
1279
1250
1280
1251
fn pretty_print_inherent_projection (
@@ -3189,10 +3160,10 @@ define_print_and_forward_display! {
3189
3160
3190
3161
TraitRefPrintSugared <' tcx> {
3191
3162
if !with_reduced_queries( )
3192
- && let Some ( kind ) = cx. tcx( ) . fn_trait_kind_from_def_id ( self . 0 . def_id)
3163
+ && cx. tcx( ) . trait_def ( self . 0 . def_id) . paren_sugar
3193
3164
&& let ty:: Tuple ( args) = self . 0 . args. type_at( 1 ) . kind( )
3194
3165
{
3195
- p!( write( "{}" , kind . as_str ( ) ) , "(" ) ;
3166
+ p!( write( "{}" , cx . tcx ( ) . item_name ( self . 0 . def_id ) ) , "(" ) ;
3196
3167
for ( i, arg) in args. iter( ) . enumerate( ) {
3197
3168
if i > 0 {
3198
3169
p!( ", " ) ;
@@ -3415,11 +3386,7 @@ pub fn provide(providers: &mut Providers) {
3415
3386
* providers = Providers { trimmed_def_paths, ..* providers } ;
3416
3387
}
3417
3388
3418
- #[ derive( Default ) ]
3419
3389
pub struct OpaqueFnEntry < ' tcx > {
3420
- // The trait ref is already stored as a key, so just track if we have it as a real predicate
3421
- has_fn_once : bool ,
3422
- fn_mut_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > ,
3423
- fn_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > ,
3390
+ kind : ty:: ClosureKind ,
3424
3391
return_ty : Option < ty:: Binder < ' tcx , Term < ' tcx > > > ,
3425
3392
}
0 commit comments