mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 14:38:46 +00:00
new uninlined_format_args lint to inline explicit arguments
Implement https://github.com/rust-lang/rust-clippy/issues/8368 - a new lint to inline format arguments such as `print!("{}", var)` into `print!("{var}")`. code | suggestion | comment ---|---|--- `print!("{}", var)` | `print!("{var}")` | simple variables `print!("{0}", var)` | `print!("{var}")` | positional variables `print!("{v}", v=var)` | `print!("{var}")` | named variables `print!("{0} {0}", var)` | `print!("{var} {var}")` | aliased variables `print!("{0:1$}", var, width)` | `print!("{var:width$}")` | width support `print!("{0:.1$}", var, prec)` | `print!("{var:.prec$}")` | precision support `print!("{:.*}", prec, var)` | `print!("{var:.prec$}")` | asterisk support code | suggestion | comment ---|---|--- `print!("{0}={1}", var, 1+2)` | `print!("{var}={0}", 1+2)` | Format string uses an indexed argument that cannot be inlined. Supporting this case requires re-indexing of the format string. changelog: [`uninlined_format_args`]: A new lint to inline format arguments, i.e. `print!("{}", var)` into `print!("{var}")`
This commit is contained in:
parent
57c9daa09b
commit
5a71bbdf3f
15 changed files with 1451 additions and 29 deletions
|
@ -4274,6 +4274,7 @@ Released 2018-09-13
|
||||||
[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented
|
[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented
|
||||||
[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init
|
[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init
|
||||||
[`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec
|
[`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec
|
||||||
|
[`uninlined_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
|
||||||
[`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg
|
[`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg
|
||||||
[`unit_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_cmp
|
[`unit_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_cmp
|
||||||
[`unit_hash`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_hash
|
[`unit_hash`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_hash
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::is_diag_trait_item;
|
use clippy_utils::macros::FormatParamKind::{Implicit, Named, Numbered, Starred};
|
||||||
use clippy_utils::macros::{is_format_macro, FormatArgsExpn};
|
use clippy_utils::macros::{is_format_macro, FormatArgsExpn, FormatParam, FormatParamUsage};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::{expand_past_previous_comma, snippet_opt};
|
||||||
use clippy_utils::ty::implements_trait;
|
use clippy_utils::ty::implements_trait;
|
||||||
|
use clippy_utils::{is_diag_trait_item, meets_msrv, msrvs};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, HirId};
|
use rustc_hir::{Expr, ExprKind, HirId, Path, QPath};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_semver::RustcVersion;
|
||||||
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{sym, ExpnData, ExpnKind, Span, Symbol};
|
use rustc_span::{sym, ExpnData, ExpnKind, Span, Symbol};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -64,7 +66,67 @@ declare_clippy_lint! {
|
||||||
"`to_string` applied to a type that implements `Display` in format args"
|
"`to_string` applied to a type that implements `Display` in format args"
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(FormatArgs => [FORMAT_IN_FORMAT_ARGS, TO_STRING_IN_FORMAT_ARGS]);
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Detect when a variable is not inlined in a format string,
|
||||||
|
/// and suggests to inline it.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// Non-inlined code is slightly more difficult to read and understand,
|
||||||
|
/// as it requires arguments to be matched against the format string.
|
||||||
|
/// The inlined syntax, where allowed, is simpler.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// # let var = 42;
|
||||||
|
/// # let width = 1;
|
||||||
|
/// # let prec = 2;
|
||||||
|
/// format!("{}", var);
|
||||||
|
/// format!("{v:?}", v = var);
|
||||||
|
/// format!("{0} {0}", var);
|
||||||
|
/// format!("{0:1$}", var, width);
|
||||||
|
/// format!("{:.*}", prec, var);
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// # let var = 42;
|
||||||
|
/// # let width = 1;
|
||||||
|
/// # let prec = 2;
|
||||||
|
/// format!("{var}");
|
||||||
|
/// format!("{var:?}");
|
||||||
|
/// format!("{var} {var}");
|
||||||
|
/// format!("{var:width$}");
|
||||||
|
/// format!("{var:.prec$}");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ### Known Problems
|
||||||
|
///
|
||||||
|
/// There may be a false positive if the format string is expanded from certain proc macros:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// println!(indoc!("{}"), var);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If a format string contains a numbered argument that cannot be inlined
|
||||||
|
/// nothing will be suggested, e.g. `println!("{0}={1}", var, 1+2)`.
|
||||||
|
#[clippy::version = "1.65.0"]
|
||||||
|
pub UNINLINED_FORMAT_ARGS,
|
||||||
|
pedantic,
|
||||||
|
"using non-inlined variables in `format!` calls"
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_lint_pass!(FormatArgs => [FORMAT_IN_FORMAT_ARGS, UNINLINED_FORMAT_ARGS, TO_STRING_IN_FORMAT_ARGS]);
|
||||||
|
|
||||||
|
pub struct FormatArgs {
|
||||||
|
msrv: Option<RustcVersion>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatArgs {
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
||||||
|
Self { msrv }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for FormatArgs {
|
impl<'tcx> LateLintPass<'tcx> for FormatArgs {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
|
@ -86,9 +148,73 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
|
||||||
check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value);
|
check_format_in_format_args(cx, outermost_expn_data.call_site, name, arg.param.value);
|
||||||
check_to_string_in_format_args(cx, name, arg.param.value);
|
check_to_string_in_format_args(cx, name, arg.param.value);
|
||||||
}
|
}
|
||||||
|
if meets_msrv(self.msrv, msrvs::FORMAT_ARGS_CAPTURE) {
|
||||||
|
check_uninlined_args(cx, &format_args, outermost_expn_data.call_site);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract_msrv_attr!(LateContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_uninlined_args(cx: &LateContext<'_>, args: &FormatArgsExpn<'_>, call_site: Span) {
|
||||||
|
if args.format_string.span.from_expansion() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fixes = Vec::new();
|
||||||
|
// If any of the arguments are referenced by an index number,
|
||||||
|
// and that argument is not a simple variable and cannot be inlined,
|
||||||
|
// we cannot remove any other arguments in the format string,
|
||||||
|
// because the index numbers might be wrong after inlining.
|
||||||
|
// Example of an un-inlinable format: print!("{}{1}", foo, 2)
|
||||||
|
if !args.params().all(|p| check_one_arg(cx, &p, &mut fixes)) || fixes.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Properly ignore a rare case where the format string is wrapped in a macro.
|
||||||
|
// Example: `format!(indoc!("{}"), foo);`
|
||||||
|
// If inlined, they will cause a compilation error:
|
||||||
|
// > to avoid ambiguity, `format_args!` cannot capture variables
|
||||||
|
// > when the format string is expanded from a macro
|
||||||
|
// @Alexendoo explanation:
|
||||||
|
// > indoc! is a proc macro that is producing a string literal with its span
|
||||||
|
// > set to its input it's not marked as from expansion, and since it's compatible
|
||||||
|
// > tokenization wise clippy_utils::is_from_proc_macro wouldn't catch it either
|
||||||
|
// This might be a relatively expensive test, so do it only we are ready to replace.
|
||||||
|
// See more examples in tests/ui/uninlined_format_args.rs
|
||||||
|
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
UNINLINED_FORMAT_ARGS,
|
||||||
|
call_site,
|
||||||
|
"variables can be used directly in the `format!` string",
|
||||||
|
|diag| {
|
||||||
|
diag.multipart_suggestion("change this to", fixes, Applicability::MachineApplicable);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_one_arg(cx: &LateContext<'_>, param: &FormatParam<'_>, fixes: &mut Vec<(Span, String)>) -> bool {
|
||||||
|
if matches!(param.kind, Implicit | Starred | Named(_) | Numbered)
|
||||||
|
&& let ExprKind::Path(QPath::Resolved(None, path)) = param.value.kind
|
||||||
|
&& let Path { span, segments, .. } = path
|
||||||
|
&& let [segment] = segments
|
||||||
|
{
|
||||||
|
let replacement = match param.usage {
|
||||||
|
FormatParamUsage::Argument => segment.ident.name.to_string(),
|
||||||
|
FormatParamUsage::Width => format!("{}$", segment.ident.name),
|
||||||
|
FormatParamUsage::Precision => format!(".{}$", segment.ident.name),
|
||||||
|
};
|
||||||
|
fixes.push((param.span, replacement));
|
||||||
|
let arg_span = expand_past_previous_comma(cx, *span);
|
||||||
|
fixes.push((arg_span, String::new()));
|
||||||
|
true // successful inlining, continue checking
|
||||||
|
} else {
|
||||||
|
// if we can't inline a numbered argument, we can't continue
|
||||||
|
param.kind != Numbered
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn outermost_expn_data(expn_data: ExpnData) -> ExpnData {
|
fn outermost_expn_data(expn_data: ExpnData) -> ExpnData {
|
||||||
|
@ -170,7 +296,7 @@ fn check_to_string_in_format_args(cx: &LateContext<'_>, name: Symbol, value: &Ex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if `hir_id` is referred to by multiple format params
|
/// Returns true if `hir_id` is referred to by multiple format params
|
||||||
fn is_aliased(args: &FormatArgsExpn<'_>, hir_id: HirId) -> bool {
|
fn is_aliased(args: &FormatArgsExpn<'_>, hir_id: HirId) -> bool {
|
||||||
args.params()
|
args.params()
|
||||||
.filter(|param| param.value.hir_id == hir_id)
|
.filter(|param| param.value.hir_id == hir_id)
|
||||||
|
|
|
@ -159,6 +159,7 @@ store.register_lints(&[
|
||||||
format::USELESS_FORMAT,
|
format::USELESS_FORMAT,
|
||||||
format_args::FORMAT_IN_FORMAT_ARGS,
|
format_args::FORMAT_IN_FORMAT_ARGS,
|
||||||
format_args::TO_STRING_IN_FORMAT_ARGS,
|
format_args::TO_STRING_IN_FORMAT_ARGS,
|
||||||
|
format_args::UNINLINED_FORMAT_ARGS,
|
||||||
format_impl::PRINT_IN_FORMAT_IMPL,
|
format_impl::PRINT_IN_FORMAT_IMPL,
|
||||||
format_impl::RECURSIVE_FORMAT_IMPL,
|
format_impl::RECURSIVE_FORMAT_IMPL,
|
||||||
format_push_string::FORMAT_PUSH_STRING,
|
format_push_string::FORMAT_PUSH_STRING,
|
||||||
|
|
|
@ -29,6 +29,7 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
|
||||||
LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
|
LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
|
||||||
LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
|
LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
|
||||||
LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
|
LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
|
||||||
|
LintId::of(format_args::UNINLINED_FORMAT_ARGS),
|
||||||
LintId::of(functions::MUST_USE_CANDIDATE),
|
LintId::of(functions::MUST_USE_CANDIDATE),
|
||||||
LintId::of(functions::TOO_MANY_LINES),
|
LintId::of(functions::TOO_MANY_LINES),
|
||||||
LintId::of(if_not_else::IF_NOT_ELSE),
|
LintId::of(if_not_else::IF_NOT_ELSE),
|
||||||
|
|
|
@ -855,7 +855,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
|
store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
|
||||||
store.register_late_pass(move || Box::new(format_args::FormatArgs));
|
store.register_late_pass(move || Box::new(format_args::FormatArgs::new(msrv)));
|
||||||
store.register_late_pass(|| Box::new(trailing_empty_array::TrailingEmptyArray));
|
store.register_late_pass(|| Box::new(trailing_empty_array::TrailingEmptyArray));
|
||||||
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
|
store.register_early_pass(|| Box::new(octal_escapes::OctalEscapes));
|
||||||
store.register_late_pass(|| Box::new(needless_late_init::NeedlessLateInit));
|
store.register_late_pass(|| Box::new(needless_late_init::NeedlessLateInit));
|
||||||
|
|
|
@ -213,7 +213,7 @@ define_Conf! {
|
||||||
///
|
///
|
||||||
/// Suppress lints whenever the suggested change would cause breakage for other crates.
|
/// Suppress lints whenever the suggested change would cause breakage for other crates.
|
||||||
(avoid_breaking_exported_api: bool = true),
|
(avoid_breaking_exported_api: bool = true),
|
||||||
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED.
|
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS.
|
||||||
///
|
///
|
||||||
/// The minimum rust version that the project supports
|
/// The minimum rust version that the project supports
|
||||||
(msrv: Option<String> = None),
|
(msrv: Option<String> = None),
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
||||||
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn, MacroCall};
|
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn, MacroCall};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::{expand_past_previous_comma, snippet_opt};
|
||||||
use rustc_ast::LitKind;
|
use rustc_ast::LitKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, ExprKind, HirIdMap, Impl, Item, ItemKind};
|
use rustc_hir::{Expr, ExprKind, HirIdMap, Impl, Item, ItemKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{sym, BytePos, Span};
|
use rustc_span::{sym, BytePos};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
|
@ -542,10 +542,3 @@ fn conservative_unescape(literal: &str) -> Result<String, UnescapeErr> {
|
||||||
|
|
||||||
if err { Err(UnescapeErr::Lint) } else { Ok(unescaped) }
|
if err { Err(UnescapeErr::Lint) } else { Ok(unescaped) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand from `writeln!(o, "")` to `writeln!(o, "")`
|
|
||||||
// ^^ ^^^^
|
|
||||||
fn expand_past_previous_comma(cx: &LateContext<'_>, span: Span) -> Span {
|
|
||||||
let extended = cx.sess().source_map().span_extend_to_prev_char(span, ',', true);
|
|
||||||
extended.with_lo(extended.lo() - BytePos(1))
|
|
||||||
}
|
|
||||||
|
|
|
@ -545,19 +545,32 @@ fn span_from_inner(base: SpanData, inner: rpf::InnerSpan) -> Span {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// How a format parameter is used in the format string
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum FormatParamKind {
|
pub enum FormatParamKind {
|
||||||
/// An implicit parameter , such as `{}` or `{:?}`.
|
/// An implicit parameter , such as `{}` or `{:?}`.
|
||||||
Implicit,
|
Implicit,
|
||||||
/// A parameter with an explicit number, or an asterisk precision. e.g. `{1}`, `{0:?}`,
|
/// A parameter with an explicit number, e.g. `{1}`, `{0:?}`, or `{:.0$}`
|
||||||
/// `{:.0$}` or `{:.*}`.
|
|
||||||
Numbered,
|
Numbered,
|
||||||
|
/// A parameter with an asterisk precision. e.g. `{:.*}`.
|
||||||
|
Starred,
|
||||||
/// A named parameter with a named `value_arg`, such as the `x` in `format!("{x}", x = 1)`.
|
/// A named parameter with a named `value_arg`, such as the `x` in `format!("{x}", x = 1)`.
|
||||||
Named(Symbol),
|
Named(Symbol),
|
||||||
/// An implicit named parameter, such as the `y` in `format!("{y}")`.
|
/// An implicit named parameter, such as the `y` in `format!("{y}")`.
|
||||||
NamedInline(Symbol),
|
NamedInline(Symbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Where a format parameter is being used in the format string
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum FormatParamUsage {
|
||||||
|
/// Appears as an argument, e.g. `format!("{}", foo)`
|
||||||
|
Argument,
|
||||||
|
/// Appears as a width, e.g. `format!("{:width$}", foo, width = 1)`
|
||||||
|
Width,
|
||||||
|
/// Appears as a precision, e.g. `format!("{:.precision$}", foo, precision = 1)`
|
||||||
|
Precision,
|
||||||
|
}
|
||||||
|
|
||||||
/// A `FormatParam` is any place in a `FormatArgument` that refers to a supplied value, e.g.
|
/// A `FormatParam` is any place in a `FormatArgument` that refers to a supplied value, e.g.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -573,6 +586,8 @@ pub struct FormatParam<'tcx> {
|
||||||
pub value: &'tcx Expr<'tcx>,
|
pub value: &'tcx Expr<'tcx>,
|
||||||
/// How this parameter refers to its `value`.
|
/// How this parameter refers to its `value`.
|
||||||
pub kind: FormatParamKind,
|
pub kind: FormatParamKind,
|
||||||
|
/// Where this format param is being used - argument/width/precision
|
||||||
|
pub usage: FormatParamUsage,
|
||||||
/// Span of the parameter, may be zero width. Includes the whitespace of implicit parameters.
|
/// Span of the parameter, may be zero width. Includes the whitespace of implicit parameters.
|
||||||
///
|
///
|
||||||
/// ```text
|
/// ```text
|
||||||
|
@ -585,6 +600,7 @@ pub struct FormatParam<'tcx> {
|
||||||
impl<'tcx> FormatParam<'tcx> {
|
impl<'tcx> FormatParam<'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
mut kind: FormatParamKind,
|
mut kind: FormatParamKind,
|
||||||
|
usage: FormatParamUsage,
|
||||||
position: usize,
|
position: usize,
|
||||||
inner: rpf::InnerSpan,
|
inner: rpf::InnerSpan,
|
||||||
values: &FormatArgsValues<'tcx>,
|
values: &FormatArgsValues<'tcx>,
|
||||||
|
@ -599,7 +615,12 @@ impl<'tcx> FormatParam<'tcx> {
|
||||||
kind = FormatParamKind::NamedInline(name);
|
kind = FormatParamKind::NamedInline(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Self { value, kind, span })
|
Some(Self {
|
||||||
|
value,
|
||||||
|
kind,
|
||||||
|
usage,
|
||||||
|
span,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,6 +639,7 @@ pub enum Count<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> Count<'tcx> {
|
impl<'tcx> Count<'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
|
usage: FormatParamUsage,
|
||||||
count: rpf::Count<'_>,
|
count: rpf::Count<'_>,
|
||||||
position: Option<usize>,
|
position: Option<usize>,
|
||||||
inner: Option<rpf::InnerSpan>,
|
inner: Option<rpf::InnerSpan>,
|
||||||
|
@ -625,15 +647,27 @@ impl<'tcx> Count<'tcx> {
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
Some(match count {
|
Some(match count {
|
||||||
rpf::Count::CountIs(val) => Self::Is(val, span_from_inner(values.format_string_span, inner?)),
|
rpf::Count::CountIs(val) => Self::Is(val, span_from_inner(values.format_string_span, inner?)),
|
||||||
rpf::Count::CountIsName(name, span) => Self::Param(FormatParam::new(
|
rpf::Count::CountIsName(name, _) => Self::Param(FormatParam::new(
|
||||||
FormatParamKind::Named(Symbol::intern(name)),
|
FormatParamKind::Named(Symbol::intern(name)),
|
||||||
|
usage,
|
||||||
position?,
|
position?,
|
||||||
span,
|
inner?,
|
||||||
|
values,
|
||||||
|
)?),
|
||||||
|
rpf::Count::CountIsParam(_) => Self::Param(FormatParam::new(
|
||||||
|
FormatParamKind::Numbered,
|
||||||
|
usage,
|
||||||
|
position?,
|
||||||
|
inner?,
|
||||||
|
values,
|
||||||
|
)?),
|
||||||
|
rpf::Count::CountIsStar(_) => Self::Param(FormatParam::new(
|
||||||
|
FormatParamKind::Starred,
|
||||||
|
usage,
|
||||||
|
position?,
|
||||||
|
inner?,
|
||||||
values,
|
values,
|
||||||
)?),
|
)?),
|
||||||
rpf::Count::CountIsParam(_) | rpf::Count::CountIsStar(_) => {
|
|
||||||
Self::Param(FormatParam::new(FormatParamKind::Numbered, position?, inner?, values)?)
|
|
||||||
},
|
|
||||||
rpf::Count::CountImplied => Self::Implied,
|
rpf::Count::CountImplied => Self::Implied,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -676,8 +710,20 @@ impl<'tcx> FormatSpec<'tcx> {
|
||||||
fill: spec.fill,
|
fill: spec.fill,
|
||||||
align: spec.align,
|
align: spec.align,
|
||||||
flags: spec.flags,
|
flags: spec.flags,
|
||||||
precision: Count::new(spec.precision, positions.precision, spec.precision_span, values)?,
|
precision: Count::new(
|
||||||
width: Count::new(spec.width, positions.width, spec.width_span, values)?,
|
FormatParamUsage::Precision,
|
||||||
|
spec.precision,
|
||||||
|
positions.precision,
|
||||||
|
spec.precision_span,
|
||||||
|
values,
|
||||||
|
)?,
|
||||||
|
width: Count::new(
|
||||||
|
FormatParamUsage::Width,
|
||||||
|
spec.width,
|
||||||
|
positions.width,
|
||||||
|
spec.width_span,
|
||||||
|
values,
|
||||||
|
)?,
|
||||||
r#trait: match spec.ty {
|
r#trait: match spec.ty {
|
||||||
"" => sym::Display,
|
"" => sym::Display,
|
||||||
"?" => sym::Debug,
|
"?" => sym::Debug,
|
||||||
|
@ -723,7 +769,7 @@ pub struct FormatArg<'tcx> {
|
||||||
pub struct FormatArgsExpn<'tcx> {
|
pub struct FormatArgsExpn<'tcx> {
|
||||||
/// The format string literal.
|
/// The format string literal.
|
||||||
pub format_string: FormatString,
|
pub format_string: FormatString,
|
||||||
// The format arguments, such as `{:?}`.
|
/// The format arguments, such as `{:?}`.
|
||||||
pub args: Vec<FormatArg<'tcx>>,
|
pub args: Vec<FormatArg<'tcx>>,
|
||||||
/// Has an added newline due to `println!()`/`writeln!()`/etc. The last format string part will
|
/// Has an added newline due to `println!()`/`writeln!()`/etc. The last format string part will
|
||||||
/// include this added newline.
|
/// include this added newline.
|
||||||
|
@ -797,6 +843,7 @@ impl<'tcx> FormatArgsExpn<'tcx> {
|
||||||
// NamedInline is handled by `FormatParam::new()`
|
// NamedInline is handled by `FormatParam::new()`
|
||||||
rpf::Position::ArgumentNamed(name) => FormatParamKind::Named(Symbol::intern(name)),
|
rpf::Position::ArgumentNamed(name) => FormatParamKind::Named(Symbol::intern(name)),
|
||||||
},
|
},
|
||||||
|
FormatParamUsage::Argument,
|
||||||
position.value,
|
position.value,
|
||||||
parsed_arg.position_span,
|
parsed_arg.position_span,
|
||||||
&values,
|
&values,
|
||||||
|
|
|
@ -13,6 +13,7 @@ macro_rules! msrv_aliases {
|
||||||
// names may refer to stabilized feature flags or library items
|
// names may refer to stabilized feature flags or library items
|
||||||
msrv_aliases! {
|
msrv_aliases! {
|
||||||
1,62,0 { BOOL_THEN_SOME }
|
1,62,0 { BOOL_THEN_SOME }
|
||||||
|
1,58,0 { FORMAT_ARGS_CAPTURE }
|
||||||
1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
|
1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
|
||||||
1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }
|
1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }
|
||||||
1,51,0 { BORROW_AS_PTR, UNSIGNED_ABS }
|
1,51,0 { BORROW_AS_PTR, UNSIGNED_ABS }
|
||||||
|
|
|
@ -392,6 +392,16 @@ pub fn trim_span(sm: &SourceMap, span: Span) -> Span {
|
||||||
.span()
|
.span()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Expand a span to include a preceding comma
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// writeln!(o, "") -> writeln!(o, "")
|
||||||
|
/// ^^ ^^^^
|
||||||
|
/// ```
|
||||||
|
pub fn expand_past_previous_comma(cx: &LateContext<'_>, span: Span) -> Span {
|
||||||
|
let extended = cx.sess().source_map().span_extend_to_prev_char(span, ',', true);
|
||||||
|
extended.with_lo(extended.lo() - BytePos(1))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{reindent_multiline, without_block_comments};
|
use super::{reindent_multiline, without_block_comments};
|
||||||
|
|
|
@ -521,6 +521,7 @@ docs! {
|
||||||
"unimplemented",
|
"unimplemented",
|
||||||
"uninit_assumed_init",
|
"uninit_assumed_init",
|
||||||
"uninit_vec",
|
"uninit_vec",
|
||||||
|
"uninlined_format_args",
|
||||||
"unit_arg",
|
"unit_arg",
|
||||||
"unit_cmp",
|
"unit_cmp",
|
||||||
"unit_hash",
|
"unit_hash",
|
||||||
|
|
36
src/docs/uninlined_format_args.txt
Normal file
36
src/docs/uninlined_format_args.txt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
### What it does
|
||||||
|
Detect when a variable is not inlined in a format string,
|
||||||
|
and suggests to inline it.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
Non-inlined code is slightly more difficult to read and understand,
|
||||||
|
as it requires arguments to be matched against the format string.
|
||||||
|
The inlined syntax, where allowed, is simpler.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```
|
||||||
|
format!("{}", var);
|
||||||
|
format!("{v:?}", v = var);
|
||||||
|
format!("{0} {0}", var);
|
||||||
|
format!("{0:1$}", var, width);
|
||||||
|
format!("{:.*}", prec, var);
|
||||||
|
```
|
||||||
|
Use instead:
|
||||||
|
```
|
||||||
|
format!("{var}");
|
||||||
|
format!("{var:?}");
|
||||||
|
format!("{var} {var}");
|
||||||
|
format!("{var:width$}");
|
||||||
|
format!("{var:.prec$}");
|
||||||
|
```
|
||||||
|
|
||||||
|
### Known Problems
|
||||||
|
|
||||||
|
There may be a false positive if the format string is expanded from certain proc macros:
|
||||||
|
|
||||||
|
```
|
||||||
|
println!(indoc!("{}"), var);
|
||||||
|
```
|
||||||
|
|
||||||
|
If a format string contains a numbered argument that cannot be inlined
|
||||||
|
nothing will be suggested, e.g. `println!("{0}={1}", var, 1+2)`.
|
168
tests/ui/uninlined_format_args.fixed
Normal file
168
tests/ui/uninlined_format_args.fixed
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(clippy::eq_op)]
|
||||||
|
#![allow(clippy::format_in_format_args)]
|
||||||
|
#![allow(clippy::print_literal)]
|
||||||
|
#![allow(named_arguments_used_positionally)]
|
||||||
|
#![allow(unused_variables, unused_imports, unused_macros)]
|
||||||
|
#![warn(clippy::uninlined_format_args)]
|
||||||
|
#![feature(custom_inner_attributes)]
|
||||||
|
|
||||||
|
macro_rules! no_param_str {
|
||||||
|
() => {
|
||||||
|
"{}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! pass_through {
|
||||||
|
($expr:expr) => {
|
||||||
|
$expr
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! my_println {
|
||||||
|
($($args:tt),*) => {{
|
||||||
|
println!($($args),*)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! my_println_args {
|
||||||
|
($($args:tt),*) => {{
|
||||||
|
println!("foo: {}", format_args!($($args),*))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tester(fn_arg: i32) {
|
||||||
|
let local_i32 = 1;
|
||||||
|
let local_f64 = 2.0;
|
||||||
|
let local_opt: Option<i32> = Some(3);
|
||||||
|
let width = 4;
|
||||||
|
let prec = 5;
|
||||||
|
let val = 6;
|
||||||
|
|
||||||
|
// make sure this file hasn't been corrupted with tabs converted to spaces
|
||||||
|
// let _ = ' '; // <- this is a single tab character
|
||||||
|
let _: &[u8; 3] = b" "; // <- <tab><space><tab>
|
||||||
|
|
||||||
|
println!("val='{local_i32}'");
|
||||||
|
println!("val='{local_i32}'"); // 3 spaces
|
||||||
|
println!("val='{local_i32}'"); // tab
|
||||||
|
println!("val='{local_i32}'"); // space+tab
|
||||||
|
println!("val='{local_i32}'"); // tab+space
|
||||||
|
println!(
|
||||||
|
"val='{local_i32}'"
|
||||||
|
);
|
||||||
|
println!("{local_i32}");
|
||||||
|
println!("{fn_arg}");
|
||||||
|
println!("{local_i32:?}");
|
||||||
|
println!("{local_i32:#?}");
|
||||||
|
println!("{local_i32:4}");
|
||||||
|
println!("{local_i32:04}");
|
||||||
|
println!("{local_i32:<3}");
|
||||||
|
println!("{local_i32:#010x}");
|
||||||
|
println!("{local_f64:.1}");
|
||||||
|
println!("Hello {} is {local_f64:.local_i32$}", "x");
|
||||||
|
println!("Hello {local_i32} is {local_f64:.*}", 5);
|
||||||
|
println!("Hello {local_i32} is {local_f64:.*}", 5);
|
||||||
|
println!("{local_i32} {local_f64}");
|
||||||
|
println!("{local_i32}, {}", local_opt.unwrap());
|
||||||
|
println!("{val}");
|
||||||
|
println!("{val}");
|
||||||
|
println!("{} {1}", local_i32, 42);
|
||||||
|
println!("val='{local_i32}'");
|
||||||
|
println!("val='{local_i32}'");
|
||||||
|
println!("val='{local_i32}'");
|
||||||
|
println!("val='{fn_arg}'");
|
||||||
|
println!("{local_i32}");
|
||||||
|
println!("{local_i32:?}");
|
||||||
|
println!("{local_i32:#?}");
|
||||||
|
println!("{local_i32:04}");
|
||||||
|
println!("{local_i32:<3}");
|
||||||
|
println!("{local_i32:#010x}");
|
||||||
|
println!("{local_f64:.1}");
|
||||||
|
println!("{local_i32} {local_i32}");
|
||||||
|
println!("{local_f64} {local_i32} {local_i32} {local_f64}");
|
||||||
|
println!("{local_i32} {local_f64}");
|
||||||
|
println!("{local_f64} {local_i32}");
|
||||||
|
println!("{local_f64} {local_i32} {local_f64} {local_i32}");
|
||||||
|
println!("{1} {0}", "str", local_i32);
|
||||||
|
println!("{local_i32}");
|
||||||
|
println!("{local_i32:width$}");
|
||||||
|
println!("{local_i32:width$}");
|
||||||
|
println!("{local_i32:.prec$}");
|
||||||
|
println!("{local_i32:.prec$}");
|
||||||
|
println!("{val:val$}");
|
||||||
|
println!("{val:val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{val:val$.val$}");
|
||||||
|
println!("{width:width$}");
|
||||||
|
println!("{local_i32:width$}");
|
||||||
|
println!("{width:width$}");
|
||||||
|
println!("{local_i32:width$}");
|
||||||
|
println!("{prec:.prec$}");
|
||||||
|
println!("{local_i32:.prec$}");
|
||||||
|
println!("{prec:.prec$}");
|
||||||
|
println!("{local_i32:.prec$}");
|
||||||
|
println!("{width:width$.prec$}");
|
||||||
|
println!("{width:width$.prec$}");
|
||||||
|
println!("{local_f64:width$.prec$}");
|
||||||
|
println!("{local_f64:width$.prec$} {local_f64} {width} {prec}");
|
||||||
|
println!(
|
||||||
|
"{local_i32:width$.prec$} {local_i32:prec$.width$} {width:local_i32$.prec$} {width:prec$.local_i32$} {prec:local_i32$.width$} {prec:width$.local_i32$}",
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$} {3}",
|
||||||
|
local_i32,
|
||||||
|
width,
|
||||||
|
prec,
|
||||||
|
1 + 2
|
||||||
|
);
|
||||||
|
println!("Width = {local_i32}, value with width = {local_f64:local_i32$}");
|
||||||
|
println!("{local_i32:width$.prec$}");
|
||||||
|
println!("{width:width$.prec$}");
|
||||||
|
println!("{}", format!("{local_i32}"));
|
||||||
|
my_println!("{}", local_i32);
|
||||||
|
my_println_args!("{}", local_i32);
|
||||||
|
|
||||||
|
// these should NOT be modified by the lint
|
||||||
|
println!(concat!("nope ", "{}"), local_i32);
|
||||||
|
println!("val='{local_i32}'");
|
||||||
|
println!("val='{local_i32 }'");
|
||||||
|
println!("val='{local_i32 }'"); // with tab
|
||||||
|
println!("val='{local_i32\n}'");
|
||||||
|
println!("{}", usize::MAX);
|
||||||
|
println!("{}", local_opt.unwrap());
|
||||||
|
println!(
|
||||||
|
"val='{local_i32
|
||||||
|
}'"
|
||||||
|
);
|
||||||
|
println!(no_param_str!(), local_i32);
|
||||||
|
|
||||||
|
// FIXME: bugs!
|
||||||
|
// println!(pass_through!("foo={local_i32}"), local_i32 = local_i32);
|
||||||
|
// println!(pass_through!("foo={}"), local_i32);
|
||||||
|
// println!(indoc!("foo={}"), local_i32);
|
||||||
|
// printdoc!("foo={}", local_i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
tester(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _under_msrv() {
|
||||||
|
#![clippy::msrv = "1.57"]
|
||||||
|
let local_i32 = 1;
|
||||||
|
println!("don't expand='{}'", local_i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _meets_msrv() {
|
||||||
|
#![clippy::msrv = "1.58"]
|
||||||
|
let local_i32 = 1;
|
||||||
|
println!("expand='{local_i32}'");
|
||||||
|
}
|
171
tests/ui/uninlined_format_args.rs
Normal file
171
tests/ui/uninlined_format_args.rs
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(clippy::eq_op)]
|
||||||
|
#![allow(clippy::format_in_format_args)]
|
||||||
|
#![allow(clippy::print_literal)]
|
||||||
|
#![allow(named_arguments_used_positionally)]
|
||||||
|
#![allow(unused_variables, unused_imports, unused_macros)]
|
||||||
|
#![warn(clippy::uninlined_format_args)]
|
||||||
|
#![feature(custom_inner_attributes)]
|
||||||
|
|
||||||
|
macro_rules! no_param_str {
|
||||||
|
() => {
|
||||||
|
"{}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! pass_through {
|
||||||
|
($expr:expr) => {
|
||||||
|
$expr
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! my_println {
|
||||||
|
($($args:tt),*) => {{
|
||||||
|
println!($($args),*)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! my_println_args {
|
||||||
|
($($args:tt),*) => {{
|
||||||
|
println!("foo: {}", format_args!($($args),*))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tester(fn_arg: i32) {
|
||||||
|
let local_i32 = 1;
|
||||||
|
let local_f64 = 2.0;
|
||||||
|
let local_opt: Option<i32> = Some(3);
|
||||||
|
let width = 4;
|
||||||
|
let prec = 5;
|
||||||
|
let val = 6;
|
||||||
|
|
||||||
|
// make sure this file hasn't been corrupted with tabs converted to spaces
|
||||||
|
// let _ = ' '; // <- this is a single tab character
|
||||||
|
let _: &[u8; 3] = b" "; // <- <tab><space><tab>
|
||||||
|
|
||||||
|
println!("val='{}'", local_i32);
|
||||||
|
println!("val='{ }'", local_i32); // 3 spaces
|
||||||
|
println!("val='{ }'", local_i32); // tab
|
||||||
|
println!("val='{ }'", local_i32); // space+tab
|
||||||
|
println!("val='{ }'", local_i32); // tab+space
|
||||||
|
println!(
|
||||||
|
"val='{
|
||||||
|
}'",
|
||||||
|
local_i32
|
||||||
|
);
|
||||||
|
println!("{}", local_i32);
|
||||||
|
println!("{}", fn_arg);
|
||||||
|
println!("{:?}", local_i32);
|
||||||
|
println!("{:#?}", local_i32);
|
||||||
|
println!("{:4}", local_i32);
|
||||||
|
println!("{:04}", local_i32);
|
||||||
|
println!("{:<3}", local_i32);
|
||||||
|
println!("{:#010x}", local_i32);
|
||||||
|
println!("{:.1}", local_f64);
|
||||||
|
println!("Hello {} is {:.*}", "x", local_i32, local_f64);
|
||||||
|
println!("Hello {} is {:.*}", local_i32, 5, local_f64);
|
||||||
|
println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
|
||||||
|
println!("{} {}", local_i32, local_f64);
|
||||||
|
println!("{}, {}", local_i32, local_opt.unwrap());
|
||||||
|
println!("{}", val);
|
||||||
|
println!("{}", v = val);
|
||||||
|
println!("{} {1}", local_i32, 42);
|
||||||
|
println!("val='{\t }'", local_i32);
|
||||||
|
println!("val='{\n }'", local_i32);
|
||||||
|
println!("val='{local_i32}'", local_i32 = local_i32);
|
||||||
|
println!("val='{local_i32}'", local_i32 = fn_arg);
|
||||||
|
println!("{0}", local_i32);
|
||||||
|
println!("{0:?}", local_i32);
|
||||||
|
println!("{0:#?}", local_i32);
|
||||||
|
println!("{0:04}", local_i32);
|
||||||
|
println!("{0:<3}", local_i32);
|
||||||
|
println!("{0:#010x}", local_i32);
|
||||||
|
println!("{0:.1}", local_f64);
|
||||||
|
println!("{0} {0}", local_i32);
|
||||||
|
println!("{1} {} {0} {}", local_i32, local_f64);
|
||||||
|
println!("{0} {1}", local_i32, local_f64);
|
||||||
|
println!("{1} {0}", local_i32, local_f64);
|
||||||
|
println!("{1} {0} {1} {0}", local_i32, local_f64);
|
||||||
|
println!("{1} {0}", "str", local_i32);
|
||||||
|
println!("{v}", v = local_i32);
|
||||||
|
println!("{local_i32:0$}", width);
|
||||||
|
println!("{local_i32:w$}", w = width);
|
||||||
|
println!("{local_i32:.0$}", prec);
|
||||||
|
println!("{local_i32:.p$}", p = prec);
|
||||||
|
println!("{:0$}", v = val);
|
||||||
|
println!("{0:0$}", v = val);
|
||||||
|
println!("{:0$.0$}", v = val);
|
||||||
|
println!("{0:0$.0$}", v = val);
|
||||||
|
println!("{0:0$.v$}", v = val);
|
||||||
|
println!("{0:v$.0$}", v = val);
|
||||||
|
println!("{v:0$.0$}", v = val);
|
||||||
|
println!("{v:v$.0$}", v = val);
|
||||||
|
println!("{v:0$.v$}", v = val);
|
||||||
|
println!("{v:v$.v$}", v = val);
|
||||||
|
println!("{:0$}", width);
|
||||||
|
println!("{:1$}", local_i32, width);
|
||||||
|
println!("{:w$}", w = width);
|
||||||
|
println!("{:w$}", local_i32, w = width);
|
||||||
|
println!("{:.0$}", prec);
|
||||||
|
println!("{:.1$}", local_i32, prec);
|
||||||
|
println!("{:.p$}", p = prec);
|
||||||
|
println!("{:.p$}", local_i32, p = prec);
|
||||||
|
println!("{:0$.1$}", width, prec);
|
||||||
|
println!("{:0$.w$}", width, w = prec);
|
||||||
|
println!("{:1$.2$}", local_f64, width, prec);
|
||||||
|
println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec);
|
||||||
|
println!(
|
||||||
|
"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}",
|
||||||
|
local_i32, width, prec,
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$} {3}",
|
||||||
|
local_i32,
|
||||||
|
width,
|
||||||
|
prec,
|
||||||
|
1 + 2
|
||||||
|
);
|
||||||
|
println!("Width = {}, value with width = {:0$}", local_i32, local_f64);
|
||||||
|
println!("{:w$.p$}", local_i32, w = width, p = prec);
|
||||||
|
println!("{:w$.p$}", w = width, p = prec);
|
||||||
|
println!("{}", format!("{}", local_i32));
|
||||||
|
my_println!("{}", local_i32);
|
||||||
|
my_println_args!("{}", local_i32);
|
||||||
|
|
||||||
|
// these should NOT be modified by the lint
|
||||||
|
println!(concat!("nope ", "{}"), local_i32);
|
||||||
|
println!("val='{local_i32}'");
|
||||||
|
println!("val='{local_i32 }'");
|
||||||
|
println!("val='{local_i32 }'"); // with tab
|
||||||
|
println!("val='{local_i32\n}'");
|
||||||
|
println!("{}", usize::MAX);
|
||||||
|
println!("{}", local_opt.unwrap());
|
||||||
|
println!(
|
||||||
|
"val='{local_i32
|
||||||
|
}'"
|
||||||
|
);
|
||||||
|
println!(no_param_str!(), local_i32);
|
||||||
|
|
||||||
|
// FIXME: bugs!
|
||||||
|
// println!(pass_through!("foo={local_i32}"), local_i32 = local_i32);
|
||||||
|
// println!(pass_through!("foo={}"), local_i32);
|
||||||
|
// println!(indoc!("foo={}"), local_i32);
|
||||||
|
// printdoc!("foo={}", local_i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
tester(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _under_msrv() {
|
||||||
|
#![clippy::msrv = "1.57"]
|
||||||
|
let local_i32 = 1;
|
||||||
|
println!("don't expand='{}'", local_i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _meets_msrv() {
|
||||||
|
#![clippy::msrv = "1.58"]
|
||||||
|
let local_i32 = 1;
|
||||||
|
println!("expand='{}'", local_i32);
|
||||||
|
}
|
866
tests/ui/uninlined_format_args.stderr
Normal file
866
tests/ui/uninlined_format_args.stderr
Normal file
|
@ -0,0 +1,866 @@
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:47:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{}'", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::uninlined-format-args` implied by `-D warnings`
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{}'", local_i32);
|
||||||
|
LL + println!("val='{local_i32}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:48:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{ }'", local_i32); // 3 spaces
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{ }'", local_i32); // 3 spaces
|
||||||
|
LL + println!("val='{local_i32}'"); // 3 spaces
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:49:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{ }'", local_i32); // tab
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{ }'", local_i32); // tab
|
||||||
|
LL + println!("val='{local_i32}'"); // tab
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:50:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{ }'", local_i32); // space+tab
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{ }'", local_i32); // space+tab
|
||||||
|
LL + println!("val='{local_i32}'"); // space+tab
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:51:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{ }'", local_i32); // tab+space
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{ }'", local_i32); // tab+space
|
||||||
|
LL + println!("val='{local_i32}'"); // tab+space
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:52:5
|
||||||
|
|
|
||||||
|
LL | / println!(
|
||||||
|
LL | | "val='{
|
||||||
|
LL | | }'",
|
||||||
|
LL | | local_i32
|
||||||
|
LL | | );
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - "val='{
|
||||||
|
LL + "val='{local_i32}'"
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:57:5
|
||||||
|
|
|
||||||
|
LL | println!("{}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{}", local_i32);
|
||||||
|
LL + println!("{local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:58:5
|
||||||
|
|
|
||||||
|
LL | println!("{}", fn_arg);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{}", fn_arg);
|
||||||
|
LL + println!("{fn_arg}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:59:5
|
||||||
|
|
|
||||||
|
LL | println!("{:?}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:?}", local_i32);
|
||||||
|
LL + println!("{local_i32:?}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:60:5
|
||||||
|
|
|
||||||
|
LL | println!("{:#?}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:#?}", local_i32);
|
||||||
|
LL + println!("{local_i32:#?}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:61:5
|
||||||
|
|
|
||||||
|
LL | println!("{:4}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:4}", local_i32);
|
||||||
|
LL + println!("{local_i32:4}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:62:5
|
||||||
|
|
|
||||||
|
LL | println!("{:04}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:04}", local_i32);
|
||||||
|
LL + println!("{local_i32:04}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:63:5
|
||||||
|
|
|
||||||
|
LL | println!("{:<3}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:<3}", local_i32);
|
||||||
|
LL + println!("{local_i32:<3}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:64:5
|
||||||
|
|
|
||||||
|
LL | println!("{:#010x}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:#010x}", local_i32);
|
||||||
|
LL + println!("{local_i32:#010x}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:65:5
|
||||||
|
|
|
||||||
|
LL | println!("{:.1}", local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:.1}", local_f64);
|
||||||
|
LL + println!("{local_f64:.1}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:66:5
|
||||||
|
|
|
||||||
|
LL | println!("Hello {} is {:.*}", "x", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("Hello {} is {:.*}", "x", local_i32, local_f64);
|
||||||
|
LL + println!("Hello {} is {local_f64:.local_i32$}", "x");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:67:5
|
||||||
|
|
|
||||||
|
LL | println!("Hello {} is {:.*}", local_i32, 5, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("Hello {} is {:.*}", local_i32, 5, local_f64);
|
||||||
|
LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:68:5
|
||||||
|
|
|
||||||
|
LL | println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("Hello {} is {2:.*}", local_i32, 5, local_f64);
|
||||||
|
LL + println!("Hello {local_i32} is {local_f64:.*}", 5);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:69:5
|
||||||
|
|
|
||||||
|
LL | println!("{} {}", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{} {}", local_i32, local_f64);
|
||||||
|
LL + println!("{local_i32} {local_f64}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:70:5
|
||||||
|
|
|
||||||
|
LL | println!("{}, {}", local_i32, local_opt.unwrap());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{}, {}", local_i32, local_opt.unwrap());
|
||||||
|
LL + println!("{local_i32}, {}", local_opt.unwrap());
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:71:5
|
||||||
|
|
|
||||||
|
LL | println!("{}", val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{}", val);
|
||||||
|
LL + println!("{val}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:72:5
|
||||||
|
|
|
||||||
|
LL | println!("{}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{}", v = val);
|
||||||
|
LL + println!("{val}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:74:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{/t }'", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{/t }'", local_i32);
|
||||||
|
LL + println!("val='{local_i32}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:75:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{/n }'", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{/n }'", local_i32);
|
||||||
|
LL + println!("val='{local_i32}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:76:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{local_i32}'", local_i32 = local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{local_i32}'", local_i32 = local_i32);
|
||||||
|
LL + println!("val='{local_i32}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:77:5
|
||||||
|
|
|
||||||
|
LL | println!("val='{local_i32}'", local_i32 = fn_arg);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("val='{local_i32}'", local_i32 = fn_arg);
|
||||||
|
LL + println!("val='{fn_arg}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:78:5
|
||||||
|
|
|
||||||
|
LL | println!("{0}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0}", local_i32);
|
||||||
|
LL + println!("{local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:79:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:?}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:?}", local_i32);
|
||||||
|
LL + println!("{local_i32:?}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:80:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:#?}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:#?}", local_i32);
|
||||||
|
LL + println!("{local_i32:#?}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:81:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:04}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:04}", local_i32);
|
||||||
|
LL + println!("{local_i32:04}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:82:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:<3}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:<3}", local_i32);
|
||||||
|
LL + println!("{local_i32:<3}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:83:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:#010x}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:#010x}", local_i32);
|
||||||
|
LL + println!("{local_i32:#010x}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:84:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:.1}", local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:.1}", local_f64);
|
||||||
|
LL + println!("{local_f64:.1}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:85:5
|
||||||
|
|
|
||||||
|
LL | println!("{0} {0}", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0} {0}", local_i32);
|
||||||
|
LL + println!("{local_i32} {local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:86:5
|
||||||
|
|
|
||||||
|
LL | println!("{1} {} {0} {}", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{1} {} {0} {}", local_i32, local_f64);
|
||||||
|
LL + println!("{local_f64} {local_i32} {local_i32} {local_f64}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:87:5
|
||||||
|
|
|
||||||
|
LL | println!("{0} {1}", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0} {1}", local_i32, local_f64);
|
||||||
|
LL + println!("{local_i32} {local_f64}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:88:5
|
||||||
|
|
|
||||||
|
LL | println!("{1} {0}", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{1} {0}", local_i32, local_f64);
|
||||||
|
LL + println!("{local_f64} {local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:89:5
|
||||||
|
|
|
||||||
|
LL | println!("{1} {0} {1} {0}", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{1} {0} {1} {0}", local_i32, local_f64);
|
||||||
|
LL + println!("{local_f64} {local_i32} {local_f64} {local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:91:5
|
||||||
|
|
|
||||||
|
LL | println!("{v}", v = local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{v}", v = local_i32);
|
||||||
|
LL + println!("{local_i32}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:92:5
|
||||||
|
|
|
||||||
|
LL | println!("{local_i32:0$}", width);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{local_i32:0$}", width);
|
||||||
|
LL + println!("{local_i32:width$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:93:5
|
||||||
|
|
|
||||||
|
LL | println!("{local_i32:w$}", w = width);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{local_i32:w$}", w = width);
|
||||||
|
LL + println!("{local_i32:width$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:94:5
|
||||||
|
|
|
||||||
|
LL | println!("{local_i32:.0$}", prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{local_i32:.0$}", prec);
|
||||||
|
LL + println!("{local_i32:.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:95:5
|
||||||
|
|
|
||||||
|
LL | println!("{local_i32:.p$}", p = prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{local_i32:.p$}", p = prec);
|
||||||
|
LL + println!("{local_i32:.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:96:5
|
||||||
|
|
|
||||||
|
LL | println!("{:0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:0$}", v = val);
|
||||||
|
LL + println!("{val:val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:97:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:0$}", v = val);
|
||||||
|
LL + println!("{val:val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:98:5
|
||||||
|
|
|
||||||
|
LL | println!("{:0$.0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:0$.0$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:99:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:0$.0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:0$.0$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:100:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:0$.v$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:0$.v$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:101:5
|
||||||
|
|
|
||||||
|
LL | println!("{0:v$.0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{0:v$.0$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:102:5
|
||||||
|
|
|
||||||
|
LL | println!("{v:0$.0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{v:0$.0$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:103:5
|
||||||
|
|
|
||||||
|
LL | println!("{v:v$.0$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{v:v$.0$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:104:5
|
||||||
|
|
|
||||||
|
LL | println!("{v:0$.v$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{v:0$.v$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:105:5
|
||||||
|
|
|
||||||
|
LL | println!("{v:v$.v$}", v = val);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{v:v$.v$}", v = val);
|
||||||
|
LL + println!("{val:val$.val$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:106:5
|
||||||
|
|
|
||||||
|
LL | println!("{:0$}", width);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:0$}", width);
|
||||||
|
LL + println!("{width:width$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:107:5
|
||||||
|
|
|
||||||
|
LL | println!("{:1$}", local_i32, width);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:1$}", local_i32, width);
|
||||||
|
LL + println!("{local_i32:width$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:108:5
|
||||||
|
|
|
||||||
|
LL | println!("{:w$}", w = width);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:w$}", w = width);
|
||||||
|
LL + println!("{width:width$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:109:5
|
||||||
|
|
|
||||||
|
LL | println!("{:w$}", local_i32, w = width);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:w$}", local_i32, w = width);
|
||||||
|
LL + println!("{local_i32:width$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:110:5
|
||||||
|
|
|
||||||
|
LL | println!("{:.0$}", prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:.0$}", prec);
|
||||||
|
LL + println!("{prec:.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:111:5
|
||||||
|
|
|
||||||
|
LL | println!("{:.1$}", local_i32, prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:.1$}", local_i32, prec);
|
||||||
|
LL + println!("{local_i32:.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:112:5
|
||||||
|
|
|
||||||
|
LL | println!("{:.p$}", p = prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:.p$}", p = prec);
|
||||||
|
LL + println!("{prec:.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:113:5
|
||||||
|
|
|
||||||
|
LL | println!("{:.p$}", local_i32, p = prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:.p$}", local_i32, p = prec);
|
||||||
|
LL + println!("{local_i32:.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:114:5
|
||||||
|
|
|
||||||
|
LL | println!("{:0$.1$}", width, prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:0$.1$}", width, prec);
|
||||||
|
LL + println!("{width:width$.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:115:5
|
||||||
|
|
|
||||||
|
LL | println!("{:0$.w$}", width, w = prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:0$.w$}", width, w = prec);
|
||||||
|
LL + println!("{width:width$.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:116:5
|
||||||
|
|
|
||||||
|
LL | println!("{:1$.2$}", local_f64, width, prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:1$.2$}", local_f64, width, prec);
|
||||||
|
LL + println!("{local_f64:width$.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:117:5
|
||||||
|
|
|
||||||
|
LL | println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:1$.2$} {0} {1} {2}", local_f64, width, prec);
|
||||||
|
LL + println!("{local_f64:width$.prec$} {local_f64} {width} {prec}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:118:5
|
||||||
|
|
|
||||||
|
LL | / println!(
|
||||||
|
LL | | "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}",
|
||||||
|
LL | | local_i32, width, prec,
|
||||||
|
LL | | );
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL ~ "{local_i32:width$.prec$} {local_i32:prec$.width$} {width:local_i32$.prec$} {width:prec$.local_i32$} {prec:local_i32$.width$} {prec:width$.local_i32$}", width, prec,
|
||||||
|
LL ~ "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", width, prec,
|
||||||
|
LL ~ "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", width, prec,
|
||||||
|
LL ~ "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", width, prec,
|
||||||
|
LL ~ "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}", width, prec,
|
||||||
|
LL ~ "{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}",
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:129:5
|
||||||
|
|
|
||||||
|
LL | println!("Width = {}, value with width = {:0$}", local_i32, local_f64);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("Width = {}, value with width = {:0$}", local_i32, local_f64);
|
||||||
|
LL + println!("Width = {local_i32}, value with width = {local_f64:local_i32$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:130:5
|
||||||
|
|
|
||||||
|
LL | println!("{:w$.p$}", local_i32, w = width, p = prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:w$.p$}", local_i32, w = width, p = prec);
|
||||||
|
LL + println!("{local_i32:width$.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:131:5
|
||||||
|
|
|
||||||
|
LL | println!("{:w$.p$}", w = width, p = prec);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{:w$.p$}", w = width, p = prec);
|
||||||
|
LL + println!("{width:width$.prec$}");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:132:20
|
||||||
|
|
|
||||||
|
LL | println!("{}", format!("{}", local_i32));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("{}", format!("{}", local_i32));
|
||||||
|
LL + println!("{}", format!("{local_i32}"));
|
||||||
|
|
|
||||||
|
|
||||||
|
error: variables can be used directly in the `format!` string
|
||||||
|
--> $DIR/uninlined_format_args.rs:170:5
|
||||||
|
|
|
||||||
|
LL | println!("expand='{}'", local_i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: change this to
|
||||||
|
|
|
||||||
|
LL - println!("expand='{}'", local_i32);
|
||||||
|
LL + println!("expand='{local_i32}'");
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 71 previous errors
|
||||||
|
|
Loading…
Add table
Reference in a new issue