diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs index 102fdb13d7..01cc392db0 100644 --- a/crates/ra_hir_def/src/type_ref.rs +++ b/crates/ra_hir_def/src/type_ref.rs @@ -93,7 +93,11 @@ impl TypeRef { } ast::TypeRef::PlaceholderType(_inner) => TypeRef::Placeholder, ast::TypeRef::FnPointerType(inner) => { - let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref())); + let ret_ty = inner + .ret_type() + .and_then(|rt| rt.type_ref()) + .map(TypeRef::from_ast) + .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); let mut params = if let Some(pl) = inner.param_list() { pl.params().map(|p| p.ascribed_type()).map(TypeRef::from_ast_opt).collect() } else { diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index a600b947d0..141f0245aa 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -1729,3 +1729,29 @@ fn foo() -> u32 { "### ); } + +#[test] +fn fn_pointer_return() { + assert_snapshot!( + infer(r#" +struct Vtable { + method: fn(), +} + +fn main() { + let vtable = Vtable { method: || {} }; + let m = vtable.method; +} +"#), + @r###" + [48; 121) '{ ...hod; }': () + [58; 64) 'vtable': Vtable + [67; 91) 'Vtable...| {} }': Vtable + [84; 89) '|| {}': || -> () + [87; 89) '{}': () + [101; 102) 'm': fn() -> () + [105; 111) 'vtable': Vtable + [105; 118) 'vtable.method': fn() -> () + "### + ); +}