@@ -44,11 +44,11 @@ use std::sync::Arc;
44
44
use std:: { fmt, iter, mem} ;
45
45
46
46
use hir_def:: {
47
- expr:: ExprId , type_ref:: Mutability , AdtId , AssocContainerId , DefWithBodyId , GenericDefId ,
48
- HasModule , Lookup , TraitId , TypeAliasId , TypeParamId , generics :: TypeParamProvenance ,
47
+ expr:: ExprId , generics :: TypeParamProvenance , type_ref:: Mutability , AdtId , AssocContainerId ,
48
+ DefWithBodyId , GenericDefId , HasModule , Lookup , TraitId , TypeAliasId , TypeParamId ,
49
49
} ;
50
- use ra_db:: { impl_intern_key, salsa, CrateId } ;
51
50
use hir_expand:: name:: Name ;
51
+ use ra_db:: { impl_intern_key, salsa, CrateId } ;
52
52
53
53
use crate :: {
54
54
db:: HirDatabase ,
@@ -360,9 +360,7 @@ impl Substs {
360
360
361
361
/// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
362
362
pub ( crate ) fn type_params ( generic_params : & Generics ) -> Substs {
363
- Substs (
364
- generic_params. iter ( ) . map ( |( id, _) | Ty :: Param ( id) ) . collect ( ) ,
365
- )
363
+ Substs ( generic_params. iter ( ) . map ( |( id, _) | Ty :: Param ( id) ) . collect ( ) )
366
364
}
367
365
368
366
/// Return Substs that replace each parameter by a bound variable.
@@ -448,7 +446,9 @@ pub struct Binders<T> {
448
446
}
449
447
450
448
impl < T > Binders < T > {
451
- pub fn new ( num_binders : usize , value : T ) -> Self { Self { num_binders, value } }
449
+ pub fn new ( num_binders : usize , value : T ) -> Self {
450
+ Self { num_binders, value }
451
+ }
452
452
}
453
453
454
454
impl < T : TypeWalk > Binders < T > {
@@ -906,8 +906,7 @@ impl HirDisplay for ApplicationTy {
906
906
write ! ( f, ") -> {}" , sig. ret( ) . display( f. db) ) ?;
907
907
}
908
908
TypeCtor :: FnDef ( def) => {
909
- let sig = f. db . callable_item_signature ( def)
910
- . subst ( & self . parameters ) ;
909
+ let sig = f. db . callable_item_signature ( def) . subst ( & self . parameters ) ;
911
910
let name = match def {
912
911
CallableDef :: FunctionId ( ff) => f. db . function_data ( ff) . name . clone ( ) ,
913
912
CallableDef :: StructId ( s) => f. db . struct_data ( s) . name . clone ( ) ,
@@ -1037,84 +1036,27 @@ impl HirDisplay for Ty {
1037
1036
Ty :: Apply ( a_ty) => a_ty. hir_fmt ( f) ?,
1038
1037
Ty :: Projection ( p_ty) => p_ty. hir_fmt ( f) ?,
1039
1038
Ty :: Param ( id) => {
1040
- let generic_params = f. db . generic_params ( id. parent ) ;
1041
- let param_data = & generic_params . types [ id. local_id ] ;
1039
+ let generics = generics ( f. db , id. parent ) ;
1040
+ let param_data = & generics . params . types [ id. local_id ] ;
1042
1041
match param_data. provenance {
1043
1042
TypeParamProvenance :: TypeParamList | TypeParamProvenance :: TraitSelf => {
1044
1043
write ! ( f, "{}" , param_data. name. clone( ) . unwrap_or_else( Name :: missing) ) ?
1045
1044
}
1046
1045
TypeParamProvenance :: ArgumentImplTrait => {
1047
- write ! ( f, "impl TODO" ) ?
1046
+ let bounds = f. db . generic_predicates_for_param ( * id) ;
1047
+ write ! ( f, "impl " ) ?;
1048
+ write_bounds_like_dyn_trait ( & bounds, f) ?;
1048
1049
}
1049
1050
}
1050
- } ,
1051
+ }
1051
1052
Ty :: Bound ( idx) => write ! ( f, "?{}" , idx) ?,
1052
1053
Ty :: Dyn ( predicates) | Ty :: Opaque ( predicates) => {
1053
1054
match self {
1054
1055
Ty :: Dyn ( _) => write ! ( f, "dyn " ) ?,
1055
1056
Ty :: Opaque ( _) => write ! ( f, "impl " ) ?,
1056
1057
_ => unreachable ! ( ) ,
1057
1058
} ;
1058
- // Note: This code is written to produce nice results (i.e.
1059
- // corresponding to surface Rust) for types that can occur in
1060
- // actual Rust. It will have weird results if the predicates
1061
- // aren't as expected (i.e. self types = $0, projection
1062
- // predicates for a certain trait come after the Implemented
1063
- // predicate for that trait).
1064
- let mut first = true ;
1065
- let mut angle_open = false ;
1066
- for p in predicates. iter ( ) {
1067
- match p {
1068
- GenericPredicate :: Implemented ( trait_ref) => {
1069
- if angle_open {
1070
- write ! ( f, ">" ) ?;
1071
- }
1072
- if !first {
1073
- write ! ( f, " + " ) ?;
1074
- }
1075
- // We assume that the self type is $0 (i.e. the
1076
- // existential) here, which is the only thing that's
1077
- // possible in actual Rust, and hence don't print it
1078
- write ! ( f, "{}" , f. db. trait_data( trait_ref. trait_) . name. clone( ) ) ?;
1079
- if trait_ref. substs . len ( ) > 1 {
1080
- write ! ( f, "<" ) ?;
1081
- f. write_joined ( & trait_ref. substs [ 1 ..] , ", " ) ?;
1082
- // there might be assoc type bindings, so we leave the angle brackets open
1083
- angle_open = true ;
1084
- }
1085
- }
1086
- GenericPredicate :: Projection ( projection_pred) => {
1087
- // in types in actual Rust, these will always come
1088
- // after the corresponding Implemented predicate
1089
- if angle_open {
1090
- write ! ( f, ", " ) ?;
1091
- } else {
1092
- write ! ( f, "<" ) ?;
1093
- angle_open = true ;
1094
- }
1095
- let name =
1096
- f. db . type_alias_data ( projection_pred. projection_ty . associated_ty )
1097
- . name
1098
- . clone ( ) ;
1099
- write ! ( f, "{} = " , name) ?;
1100
- projection_pred. ty . hir_fmt ( f) ?;
1101
- }
1102
- GenericPredicate :: Error => {
1103
- if angle_open {
1104
- // impl Trait<X, {error}>
1105
- write ! ( f, ", " ) ?;
1106
- } else if !first {
1107
- // impl Trait + {error}
1108
- write ! ( f, " + " ) ?;
1109
- }
1110
- p. hir_fmt ( f) ?;
1111
- }
1112
- }
1113
- first = false ;
1114
- }
1115
- if angle_open {
1116
- write ! ( f, ">" ) ?;
1117
- }
1059
+ write_bounds_like_dyn_trait ( & predicates, f) ?;
1118
1060
}
1119
1061
Ty :: Unknown => write ! ( f, "{{unknown}}" ) ?,
1120
1062
Ty :: Infer ( ..) => write ! ( f, "_" ) ?,
@@ -1123,6 +1065,71 @@ impl HirDisplay for Ty {
1123
1065
}
1124
1066
}
1125
1067
1068
+ fn write_bounds_like_dyn_trait (
1069
+ predicates : & [ GenericPredicate ] ,
1070
+ f : & mut HirFormatter < impl HirDatabase > ,
1071
+ ) -> fmt:: Result {
1072
+ // Note: This code is written to produce nice results (i.e.
1073
+ // corresponding to surface Rust) for types that can occur in
1074
+ // actual Rust. It will have weird results if the predicates
1075
+ // aren't as expected (i.e. self types = $0, projection
1076
+ // predicates for a certain trait come after the Implemented
1077
+ // predicate for that trait).
1078
+ let mut first = true ;
1079
+ let mut angle_open = false ;
1080
+ for p in predicates. iter ( ) {
1081
+ match p {
1082
+ GenericPredicate :: Implemented ( trait_ref) => {
1083
+ if angle_open {
1084
+ write ! ( f, ">" ) ?;
1085
+ }
1086
+ if !first {
1087
+ write ! ( f, " + " ) ?;
1088
+ }
1089
+ // We assume that the self type is $0 (i.e. the
1090
+ // existential) here, which is the only thing that's
1091
+ // possible in actual Rust, and hence don't print it
1092
+ write ! ( f, "{}" , f. db. trait_data( trait_ref. trait_) . name. clone( ) ) ?;
1093
+ if trait_ref. substs . len ( ) > 1 {
1094
+ write ! ( f, "<" ) ?;
1095
+ f. write_joined ( & trait_ref. substs [ 1 ..] , ", " ) ?;
1096
+ // there might be assoc type bindings, so we leave the angle brackets open
1097
+ angle_open = true ;
1098
+ }
1099
+ }
1100
+ GenericPredicate :: Projection ( projection_pred) => {
1101
+ // in types in actual Rust, these will always come
1102
+ // after the corresponding Implemented predicate
1103
+ if angle_open {
1104
+ write ! ( f, ", " ) ?;
1105
+ } else {
1106
+ write ! ( f, "<" ) ?;
1107
+ angle_open = true ;
1108
+ }
1109
+ let name =
1110
+ f. db . type_alias_data ( projection_pred. projection_ty . associated_ty ) . name . clone ( ) ;
1111
+ write ! ( f, "{} = " , name) ?;
1112
+ projection_pred. ty . hir_fmt ( f) ?;
1113
+ }
1114
+ GenericPredicate :: Error => {
1115
+ if angle_open {
1116
+ // impl Trait<X, {error}>
1117
+ write ! ( f, ", " ) ?;
1118
+ } else if !first {
1119
+ // impl Trait + {error}
1120
+ write ! ( f, " + " ) ?;
1121
+ }
1122
+ p. hir_fmt ( f) ?;
1123
+ }
1124
+ }
1125
+ first = false ;
1126
+ }
1127
+ if angle_open {
1128
+ write ! ( f, ">" ) ?;
1129
+ }
1130
+ Ok ( ( ) )
1131
+ }
1132
+
1126
1133
impl TraitRef {
1127
1134
fn hir_fmt_ext ( & self , f : & mut HirFormatter < impl HirDatabase > , use_as : bool ) -> fmt:: Result {
1128
1135
if f. should_truncate ( ) {
0 commit comments