-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mark associated constants used in equality constraints as used #127505
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -857,6 +857,31 @@ fn check_item<'tcx>( | |
// global_asm! is always live. | ||
worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No)); | ||
} | ||
DefKind::OpaqueTy => { | ||
if let hir::ItemKind::OpaqueTy(ty) = tcx.hir().item(id).kind { | ||
for bound in ty.bounds { | ||
if let hir::GenericBound::Trait(polytraitref, _) = bound | ||
&& let Some(pathsegment) = polytraitref.trait_ref.path.segments.last() | ||
&& let Some(args) = pathsegment.args | ||
{ | ||
for constraint in args.constraints { | ||
if let Some(item) = tcx | ||
.associated_items(pathsegment.res.def_id()) | ||
.filter_by_name_unhygienic(constraint.ident.name) | ||
.find(|i| { | ||
i.kind == ty::AssocKind::Const | ||
&& i.ident(tcx).normalize_to_macros_2_0() | ||
== constraint.ident | ||
}) | ||
&& let Some(local_def_id) = item.def_id.as_local() | ||
{ | ||
worklist.push((local_def_id, ComesFromAllowExpect::No)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
Comment on lines
+862
to
+883
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will we get this for free by just visiting the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t think so, because the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, this is a more fundamental problem. https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=dd0c2930c397acba2692b51a633b367d will still fail after your PR. If these could be used in trait objects we'd probably see the issue there, too. Considering that #![deny(dead_code)]
trait Tr {
type T;
}
impl Tr for () {
type T = ();
}
fn foo<T: Tr>(_: T) { }
fn main() {
foo(());
} passes, I'm assuming that if a trait is marked as used, all its assoc types are marked as used. We should do the same for assoc consts, not sure how that didn't happen or if there was an explicit reason for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It was made in #126618. I think it's not the best solution, i.e., marking assoc const/tys live if the trait is used, considering that trait Trait {
const X: i32;
fn foo(&self) {}
}
impl Trait for () {
const X: i32 = 0;
}
fn main() {
().foo();
} The assoc const is not used and we can lint it. |
||
} | ||
_ => {} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
//@ check-pass | ||
|
||
#![feature(associated_const_equality)] | ||
#![deny(dead_code)] | ||
|
||
trait Tr { | ||
const I: i32; | ||
} | ||
|
||
impl Tr for () { | ||
const I: i32 = 1; | ||
} | ||
|
||
fn foo() -> impl Tr<I = 1> {} | ||
|
||
trait Tr2 { | ||
const J: i32; | ||
const K: i32; | ||
} | ||
|
||
impl Tr2 for () { | ||
const J: i32 = 1; | ||
const K: i32 = 1; | ||
} | ||
|
||
fn foo2() -> impl Tr2<J = 1, K = 1> {} | ||
|
||
mod t { | ||
pub trait Tr3 { | ||
const L: i32; | ||
} | ||
|
||
impl Tr3 for () { | ||
const L: i32 = 1; | ||
} | ||
} | ||
|
||
fn foo3() -> impl t::Tr3<L = 1> {} | ||
|
||
fn main() { | ||
foo(); | ||
foo2(); | ||
foo3(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we do this in
visit_poly_trait_ref
? For example, things likedyn Tr<X = ()>
andfn foo<T: Tr<X = ()>>
should also markX
live.