Rust: com #! [no_std] habilitado, 'panic! ("{{}}")' e 'panic! ("{{}}",)' são diferentes

Criado em 7 fev. 2018  ·  1Comentário  ·  Fonte: rust-lang/rust

Descoberto ao tentar implementar correções para # 46241. Possível perigo de compatibilidade traseira para suporte de vírgula à direita, mas espero que não.

libstd / macros.rs

macro_rules! panic {
    () => (/* default message */);
    ($msg:expr) => (/* use msg as literal */);
    ($fmt:expr, $($arg:tt)+) => (/* use format_args! */);
}

libcore / macros.rs

macro_rules! panic {
    () => (/* default message */);
    ($msg:expr) => (/* use msg as literal */);
    ($fmt:expr, $($arg:tt)*) => (/* use format_args! */);
}

Você pode ver a diferença?


A definição em std não suporta vírgulas finais após um único literal de string:

fn main() {
    panic!("a");
    panic!("a",); //~ ERROR unexpected end of macro invocation

    panic!("{}");
    panic!("{}",); //~ ERROR unexpected end of macro invocation
}

A definição no núcleo aceita uma vírgula final, mas segue um caminho de código completamente diferente com semântica potencialmente diferente.

#![no_std]

fn main() {
    panic!("a");
    panic!("a",);

    panic!("{}");
    panic!("{}",); //~ ERROR 1 positional argument in format string, but no arguments were given
}

~ Por acaso, parece-me que a definição da libcore produz um comportamento equivalente para panic!(<literal>,) e panic!(<literal>) em todos os casos em que ambas as formas compilam com sucesso, o que significa que deve ser seguro alterar panic!(<literal>,) se comportar como panic!(<literal>) . ~

A-macros C-bug T-libs

Comentários muito úteis

Porcaria. Encontrei um exemplo do tipo de perigo back-compat de que estava falando.

Na ferrugem de hoje, os dois programas a seguir são diferentes:

#![no_std]

fn main() {
    panic!("{{}}");  // panics with "{{}}"
}
#![no_std]

fn main() {
    panic!("{{}}",);  // panics with "{}"
}

>Todos os comentários

Porcaria. Encontrei um exemplo do tipo de perigo back-compat de que estava falando.

Na ferrugem de hoje, os dois programas a seguir são diferentes:

#![no_std]

fn main() {
    panic!("{{}}");  // panics with "{{}}"
}
#![no_std]

fn main() {
    panic!("{{}}",);  // panics with "{}"
}
Esta página foi útil?
0 / 5 - 0 avaliações