Skip to content

Commit

Permalink
Extract checking for self arg to separate method
Browse files Browse the repository at this point in the history
  • Loading branch information
VirrageS committed Dec 23, 2019
1 parent 7353afd commit 2168c0b
Showing 1 changed file with 40 additions and 35 deletions.
75 changes: 40 additions & 35 deletions src/librustc_resolve/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Span>)> {
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
Expand Down

0 comments on commit 2168c0b

Please sign in to comment.