@@ -110,10 +110,12 @@ fn signature_help_for_call(
110
110
SignatureHelp { doc : None , signature : String :: new ( ) , parameters : vec ! [ ] , active_parameter } ;
111
111
112
112
let db = sema. db ;
113
+ let mut fn_params = None ;
113
114
match callable. kind ( ) {
114
115
hir:: CallableKind :: Function ( func) => {
115
116
res. doc = func. docs ( db) . map ( |it| it. into ( ) ) ;
116
117
format_to ! ( res. signature, "fn {}" , func. name( db) ) ;
118
+ fn_params = Some ( func. assoc_fn_params ( db) ) ;
117
119
}
118
120
hir:: CallableKind :: TupleStruct ( strukt) => {
119
121
res. doc = strukt. docs ( db) . map ( |it| it. into ( ) ) ;
@@ -137,26 +139,39 @@ fn signature_help_for_call(
137
139
format_to ! ( res. signature, "{}" , self_param)
138
140
}
139
141
let mut buf = String :: new ( ) ;
140
- for ( pat, ty) in callable. params ( db) {
142
+ for ( idx , ( pat, ty) ) in callable. params ( db) . into_iter ( ) . enumerate ( ) {
141
143
buf. clear ( ) ;
142
144
if let Some ( pat) = pat {
143
145
match pat {
144
146
Either :: Left ( _self) => format_to ! ( buf, "self: " ) ,
145
147
Either :: Right ( pat) => format_to ! ( buf, "{}: " , pat) ,
146
148
}
147
149
}
148
- format_to ! ( buf, "{}" , ty. display( db) ) ;
150
+ // APITs (argument position `impl Trait`s) are inferred as {unknown} as the user is
151
+ // in the middle of entering call arguments.
152
+ // In that case, fall back to render definitions of the respective parameters.
153
+ // This is overly conservative: we do not substitute known type vars
154
+ // (see FIXME in tests::impl_trait) and falling back on any unknowns.
155
+ match ( ty. contains_unknown ( ) , fn_params. as_deref ( ) ) {
156
+ ( true , Some ( fn_params) ) => format_to ! ( buf, "{}" , fn_params[ idx] . ty( ) . display( db) ) ,
157
+ _ => format_to ! ( buf, "{}" , ty. display( db) ) ,
158
+ }
149
159
res. push_call_param ( & buf) ;
150
160
}
151
161
}
152
162
res. signature . push ( ')' ) ;
153
163
164
+ let mut render = |ret_type : hir:: Type | {
165
+ if !ret_type. is_unit ( ) {
166
+ format_to ! ( res. signature, " -> {}" , ret_type. display( db) ) ;
167
+ }
168
+ } ;
154
169
match callable. kind ( ) {
170
+ hir:: CallableKind :: Function ( func) if callable. return_type ( ) . contains_unknown ( ) => {
171
+ render ( func. ret_type ( db) )
172
+ }
155
173
hir:: CallableKind :: Function ( _) | hir:: CallableKind :: Closure => {
156
- let ret_type = callable. return_type ( ) ;
157
- if !ret_type. is_unit ( ) {
158
- format_to ! ( res. signature, " -> {}" , ret_type. display( db) ) ;
159
- }
174
+ render ( callable. return_type ( ) )
160
175
}
161
176
hir:: CallableKind :: TupleStruct ( _) | hir:: CallableKind :: TupleEnumVariant ( _) => { }
162
177
}
@@ -420,8 +435,8 @@ fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
420
435
fn bar() { foo($03, ); }
421
436
"# ,
422
437
expect ! [ [ r#"
423
- fn foo(x: i32, y: {unknown} ) -> u32
424
- ^^^^^^ ------------
438
+ fn foo(x: i32, y: U ) -> u32
439
+ ^^^^^^ ----
425
440
"# ] ] ,
426
441
) ;
427
442
}
@@ -434,7 +449,7 @@ fn foo<T>() -> T where T: Copy + Display {}
434
449
fn bar() { foo($0); }
435
450
"# ,
436
451
expect ! [ [ r#"
437
- fn foo() -> {unknown}
452
+ fn foo() -> T
438
453
"# ] ] ,
439
454
) ;
440
455
}
@@ -633,26 +648,21 @@ pub fn do_it() {
633
648
fn test_fn_signature_with_docs_from_actix ( ) {
634
649
check (
635
650
r#"
636
- struct WriteHandler<E>;
637
-
638
- impl<E> WriteHandler<E> {
639
- /// Method is called when writer emits error.
640
- ///
641
- /// If this method returns `ErrorAction::Continue` writer processing
642
- /// continues otherwise stream processing stops.
643
- fn error(&mut self, err: E, ctx: &mut Self::Context) -> Running {
644
- Running::Stop
645
- }
646
-
651
+ trait Actor {
652
+ /// Actor execution context type
653
+ type Context;
654
+ }
655
+ trait WriteHandler<E>
656
+ where
657
+ Self: Actor
658
+ {
647
659
/// Method is called when writer finishes.
648
660
///
649
661
/// By default this method stops actor's `Context`.
650
- fn finished(&mut self, ctx: &mut Self::Context) {
651
- ctx.stop()
652
- }
662
+ fn finished(&mut self, ctx: &mut Self::Context) {}
653
663
}
654
664
655
- pub fn foo(mut r: WriteHandler<()>) {
665
+ fn foo(mut r: impl WriteHandler<()>) {
656
666
r.finished($0);
657
667
}
658
668
"# ,
@@ -661,8 +671,8 @@ pub fn foo(mut r: WriteHandler<()>) {
661
671
662
672
By default this method stops actor's `Context`.
663
673
------
664
- fn finished(&mut self, ctx: &mut {unknown} )
665
- ^^^^^^^^^^^^^^^^^^^
674
+ fn finished(&mut self, ctx: &mut <impl WriteHandler<()> as Actor>::Context )
675
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
666
676
"# ] ] ,
667
677
) ;
668
678
}
@@ -1055,4 +1065,23 @@ fn f() {
1055
1065
"# ] ] ,
1056
1066
) ;
1057
1067
}
1068
+
1069
+ #[ test]
1070
+ fn impl_trait ( ) {
1071
+ // FIXME: Substitute type vars in impl trait (`U` -> `i8`)
1072
+ check (
1073
+ r#"
1074
+ trait Trait<T> {}
1075
+ struct Wrap<T>(T);
1076
+ fn foo<U>(x: Wrap<impl Trait<U>>) {}
1077
+ fn f() {
1078
+ foo::<i8>($0)
1079
+ }
1080
+ "# ,
1081
+ expect ! [ [ r#"
1082
+ fn foo(x: Wrap<impl Trait<U>>)
1083
+ ^^^^^^^^^^^^^^^^^^^^^^
1084
+ "# ] ] ,
1085
+ ) ;
1086
+ }
1058
1087
}
0 commit comments