})
.unwrap_or(Access::Owned)
}
+
+ pub fn display(self, db: &dyn HirDatabase) -> &'static str {
+ match self.access(db) {
+ Access::Shared => "&self",
+ Access::Exclusive => "&mut self",
+ Access::Owned => "self",
+ }
+ }
}
impl HasVisibility for Function {
"#,
expect![[r#"
fd foo u32
- me bar() -> ()
+ me bar() fn(&self)
"#]],
);
}
"#,
expect![[r#"
fd the_field (u32,)
- me foo() -> ()
+ me foo() fn(self)
"#]],
)
}
"#,
expect![[r#"
fd the_field (u32, i32)
- me foo() -> ()
+ me foo() fn(&self)
"#]],
)
}
fn foo(a: A) { a.$0 }
"#,
expect![[r#"
- me the_method() -> ()
+ me the_method() fn(&self)
"#]],
);
}
fn foo(a: A<u32>) { a.$0 }
"#,
expect![[r#"
- me the_method() -> ()
+ me the_method() fn(&self)
"#]],
)
}
fn foo(a: A) { a.$0 }
"#,
expect![[r#"
- me the_method() -> ()
+ me the_method() fn(&self)
"#]],
);
}
fn foo(a: &A) { a.$0 }
",
expect![[r#"
- me the_method() -> ()
+ me the_method() fn(&self)
"#]],
);
}
fn foo(a: A) { a.$0 }
",
expect![[r#"
- me the_method() -> ()
+ me the_method() fn(&self)
"#]],
);
}
}
"#,
expect![[r#"
- me blah() -> ()
+ me blah() fn(&self)
"#]],
);
}
}
"#,
expect![[r#"
- me the_method() -> ()
+ me the_method() fn(&self)
"#]],
);
}
fn main() { make_s!().f$0; }
"#,
expect![[r#"
- me foo() -> ()
+ me foo() fn(&self)
"#]],
)
}
}
"#,
expect![[r#"
- me private() -> ()
+ me private() fn(&self)
"#]],
);
}
check(
fixture,
expect![[r#"
- fn weird_function() (dep::test_mod::TestTrait) -> ()
+ fn weird_function() (dep::test_mod::TestTrait) fn()
"#]],
);
check(
fixture,
expect![[r#"
- me random_method() (dep::test_mod::TestTrait) -> ()
+ me random_method() (dep::test_mod::TestTrait) fn(&self)
"#]],
);
}
"#,
expect![[r#"
- me random_method() (dep::test_mod::TestTrait) -> () DEPRECATED
+ me random_method() (dep::test_mod::TestTrait) fn(&self) DEPRECATED
"#]],
);
"#,
expect![[r#"
ct SPECIAL_CONST (dep::test_mod::TestTrait) DEPRECATED
- fn weird_function() (dep::test_mod::TestTrait) -> () DEPRECATED
+ fn weird_function() (dep::test_mod::TestTrait) fn() DEPRECATED
"#]],
);
}
fn foo() { let _ = S::$0 }
"#,
expect![[r#"
- fn a() -> ()
- me b(…) -> ()
+ fn a() fn()
+ me b(…) fn(&self)
ct C const C: i32 = 42;
ta T type T = i32;
"#]],
fn foo() { let _ = S::$0 }
"#,
expect![[r#"
- fn public_method() -> ()
+ fn public_method() fn()
ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1;
ta PublicType pub(crate) type PublicType = u32;
"#]],
fn foo() { let _ = E::$0 }
"#,
expect![[r#"
- fn m() -> ()
+ fn m() fn()
"#]],
);
}
fn foo() { let _ = U::$0 }
"#,
expect![[r#"
- fn m() -> ()
+ fn m() fn()
"#]],
);
}
fn foo() { let _ = Trait::$0 }
"#,
expect![[r#"
- fn m() -> ()
+ fn m() fn()
"#]],
);
}
fn foo() { let _ = S::$0 }
"#,
expect![[r#"
- fn m() -> ()
+ fn m() fn()
"#]],
);
}
fn foo() { let _ = <S as Trait>::$0 }
"#,
expect![[r#"
- fn m() -> ()
+ fn m() fn()
"#]],
);
}
ta SubTy type SubTy;
ta Ty type Ty;
ct C2 const C2: ();
- fn subfunc() -> ()
- me submethod(…) -> ()
+ fn subfunc() fn()
+ me submethod(…) fn(&self)
ct CONST const CONST: u8;
- fn func() -> ()
- me method(…) -> ()
+ fn func() fn()
+ me method(…) fn(&self)
"#]],
);
}
ta SubTy type SubTy;
ta Ty type Ty;
ct CONST const CONST: u8 = 0;
- fn func() -> ()
- me method(…) -> ()
+ fn func() fn()
+ me method(…) fn(&self)
ct C2 const C2: () = ();
- fn subfunc() -> ()
- me submethod(…) -> ()
+ fn subfunc() fn()
+ me submethod(…) fn(&self)
"#]],
);
}
fn main() { T::$0; }
"#,
expect![[r#"
- fn foo() -> ()
- fn bar() -> ()
+ fn foo() fn()
+ fn bar() fn()
"#]],
);
}
fn main() { let _ = crate::$0 }
"#,
expect![[r##"
- fn main() -> ()
+ fn main() fn()
ma foo!(…) #[macro_export] macro_rules! foo
"##]],
);
"#,
expect![[r#"
ct RIGHT_CONST
- fn right_fn() -> ()
+ fn right_fn() fn()
st RightType
"#]],
);
fn foo() {}
"#,
expect![[r#"
- fn main() -> ()
- fn foo() -> ()
+ fn main() fn()
+ fn foo() fn()
"#]],
);
}
"#,
expect![[r#"
md z
- fn z() -> ()
+ fn z() fn()
"#]],
);
}
}
"#,
expect![[r#"
- fn new() -> HashMap<K, V, RandomState>
+ fn new() fn() -> HashMap<K, V, RandomState>
"#]],
);
}
}
"#,
expect![[r#"
- fn main() -> ()
- fn foo(…) -> ()
+ fn main() fn()
+ fn foo(…) fn(i32, i32)
"#]],
);
}
expect![[r#"
ev Bar ()
ev Baz ()
- me foo(…) -> ()
+ me foo(…) fn(self)
"#]],
);
}
"#,
expect![[r#"
ct MAX pub const MAX: Self = 255;
- me func(…) -> ()
+ me func(…) fn(self)
"#]],
);
}
expect![[r#"
lc y i32
lc x i32
- fn quux(…) -> ()
+ fn quux(…) fn(i32)
"#]],
);
}
expect![[r#"
lc b i32
lc a
- fn quux() -> ()
+ fn quux() fn()
"#]],
);
}
"#,
expect![[r#"
lc x
- fn quux() -> ()
+ fn quux() fn()
"#]],
);
}
r#"fn quux<T>() { $0 }"#,
expect![[r#"
tp T
- fn quux() -> ()
+ fn quux() fn()
"#]],
);
check(
r#"fn quux<const C: usize>() { $0 }"#,
expect![[r#"
cp C
- fn quux() -> ()
+ fn quux() fn()
"#]],
);
}
check(
r#"fn quux<'a>() { $0 }"#,
expect![[r#"
- fn quux() -> ()
+ fn quux() fn()
"#]],
);
}
"#,
expect![[r#"
st S
- fn quux() -> ()
+ fn quux() fn()
en E
"#]],
);
}
"#,
expect![[r#"
- fn quux() -> ()
+ fn quux() fn()
st Bar
"#]],
);
"#,
expect![[r#"
st Foo
- fn x() -> ()
+ fn x() fn()
"#]],
);
}
expect![[r#"
lc bar i32
lc bar i32
- fn foo() -> ()
+ fn foo() fn()
"#]],
);
}
mod prelude { struct Option; }
"#,
expect![[r#"
- fn foo() -> ()
+ fn foo() fn()
md std
st Option
"#]],
}
"#,
expect![[r##"
- fn f() -> ()
+ fn f() fn()
ma concat!(…) #[macro_export] macro_rules! concat
md std
"##]],
mod prelude { struct String; }
"#,
expect![[r#"
- fn foo() -> ()
+ fn foo() fn()
md std
md core
st String
expect![[r##"
md m1
ma baz!(…) #[macro_export] macro_rules! baz
- fn main() -> ()
+ fn main() fn()
md m2
ma bar!(…) macro_rules! bar
ma foo!(…) macro_rules! foo
fn foo() { $0 }
"#,
expect![[r#"
- fn foo() -> ()
+ fn foo() fn()
ma foo!(…) macro_rules! foo
"#]],
);
fn main() { let x: $0 }
"#,
expect![[r#"
- fn main() -> ()
+ fn main() fn()
ma foo!(…) macro_rules! foo
"#]],
);
fn main() { $0 }
"#,
expect![[r#"
- fn main() -> ()
+ fn main() fn()
ma foo!(…) macro_rules! foo
"#]],
);
}
"#,
expect![[r#"
- fn frobnicate() -> ()
- fn main() -> ()
+ fn frobnicate() fn()
+ fn main() fn()
"#]],
);
}
expect![[r#"
lc y i32
lc x i32
- fn quux(…) -> ()
+ fn quux(…) fn(i32)
ma m!(…) macro_rules! m
"#]],
);
expect![[r#"
lc y i32
lc x i32
- fn quux(…) -> ()
+ fn quux(…) fn(i32)
ma m!(…) macro_rules! m
"#]],
);
expect![[r#"
lc y i32
lc x i32
- fn quux(…) -> ()
+ fn quux(…) fn(i32)
ma m!(…) macro_rules! m
"#]],
);
fn main() { $0 }
"#,
expect![[r#"
- fn main() -> ()
+ fn main() fn()
?? Quux
"#]],
);
ev Foo::Baz ()
ev Foo::Quux ()
en Foo
- fn main() -> ()
+ fn main() fn()
"#]],
)
}
expect![[r#"
ev m::E::V ()
md m
- fn f() -> E
+ fn f() fn() -> E
"#]],
)
}
bar.fo$0;
}
"#,
- DetailAndDocumentation { detail: "-> ()", documentation: "Do the foo" },
+ DetailAndDocumentation { detail: "fn(&self)", documentation: "Do the foo" },
);
}
bar.fo$0;
}
"#,
- DetailAndDocumentation { detail: "-> ()", documentation: " Do the foo" },
+ DetailAndDocumentation { detail: "fn(&self)", documentation: " Do the foo" },
);
}
for c in fo$0
}
"#,
- DetailAndDocumentation { detail: "-> &str", documentation: "Do the foo" },
+ DetailAndDocumentation { detail: "fn() -> &str", documentation: "Do the foo" },
);
}
}
);
}
+ #[test]
+ fn fn_detail_includes_args_and_return_type() {
+ check(
+ r#"
+fn foo<T>(a: u32, b: u32, t: T) -> (u32, T) { (a, t) }
+
+fn main() { fo$0 }
+"#,
+ expect![[r#"
+ [
+ CompletionItem {
+ label: "foo(…)",
+ source_range: 68..70,
+ delete: 68..70,
+ insert: "foo(${1:a}, ${2:b}, ${3:t})$0",
+ kind: SymbolKind(
+ Function,
+ ),
+ lookup: "foo",
+ detail: "fn(u32, u32, T) -> (u32, T)",
+ trigger_call_info: true,
+ },
+ CompletionItem {
+ label: "main()",
+ source_range: 68..70,
+ delete: 68..70,
+ insert: "main()$0",
+ kind: SymbolKind(
+ Function,
+ ),
+ lookup: "main",
+ detail: "fn()",
+ },
+ ]
+ "#]],
+ );
+ }
+
#[test]
fn enum_detail_just_parentheses_for_unit() {
check(
Function,
),
lookup: "main",
- detail: "-> ()",
+ detail: "fn()",
},
]
"#]],
Function,
),
lookup: "main",
- detail: "-> ()",
+ detail: "fn()",
},
CompletionItem {
label: "something_deprecated()",
Function,
),
lookup: "something_deprecated",
- detail: "-> ()",
+ detail: "fn()",
deprecated: true,
},
CompletionItem {
Function,
),
lookup: "something_else_deprecated",
- detail: "-> ()",
+ detail: "fn()",
deprecated: true,
},
]
insert: "bar()$0",
kind: Method,
lookup: "bar",
- detail: "-> ()",
+ detail: "fn(self)",
documentation: Documentation(
"Method docs",
),
insert: "the_method()$0",
kind: Method,
lookup: "the_method",
- detail: "-> ()",
+ detail: "fn(&self)",
},
]
"#]],
Function,
),
lookup: "foo",
- detail: "-> ()",
+ detail: "fn(&mut S)",
trigger_call_info: true,
},
CompletionItem {
Function,
),
lookup: "main",
- detail: "-> ()",
+ detail: "fn()",
},
CompletionItem {
label: "s",
use hir::{HasSource, HirDisplay, Type};
use ide_db::SymbolKind;
+use itertools::Itertools;
use syntax::ast::Fn;
use crate::{
}
fn detail(&self) -> String {
- let ty = self.func.ret_type(self.ctx.db());
- format!("-> {}", ty.display(self.ctx.db()))
+ let params = if let Some(self_param) = self.func.self_param(self.ctx.db()) {
+ let params = self
+ .func
+ .assoc_fn_params(self.ctx.db())
+ .into_iter()
+ .skip(1) // skip the self param because we are manually handling that
+ .map(|p| p.ty().display(self.ctx.db()).to_string());
+
+ std::iter::once(self_param.display(self.ctx.db()).to_owned()).chain(params).join(", ")
+ } else {
+ let params = self
+ .func
+ .assoc_fn_params(self.ctx.db())
+ .into_iter()
+ .map(|p| p.ty().display(self.ctx.db()).to_string())
+ .join(", ");
+ params
+ };
+
+ let ret_ty = self.func.ret_type(self.ctx.db());
+ let ret = if ret_ty.is_unit() {
+ // Omit the `-> ()` for unit return types
+ String::new()
+ } else {
+ format!(" -> {}", ret_ty.display(self.ctx.db()))
+ };
+
+ format!("fn({}){}", params, ret)
}
fn add_arg(&self, arg: &str, ty: &Type) -> String {