diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/handlers/pull_assignment_up.rs (renamed from crates/assists/src/handlers/extract_assignment.rs) | 54 | ||||
-rw-r--r-- | crates/assists/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/assists/src/tests/generated.rs | 58 | ||||
-rw-r--r-- | crates/hir/src/code_model.rs | 20 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/display/short_label.rs | 11 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 91 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 2 |
8 files changed, 166 insertions, 80 deletions
diff --git a/crates/assists/src/handlers/extract_assignment.rs b/crates/assists/src/handlers/pull_assignment_up.rs index ae99598c0..560d93e10 100644 --- a/crates/assists/src/handlers/extract_assignment.rs +++ b/crates/assists/src/handlers/pull_assignment_up.rs | |||
@@ -9,9 +9,9 @@ use crate::{ | |||
9 | AssistId, AssistKind, | 9 | AssistId, AssistKind, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | // Assist: extract_assignment | 12 | // Assist: pull_assignment_up |
13 | // | 13 | // |
14 | // Extracts variable assigment to outside an if or match statement. | 14 | // Extracts variable assignment to outside an if or match statement. |
15 | // | 15 | // |
16 | // ``` | 16 | // ``` |
17 | // fn main() { | 17 | // fn main() { |
@@ -36,7 +36,7 @@ use crate::{ | |||
36 | // }; | 36 | // }; |
37 | // } | 37 | // } |
38 | // ``` | 38 | // ``` |
39 | pub(crate) fn extract_assigment(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 39 | pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
40 | let assign_expr = ctx.find_node_at_offset::<ast::BinExpr>()?; | 40 | let assign_expr = ctx.find_node_at_offset::<ast::BinExpr>()?; |
41 | let name_expr = if assign_expr.op_kind()? == ast::BinOp::Assignment { | 41 | let name_expr = if assign_expr.op_kind()? == ast::BinOp::Assignment { |
42 | assign_expr.lhs()? | 42 | assign_expr.lhs()? |
@@ -61,8 +61,8 @@ pub(crate) fn extract_assigment(acc: &mut Assists, ctx: &AssistContext) -> Optio | |||
61 | let expr_stmt = make::expr_stmt(new_stmt); | 61 | let expr_stmt = make::expr_stmt(new_stmt); |
62 | 62 | ||
63 | acc.add( | 63 | acc.add( |
64 | AssistId("extract_assignment", AssistKind::RefactorExtract), | 64 | AssistId("pull_assignment_up", AssistKind::RefactorExtract), |
65 | "Extract assignment", | 65 | "Pull assignment up", |
66 | old_stmt.syntax().text_range(), | 66 | old_stmt.syntax().text_range(), |
67 | move |edit| { | 67 | move |edit| { |
68 | edit.replace(old_stmt.syntax().text_range(), format!("{} = {};", name_expr, expr_stmt)); | 68 | edit.replace(old_stmt.syntax().text_range(), format!("{} = {};", name_expr, expr_stmt)); |
@@ -104,7 +104,7 @@ fn exprify_if( | |||
104 | ast::ElseBranch::Block(exprify_block(block, sema, name)?) | 104 | ast::ElseBranch::Block(exprify_block(block, sema, name)?) |
105 | } | 105 | } |
106 | ast::ElseBranch::IfExpr(expr) => { | 106 | ast::ElseBranch::IfExpr(expr) => { |
107 | mark::hit!(test_extract_assigment_chained_if); | 107 | mark::hit!(test_pull_assignment_up_chained_if); |
108 | ast::ElseBranch::IfExpr(ast::IfExpr::cast( | 108 | ast::ElseBranch::IfExpr(ast::IfExpr::cast( |
109 | exprify_if(&expr, sema, name)?.syntax().to_owned(), | 109 | exprify_if(&expr, sema, name)?.syntax().to_owned(), |
110 | )?) | 110 | )?) |
@@ -144,7 +144,7 @@ fn is_equivalent( | |||
144 | ) -> bool { | 144 | ) -> bool { |
145 | match (expr0, expr1) { | 145 | match (expr0, expr1) { |
146 | (ast::Expr::FieldExpr(field_expr0), ast::Expr::FieldExpr(field_expr1)) => { | 146 | (ast::Expr::FieldExpr(field_expr0), ast::Expr::FieldExpr(field_expr1)) => { |
147 | mark::hit!(test_extract_assignment_field_assignment); | 147 | mark::hit!(test_pull_assignment_up_field_assignment); |
148 | sema.resolve_field(field_expr0) == sema.resolve_field(field_expr1) | 148 | sema.resolve_field(field_expr0) == sema.resolve_field(field_expr1) |
149 | } | 149 | } |
150 | (ast::Expr::PathExpr(path0), ast::Expr::PathExpr(path1)) => { | 150 | (ast::Expr::PathExpr(path0), ast::Expr::PathExpr(path1)) => { |
@@ -167,9 +167,9 @@ mod tests { | |||
167 | use crate::tests::{check_assist, check_assist_not_applicable}; | 167 | use crate::tests::{check_assist, check_assist_not_applicable}; |
168 | 168 | ||
169 | #[test] | 169 | #[test] |
170 | fn test_extract_assignment_if() { | 170 | fn test_pull_assignment_up_if() { |
171 | check_assist( | 171 | check_assist( |
172 | extract_assigment, | 172 | pull_assignment_up, |
173 | r#" | 173 | r#" |
174 | fn foo() { | 174 | fn foo() { |
175 | let mut a = 1; | 175 | let mut a = 1; |
@@ -194,9 +194,9 @@ fn foo() { | |||
194 | } | 194 | } |
195 | 195 | ||
196 | #[test] | 196 | #[test] |
197 | fn test_extract_assignment_match() { | 197 | fn test_pull_assignment_up_match() { |
198 | check_assist( | 198 | check_assist( |
199 | extract_assigment, | 199 | pull_assignment_up, |
200 | r#" | 200 | r#" |
201 | fn foo() { | 201 | fn foo() { |
202 | let mut a = 1; | 202 | let mut a = 1; |
@@ -233,9 +233,9 @@ fn foo() { | |||
233 | } | 233 | } |
234 | 234 | ||
235 | #[test] | 235 | #[test] |
236 | fn test_extract_assignment_not_last_not_applicable() { | 236 | fn test_pull_assignment_up_not_last_not_applicable() { |
237 | check_assist_not_applicable( | 237 | check_assist_not_applicable( |
238 | extract_assigment, | 238 | pull_assignment_up, |
239 | r#" | 239 | r#" |
240 | fn foo() { | 240 | fn foo() { |
241 | let mut a = 1; | 241 | let mut a = 1; |
@@ -251,10 +251,10 @@ fn foo() { | |||
251 | } | 251 | } |
252 | 252 | ||
253 | #[test] | 253 | #[test] |
254 | fn test_extract_assignment_chained_if() { | 254 | fn test_pull_assignment_up_chained_if() { |
255 | mark::check!(test_extract_assigment_chained_if); | 255 | mark::check!(test_pull_assignment_up_chained_if); |
256 | check_assist( | 256 | check_assist( |
257 | extract_assigment, | 257 | pull_assignment_up, |
258 | r#" | 258 | r#" |
259 | fn foo() { | 259 | fn foo() { |
260 | let mut a = 1; | 260 | let mut a = 1; |
@@ -283,9 +283,9 @@ fn foo() { | |||
283 | } | 283 | } |
284 | 284 | ||
285 | #[test] | 285 | #[test] |
286 | fn test_extract_assigment_retains_stmts() { | 286 | fn test_pull_assignment_up_retains_stmts() { |
287 | check_assist( | 287 | check_assist( |
288 | extract_assigment, | 288 | pull_assignment_up, |
289 | r#" | 289 | r#" |
290 | fn foo() { | 290 | fn foo() { |
291 | let mut a = 1; | 291 | let mut a = 1; |
@@ -314,9 +314,9 @@ fn foo() { | |||
314 | } | 314 | } |
315 | 315 | ||
316 | #[test] | 316 | #[test] |
317 | fn extract_assignment_let_stmt_not_applicable() { | 317 | fn pull_assignment_up_let_stmt_not_applicable() { |
318 | check_assist_not_applicable( | 318 | check_assist_not_applicable( |
319 | extract_assigment, | 319 | pull_assignment_up, |
320 | r#" | 320 | r#" |
321 | fn foo() { | 321 | fn foo() { |
322 | let mut a = 1; | 322 | let mut a = 1; |
@@ -331,9 +331,9 @@ fn foo() { | |||
331 | } | 331 | } |
332 | 332 | ||
333 | #[test] | 333 | #[test] |
334 | fn extract_assignment_if_missing_assigment_not_applicable() { | 334 | fn pull_assignment_up_if_missing_assigment_not_applicable() { |
335 | check_assist_not_applicable( | 335 | check_assist_not_applicable( |
336 | extract_assigment, | 336 | pull_assignment_up, |
337 | r#" | 337 | r#" |
338 | fn foo() { | 338 | fn foo() { |
339 | let mut a = 1; | 339 | let mut a = 1; |
@@ -346,9 +346,9 @@ fn foo() { | |||
346 | } | 346 | } |
347 | 347 | ||
348 | #[test] | 348 | #[test] |
349 | fn extract_assignment_match_missing_assigment_not_applicable() { | 349 | fn pull_assignment_up_match_missing_assigment_not_applicable() { |
350 | check_assist_not_applicable( | 350 | check_assist_not_applicable( |
351 | extract_assigment, | 351 | pull_assignment_up, |
352 | r#" | 352 | r#" |
353 | fn foo() { | 353 | fn foo() { |
354 | let mut a = 1; | 354 | let mut a = 1; |
@@ -367,10 +367,10 @@ fn foo() { | |||
367 | } | 367 | } |
368 | 368 | ||
369 | #[test] | 369 | #[test] |
370 | fn test_extract_assignment_field_assignment() { | 370 | fn test_pull_assignment_up_field_assignment() { |
371 | mark::check!(test_extract_assignment_field_assignment); | 371 | mark::check!(test_pull_assignment_up_field_assignment); |
372 | check_assist( | 372 | check_assist( |
373 | extract_assigment, | 373 | pull_assignment_up, |
374 | r#" | 374 | r#" |
375 | struct A(usize); | 375 | struct A(usize); |
376 | 376 | ||
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 212464f85..01baa65fe 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs | |||
@@ -116,7 +116,6 @@ mod handlers { | |||
116 | mod convert_integer_literal; | 116 | mod convert_integer_literal; |
117 | mod early_return; | 117 | mod early_return; |
118 | mod expand_glob_import; | 118 | mod expand_glob_import; |
119 | mod extract_assignment; | ||
120 | mod extract_module_to_file; | 119 | mod extract_module_to_file; |
121 | mod extract_struct_from_enum_variant; | 120 | mod extract_struct_from_enum_variant; |
122 | mod extract_variable; | 121 | mod extract_variable; |
@@ -125,8 +124,8 @@ mod handlers { | |||
125 | mod flip_binexpr; | 124 | mod flip_binexpr; |
126 | mod flip_comma; | 125 | mod flip_comma; |
127 | mod flip_trait_bound; | 126 | mod flip_trait_bound; |
128 | mod generate_derive; | ||
129 | mod generate_default_from_enum_variant; | 127 | mod generate_default_from_enum_variant; |
128 | mod generate_derive; | ||
130 | mod generate_from_impl_for_enum; | 129 | mod generate_from_impl_for_enum; |
131 | mod generate_function; | 130 | mod generate_function; |
132 | mod generate_impl; | 131 | mod generate_impl; |
@@ -139,6 +138,7 @@ mod handlers { | |||
139 | mod merge_match_arms; | 138 | mod merge_match_arms; |
140 | mod move_bounds; | 139 | mod move_bounds; |
141 | mod move_guard; | 140 | mod move_guard; |
141 | mod pull_assignment_up; | ||
142 | mod qualify_path; | 142 | mod qualify_path; |
143 | mod raw_string; | 143 | mod raw_string; |
144 | mod remove_dbg; | 144 | mod remove_dbg; |
@@ -168,7 +168,6 @@ mod handlers { | |||
168 | convert_integer_literal::convert_integer_literal, | 168 | convert_integer_literal::convert_integer_literal, |
169 | early_return::convert_to_guarded_return, | 169 | early_return::convert_to_guarded_return, |
170 | expand_glob_import::expand_glob_import, | 170 | expand_glob_import::expand_glob_import, |
171 | extract_assignment::extract_assigment, | ||
172 | extract_module_to_file::extract_module_to_file, | 171 | extract_module_to_file::extract_module_to_file, |
173 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, | 172 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, |
174 | extract_variable::extract_variable, | 173 | extract_variable::extract_variable, |
@@ -177,8 +176,8 @@ mod handlers { | |||
177 | flip_binexpr::flip_binexpr, | 176 | flip_binexpr::flip_binexpr, |
178 | flip_comma::flip_comma, | 177 | flip_comma::flip_comma, |
179 | flip_trait_bound::flip_trait_bound, | 178 | flip_trait_bound::flip_trait_bound, |
180 | generate_derive::generate_derive, | ||
181 | generate_default_from_enum_variant::generate_default_from_enum_variant, | 179 | generate_default_from_enum_variant::generate_default_from_enum_variant, |
180 | generate_derive::generate_derive, | ||
182 | generate_from_impl_for_enum::generate_from_impl_for_enum, | 181 | generate_from_impl_for_enum::generate_from_impl_for_enum, |
183 | generate_function::generate_function, | 182 | generate_function::generate_function, |
184 | generate_impl::generate_impl, | 183 | generate_impl::generate_impl, |
@@ -192,6 +191,7 @@ mod handlers { | |||
192 | move_bounds::move_bounds_to_where_clause, | 191 | move_bounds::move_bounds_to_where_clause, |
193 | move_guard::move_arm_cond_to_match_guard, | 192 | move_guard::move_arm_cond_to_match_guard, |
194 | move_guard::move_guard_to_arm_body, | 193 | move_guard::move_guard_to_arm_body, |
194 | pull_assignment_up::pull_assignment_up, | ||
195 | qualify_path::qualify_path, | 195 | qualify_path::qualify_path, |
196 | raw_string::add_hash, | 196 | raw_string::add_hash, |
197 | raw_string::make_usual_string, | 197 | raw_string::make_usual_string, |
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs index b91a816e8..85e3c6742 100644 --- a/crates/assists/src/tests/generated.rs +++ b/crates/assists/src/tests/generated.rs | |||
@@ -238,35 +238,6 @@ fn qux(bar: Bar, baz: Baz) {} | |||
238 | } | 238 | } |
239 | 239 | ||
240 | #[test] | 240 | #[test] |
241 | fn doctest_extract_assignment() { | ||
242 | check_doc_test( | ||
243 | "extract_assignment", | ||
244 | r#####" | ||
245 | fn main() { | ||
246 | let mut foo = 6; | ||
247 | |||
248 | if true { | ||
249 | <|>foo = 5; | ||
250 | } else { | ||
251 | foo = 4; | ||
252 | } | ||
253 | } | ||
254 | "#####, | ||
255 | r#####" | ||
256 | fn main() { | ||
257 | let mut foo = 6; | ||
258 | |||
259 | foo = if true { | ||
260 | 5 | ||
261 | } else { | ||
262 | 4 | ||
263 | }; | ||
264 | } | ||
265 | "#####, | ||
266 | ) | ||
267 | } | ||
268 | |||
269 | #[test] | ||
270 | fn doctest_extract_module_to_file() { | 241 | fn doctest_extract_module_to_file() { |
271 | check_doc_test( | 242 | check_doc_test( |
272 | "extract_module_to_file", | 243 | "extract_module_to_file", |
@@ -767,6 +738,35 @@ fn handle(action: Action) { | |||
767 | } | 738 | } |
768 | 739 | ||
769 | #[test] | 740 | #[test] |
741 | fn doctest_pull_assignment_up() { | ||
742 | check_doc_test( | ||
743 | "pull_assignment_up", | ||
744 | r#####" | ||
745 | fn main() { | ||
746 | let mut foo = 6; | ||
747 | |||
748 | if true { | ||
749 | <|>foo = 5; | ||
750 | } else { | ||
751 | foo = 4; | ||
752 | } | ||
753 | } | ||
754 | "#####, | ||
755 | r#####" | ||
756 | fn main() { | ||
757 | let mut foo = 6; | ||
758 | |||
759 | foo = if true { | ||
760 | 5 | ||
761 | } else { | ||
762 | 4 | ||
763 | }; | ||
764 | } | ||
765 | "#####, | ||
766 | ) | ||
767 | } | ||
768 | |||
769 | #[test] | ||
770 | fn doctest_qualify_path() { | 770 | fn doctest_qualify_path() { |
771 | check_doc_test( | 771 | check_doc_test( |
772 | "qualify_path", | 772 | "qualify_path", |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 62eccf475..a2255508e 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -5,9 +5,7 @@ use arrayvec::ArrayVec; | |||
5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; | 5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; |
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::ReprKind, | 8 | adt::{ReprKind, StructKind, VariantData}, |
9 | adt::StructKind, | ||
10 | adt::VariantData, | ||
11 | builtin_type::BuiltinType, | 9 | builtin_type::BuiltinType, |
12 | expr::{BindingAnnotation, LabelId, Pat, PatId}, | 10 | expr::{BindingAnnotation, LabelId, Pat, PatId}, |
13 | import_map, | 11 | import_map, |
@@ -31,7 +29,7 @@ use hir_expand::{ | |||
31 | }; | 29 | }; |
32 | use hir_ty::{ | 30 | use hir_ty::{ |
33 | autoderef, | 31 | autoderef, |
34 | display::{HirDisplayError, HirFormatter}, | 32 | display::{write_bounds_like_dyn_trait, HirDisplayError, HirFormatter}, |
35 | method_resolution, | 33 | method_resolution, |
36 | traits::{FnTrait, Solution, SolutionVariables}, | 34 | traits::{FnTrait, Solution, SolutionVariables}, |
37 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 35 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, |
@@ -1293,6 +1291,20 @@ impl TypeParam { | |||
1293 | } | 1291 | } |
1294 | } | 1292 | } |
1295 | 1293 | ||
1294 | impl HirDisplay for TypeParam { | ||
1295 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
1296 | write!(f, "{}", self.name(f.db))?; | ||
1297 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
1298 | let substs = Substs::type_params(f.db, self.id.parent); | ||
1299 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
1300 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
1301 | write!(f, ": ")?; | ||
1302 | write_bounds_like_dyn_trait(&predicates, f)?; | ||
1303 | } | ||
1304 | Ok(()) | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1296 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1308 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1297 | pub struct LifetimeParam { | 1309 | pub struct LifetimeParam { |
1298 | pub(crate) id: LifetimeParamId, | 1310 | pub(crate) id: LifetimeParamId, |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 0e827a29e..a54225c18 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -595,7 +595,7 @@ impl HirDisplay for FnSig { | |||
595 | } | 595 | } |
596 | } | 596 | } |
597 | 597 | ||
598 | fn write_bounds_like_dyn_trait( | 598 | pub fn write_bounds_like_dyn_trait( |
599 | predicates: &[GenericPredicate], | 599 | predicates: &[GenericPredicate], |
600 | f: &mut HirFormatter, | 600 | f: &mut HirFormatter, |
601 | ) -> Result<(), HirDisplayError> { | 601 | ) -> Result<(), HirDisplayError> { |
diff --git a/crates/ide/src/display/short_label.rs b/crates/ide/src/display/short_label.rs index ea49d9f97..990f740b8 100644 --- a/crates/ide/src/display/short_label.rs +++ b/crates/ide/src/display/short_label.rs | |||
@@ -87,6 +87,17 @@ impl ShortLabel for ast::Variant { | |||
87 | } | 87 | } |
88 | } | 88 | } |
89 | 89 | ||
90 | impl ShortLabel for ast::ConstParam { | ||
91 | fn short_label(&self) -> Option<String> { | ||
92 | let mut buf = "const ".to_owned(); | ||
93 | buf.push_str(self.name()?.text().as_str()); | ||
94 | if let Some(type_ref) = self.ty() { | ||
95 | format_to!(buf, ": {}", type_ref.syntax()); | ||
96 | } | ||
97 | Some(buf) | ||
98 | } | ||
99 | } | ||
100 | |||
90 | fn short_label_from_ty<T>(node: &T, ty: Option<ast::Type>, prefix: &str) -> Option<String> | 101 | fn short_label_from_ty<T>(node: &T, ty: Option<ast::Type>, prefix: &str) -> Option<String> |
91 | where | 102 | where |
92 | T: NameOwner + VisibilityOwner, | 103 | T: NameOwner + VisibilityOwner, |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 2737c900f..c0786eb51 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -70,7 +70,7 @@ impl HoverConfig { | |||
70 | #[derive(Debug, Clone)] | 70 | #[derive(Debug, Clone)] |
71 | pub enum HoverAction { | 71 | pub enum HoverAction { |
72 | Runnable(Runnable), | 72 | Runnable(Runnable), |
73 | Implementaion(FilePosition), | 73 | Implementation(FilePosition), |
74 | GoToType(Vec<HoverGotoTypeData>), | 74 | GoToType(Vec<HoverGotoTypeData>), |
75 | } | 75 | } |
76 | 76 | ||
@@ -116,12 +116,13 @@ pub(crate) fn hover( | |||
116 | }; | 116 | }; |
117 | if let Some(definition) = definition { | 117 | if let Some(definition) = definition { |
118 | if let Some(markup) = hover_for_definition(db, definition) { | 118 | if let Some(markup) = hover_for_definition(db, definition) { |
119 | let markup = markup.as_str(); | ||
119 | let markup = if !markdown { | 120 | let markup = if !markdown { |
120 | remove_markdown(&markup.as_str()) | 121 | remove_markdown(markup) |
121 | } else if links_in_hover { | 122 | } else if links_in_hover { |
122 | rewrite_links(db, &markup.as_str(), &definition) | 123 | rewrite_links(db, markup, &definition) |
123 | } else { | 124 | } else { |
124 | remove_links(&markup.as_str()) | 125 | remove_links(markup) |
125 | }; | 126 | }; |
126 | res.markup = Markup::from(markup); | 127 | res.markup = Markup::from(markup); |
127 | if let Some(action) = show_implementations_action(db, definition) { | 128 | if let Some(action) = show_implementations_action(db, definition) { |
@@ -175,7 +176,7 @@ pub(crate) fn hover( | |||
175 | 176 | ||
176 | fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | 177 | fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { |
177 | fn to_action(nav_target: NavigationTarget) -> HoverAction { | 178 | fn to_action(nav_target: NavigationTarget) -> HoverAction { |
178 | HoverAction::Implementaion(FilePosition { | 179 | HoverAction::Implementation(FilePosition { |
179 | file_id: nav_target.file_id, | 180 | file_id: nav_target.file_id, |
180 | offset: nav_target.focus_or_full_range().start(), | 181 | offset: nav_target.focus_or_full_range().start(), |
181 | }) | 182 | }) |
@@ -370,10 +371,8 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
370 | } | 371 | } |
371 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 372 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
372 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | 373 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), |
373 | Definition::TypeParam(_) | Definition::ConstParam(_) => { | 374 | Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), |
374 | // FIXME: Hover for generic param | 375 | Definition::ConstParam(it) => from_def_source(db, it, None), |
375 | None | ||
376 | } | ||
377 | }; | 376 | }; |
378 | 377 | ||
379 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> | 378 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> |
@@ -1393,7 +1392,7 @@ fn bar() { fo<|>o(); } | |||
1393 | r"unsafe trait foo<|>() {}", | 1392 | r"unsafe trait foo<|>() {}", |
1394 | expect![[r#" | 1393 | expect![[r#" |
1395 | [ | 1394 | [ |
1396 | Implementaion( | 1395 | Implementation( |
1397 | FilePosition { | 1396 | FilePosition { |
1398 | file_id: FileId( | 1397 | file_id: FileId( |
1399 | 0, | 1398 | 0, |
@@ -2105,7 +2104,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2105 | r#"trait foo<|>() {}"#, | 2104 | r#"trait foo<|>() {}"#, |
2106 | expect![[r#" | 2105 | expect![[r#" |
2107 | [ | 2106 | [ |
2108 | Implementaion( | 2107 | Implementation( |
2109 | FilePosition { | 2108 | FilePosition { |
2110 | file_id: FileId( | 2109 | file_id: FileId( |
2111 | 0, | 2110 | 0, |
@@ -2124,7 +2123,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2124 | r"struct foo<|>() {}", | 2123 | r"struct foo<|>() {}", |
2125 | expect![[r#" | 2124 | expect![[r#" |
2126 | [ | 2125 | [ |
2127 | Implementaion( | 2126 | Implementation( |
2128 | FilePosition { | 2127 | FilePosition { |
2129 | file_id: FileId( | 2128 | file_id: FileId( |
2130 | 0, | 2129 | 0, |
@@ -2143,7 +2142,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2143 | r#"union foo<|>() {}"#, | 2142 | r#"union foo<|>() {}"#, |
2144 | expect![[r#" | 2143 | expect![[r#" |
2145 | [ | 2144 | [ |
2146 | Implementaion( | 2145 | Implementation( |
2147 | FilePosition { | 2146 | FilePosition { |
2148 | file_id: FileId( | 2147 | file_id: FileId( |
2149 | 0, | 2148 | 0, |
@@ -2162,7 +2161,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2162 | r"enum foo<|>() { A, B }", | 2161 | r"enum foo<|>() { A, B }", |
2163 | expect![[r#" | 2162 | expect![[r#" |
2164 | [ | 2163 | [ |
2165 | Implementaion( | 2164 | Implementation( |
2166 | FilePosition { | 2165 | FilePosition { |
2167 | file_id: FileId( | 2166 | file_id: FileId( |
2168 | 0, | 2167 | 0, |
@@ -3257,4 +3256,68 @@ fn foo() { | |||
3257 | "#]], | 3256 | "#]], |
3258 | ); | 3257 | ); |
3259 | } | 3258 | } |
3259 | |||
3260 | #[test] | ||
3261 | fn hover_type_param() { | ||
3262 | check( | ||
3263 | r#" | ||
3264 | struct Foo<T>(T); | ||
3265 | trait Copy {} | ||
3266 | trait Clone {} | ||
3267 | trait Sized {} | ||
3268 | impl<T: Copy + Clone> Foo<T<|>> where T: Sized {} | ||
3269 | "#, | ||
3270 | expect![[r#" | ||
3271 | *T* | ||
3272 | |||
3273 | ```rust | ||
3274 | T: Copy + Clone + Sized | ||
3275 | ``` | ||
3276 | "#]], | ||
3277 | ); | ||
3278 | check( | ||
3279 | r#" | ||
3280 | struct Foo<T>(T); | ||
3281 | impl<T> Foo<T<|>> {} | ||
3282 | "#, | ||
3283 | expect![[r#" | ||
3284 | *T* | ||
3285 | |||
3286 | ```rust | ||
3287 | T | ||
3288 | ``` | ||
3289 | "#]], | ||
3290 | ); | ||
3291 | // lifetimes aren't being substituted yet | ||
3292 | check( | ||
3293 | r#" | ||
3294 | struct Foo<T>(T); | ||
3295 | impl<T: 'static> Foo<T<|>> {} | ||
3296 | "#, | ||
3297 | expect![[r#" | ||
3298 | *T* | ||
3299 | |||
3300 | ```rust | ||
3301 | T: {error} | ||
3302 | ``` | ||
3303 | "#]], | ||
3304 | ); | ||
3305 | } | ||
3306 | |||
3307 | #[test] | ||
3308 | fn hover_const_param() { | ||
3309 | check( | ||
3310 | r#" | ||
3311 | struct Foo<const LEN: usize>; | ||
3312 | impl<const LEN: usize> Foo<LEN<|>> {} | ||
3313 | "#, | ||
3314 | expect![[r#" | ||
3315 | *LEN* | ||
3316 | |||
3317 | ```rust | ||
3318 | const LEN: usize | ||
3319 | ``` | ||
3320 | "#]], | ||
3321 | ); | ||
3322 | } | ||
3260 | } | 3323 | } |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index dd486070b..c21ca044a 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -1648,7 +1648,7 @@ fn prepare_hover_actions( | |||
1648 | actions | 1648 | actions |
1649 | .iter() | 1649 | .iter() |
1650 | .filter_map(|it| match it { | 1650 | .filter_map(|it| match it { |
1651 | HoverAction::Implementaion(position) => show_impl_command_link(snap, position), | 1651 | HoverAction::Implementation(position) => show_impl_command_link(snap, position), |
1652 | HoverAction::Runnable(r) => runnable_action_links(snap, file_id, r.clone()), | 1652 | HoverAction::Runnable(r) => runnable_action_links(snap, file_id, r.clone()), |
1653 | HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), | 1653 | HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), |
1654 | }) | 1654 | }) |