10146: fix: use placeholder as default type in `Generate function` and `Extract into function`. r=matklad a=iDawer

Closes #10123 

Co-authored-by: Dawer <7803845+iDawer@users.noreply.github.com>
This commit is contained in:
bors[bot] 2021-09-04 14:04:30 +00:00 committed by GitHub
commit fd30bd179c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 33 deletions

View file

@ -1319,7 +1319,7 @@ impl Function {
.type_arguments() .type_arguments()
.nth(1) .nth(1)
.map(|ty| make_ty(&ty, ctx, module)) .map(|ty| make_ty(&ty, ctx, module))
.unwrap_or_else(make::ty_unit); .unwrap_or_else(make::ty_placeholder);
make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty) make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty)
} }
FlowHandler::If { .. } => make::ext::ty_bool(), FlowHandler::If { .. } => make::ext::ty_bool(),
@ -1327,7 +1327,7 @@ impl Function {
let handler_ty = action let handler_ty = action
.expr_ty(ctx) .expr_ty(ctx)
.map(|ty| make_ty(&ty, ctx, module)) .map(|ty| make_ty(&ty, ctx, module))
.unwrap_or_else(make::ty_unit); .unwrap_or_else(make::ty_placeholder);
make::ext::ty_option(handler_ty) make::ext::ty_option(handler_ty)
} }
FlowHandler::MatchOption { .. } => make::ext::ty_option(fun_ty.make_ty(ctx, module)), FlowHandler::MatchOption { .. } => make::ext::ty_option(fun_ty.make_ty(ctx, module)),
@ -1335,7 +1335,7 @@ impl Function {
let handler_ty = err let handler_ty = err
.expr_ty(ctx) .expr_ty(ctx)
.map(|ty| make_ty(&ty, ctx, module)) .map(|ty| make_ty(&ty, ctx, module))
.unwrap_or_else(make::ty_unit); .unwrap_or_else(make::ty_placeholder);
make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty) make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty)
} }
}; };
@ -1501,7 +1501,7 @@ fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr
} }
fn format_type(ty: &hir::Type, ctx: &AssistContext, module: hir::Module) -> String { fn format_type(ty: &hir::Type, ctx: &AssistContext, module: hir::Module) -> String {
ty.display_source_code(ctx.db(), module.into()).ok().unwrap_or_else(|| "()".to_string()) ty.display_source_code(ctx.db(), module.into()).ok().unwrap_or_else(|| "_".to_string())
} }
fn make_ty(ty: &hir::Type, ctx: &AssistContext, module: hir::Module) -> ast::Type { fn make_ty(ty: &hir::Type, ctx: &AssistContext, module: hir::Module) -> ast::Type {
@ -4191,6 +4191,29 @@ fn main() {
fn $0fun_name(bar: &str) { fn $0fun_name(bar: &str) {
m!(bar); m!(bar);
} }
"#,
);
}
#[test]
fn unresolveable_types_default_to_placeholder() {
check_assist(
extract_function,
r#"
fn foo() {
let a = __unresolved;
let _ = $0{a}$0;
}
"#,
r#"
fn foo() {
let a = __unresolved;
let _ = fun_name(a);
}
fn $0fun_name(a: _) -> _ {
a
}
"#, "#,
); );
} }

View file

