about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-09 07:13:08 +0000
committerbors <bors@rust-lang.org>2019-04-09 07:13:08 +0000
commit37f5c1ec734f806fe98930b8d5f54f00013f06f1 (patch)
treed9f803df2fcc6c06c5c67ba37e6eef381c050686
parent949f58440b19e470a8ed370166f9d72cd09bd7e3 (diff)
parent3ab803845028b02e8c0174020c7ae2c6eb736f8f (diff)
downloadrust-37f5c1ec734f806fe98930b8d5f54f00013f06f1.tar.gz
rust-37f5c1ec734f806fe98930b8d5f54f00013f06f1.zip
Auto merge of #3925 - phansch:3741, r=flip1995
Fix ICE in suspicious_else_formatting

Fixes #3741
-rw-r--r--clippy_lints/src/formatting.rs3
-rw-r--r--tests/ui/crashes/auxiliary/proc_macro_crash.rs37
-rw-r--r--tests/ui/crashes/ice-3741.rs12
3 files changed, 51 insertions, 1 deletions
diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs
index 4788f57d070..08376bc49d2 100644
--- a/clippy_lints/src/formatting.rs
+++ b/clippy_lints/src/formatting.rs
@@ -1,5 +1,5 @@
 use crate::utils::{differing_macro_contexts, in_macro, snippet_opt, span_note_and_lint};
-use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
+use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintPass};
 use rustc::{declare_tool_lint, lint_array};
 use syntax::ast;
 use syntax::ptr::P;
@@ -150,6 +150,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &ast::Expr) {
         if (is_block(else_) || unsugar_if(else_).is_some())
             && !differing_macro_contexts(then.span, else_.span)
             && !in_macro(then.span)
+            && !in_external_macro(cx.sess, expr.span)
         {
             // workaround for rust-lang/rust#43081
             if expr.span.lo().0 == 0 && expr.span.hi().0 == 0 {
diff --git a/tests/ui/crashes/auxiliary/proc_macro_crash.rs b/tests/ui/crashes/auxiliary/proc_macro_crash.rs
new file mode 100644
index 00000000000..71b10ed4db4
--- /dev/null
+++ b/tests/ui/crashes/auxiliary/proc_macro_crash.rs
@@ -0,0 +1,37 @@
+// no-prefer-dynamic
+// ^ compiletest by default builds all aux files as dylibs, but we don't want that for proc-macro
+// crates. If we don't set this, compiletest will override the `crate_type` attribute below and
+// compile this as dylib. Removing this then causes the test to fail because a `dylib` crate can't
+// contain a proc-macro.
+
+#![feature(repr128)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+use std::iter::FromIterator;
+
+#[proc_macro]
+pub fn macro_test(input_stream: TokenStream) -> TokenStream {
+    let first_token = input_stream.into_iter().next().unwrap();
+    let span = first_token.span();
+
+    TokenStream::from_iter(vec![
+        TokenTree::Ident(Ident::new("fn", Span::call_site())),
+        TokenTree::Ident(Ident::new("code", Span::call_site())),
+        TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+        TokenTree::Group(Group::new(Delimiter::Brace, {
+            let mut clause = Group::new(Delimiter::Brace, TokenStream::new());
+            clause.set_span(span);
+
+            TokenStream::from_iter(vec![
+                TokenTree::Ident(Ident::new("if", Span::call_site())),
+                TokenTree::Ident(Ident::new("true", Span::call_site())),
+                TokenTree::Group(clause.clone()),
+                TokenTree::Ident(Ident::new("else", Span::call_site())),
+                TokenTree::Group(clause.clone()),
+            ])
+        })),
+    ])
+}
diff --git a/tests/ui/crashes/ice-3741.rs b/tests/ui/crashes/ice-3741.rs
new file mode 100644
index 00000000000..74b9c9c86c8
--- /dev/null
+++ b/tests/ui/crashes/ice-3741.rs
@@ -0,0 +1,12 @@
+// aux-build:proc_macro_crash.rs
+// run-pass
+
+#![feature(proc_macro_hygiene)]
+#![warn(clippy::suspicious_else_formatting)]
+
+extern crate proc_macro_crash;
+use proc_macro_crash::macro_test;
+
+fn main() {
+    macro_test!(2);
+}