From 8ba9c2d4cedbcf8f1d2c644733d2b06fa1984d22 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 15 Jan 2019 20:54:18 +0300 Subject: remove Cancelable from type inference --- crates/ra_hir/src/code_model_api.rs | 2 +- crates/ra_hir/src/db.rs | 6 +- crates/ra_hir/src/lib.rs | 9 -- crates/ra_hir/src/ty.rs | 128 ++++++++++------------- crates/ra_hir/src/ty/method_resolution.rs | 37 +++---- crates/ra_hir/src/ty/tests.rs | 6 +- crates/ra_ide_api/src/completion/complete_dot.rs | 15 +-- crates/ra_ide_api/src/goto_definition.rs | 2 +- crates/ra_ide_api/src/hover.rs | 2 +- 9 files changed, 88 insertions(+), 119 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index d0c455d0a..0cf45944f 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs @@ -318,7 +318,7 @@ impl Function { db.fn_signature(self.def_id) } - pub fn infer(&self, db: &impl HirDatabase) -> Cancelable> { + pub fn infer(&self, db: &impl HirDatabase) -> Arc { db.infer(self.def_id) } } diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 4a2b0b3dc..0a0994f5f 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; -use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase, Cancelable}; +use ra_db::{SourceRootId, LocationIntener, SyntaxDatabase}; use crate::{ DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, @@ -52,7 +52,7 @@ pub trait HirDatabase: SyntaxDatabase use fn crate::adt::EnumVariantData::enum_variant_data_query; } - fn infer(def_id: DefId) -> Cancelable> { + fn infer(def_id: DefId) -> Arc { type InferQuery; use fn crate::ty::infer; } @@ -102,7 +102,7 @@ pub trait HirDatabase: SyntaxDatabase use fn crate::impl_block::impls_in_module; } - fn impls_in_crate(krate: Crate) -> Cancelable> { + fn impls_in_crate(krate: Crate) -> Arc { type ImplsInCrateQuery; use fn crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query; } diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 45dda4f7f..ef7d049ee 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -5,15 +5,6 @@ //! to a particular crate instance. That is, it has cfg flags and features //! applied. So, the relation between syntax and HIR is many-to-one. -macro_rules! ctry { - ($expr:expr) => { - match $expr { - None => return Ok(None), - Some(it) => it, - } - }; -} - pub mod db; #[cfg(test)] mod mock; diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 37fc8643a..dbbbce795 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -30,8 +30,6 @@ use ra_arena::map::ArenaMap; use join_to_string::join; use rustc_hash::FxHashMap; -use ra_db::Cancelable; - use crate::{ Def, DefId, Module, Function, Struct, Enum, EnumVariant, Path, Name, ImplBlock, FnSignature, FnScopes, @@ -41,14 +39,6 @@ use crate::{ expr::{Body, Expr, Literal, ExprId, PatId, UnaryOp, BinaryOp, Statement}, }; -fn transpose(x: Cancelable>) -> Option> { - match x { - Ok(Some(t)) => Some(Ok(t)), - Ok(None) => None, - Err(e) => Some(Err(e)), - } -} - /// The ID of a type variable. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct TypeVarId(u32); @@ -836,36 +826,36 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { }) } - fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Cancelable> { + fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option { if path.is_ident() || path.is_self() { // resolve locally let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { - let ty = ctry!(self.type_of_pat.get(scope_entry.pat())); + let ty = self.type_of_pat.get(scope_entry.pat())?; let ty = self.resolve_ty_as_possible(ty.clone()); - return Ok(Some(ty)); + return Some(ty); }; }; // resolve in module - let resolved = ctry!(self.module.resolve_path(self.db, &path).take_values()); + let resolved = self.module.resolve_path(self.db, &path).take_values()?; let ty = self.db.type_for_def(resolved); let ty = self.insert_type_vars(ty); - Ok(Some(ty)) + Some(ty) } - fn resolve_variant(&self, path: Option<&Path>) -> Cancelable<(Ty, Option)> { + fn resolve_variant(&self, path: Option<&Path>) -> (Ty, Option) { let path = if let Some(path) = path { path } else { - return Ok((Ty::Unknown, None)); + return (Ty::Unknown, None); }; let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path).take_types() { def_id } else { - return Ok((Ty::Unknown, None)); + return (Ty::Unknown, None); }; - Ok(match def_id.resolve(self.db) { + match def_id.resolve(self.db) { Def::Struct(s) => { let ty = type_for_struct(self.db, s); (ty, Some(def_id)) @@ -875,10 +865,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { (ty, Some(def_id)) } _ => (Ty::Unknown, None), - }) + } } - fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Cancelable { + fn infer_expr(&mut self, expr: ExprId, expected: &Expectation) -> Ty { let body = Arc::clone(&self.body); // avoid borrow checker problem let ty = match &body[expr] { Expr::Missing => Ty::Unknown, @@ -888,11 +878,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { else_branch, } => { // if let is desugared to match, so this is always simple if - self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; - let then_ty = self.infer_expr(*then_branch, expected)?; + self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); + let then_ty = self.infer_expr(*then_branch, expected); match else_branch { Some(else_branch) => { - self.infer_expr(*else_branch, expected)?; + self.infer_expr(*else_branch, expected); } None => { // no else branch -> unit @@ -901,31 +891,31 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { }; then_ty } - Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected)?, + Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), Expr::Loop { body } => { - self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; + self.infer_expr(*body, &Expectation::has_type(Ty::unit())); // TODO handle break with value Ty::Never } Expr::While { condition, body } => { // while let is desugared to a match loop, so this is always simple while - self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; - self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; + self.infer_expr(*condition, &Expectation::has_type(Ty::Bool)); + self.infer_expr(*body, &Expectation::has_type(Ty::unit())); Ty::unit() } Expr::For { iterable, body, .. } => { let _iterable_ty = self.infer_expr(*iterable, &Expectation::none()); // TODO write type for pat - self.infer_expr(*body, &Expectation::has_type(Ty::unit()))?; + self.infer_expr(*body, &Expectation::has_type(Ty::unit())); Ty::unit() } Expr::Lambda { body, .. } => { // TODO write types for args, infer lambda type etc. - let _body_ty = self.infer_expr(*body, &Expectation::none())?; + let _body_ty = self.infer_expr(*body, &Expectation::none()); Ty::Unknown } Expr::Call { callee, args } => { - let callee_ty = self.infer_expr(*callee, &Expectation::none())?; + let callee_ty = self.infer_expr(*callee, &Expectation::none()); let (param_tys, ret_ty) = match &callee_ty { Ty::FnPtr(sig) => (&sig.input[..], sig.output.clone()), _ => { @@ -938,7 +928,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.infer_expr( *arg, &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), - )?; + ); } ret_ty } @@ -947,8 +937,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { args, method_name, } => { - let receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; - let resolved = receiver_ty.clone().lookup_method(self.db, method_name)?; + let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); + let resolved = receiver_ty.clone().lookup_method(self.db, method_name); let method_ty = match resolved { Some(def_id) => { self.write_method_resolution(expr, def_id); @@ -974,32 +964,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.infer_expr( *arg, &Expectation::has_type(param_tys.get(i).cloned().unwrap_or(Ty::Unknown)), - )?; + ); } ret_ty } Expr::Match { expr, arms } => { - let _ty = self.infer_expr(*expr, &Expectation::none())?; + let _ty = self.infer_expr(*expr, &Expectation::none()); for arm in arms { // TODO type the bindings in pats // TODO type the guard - let _ty = self.infer_expr(arm.expr, &Expectation::none())?; + let _ty = self.infer_expr(arm.expr, &Expectation::none()); } // TODO unify all the match arm types Ty::Unknown } - Expr::Path(p) => self.infer_path_expr(expr, p)?.unwrap_or(Ty::Unknown), + Expr::Path(p) => self.infer_path_expr(expr, p).unwrap_or(Ty::Unknown), Expr::Continue => Ty::Never, Expr::Break { expr } => { if let Some(expr) = expr { // TODO handle break with value - self.infer_expr(*expr, &Expectation::none())?; + self.infer_expr(*expr, &Expectation::none()); } Ty::Never } Expr::Return { expr } => { if let Some(expr) = expr { - self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone()))?; + self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); } Ty::Never } @@ -1008,7 +998,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { fields, spread, } => { - let (ty, def_id) = self.resolve_variant(path.as_ref())?; + let (ty, def_id) = self.resolve_variant(path.as_ref()); for field in fields { let field_ty = if let Some(def_id) = def_id { self.db @@ -1017,37 +1007,35 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } else { Ty::Unknown }; - self.infer_expr(field.expr, &Expectation::has_type(field_ty))?; + self.infer_expr(field.expr, &Expectation::has_type(field_ty)); } if let Some(expr) = spread { - self.infer_expr(*expr, &Expectation::has_type(ty.clone()))?; + self.infer_expr(*expr, &Expectation::has_type(ty.clone())); } ty } Expr::Field { expr, name } => { - let receiver_ty = self.infer_expr(*expr, &Expectation::none())?; + let receiver_ty = self.infer_expr(*expr, &Expectation::none()); let ty = receiver_ty .autoderef(self.db) .find_map(|derefed_ty| match derefed_ty { // this is more complicated than necessary because type_for_field is cancelable Ty::Tuple(fields) => { let i = name.to_string().parse::().ok(); - i.and_then(|i| fields.get(i).cloned()).map(Ok) - } - Ty::Adt { def_id, .. } => { - transpose(Ok(self.db.type_for_field(def_id, name.clone()))) + i.and_then(|i| fields.get(i).cloned()) } + Ty::Adt { def_id, .. } => self.db.type_for_field(def_id, name.clone()), _ => None, }) - .unwrap_or(Ok(Ty::Unknown))?; + .unwrap_or(Ty::Unknown); self.insert_type_vars(ty) } Expr::Try { expr } => { - let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; + let _inner_ty = self.infer_expr(*expr, &Expectation::none()); Ty::Unknown } Expr::Cast { expr, type_ref } => { - let _inner_ty = self.infer_expr(*expr, &Expectation::none())?; + let _inner_ty = self.infer_expr(*expr, &Expectation::none()); let cast_ty = Ty::from_hir(self.db, &self.module, self.impl_block.as_ref(), type_ref); let cast_ty = self.insert_type_vars(cast_ty); @@ -1056,12 +1044,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } Expr::Ref { expr, mutability } => { // TODO pass the expectation down - let inner_ty = self.infer_expr(*expr, &Expectation::none())?; + let inner_ty = self.infer_expr(*expr, &Expectation::none()); // TODO reference coercions etc. Ty::Ref(Arc::new(inner_ty), *mutability) } Expr::UnaryOp { expr, op } => { - let inner_ty = self.infer_expr(*expr, &Expectation::none())?; + let inner_ty = self.infer_expr(*expr, &Expectation::none()); match op { Some(UnaryOp::Deref) => { if let Some(derefed_ty) = inner_ty.builtin_deref() { @@ -1082,11 +1070,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } _ => Expectation::none(), }; - let lhs_ty = self.infer_expr(*lhs, &lhs_expectation)?; + let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); // TODO: find implementation of trait corresponding to operation // symbol and resolve associated `Output` type let rhs_expectation = binary_op_rhs_expectation(*op, lhs_ty); - let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation))?; + let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); // TODO: similar as above, return ty is often associated trait type binary_op_return_ty(*op, rhs_ty) @@ -1096,7 +1084,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Expr::Tuple { exprs } => { let mut ty_vec = Vec::with_capacity(exprs.len()); for arg in exprs.iter() { - ty_vec.push(self.infer_expr(*arg, &Expectation::none())?); + ty_vec.push(self.infer_expr(*arg, &Expectation::none())); } Ty::Tuple(Arc::from(ty_vec)) @@ -1121,7 +1109,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.unify(&ty, &expected.ty); let ty = self.resolve_ty_as_possible(ty); self.write_expr_ty(expr, ty.clone()); - Ok(ty) + ty } fn infer_block( @@ -1129,7 +1117,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { statements: &[Statement], tail: Option, expected: &Expectation, - ) -> Cancelable { + ) -> Ty { for stmt in statements { match stmt { Statement::Let { @@ -1145,7 +1133,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ); let decl_ty = self.insert_type_vars(decl_ty); let ty = if let Some(expr) = initializer { - let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty))?; + let expr_ty = self.infer_expr(*expr, &Expectation::has_type(decl_ty)); expr_ty } else { decl_ty @@ -1154,19 +1142,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.write_pat_ty(*pat, ty); } Statement::Expr(expr) => { - self.infer_expr(*expr, &Expectation::none())?; + self.infer_expr(*expr, &Expectation::none()); } } } let ty = if let Some(expr) = tail { - self.infer_expr(expr, expected)? + self.infer_expr(expr, expected) } else { Ty::unit() }; - Ok(ty) + ty } - fn collect_fn_signature(&mut self, signature: &FnSignature) -> Cancelable<()> { + fn collect_fn_signature(&mut self, signature: &FnSignature) { let body = Arc::clone(&self.body); // avoid borrow checker problem for (type_ref, pat) in signature.params().iter().zip(body.params()) { let ty = self.make_ty(type_ref); @@ -1178,19 +1166,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let ty = self.insert_type_vars(ty); ty }; - Ok(()) } - fn infer_body(&mut self) -> Cancelable<()> { + fn infer_body(&mut self) { self.infer_expr( self.body.body_expr(), &Expectation::has_type(self.return_ty.clone()), - )?; - Ok(()) + ); } } -pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable> { +pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc { db.check_canceled(); let function = Function::new(def_id); // TODO: consts also need inference let body = function.body(db); @@ -1200,9 +1186,9 @@ pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable impl Iterator> + 'a { + ) -> impl Iterator + 'a { let fingerprint = TyFingerprint::for_impl(ty); fingerprint .and_then(|f| self.impls.get(&f)) @@ -50,11 +50,11 @@ impl CrateImplBlocks { .flat_map(|i| i.iter()) .map(move |(module_id, impl_id)| { let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id); - Ok(ImplBlock::from_id(module_impl_blocks, *impl_id)) + ImplBlock::from_id(module_impl_blocks, *impl_id) }) } - fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { + fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { let module_id = module.def_id.loc(db).module_id; let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id); @@ -76,16 +76,14 @@ impl CrateImplBlocks { } for child in module.children(db) { - self.collect_recursive(db, child)?; + self.collect_recursive(db, child); } - - Ok(()) } pub(crate) fn impls_in_crate_query( db: &impl HirDatabase, krate: Crate, - ) -> Cancelable> { + ) -> Arc { let crate_graph = db.crate_graph(); let file_id = crate_graph.crate_root(krate.crate_id); let source_root_id = db.file_source_root(file_id); @@ -94,9 +92,9 @@ impl CrateImplBlocks { impls: FxHashMap::default(), }; if let Some(module) = krate.root_module(db) { - crate_impl_blocks.collect_recursive(db, module)?; + crate_impl_blocks.collect_recursive(db, module); } - Ok(Arc::new(crate_impl_blocks)) + Arc::new(crate_impl_blocks) } } @@ -111,13 +109,13 @@ impl Ty { // TODO: cache this as a query? // - if so, what signature? (TyFingerprint, Name)? // - or maybe cache all names and def_ids of methods per fingerprint? - pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Cancelable> { + pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option { self.iterate_methods(db, |f| { let sig = f.signature(db); if sig.name() == name && sig.has_self_param() { - Ok(Some(f.def_id())) + Some(f.def_id()) } else { - Ok(None) + None } }) } @@ -127,8 +125,8 @@ impl Ty { pub fn iterate_methods( self, db: &impl HirDatabase, - mut callback: impl FnMut(Function) -> Cancelable>, - ) -> Cancelable> { + mut callback: impl FnMut(Function) -> Option, + ) -> Option { // For method calls, rust first does any number of autoderef, and then one // autoref (i.e. when the method takes &self or &mut self). We just ignore // the autoref currently -- when we find a method matching the given name, @@ -143,15 +141,14 @@ impl Ty { Some(krate) => krate, None => continue, }; - let impls = db.impls_in_crate(krate)?; + let impls = db.impls_in_crate(krate); for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) { - let impl_block = impl_block?; for item in impl_block.items() { match item { ImplItem::Method(f) => { - if let Some(result) = callback(f.clone())? { - return Ok(Some(result)); + if let Some(result) = callback(f.clone()) { + return Some(result); } } _ => {} @@ -159,6 +156,6 @@ impl Ty { } } } - Ok(None) + None } } diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index b44ac9987..929fee04c 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -321,7 +321,7 @@ fn infer(content: &str) -> String { .filter_map(ast::FnDef::cast) { let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap(); - let inference_result = func.infer(&db).unwrap(); + let inference_result = func.infer(&db); let body_syntax_mapping = func.body_syntax_mapping(&db); let mut types = Vec::new(); for (pat, ty) in inference_result.type_of_pat.iter() { @@ -405,7 +405,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { let func = source_binder::function_from_position(&db, pos).unwrap(); { let events = db.log_executed(|| { - func.infer(&db).unwrap(); + func.infer(&db); }); assert!(format!("{:?}", events).contains("infer")) } @@ -424,7 +424,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { { let events = db.log_executed(|| { - func.infer(&db).unwrap(); + func.infer(&db); }); assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) } diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 30a0a3924..31a2478d1 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs @@ -9,7 +9,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca (Some(function), Some(receiver)) => (function, receiver), _ => return Ok(()), }; - let infer_result = function.infer(ctx.db)?; + let infer_result = function.infer(ctx.db); let syntax_mapping = function.body_syntax_mapping(ctx.db); let expr = match syntax_mapping.node_expr(receiver) { Some(expr) => expr, @@ -19,7 +19,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca if !ctx.is_call { complete_fields(acc, ctx, receiver_ty.clone()); } - complete_methods(acc, ctx, receiver_ty)?; + complete_methods(acc, ctx, receiver_ty); Ok(()) } @@ -55,11 +55,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) } } -fn complete_methods( - acc: &mut Completions, - ctx: &CompletionContext, - receiver: Ty, -) -> Cancelable<()> { +fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { receiver.iterate_methods(ctx.db, |func| { let sig = func.signature(ctx.db); if sig.has_self_param() { @@ -68,9 +64,8 @@ fn complete_methods( .kind(CompletionItemKind::Method) .add_to(acc); } - Ok(None::<()>) - })?; - Ok(()) + None::<()> + }); } #[cfg(test)] diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index cdd8e211d..e0f3deb0b 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -63,7 +63,7 @@ pub(crate) fn reference_definition( .parent() .and_then(ast::MethodCallExpr::cast) { - let infer_result = function.infer(db)?; + let infer_result = function.infer(db); let syntax_mapping = function.body_syntax_mapping(db); let expr = ast::Expr::cast(method_call.syntax()).unwrap(); if let Some(def_id) = syntax_mapping diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 0e9c48421..6b5887bda 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -73,7 +73,7 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Cancelable