diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 1f31b24b443..53a37f23fa4 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -16,6 +16,7 @@ use toml; use rustc_plugin; +use rustc; macro_rules! declare_clippy_lint { @@ -175,6 +176,10 @@ mod reexport { crate use syntax::ast::{Name, NodeId}; } +pub fn register_pre_expansion_lints(session: &rustc::session::Session, store: &mut rustc::lint::LintStore) { + store.register_pre_expansion_pass(Some(session), box write::Pass); +} + #[cfg_attr(rustfmt, rustfmt_skip)] pub fn register_plugins(reg: &mut rustc_plugin::Registry) { let conf = match utils::conf::file_from_args(reg.args()) { @@ -320,7 +325,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { reg.register_late_lint_pass(box strings::StringLitAsBytes); reg.register_late_lint_pass(box derive::Derive); reg.register_late_lint_pass(box types::CharLitAsU8); - reg.register_late_lint_pass(box write::Pass); reg.register_late_lint_pass(box vec::Pass); reg.register_early_lint_pass(box non_expressive_names::NonExpressiveNames { single_char_binding_names_threshold: conf.single_char_binding_names_threshold, diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index 0f0bd64cb61..c4b5a9ccefc 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -1,15 +1,9 @@ -use rustc::hir::map::Node::{NodeImplItem, NodeItem}; -use rustc::hir::*; use rustc::lint::*; use rustc::{declare_lint, lint_array}; -use if_chain::if_chain; -use std::ops::Deref; -use syntax::ast::LitKind; -use syntax::ptr; -use syntax::symbol::LocalInternedString; -use syntax_pos::Span; -use crate::utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint, span_lint_and_sugg}; -use crate::utils::{opt_def_id, paths, last_path_segment}; +use syntax::ast::*; +use syntax::tokenstream::{ThinTokenStream, TokenStream}; +use syntax::parse::{token, parser}; +use crate::utils::{span_lint, span_lint_and_sugg}; /// **What it does:** This lint warns when you use `println!("")` to /// print a newline. @@ -173,317 +167,149 @@ impl LintPass for Pass { } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { - match expr.node { - // print!() - ExprKind::Call(ref fun, ref args) => { - if_chain! { - if let ExprKind::Path(ref qpath) = fun.node; - if let Some(fun_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)); - then { - check_print_variants(cx, expr, fun_id, args); - } +impl EarlyLintPass for Pass { + fn check_mac(&mut self, cx: &EarlyContext, mac: &Mac) { + if mac.node.path == "println" { + span_lint(cx, PRINT_STDOUT, mac.span, "use of `println!`"); + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, false) { + if fmtstr == "" { + span_lint_and_sugg( + cx, + PRINTLN_EMPTY_STRING, + mac.span, + "using `println!(\"\")`", + "replace it with", + "println!()".to_string(), + ); } - }, - // write!() - ExprKind::MethodCall(ref fun, _, ref args) => { - if fun.ident.name == "write_fmt" { - check_write_variants(cx, expr, args); + } + } else if mac.node.path == "print" { + span_lint(cx, PRINT_STDOUT, mac.span, "use of `print!`"); + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, false) { + if fmtstr.ends_with("\\n") { + span_lint(cx, PRINT_WITH_NEWLINE, mac.span, + "using `print!()` with a format string that ends in a \ + newline, consider using `println!()` instead"); } - }, - _ => (), + } + } else if mac.node.path == "write" { + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, true) { + if fmtstr.ends_with("\\n") { + span_lint(cx, WRITE_WITH_NEWLINE, mac.span, + "using `write!()` with a format string that ends in a \ + newline, consider using `writeln!()` instead"); + } + } + } else if mac.node.path == "writeln" { + if let Some(fmtstr) = check_tts(cx, &mac.node.tts, true) { + if fmtstr == "" { + span_lint_and_sugg( + cx, + WRITELN_EMPTY_STRING, + mac.span, + "using `writeln!(v, \"\")`", + "replace it with", + "writeln!(v)".to_string(), + ); + } + } } } } -fn check_write_variants<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, write_args: &ptr::P<[Expr]>) { - // `writeln!` uses `write!`. - if let Some(span) = is_expn_of(expr.span, "write") { - let (span, name) = match is_expn_of(span, "writeln") { - Some(span) => (span, "writeln"), - None => (span, "write"), +fn check_tts(cx: &EarlyContext<'a>, tts: &ThinTokenStream, is_write: bool) -> Option { + let tts = TokenStream::from(tts.clone()); + let mut parser = parser::Parser::new( + &cx.sess.parse_sess, + tts, + None, + false, + false, + ); + if is_write { + // skip the initial write target + parser.parse_expr().map_err(|mut err| err.cancel()).ok()?; + // might be `writeln!(foo)` + parser.expect(&token::Comma).map_err(|mut err| err.cancel()).ok()?; + } + let fmtstr = parser.parse_str().map_err(|mut err| err.cancel()).ok()?.0.to_string(); + use fmt_macros::*; + let tmp = fmtstr.clone(); + let mut args = vec![]; + let mut fmt_parser = Parser::new(&tmp, None); + while let Some(piece) = fmt_parser.next() { + if !fmt_parser.errors.is_empty() { + return None; + } + if let Piece::NextArgument(arg) = piece { + if arg.format.ty == "?" { + // FIXME: modify rustc's fmt string parser to give us the current span + span_lint(cx, USE_DEBUG, parser.prev_span, "use of `Debug`-based formatting"); + } + args.push(arg); + } + } + let lint = if is_write { + WRITE_LITERAL + } else { + PRINT_LITERAL + }; + let mut idx = 0; + loop { + if !parser.eat(&token::Comma) { + assert!(parser.eat(&token::Eof)); + return Some(fmtstr); + } + let expr = parser.parse_expr().map_err(|mut err| err.cancel()).ok()?; + const SIMPLE: FormatSpec = FormatSpec { + fill: None, + align: AlignUnknown, + flags: 0, + precision: CountImplied, + width: CountImplied, + ty: "", }; - - if_chain! { - // ensure we're calling Arguments::new_v1 or Arguments::new_v1_formatted - if write_args.len() == 2; - if let ExprKind::Call(ref args_fun, ref args_args) = write_args[1].node; - if let ExprKind::Path(ref qpath) = args_fun.node; - if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)); - if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1) || - match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED); - then { - // Check for literals in the write!/writeln! args - check_fmt_args_for_literal(cx, args_args, |span| { - span_lint(cx, WRITE_LITERAL, span, "writing a literal with an empty format string"); - }); - - if_chain! { - if args_args.len() >= 2; - if let ExprKind::AddrOf(_, ref match_expr) = args_args[1].node; - if let ExprKind::Match(ref args, _, _) = match_expr.node; - if let ExprKind::Tup(ref args) = args.node; - if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]); - then { - match name { - "write" => if has_newline_end(args, fmtstr, fmtlen) { - span_lint(cx, WRITE_WITH_NEWLINE, span, - "using `write!()` with a format string that ends in a \ - newline, consider using `writeln!()` instead"); + match &expr.node { + ExprKind::Lit(_) => { + let mut all_simple = true; + let mut seen = false; + for arg in &args { + match arg.position { + | ArgumentImplicitlyIs(n) + | ArgumentIs(n) + => if n == idx { + all_simple &= arg.format == SIMPLE; + seen = true; + }, + ArgumentNamed(_) => {}, + } + } + if all_simple && seen { + span_lint(cx, lint, expr.span, "literal with an empty format string"); + } + idx += 1; + }, + ExprKind::Assign(lhs, rhs) => { + if let ExprKind::Path(_, p) = &lhs.node { + let mut all_simple = true; + let mut seen = false; + for arg in &args { + match arg.position { + | ArgumentImplicitlyIs(_) + | ArgumentIs(_) + => {}, + ArgumentNamed(name) => if *p == name { + seen = true; + all_simple &= arg.format == SIMPLE; }, - "writeln" => if let Some(final_span) = has_empty_arg(cx, span, fmtstr, fmtlen) { - span_lint_and_sugg( - cx, - WRITE_WITH_NEWLINE, - final_span, - "using `writeln!(v, \"\")`", - "replace it with", - "writeln!(v)".to_string(), - ); - }, - _ => (), } } - } - } - } - } -} - -fn check_print_variants<'a, 'tcx>( - cx: &LateContext<'a, 'tcx>, - expr: &'tcx Expr, - fun_id: def_id::DefId, - args: &ptr::P<[Expr]>, -) { - // Search for `std::io::_print(..)` which is unique in a - // `print!` expansion. - if match_def_path(cx.tcx, fun_id, &paths::IO_PRINT) { - if let Some(span) = is_expn_of(expr.span, "print") { - // `println!` uses `print!`. - let (span, name) = match is_expn_of(span, "println") { - Some(span) => (span, "println"), - None => (span, "print"), - }; - - span_lint(cx, PRINT_STDOUT, span, &format!("use of `{}!`", name)); - if_chain! { - // ensure we're calling Arguments::new_v1 - if args.len() == 1; - if let ExprKind::Call(ref args_fun, ref args_args) = args[0].node; - then { - // Check for literals in the print!/println! args - check_fmt_args_for_literal(cx, args_args, |span| { - span_lint(cx, PRINT_LITERAL, span, "printing a literal with an empty format string"); - }); - - if_chain! { - if let ExprKind::Path(ref qpath) = args_fun.node; - if let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)); - if match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1); - if args_args.len() == 2; - if let ExprKind::AddrOf(_, ref match_expr) = args_args[1].node; - if let ExprKind::Match(ref args, _, _) = match_expr.node; - if let ExprKind::Tup(ref args) = args.node; - if let Some((fmtstr, fmtlen)) = get_argument_fmtstr_parts(&args_args[0]); - then { - match name { - "print" => - if has_newline_end(args, fmtstr, fmtlen) { - span_lint(cx, PRINT_WITH_NEWLINE, span, - "using `print!()` with a format string that ends in a \ - newline, consider using `println!()` instead"); - }, - "println" => - if let Some(final_span) = has_empty_arg(cx, span, fmtstr, fmtlen) { - span_lint_and_sugg( - cx, - PRINT_WITH_NEWLINE, - final_span, - "using `println!(\"\")`", - "replace it with", - "println!()".to_string(), - ); - }, - _ => (), - } - } + if all_simple && seen { + span_lint(cx, lint, rhs.span, "literal with an empty format string"); } } - } - } - } - // Search for something like - // `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)` - else if args.len() == 2 && match_def_path(cx.tcx, fun_id, &paths::FMT_ARGUMENTV1_NEW) { - if let ExprKind::Path(ref qpath) = args[1].node { - if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, args[1].hir_id)) { - if match_def_path(cx.tcx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) - && is_expn_of(expr.span, "panic").is_none() - { - span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); - } - } + }, + _ => idx += 1, } } } - -// Check for literals in write!/writeln! and print!/println! args -// ensuring the format string for the literal is `DISPLAY_FMT_METHOD` -// e.g., `writeln!(buf, "... {} ...", "foo")` -// ^ literal in `writeln!` -// e.g., `println!("... {} ...", "foo")` -// ^ literal in `println!` -fn check_fmt_args_for_literal<'a, 'tcx, F>(cx: &LateContext<'a, 'tcx>, args: &HirVec, lint_fn: F) -where - F: Fn(Span), -{ - if_chain! { - if args.len() >= 2; - - // the match statement - if let ExprKind::AddrOf(_, ref match_expr) = args[1].node; - if let ExprKind::Match(ref matchee, ref arms, _) = match_expr.node; - if let ExprKind::Tup(ref tup) = matchee.node; - if arms.len() == 1; - if let ExprKind::Array(ref arm_body_exprs) = arms[0].body.node; - then { - // it doesn't matter how many args there are in the `write!`/`writeln!`, - // if there's one literal, we should warn the user - for (idx, tup_arg) in tup.iter().enumerate() { - if_chain! { - // first, make sure we're dealing with a literal (i.e., an ExprKind::Lit) - if let ExprKind::AddrOf(_, ref tup_val) = tup_arg.node; - if let ExprKind::Lit(_) = tup_val.node; - - // next, check the corresponding match arm body to ensure - // this is DISPLAY_FMT_METHOD - if let ExprKind::Call(_, ref body_args) = arm_body_exprs[idx].node; - if body_args.len() == 2; - if let ExprKind::Path(ref body_qpath) = body_args[1].node; - if let Some(fun_def_id) = opt_def_id(resolve_node(cx, body_qpath, body_args[1].hir_id)); - if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD); - then { - if args.len() == 2 { - lint_fn(tup_val.span); - } - - // ensure the format str has no options (e.g., width, precision, alignment, etc.) - // and is just "{}" - if_chain! { - if args.len() == 3; - if let ExprKind::AddrOf(_, ref format_expr) = args[2].node; - if let ExprKind::Array(ref format_exprs) = format_expr.node; - if format_exprs.len() >= 1; - if let ExprKind::Struct(_, ref fields, _) = format_exprs[idx].node; - if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format"); - if check_unformatted(&format_field.expr); - then { - lint_fn(tup_val.span); - } - } - } - } - } - } - } -} - -/// Check for fmtstr = "... \n" -fn has_newline_end(args: &HirVec, fmtstr: LocalInternedString, fmtlen: usize) -> bool { - if_chain! { - // check the final format string part - if let Some('\n') = fmtstr.chars().last(); - - // "foo{}bar" is made into two strings + one argument, - // if the format string starts with `{}` (eg. "{}foo"), - // the string array is prepended an empty string "". - // We only want to check the last string after any `{}`: - if args.len() < fmtlen; - then { - return true - } - } - false -} - -/// Check for writeln!(v, "") / println!("") -fn has_empty_arg<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, fmtstr: LocalInternedString, fmtlen: usize) -> Option { - if_chain! { - // check that the string is empty - if fmtlen == 1; - if fmtstr.deref() == "\n"; - - // check the presence of that string - if let Ok(snippet) = cx.sess().codemap().span_to_snippet(span); - if snippet.contains("\"\""); - then { - if snippet.ends_with(';') { - return Some(cx.sess().codemap().span_until_char(span, ';')); - } - return Some(span) - } - } - None -} - -/// Returns the slice of format string parts in an `Arguments::new_v1` call. -fn get_argument_fmtstr_parts(expr: &Expr) -> Option<(LocalInternedString, usize)> { - if_chain! { - if let ExprKind::AddrOf(_, ref expr) = expr.node; // &["…", "…", …] - if let ExprKind::Array(ref exprs) = expr.node; - if let Some(expr) = exprs.last(); - if let ExprKind::Lit(ref lit) = expr.node; - if let LitKind::Str(ref lit, _) = lit.node; - then { - return Some((lit.as_str(), exprs.len())); - } - } - None -} - -fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool { - let map = &cx.tcx.hir; - - // `fmt` method - if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) { - // `Debug` impl - if let Some(NodeItem(item)) = map.find(map.get_parent(item.id)) { - if let ItemKind::Impl(_, _, _, _, Some(ref tr), _, _) = item.node { - return match_path(&tr.path, &["Debug"]); - } - } - } - false -} - -/// Checks if the expression matches -/// ```rust,ignore -/// &[_ { -/// format: _ { -/// width: _::Implied, -/// ... -/// }, -/// ..., -/// }] -/// ``` -pub fn check_unformatted(format_field: &Expr) -> bool { - if_chain! { - if let ExprKind::Struct(_, ref fields, _) = format_field.node; - if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width"); - if let ExprKind::Path(ref qpath) = width_field.expr.node; - if last_path_segment(qpath).ident.name == "Implied"; - if let Some(align_field) = fields.iter().find(|f| f.ident.name == "align"); - if let ExprKind::Path(ref qpath) = align_field.expr.node; - if last_path_segment(qpath).ident.name == "Unknown"; - if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision"); - if let ExprKind::Path(ref qpath_precision) = precision_field.expr.node; - if last_path_segment(qpath_precision).ident.name == "Implied"; - then { - return true; - } - } - - false -} diff --git a/src/driver.rs b/src/driver.rs index 585edcd82a6..e9e81bb88e3 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -118,6 +118,7 @@ pub fn main() { for (name, to) in lint_groups { ls.register_group(Some(sess), true, name, to); } + clippy_lints::register_pre_expansion_lints(sess, &mut ls); sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes); sess.plugin_attributes.borrow_mut().extend(attributes); diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs index c17639aaf04..88f24d27dbc 100644 --- a/tests/ui/excessive_precision.rs +++ b/tests/ui/excessive_precision.rs @@ -22,7 +22,7 @@ fn main() { const BAD64_3: f64 = 0.100_000_000_000_000_000_1; // Literal as param - println!("{}", 8.888_888_888_888_888_888_888); + println!("{:?}", 8.888_888_888_888_888_888_888); // // TODO add inferred type tests for f32 // Locals diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr index a167deac038..295846e9d7e 100644 --- a/tests/ui/excessive_precision.stderr +++ b/tests/ui/excessive_precision.stderr @@ -43,10 +43,10 @@ error: float has excessive precision | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1` error: float has excessive precision - --> $DIR/excessive_precision.rs:25:20 + --> $DIR/excessive_precision.rs:25:22 | -25 | println!("{}", 8.888_888_888_888_888_888_888); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89` +25 | println!("{:?}", 8.888_888_888_888_888_888_888); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89` error: float has excessive precision --> $DIR/excessive_precision.rs:36:22 diff --git a/tests/ui/matches.stderr b/tests/ui/matches.stderr index e0afc939b42..6554b6d3449 100644 --- a/tests/ui/matches.stderr +++ b/tests/ui/matches.stderr @@ -26,6 +26,23 @@ help: instead of prefixing all patterns with `&`, you can dereference the expres 32 | None => println!("none"), | +error: you seem to be trying to use match for destructuring a single pattern. Consider using `if let` + --> $DIR/matches.rs:40:5 + | +40 | / match tup { +41 | | &(v, 1) => println!("{}", v), +42 | | _ => println!("none"), +43 | | } + | |_____^ +help: try this + | +40 | if let &(v, 1) = tup { +41 | # [ cfg ( not ( stage0 ) ) ] { +42 | ( $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ) ; } # [ +43 | cfg ( stage0 ) ] { print ! ( "{}/n" , format_args ! ( $ ( $ arg ) * ) ) } } else { +44 | ( $ crate :: io :: _print ( format_args_nl ! ( $ ( $ arg ) * ) ) ) ; } + | + error: you don't need to add `&` to all patterns --> $DIR/matches.rs:40:5 | @@ -350,5 +367,5 @@ error: use as_mut() instead 221 | | }; | |_____^ help: try this: `mut_owned.as_mut()` -error: aborting due to 25 previous errors +error: aborting due to 26 previous errors diff --git a/tests/ui/non_expressive_names.stderr b/tests/ui/non_expressive_names.stderr index 4b95a1a9e70..c63b493db8d 100644 --- a/tests/ui/non_expressive_names.stderr +++ b/tests/ui/non_expressive_names.stderr @@ -1,3 +1,23 @@ +error: using `println!("")` + --> $DIR/non_expressive_names.rs:60:14 + | +60 | _ => println!(""), + | ^^^^^^^^^^^^ help: replace it with: `println!()` + | + = note: `-D println-empty-string` implied by `-D warnings` + +error: using `println!("")` + --> $DIR/non_expressive_names.rs:128:18 + | +128 | 1 => println!(""), + | ^^^^^^^^^^^^ help: replace it with: `println!()` + +error: using `println!("")` + --> $DIR/non_expressive_names.rs:132:18 + | +132 | 1 => println!(""), + | ^^^^^^^^^^^^ help: replace it with: `println!()` + error: binding's name is too similar to existing binding --> $DIR/non_expressive_names.rs:18:9 | @@ -167,5 +187,5 @@ error: consider choosing a more descriptive name 151 | let __1___2 = 12; | ^^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 20 previous errors diff --git a/tests/ui/print.stderr b/tests/ui/print.stderr index 457ed38a1b5..f2d2afd9bf7 100644 --- a/tests/ui/print.stderr +++ b/tests/ui/print.stderr @@ -1,16 +1,22 @@ error: use of `Debug`-based formatting - --> $DIR/print.rs:13:27 + --> $DIR/print.rs:13:19 | 13 | write!(f, "{:?}", 43.1415) - | ^^^^^^^ + | ^^^^^^ | = note: `-D use-debug` implied by `-D warnings` +error: use of `Debug`-based formatting + --> $DIR/print.rs:20:19 + | +20 | write!(f, "{:?}", 42.718) + | ^^^^^^ + error: use of `println!` --> $DIR/print.rs:25:5 | 25 | println!("Hello"); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: `-D print-stdout` implied by `-D warnings` @@ -18,37 +24,37 @@ error: use of `print!` --> $DIR/print.rs:26:5 | 26 | print!("Hello"); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: use of `print!` --> $DIR/print.rs:28:5 | 28 | print!("Hello {}", "World"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `print!` --> $DIR/print.rs:30:5 | 30 | print!("Hello {:?}", "World"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> $DIR/print.rs:30:26 + --> $DIR/print.rs:30:12 | 30 | print!("Hello {:?}", "World"); - | ^^^^^^^ + | ^^^^^^^^^^^^ error: use of `print!` --> $DIR/print.rs:32:5 | 32 | print!("Hello {:#?}", "#orld"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of `Debug`-based formatting - --> $DIR/print.rs:32:27 + --> $DIR/print.rs:32:12 | 32 | print!("Hello {:#?}", "#orld"); - | ^^^^^^^ + | ^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/tests/ui/print_literal.stderr b/tests/ui/print_literal.stderr index d1e4b49cbdd..39e0387cb5e 100644 --- a/tests/ui/print_literal.stderr +++ b/tests/ui/print_literal.stderr @@ -1,4 +1,4 @@ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:23:71 | 23 | println!("{} of {:b} people know binary, the other half doesn't", 1, 2); @@ -6,79 +6,79 @@ error: printing a literal with an empty format string | = note: `-D print-literal` implied by `-D warnings` -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:24:24 | 24 | print!("Hello {}", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:25:36 | 25 | println!("Hello {} {}", world, "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:26:26 | 26 | println!("Hello {}", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:27:30 | 27 | println!("10 / 4 is {}", 2.5); | ^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:28:28 | 28 | println!("2 + 1 = {}", 3); | ^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:33:25 | 33 | println!("{0} {1}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:33:34 | 33 | println!("{0} {1}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:34:25 | 34 | println!("{1} {0}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:34:34 | 34 | println!("{1} {0}", "hello", "world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:37:33 | 37 | println!("{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:37:46 | 37 | println!("{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:38:33 | 38 | println!("{bar} {foo}", foo="hello", bar="world"); | ^^^^^^^ -error: printing a literal with an empty format string +error: literal with an empty format string --> $DIR/print_literal.rs:38:46 | 38 | println!("{bar} {foo}", foo="hello", bar="world"); diff --git a/tests/ui/print_with_newline.stderr b/tests/ui/print_with_newline.stderr index 5f2013e728e..181f16b5cb7 100644 --- a/tests/ui/print_with_newline.stderr +++ b/tests/ui/print_with_newline.stderr @@ -2,9 +2,27 @@ error: using `print!()` with a format string that ends in a newline, consider us --> $DIR/print_with_newline.rs:7:5 | 7 | print!("Hello/n"); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ | = note: `-D print-with-newline` implied by `-D warnings` -error: aborting due to previous error +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:8:5 + | +8 | print!("Hello {}/n", "world"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:9:5 + | +9 | print!("Hello {} {}/n/n", "world", "#2"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: using `print!()` with a format string that ends in a newline, consider using `println!()` instead + --> $DIR/print_with_newline.rs:10:5 + | +10 | print!("{}/n", 1265); + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors diff --git a/tests/ui/println_empty_string.stderr b/tests/ui/println_empty_string.stderr index 1148a4496a5..cff3f988052 100644 --- a/tests/ui/println_empty_string.stderr +++ b/tests/ui/println_empty_string.stderr @@ -4,7 +4,7 @@ error: using `println!("")` 3 | println!(""); | ^^^^^^^^^^^^ help: replace it with: `println!()` | - = note: `-D print-with-newline` implied by `-D warnings` + = note: `-D println-empty-string` implied by `-D warnings` error: using `println!("")` --> $DIR/println_empty_string.rs:6:14 diff --git a/tests/ui/write_literal.stderr b/tests/ui/write_literal.stderr index 323a83e244a..70855ef8187 100644 --- a/tests/ui/write_literal.stderr +++ b/tests/ui/write_literal.stderr @@ -1,4 +1,4 @@ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:26:79 | 26 | writeln!(&mut v, "{} of {:b} people know binary, the other half doesn't", 1, 2); @@ -6,79 +6,79 @@ error: writing a literal with an empty format string | = note: `-D write-literal` implied by `-D warnings` -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:27:32 | 27 | write!(&mut v, "Hello {}", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:28:44 | 28 | writeln!(&mut v, "Hello {} {}", world, "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:29:34 | 29 | writeln!(&mut v, "Hello {}", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:30:38 | 30 | writeln!(&mut v, "10 / 4 is {}", 2.5); | ^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:31:36 | 31 | writeln!(&mut v, "2 + 1 = {}", 3); | ^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:36:33 | 36 | writeln!(&mut v, "{0} {1}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:36:42 | 36 | writeln!(&mut v, "{0} {1}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:37:33 | 37 | writeln!(&mut v, "{1} {0}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:37:42 | 37 | writeln!(&mut v, "{1} {0}", "hello", "world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:40:41 | 40 | writeln!(&mut v, "{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:40:54 | 40 | writeln!(&mut v, "{foo} {bar}", foo="hello", bar="world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:41:41 | 41 | writeln!(&mut v, "{bar} {foo}", foo="hello", bar="world"); | ^^^^^^^ -error: writing a literal with an empty format string +error: literal with an empty format string --> $DIR/write_literal.rs:41:54 | 41 | writeln!(&mut v, "{bar} {foo}", foo="hello", bar="world"); diff --git a/tests/ui/write_with_newline.stderr b/tests/ui/write_with_newline.stderr index 37f03afb016..7bb9b99731f 100644 --- a/tests/ui/write_with_newline.stderr +++ b/tests/ui/write_with_newline.stderr @@ -2,7 +2,7 @@ error: using `write!()` with a format string that ends in a newline, consider us --> $DIR/write_with_newline.rs:10:5 | 10 | write!(&mut v, "Hello/n"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D write-with-newline` implied by `-D warnings` @@ -10,19 +10,19 @@ error: using `write!()` with a format string that ends in a newline, consider us --> $DIR/write_with_newline.rs:11:5 | 11 | write!(&mut v, "Hello {}/n", "world"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `write!()` with a format string that ends in a newline, consider using `writeln!()` instead --> $DIR/write_with_newline.rs:12:5 | 12 | write!(&mut v, "Hello {} {}/n/n", "world", "#2"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: using `write!()` with a format string that ends in a newline, consider using `writeln!()` instead --> $DIR/write_with_newline.rs:13:5 | 13 | write!(&mut v, "{}/n", 1265); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/writeln_empty_string.stderr b/tests/ui/writeln_empty_string.stderr index b4649384865..16a8e0a203d 100644 --- a/tests/ui/writeln_empty_string.stderr +++ b/tests/ui/writeln_empty_string.stderr @@ -4,7 +4,7 @@ error: using `writeln!(v, "")` 9 | writeln!(&mut v, ""); | ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(v)` | - = note: `-D write-with-newline` implied by `-D warnings` + = note: `-D writeln-empty-string` implied by `-D warnings` error: aborting due to previous error