You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
impl<'a>IrcCommand<'a>{pubfnnew(cmd:&'a[u8]) -> IrcCommand<'a>{if cmd.len() == 3 && match(cmd[0], cmd[1], cmd[2]){(b'0'...b'9',b'0'...b'9',b'0'...b'9') => {// TODO switch to TryFrom/TryInto once those are stable. (rust-lang/rust#33417)returnIrcCommand::Numeric(Numeric::new(array_ref![cmd,0,3]));},
_ => false}{unreachable!()}else{IrcCommand::Stringy(Stringy(cmd))}}}
With generic let, I'd be able to write instead:
impl<'a>IrcCommand<'a>{pubfnnew(cmd:&'a[u8]) -> IrcCommand<'a>{if cmd.len() == 3 && let(b'0'...b'9',b'0'...b'9',b'0'...b'9') = (cmd[0], cmd[1], cmd[2]){// TODO switch to TryFrom/TryInto once those are stable. (rust-lang/rust#33417)IrcCommand::Numeric(Numeric::new(array_ref![cmd,0,3]))}else{IrcCommand::Stringy(Stringy(cmd))}}}
Generic let works as follows:
let pattern = value becomes an expression, its return value is true if the pattern matches (always true for irrefutable patterns), false if it doesn't.
It binds the names when it matches, and only when it matches, so the compiler needs to check the true path for the names, and the false path for the lack of the names.
In the case of irrefutable patterns, the result is always true, so this is always valid:
let x = 1u8;// this path is always trueprintln!("{}", x);
Using a refutable pattern in that let would cause the compiler to error.
whilelet data = do_some_io()? {// while we have linesprintln!("{}", data);// print the lines}
ifletSome(x @ '0'...'9' | x @ 'A'...'F' | x @ 'a'...'f') = v {println!("got hex: {}", x);}// ORif(let Some(x @ '0'...'9') = v) || (let Some(x @ 'A'...'F') = v) || let Some(x @ 'a'...'f') = v {// note that "x" must appear in every || case.println!("got hex: {}", x);}// (with a strong preference for the former, ofc, as the latter needs parens)
Corner cases:
let would have the same precedence it does today. this means in patterns, you'd have to write if (let x = y) && ... (parens required except as the last expr). but it does give backwards compatibility with basically anything you can think of: if let true = p && q {, etc would still work.
I can't think of any other corner cases because every corner case I can think of is either an explicit consequence of this feature (e.g. irrefutable patterns in if-let and while-let, which still give a compiler warning as proposed in RFC: Allow Irrefutable Patterns in if-let and while-let statements #2086 as the compiler can guarantee it's always true and while true {} gives a warning), or it doesn't work and still won't work even with this feature.
I'm tired of writing code like the following:
With generic let, I'd be able to write instead:
Generic let works as follows:
let pattern = valuebecomes an expression, its return value istrueif the pattern matches (always true for irrefutable patterns),falseif it doesn't.It binds the names when it matches, and only when it matches, so the compiler needs to check the true path for the names, and the false path for the lack of the names.
In the case of irrefutable patterns, the result is always true, so this is always valid:
Using a refutable pattern in that
letwould cause the compiler to error.Other cases where this is nice:
#2086 #935 etc.
Corner cases:
letwould have the same precedence it does today. this means in patterns, you'd have to writeif (let x = y) && ...(parens required except as the last expr). but it does give backwards compatibility with basically anything you can think of:if let true = p && q {, etc would still work.while true {}gives a warning), or it doesn't work and still won't work even with this feature.