Rollup merge of #148262 - JonathanBrouwer:dead-code-inference, r=nnethercote
Fix types being marked as dead when they are inferred generic arguments Previously usages of a type in a pattern were ignored. This is incorrect, since if the type is in a pattern we're clearly producing it in the expression we're matching against. I think this `in_pat` check was meant to be only for variants, which we should indeed ignore since we can just remove the match arm that matches the pattern. Please double check my logic here since this is my first time touching the dead-code pass and I'm not 100% sure this is what the `self.in_pat` check was for. Fixes https://github.com/rust-lang/rust/issues/148144
This commit is contained in:
@@ -125,9 +125,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
||||
) => {
|
||||
self.check_def_id(def_id);
|
||||
}
|
||||
_ if self.in_pat => {}
|
||||
Res::PrimTy(..) | Res::SelfCtor(..) | Res::Local(..) => {}
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => {
|
||||
// Using a variant in patterns should not make the variant live,
|
||||
// since we can just remove the match arm that matches the pattern
|
||||
if self.in_pat {
|
||||
return;
|
||||
}
|
||||
let variant_id = self.tcx.parent(ctor_def_id);
|
||||
let enum_id = self.tcx.parent(variant_id);
|
||||
self.check_def_id(enum_id);
|
||||
@@ -136,6 +140,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
Res::Def(DefKind::Variant, variant_id) => {
|
||||
// Using a variant in patterns should not make the variant live,
|
||||
// since we can just remove the match arm that matches the pattern
|
||||
if self.in_pat {
|
||||
return;
|
||||
}
|
||||
let enum_id = self.tcx.parent(variant_id);
|
||||
self.check_def_id(enum_id);
|
||||
if !self.ignore_variant_stack.contains(&variant_id) {
|
||||
|
||||
16
tests/ui/lint/dead-code/inferred-generic-arg.rs
Normal file
16
tests/ui/lint/dead-code/inferred-generic-arg.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
//@ check-pass
|
||||
|
||||
#![deny(dead_code)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct Test {
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if let Some::<Test>(test) = magic::<Test>() { }
|
||||
}
|
||||
|
||||
fn magic<T: Default>() -> Option<T> {
|
||||
Some(T::default())
|
||||
}
|
||||
Reference in New Issue
Block a user