};
use crate::{
+ utils::useless_type_special_case,
utils::{render_snippet, Cursor},
AssistContext, AssistId, AssistKind, Assists,
};
None => String::from("arg"),
});
arg_types.push(match fn_arg_type(ctx, target_module, &arg) {
- Some(ty) => ty,
+ Some(ty) => {
+ if ty.len() > 0 && ty.starts_with('&') {
+ if let Some((new_ty, _)) = useless_type_special_case("", &ty[1..].to_owned()) {
+ new_ty
+ } else {
+ ty
+ }
+ } else {
+ ty
+ }
+ }
None => String::from("()"),
});
}
use syntax::ast::{self, AstNode, NameOwner, VisibilityOwner};
use crate::{
+ utils::useless_type_special_case,
utils::{find_impl_block_end, find_struct_impl, generate_impl_text},
AssistContext, AssistId, AssistKind, Assists, GroupLabel,
};
let (ty, body) = if mutable {
(format!("&mut {}", field_ty), format!("&mut self.{}", field_name))
} else {
- useless_type_special_case(&field_name.to_string(), &field_ty)
+ useless_type_special_case(&field_name.to_string(), &field_ty.to_string())
.unwrap_or_else(|| (format!("&{}", field_ty), format!("&self.{}", field_name)))
};
)
}
-fn useless_type_special_case(field_name: &str, field_ty: &ast::Type) -> Option<(String, String)> {
- if field_ty.to_string() == "String" {
- cov_mark::hit!(useless_type_special_case);
- return Some(("&str".to_string(), format!("self.{}.as_str()", field_name)));
- }
- if let Some(arg) = ty_ctor(field_ty, "Vec") {
- return Some((format!("&[{}]", arg), format!("self.{}.as_slice()", field_name)));
- }
- if let Some(arg) = ty_ctor(field_ty, "Box") {
- return Some((format!("&{}", arg), format!("self.{}.as_ref()", field_name)));
- }
- if let Some(arg) = ty_ctor(field_ty, "Option") {
- return Some((format!("Option<&{}>", arg), format!("self.{}.as_ref()", field_name)));
- }
- None
-}
-
-// FIXME: This should rely on semantic info.
-fn ty_ctor(ty: &ast::Type, ctor: &str) -> Option<String> {
- let res = ty.to_string().strip_prefix(ctor)?.strip_prefix('<')?.strip_suffix('>')?.to_string();
- Some(res)
-}
-
#[cfg(test)]
mod tests {
use crate::tests::{check_assist, check_assist_not_applicable};
builder.insert(start_offset, buf);
}
+
+pub fn useless_type_special_case(field_name: &str, field_ty: &String) -> Option<(String, String)> {
+ if field_ty.to_string() == "String" {
+ cov_mark::hit!(useless_type_special_case);
+ return Some(("&str".to_string(), format!("self.{}.as_str()", field_name)));
+ }
+ if let Some(arg) = ty_ctor(field_ty, "Vec") {
+ return Some((format!("&[{}]", arg), format!("self.{}.as_slice()", field_name)));
+ }
+ if let Some(arg) = ty_ctor(field_ty, "Box") {
+ return Some((format!("&{}", arg), format!("self.{}.as_ref()", field_name)));
+ }
+ if let Some(arg) = ty_ctor(field_ty, "Option") {
+ return Some((format!("Option<&{}>", arg), format!("self.{}.as_ref()", field_name)));
+ }
+ None
+}
+
+// FIXME: This should rely on semantic info.
+fn ty_ctor(ty: &String, ctor: &str) -> Option<String> {
+ let res = ty.to_string().strip_prefix(ctor)?.strip_prefix('<')?.strip_suffix('>')?.to_string();
+ Some(res)
+}