From 60c1bb05466a817cc8bd4781e8cd4d87f40b9ad4 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 7 Apr 2019 11:11:06 +0200 Subject: [PATCH 1/3] Fix ICE in suspicious_else_formatting --- clippy_lints/src/formatting.rs | 4 +-- .../ui/crashes/auxiliary/proc_macro_crash.rs | 34 +++++++++++++++++++ tests/ui/crashes/ice-3741.rs | 12 +++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/ui/crashes/auxiliary/proc_macro_crash.rs create mode 100644 tests/ui/crashes/ice-3741.rs diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 4788f57d070a4..7c5c1169c4374 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 0000000000000..d708e22310915 --- /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 0000000000000..74b9c9c86c81c --- /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); +} From 547c5c06678181ddba71f576cd79f2bce7529ca7 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Mon, 8 Apr 2019 07:56:54 +0200 Subject: [PATCH 2/3] cargo fmt --- clippy_lints/src/formatting.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs index 7c5c1169c4374..08376bc49d224 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, in_external_macro}; +use rustc::lint::{in_external_macro, EarlyContext, EarlyLintPass, LintArray, LintPass}; use rustc::{declare_tool_lint, lint_array}; use syntax::ast; use syntax::ptr::P; @@ -149,7 +149,8 @@ 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_external_macro(cx.sess, expr.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 { From 3ab803845028b02e8c0174020c7ae2c6eb736f8f Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Mon, 8 Apr 2019 21:23:39 +0200 Subject: [PATCH 3/3] Remove force-host and explain no-prefer-dynamic --- tests/ui/crashes/auxiliary/proc_macro_crash.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/ui/crashes/auxiliary/proc_macro_crash.rs b/tests/ui/crashes/auxiliary/proc_macro_crash.rs index d708e22310915..71b10ed4db4d4 100644 --- a/tests/ui/crashes/auxiliary/proc_macro_crash.rs +++ b/tests/ui/crashes/auxiliary/proc_macro_crash.rs @@ -1,5 +1,8 @@ -// force-host // 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"]