about summary refs log tree commit diff
path: root/clippy_utils/src/source.rs
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2021-04-01 22:46:10 -0400
committerJason Newcomb <jsnewcomb@pm.me>2021-04-22 09:13:06 -0400
commit22f8c13cf5650d6c9d6ee7b4f0e88bffba9076ca (patch)
tree3169d2f267e7f8ec44edb317934ebd2dbb3bae97 /clippy_utils/src/source.rs
parent98e2b9f25b6db4b2680a3d388456d9f95cb28344 (diff)
downloadrust-22f8c13cf5650d6c9d6ee7b4f0e88bffba9076ca.tar.gz
rust-22f8c13cf5650d6c9d6ee7b4f0e88bffba9076ca.zip
Improve `implicit_return`
Better suggestions when returning macro calls.
Suggest changeing all the break expressions in a loop, not just the final statement.
Don't lint divergent functions.
Don't suggest returning the result of any divergent fuction.
Diffstat (limited to 'clippy_utils/src/source.rs')
-rw-r--r--clippy_utils/src/source.rs31
1 files changed, 20 insertions, 11 deletions
diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs
index 53180d1f9f5..2e731c182ec 100644
--- a/clippy_utils/src/source.rs
+++ b/clippy_utils/src/source.rs
@@ -280,17 +280,17 @@ pub fn snippet_with_context(
     default: &'a str,
     applicability: &mut Applicability,
 ) -> (Cow<'a, str>, bool) {
-    let outer_span = hygiene::walk_chain(span, outer);
-    let (span, is_macro_call) = if outer_span.ctxt() == outer {
-        (outer_span, span.ctxt() != outer)
-    } else {
-        // The span is from a macro argument, and the outer context is the macro using the argument
-        if *applicability != Applicability::Unspecified {
-            *applicability = Applicability::MaybeIncorrect;
-        }
-        // TODO: get the argument span.
-        (span, false)
-    };
+    let (span, is_macro_call) = walk_span_to_context(span, outer).map_or_else(
+        || {
+            // The span is from a macro argument, and the outer context is the macro using the argument
+            if *applicability != Applicability::Unspecified {
+                *applicability = Applicability::MaybeIncorrect;
+            }
+            // TODO: get the argument span.
+            (span, false)
+        },
+        |outer_span| (outer_span, span.ctxt() != outer),
+    );
 
     (
         snippet_with_applicability(cx, span, default, applicability),
@@ -298,6 +298,15 @@ pub fn snippet_with_context(
     )
 }
 
+/// Walks the span up to the target context, thereby returning the macro call site if the span is
+/// inside a macro expansion, or the original span if it is not. Note this will return `None` in the
+/// case of the span being in a macro expansion, but the target context is from expanding a macro
+/// argument.
+pub fn walk_span_to_context(span: Span, outer: SyntaxContext) -> Option<Span> {
+    let outer_span = hygiene::walk_chain(span, outer);
+    (outer_span.ctxt() == outer).then(|| outer_span)
+}
+
 /// Removes block comments from the given `Vec` of lines.
 ///
 /// # Examples