From 6b76d82b1395e42693cf227169ef2bfd32b8418e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 10 Dec 2019 10:30:08 -0800 Subject: [PATCH] Move suggestion code to its own method --- .../infer/error_reporting/need_type_info.rs | 96 +++++++++++-------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index c5133e884322..55a95d056984 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -376,48 +376,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; err.span_label(pattern.span, msg); } else if let Some(e) = local_visitor.found_method_call { - if let ExprKind::MethodCall(segment, _call_sp, _args) = &e.kind { - if let (Ok(snippet), Some(tables), None) = ( - self.tcx.sess.source_map().span_to_snippet(segment.ident.span), - self.in_progress_tables, - &segment.args, - ) { - let borrow = tables.borrow(); - let sigs = borrow.node_method_sig(); - if let Some(sig) = sigs.get(e.hir_id) { - let mut params = vec![]; - for arg in sig.inputs_and_output().skip_binder().iter() { - if let ty::Param(param) = arg.kind { - if param.name != kw::SelfUpper { - let name = param.name.to_string(); - if !params.contains(&name) { - params.push(name); - } - } - } - } - if !params.is_empty() { - err.span_suggestion( - segment.ident.span, - &format!( - "consider specifying the type argument{} in the method call", - if params.len() > 1 { - "s" - } else { - "" - }, - ), - format!("{}::<{}>", snippet, params.join(", ")), - Applicability::HasPlaceholders, - ); - } else { - err.span_label(e.span, &format!( - "this method call resolves to `{:?}`", - sig.output().skip_binder(), - )); - } - } - } + if let ExprKind::MethodCall(segment, ..) = &e.kind { + // Suggest specifiying type params or point out the return type of the call. + self.annotate_method_call(segment, e, &mut err); } } // Instead of the following: @@ -447,6 +408,57 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err } + /// If the `FnSig` for the method call can be found and type arguments are identified as + /// needed, suggest annotating the call, otherwise point out the resulting type of the call. + fn annotate_method_call( + &self, + segment: &hir::ptr::P, + e: &Expr, + err: &mut DiagnosticBuilder<'_>, + ) { + if let (Ok(snippet), Some(tables), None) = ( + self.tcx.sess.source_map().span_to_snippet(segment.ident.span), + self.in_progress_tables, + &segment.args, + ) { + let borrow = tables.borrow(); + let sigs = borrow.node_method_sig(); + if let Some(sig) = sigs.get(e.hir_id) { + let mut params = vec![]; + for arg in sig.inputs_and_output().skip_binder().iter() { + if let ty::Param(param) = arg.kind { + if param.name != kw::SelfUpper { + let name = param.name.to_string(); + if !params.contains(&name) { + params.push(name); + } + } + } + } + if !params.is_empty() { + err.span_suggestion( + segment.ident.span, + &format!( + "consider specifying the type argument{} in the method call", + if params.len() > 1 { + "s" + } else { + "" + }, + ), + format!("{}::<{}>", snippet, params.join(", ")), + Applicability::HasPlaceholders, + ); + } else { + err.span_label(e.span, &format!( + "this method call resolves to `{:?}`", + sig.output().skip_binder(), + )); + } + } + } + } + pub fn need_type_info_err_in_generator( &self, kind: hir::GeneratorKind,