aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/handlers/extract_function.rs29
-rw-r--r--crates/hir/src/code_model.rs12
2 files changed, 17 insertions, 24 deletions
diff --git a/crates/assists/src/handlers/extract_function.rs b/crates/assists/src/handlers/extract_function.rs
index 74fa2013c..9f34cc725 100644
--- a/crates/assists/src/handlers/extract_function.rs
+++ b/crates/assists/src/handlers/extract_function.rs
@@ -1131,8 +1131,11 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti
1131 make::ty_generic(make::name_ref("Option"), iter::once(fun_ty.make_ty(ctx, module))) 1131 make::ty_generic(make::name_ref("Option"), iter::once(fun_ty.make_ty(ctx, module)))
1132 } 1132 }
1133 FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => { 1133 FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => {
1134 let handler_ty = 1134 let handler_ty = parent_ret_ty
1135 result_err_ty(parent_ret_ty, ctx, module).unwrap_or_else(make::ty_unit); 1135 .type_parameters()
1136 .nth(1)
1137 .map(|ty| make_ty(&ty, ctx, module))
1138 .unwrap_or_else(make::ty_unit);
1136 make::ty_generic( 1139 make::ty_generic(
1137 make::name_ref("Result"), 1140 make::name_ref("Result"),
1138 vec![fun_ty.make_ty(ctx, module), handler_ty], 1141 vec![fun_ty.make_ty(ctx, module), handler_ty],
@@ -1161,28 +1164,6 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti
1161 Some(make::ret_type(ret_ty)) 1164 Some(make::ret_type(ret_ty))
1162} 1165}
1163 1166
1164/// Extract `E` type from `Result<T, E>`
1165fn result_err_ty(
1166 parent_ret_ty: &hir::Type,
1167 ctx: &AssistContext,
1168 module: hir::Module,
1169) -> Option<ast::Type> {
1170 // FIXME: use hir to extract argument information
1171 // currently we use `format -> take part -> parse`
1172 let path_ty = match make_ty(&parent_ret_ty, ctx, module) {
1173 ast::Type::PathType(path_ty) => path_ty,
1174 _ => return None,
1175 };
1176 let arg_list = path_ty.path()?.segment()?.generic_arg_list()?;
1177 let err_arg = arg_list.generic_args().nth(1)?;
1178 let type_arg = match err_arg {
1179 ast::GenericArg::TypeArg(type_arg) => type_arg,
1180 _ => return None,
1181 };
1182
1183 type_arg.ty()
1184}
1185
1186fn make_body( 1167fn make_body(
1187 ctx: &AssistContext, 1168 ctx: &AssistContext,
1188 old_indent: IndentLevel, 1169 old_indent: IndentLevel,
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index 35b532602..7d43d4097 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -1802,6 +1802,18 @@ impl Type {
1802 None 1802 None
1803 } 1803 }
1804 1804
1805 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1806 let ty = self.ty.value.strip_references();
1807 let substs = match ty {
1808 Ty::Apply(apply_ty) => &apply_ty.parameters,
1809 Ty::Opaque(opaque_ty) => &opaque_ty.parameters,
1810 _ => return Either::Left(iter::empty()),
1811 };
1812
1813 let iter = substs.iter().map(move |ty| self.derived(ty.clone()));
1814 Either::Right(iter)
1815 }
1816
1805 pub fn iterate_method_candidates<T>( 1817 pub fn iterate_method_candidates<T>(
1806 &self, 1818 &self,
1807 db: &dyn HirDatabase, 1819 db: &dyn HirDatabase,