diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index a1cbcac1a9a76..904a4125f2f72 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -260,41 +260,9 @@ impl<'a> LateResolutionVisitor<'a, '_> { return (err, candidates); } - // Check if the first argument is `self` and suggest calling a method. - let mut has_self_arg = None; - if let PathSource::Expr(parent) = source { - match &parent.map(|p| &p.kind) { - Some(ExprKind::Call(_, args)) if args.len() > 0 => { - let mut expr_kind = &args[0].kind; - loop { - match expr_kind { - ExprKind::Path(_, arg_name) if arg_name.segments.len() == 1 => { - if arg_name.segments[0].ident.name == kw::SelfLower { - let call_span = parent.unwrap().span; - let args_span = if args.len() > 1 { - Some(Span::new( - args[1].span.lo(), - args.last().unwrap().span.hi(), - call_span.ctxt(), - )) - } else { - None - }; - has_self_arg = Some((call_span, args_span)); - } - break; - }, - ExprKind::AddrOf(_, _, expr) => expr_kind = &expr.kind, - _ => break, - } - } - } - _ => (), - } - }; - - if let Some((call_span, args_span)) = has_self_arg { - let mut args_snippet: String = String::from(""); + // If the first argument in call is `self` suggest calling a method. + if let Some((call_span, args_span)) = self.call_has_self_arg(source) { + let mut args_snippet = String::new(); if let Some(args_span) = args_span { if let Ok(snippet) = self.r.session.source_map().span_to_snippet(args_span) { args_snippet = snippet; @@ -348,6 +316,43 @@ impl<'a> LateResolutionVisitor<'a, '_> { (err, candidates) } + /// Check if the source is call expression and the first argument is `self`. If true, + /// return the span of whole call and the span for all arguments expect the first one (`self`). + fn call_has_self_arg(&self, source: PathSource<'_>) -> Option<(Span, Option)> { + let mut has_self_arg = None; + if let PathSource::Expr(parent) = source { + match &parent.map(|p| &p.kind) { + Some(ExprKind::Call(_, args)) if args.len() > 0 => { + let mut expr_kind = &args[0].kind; + loop { + match expr_kind { + ExprKind::Path(_, arg_name) if arg_name.segments.len() == 1 => { + if arg_name.segments[0].ident.name == kw::SelfLower { + let call_span = parent.unwrap().span; + let tail_args_span = if args.len() > 1 { + Some(Span::new( + args[1].span.lo(), + args.last().unwrap().span.hi(), + call_span.ctxt(), + )) + } else { + None + }; + has_self_arg = Some((call_span, tail_args_span)); + } + break; + } + ExprKind::AddrOf(_, _, expr) => expr_kind = &expr.kind, + _ => break, + } + } + } + _ => (), + } + }; + return has_self_arg; + } + fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) { // HACK(estebank): find a better way to figure out that this was a // parser issue where a struct literal is being used on an expression