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

Improve lint for type alias bounds #48909

Merged
merged 5 commits into from
Mar 23, 2018

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Mar 10, 2018

First of all, I learned just today that I was wrong assuming that the bounds in type aliases are entirely ignored: It turns out they are used to resolve associated types in type aliases. So:

type T1<U: Bound> = U::Assoc; // compiles
type T2<U> = U::Assoc; // fails
type T3<U> = <U as Bound>::Assoc; // "correct" way to write this, maybe?

I am sorry for creating this mess.

This PR changes the wording of the lint accordingly. Moreover, since just removing the bound is no longer always a possible fix, I tried to detect cases like T1 above and show a helpful message to the user:

warning: bounds on generic parameters are not enforced in type aliases
  --> $DIR/type-alias-bounds.rs:57:12
   |
LL | type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
   |            ^^^^^
   |
   = help: the bound will not be checked when the type alias is used, and should be removed
help: use absolute paths (i.e., <T as Trait>::Assoc) to refer to associated types in type aliases
  --> $DIR/type-alias-bounds.rs:57:21
   |
LL | type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
   |                     ^^^^^^^^

I am not sure if I got this entirely right. Ideally, we could provide a suggestion involving the correct trait and type name -- however, while I have access to the HIR in the lint, I do not know how to get access to the resolved name information, like which trait Assoc belongs to above. The lint does not even run if that resolution fails, so I assume that information is available somewhere...

This is a follow-up for (parts of) #48326. Also see #21903.

This changes the name of a lint, but that lint was just merged to master yesterday and has never even been on beta.

…hings

Also, tweak the test for ignored type aliases such that replacing the type alias
by a newtype struct leads to a well-formed type definition, and errors when used
the way the type alias is used.
First of all, the lint is specific for type aliases.  Second, it turns out the
bounds are not entirely ignored but actually used when accessing associated
types.  So change the wording of the lint, and adapt its name to reality.

The lint has never been on stable or beta, so renaming is safe.
…hout "as", suggest to use the "as" form instead.

This is necessary to get rid of the type bound, and hence silence the warning.
@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 10, 2018
@RalfJung
Copy link
Member Author

I guess there is also the question if we even want to nudge people towards writing type T3<U> = <U as Bound>::Assoc;. If that is controversial, I suggest I remove the last commit from this MR (so we get the lint wording and name corrected at least).

The alternative to having people write type T3<U> = <U as Bound>::Assoc; is to detect if a bound is necessary for well-formedness. So, type T3<U: Bound> = U::Assoc; should be accepted but type T3<U: Bound> = Vec<U>; should be linted against. I have no idea how to do that.

// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
// bound. Let's see of this type does that.

// We use an AST visitor to walk the type.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: HIR visitor

fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) {
if TypeAliasBounds::is_type_variable_assoc(qpath) {
self.err.span_help(span,
"use absolute paths (i.e., <T as Trait>::Assoc) to refer to associated \
Copy link
Contributor

Choose a reason for hiding this comment

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

Absolute paths are ::a::b::c.
IIRC, doc and lang teams had a council at one time and discussed how to call "UFCS paths" (<T as Trait>::Assoc) properly, but I don't remember what they decided. "Fully disambiguated paths" maybe.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, missing backquotes around <T as Trait>::Assoc.

@petrochenkov
Copy link
Contributor

r=me modulo couple of wording nits
@bors delegate+

@bors
Copy link
Contributor

bors commented Mar 17, 2018

✌️ @RalfJung can now approve this pull request

@petrochenkov
Copy link
Contributor

+ Travis says some compile-fail tests are failing

[01:04:45] [compile-fail] compile-fail/issue-17994.rs
[01:04:45] [compile-fail] compile-fail/private-in-public-warn.rs

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 17, 2018
@RalfJung
Copy link
Member Author

  • Travis says some compile-fail tests are failing

It seems those warnings went away when I moved this from an early to a late lint... is it possible that late (HIR) lints don't run in these cases?

@RalfJung
Copy link
Member Author

RalfJung commented Mar 19, 2018

is it possible that late (HIR) lints don't run in these cases?

@rkruppe confirmed on IRC that's a reasonable assumption, and the UI test looking for these warnings still passes so I think all is good.

@bors r=petrochenkov

@bors
Copy link
Contributor

bors commented Mar 19, 2018

📌 Commit c05d234 has been approved by @petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 19, 2018
@bors
Copy link
Contributor

bors commented Mar 19, 2018

💡 This pull request was already approved, no need to approve it again.

@bors
Copy link
Contributor

bors commented Mar 19, 2018

📌 Commit c05d234 has been approved by petrochenkov

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 23, 2018
…chenkov

Improve lint for type alias bounds

First of all, I learned just today that I was wrong assuming that the bounds in type aliases are entirely ignored: It turns out they are used to resolve associated types in type aliases. So:
```rust
type T1<U: Bound> = U::Assoc; // compiles
type T2<U> = U::Assoc; // fails
type T3<U> = <U as Bound>::Assoc; // "correct" way to write this, maybe?
```
I am sorry for creating this mess.

This PR changes the wording of the lint accordingly. Moreover, since just removing the bound is no longer always a possible fix, I tried to detect cases like `T1` above and show a helpful message to the user:
```
warning: bounds on generic parameters are not enforced in type aliases
  --> $DIR/type-alias-bounds.rs:57:12
   |
LL | type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
   |            ^^^^^
   |
   = help: the bound will not be checked when the type alias is used, and should be removed
help: use absolute paths (i.e., <T as Trait>::Assoc) to refer to associated types in type aliases
  --> $DIR/type-alias-bounds.rs:57:21
   |
LL | type T1<U: Bound> = U::Assoc; //~ WARN not enforced in type aliases
   |                     ^^^^^^^^
```
I am not sure if I got this entirely right. Ideally, we could provide a suggestion involving the correct trait and type name -- however, while I have access to the HIR in the lint, I do not know how to get access to the resolved name information, like which trait `Assoc` belongs to above. The lint does not even run if that resolution fails, so I assume that information is available *somewhere*...

This is a follow-up for (parts of) rust-lang#48326. Also see rust-lang#21903.

This changes the name of a lint, but that lint was just merged to master yesterday and has never even been on beta.
bors added a commit that referenced this pull request Mar 23, 2018
@alexcrichton alexcrichton merged commit c05d234 into rust-lang:master Mar 23, 2018
@RalfJung RalfJung deleted the type_alias_bounds branch July 10, 2018 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants