Rust: avec #! [no_std] activé, 'panic! ("{{}}")' et 'panic! ("{{}}",)' sont différents

Créé le 7 févr. 2018  ·  1Commentaire  ·  Source: rust-lang/rust

Découvert en essayant d'implémenter des correctifs pour # 46241. Risque de compatibilité de retour possible pour la prise en charge de la virgule de fin, mais j'espère que non.

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! */);
}

Pouvez-vous repérer la différence?


La définition dans std ne prend pas en charge les virgules de fin après un seul littéral de chaîne:

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

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

La définition dans core accepte une virgule à la fin, mais suit un chemin de code complètement différent avec une sémantique potentiellement différente.

#![no_std]

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

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

~ Fortuitement, il me semble que la définition de libcore produit un comportement équivalent pour panic!(<literal>,) et panic!(<literal>) dans tous les cas où les deux formes se compilent avec succès, ce qui signifie qu'il devrait être prudent de changer panic!(<literal>,) se comporter comme panic!(<literal>) . ~

A-macros C-bug T-libs

Commentaire le plus utile

Merde. J'ai trouvé un exemple du genre de risque de rétrocompatibilité dont je parlais.

Dans la rouille d'aujourd'hui, les deux programmes suivants sont différents:

#![no_std]

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

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

>Tous les commentaires

Merde. J'ai trouvé un exemple du genre de risque de rétrocompatibilité dont je parlais.

Dans la rouille d'aujourd'hui, les deux programmes suivants sont différents:

#![no_std]

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

fn main() {
    panic!("{{}}",);  // panics with "{}"
}
Cette page vous a été utile?
0 / 5 - 0 notes