I tried this code:
with expansion:
https://gist.github.com/bkchr/92b754ec82efcc115637ab5533e79ff4
use futures::{future, select}; // 0.3.6
pub enum Foo {
Bar,
Baz,
}
/* this function does produce warnings
fn match_foo(foo: Foo) -> i32 {
match foo {
x => 1,
_ => unreachable!("why you do this rust?"),
}
}
*/
pub async fn foo(foo: Foo) {
let mut a = future::ready(4);
use Foo::Bar;
let res = select! {
// but this doesn't
a_res = a => match foo {
Bar => 1,
_ => 4,
_ => unreachable!("why you do this rust?"),
},
};
assert_eq!(res, 4, "oh");
}
fn main() {
futures::executor::block_on(async move {
foo(Foo::Baz).await
});
}
I expected to see this happen:
Be warned about the unreachable pattern / enum variant.
Instead, this happened:
No warning was displayed despite an unreachable pattern being present.
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.79s
Running `target/debug/playground`
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `4`: oh', src/main.rs:29:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
rustc --version --verbose
:
rustc 1.47.0 (18bf6b4f0 2020-10-07)
binary: rustc
commit-hash: 18bf6b4f01a6feaf7259ba7cdae58031af1b7b39
commit-date: 2020-10-07
host: x86_64-unknown-linux-gnu
release: 1.47.0
LLVM version: 11.0
Credit for example @ordian , initial finding by @coriolinus
Can confirm the warning[E0170]
doesn't trigger for the code above.
The code could be simplify more by remove unused assert:
use futures::{future, select}; // 0.3.6
pub enum Foo {
Bar,
Baz,
}
/* this function does produce warnings
fn match_foo(foo: Foo) -> i32 {
match foo {
Bar => 1,
_ => unreachable!("why you do this rust?"),
}
}
*/
pub async fn asdf(foo: Foo) {
let mut a = future::ready(4);
select! {
// but this doesn't
a_res = a => match foo {
Bar => 1,
_ => 4,
// _ => unreachable!("why you do this rust?"),
},
};
}
fn main() {
futures::executor::block_on(asdf(Foo::Baz));
}
@rustbot prioritize
@drahnr By the way, not sure if you realized this but matching on Bar
treats Bar
as a variable not the enum variant Foo::Bar
.
This appears to be due to the select!
macro using proc-macro-hack
. As the name would suggest, proc-macro-hack
does a number of hacky things, which appears to include sending input tokens through a generated macro_rules!
macro. This applies a mark to the token spans, causing the lint to be suppressed by this check: https://github.com/rust-lang/rust/blob/7f587168102498a488abf608a86c7fdfa62fb7bb/compiler/rustc_middle/src/lint.rs#L245-L260
This should be fixed when https://github.com/dtolnay/proc-macro-hack/issues/62 is implemented. I don't think there's anything that can be done on the rustc side.
@drahnr By the way, not sure if you realized this but matching on
Bar
treatsBar
as a variable not the enum variantFoo::Bar
.
I think that was a result of minimization removing a use Foo::Bar;
from the scope. Doesn't really change much for the repro.
Assigning P-low
as discussed as part of the Prioritization Working Group procedure and removing I-prioritize
.
This should be fixed when dtolnay/proc-macro-hack#62 is implemented. I don't think there's anything that can be done on the rustc side.
According to this comment, this should have been fixed by https://github.com/dtolnay/proc-macro-hack/pull/66, which was released in 0.5.19.
But with
❯ cargo update -p proc-macro-hack
Updating crates.io index
Updating proc-macro-hack v0.5.18 -> v0.5.19
I am still not getting the warnings.
It looks like that change requires explicit opt-in via #[proc_macro_hack(only_hack_old_rustc)]
in the proc macro crate.
This now produces a warning if you change the Cargo.toml
dependency to futures = { git = "https://github.com/rust-lang/futures-rs" }
:
warning: unreachable pattern
--> src/main.rs:26:13
|
26 | _ => unreachable!("why you do this rust?"),
| ^
|
= note: `#[warn(unreachable_patterns)]` on by default
warning: unused variable: `a_res`
--> src/main.rs:23:9
|
23 | a_res = a => match foo {
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_a_res`
|
= note: `#[warn(unused_variables)]` on by default
Most helpful comment
This appears to be due to the
select!
macro usingproc-macro-hack
. As the name would suggest,proc-macro-hack
does a number of hacky things, which appears to include sending input tokens through a generatedmacro_rules!
macro. This applies a mark to the token spans, causing the lint to be suppressed by this check: https://github.com/rust-lang/rust/blob/7f587168102498a488abf608a86c7fdfa62fb7bb/compiler/rustc_middle/src/lint.rs#L245-L260This should be fixed when https://github.com/dtolnay/proc-macro-hack/issues/62 is implemented. I don't think there's anything that can be done on the rustc side.