Skip to content

new large_enum_variants lint #1187

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

Closed
wants to merge 4 commits into from
Closed

Conversation

gnieto
Copy link
Contributor

@gnieto gnieto commented Aug 21, 2016

Added lint to detect large variants and suggesting to box them

Solves https://github.com/Manishearth/rust-clippy/issues/1127

Added linter to detect large variants and suggesting to box them
@@ -162,6 +162,8 @@ define_Conf! {
("too-large-for-stack", too_large_for_stack, 200 => u64),
/// Lint: ENUM_VARIANT_NAMES. The minimum number of enum variants for the lints about variant names to trigger
("enum-variant-name-threshold", enum_variant_name_threshold, 3 => u64),
/// Lint: ENUM_LARGE_VARIANT. The maximum size of a emum's variant to avoid box suggestion
("enum-variant-size-threshold", enum_variant_size_threshold, 200 => u64),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used the same value as 'too-large-for-stack'. I don't know which value use as default

Copy link
Member

@mcarton mcarton Aug 21, 2016

Choose a reason for hiding this comment

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

That's already quite big for an enum variant IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So is the default value ok? Should I leave it to 200?

@mcarton
Copy link
Member

mcarton commented Aug 21, 2016

r+ modulo the default value of enum-variant-size-threshold.

/// }
/// ```
declare_lint! {
pub ENUM_LARGE_VARIANT,
Copy link
Member

Choose a reason for hiding this comment

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

Should be named LARGE_ENUM_VARIANT IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed all references to 'enum_large_variant' to 'large_enum_variant' on 088bb8f

@oli-obk
Copy link
Contributor

oli-obk commented Sep 5, 2016

needs a rebase + some research into enum variant sizes in existing code bases for choosing the default value.

@gnieto
Copy link
Contributor Author

gnieto commented Sep 6, 2016

While I was doing some research on popular Rust projects with this lint, I discovered that under some conditions, this lint will panic. Consider the following code:

trait SomeTrait {
    type Item;
}

enum LargeEnumGeneric<A: SomeTrait> {
    Var(A::Item),
}

With that code, one of the calls to rustc is panicking with:

../src/librustc/ty/context.rs:161: Attempted to intern _ which contains inference types/regions in the global type context

Is obvious that the compiler is not able to know the size of 'SomeTrait::Item' because it's generic and it depends on which concrete trait implementations is given. In this scenario, the lint should ignore generic enums depending on associated types? Or the lint should search for any concretion of the enum (I don't know the technical name of this, I mean: LargeEnumGeneric), and then calculate the variant sizes of this?

@mcarton
Copy link
Member

mcarton commented Sep 6, 2016

@gnieto Good catch! IMO it's ok to bail (cleanly, not ICEing 😄) when the size is unknown. You could manage to look at the enumeration instances, but it might be overkill.

Although, while testing this I noticed it looks like compiletest-rs does not catch ICE if all expected error are found before the ICE. This is bad, cc @Manishearth.

@Manishearth
Copy link
Member

hmm, weird. IIRC compiletest does check the exit code.

@mcarton
Copy link
Member

mcarton commented Sep 6, 2016

@Manishearth compiletest-rs, rustc

The actual error is

{all}
{other}
{errors}
{…}
{"message":"../src/librustc/ty/context.rs:161: Attempted to intern `_` which contains inference types/regions in the global type context","code":null,"level":"error: internal compiler error","spans":[],"children":[],"rendered":null}
note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: run with `RUST_BACKTRACE=1` for a backtrace

It looks like that function was not adapted to the JSON format. I'll do a PR tomorrow. As for the error code, it is checked but rustc returns 101 for any kind of error (so it should work in run-pass, but not compile-fail).

@gnieto
Copy link
Contributor Author

gnieto commented Nov 11, 2016

It has been a while since I opened the PR , and I tried a couple of ways to avoid the internal compiler error:

  • Try to get a distinct "infer context" (I was using "borrowck_fake_infer_ctxt") to avoid the ICE (without success)
  • Tried to inspect recursively the TypeVariants of each field of each variant in search of associated types (TyProjection). This can lead to a infinite loop if there are types depending on each other and... well, it seems like an ugly hack.

If anyone has some idea on how I can approach the issue, I'll try to do it, but at the moment, I don't know how to continue.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 15, 2016

Tried to inspect recursively the TypeVariants of each field of each variant in search of associated types (TyProjection). This can lead to a infinite loop if there are types depending on each other and... well, it seems like an ugly hack.

I think that's the right approach for now. You can always use a HashSet to prevent recursing into types you've already seen.

@oli-obk
Copy link
Contributor

oli-obk commented Dec 21, 2016

@gnieto: are you planning to continue with this PR?

@gnieto
Copy link
Contributor Author

gnieto commented Dec 23, 2016

@oli-obk I don't think that I will not have time to dedicate to this in the following weeks.
A part of that, I think that i picked a task that was too hard for me. Anyway, thanks for your help.

@gnieto gnieto closed this Dec 23, 2016
@oli-obk
Copy link
Contributor

oli-obk commented Dec 23, 2016

I just wanted to ask, to make sure I don't steal your PR that you still planned to continue. I'll finish it.

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.

4 participants