diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 4788f57d070..7c5c1169c43 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::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro}; use rustc::{declare_tool_lint, lint_array}; use syntax::ast; use syntax::ptr::P; @@ -149,7 +149,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &ast::Expr) { if let Some((then, &Some(ref else_))) = unsugar_if(expr) { if (is_block(else_) || unsugar_if(else_).is_some()) && !differing_macro_contexts(then.span, else_.span) - && !in_macro(then.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..d708e223109 --- /dev/null +++ b/tests/ui/crashes/auxiliary/proc_macro_crash.rs @@ -0,0 +1,34 @@ +// force-host +// no-prefer-dynamic + +#![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); +}