diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/handlers/generate_impl.rs | 24 | ||||
-rw-r--r-- | crates/assists/src/utils.rs | 32 |
2 files changed, 49 insertions, 7 deletions
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs index 050bcd4e2..16a600e6f 100644 --- a/crates/assists/src/handlers/generate_impl.rs +++ b/crates/assists/src/handlers/generate_impl.rs | |||
@@ -98,6 +98,30 @@ mod tests { | |||
98 | $0 | 98 | $0 |
99 | }"#, | 99 | }"#, |
100 | ); | 100 | ); |
101 | |||
102 | check_assist( | ||
103 | generate_impl, | ||
104 | r#" | ||
105 | struct Defaulted<T = i32> {}$0"#, | ||
106 | r#" | ||
107 | struct Defaulted<T = i32> {} | ||
108 | |||
109 | impl<T> Defaulted<T> { | ||
110 | $0 | ||
111 | }"#, | ||
112 | ); | ||
113 | |||
114 | check_assist( | ||
115 | generate_impl, | ||
116 | r#" | ||
117 | struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String> {}$0"#, | ||
118 | r#" | ||
119 | struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String> {} | ||
120 | |||
121 | impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b> Defaulted<'a, 'b, T> { | ||
122 | $0 | ||
123 | }"#, | ||
124 | ); | ||
101 | } | 125 | } |
102 | 126 | ||
103 | #[test] | 127 | #[test] |
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 98c4462bb..8418e6e12 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | use std::ops; | 3 | use std::ops; |
4 | 4 | ||
5 | use ast::TypeBoundsOwner; | ||
5 | use hir::{Adt, HasSource}; | 6 | use hir::{Adt, HasSource}; |
6 | use ide_db::{helpers::SnippetCap, RootDatabase}; | 7 | use ide_db::{helpers::SnippetCap, RootDatabase}; |
7 | use itertools::Itertools; | 8 | use itertools::Itertools; |
@@ -377,15 +378,30 @@ pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: & | |||
377 | } | 378 | } |
378 | 379 | ||
379 | fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str) -> String { | 380 | fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str) -> String { |
380 | let type_params = adt.generic_param_list(); | 381 | let generic_params = adt.generic_param_list(); |
381 | let mut buf = String::with_capacity(code.len()); | 382 | let mut buf = String::with_capacity(code.len()); |
382 | buf.push_str("\n\n"); | 383 | buf.push_str("\n\n"); |
383 | adt.attrs() | 384 | adt.attrs() |
384 | .filter(|attr| attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false)) | 385 | .filter(|attr| attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false)) |
385 | .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); | 386 | .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); |
386 | buf.push_str("impl"); | 387 | buf.push_str("impl"); |
387 | if let Some(type_params) = &type_params { | 388 | if let Some(generic_params) = &generic_params { |
388 | format_to!(buf, "{}", type_params.syntax()); | 389 | let lifetimes = generic_params.lifetime_params().map(|lt| format!("{}", lt.syntax())); |
390 | let type_params = generic_params.type_params().map(|type_param| { | ||
391 | let mut buf = String::new(); | ||
392 | if let Some(it) = type_param.name() { | ||
393 | format_to!(buf, "{}", it.syntax()); | ||
394 | } | ||
395 | if let Some(it) = type_param.colon_token() { | ||
396 | format_to!(buf, "{} ", it); | ||
397 | } | ||
398 | if let Some(it) = type_param.type_bound_list() { | ||
399 | format_to!(buf, "{}", it.syntax()); | ||
400 | } | ||
401 | buf | ||
402 | }); | ||
403 | let generics = lifetimes.chain(type_params).format(", "); | ||
404 | format_to!(buf, "<{}>", generics); | ||
389 | } | 405 | } |
390 | buf.push(' '); | 406 | buf.push(' '); |
391 | if let Some(trait_text) = trait_text { | 407 | if let Some(trait_text) = trait_text { |
@@ -393,13 +409,15 @@ fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str | |||
393 | buf.push_str(" for "); | 409 | buf.push_str(" for "); |
394 | } | 410 | } |
395 | buf.push_str(adt.name().unwrap().text()); | 411 | buf.push_str(adt.name().unwrap().text()); |
396 | if let Some(type_params) = type_params { | 412 | if let Some(generic_params) = generic_params { |
397 | let lifetime_params = type_params | 413 | let lifetime_params = generic_params |
398 | .lifetime_params() | 414 | .lifetime_params() |
399 | .filter_map(|it| it.lifetime()) | 415 | .filter_map(|it| it.lifetime()) |
400 | .map(|it| SmolStr::from(it.text())); | 416 | .map(|it| SmolStr::from(it.text())); |
401 | let type_params = | 417 | let type_params = generic_params |
402 | type_params.type_params().filter_map(|it| it.name()).map(|it| SmolStr::from(it.text())); | 418 | .type_params() |
419 | .filter_map(|it| it.name()) | ||
420 | .map(|it| SmolStr::from(it.text())); | ||
403 | format_to!(buf, "<{}>", lifetime_params.chain(type_params).format(", ")) | 421 | format_to!(buf, "<{}>", lifetime_params.chain(type_params).format(", ")) |
404 | } | 422 | } |
405 | 423 | ||