mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 07:04:18 +00:00
Auto merge of #10573 - Alexendoo:print-literal-file-macro, r=Jarcho
Ignore `file!()` macro in `print_literal`, `write_literal` changelog: [`print_literal`], [`write_literal`]: Ignore the `file!()` macro `file!()` expands to a string literal with its span set to that of the `file!()` callsite, but isn't marked as coming from an expansion. To fix this we make sure we actually find a string/char literal instead of assuming it's one and slicing It would also ignore any other macros that result in the same situation, but that shouldn't be common as `proc_macro::Span::call_site()` returns a span that is marked as from expansion Fixes #10544
This commit is contained in:
commit
d43714a101
3 changed files with 15 additions and 5 deletions
|
@ -463,12 +463,18 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
|
|||
&& let Some(value_string) = snippet_opt(cx, arg.expr.span)
|
||||
{
|
||||
let (replacement, replace_raw) = match lit.kind {
|
||||
LitKind::Str | LitKind::StrRaw(_) => extract_str_literal(&value_string),
|
||||
LitKind::Str | LitKind::StrRaw(_) => match extract_str_literal(&value_string) {
|
||||
Some(extracted) => extracted,
|
||||
None => return,
|
||||
},
|
||||
LitKind::Char => (
|
||||
match lit.symbol.as_str() {
|
||||
"\"" => "\\\"",
|
||||
"\\'" => "'",
|
||||
_ => &value_string[1..value_string.len() - 1],
|
||||
_ => match value_string.strip_prefix('\'').and_then(|s| s.strip_suffix('\'')) {
|
||||
Some(stripped) => stripped,
|
||||
None => return,
|
||||
},
|
||||
}
|
||||
.to_string(),
|
||||
false,
|
||||
|
@ -533,13 +539,13 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
|
|||
/// `r#"a"#` -> (`a`, true)
|
||||
///
|
||||
/// `"b"` -> (`b`, false)
|
||||
fn extract_str_literal(literal: &str) -> (String, bool) {
|
||||
fn extract_str_literal(literal: &str) -> Option<(String, bool)> {
|
||||
let (literal, raw) = match literal.strip_prefix('r') {
|
||||
Some(stripped) => (stripped.trim_matches('#'), true),
|
||||
None => (literal, false),
|
||||
};
|
||||
|
||||
(literal[1..literal.len() - 1].to_string(), raw)
|
||||
Some((literal.strip_prefix('"')?.strip_suffix('"')?.to_string(), raw))
|
||||
}
|
||||
|
||||
enum UnescapeErr {
|
||||
|
|
|
@ -63,7 +63,7 @@ fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Gro
|
|||
/// Token used to escape the following token from the macro's span rules.
|
||||
const ESCAPE_CHAR: char = '$';
|
||||
|
||||
/// Takes a single token followed by a sequence tokens. Returns the sequence of tokens with their
|
||||
/// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their
|
||||
/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`.
|
||||
#[proc_macro]
|
||||
pub fn with_span(input: TokenStream) -> TokenStream {
|
||||
|
|
|
@ -38,4 +38,8 @@ fn main() {
|
|||
// named args shouldn't change anything either
|
||||
println!("{foo} {bar}", foo = "hello", bar = "world");
|
||||
println!("{bar} {foo}", foo = "hello", bar = "world");
|
||||
|
||||
// The string literal from `file!()` has a callsite span that isn't marked as coming from an
|
||||
// expansion
|
||||
println!("file: {}", file!());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue