@@ -110,10 +110,12 @@ fn signature_help_for_call(
110110 SignatureHelp { doc : None , signature : String :: new ( ) , parameters : vec ! [ ] , active_parameter } ;
111111
112112 let db = sema. db ;
113+ let mut fn_params = None ;
113114 match callable. kind ( ) {
114115 hir:: CallableKind :: Function ( func) => {
115116 res. doc = func. docs ( db) . map ( |it| it. into ( ) ) ;
116117 format_to ! ( res. signature, "fn {}" , func. name( db) ) ;
118+ fn_params = Some ( func. assoc_fn_params ( db) ) ;
117119 }
118120 hir:: CallableKind :: TupleStruct ( strukt) => {
119121 res. doc = strukt. docs ( db) . map ( |it| it. into ( ) ) ;
@@ -137,26 +139,39 @@ fn signature_help_for_call(
137139 format_to ! ( res. signature, "{}" , self_param)
138140 }
139141 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 ( ) {
141143 buf. clear ( ) ;
142144 if let Some ( pat) = pat {
143145 match pat {
144146 Either :: Left ( _self) => format_to ! ( buf, "self: " ) ,
145147 Either :: Right ( pat) => format_to ! ( buf, "{}: " , pat) ,
146148 }
147149 }
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+ }
149159 res. push_call_param ( & buf) ;
150160 }
151161 }
152162 res. signature . push ( ')' ) ;
153163
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+ } ;
154169 match callable. kind ( ) {
170+ hir:: CallableKind :: Function ( func) if callable. return_type ( ) . contains_unknown ( ) => {
171+ render ( func. ret_type ( db) )
172+ }
155173 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 ( ) )
160175 }
161176 hir:: CallableKind :: TupleStruct ( _) | hir:: CallableKind :: TupleEnumVariant ( _) => { }
162177 }
@@ -420,8 +435,8 @@ fn foo<T, U: Copy + Display>(x: T, y: U) -> u32
420435fn bar() { foo($03, ); }
421436"# ,
422437 expect ! [ [ r#"
423- fn foo(x: i32, y: {unknown} ) -> u32
424- ^^^^^^ ------------
438+ fn foo(x: i32, y: U ) -> u32
439+ ^^^^^^ ----
425440 "# ] ] ,
426441 ) ;
427442 }
@@ -434,7 +449,7 @@ fn foo<T>() -> T where T: Copy + Display {}
434449fn bar() { foo($0); }
435450"# ,
436451 expect ! [ [ r#"
437- fn foo() -> {unknown}
452+ fn foo() -> T
438453 "# ] ] ,
439454 ) ;
440455 }
@@ -633,26 +648,21 @@ pub fn do_it() {
633648 fn test_fn_signature_with_docs_from_actix ( ) {
634649 check (
635650 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+ {
647659 /// Method is called when writer finishes.
648660 ///
649661 /// 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) {}
653663}
654664
655- pub fn foo(mut r: WriteHandler<()>) {
665+ fn foo(mut r: impl WriteHandler<()>) {
656666 r.finished($0);
657667}
658668"# ,
@@ -661,8 +671,8 @@ pub fn foo(mut r: WriteHandler<()>) {
661671
662672 By default this method stops actor's `Context`.
663673 ------
664- fn finished(&mut self, ctx: &mut {unknown} )
665- ^^^^^^^^^^^^^^^^^^^
674+ fn finished(&mut self, ctx: &mut <impl WriteHandler<()> as Actor>::Context )
675+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
666676 "# ] ] ,
667677 ) ;
668678 }
@@ -1055,4 +1065,23 @@ fn f() {
10551065 "# ] ] ,
10561066 ) ;
10571067 }
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+ }
10581087}
0 commit comments