mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
introduce Span::find_ancestor_inside_same_ctxt
and use it for function argument diagnostics
This commit is contained in:
parent
10ef96f6a5
commit
3694fd08e6
@ -519,7 +519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// suggestions and labels are (more) correct when an arg is a
|
||||
// macro invocation.
|
||||
let normalize_span = |span: Span| -> Span {
|
||||
let normalized_span = span.find_ancestor_inside(error_span).unwrap_or(span);
|
||||
let normalized_span = span.find_ancestor_inside_same_ctxt(error_span).unwrap_or(span);
|
||||
// Sometimes macros mess up the spans, so do not normalize the
|
||||
// arg span to equal the error span, because that's less useful
|
||||
// than pointing out the arg expr in the wrong context.
|
||||
@ -1220,22 +1220,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
if let Some(suggestion_text) = suggestion_text {
|
||||
let source_map = self.sess().source_map();
|
||||
let (mut suggestion, suggestion_span) =
|
||||
if let Some(call_span) = full_call_span.find_ancestor_inside(error_span) {
|
||||
("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
|
||||
} else {
|
||||
(
|
||||
format!(
|
||||
"{}(",
|
||||
source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
|
||||
fn_def_id.map_or("".to_string(), |fn_def_id| {
|
||||
tcx.item_name(fn_def_id).to_string()
|
||||
})
|
||||
let (mut suggestion, suggestion_span) = if let Some(call_span) =
|
||||
full_call_span.find_ancestor_inside_same_ctxt(error_span)
|
||||
{
|
||||
("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
|
||||
} else {
|
||||
(
|
||||
format!(
|
||||
"{}(",
|
||||
source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
|
||||
fn_def_id.map_or("".to_string(), |fn_def_id| {
|
||||
tcx.item_name(fn_def_id).to_string()
|
||||
})
|
||||
),
|
||||
error_span,
|
||||
)
|
||||
};
|
||||
})
|
||||
),
|
||||
error_span,
|
||||
)
|
||||
};
|
||||
let mut needs_comma = false;
|
||||
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
|
||||
if needs_comma {
|
||||
|
@ -685,6 +685,12 @@ impl Span {
|
||||
}
|
||||
|
||||
/// Walk down the expansion ancestors to find a span that's contained within `outer`.
|
||||
///
|
||||
/// The span returned by this method may have a different [`SyntaxContext`] as `outer`.
|
||||
/// If you need to extend the span, use [`find_ancestor_inside_same_ctxt`] instead,
|
||||
/// because joining spans with different syntax contexts can create unexpected results.
|
||||
///
|
||||
/// [`find_ancestor_inside_same_ctxt`]: Self::find_ancestor_inside_same_ctxt
|
||||
pub fn find_ancestor_inside(mut self, outer: Span) -> Option<Span> {
|
||||
while !outer.contains(self) {
|
||||
self = self.parent_callsite()?;
|
||||
@ -692,11 +698,34 @@ impl Span {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
/// Like `find_ancestor_inside`, but specifically for when spans might not
|
||||
/// overlaps. Take care when using this, and prefer `find_ancestor_inside`
|
||||
/// when you know that the spans are nested (modulo macro expansion).
|
||||
/// Walk down the expansion ancestors to find a span with the same [`SyntaxContext`] as
|
||||
/// `other`.
|
||||
///
|
||||
/// Like [`find_ancestor_inside_same_ctxt`], but specifically for when spans might not
|
||||
/// overlap. Take care when using this, and prefer [`find_ancestor_inside`] or
|
||||
/// [`find_ancestor_inside_same_ctxt`] when you know that the spans are nested (modulo
|
||||
/// macro expansion).
|
||||
///
|
||||
/// [`find_ancestor_inside`]: Self::find_ancestor_inside
|
||||
/// [`find_ancestor_inside_same_ctxt`]: Self::find_ancestor_inside_same_ctxt
|
||||
pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option<Span> {
|
||||
while !Span::eq_ctxt(self, other) {
|
||||
while !self.eq_ctxt(other) {
|
||||
self = self.parent_callsite()?;
|
||||
}
|
||||
Some(self)
|
||||
}
|
||||
|
||||
/// Walk down the expansion ancestors to find a span that's contained within `outer` and
|
||||
/// has the same [`SyntaxContext`] as `outer`.
|
||||
///
|
||||
/// This method is the combination of [`find_ancestor_inside`] and
|
||||
/// [`find_ancestor_in_same_ctxt`] and should be preferred when extending the returned span.
|
||||
/// If you do not need to modify the span, use [`find_ancestor_inside`] instead.
|
||||
///
|
||||
/// [`find_ancestor_inside`]: Self::find_ancestor_inside
|
||||
/// [`find_ancestor_in_same_ctxt`]: Self::find_ancestor_in_same_ctxt
|
||||
pub fn find_ancestor_inside_same_ctxt(mut self, outer: Span) -> Option<Span> {
|
||||
while !outer.contains(self) || !self.eq_ctxt(outer) {
|
||||
self = self.parent_callsite()?;
|
||||
}
|
||||
Some(self)
|
||||
|
@ -321,7 +321,10 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
|
||||
--> $DIR/extra_arguments.rs:53:3
|
||||
|
|
||||
LL | one_arg(1, panic!());
|
||||
| ^^^^^^^ -------- unexpected argument
|
||||
| ^^^^^^^ ----------
|
||||
| | |
|
||||
| | unexpected argument
|
||||
| help: remove the extra argument
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/extra_arguments.rs:2:4
|
||||
@ -333,8 +336,9 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
|
||||
--> $DIR/extra_arguments.rs:54:3
|
||||
|
|
||||
LL | one_arg(panic!(), 1);
|
||||
| ^^^^^^^ - - unexpected argument of type `{integer}`
|
||||
| |
|
||||
| ^^^^^^^ ---
|
||||
| | |
|
||||
| | unexpected argument of type `{integer}`
|
||||
| help: remove the extra argument
|
||||
|
|
||||
note: function defined here
|
||||
|
@ -10,7 +10,6 @@ LL | b"".starts_with(stringify!(foo))
|
||||
found reference `&'static str`
|
||||
note: method defined here
|
||||
--> $SRC_DIR/core/src/slice/mod.rs:LL:COL
|
||||
= note: this error originates in the macro `stringify` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user