Fix diagnostics spans for missing generics in edge cases
This commit is contained in:
parent
b1c8835a0f
commit
338dc1f18c
1 changed files with 28 additions and 27 deletions
|
@ -94,14 +94,10 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
gen_args: &'a hir::GenericArgs<'a>,
|
gen_args: &'a hir::GenericArgs<'a>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let angle_brackets = if gen_args.is_empty() {
|
let angle_brackets = if gen_args.span_ext().is_none() {
|
||||||
AngleBrackets::Missing
|
if gen_args.is_empty() { AngleBrackets::Missing } else { AngleBrackets::Implied }
|
||||||
} else {
|
} else {
|
||||||
if gen_args.span().is_none() {
|
AngleBrackets::Available
|
||||||
AngleBrackets::Implied
|
|
||||||
} else {
|
|
||||||
AngleBrackets::Available
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -337,7 +333,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.gen_args.span().is_some() {
|
if self.gen_args.span_ext().is_some() {
|
||||||
format!(
|
format!(
|
||||||
"this {} takes {}{} {} argument{} but {} {} supplied",
|
"this {} takes {}{} {} argument{} but {} {} supplied",
|
||||||
def_kind,
|
def_kind,
|
||||||
|
@ -579,27 +575,32 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders);
|
err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders);
|
||||||
}
|
}
|
||||||
AngleBrackets::Available => {
|
AngleBrackets::Available => {
|
||||||
// angle brackets exist, so we just insert missing arguments after the existing
|
let gen_args_span = self.gen_args.span().unwrap();
|
||||||
// type or const args
|
let sugg_offset =
|
||||||
|
self.get_lifetime_args_offset() + self.num_provided_type_or_const_args();
|
||||||
|
|
||||||
let index_last_provided_arg =
|
let (sugg_span, is_first) = if sugg_offset == 0 {
|
||||||
self.get_lifetime_args_offset() + self.num_provided_type_or_const_args() - 1;
|
(gen_args_span.shrink_to_lo(), true)
|
||||||
if index_last_provided_arg < self.gen_args.args.len() {
|
} else {
|
||||||
let first_arg_span =
|
let arg_span = self.gen_args.args[sugg_offset - 1].span();
|
||||||
self.gen_args.args[index_last_provided_arg].span().shrink_to_hi();
|
// If we came here then inferred lifetimes's spans can only point
|
||||||
let source_map = self.tcx.sess.source_map();
|
// to either the opening bracket or to the space right after.
|
||||||
if let Ok(first_gen_arg) = source_map.span_to_snippet(first_arg_span) {
|
// Both of these spans have an `hi` lower than or equal to the span
|
||||||
let sugg = format!("{}, {}", first_gen_arg, suggested_args);
|
// of the generics excluding the brackets.
|
||||||
debug!("sugg: {:?}", sugg);
|
// This allows us to check if `arg_span` is the artificial span of
|
||||||
|
// an inferred lifetime, in which case the generic we're suggesting to
|
||||||
|
// add will be the first visible, even if it isn't the actual first generic.
|
||||||
|
(arg_span.shrink_to_hi(), arg_span.hi() <= gen_args_span.lo())
|
||||||
|
};
|
||||||
|
|
||||||
err.span_suggestion_verbose(
|
let sugg_prefix = if is_first { "" } else { ", " };
|
||||||
first_arg_span,
|
let sugg_suffix =
|
||||||
&msg,
|
if is_first && !self.gen_args.bindings.is_empty() { ", " } else { "" };
|
||||||
sugg,
|
|
||||||
Applicability::HasPlaceholders,
|
let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix);
|
||||||
);
|
debug!("sugg: {:?}", sugg);
|
||||||
}
|
|
||||||
}
|
err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue