Skip to content
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

Add a lint for 'static impl shenanigans #265

Merged
merged 5 commits into from
Mar 23, 2023
Merged

Conversation

thomcc
Copy link
Contributor

@thomcc thomcc commented Mar 21, 2023

This applies on top of #264 because I'm lazy. Edit: not anymore

It basically works but needs more testing and docs. I've decided to handle it by detecting the impl ... for <something that contains 'static in here> pattern, which should be pretty rare.

@thomcc thomcc changed the title Add a lint for certain suspicious trait object usage Add a lint for 'static shenanigans Mar 21, 2023
@thomcc thomcc changed the title Add a lint for 'static shenanigans Add a lint for 'static impl shenanigans Mar 21, 2023
@thomcc thomcc force-pushed the thomcc/static_impls branch from f537a97 to b7b797a Compare March 21, 2023 14:21
@thomcc
Copy link
Contributor Author

thomcc commented Mar 21, 2023

Note that this deliberately doesn't pierce through struct definitions, since those enforce wf-ness on their own (seemingly).

@thomcc thomcc force-pushed the thomcc/static_impls branch from bd2e9ca to e801651 Compare March 21, 2023 21:30
@thomcc thomcc marked this pull request as ready for review March 21, 2023 21:30
@thomcc
Copy link
Contributor Author

thomcc commented Mar 21, 2023

Okay, I'm pretty confident this is the right approach (and that trying to solve it by additional analysis passes is more trouble than its worth).

@thomcc
Copy link
Contributor Author

thomcc commented Mar 21, 2023

I think the CI failure is just aws flakiness. (CC @BradyBonnette)

@workingjubilee
Copy link
Contributor

Yes. Will rerun those tests when it settles.

struct Baz<'a, A>(core::marker::PhantomData<&'a A>);
trait Quux<A> {}

impl<T> Foo for &'static T {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these are generic because technically this is only (known to be) unsound in a case involving generics. I have not been able to trigger the unsound situation in cases with concrete types.

That said, given that we unload functions in create or replace situations, doing too much of anything with statics isn't exactly ideal, and just because I couldn't repro it doesn't mean it can't be done.

LL | impl<T> Foo for &'static dyn Quux<T> {}
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 11 previous errors
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that there are 11 impl lines in the test file, and we want each of them to trigger.

@thomcc thomcc requested a review from workingjubilee March 22, 2023 19:56
Comment on lines +111 to +113
TyKind::Rptr(Lifetime { res: Static, .. }, _) | TyKind::TraitObject(_, Lifetime { res: Static, .. }, _) => true,
// Need to keep looking.
TyKind::Rptr(_, MutTy { ty, .. })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Rptr" is a very confusing way for rustc to say "reference", honestly.

Comment on lines +9 to +11
// This is more complex than the one in the issue, to make sure the `Box`'s
// lang_item status doesn't bite us.
impl<T: Display> Displayable for (T, Box<Option<&'static T>>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is making me wonder: Box<T> is a lang item, but more than that, it is #[fundamental]. Should we have any special concerns about other #[fundamental] types here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not as far as I know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be more concrete, we are looking somewhat blindly for 'static through almost everything, so fundamental or not, it doesn't make a huge difference.

let segs = match qpath {
hir::QPath::Resolved(Some(maybe_ty), _) if self.has_static(maybe_ty) => return true,
hir::QPath::TypeRelative(t, _) if self.has_static(*t) => return true,
hir::QPath::LangItem(..) => return false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is this why you mentioned the Box<Option<&'static T>> thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I think it only happens if the path refers to a function.

plrustc/plrustc/src/lints.rs Outdated Show resolved Hide resolved
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
@workingjubilee workingjubilee merged commit d8c6d4a into main Mar 23, 2023
@thomcc thomcc deleted the thomcc/static_impls branch March 23, 2023 22:02
@eeeebbbbrrrr eeeebbbbrrrr mentioned this pull request Apr 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants