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 future_prelude_collision lint #85707

Merged
merged 25 commits into from
Jun 22, 2021

Conversation

jam1garner
Copy link
Contributor

@jam1garner jam1garner commented May 26, 2021

Implements #84594. (RFC rust-lang/rfcs#3114 (rendered)) Not entirely complete but wanted to have my progress decently available while I finish off the last little bits.

Things left to implement:

  • UI tests for lints
  • Only emit lint for 2015 and 2018 editions
  • Lint name/message bikeshedding (todo)
  • Implement for FromIterator (from best I can tell, the current approach as mentioned from this comment won't work due to FromIterator instances not using dot-call syntax, but if I'm correct about this then that would also need to be fixed for TryFrom/TryInto)*
  • Add to rust-2021-migration group? (See force-warn for edition lints #85512) (added to rust-2021-compatibility group)
  • Link to edition guide in lint docs (todo)

*edit: looked into it, lookup_method will also not be hit for TryFrom/TryInto for non-dotcall syntax. If anyone who is more familiar with typecheck knows the equivalent for looking up associated functions, feel free to chime in.

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @estebank (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 26, 2021
@jam1garner
Copy link
Contributor Author

I believe all of the issues preventing a review have been resolved if you'd like to take a look or tag someone in @estebank!

@nikomatsakis
Copy link
Contributor

r? @nikomatsakis

I can try to review this!

@m-ou-se m-ou-se added the A-edition-2021 Area: The 2021 edition label May 27, 2021
/// method is called via dot-call syntax or a `try_from`/`from_iter` associated function
/// is called directly on a type.
///
/// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes
Copy link
Member

Choose a reason for hiding this comment

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

Note: We should link to the edition guide once the 2021 stuff is online.

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

The code looks very nice!

compiler/rustc_typeck/src/check/method/mod.rs Outdated Show resolved Hide resolved
@m-ou-se
Copy link
Member

m-ou-se commented May 27, 2021

For some more test cases, try running cargo +yourversion fix on https://github.com/derekjw/try_from. That results in:

after fixes were automatically applied the compiler reported errors within these files:

  * src/char.rs
  * src/int.rs
  * src/lib.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see 
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0107]: missing generics for trait `TryFrom`
  --> src/lib.rs:55:30
   |
55 |         let result = <u32 as TryFrom>::try_from("3");
   |                              ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
55 |         let result = <u32 as TryFrom<T>>::try_from("3");
   |                              ^^^^^^^^^^
The rest of the output
error[E0107]: missing generics for trait `TryFrom`
  --> src/lib.rs:61:30
   |
61 |         let result = <u32 as TryFrom>::try_from("hello");
   |                              ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
61 |         let result = <u32 as TryFrom<T>>::try_from("hello");
   |                              ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:29:23
   |
29 |     assert_eq!(<u8 as TryFrom>::try_from('~'), Ok(0x7e));
   |                       ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
29 |     assert_eq!(<u8 as TryFrom<T>>::try_from('~'), Ok(0x7e));
   |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:30:23
   |
30 |     assert_eq!(<u8 as TryFrom>::try_from('\u{100}'), Err(TryFromIntError::Overflow));
   |                       ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
30 |     assert_eq!(<u8 as TryFrom<T>>::try_from('\u{100}'), Err(TryFromIntError::Overflow));
   |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:46:25
   |
46 |     assert_eq!(<char as TryFrom>::try_from(0x7e), Ok('~'));
   |                         ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
46 |     assert_eq!(<char as TryFrom<T>>::try_from(0x7e), Ok('~'));
   |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:47:25
   |
47 |     assert_eq!(<char as TryFrom>::try_from('~'), Ok('~'));
   |                         ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
47 |     assert_eq!(<char as TryFrom<T>>::try_from('~'), Ok('~'));
   |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:56:31
   |
56 |                 match <u32 as TryFrom>::try_from(n)? {
   |                               ^^^^^^^ expected 1 generic argument
...
68 | impl_int_to_char!(i8, i16, i32, i64, isize, u16, u32, u64, usize);
   | ------------------------------------------------------------------ in this macro invocation
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
   = note: this error originates in the macro `impl_int_to_char` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add missing generic argument
   |
56 |                 match <u32 as TryFrom<T>>::try_from(n)? {
   |                               ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:72:25
   |
72 |     assert_eq!(<char as TryFrom>::try_from(-1), Err(TryFromIntToCharError::Underflow));
   |                         ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
72 |     assert_eq!(<char as TryFrom<T>>::try_from(-1), Err(TryFromIntToCharError::Underflow));
   |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:73:25
   |
73 |     assert_eq!(<char as TryFrom>::try_from(0x7eu32), Ok('~'));
   |                         ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
73 |     assert_eq!(<char as TryFrom<T>>::try_from(0x7eu32), Ok('~'));
   |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:74:25
   |
74 |     assert_eq!(<char as TryFrom>::try_from(0xd888), Err(TryFromIntToCharError::Reserved));
   |                         ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
74 |     assert_eq!(<char as TryFrom<T>>::try_from(0xd888), Err(TryFromIntToCharError::Reserved));
   |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:75:25
   |
75 |     assert_eq!(<char as TryFrom>::try_from(0x10ffff), Ok('\u{10ffff}'));
   |                         ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
75 |     assert_eq!(<char as TryFrom<T>>::try_from(0x10ffff), Ok('\u{10ffff}'));
   |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/char.rs:77:18
   |
77 |         <char as TryFrom>::try_from(0x110000),
   |                  ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
77 |         <char as TryFrom<T>>::try_from(0x110000),
   |                  ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
  --> src/int.rs:77:24
   |
77 |     assert_eq!(<u64 as TryFrom>::try_from(usize::MAX), Ok(usize::MAX as u64));
   |                        ^^^^^^^ expected 1 generic argument
   |
note: trait defined here, with 1 generic parameter: `T`
  --> src/lib.rs:19:11
   |
19 | pub trait TryFrom<T>: Sized {
   |           ^^^^^^^ -
help: add missing generic argument
   |
77 |     assert_eq!(<u64 as TryFrom<T>>::try_from(usize::MAX), Ok(usize::MAX as u64));
   |                        ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:106:23
    |
106 |     assert_eq!(<u8 as TryFrom>::try_from(0xffu16), Ok(0xffu8));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
106 |     assert_eq!(<u8 as TryFrom<T>>::try_from(0xffu16), Ok(0xffu8));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:107:23
    |
107 |     assert_eq!(<u8 as TryFrom>::try_from(0x100u16), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
107 |     assert_eq!(<u8 as TryFrom<T>>::try_from(0x100u16), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:110:28
    |
110 |         assert_eq!(<u32 as TryFrom>::try_from(usize::MAX), Ok(u32::MAX));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
110 |         assert_eq!(<u32 as TryFrom<T>>::try_from(usize::MAX), Ok(u32::MAX));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:111:30
    |
111 |         assert_eq!(<usize as TryFrom>::try_from(u64::MAX), Err(TryFromIntError::Overflow));
    |                              ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
111 |         assert_eq!(<usize as TryFrom<T>>::try_from(u64::MAX), Err(TryFromIntError::Overflow));
    |                              ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:113:28
    |
113 |         assert_eq!(<u32 as TryFrom>::try_from(usize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
113 |         assert_eq!(<u32 as TryFrom<T>>::try_from(usize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:114:30
    |
114 |         assert_eq!(<usize as TryFrom>::try_from(u64::MAX), Ok(usize::MAX));
    |                              ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
114 |         assert_eq!(<usize as TryFrom<T>>::try_from(u64::MAX), Ok(usize::MAX));
    |                              ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:147:23
    |
147 |     assert_eq!(<u8 as TryFrom>::try_from(0i16), Ok(0u8));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
147 |     assert_eq!(<u8 as TryFrom<T>>::try_from(0i16), Ok(0u8));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:148:23
    |
148 |     assert_eq!(<u8 as TryFrom>::try_from(-1i16), Err(TryFromIntError::Underflow));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
148 |     assert_eq!(<u8 as TryFrom<T>>::try_from(-1i16), Err(TryFromIntError::Underflow));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:149:23
    |
149 |     assert_eq!(<u8 as TryFrom>::try_from(256i16), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
149 |     assert_eq!(<u8 as TryFrom<T>>::try_from(256i16), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:151:25
    |
151 |     assert_eq!(<u128 as TryFrom>::try_from(i32::MAX), Ok(i32::MAX as u128));
    |                         ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
151 |     assert_eq!(<u128 as TryFrom<T>>::try_from(i32::MAX), Ok(i32::MAX as u128));
    |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:152:25
    |
152 |     assert_eq!(<u128 as TryFrom>::try_from(-1i32), Err(TryFromIntError::Underflow));
    |                         ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
152 |     assert_eq!(<u128 as TryFrom<T>>::try_from(-1i32), Err(TryFromIntError::Underflow));
    |                         ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:154:28
    |
154 |         assert_eq!(<u32 as TryFrom>::try_from(isize::MAX), Ok(0x7fff_ffffu32));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
154 |         assert_eq!(<u32 as TryFrom<T>>::try_from(isize::MAX), Ok(0x7fff_ffffu32));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:155:30
    |
155 |         assert_eq!(<usize as TryFrom>::try_from(i64::MAX), Err(TryFromIntError::Overflow));
    |                              ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
155 |         assert_eq!(<usize as TryFrom<T>>::try_from(i64::MAX), Err(TryFromIntError::Overflow));
    |                              ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:157:28
    |
157 |         assert_eq!(<u32 as TryFrom>::try_from(isize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
157 |         assert_eq!(<u32 as TryFrom<T>>::try_from(isize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:158:27
    |
158 |         assert!(<usize as TryFrom>::try_from(i64::MAX).unwrap() > 0xffff_ffffusize);
    |                           ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
158 |         assert!(<usize as TryFrom<T>>::try_from(i64::MAX).unwrap() > 0xffff_ffffusize);
    |                           ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:188:23
    |
188 |     assert_eq!(<i8 as TryFrom>::try_from(0x7fu8), Ok(0x7fi8));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
188 |     assert_eq!(<i8 as TryFrom<T>>::try_from(0x7fu8), Ok(0x7fi8));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:189:23
    |
189 |     assert_eq!(<i8 as TryFrom>::try_from(0x80u8), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
189 |     assert_eq!(<i8 as TryFrom<T>>::try_from(0x80u8), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:191:24
    |
191 |     assert_eq!(<i64 as TryFrom>::try_from(i64::MAX as u128), Ok(i64::MAX));
    |                        ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
191 |     assert_eq!(<i64 as TryFrom<T>>::try_from(i64::MAX as u128), Ok(i64::MAX));
    |                        ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:192:24
    |
192 |     assert_eq!(<i64 as TryFrom>::try_from(u128::MAX), Err(TryFromIntError::Overflow));
    |                        ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
192 |     assert_eq!(<i64 as TryFrom<T>>::try_from(u128::MAX), Err(TryFromIntError::Overflow));
    |                        ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:194:28
    |
194 |         assert_eq!(<i64 as TryFrom>::try_from(usize::MAX), Ok(0xffff_ffffi64));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
194 |         assert_eq!(<i64 as TryFrom<T>>::try_from(usize::MAX), Ok(0xffff_ffffi64));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:196:23
    |
196 |             <isize as TryFrom>::try_from(0x8000_0000u64),
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
196 |             <isize as TryFrom<T>>::try_from(0x8000_0000u64),
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:200:28
    |
200 |         assert_eq!(<i64 as TryFrom>::try_from(usize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
200 |         assert_eq!(<i64 as TryFrom<T>>::try_from(usize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:201:27
    |
201 |         assert!(<isize as TryFrom>::try_from(0x8000_0000u64).unwrap() > 0x7fff_ffff);
    |                           ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
201 |         assert!(<isize as TryFrom<T>>::try_from(0x8000_0000u64).unwrap() > 0x7fff_ffff);
    |                           ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:234:23
    |
234 |     assert_eq!(<i8 as TryFrom>::try_from(127i16), Ok(127i8));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
234 |     assert_eq!(<i8 as TryFrom<T>>::try_from(127i16), Ok(127i8));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:235:23
    |
235 |     assert_eq!(<i8 as TryFrom>::try_from(128i16), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
235 |     assert_eq!(<i8 as TryFrom<T>>::try_from(128i16), Err(TryFromIntError::Overflow));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:236:23
    |
236 |     assert_eq!(<i8 as TryFrom>::try_from(-128i16), Ok(-128i8));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
236 |     assert_eq!(<i8 as TryFrom<T>>::try_from(-128i16), Ok(-128i8));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:237:23
    |
237 |     assert_eq!(<i8 as TryFrom>::try_from(-129i16), Err(TryFromIntError::Underflow));
    |                       ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
237 |     assert_eq!(<i8 as TryFrom<T>>::try_from(-129i16), Err(TryFromIntError::Underflow));
    |                       ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:239:24
    |
239 |     assert_eq!(<i64 as TryFrom>::try_from(i64::MAX as i128), Ok(i64::MAX));
    |                        ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
239 |     assert_eq!(<i64 as TryFrom<T>>::try_from(i64::MAX as i128), Ok(i64::MAX));
    |                        ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:240:24
    |
240 |     assert_eq!(<i64 as TryFrom>::try_from(i128::MAX), Err(TryFromIntError::Overflow));
    |                        ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
240 |     assert_eq!(<i64 as TryFrom<T>>::try_from(i128::MAX), Err(TryFromIntError::Overflow));
    |                        ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:243:28
    |
243 |         assert_eq!(<i32 as TryFrom>::try_from(isize::MAX), Ok(i32::MAX));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
243 |         assert_eq!(<i32 as TryFrom<T>>::try_from(isize::MAX), Ok(i32::MAX));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:244:30
    |
244 |         assert_eq!(<isize as TryFrom>::try_from(i64::MAX), Err(TryFromIntError::Overflow));
    |                              ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
244 |         assert_eq!(<isize as TryFrom<T>>::try_from(i64::MAX), Err(TryFromIntError::Overflow));
    |                              ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:246:28
    |
246 |         assert_eq!(<i32 as TryFrom>::try_from(isize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
246 |         assert_eq!(<i32 as TryFrom<T>>::try_from(isize::MAX), Err(TryFromIntError::Overflow));
    |                            ^^^^^^^^^^

error[E0107]: missing generics for trait `TryFrom`
   --> src/int.rs:247:27
    |
247 |         assert!(<isize as TryFrom>::try_from(i64::MAX).unwrap() > 0x7fff_ffffisize);
    |                           ^^^^^^^ expected 1 generic argument
    |
note: trait defined here, with 1 generic parameter: `T`
   --> src/lib.rs:19:11
    |
19  | pub trait TryFrom<T>: Sized {
    |           ^^^^^^^ -
help: add missing generic argument
    |
247 |         assert!(<isize as TryFrom<T>>::try_from(i64::MAX).unwrap() > 0x7fff_ffffisize);
    |                           ^^^^^^^^^^

error: aborting due to 46 previous errors

@m-ou-se
Copy link
Member

m-ou-se commented May 27, 2021

It fails in another way on https://github.com/droundy/clapme:

after fixes were automatically applied the compiler reported errors within these files:

  * tests/nested.rs

<snip>

The following errors were reported:
error[E0433]: failed to resolve: use of undeclared crate or module `required_option`
  --> tests/nested.rs:31:10
   |
31 |         <required_option::SuperOpt as ClapMe>::from_iter(&["", "--arg-arg", "7", "--other", "hello"]).unwrap());
   |          ^^^^^^^^^^^^^^^ use of undeclared crate or module `required_option`
   
<snip>

(required_option is the name of the function the SuperOpt::from_iter call appears in.)

@m-ou-se
Copy link
Member

m-ou-se commented May 27, 2021

(Sorry! Don't want to demotivate you! ^^' I'm just going over the crater results from a test where we added these traits to all the preludes, to see if this lint fixes the crates that broke.)

@jam1garner
Copy link
Contributor Author

(Sorry! Don't want to demotivate you! ^^' I'm just going over the crater results from a test where we added these traits to all the preludes, to see if this lint fixes the crates that broke.)

No worries, I appreciate the thorough review actually, these are very much good finds, there's a reason we have the tooling to check the things that are error-prone :)

@m-ou-se
Copy link
Member

m-ou-se commented May 27, 2021

Another interesting case is https://github.com/mechiru/json-ext

The lint does not trigger on that code.

But it should, because compiling that crate on edition 2021 (with the prelude changes) results in:

error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
   --> src/object.rs:102:24
    |
102 |         let obj2 = obj.try_into::<Ext>()?;
    |                        ^^^^^^^^------- help: remove these generics
    |                        |
    |                        expected 0 generic arguments
    |
note: associated function defined here, with 0 generic parameters
   --> rust/library/core/src/convert/mod.rs:395:8
    |
395 |     fn try_into(self) -> Result<T, Self::Error>;
    |        ^^^^^^^^

Not sure why the new prelude affects this code though. try_into is a inherent method here, not a trait method.

@m-ou-se
Copy link
Member

m-ou-se commented May 27, 2021

And another one: https://github.com/mqnfred/ffishim

The lint does also not trigger on this code.

But compiling it in the new edition results in:

error[E0061]: this function takes 0 arguments but 2 arguments were supplied
   --> ffishim/src/field.rs:40:44
    |
40  |             crate::types::switch(&self.ty).try_into(&self.ty, receiver)
    |                                            ^^^^^^^^ --------  -------- supplied 2 arguments
    |                                            |
    |                                            expected 0 arguments
    |
note: associated function defined here
   --> rust/library/core/src/convert/mod.rs:395:8
    |
395 |     fn try_into(self) -> Result<T, Self::Error>;
    |        ^^^^^^^^

Here, the receiver is a &Box<dyn Behavior>, where Behavior is a trait with a try_into function (taking two arguments).

@m-ou-se
Copy link
Member

m-ou-se commented May 27, 2021

I think that's all I can find. Everything else seem to be the same issues as in the cases I already commented about.

@nikomatsakis
Copy link
Contributor

<u32 as TryFrom<_>>::try_from("3"); would probably work

compiler/rustc_typeck/src/check/method/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/method/mod.rs Outdated Show resolved Hide resolved
@rust-log-analyzer

This comment has been minimized.

@jam1garner
Copy link
Contributor Author

It fails in another way on https://github.com/droundy/clapme:

after fixes were automatically applied the compiler reported errors within these files:

  * tests/nested.rs

<snip>

The following errors were reported:
error[E0433]: failed to resolve: use of undeclared crate or module `required_option`
  --> tests/nested.rs:31:10
   |
31 |         <required_option::SuperOpt as ClapMe>::from_iter(&["", "--arg-arg", "7", "--other", "hello"]).unwrap());
   |          ^^^^^^^^^^^^^^^ use of undeclared crate or module `required_option`
   
<snip>

(required_option is the name of the function the SuperOpt::from_iter call appears in.)

It looks like this is because the way I was resolving the path via TyCtxt::def_path_str, which is intended for user output, so in the above case, the code is tests which are embed types with identical names inside. For disambiguating to the user, describing the type path being in a function "module", so that the 10 or so different types with the same name are distinct.

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

Some nits and thoughts.

compiler/rustc_typeck/src/check/method/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/method/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/method/mod.rs Outdated Show resolved Hide resolved
@rust-log-analyzer

This comment has been minimized.

@jam1garner
Copy link
Contributor Author

jam1garner commented May 28, 2021

@m-ou-se when you have some time could you check if the warnings from the previous @rust-log-analyzer message are accurate? I took a look at them and they might be right? But I also wouldn't even know where to start with trying to compile rustc itself using the 2021 prelude, so I can't actually confirm if those are correct.

And if they're correct, I can resolve them.

@rust-log-analyzer

This comment has been minimized.

@jam1garner
Copy link
Contributor Author

Ok current status:

  • json-ext is still broken, no lint firing. I still haven't gotten to diving into what causes the breakage in the first place.
  • ffishim is still broken. Lint fires, but
    • It handles the boxed trait object fine, however TyCtxt::def_path_str isn't suitable for referencing inherent impls or renamed/duplicate types within a crate
      • inherent impl failing: field::<impl Field>::try_into(&*field)
      • duplicate type failing: types::Behavior::try_into(&**crate::types::switch(&self.ty))
        • This fails because types::Behavior describes a trait, but there's also 10 structs in the crate named Behavior, so the module name gets included

Point being: def_path_str is a poor fit. Sorry if I'm being a broken record but if anyone has any ideas where I should look for a replacement that takes into account what is imported at the given scope, it would help immensely, as I've spent an embarrassingly long amount of time looking for possibilities with no luck. One alternative is to output absolute paths to types, however this has the rather obvious downside of producing rather unappealing output and feels like throwing out the baby with the bathwater.

As far as I know, ignoring things that I don't think are my place to resolve (which group to add the lint to, linking to the edition guide), I believe these two issues are the last outstanding bits from what has been identified so far

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@jam1garner
Copy link
Contributor Author

Remaining issues:

Note: We should link to the edition guide once the 2021 stuff is online.
  • The test failing (see the @rust-log-analyzer comment above): future-prelude-collision-shadow. This is because the test is made to ensure compile-fail maintains even after a rustfix run. However ui tests don't seem to support this. Should this test be removed or is there some way to test compile-file for rustfix'd UI tests?

I have gone back through all the crater issues @m-ou-se pointed out and rustfix seems to handle them all.

@m-ou-se
Copy link
Member

m-ou-se commented Jun 21, 2021

Note: We should link to the edition guide once the 2021 stuff is online.

We need to do that for all the 2021 migraiton lints. We can just do that for all of them in a separate PR.

@rust-log-analyzer

This comment has been minimized.

@nikomatsakis nikomatsakis force-pushed the future_prelude_collision_lint branch from 257fe7a to 3dc47e2 Compare June 21, 2021 15:22
Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

left some nits, I may just fix them

compiler/rustc_typeck/src/check/method/prelude2021.rs Outdated Show resolved Hide resolved
compiler/rustc_typeck/src/check/pat.rs Show resolved Hide resolved
@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Jun 21, 2021

📌 Commit aa3580b has been approved by nikomatsakis

@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-review Status: Awaiting review from the assignee but also interested parties. labels Jun 21, 2021
fee1-dead added a commit to fee1-dead-contrib/rust that referenced this pull request Jun 22, 2021
…_lint, r=nikomatsakis

Add `future_prelude_collision` lint

Implements rust-lang#84594. (RFC rust-lang/rfcs#3114 ([rendered](https://github.com/rust-lang/rfcs/blob/master/text/3114-prelude-2021.md))) Not entirely complete but wanted to have my progress decently available while I finish off the last little bits.

Things left to implement:

* [x] UI tests for lints
* [x] Only emit lint for 2015 and 2018 editions
* [ ] Lint name/message bikeshedding
* [x] Implement for `FromIterator` (from best I can tell, the current approach as mentioned from [this comment](rust-lang#84594 (comment)) won't work due to `FromIterator` instances not using dot-call syntax, but if I'm correct about this then that would also need to be fixed for `TryFrom`/`TryInto`)*
* [x] Add to `rust-2021-migration` group? (See rust-lang#85512) (added to `rust-2021-compatibility` group)
* [ ] Link to edition guide in lint docs

*edit: looked into it, `lookup_method` will also not be hit for `TryFrom`/`TryInto` for non-dotcall syntax. If anyone who is more familiar with typecheck knows the equivalent for looking up associated functions, feel free to chime in.
@bors
Copy link
Contributor

bors commented Jun 22, 2021

⌛ Testing commit aa3580b with merge 44f4a87...

@bors
Copy link
Contributor

bors commented Jun 22, 2021

☀️ Test successful - checks-actions
Approved by: nikomatsakis
Pushing 44f4a87 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 22, 2021
@bors bors merged commit 44f4a87 into rust-lang:master Jun 22, 2021
@rustbot rustbot added this to the 1.55.0 milestone Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-edition-2021 Area: The 2021 edition merged-by-bors This PR was explicitly merged by bors. 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.

8 participants