diff options
-rw-r--r-- | crates/assists/src/handlers/extract_function.rs | 29 | ||||
-rw-r--r-- | crates/hir/src/code_model.rs | 12 |
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>` | ||
1165 | fn 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 | |||
1186 | fn make_body( | 1167 | fn 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, |