@ -37,7 +37,7 @@ use crate::{
// bar("", baz()); // bar("", baz());
// } // }
// //
// fn bar(arg: &str, baz: Baz) ${0:-> ()} { // fn bar(arg: &str, baz: Baz) ${0:-> _} {
// todo!() // todo!()
// } // }
// //
@ -342,7 +342,7 @@ impl FunctionBuilder {
} }
/// Makes an optional return type along with whether the return type should be focused by the cursor. /// Makes an optional return type along with whether the return type should be focused by the cursor.
/// If we cannot infer what the return type should be, we create unit as a placeholder. /// If we cannot infer what the return type should be, we create a placeholder type.
/// ///
/// The rule for whether we focus a return type or not (and thus focus the function body), /// The rule for whether we focus a return type or not (and thus focus the function body),
/// is rather simple: /// is rather simple:
@ -357,14 +357,14 @@ fn make_return_type(
) -> (Option<ast::RetType>, bool) { ) -> (Option<ast::RetType>, bool) {
let (ret_ty, should_focus_return_type) = { let (ret_ty, should_focus_return_type) = {
match ctx.sema.type_of_expr(call).map(TypeInfo::original) { match ctx.sema.type_of_expr(call).map(TypeInfo::original) {
Some(ty) if ty.is_unknown() => (Some(make::ty_unit()), true), Some(ty) if ty.is_unknown() => (Some(make::ty_placeholder()), true),
None => (Some(make::ty_unit()), true), None => (Some(make::ty_placeholder()), true),
Some(ty) if ty.is_unit() => (None, false), Some(ty) if ty.is_unit() => (None, false),
Some(ty) => { Some(ty) => {
let rendered = ty.display_source_code(ctx.db(), target_module.into()); let rendered = ty.display_source_code(ctx.db(), target_module.into());
match rendered { match rendered {
Ok(rendered) => (Some(make::ty(&rendered)), false), Ok(rendered) => (Some(make::ty(&rendered)), false),
Err(_) => (Some(make::ty_unit()), true), Err(_) => (Some(make::ty_placeholder()), true),
} }
} }
} }
@ -458,7 +458,7 @@ fn fn_args(
ty ty
} }
} }
None => String::from("()"), None => String::from("_"),
}); });
} }
deduplicate_arg_names(&mut arg_names); deduplicate_arg_names(&mut arg_names);
@ -639,7 +639,7 @@ fn foo() {
bar(); bar();
} }
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
", ",
@ -666,7 +666,7 @@ impl Foo {
} }
} }
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
", ",
@ -690,7 +690,7 @@ fn foo1() {
bar(); bar();
} }
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
@ -716,7 +716,7 @@ mod baz {
bar(); bar();
} }
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
} }
@ -740,7 +740,7 @@ fn foo() {
bar(BazBaz); bar(BazBaz);
} }
fn bar(baz_baz: BazBaz) ${0:-> ()} { fn bar(baz_baz: BazBaz) ${0:-> _} {
todo!() todo!()
} }
", ",
@ -763,7 +763,7 @@ fn foo() {
bar(&BazBaz as *const BazBaz); bar(&BazBaz as *const BazBaz);
} }
fn bar(baz_baz: *const BazBaz) ${0:-> ()} { fn bar(baz_baz: *const BazBaz) ${0:-> _} {
todo!() todo!()
} }
", ",
@ -788,7 +788,7 @@ fn foo() {
bar(baz()); bar(baz());
} }
fn bar(baz: Baz) ${0:-> ()} { fn bar(baz: Baz) ${0:-> _} {
todo!() todo!()
} }
", ",
@ -1091,7 +1091,7 @@ fn foo() {
bar(Baz::new); bar(Baz::new);
} }
fn bar(new: fn) ${0:-> ()} { fn bar(new: fn) ${0:-> _} {
todo!() todo!()
} }
", ",
@ -1115,7 +1115,7 @@ fn foo() {
bar(closure) bar(closure)
} }
fn bar(closure: ()) { fn bar(closure: _) {
${0:todo!()} ${0:todo!()}
} }
", ",
@ -1123,7 +1123,7 @@ fn bar(closure: ()) {
} }
#[test] #[test]
fn unresolveable_types_default_to_unit() { fn unresolveable_types_default_to_placeholder() {
check_assist( check_assist(
generate_function, generate_function,
r" r"
@ -1136,7 +1136,7 @@ fn foo() {
bar(baz) bar(baz)
} }
fn bar(baz: ()) { fn bar(baz: _) {
${0:todo!()} ${0:todo!()}
} }
", ",
@ -1400,7 +1400,7 @@ impl Foo {
self.bar(); self.bar();
} }
fn bar(&self) ${0:-> ()} { fn bar(&self) ${0:-> _} {
todo!() todo!()
} }
} }
@ -1422,7 +1422,7 @@ fn foo() {
bar(42).await(); bar(42).await();
} }
async fn bar(arg: i32) ${0:-> ()} { async fn bar(arg: i32) ${0:-> _} {
todo!() todo!()
} }
", ",
@ -1443,7 +1443,7 @@ fn foo() {S.bar();}
impl S { impl S {
fn bar(&self) ${0:-> ()} { fn bar(&self) ${0:-> _} {
todo!() todo!()
} }
} }
@ -1465,7 +1465,7 @@ impl S {}
struct S; struct S;
fn foo() {S.bar();} fn foo() {S.bar();}
impl S { impl S {
fn bar(&self) ${0:-> ()} { fn bar(&self) ${0:-> _} {
todo!() todo!()
} }
} }
@ -1490,7 +1490,7 @@ mod s {
impl S { impl S {
pub(crate) fn bar(&self) ${0:-> ()} { pub(crate) fn bar(&self) ${0:-> _} {
todo!() todo!()
} }
} }
@ -1523,7 +1523,7 @@ mod s {
impl S { impl S {
fn bar(&self) ${0:-> ()} { fn bar(&self) ${0:-> _} {
todo!() todo!()
} }
} }
@ -1546,7 +1546,7 @@ fn foo() {S.bar();}
impl S { impl S {
fn bar(&self) ${0:-> ()} { fn bar(&self) ${0:-> _} {
todo!() todo!()
} }
} }
@ -1568,7 +1568,7 @@ fn foo() {S::bar();}
impl S { impl S {
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
} }
@ -1590,7 +1590,7 @@ impl S {}
struct S; struct S;
fn foo() {S::bar();} fn foo() {S::bar();}
impl S { impl S {
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
} }
@ -1615,7 +1615,7 @@ mod s {
impl S { impl S {
pub(crate) fn bar() ${0:-> ()} { pub(crate) fn bar() ${0:-> _} {
todo!() todo!()
} }
} }
@ -1639,7 +1639,7 @@ fn foo() {S::bar();}
impl S { impl S {
fn bar() ${0:-> ()} { fn bar() ${0:-> _} {
todo!() todo!()
} }
} }

View file

@ -819,7 +819,7 @@ fn foo() {
bar("", baz()); bar("", baz());
} }
fn bar(arg: &str, baz: Baz) ${0:-> ()} { fn bar(arg: &str, baz: Baz) ${0:-> _} {
todo!() todo!()
} }

View file

@ -95,6 +95,9 @@ pub fn lifetime(text: &str) -> ast::Lifetime {
pub fn ty(text: &str) -> ast::Type { pub fn ty(text: &str) -> ast::Type {
ty_from_text(text) ty_from_text(text)
} }
pub fn ty_placeholder() -> ast::Type {
ty_from_text("_")
}
pub fn ty_unit() -> ast::Type { pub fn ty_unit() -> ast::Type {
ty_from_text("()") ty_from_text("()")
} }