From 3694fd08e6e9d0828369ac1c9ee205cd0de71287 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sat, 10 Jun 2023 19:13:42 +0200 Subject: introduce `Span::find_ancestor_inside_same_ctxt` and use it for function argument diagnostics --- compiler/rustc_span/src/lib.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_span/src/lib.rs') diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ecaa82874a3..02a5d6966a7 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -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 { 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 { - 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 { + while !outer.contains(self) || !self.eq_ctxt(outer) { self = self.parent_callsite()?; } Some(self) -- cgit 1.4.1-3-g733a5