println! error: expected a literal / format argument must be a string literal

rust string literal
rust string interpolation
rust const string literal
rust println macro
rust multiline string
rust print variable
rust format string variable
rust format lowercase

This extremely simple Rust program:

fn main() {
    let c = "hello";
    println!(c);
}

throws the following compile-time error:

error: expected a literal
 --> src/main.rs:3:14
  |
3 |     println!(c);
  |              ^

In previous versions of Rust, the error said:

error: format argument must be a string literal.
     println!(c);
              ^

Replacing the program with:

fn main() {
    println!("Hello");    
}

Works fine.

The meaning of this error isn't clear to me and a Google search hasn't really shed light on it. Why does passing c to the println! macro cause a compile time error? This seems like quite unusual behaviour.


TL;DR If you don't care why and just want to fix it, see the sibling answer.


The reason that

fn main() {
    let c = "hello";
    println!(c);
}

Cannot work is because the println! macro looks at the string at compile time and verifies that the arguments and argument specifiers match in amount and type (this is a very good thing!). At this point in time, during macro evaluation, it's not possible to tell that c came from a literal or a function or what have you.

Here's an example of what the macro expands out to:

let c = "hello";
match (&c,) {
    (__arg0,) => {
        #[inline]
        #[allow(dead_code)]
        static __STATIC_FMTSTR: &'static [&'static str] = &[""];
        ::std::io::stdio::println_args(&::std::fmt::Arguments::new(
            __STATIC_FMTSTR,
            &[::std::fmt::argument(::std::fmt::Show::fmt, __arg0)]
        ))
    }
};

I don't think that it's actually impossible for the compiler to figure this out, but it would probably take a lot of work (potentially for little gain). Macros operate on portions of the AST, which I assume only has type information. To work in this case, the AST would have to include the source of the identifier and enough information to determine it's "safe". In addition, it might interact poorly with type inference - you'd want to know the type before it's been picked yet!

The error message asks for a "string literal". There's a SO question about what that means, which links to the Wikipedia entry:

a literal is a notation for representing a fixed value in source code

"foo" is a string literal, 8 is a numeric literal. let s = "foo" is a statement that assigns the value of a string literal to an identifier (variable). println!(s) is a statement that provides an identifier to the macro.

Argument must be a string literal What, why? - help, String literal, What is this error all about: use std::process::Command; fn main() { let output = Command::new("pwd") .output() .expect("failed to  The following all compile and run for example: println!(0); writeln!(b, true); println!('a'); I would expect them to produce "error: format argument must be a string literal." like print!(0); does. This is because they use things like co


This should work:

fn main() {
    let c = "hello";
    println!("{}", c);
}

The string "{}" is a template where {} will be replaced by the next argument passed to println!.

How can i solve: format argument must be a string literal - help, error: format argument must be a string literal --> play.rs:13:27 | 13 println! , write! , writeln! , format! , etc. macros must be a literal format string. error: format argument must be a string literal. println!(c); ^ remplaçant le programme par: fn main() { println!("Hello"); } fonctionne très bien. le sens de cette erreur n'est pas clair pour moi et une recherche sur Google n'a pas vraiment fait la lumière sur elle. Pourquoi passer c à la macro println! de causer une erreur de temps de


If your format string will be reused only a moderate number of times, and only some variable data will be changed, then a small function may be a better option than a macro:

fn pr(x: &str) {
    println!("Some stuff that will always repeat, something variable: {}", x);
}

pr("I am the variable data");

Outputs

Some stuff that will always repeat, something variable: I am the variable data

println!, eprintln! and writeln! accept other literals not just format , error: error: expected a literal --> src/main.rs:3:14 | 3 | println!(c); | ^ In previous versions of Rust, the error said: error: format argument must be a string literal. Rust concat! expects a literal as in a symbol literal (like true, 32 'c', "string") since it works in earliest parts of compile stages.During that time runtime value of types aren't resolved yet.


If you really want to define the first argument of println! in one place, I found a way to do it. You can use a macro:

macro_rules! hello {() => ("hello")};
println!(hello!());

Doesn't look too useful here, but I wanted to use the same formatting in a few places, and in this case the method was very helpful:

macro_rules! cell_format {() => ("{:<10}")};  // Pads with spaces on right
                                              // to fill up 10 characters
println!(cell_format!(), "Foo");
println!(cell_format!(), 456);

The macro saved me from having to duplicate the formatting option in my code.

You could also, obviously, make the macro more fancy and take arguments if necessary to print different things with different arguments.

Rust is defying the logic part of my brain when it comes to the , I would expect them to produce "error: format argument must be a string literal." like print!(0); does. This is because they use things like  error: se espera que un argumento literal / formato debe ser una cadena literal Este progtwig extremadamente simple de Rust: fn main() { let c = "hello"; println!(c); }


fomat_macros - Rust, This extremely simple Rust program: fn main() { let c = "hello"; println!(c); } throws the following compile-time error: error: expected a literal  This is a formatted print. Each set of {} signals that the variables following this string literal will be put into the string. This will print "The value of our variable is: Hello I'm a str". If we were to simply write println! (str), we would get a compile error due to type mismatch.


rust-lang/rust, If I run this, I get - error: expected a literal It is a non-mutable variable, so the compiler should know that whatever is passed into println is definitely a string! the println! macro can't see inside the string, so it can't figure out what formatting code to fn main() { let x = 3; ::io::_print(::std::fmt::Arguments::new_v1_formatted(​  The first argument format! receives is a format string. This must be a string literal. The power of the formatting string is in the {}s contained. Additional parameters passed to format! replace the {}s within the formatting string in the order given unless named or positional parameters are used; see std::fmt for more information.


Each thing could be either a string literal, something inside brackets ( () , [] or {} ) or a There has to be no separator (like a comma) between those things. If you only want to print a single argument with a custom format parameters, you If you hit the error about recursion depth, which occurs when you try to print more​  From these, you can see that the first argument is a format string. required by the compiler for this to be a string literal; it cannot be a variable passed in (in order to perform validity checking). The compiler will then parse the format string and determine if the list of arguments