1+ use hir:: HirDisplay ;
12use syntax:: {
23 ast:: { Expr , GenericArg } ,
34 ast:: { LetStmt , Type :: InferType } ,
@@ -65,7 +66,16 @@ pub(crate) fn replace_turbofish_with_explicit_type(
6566
6667 // An improvement would be to check that this is correctly part of the return value of the
6768 // function call, or sub in the actual return type.
68- let turbofish_type = & turbofish_args[ 0 ] ;
69+ let returned_type = match ctx. sema . type_of_expr ( & initializer) {
70+ Some ( returned_type) if !returned_type. original . contains_unknown ( ) => {
71+ let module = ctx. sema . scope ( let_stmt. syntax ( ) ) ?. module ( ) ;
72+ returned_type. original . display_source_code ( ctx. db ( ) , module. into ( ) ) . ok ( ) ?
73+ }
74+ _ => {
75+ cov_mark:: hit!( fallback_to_turbofish_type_if_type_info_not_available) ;
76+ turbofish_args[ 0 ] . to_string ( )
77+ }
78+ } ;
6979
7080 let initializer_start = initializer. syntax ( ) . text_range ( ) . start ( ) ;
7181 if ctx. offset ( ) > turbofish_range. end ( ) || ctx. offset ( ) < initializer_start {
@@ -83,7 +93,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
8393 "Replace turbofish with explicit type" ,
8494 TextRange :: new ( initializer_start, turbofish_range. end ( ) ) ,
8595 |builder| {
86- builder. insert ( ident_range. end ( ) , format ! ( ": {}" , turbofish_type ) ) ;
96+ builder. insert ( ident_range. end ( ) , format ! ( ": {}" , returned_type ) ) ;
8797 builder. delete ( turbofish_range) ;
8898 } ,
8999 ) ;
@@ -98,7 +108,7 @@ pub(crate) fn replace_turbofish_with_explicit_type(
98108 "Replace `_` with turbofish type" ,
99109 turbofish_range,
100110 |builder| {
101- builder. replace ( underscore_range, turbofish_type . to_string ( ) ) ;
111+ builder. replace ( underscore_range, returned_type ) ;
102112 builder. delete ( turbofish_range) ;
103113 } ,
104114 ) ;
@@ -115,6 +125,7 @@ mod tests {
115125
116126 #[ test]
117127 fn replaces_turbofish_for_vec_string ( ) {
128+ cov_mark:: check!( fallback_to_turbofish_type_if_type_info_not_available) ;
118129 check_assist (
119130 replace_turbofish_with_explicit_type,
120131 r#"
@@ -135,6 +146,7 @@ fn main() {
135146 #[ test]
136147 fn replaces_method_calls ( ) {
137148 // foo.make() is a method call which uses a different expr in the let initializer
149+ cov_mark:: check!( fallback_to_turbofish_type_if_type_info_not_available) ;
138150 check_assist (
139151 replace_turbofish_with_explicit_type,
140152 r#"
@@ -237,6 +249,82 @@ fn make<T>() -> T {}
237249fn main() {
238250 let a = make$0::<Vec<String>, i32>();
239251}
252+ "# ,
253+ ) ;
254+ }
255+
256+ #[ test]
257+ fn replaces_turbofish_for_known_type ( ) {
258+ check_assist (
259+ replace_turbofish_with_explicit_type,
260+ r#"
261+ fn make<T>() -> T {}
262+ fn main() {
263+ let a = make$0::<i32>();
264+ }
265+ "# ,
266+ r#"
267+ fn make<T>() -> T {}
268+ fn main() {
269+ let a: i32 = make();
270+ }
271+ "# ,
272+ ) ;
273+ check_assist (
274+ replace_turbofish_with_explicit_type,
275+ r#"
276+ //- minicore: option
277+ fn make<T>() -> T {}
278+ fn main() {
279+ let a = make$0::<Option<bool>>();
280+ }
281+ "# ,
282+ r#"
283+ fn make<T>() -> T {}
284+ fn main() {
285+ let a: Option<bool> = make();
286+ }
287+ "# ,
288+ ) ;
289+ }
290+
291+ #[ test]
292+ fn replaces_turbofish_not_same_type ( ) {
293+ check_assist (
294+ replace_turbofish_with_explicit_type,
295+ r#"
296+ //- minicore: option
297+ fn make<T>() -> Option<T> {}
298+ fn main() {
299+ let a = make$0::<u128>();
300+ }
301+ "# ,
302+ r#"
303+ fn make<T>() -> Option<T> {}
304+ fn main() {
305+ let a: Option<u128> = make();
306+ }
307+ "# ,
308+ ) ;
309+ }
310+
311+ #[ test]
312+ fn replaces_turbofish_for_type_with_defaulted_generic_param ( ) {
313+ check_assist (
314+ replace_turbofish_with_explicit_type,
315+ r#"
316+ struct HasDefault<T, U = i32>(T, U);
317+ fn make<T>() -> HasDefault<T> {}
318+ fn main() {
319+ let a = make$0::<bool>();
320+ }
321+ "# ,
322+ r#"
323+ struct HasDefault<T, U = i32>(T, U);
324+ fn make<T>() -> HasDefault<T> {}
325+ fn main() {
326+ let a: HasDefault<bool> = make();
327+ }
240328"# ,
241329 ) ;
242330 }
0 commit comments