Repository: rust
Issue: Missed optimization: Useless branches are kept when matching pattern
Labels: I-slow,E-needs-test,T-compiler,C-bug

EDIT: this is now reasonably optimized: https://rust.godbolt.org/z/nP599MaKM
So it just needs tests: @rustbot label +E-needs-test

---

I tried this code: https://rust.godbolt.org/z/hP3YKe

The code below does not compile because I strip some code, try the godbolt link above:
```rust
const fn doc_comment_kind(s: &str) -> Option<(DocCommentKind, AttrStyle)> {
    match s.as_bytes() {
        [b'/', b'/', b'/', b'/', ..] => None,
        [b'/', b'/', b'/', ..] => Some((DocCommentKind::Line, AttrStyle::Inner)),
        [b'/', b'/', b'!', ..] => Some((DocCommentKind::Line, AttrStyle::Outer)),
        [b'/', b'*', b'*', b'*', _, ..] => None,
        [b'/', b'*', b'*', _, _, ..] => Some((DocCommentKind::Block, AttrStyle::Inner)),
        [b'/', b'*', b'!', _, _, ..] => Some((DocCommentKind::Block, AttrStyle::Outer)),
        _ => None,
    }
}

pub const fn is_line_doc_comment(s: &str) -> bool {
    match doc_comment_kind(s) {
        Some((DocCommentKind::Line, _)) => true,
        _ => false
    }
}
```

**I expected to see this happen:**
The generated code of `is_line_doc_comment` should be optimized out useless branches.
And it should be equivalent to this function:
```rust
pub const fn is_line_doc_comment_2(s: &str) -> bool {
    match s.as_bytes() {
        [b'/', b'/', b'/', b'/', ..] => false,
        [b'/', b'/', b'/', ..] => true,
        [b'/', b'/', b'!', ..] => true,
        _ => false,
    }
}
```

*How would the two `is_line_doc_comment` functions be able to generate the same code?*

When `doc_comment_kind` inlined in `is_line_doc_comment`,
the optimizer could see that 

* `Some((DocCommentKind::Block, _))` branches are useless and remove it
```rust
const fn doc_comment_kind(s: &str) -> Option<(DocCommentKind, AttrStyle)> {
    match s.as_bytes() {
        [b'/', b'/', b'/', b'/', ..] => None,
        [b'/', b'/', b'/', ..] => Some((DocCommentKind::Line, AttrStyle::Inner)),
        [b'/', b'/', b'!', ..] => Some((DocCommentKind::Line, AttrStyle::Outer)),
        [b'/', b'*', b'*', b'*', _, ..] => None,
        _ => None,
    }
}
```

* `is_line_doc_comment` doesn't care about `AttrStyle`,
```rust
const fn doc_comment_kind(s: &str) -> Option<DocCommentKind> {
    match s.as_bytes() {
        [b'/', b'/', b'/', b'/', ..] => None,
        [b'/', b'/', b'/', ..] => Some(DocCommentKind::Line),
        [b'/', b'/', b'!', ..] => Some(DocCommentKind::Line),
        [b'/', b'*', b'*', b'*', _, ..] => None,
        _ => None,
    }
}
```

* The first branch overlaps with second branch of `DocCommentKind::Line` branches, 
keep this branch.

* Other `None` branches don't overlap, just make them as fallback:
```rust
const fn doc_comment_kind(s: &str) -> Option<DocCommentKind> {
    match s.as_bytes() {
        [b'/', b'/', b'/', b'/', ..] => None,
        [b'/', b'/', b'/', ..] => Some(DocCommentKind::Line),
        [b'/', b'/', b'!', ..] => Some(DocCommentKind::Line),
        _ => None,
    }
}
```

Final result: https://rust.godbolt.org/z/jrPGr7


**Instead, this happened:**
The generated code still keeps some useless branches.
Maybe I am just asking too much from optimizer.

### Meta

`rustc --version --verbose`:

```
rustc 1.46.0-nightly (8aa18cbdc 2020-07-08)
binary: rustc
commit-hash: 8aa18cbdc5d4bc33bd61e2d9a4b643d87f5d21de
commit-date: 2020-07-08
host: x86_64-unknown-linux-gnu
release: 1.46.0-nightly
LLVM version: 10.0
```