about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-06-22 07:01:54 +0000
committerbors <bors@rust-lang.org>2021-06-22 07:01:54 +0000
commit44f4a87d7047db0deff5ef033fd2af820722e9a5 (patch)
tree4960627de594af7fc920104a8f40245e480485e9 /src
parentc38111c4fb9c22a36f9a9195d1884052bb670af2 (diff)
parentaa3580baa6f5ef69aba41a63297fb659bcd4b793 (diff)
downloadrust-44f4a87d7047db0deff5ef033fd2af820722e9a5.tar.gz
rust-44f4a87d7047db0deff5ef033fd2af820722e9a5.zip
Auto merge of #85707 - jam1garner:future_prelude_collision_lint, r=nikomatsakis
Add `future_prelude_collision` lint

Implements #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](https://github.com/rust-lang/rust/issues/84594#issuecomment-847288288) 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 #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.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.fixed59
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.rs59
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.stderr34
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-shadow.rs32
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-shadow.stderr40
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.fixed96
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.rs96
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.stderr79
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.fixed18
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.rs18
-rw-r--r--src/test/ui/rust-2021/generic-type-collision.stderr16
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.fixed53
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.rs53
-rw-r--r--src/test/ui/rust-2021/inherent-dyn-collision.stderr16
-rw-r--r--src/test/ui/rust-2021/inherent-method-collision.rs15
15 files changed, 684 insertions, 0 deletions
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
new file mode 100644
index 00000000000..4f8fd9b345b
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
@@ -0,0 +1,59 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(future_prelude_collision)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+mod m {
+    pub trait TryIntoU32 {
+        fn try_into(self) -> Result<u32, ()>;
+    }
+
+    impl TryIntoU32 for u8 {
+        fn try_into(self) -> Result<u32, ()> {
+            Ok(self as u32)
+        }
+    }
+
+    pub trait AnotherTrick {}
+}
+
+mod a {
+    use crate::m::TryIntoU32;
+
+    fn main() {
+        // In this case, we can just use `TryIntoU32`
+        let _: u32 = TryIntoU32::try_into(3u8).unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    }
+}
+
+mod b {
+    use crate::m::AnotherTrick as TryIntoU32;
+    use crate::m::TryIntoU32 as _;
+
+    fn main() {
+        // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use
+        // the path `crate::m::TryIntoU32` (with which it was imported).
+        let _: u32 = crate::m::TryIntoU32::try_into(3u8).unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    }
+}
+
+mod c {
+    use super::m::TryIntoU32 as _;
+    use crate::m::AnotherTrick as TryIntoU32;
+
+    fn main() {
+        // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use
+        // the path `super::m::TryIntoU32` (with which it was imported).
+        let _: u32 = super::m::TryIntoU32::try_into(3u8).unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.rs b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
new file mode 100644
index 00000000000..2ce1be6151b
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
@@ -0,0 +1,59 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(future_prelude_collision)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+mod m {
+    pub trait TryIntoU32 {
+        fn try_into(self) -> Result<u32, ()>;
+    }
+
+    impl TryIntoU32 for u8 {
+        fn try_into(self) -> Result<u32, ()> {
+            Ok(self as u32)
+        }
+    }
+
+    pub trait AnotherTrick {}
+}
+
+mod a {
+    use crate::m::TryIntoU32;
+
+    fn main() {
+        // In this case, we can just use `TryIntoU32`
+        let _: u32 = 3u8.try_into().unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    }
+}
+
+mod b {
+    use crate::m::AnotherTrick as TryIntoU32;
+    use crate::m::TryIntoU32 as _;
+
+    fn main() {
+        // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use
+        // the path `crate::m::TryIntoU32` (with which it was imported).
+        let _: u32 = 3u8.try_into().unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    }
+}
+
+mod c {
+    use super::m::TryIntoU32 as _;
+    use crate::m::AnotherTrick as TryIntoU32;
+
+    fn main() {
+        // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use
+        // the path `super::m::TryIntoU32` (with which it was imported).
+        let _: u32 = 3u8.try_into().unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
new file mode 100644
index 00000000000..3903cbfe824
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
@@ -0,0 +1,34 @@
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-imported.rs:27:22
+   |
+LL |         let _: u32 = 3u8.try_into().unwrap();
+   |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
+   |
+note: the lint level is defined here
+  --> $DIR/future-prelude-collision-imported.rs:4:9
+   |
+LL | #![warn(future_prelude_collision)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-imported.rs:40:22
+   |
+LL |         let _: u32 = 3u8.try_into().unwrap();
+   |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `crate::m::TryIntoU32::try_into(3u8)`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-imported.rs:53:22
+   |
+LL |         let _: u32 = 3u8.try_into().unwrap();
+   |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `super::m::TryIntoU32::try_into(3u8)`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.rs b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs
new file mode 100644
index 00000000000..c9d2529341f
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs
@@ -0,0 +1,32 @@
+// edition:2018
+#![warn(future_prelude_collision)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+mod m {
+    pub trait TryIntoU32 {
+        fn try_into(self) -> Result<u32, ()>;
+    }
+
+    impl TryIntoU32 for u8 {
+        fn try_into(self) -> Result<u32, ()> {
+            Ok(self as u32)
+        }
+    }
+
+    pub trait AnotherTrick {}
+}
+
+mod d {
+    use crate::m::AnotherTrick as TryIntoU32;
+    use crate::m::*;
+
+    fn main() {
+        // Here, `TryIntoU32` is imported but shadowed, but in that case we don't permit its methods
+        // to be available.
+        let _: u32 = 3u8.try_into().unwrap();
+        //~^ ERROR no method named `try_into` found for type `u8` in the current scope
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr
new file mode 100644
index 00000000000..ad9b8af00e4
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr
@@ -0,0 +1,40 @@
+error[E0599]: no method named `try_into` found for type `u8` in the current scope
+  --> $DIR/future-prelude-collision-shadow.rs:27:26
+   |
+LL |         let _: u32 = 3u8.try_into().unwrap();
+   |                          ^^^^^^^^ method not found in `u8`
+   | 
+  ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL
+   |
+LL |     fn try_into(self) -> Result<T, Self::Error>;
+   |        --------
+   |        |
+   |        the method is available for `Box<u8>` here
+   |        the method is available for `Pin<u8>` here
+   |        the method is available for `Arc<u8>` here
+   |        the method is available for `Rc<u8>` here
+   |
+   = help: items from traits can only be used if the trait is in scope
+   = note: the following traits are implemented but not in scope; perhaps add a `use` for one of them:
+           candidate #1: `use crate::m::TryIntoU32;`
+           candidate #2: `use std::convert::TryInto;`
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |         let _: u32 = Box::new(3u8).try_into().unwrap();
+   |                      ^^^^^^^^^   ^
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |         let _: u32 = Pin::new(3u8).try_into().unwrap();
+   |                      ^^^^^^^^^   ^
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |         let _: u32 = Arc::new(3u8).try_into().unwrap();
+   |                      ^^^^^^^^^   ^
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |         let _: u32 = Rc::new(3u8).try_into().unwrap();
+   |                      ^^^^^^^^   ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/rust-2021/future-prelude-collision.fixed b/src/test/ui/rust-2021/future-prelude-collision.fixed
new file mode 100644
index 00000000000..9ede9f3a2fb
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision.fixed
@@ -0,0 +1,96 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(future_prelude_collision)]
+
+trait TryIntoU32 {
+    fn try_into(self) -> Result<u32, ()>;
+}
+
+impl TryIntoU32 for u8 {
+    fn try_into(self) -> Result<u32, ()> {
+        Ok(self as u32)
+    }
+}
+
+// needed for autoref test
+impl TryIntoU32 for &f32 {
+    fn try_into(self) -> Result<u32, ()> {
+        Ok(*self as u32)
+    }
+}
+
+trait TryFromU8: Sized {
+    fn try_from(x: u8) -> Result<Self, ()>;
+}
+
+impl TryFromU8 for u32 {
+    fn try_from(x: u8) -> Result<Self, ()> {
+        Ok(x as u32)
+    }
+}
+
+impl TryIntoU32 for *const u16 {
+    fn try_into(self) -> Result<u32, ()> {
+        Ok(unsafe { *self } as u32)
+    }
+}
+
+trait FromByteIterator {
+    fn from_iter<T>(iter: T) -> Self
+        where T: Iterator<Item = u8>;
+}
+
+impl FromByteIterator for Vec<u8> {
+    fn from_iter<T>(iter: T) -> Self
+        where T: Iterator<Item = u8>
+    {
+        iter.collect()
+    }
+}
+
+fn main() {
+    // test dot-call that will break in 2021 edition
+    let _: u32 = TryIntoU32::try_into(3u8).unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test associated function call that will break in 2021 edition
+    let _ = <u32 as TryFromU8>::try_from(3u8).unwrap();
+    //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test reverse turbofish too
+    let _ = <Vec<u8> as FromByteIterator>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // negative testing lint (this line should *not* emit a warning)
+    let _: u32 = TryFromU8::try_from(3u8).unwrap();
+
+    // test type omission
+    let _: u32 = <_ as TryFromU8>::try_from(3u8).unwrap();
+    //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test autoderef
+    let _: u32 = TryIntoU32::try_into(*(&3u8)).unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test autoref
+    let _: u32 = TryIntoU32::try_into(&3.0).unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    let mut data = 3u16;
+    let mut_ptr = std::ptr::addr_of_mut!(data);
+    let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    type U32Alias = u32;
+    let _ = <U32Alias as TryFromU8>::try_from(3u8).unwrap();
+    //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision.rs b/src/test/ui/rust-2021/future-prelude-collision.rs
new file mode 100644
index 00000000000..914e910396a
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision.rs
@@ -0,0 +1,96 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(future_prelude_collision)]
+
+trait TryIntoU32 {
+    fn try_into(self) -> Result<u32, ()>;
+}
+
+impl TryIntoU32 for u8 {
+    fn try_into(self) -> Result<u32, ()> {
+        Ok(self as u32)
+    }
+}
+
+// needed for autoref test
+impl TryIntoU32 for &f32 {
+    fn try_into(self) -> Result<u32, ()> {
+        Ok(*self as u32)
+    }
+}
+
+trait TryFromU8: Sized {
+    fn try_from(x: u8) -> Result<Self, ()>;
+}
+
+impl TryFromU8 for u32 {
+    fn try_from(x: u8) -> Result<Self, ()> {
+        Ok(x as u32)
+    }
+}
+
+impl TryIntoU32 for *const u16 {
+    fn try_into(self) -> Result<u32, ()> {
+        Ok(unsafe { *self } as u32)
+    }
+}
+
+trait FromByteIterator {
+    fn from_iter<T>(iter: T) -> Self
+        where T: Iterator<Item = u8>;
+}
+
+impl FromByteIterator for Vec<u8> {
+    fn from_iter<T>(iter: T) -> Self
+        where T: Iterator<Item = u8>
+    {
+        iter.collect()
+    }
+}
+
+fn main() {
+    // test dot-call that will break in 2021 edition
+    let _: u32 = 3u8.try_into().unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test associated function call that will break in 2021 edition
+    let _ = u32::try_from(3u8).unwrap();
+    //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test reverse turbofish too
+    let _ = <Vec<u8>>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // negative testing lint (this line should *not* emit a warning)
+    let _: u32 = TryFromU8::try_from(3u8).unwrap();
+
+    // test type omission
+    let _: u32 = <_>::try_from(3u8).unwrap();
+    //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test autoderef
+    let _: u32 = (&3u8).try_into().unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    // test autoref
+    let _: u32 = 3.0.try_into().unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    let mut data = 3u16;
+    let mut_ptr = std::ptr::addr_of_mut!(data);
+    let _: u32 = mut_ptr.try_into().unwrap();
+    //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+
+    type U32Alias = u32;
+    let _ = U32Alias::try_from(3u8).unwrap();
+    //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision.stderr b/src/test/ui/rust-2021/future-prelude-collision.stderr
new file mode 100644
index 00000000000..190145ef4db
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision.stderr
@@ -0,0 +1,79 @@
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:54:18
+   |
+LL |     let _: u32 = 3u8.try_into().unwrap();
+   |                  ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
+   |
+note: the lint level is defined here
+  --> $DIR/future-prelude-collision.rs:4:9
+   |
+LL | #![warn(future_prelude_collision)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:59:13
+   |
+LL |     let _ = u32::try_from(3u8).unwrap();
+   |             ^^^^^^^^^^^^^ help: disambiguate the associated function: `<u32 as TryFromU8>::try_from`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:64:13
+   |
+LL |     let _ = <Vec<u8>>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
+   |             ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<u8> as FromByteIterator>::from_iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:72:18
+   |
+LL |     let _: u32 = <_>::try_from(3u8).unwrap();
+   |                  ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:77:18
+   |
+LL |     let _: u32 = (&3u8).try_into().unwrap();
+   |                  ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:82:18
+   |
+LL |     let _: u32 = 3.0.try_into().unwrap();
+   |                  ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:88:18
+   |
+LL |     let _: u32 = mut_ptr.try_into().unwrap();
+   |                  ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision.rs:93:13
+   |
+LL |     let _ = U32Alias::try_from(3u8).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<U32Alias as TryFromU8>::try_from`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 8 warnings emitted
+
diff --git a/src/test/ui/rust-2021/generic-type-collision.fixed b/src/test/ui/rust-2021/generic-type-collision.fixed
new file mode 100644
index 00000000000..00fb128a981
--- /dev/null
+++ b/src/test/ui/rust-2021/generic-type-collision.fixed
@@ -0,0 +1,18 @@
+// check-pass
+// run-rustfix
+// edition 2018
+#![warn(future_prelude_collision)]
+
+trait MyTrait<A> {
+    fn from_iter(x: Option<A>);
+}
+
+impl<T> MyTrait<()> for Vec<T> {
+    fn from_iter(_: Option<()>) {}
+}
+
+fn main() {
+    <Vec<i32> as MyTrait<_>>::from_iter(None);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+}
diff --git a/src/test/ui/rust-2021/generic-type-collision.rs b/src/test/ui/rust-2021/generic-type-collision.rs
new file mode 100644
index 00000000000..406fba4d247
--- /dev/null
+++ b/src/test/ui/rust-2021/generic-type-collision.rs
@@ -0,0 +1,18 @@
+// check-pass
+// run-rustfix
+// edition 2018
+#![warn(future_prelude_collision)]
+
+trait MyTrait<A> {
+    fn from_iter(x: Option<A>);
+}
+
+impl<T> MyTrait<()> for Vec<T> {
+    fn from_iter(_: Option<()>) {}
+}
+
+fn main() {
+    <Vec<i32>>::from_iter(None);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+}
diff --git a/src/test/ui/rust-2021/generic-type-collision.stderr b/src/test/ui/rust-2021/generic-type-collision.stderr
new file mode 100644
index 00000000000..9374379d247
--- /dev/null
+++ b/src/test/ui/rust-2021/generic-type-collision.stderr
@@ -0,0 +1,16 @@
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/generic-type-collision.rs:15:5
+   |
+LL |     <Vec<i32>>::from_iter(None);
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<i32> as MyTrait<_>>::from_iter`
+   |
+note: the lint level is defined here
+  --> $DIR/generic-type-collision.rs:4:9
+   |
+LL | #![warn(future_prelude_collision)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.fixed b/src/test/ui/rust-2021/inherent-dyn-collision.fixed
new file mode 100644
index 00000000000..cbb6e9659df
--- /dev/null
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.fixed
@@ -0,0 +1,53 @@
+// Test case where the method we want is an inherent method on a
+// dyn Trait. In that case, the fix is to insert `*` on the receiver.
+//
+// check-pass
+// run-rustfix
+// edition:2018
+
+#![warn(future_prelude_collision)]
+
+trait TryIntoU32 {
+    fn try_into(&self) -> Result<u32, ()>;
+}
+
+impl TryIntoU32 for u8 {
+    // note: &self
+    fn try_into(&self) -> Result<u32, ()> {
+        Ok(22)
+    }
+}
+
+mod inner {
+    use super::get_dyn_trait;
+
+    // note: this does nothing, but is copying from ffishim's problem of
+    // having a struct of the same name as the trait in-scope, while *also*
+    // implementing the trait for that struct but **without** importing the
+    // trait itself into scope
+    struct TryIntoU32;
+
+    impl super::TryIntoU32 for TryIntoU32 {
+        fn try_into(&self) -> Result<u32, ()> {
+            Ok(0)
+        }
+    }
+
+    // this is where the gross part happens. since `get_dyn_trait` returns
+    // a Box<dyn Trait>, it can still call the method for `dyn Trait` without
+    // `Trait` being in-scope. it might even be possible to make the trait itself
+    // entirely unreference-able from the callsite?
+    pub fn test() -> u32 {
+        (&*get_dyn_trait()).try_into().unwrap()
+        //~^ WARNING trait method `try_into` will become ambiguous
+        //~| WARNING this was previously accepted
+    }
+}
+
+fn get_dyn_trait() -> Box<dyn TryIntoU32> {
+    Box::new(3u8) as Box<dyn TryIntoU32>
+}
+
+fn main() {
+    dbg!(inner::test());
+}
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.rs b/src/test/ui/rust-2021/inherent-dyn-collision.rs
new file mode 100644
index 00000000000..1c9929eff91
--- /dev/null
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.rs
@@ -0,0 +1,53 @@
+// Test case where the method we want is an inherent method on a
+// dyn Trait. In that case, the fix is to insert `*` on the receiver.
+//
+// check-pass
+// run-rustfix
+// edition:2018
+
+#![warn(future_prelude_collision)]
+
+trait TryIntoU32 {
+    fn try_into(&self) -> Result<u32, ()>;
+}
+
+impl TryIntoU32 for u8 {
+    // note: &self
+    fn try_into(&self) -> Result<u32, ()> {
+        Ok(22)
+    }
+}
+
+mod inner {
+    use super::get_dyn_trait;
+
+    // note: this does nothing, but is copying from ffishim's problem of
+    // having a struct of the same name as the trait in-scope, while *also*
+    // implementing the trait for that struct but **without** importing the
+    // trait itself into scope
+    struct TryIntoU32;
+
+    impl super::TryIntoU32 for TryIntoU32 {
+        fn try_into(&self) -> Result<u32, ()> {
+            Ok(0)
+        }
+    }
+
+    // this is where the gross part happens. since `get_dyn_trait` returns
+    // a Box<dyn Trait>, it can still call the method for `dyn Trait` without
+    // `Trait` being in-scope. it might even be possible to make the trait itself
+    // entirely unreference-able from the callsite?
+    pub fn test() -> u32 {
+        get_dyn_trait().try_into().unwrap()
+        //~^ WARNING trait method `try_into` will become ambiguous
+        //~| WARNING this was previously accepted
+    }
+}
+
+fn get_dyn_trait() -> Box<dyn TryIntoU32> {
+    Box::new(3u8) as Box<dyn TryIntoU32>
+}
+
+fn main() {
+    dbg!(inner::test());
+}
diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.stderr b/src/test/ui/rust-2021/inherent-dyn-collision.stderr
new file mode 100644
index 00000000000..3d7637100c2
--- /dev/null
+++ b/src/test/ui/rust-2021/inherent-dyn-collision.stderr
@@ -0,0 +1,16 @@
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/inherent-dyn-collision.rs:41:9
+   |
+LL |         get_dyn_trait().try_into().unwrap()
+   |         ^^^^^^^^^^^^^^^ help: disambiguate the method call: `(&*get_dyn_trait())`
+   |
+note: the lint level is defined here
+  --> $DIR/inherent-dyn-collision.rs:8:9
+   |
+LL | #![warn(future_prelude_collision)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/rust-2021/inherent-method-collision.rs b/src/test/ui/rust-2021/inherent-method-collision.rs
new file mode 100644
index 00000000000..c638351d5fc
--- /dev/null
+++ b/src/test/ui/rust-2021/inherent-method-collision.rs
@@ -0,0 +1,15 @@
+// Test that we do NOT warn for inherent methods invoked via `T::` form.
+//
+// check-pass
+
+#![deny(future_prelude_collision)]
+
+pub struct MySeq {}
+
+impl MySeq {
+    pub fn from_iter(_: impl IntoIterator<Item = u32>) {}
+}
+
+fn main() {
+    MySeq::from_iter(Some(22));
+}