Topic : Doing match
on a const
variable
Suggestion : Let rustc allow unresolved symbols inside match arms that don't match the const
variable.
Example-1 : All statements of every match arm don't contain any unresolved symbols
- The program below compiles successfully.
- Every match arm doesn't contain any unresolved symbols.
- Compiled in
Debug
mode: binary for every match arm is generated. - Compiled in
Release
mode: binary for only the matching arm is generated.
// Godbolt link: https://godbolt.org/z/mnAuV_
enum Menu {
SANDWICH,
SPAGHETTI,
SALAD,
UNDEFINED,
}
const what : Menu = Menu::SANDWICH;
pub fn mymenu() {
match what {
Menu::SANDWICH => println!("SANDWICH!"),
Menu::SPAGHETTI => println!("SPAGHETTI!"),
Menu::SALAD => println!("SALAD!"),
Menu::UNDEFINED => println!("NO LUNCH!")
}
}
Example-2 : Statements of match arms may contain unresolved symbols (due to conditional compilation)
- There is a match statement on a
const
variable in themain
function. - Some functions(
make_sandwich
,make_spaghetti
,make_salad
,no_lunch
) are conditionally compiled in order to optimize program binary size. - The program below does not compile, since invocations to conditionally compiled functions become unresolved symbols inside match arms that don't match the
const
variable. (ex.error[E0425]: cannot find function 'make_sandwich' in this scope
)
pub enum Menu {
SANDWICH,
SPAGHETTI,
SALAD,
UNDEFINED,
}
cfg_if::cfg_if! {
if #[cfg(all(
feature="SANDWICH",
not(feature="SPAGHETTI"),
not(feature="SALAD")
))] {
const mylunch : Menu = Menu::SANDWICH;
pub fn make_sandwich() {
println!("MAKE SANDWICH!");
}
}
else if #[cfg(all(
not(feature="SANDWICH"),
feature="SPAGHETTI",
not(feature="SALAD")
))] {
const mylunch : Menu = Menu::SPAGHETTI;
pub fn make_spaghetti() {
println!("MAKE SPAGHETTI!");
}
}
else if #[cfg(all(
not(feature="SANDWICH"),
not(feature="SPAGHETTI"),
feature="SALAD")
)] {
const mylunch : Menu = Menu::SALAD;
pub fn make_salad() {
println!("MAKE SALAD!");
}
}
else {
const mylunch : Menu = Menu::UNDEFINED;
pub fn no_lunch() {
println!("NO LUNCH FOR TODAY!");
}
}
}
fn main() {
// the if-statement compiles only when: feature="SANDWICH"
if let Menu::SANDWICH = mylunch {
make_sandwich();
}
// the following match statement does not compile
match mylunch {
Menu::SANDWICH => make_sandwich(),
Menu::SPAGHETTI => make_spaghetti(),
Menu::SALAD => make_salad(),
Menu::UNDEFINED => no_lunch(),
}
}
Regarding the suggestion..
-
Expected benefit
Allow programmers to write conditionally compiled programs more elegantly (without having to write#cfg(~)
all over the place) -
Doubts
Is conditional compilation on functions really helpful in optimizing program binary size? (: Is writing code like Example-2 even necessary to optimize program binary size?)
It's a very rough idea, and I don't yet have an idea on the implementation side.. But I would really appreciate any feedback on this direction!