1
1
use syntax:: {
2
- ast:: { Expr , GenericArg , GenericArgList } ,
2
+ ast:: { Expr , GenericArg } ,
3
3
ast:: { LetStmt , Type :: InferType } ,
4
4
AstNode , TextRange ,
5
5
} ;
@@ -34,15 +34,13 @@ pub(crate) fn replace_turbofish_with_explicit_type(
34
34
35
35
let initializer = let_stmt. initializer ( ) ?;
36
36
37
- let ( turbofish_range , turbofish_type ) = match & initializer {
37
+ let generic_args = match & initializer {
38
38
Expr :: MethodCallExpr ( ce) => {
39
- let generic_args = ce. generic_arg_list ( ) ?;
40
- ( turbofish_range ( & generic_args) ?, turbofish_type ( & generic_args) ?)
39
+ ce. generic_arg_list ( ) ?
41
40
}
42
41
Expr :: CallExpr ( ce) => {
43
42
if let Expr :: PathExpr ( pe) = ce. expr ( ) ? {
44
- let generic_args = pe. path ( ) ?. segment ( ) ?. generic_arg_list ( ) ?;
45
- ( turbofish_range ( & generic_args) ?, turbofish_type ( & generic_args) ?)
43
+ pe. path ( ) ?. segment ( ) ?. generic_arg_list ( ) ?
46
44
} else {
47
45
cov_mark:: hit!( not_applicable_if_non_path_function_call) ;
48
46
return None ;
@@ -54,6 +52,23 @@ pub(crate) fn replace_turbofish_with_explicit_type(
54
52
}
55
53
} ;
56
54
55
+ // Find range of ::<_>
56
+ let colon2 = generic_args. coloncolon_token ( ) ?;
57
+ let r_angle = generic_args. r_angle_token ( ) ?;
58
+ let turbofish_range = TextRange :: new ( colon2. text_range ( ) . start ( ) , r_angle. text_range ( ) . end ( ) ) ;
59
+
60
+ let turbofish_args: Vec < GenericArg > = generic_args. generic_args ( ) . into_iter ( ) . collect ( ) ;
61
+
62
+ // Find type of ::<_>
63
+ if turbofish_args. len ( ) != 1 {
64
+ cov_mark:: hit!( not_applicable_if_not_single_arg) ;
65
+ return None ;
66
+ }
67
+
68
+ // An improvement would be to check that this is correctly part of the return value of the
69
+ // function call, or sub in the actual return type.
70
+ let turbofish_type = & turbofish_args[ 0 ] ;
71
+
57
72
let initializer_start = initializer. syntax ( ) . text_range ( ) . start ( ) ;
58
73
if ctx. offset ( ) > turbofish_range. end ( ) || ctx. offset ( ) < initializer_start {
59
74
cov_mark:: hit!( not_applicable_outside_turbofish) ;
@@ -67,7 +82,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
67
82
68
83
return acc. add (
69
84
AssistId ( "replace_turbofish_with_explicit_type" , AssistKind :: RefactorRewrite ) ,
70
- format ! ( "Replace turbofish with explicit type `: <{}>`" , turbofish_type ) ,
85
+ "Replace turbofish with explicit type" ,
71
86
TextRange :: new ( initializer_start, turbofish_range. end ( ) ) ,
72
87
|builder| {
73
88
builder. insert ( ident_range. end ( ) , format ! ( ": {}" , turbofish_type) ) ;
@@ -82,10 +97,10 @@ pub(crate) fn replace_turbofish_with_explicit_type(
82
97
83
98
return acc. add (
84
99
AssistId ( "replace_turbofish_with_explicit_type" , AssistKind :: RefactorRewrite ) ,
85
- format ! ( "Replace `_` with turbofish type `{}`" , turbofish_type ) ,
100
+ "Replace `_` with turbofish type" ,
86
101
turbofish_range,
87
102
|builder| {
88
- builder. replace ( underscore_range, turbofish_type) ;
103
+ builder. replace ( underscore_range, turbofish_type. to_string ( ) ) ;
89
104
builder. delete ( turbofish_range) ;
90
105
} ,
91
106
) ;
@@ -94,31 +109,6 @@ pub(crate) fn replace_turbofish_with_explicit_type(
94
109
None
95
110
}
96
111
97
- /// Returns the type of the turbofish as a String.
98
- /// Returns None if there are 0 or >1 arguments.
99
- fn turbofish_type ( generic_args : & GenericArgList ) -> Option < String > {
100
- let turbofish_args: Vec < GenericArg > = generic_args. generic_args ( ) . into_iter ( ) . collect ( ) ;
101
-
102
- if turbofish_args. len ( ) != 1 {
103
- cov_mark:: hit!( not_applicable_if_not_single_arg) ;
104
- return None ;
105
- }
106
-
107
- // An improvement would be to check that this is correctly part of the return value of the
108
- // function call, or sub in the actual return type.
109
- let turbofish_type = turbofish_args[ 0 ] . to_string ( ) ;
110
-
111
- Some ( turbofish_type)
112
- }
113
-
114
- /// Returns the TextRange of the whole turbofish expression, and the generic argument as a String.
115
- fn turbofish_range ( generic_args : & GenericArgList ) -> Option < TextRange > {
116
- let colon2 = generic_args. coloncolon_token ( ) ?;
117
- let r_angle = generic_args. r_angle_token ( ) ?;
118
-
119
- Some ( TextRange :: new ( colon2. text_range ( ) . start ( ) , r_angle. text_range ( ) . end ( ) ) )
120
- }
121
-
122
112
#[ cfg( test) ]
123
113
mod tests {
124
114
use super :: * ;
0 commit comments