diff options
| author | bors <bors@rust-lang.org> | 2021-06-22 07:01:54 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-06-22 07:01:54 +0000 |
| commit | 44f4a87d7047db0deff5ef033fd2af820722e9a5 (patch) | |
| tree | 4960627de594af7fc920104a8f40245e480485e9 /src | |
| parent | c38111c4fb9c22a36f9a9195d1884052bb670af2 (diff) | |
| parent | aa3580baa6f5ef69aba41a63297fb659bcd4b793 (diff) | |
| download | rust-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')
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)); +} |
