Skip to content

Commit 3694fd0

Browse files
author
Lukas Markeffsky
committed
introduce Span::find_ancestor_inside_same_ctxt
and use it for function argument diagnostics
1 parent 10ef96f commit 3694fd0

File tree

4 files changed

+57
-24
lines changed

4 files changed

+57
-24
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+17-16
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
519519
// suggestions and labels are (more) correct when an arg is a
520520
// macro invocation.
521521
let normalize_span = |span: Span| -> Span {
522-
let normalized_span = span.find_ancestor_inside(error_span).unwrap_or(span);
522+
let normalized_span = span.find_ancestor_inside_same_ctxt(error_span).unwrap_or(span);
523523
// Sometimes macros mess up the spans, so do not normalize the
524524
// arg span to equal the error span, because that's less useful
525525
// than pointing out the arg expr in the wrong context.
@@ -1220,22 +1220,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12201220
};
12211221
if let Some(suggestion_text) = suggestion_text {
12221222
let source_map = self.sess().source_map();
1223-
let (mut suggestion, suggestion_span) =
1224-
if let Some(call_span) = full_call_span.find_ancestor_inside(error_span) {
1225-
("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
1226-
} else {
1227-
(
1228-
format!(
1229-
"{}(",
1230-
source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
1231-
fn_def_id.map_or("".to_string(), |fn_def_id| {
1232-
tcx.item_name(fn_def_id).to_string()
1233-
})
1223+
let (mut suggestion, suggestion_span) = if let Some(call_span) =
1224+
full_call_span.find_ancestor_inside_same_ctxt(error_span)
1225+
{
1226+
("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi()))
1227+
} else {
1228+
(
1229+
format!(
1230+
"{}(",
1231+
source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| {
1232+
fn_def_id.map_or("".to_string(), |fn_def_id| {
1233+
tcx.item_name(fn_def_id).to_string()
12341234
})
1235-
),
1236-
error_span,
1237-
)
1238-
};
1235+
})
1236+
),
1237+
error_span,
1238+
)
1239+
};
12391240
let mut needs_comma = false;
12401241
for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
12411242
if needs_comma {

compiler/rustc_span/src/lib.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -685,18 +685,47 @@ impl Span {
685685
}
686686

687687
/// Walk down the expansion ancestors to find a span that's contained within `outer`.
688+
///
689+
/// The span returned by this method may have a different [`SyntaxContext`] as `outer`.
690+
/// If you need to extend the span, use [`find_ancestor_inside_same_ctxt`] instead,
691+
/// because joining spans with different syntax contexts can create unexpected results.
692+
///
693+
/// [`find_ancestor_inside_same_ctxt`]: Self::find_ancestor_inside_same_ctxt
688694
pub fn find_ancestor_inside(mut self, outer: Span) -> Option<Span> {
689695
while !outer.contains(self) {
690696
self = self.parent_callsite()?;
691697
}
692698
Some(self)
693699
}
694700

695-
/// Like `find_ancestor_inside`, but specifically for when spans might not
696-
/// overlaps. Take care when using this, and prefer `find_ancestor_inside`
697-
/// when you know that the spans are nested (modulo macro expansion).
701+
/// Walk down the expansion ancestors to find a span with the same [`SyntaxContext`] as
702+
/// `other`.
703+
///
704+
/// Like [`find_ancestor_inside_same_ctxt`], but specifically for when spans might not
705+
/// overlap. Take care when using this, and prefer [`find_ancestor_inside`] or
706+
/// [`find_ancestor_inside_same_ctxt`] when you know that the spans are nested (modulo
707+
/// macro expansion).
708+
///
709+
/// [`find_ancestor_inside`]: Self::find_ancestor_inside
710+
/// [`find_ancestor_inside_same_ctxt`]: Self::find_ancestor_inside_same_ctxt
698711
pub fn find_ancestor_in_same_ctxt(mut self, other: Span) -> Option<Span> {
699-
while !Span::eq_ctxt(self, other) {
712+
while !self.eq_ctxt(other) {
713+
self = self.parent_callsite()?;
714+
}
715+
Some(self)
716+
}
717+
718+
/// Walk down the expansion ancestors to find a span that's contained within `outer` and
719+
/// has the same [`SyntaxContext`] as `outer`.
720+
///
721+
/// This method is the combination of [`find_ancestor_inside`] and
722+
/// [`find_ancestor_in_same_ctxt`] and should be preferred when extending the returned span.
723+
/// If you do not need to modify the span, use [`find_ancestor_inside`] instead.
724+
///
725+
/// [`find_ancestor_inside`]: Self::find_ancestor_inside
726+
/// [`find_ancestor_in_same_ctxt`]: Self::find_ancestor_in_same_ctxt
727+
pub fn find_ancestor_inside_same_ctxt(mut self, outer: Span) -> Option<Span> {
728+
while !outer.contains(self) || !self.eq_ctxt(outer) {
700729
self = self.parent_callsite()?;
701730
}
702731
Some(self)

tests/ui/argument-suggestions/extra_arguments.stderr

+7-3
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,10 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
321321
--> $DIR/extra_arguments.rs:53:3
322322
|
323323
LL | one_arg(1, panic!());
324-
| ^^^^^^^ -------- unexpected argument
324+
| ^^^^^^^ ----------
325+
| | |
326+
| | unexpected argument
327+
| help: remove the extra argument
325328
|
326329
note: function defined here
327330
--> $DIR/extra_arguments.rs:2:4
@@ -333,8 +336,9 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
333336
--> $DIR/extra_arguments.rs:54:3
334337
|
335338
LL | one_arg(panic!(), 1);
336-
| ^^^^^^^ - - unexpected argument of type `{integer}`
337-
| |
339+
| ^^^^^^^ ---
340+
| | |
341+
| | unexpected argument of type `{integer}`
338342
| help: remove the extra argument
339343
|
340344
note: function defined here

tests/ui/issues/issue-48364.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ LL | b"".starts_with(stringify!(foo))
1010
found reference `&'static str`
1111
note: method defined here
1212
--> $SRC_DIR/core/src/slice/mod.rs:LL:COL
13-
= note: this error originates in the macro `stringify` (in Nightly builds, run with -Z macro-backtrace for more info)
1413

1514
error: aborting due to previous error
1615

0 commit comments

Comments
 (0)