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

Types borrow box #1501

Merged
merged 13 commits into from
Jun 13, 2017
Merged

Types borrow box #1501

merged 13 commits into from
Jun 13, 2017

Conversation

scott-linder
Copy link

Lint for #1480 to check for borrowed boxes

mcarton
mcarton previously requested changes Feb 1, 2017
Copy link
Member

@mcarton mcarton left a comment

Choose a reason for hiding this comment

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

Looks good!

BOX_VEC,
ast_ty.span,
"you seem to be trying to use `&Box<T>`. Consider using just `&T`",
"replace `&Box<T>` with simply `&T`");
Copy link
Member

Choose a reason for hiding this comment

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

Could you use span_suggestion here?

Copy link
Author

Choose a reason for hiding this comment

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

I just need to read through some other examples and I think I can use span_suggestion. Something like mcarton@44daa8b?

#![allow(boxed_local)]
#![allow(blacklisted_name)]

pub fn test(foo: &Box<bool>) { //~ ERROR you seem to be trying to use `&Box<T>`
Copy link
Member

Choose a reason for hiding this comment

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

For completeness, could you had a test with a &Box<T> in a struct, in an expression (eg. let foo: &Box<T>), etc.?

Copy link
Author

Choose a reason for hiding this comment

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

I will add some more exhaustive tests

Copy link
Author

Choose a reason for hiding this comment

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

In the new tests, the type of a binding (e.g. let foo: &Box<bool>) is not detected by the lint. It seems like the TypePass needs an implementation for check_expr in order to catch this; is my understanding correct?

This will also have the effect of adding this check to the other two lints in the same pass (BOX_VEC and LINKEDLIST); that seems fine, but I just want to make sure that is desired.

I am also going to add a test for associated constants/types on a trait.

Copy link
Member

Choose a reason for hiding this comment

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

After thinking about it, let foo: &Box<T> should probably not be linted about:

let foo: &Box<T> = some_extern_crate::bar();

It's not your fault if the crate returns that. You can't change it.

Copy link
Contributor

Choose a reason for hiding this comment

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

uhm... let foo: &T = some_extern_crate::bar() will work just fine, even if that function returns a &Box<T>: https://is.gd/kdISz8

Copy link
Member

Choose a reason for hiding this comment

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

Good point

@scott-linder
Copy link
Author

So after looking into testing a few more cases, I am wondering what to check. For example, the current TypePass (that is, lints BOX_VEC and LINKEDLIST) check trait items, but not impl items. Is this intentional?

For trait items, TraitItemKind::{Const,Type} will only have a real type to check in the case of associated constants and default associated types, both of which are behind a feature gate currently.

For impl items, #605 prevents checking methods, and I want to be sure the same is not true for associated types/constants.

As of right now I have tried to add the following tests:

pub fn test2() {
    let foo: &Box<bool>; //~ ERROR you seem to be trying to use `&Box<T>`
}

trait Test4 {
    type T;
}

impl<'a> Test4 for Test3<'a> {
    type T = &'a Box<bool>; //~ ERROR you seem to be trying to use `&Box<T>`
}

But neither is actually detected. Should I implement check_expr and check_impl_item to catch them?

@mcarton
Copy link
Member

mcarton commented Feb 2, 2017

the current TypePass (that is, lints BOX_VEC and LINKEDLIST) check trait items, but not impl items. Is this intentional?

Yes. If you define a trait with one of those it's bad. If you implement a trait with those, you cannot change that, it's not your fault (unless you've also defined the trait, but then you'll have the warning there anyway).

@oli-obk
Copy link
Contributor

oli-obk commented Feb 4, 2017

But neither is actually detected. Should I implement check_expr and check_impl_item to catch them?

I think for the first it is check_local. You need to be careful not to break the other lints, but there should be tests for those. Maybe add a boolean parameter to the check_ty function which decides whether it's called from one of the current functions or one of the new ones.

@oli-obk
Copy link
Contributor

oli-obk commented Mar 24, 2017

Are you planning to continue this PR or do you want someone to take it over?

@scott-linder
Copy link
Author

I would like to finish it, but I don't think I have the time right now. I'm sorry for squating on it. I will watch this PR to see how the rest is done and pick up another issue after my finals.

@oli-obk
Copy link
Contributor

oli-obk commented Mar 24, 2017

I would like to finish it, but I don't think I have the time right now. I'm sorry for squating on it.

No worries! Just wanted to check up on it.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 9, 2017

Just a reminder that you have a PR open here. No need to hurry or anything.

@scott-linder
Copy link
Author

I am going to dedicate more time to this. I rebased onto master, and I notice some changes in how testing works. Are the "annotated source" style tests gone? Should I just add an example for this lint to the clippy_tests crate?

@scott-linder
Copy link
Author

I think I understand the new system after rereading the contributing file. I will move the test over and get back up to speed with what this lint should cover.

@scott-linder
Copy link
Author

@mcarton I took a crack at adding a span_suggestion, by digging down through Box<T> to get a snippet of the inner type. I formatted this (along with the optional lifetime and mutability), and it works for a couple trivial cases, but I don't know if it is actually "correct."

I will work on the remaining check_* functions tomorrow.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 11, 2017

I think you need to rerun the tests and commit the changes, since you changed the output

@scott-linder
Copy link
Author

Thank you for sticking with me, I hope after I get through one lint I can make a lot more progress on other lints alone. I had been running only my example, which doesn't update the stderr file.

@scott-linder
Copy link
Author

I added check_local to the pass and pushed up the new stderr. All of the current tests seem to be passing. Should I add more? Are there more checks I could add for this lint?

I am also not perfectly happy with the extra bool flag needed for check_ty now, but the alternatives seem to require duplicating the code for recursively checking types. Any suggestions are welcome for making it more obvious what is going on.

Add negative tests for types in local declarations in the `LINKEDLIST`
and `BOX_VEC` lints. They share a pass with `BORROWED_BOX` which does
check local delclarations.
@scott-linder
Copy link
Author

I added tests to the other lints in the same pass, to make sure they are not checking local declarations.

if let Some(def_id) = opt_def_id(def) {
if Some(def_id) == cx.tcx.lang_items.owned_box() {
if_let_chain! {[
let QPath::Resolved(None, ref path) = *qpath,
Copy link
Contributor

Choose a reason for hiding this comment

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

You can merge the above two ifs into this if let chain.

println!("{:?}", foo)
}

pub fn test2() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a trait method taking a box reference and an impl to show that only the trait is linted and not the impl?

@oli-obk
Copy link
Contributor

oli-obk commented Jun 12, 2017

Two nits, then we are good to go.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 12, 2017

The bool flag is fine with me. You could use an enum if you wanted, but it's not necessary. Maybe just add a comment explaining the argument?

@scott-linder
Copy link
Author

I added the test and merged the ifs, and I also added a short comment about the flag.

@oli-obk oli-obk dismissed mcarton’s stale review June 12, 2017 13:13

Has been addressed

@oli-obk oli-obk merged commit 7056018 into rust-lang:master Jun 13, 2017
@oli-obk
Copy link
Contributor

oli-obk commented Jun 13, 2017

Great work. Thanks.

@scott-linder scott-linder deleted the types-borrow-box branch June 13, 2017 11:55
@scott-linder
Copy link
Author

Thanks @oli-obk and @mcarton for all the help!

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.

3 participants