@@ -88,7 +88,9 @@ fn introduction_builder(ast_func: &ast::Fn, ctx: &AssistContext) -> String {
88
88
89
89
let is_new = ast_func. name ( ) ?. to_string ( ) == "new" ;
90
90
match is_new && ret_ty == self_ty {
91
- true => Some ( format ! ( "Creates a new [`{}`]." , self_type( ast_func) ?) ) ,
91
+ true => {
92
+ Some ( format ! ( "Creates a new [`{}`]." , self_type_without_lifetimes( ast_func) ?) )
93
+ }
92
94
false => None ,
93
95
}
94
96
} else {
@@ -221,18 +223,34 @@ fn self_name(ast_func: &ast::Fn) -> Option<String> {
221
223
}
222
224
223
225
/// Heper function to get the name of the type of `self`
224
- fn self_type ( ast_func : & ast:: Fn ) -> Option < String > {
225
- ast_func
226
- . syntax ( )
227
- . ancestors ( )
228
- . find_map ( ast:: Impl :: cast)
229
- . and_then ( |i| i. self_ty ( ) )
230
- . map ( |t| ( t. to_string ( ) ) )
226
+ fn self_type ( ast_func : & ast:: Fn ) -> Option < ast:: Type > {
227
+ ast_func. syntax ( ) . ancestors ( ) . find_map ( ast:: Impl :: cast) . and_then ( |i| i. self_ty ( ) )
228
+ }
229
+
230
+ /// Output the real name of `Self` like `MyType<T>`, without the lifetimes.
231
+ fn self_type_without_lifetimes ( ast_func : & ast:: Fn ) -> Option < String > {
232
+ let path_segment = match self_type ( ast_func) ? {
233
+ ast:: Type :: PathType ( path_type) => path_type. path ( ) ?. segment ( ) ?,
234
+ _ => return None ,
235
+ } ;
236
+ let mut name = path_segment. name_ref ( ) ?. to_string ( ) ;
237
+ let generics = path_segment
238
+ . generic_arg_list ( ) ?
239
+ . generic_args ( )
240
+ . filter ( |generic| matches ! ( generic, ast:: GenericArg :: TypeArg ( _) ) )
241
+ . map ( |generic| generic. to_string ( ) ) ;
242
+ let generics: String = generics. format ( ", " ) . to_string ( ) ;
243
+ if !generics. is_empty ( ) {
244
+ name. push ( '<' ) ;
245
+ name. push_str ( & generics) ;
246
+ name. push ( '>' ) ;
247
+ }
248
+ Some ( name)
231
249
}
232
250
233
251
/// Heper function to get the name of the type of `self` without generic arguments
234
252
fn self_partial_type ( ast_func : & ast:: Fn ) -> Option < String > {
235
- let mut self_type = self_type ( ast_func) ?;
253
+ let mut self_type = self_type ( ast_func) ?. to_string ( ) ;
236
254
if let Some ( idx) = self_type. find ( |c| [ '<' , ' ' ] . contains ( & c) ) {
237
255
self_type. truncate ( idx) ;
238
256
}
@@ -309,7 +327,7 @@ fn arguments_from_params(param_list: &ast::ParamList) -> String {
309
327
} ,
310
328
_ => "_" . to_string ( ) ,
311
329
} ) ;
312
- Itertools :: intersperse ( args_iter, ", " . to_string ( ) ) . collect ( )
330
+ args_iter. format ( ", " ) . to_string ( )
313
331
}
314
332
315
333
/// Helper function to build a function call. `None` if expected `self_name` was not provided
@@ -991,6 +1009,124 @@ impl<T> MyGenericStruct<T> {
991
1009
) ;
992
1010
}
993
1011
1012
+ #[ test]
1013
+ fn removes_one_lifetime_from_description ( ) {
1014
+ check_assist (
1015
+ generate_documentation_template,
1016
+ r#"
1017
+ #[derive(Debug, PartialEq)]
1018
+ pub struct MyGenericStruct<'a, T> {
1019
+ pub x: &'a T,
1020
+ }
1021
+ impl<'a, T> MyGenericStruct<'a, T> {
1022
+ pub fn new$0(x: &'a T) -> Self {
1023
+ MyGenericStruct { x }
1024
+ }
1025
+ }
1026
+ "# ,
1027
+ r#"
1028
+ #[derive(Debug, PartialEq)]
1029
+ pub struct MyGenericStruct<'a, T> {
1030
+ pub x: &'a T,
1031
+ }
1032
+ impl<'a, T> MyGenericStruct<'a, T> {
1033
+ /// Creates a new [`MyGenericStruct<T>`].
1034
+ ///
1035
+ /// # Examples
1036
+ ///
1037
+ /// ```
1038
+ /// use test::MyGenericStruct;
1039
+ ///
1040
+ /// assert_eq!(MyGenericStruct::new(x), );
1041
+ /// ```
1042
+ pub fn new(x: &'a T) -> Self {
1043
+ MyGenericStruct { x }
1044
+ }
1045
+ }
1046
+ "# ,
1047
+ ) ;
1048
+ }
1049
+
1050
+ #[ test]
1051
+ fn removes_all_lifetimes_from_description ( ) {
1052
+ check_assist (
1053
+ generate_documentation_template,
1054
+ r#"
1055
+ #[derive(Debug, PartialEq)]
1056
+ pub struct MyGenericStruct<'a, 'b, T> {
1057
+ pub x: &'a T,
1058
+ pub y: &'b T,
1059
+ }
1060
+ impl<'a, 'b, T> MyGenericStruct<'a, 'b, T> {
1061
+ pub fn new$0(x: &'a T, y: &'b T) -> Self {
1062
+ MyGenericStruct { x, y }
1063
+ }
1064
+ }
1065
+ "# ,
1066
+ r#"
1067
+ #[derive(Debug, PartialEq)]
1068
+ pub struct MyGenericStruct<'a, 'b, T> {
1069
+ pub x: &'a T,
1070
+ pub y: &'b T,
1071
+ }
1072
+ impl<'a, 'b, T> MyGenericStruct<'a, 'b, T> {
1073
+ /// Creates a new [`MyGenericStruct<T>`].
1074
+ ///
1075
+ /// # Examples
1076
+ ///
1077
+ /// ```
1078
+ /// use test::MyGenericStruct;
1079
+ ///
1080
+ /// assert_eq!(MyGenericStruct::new(x, y), );
1081
+ /// ```
1082
+ pub fn new(x: &'a T, y: &'b T) -> Self {
1083
+ MyGenericStruct { x, y }
1084
+ }
1085
+ }
1086
+ "# ,
1087
+ ) ;
1088
+ }
1089
+
1090
+ #[ test]
1091
+ fn removes_all_lifetimes_and_brackets_from_description ( ) {
1092
+ check_assist (
1093
+ generate_documentation_template,
1094
+ r#"
1095
+ #[derive(Debug, PartialEq)]
1096
+ pub struct MyGenericStruct<'a, 'b> {
1097
+ pub x: &'a usize,
1098
+ pub y: &'b usize,
1099
+ }
1100
+ impl<'a, 'b> MyGenericStruct<'a, 'b> {
1101
+ pub fn new$0(x: &'a usize, y: &'b usize) -> Self {
1102
+ MyGenericStruct { x, y }
1103
+ }
1104
+ }
1105
+ "# ,
1106
+ r#"
1107
+ #[derive(Debug, PartialEq)]
1108
+ pub struct MyGenericStruct<'a, 'b> {
1109
+ pub x: &'a usize,
1110
+ pub y: &'b usize,
1111
+ }
1112
+ impl<'a, 'b> MyGenericStruct<'a, 'b> {
1113
+ /// Creates a new [`MyGenericStruct`].
1114
+ ///
1115
+ /// # Examples
1116
+ ///
1117
+ /// ```
1118
+ /// use test::MyGenericStruct;
1119
+ ///
1120
+ /// assert_eq!(MyGenericStruct::new(x, y), );
1121
+ /// ```
1122
+ pub fn new(x: &'a usize, y: &'b usize) -> Self {
1123
+ MyGenericStruct { x, y }
1124
+ }
1125
+ }
1126
+ "# ,
1127
+ ) ;
1128
+ }
1129
+
994
1130
#[ test]
995
1131
fn detects_new_with_self ( ) {
996
1132
check_assist (
0 commit comments