summaryrefslogtreecommitdiffstats
path: root/src/test/ui/rust-2021
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/rust-2021')
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.fixed27
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.rs27
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.stderr16
-rw-r--r--src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs25
-rw-r--r--src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs25
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed30
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs30
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr16
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.fixed37
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.rs37
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.stderr34
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.fixed70
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.rs70
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.stderr43
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-macros.fixed45
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-macros.rs45
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-macros.stderr25
-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.stderr18
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-turbofish.fixed28
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-turbofish.rs28
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr25
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-unneeded.rs60
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.fixed98
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision.rs98
-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
-rw-r--r--src/test/ui/rust-2021/panic.rs24
-rw-r--r--src/test/ui/rust-2021/panic.stderr101
-rw-r--r--src/test/ui/rust-2021/prelude2021.rs6
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.fixed38
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.rs38
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-migration.stderr77
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs21
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr29
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes-via-macro.rs12
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes.rs36
-rw-r--r--src/test/ui/rust-2021/reserved-prefixes.stderr119
44 files changed, 1758 insertions, 0 deletions
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed b/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed
new file mode 100644
index 000000000..76f661bae
--- /dev/null
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed
@@ -0,0 +1,27 @@
+// See https://github.com/rust-lang/rust/issues/88475
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(array_into_iter)]
+#![allow(unused)]
+
+struct FooIter;
+
+trait MyIntoIter {
+ fn into_iter(self) -> FooIter;
+}
+
+impl<T, const N: usize> MyIntoIter for [T; N] {
+ fn into_iter(self) -> FooIter {
+ FooIter
+ }
+}
+
+struct Point;
+
+pub fn main() {
+ let points: [Point; 1] = [Point];
+ let y = MyIntoIter::into_iter(points);
+ //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021
+ //~| WARNING this changes meaning in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.rs b/src/test/ui/rust-2021/array-into-iter-ambiguous.rs
new file mode 100644
index 000000000..83fbf8f6c
--- /dev/null
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.rs
@@ -0,0 +1,27 @@
+// See https://github.com/rust-lang/rust/issues/88475
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(array_into_iter)]
+#![allow(unused)]
+
+struct FooIter;
+
+trait MyIntoIter {
+ fn into_iter(self) -> FooIter;
+}
+
+impl<T, const N: usize> MyIntoIter for [T; N] {
+ fn into_iter(self) -> FooIter {
+ FooIter
+ }
+}
+
+struct Point;
+
+pub fn main() {
+ let points: [Point; 1] = [Point];
+ let y = points.into_iter();
+ //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021
+ //~| WARNING this changes meaning in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
new file mode 100644
index 000000000..fac8d21c7
--- /dev/null
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
@@ -0,0 +1,16 @@
+warning: trait method `into_iter` will become ambiguous in Rust 2021
+ --> $DIR/array-into-iter-ambiguous.rs:24:13
+ |
+LL | let y = points.into_iter();
+ | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
+ |
+note: the lint level is defined here
+ --> $DIR/array-into-iter-ambiguous.rs:5:9
+ |
+LL | #![warn(array_into_iter)]
+ | ^^^^^^^^^^^^^^^
+ = warning: this changes meaning in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs
new file mode 100644
index 000000000..eb301e5e1
--- /dev/null
+++ b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2018.rs
@@ -0,0 +1,25 @@
+// force-host
+// edition:2018
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use std::str::FromStr;
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_integer_literal(_: TokenStream) -> TokenStream {
+ TokenStream::from_str("hey#123").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_char_literal(_: TokenStream) -> TokenStream {
+ TokenStream::from_str("hey#'a'").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_string_literal(_: TokenStream) -> TokenStream {
+ TokenStream::from_str("hey#\"abc\"").unwrap().into_iter().count().to_string().parse().unwrap()
+}
diff --git a/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs
new file mode 100644
index 000000000..691bfdc15
--- /dev/null
+++ b/src/test/ui/rust-2021/auxiliary/reserved-prefixes-macro-2021.rs
@@ -0,0 +1,25 @@
+// force-host
+// edition:2021
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use std::str::FromStr;
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_integer_literal(_: TokenStream) -> TokenStream {
+ TokenStream::from_str("hey#123").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_char_literal(_: TokenStream) -> TokenStream {
+ TokenStream::from_str("hey#'a'").unwrap().into_iter().count().to_string().parse().unwrap()
+}
+
+#[proc_macro]
+pub fn number_of_tokens_in_a_prefixed_string_literal(_: TokenStream) -> TokenStream {
+ TokenStream::from_str("hey#\"abc\"").unwrap().into_iter().count().to_string().parse().unwrap()
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed
new file mode 100644
index 000000000..a1b6f5b16
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed
@@ -0,0 +1,30 @@
+// See https://github.com/rust-lang/rust/issues/88470
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+pub trait PyTryFrom<'v, T>: Sized {
+ fn try_from<V>(value: V) -> Result<&'v Self, T>;
+}
+
+pub trait PyTryInto<T>: Sized {
+ fn try_into(&self) -> Result<&T, i32>;
+}
+
+struct Foo;
+
+impl<U> PyTryInto<U> for Foo
+where
+ U: for<'v> PyTryFrom<'v, i32>,
+{
+ fn try_into(&self) -> Result<&U, i32> {
+ <U as PyTryFrom<'_, _>>::try_from(self)
+ //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs
new file mode 100644
index 000000000..142ba5520
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs
@@ -0,0 +1,30 @@
+// See https://github.com/rust-lang/rust/issues/88470
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+pub trait PyTryFrom<'v, T>: Sized {
+ fn try_from<V>(value: V) -> Result<&'v Self, T>;
+}
+
+pub trait PyTryInto<T>: Sized {
+ fn try_into(&self) -> Result<&T, i32>;
+}
+
+struct Foo;
+
+impl<U> PyTryInto<U> for Foo
+where
+ U: for<'v> PyTryFrom<'v, i32>,
+{
+ fn try_into(&self) -> Result<&U, i32> {
+ U::try_from(self)
+ //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
new file mode 100644
index 000000000..14ad9b017
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
@@ -0,0 +1,16 @@
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-generic-trait.rs:24:9
+ |
+LL | U::try_from(self)
+ | ^^^^^^^^^^^ help: disambiguate the associated function: `<U as PyTryFrom<'_, _>>::try_from`
+ |
+note: the lint level is defined here
+ --> $DIR/future-prelude-collision-generic-trait.rs:5:9
+ |
+LL | #![warn(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
new file mode 100644
index 000000000..1bb9ba377
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
@@ -0,0 +1,37 @@
+// test for https://github.com/rust-lang/rust/issues/86940
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+struct Generic<'a, U>(&'a U);
+
+trait MyFromIter {
+ fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<'static, i32> {
+ fn from_iter(_: i32) -> Self {
+ todo!()
+ }
+}
+
+impl std::iter::FromIterator<i32> for Generic<'static, i32> {
+ fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
+ todo!()
+ }
+}
+
+fn main() {
+ <Generic<'_, _> as MyFromIter>::from_iter(1);
+ //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+ <Generic::<'static, i32> as MyFromIter>::from_iter(1);
+ //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+ <Generic::<'_, _> as MyFromIter>::from_iter(1);
+ //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.rs b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
new file mode 100644
index 000000000..d7f8affc6
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
@@ -0,0 +1,37 @@
+// test for https://github.com/rust-lang/rust/issues/86940
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+struct Generic<'a, U>(&'a U);
+
+trait MyFromIter {
+ fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<'static, i32> {
+ fn from_iter(_: i32) -> Self {
+ todo!()
+ }
+}
+
+impl std::iter::FromIterator<i32> for Generic<'static, i32> {
+ fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
+ todo!()
+ }
+}
+
+fn main() {
+ Generic::from_iter(1);
+ //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+ Generic::<'static, i32>::from_iter(1);
+ //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+ Generic::<'_, _>::from_iter(1);
+ //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+ //~| this is accepted in the current edition (Rust 2018)
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
new file mode 100644
index 000000000..e1d3f3c0a
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
@@ -0,0 +1,34 @@
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-generic.rs:28:5
+ |
+LL | Generic::from_iter(1);
+ | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<'_, _> as MyFromIter>::from_iter`
+ |
+note: the lint level is defined here
+ --> $DIR/future-prelude-collision-generic.rs:5:9
+ |
+LL | #![warn(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-generic.rs:31:5
+ |
+LL | Generic::<'static, i32>::from_iter(1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'static, i32> as MyFromIter>::from_iter`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-generic.rs:34:5
+ |
+LL | Generic::<'_, _>::from_iter(1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'_, _> as MyFromIter>::from_iter`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 3 warnings emitted
+
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 000000000..15ccff749
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
@@ -0,0 +1,70 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![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 is accepted in the current 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 is accepted in the current 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 is accepted in the current edition
+ }
+}
+
+mod d {
+ use super::m::*;
+
+ fn main() {
+ // See https://github.com/rust-lang/rust/issues/88471
+ let _: u32 = TryIntoU32::try_into(3u8).unwrap();
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current 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 000000000..cdffcaf75
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
@@ -0,0 +1,70 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![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 is accepted in the current 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 is accepted in the current 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 is accepted in the current edition
+ }
+}
+
+mod d {
+ use super::m::*;
+
+ fn main() {
+ // See https://github.com/rust-lang/rust/issues/88471
+ let _: u32 = 3u8.try_into().unwrap();
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current 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 000000000..56abb8abd
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
@@ -0,0 +1,43 @@
+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(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+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 is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+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 is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-imported.rs:64:22
+ |
+LL | let _: u32 = 3u8.try_into().unwrap();
+ | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 4 warnings emitted
+
diff --git a/src/test/ui/rust-2021/future-prelude-collision-macros.fixed b/src/test/ui/rust-2021/future-prelude-collision-macros.fixed
new file mode 100644
index 000000000..a97dc176e
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-macros.fixed
@@ -0,0 +1,45 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(unreachable_code)]
+
+macro_rules! foo {
+ () => {{
+ 123;
+ S
+ }};
+}
+
+trait MyTry<T> {
+ fn try_into(self, _: u8);
+}
+
+struct S;
+
+impl MyTry<i32> for S {
+ fn try_into(self, _: u8) {}
+}
+
+trait TryFromU8: Sized {
+ fn try_from(_: u8);
+}
+
+impl TryFromU8 for u32 {
+ fn try_from(_: u8) {}
+}
+
+macro_rules! bar {
+ () => {
+ u32
+ };
+}
+
+fn main() {
+ MyTry::try_into(foo!(), todo!());
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition
+ <bar!() as TryFromU8>::try_from(0);
+ //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-macros.rs b/src/test/ui/rust-2021/future-prelude-collision-macros.rs
new file mode 100644
index 000000000..82484b5b3
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-macros.rs
@@ -0,0 +1,45 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(unreachable_code)]
+
+macro_rules! foo {
+ () => {{
+ 123;
+ S
+ }};
+}
+
+trait MyTry<T> {
+ fn try_into(self, _: u8);
+}
+
+struct S;
+
+impl MyTry<i32> for S {
+ fn try_into(self, _: u8) {}
+}
+
+trait TryFromU8: Sized {
+ fn try_from(_: u8);
+}
+
+impl TryFromU8 for u32 {
+ fn try_from(_: u8) {}
+}
+
+macro_rules! bar {
+ () => {
+ u32
+ };
+}
+
+fn main() {
+ foo!().try_into(todo!());
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition
+ <bar!()>::try_from(0);
+ //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-macros.stderr b/src/test/ui/rust-2021/future-prelude-collision-macros.stderr
new file mode 100644
index 000000000..4c3543ca7
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-macros.stderr
@@ -0,0 +1,25 @@
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-macros.rs:39:5
+ |
+LL | foo!().try_into(todo!());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyTry::try_into(foo!(), todo!())`
+ |
+note: the lint level is defined here
+ --> $DIR/future-prelude-collision-macros.rs:4:9
+ |
+LL | #![warn(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-macros.rs:42:5
+ |
+LL | <bar!()>::try_from(0);
+ | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<bar!() as TryFromU8>::try_from`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 2 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 000000000..27891a8d1
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs
@@ -0,0 +1,32 @@
+// edition:2018
+#![warn(rust_2021_prelude_collisions)]
+#![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 000000000..3d21b735a
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr
@@ -0,0 +1,18 @@
+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`
+ |
+ = help: items from traits can only be used if the trait is in scope
+ = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021
+help: the following traits are implemented but not in scope; perhaps add a `use` for one of them:
+ |
+LL | use crate::m::TryIntoU32;
+ |
+LL | use std::convert::TryInto;
+ |
+
+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-turbofish.fixed b/src/test/ui/rust-2021/future-prelude-collision-turbofish.fixed
new file mode 100644
index 000000000..3e76fced7
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-turbofish.fixed
@@ -0,0 +1,28 @@
+// See https://github.com/rust-lang/rust/issues/88442
+// run-rustfix
+// edition:2018
+// check-pass
+#![allow(unused)]
+#![warn(rust_2021_prelude_collisions)]
+
+trait AnnotatableTryInto {
+ fn try_into<T>(self) -> Result<T, Self::Error>
+ where Self: std::convert::TryInto<T> {
+ std::convert::TryInto::try_into(self)
+ }
+}
+
+impl<T> AnnotatableTryInto for T where T: From<u8> {}
+
+fn main() -> Result<(), &'static str> {
+ let x: u64 = 1;
+ AnnotatableTryInto::try_into::<usize>(x).or(Err("foo"))?.checked_sub(1);
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+
+ AnnotatableTryInto::try_into::<usize>(x).or(Err("foo"))?;
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+
+ Ok(())
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-turbofish.rs b/src/test/ui/rust-2021/future-prelude-collision-turbofish.rs
new file mode 100644
index 000000000..abb292ef9
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-turbofish.rs
@@ -0,0 +1,28 @@
+// See https://github.com/rust-lang/rust/issues/88442
+// run-rustfix
+// edition:2018
+// check-pass
+#![allow(unused)]
+#![warn(rust_2021_prelude_collisions)]
+
+trait AnnotatableTryInto {
+ fn try_into<T>(self) -> Result<T, Self::Error>
+ where Self: std::convert::TryInto<T> {
+ std::convert::TryInto::try_into(self)
+ }
+}
+
+impl<T> AnnotatableTryInto for T where T: From<u8> {}
+
+fn main() -> Result<(), &'static str> {
+ let x: u64 = 1;
+ x.try_into::<usize>().or(Err("foo"))?.checked_sub(1);
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+
+ x.try_into::<usize>().or(Err("foo"))?;
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+
+ Ok(())
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr b/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr
new file mode 100644
index 000000000..2de9020bc
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr
@@ -0,0 +1,25 @@
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-turbofish.rs:19:5
+ |
+LL | x.try_into::<usize>().or(Err("foo"))?.checked_sub(1);
+ | ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `AnnotatableTryInto::try_into::<usize>(x)`
+ |
+note: the lint level is defined here
+ --> $DIR/future-prelude-collision-turbofish.rs:6:9
+ |
+LL | #![warn(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision-turbofish.rs:23:5
+ |
+LL | x.try_into::<usize>().or(Err("foo"))?;
+ | ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `AnnotatableTryInto::try_into::<usize>(x)`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 2 warnings emitted
+
diff --git a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs
new file mode 100644
index 000000000..247d5884b
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs
@@ -0,0 +1,60 @@
+// edition:2018
+// check-pass
+#![allow(unused)]
+#![deny(rust_2021_prelude_collisions)]
+
+struct S;
+
+impl S {
+ fn try_into(self) -> S {
+ S
+ }
+}
+
+struct X;
+
+trait Hey {
+ fn from_iter(_: i32) -> Self;
+}
+
+impl Hey for X {
+ fn from_iter(_: i32) -> Self {
+ X
+ }
+}
+
+struct Y<T>(T);
+
+impl Hey for Y<i32> {
+ fn from_iter(_: i32) -> Self {
+ Y(0)
+ }
+}
+
+struct Z<T>(T);
+
+impl Hey for Z<i32> {
+ fn from_iter(_: i32) -> Self {
+ Z(0)
+ }
+}
+
+impl std::iter::FromIterator<u32> for Z<u32> {
+ fn from_iter<T: IntoIterator<Item = u32>>(_: T) -> Self {
+ todo!()
+ }
+}
+
+fn main() {
+ // See https://github.com/rust-lang/rust/issues/86633
+ let s = S;
+ let s2 = s.try_into();
+
+ // Check that we do not issue suggestions for types that do not implement `FromIter`.
+ //
+ // See https://github.com/rust-lang/rust/issues/86902
+ X::from_iter(1);
+ Y::from_iter(1);
+ Y::<i32>::from_iter(1);
+ Z::<i32>::from_iter(1);
+}
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 000000000..43b0ec1c3
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision.fixed
@@ -0,0 +1,98 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+
+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 is accepted in the current 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 is accepted in the current 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 is accepted in the current 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 is accepted in the current edition
+
+ // test autoderef
+ let _: u32 = TryIntoU32::try_into(*(&3u8)).unwrap();
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current edition
+
+ // test autoref
+ let _: u32 = TryIntoU32::try_into(&3.0).unwrap();
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current 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 is accepted in the current 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 is accepted in the current 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 000000000..4c7a47ffb
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision.rs
@@ -0,0 +1,98 @@
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+
+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 is accepted in the current 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 is accepted in the current 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 is accepted in the current 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 is accepted in the current edition
+
+ // test autoderef
+ let _: u32 = (&3u8).try_into().unwrap();
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current edition
+
+ // test autoref
+ let _: u32 = 3.0.try_into().unwrap();
+ //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current 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 is accepted in the current edition
+
+ type U32Alias = u32;
+ let _ = U32Alias::try_from(3u8).unwrap();
+ //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+ //~^^ WARNING this is accepted in the current 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 000000000..889e66de0
--- /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:56: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(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:61:13
+ |
+LL | let _ = u32::try_from(3u8).unwrap();
+ | ^^^^^^^^^^^^^ help: disambiguate the associated function: `<u32 as TryFromU8>::try_from`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:66: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 is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:74:18
+ |
+LL | let _: u32 = <_>::try_from(3u8).unwrap();
+ | ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:79:18
+ |
+LL | let _: u32 = (&3u8).try_into().unwrap();
+ | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:84:18
+ |
+LL | let _: u32 = 3.0.try_into().unwrap();
+ | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait method `try_into` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:90:18
+ |
+LL | let _: u32 = mut_ptr.try_into().unwrap();
+ | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+ --> $DIR/future-prelude-collision.rs:95:13
+ |
+LL | let _ = U32Alias::try_from(3u8).unwrap();
+ | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<U32Alias as TryFromU8>::try_from`
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+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 000000000..feba7d19b
--- /dev/null
+++ b/src/test/ui/rust-2021/generic-type-collision.fixed
@@ -0,0 +1,18 @@
+// check-pass
+// run-rustfix
+// edition 2018
+#![warn(rust_2021_prelude_collisions)]
+
+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 is accepted in the current 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 000000000..335e7e520
--- /dev/null
+++ b/src/test/ui/rust-2021/generic-type-collision.rs
@@ -0,0 +1,18 @@
+// check-pass
+// run-rustfix
+// edition 2018
+#![warn(rust_2021_prelude_collisions)]
+
+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 is accepted in the current 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 000000000..e6ea28d71
--- /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(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+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 000000000..5789a9039
--- /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(rust_2021_prelude_collisions)]
+
+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 is accepted in the current edition
+ }
+}
+
+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 000000000..a3893c033
--- /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(rust_2021_prelude_collisions)]
+
+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 is accepted in the current edition
+ }
+}
+
+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 000000000..77b4c3851
--- /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(rust_2021_prelude_collisions)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+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 000000000..507105207
--- /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(rust_2021_prelude_collisions)]
+
+pub struct MySeq {}
+
+impl MySeq {
+ pub fn from_iter(_: impl IntoIterator<Item = u32>) {}
+}
+
+fn main() {
+ MySeq::from_iter(Some(22));
+}
diff --git a/src/test/ui/rust-2021/panic.rs b/src/test/ui/rust-2021/panic.rs
new file mode 100644
index 000000000..394fc3c8f
--- /dev/null
+++ b/src/test/ui/rust-2021/panic.rs
@@ -0,0 +1,24 @@
+// edition:2021
+
+fn main() {
+ debug_assert!(false, 123);
+ //~^ ERROR must be a string literal
+ assert!(false, 123);
+ //~^ ERROR must be a string literal
+ panic!(false, 123);
+ //~^ ERROR must be a string literal
+
+ std::debug_assert!(false, 123);
+ //~^ ERROR must be a string literal
+ std::assert!(false, 123);
+ //~^ ERROR must be a string literal
+ std::panic!(false, 123);
+ //~^ ERROR must be a string literal
+
+ core::debug_assert!(false, 123);
+ //~^ ERROR must be a string literal
+ core::assert!(false, 123);
+ //~^ ERROR must be a string literal
+ core::panic!(false, 123);
+ //~^ ERROR must be a string literal
+}
diff --git a/src/test/ui/rust-2021/panic.stderr b/src/test/ui/rust-2021/panic.stderr
new file mode 100644
index 000000000..40b62d279
--- /dev/null
+++ b/src/test/ui/rust-2021/panic.stderr
@@ -0,0 +1,101 @@
+error: format argument must be a string literal
+ --> $DIR/panic.rs:4:26
+ |
+LL | debug_assert!(false, 123);
+ | ^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | debug_assert!(false, "{}", 123);
+ | +++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:6:20
+ |
+LL | assert!(false, 123);
+ | ^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | assert!(false, "{}", 123);
+ | +++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:8:12
+ |
+LL | panic!(false, 123);
+ | ^^^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | panic!("{} {}", false, 123);
+ | ++++++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:11:31
+ |
+LL | std::debug_assert!(false, 123);
+ | ^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | std::debug_assert!(false, "{}", 123);
+ | +++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:13:25
+ |
+LL | std::assert!(false, 123);
+ | ^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | std::assert!(false, "{}", 123);
+ | +++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:15:17
+ |
+LL | std::panic!(false, 123);
+ | ^^^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | std::panic!("{} {}", false, 123);
+ | ++++++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:18:32
+ |
+LL | core::debug_assert!(false, 123);
+ | ^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | core::debug_assert!(false, "{}", 123);
+ | +++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:20:26
+ |
+LL | core::assert!(false, 123);
+ | ^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | core::assert!(false, "{}", 123);
+ | +++++
+
+error: format argument must be a string literal
+ --> $DIR/panic.rs:22:18
+ |
+LL | core::panic!(false, 123);
+ | ^^^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | core::panic!("{} {}", false, 123);
+ | ++++++++
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/rust-2021/prelude2021.rs b/src/test/ui/rust-2021/prelude2021.rs
new file mode 100644
index 000000000..a63b6fcf2
--- /dev/null
+++ b/src/test/ui/rust-2021/prelude2021.rs
@@ -0,0 +1,6 @@
+// check-pass
+// edition:2021
+
+fn main() {
+ let _: u16 = 123i32.try_into().unwrap();
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.fixed b/src/test/ui/rust-2021/reserved-prefixes-migration.fixed
new file mode 100644
index 000000000..eed2f313a
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.fixed
@@ -0,0 +1,38 @@
+// check-pass
+// run-rustfix
+// edition:2018
+
+#![warn(rust_2021_prefixes_incompatible_syntax)]
+
+macro_rules! m2 {
+ ($a:tt $b:tt) => {};
+}
+
+macro_rules! m3 {
+ ($a:tt $b:tt $c:tt) => {};
+}
+
+fn main() {
+ m2!(z "hey");
+ //~^ WARNING prefix `z` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+ m2!(prefix "hey");
+ //~^ WARNING prefix `prefix` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+ m3!(hey #123);
+ //~^ WARNING prefix `hey` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+ m3!(hey #hey);
+ //~^ WARNING prefix `hey` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+}
+
+macro_rules! quote {
+ (# name = # kind # value) => {};
+}
+
+quote! {
+ #name = #kind #value
+ //~^ WARNING prefix `kind` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.rs b/src/test/ui/rust-2021/reserved-prefixes-migration.rs
new file mode 100644
index 000000000..0565db793
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.rs
@@ -0,0 +1,38 @@
+// check-pass
+// run-rustfix
+// edition:2018
+
+#![warn(rust_2021_prefixes_incompatible_syntax)]
+
+macro_rules! m2 {
+ ($a:tt $b:tt) => {};
+}
+
+macro_rules! m3 {
+ ($a:tt $b:tt $c:tt) => {};
+}
+
+fn main() {
+ m2!(z"hey");
+ //~^ WARNING prefix `z` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+ m2!(prefix"hey");
+ //~^ WARNING prefix `prefix` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+ m3!(hey#123);
+ //~^ WARNING prefix `hey` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+ m3!(hey#hey);
+ //~^ WARNING prefix `hey` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+}
+
+macro_rules! quote {
+ (# name = # kind # value) => {};
+}
+
+quote! {
+ #name = #kind#value
+ //~^ WARNING prefix `kind` is unknown [rust_2021_prefixes_incompatible_syntax]
+ //~| WARNING hard error in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
new file mode 100644
index 000000000..647a9f393
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr
@@ -0,0 +1,77 @@
+warning: prefix `z` is unknown
+ --> $DIR/reserved-prefixes-migration.rs:16:9
+ |
+LL | m2!(z"hey");
+ | ^ unknown prefix
+ |
+note: the lint level is defined here
+ --> $DIR/reserved-prefixes-migration.rs:5:9
+ |
+LL | #![warn(rust_2021_prefixes_incompatible_syntax)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+ |
+LL - m2!(z"hey");
+LL + m2!(z "hey");
+ |
+
+warning: prefix `prefix` is unknown
+ --> $DIR/reserved-prefixes-migration.rs:19:9
+ |
+LL | m2!(prefix"hey");
+ | ^^^^^^ unknown prefix
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+ |
+LL - m2!(prefix"hey");
+LL + m2!(prefix "hey");
+ |
+
+warning: prefix `hey` is unknown
+ --> $DIR/reserved-prefixes-migration.rs:22:9
+ |
+LL | m3!(hey#123);
+ | ^^^ unknown prefix
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+ |
+LL - m3!(hey#123);
+LL + m3!(hey #123);
+ |
+
+warning: prefix `hey` is unknown
+ --> $DIR/reserved-prefixes-migration.rs:25:9
+ |
+LL | m3!(hey#hey);
+ | ^^^ unknown prefix
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+ |
+LL - m3!(hey#hey);
+LL + m3!(hey #hey);
+ |
+
+warning: prefix `kind` is unknown
+ --> $DIR/reserved-prefixes-migration.rs:35:14
+ |
+LL | #name = #kind#value
+ | ^^^^ unknown prefix
+ |
+ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+ |
+LL - #name = #kind#value
+LL + #name = #kind #value
+ |
+
+warning: 5 warnings emitted
+
diff --git a/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs
new file mode 100644
index 000000000..74f206606
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.rs
@@ -0,0 +1,21 @@
+// edition:2018
+// aux-build:reserved-prefixes-macro-2018.rs
+// aux-build:reserved-prefixes-macro-2021.rs
+
+extern crate reserved_prefixes_macro_2018 as m2018;
+extern crate reserved_prefixes_macro_2021 as m2021;
+
+fn main() {
+ // Ok:
+ m2018::number_of_tokens_in_a_prefixed_integer_literal!();
+ m2018::number_of_tokens_in_a_prefixed_char_literal!();
+ m2018::number_of_tokens_in_a_prefixed_string_literal!();
+
+ // Error, even though *this* crate is 2018:
+ m2021::number_of_tokens_in_a_prefixed_integer_literal!();
+ //~^ ERROR prefix `hey` is unknown
+ m2021::number_of_tokens_in_a_prefixed_char_literal!();
+ //~^ ERROR prefix `hey` is unknown
+ m2021::number_of_tokens_in_a_prefixed_string_literal!();
+ //~^ ERROR prefix `hey` is unknown
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr
new file mode 100644
index 000000000..ae7c5d60c
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-via-macro-2.stderr
@@ -0,0 +1,29 @@
+error: prefix `hey` is unknown
+ --> $DIR/reserved-prefixes-via-macro-2.rs:15:5
+ |
+LL | m2021::number_of_tokens_in_a_prefixed_integer_literal!();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+ = note: this error originates in the macro `m2021::number_of_tokens_in_a_prefixed_integer_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: prefix `hey` is unknown
+ --> $DIR/reserved-prefixes-via-macro-2.rs:17:5
+ |
+LL | m2021::number_of_tokens_in_a_prefixed_char_literal!();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+ = note: this error originates in the macro `m2021::number_of_tokens_in_a_prefixed_char_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: prefix `hey` is unknown
+ --> $DIR/reserved-prefixes-via-macro-2.rs:19:5
+ |
+LL | m2021::number_of_tokens_in_a_prefixed_string_literal!();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+ = note: this error originates in the macro `m2021::number_of_tokens_in_a_prefixed_string_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/rust-2021/reserved-prefixes-via-macro.rs b/src/test/ui/rust-2021/reserved-prefixes-via-macro.rs
new file mode 100644
index 000000000..110b6d64c
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes-via-macro.rs
@@ -0,0 +1,12 @@
+// run-pass
+// edition:2021
+// aux-build:reserved-prefixes-macro-2018.rs
+
+extern crate reserved_prefixes_macro_2018 as m2018;
+
+fn main() {
+ // Ok, even though *this* crate is 2021:
+ assert_eq!(m2018::number_of_tokens_in_a_prefixed_integer_literal!(), 3);
+ assert_eq!(m2018::number_of_tokens_in_a_prefixed_char_literal!(), 3);
+ assert_eq!(m2018::number_of_tokens_in_a_prefixed_string_literal!(), 3);
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes.rs b/src/test/ui/rust-2021/reserved-prefixes.rs
new file mode 100644
index 000000000..1994f25b6
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes.rs
@@ -0,0 +1,36 @@
+// edition:2021
+
+macro_rules! demo2 {
+ ( $a:tt $b:tt ) => { println!("two tokens") };
+}
+
+macro_rules! demo3 {
+ ( $a:tt $b:tt $c:tt ) => { println!("three tokens") };
+}
+
+macro_rules! demo4 {
+ ( $a:tt $b:tt $c:tt $d:tt ) => { println!("four tokens") };
+}
+
+fn main() {
+ demo3!(foo#bar); //~ ERROR prefix `foo` is unknown
+ demo2!(foo"bar"); //~ ERROR prefix `foo` is unknown
+ demo2!(foo'b'); //~ ERROR prefix `foo` is unknown
+
+ demo2!(foo'b); //~ ERROR prefix `foo` is unknown
+ demo3!(foo# bar); //~ ERROR prefix `foo` is unknown
+ demo4!(foo#! bar); //~ ERROR prefix `foo` is unknown
+ demo4!(foo## bar); //~ ERROR prefix `foo` is unknown
+
+ demo4!(foo#bar#);
+ //~^ ERROR prefix `foo` is unknown
+ //~| ERROR prefix `bar` is unknown
+
+ demo3!(foo # bar);
+ demo3!(foo #bar);
+ demo4!(foo!#bar);
+ demo4!(foo ##bar);
+
+ demo3!(r"foo"#bar);
+ demo3!(r#foo#bar);
+}
diff --git a/src/test/ui/rust-2021/reserved-prefixes.stderr b/src/test/ui/rust-2021/reserved-prefixes.stderr
new file mode 100644
index 000000000..df31aee66
--- /dev/null
+++ b/src/test/ui/rust-2021/reserved-prefixes.stderr
@@ -0,0 +1,119 @@
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:16:12
+ |
+LL | demo3!(foo#bar);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo3!(foo#bar);
+LL + demo3!(foo #bar);
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:17:12
+ |
+LL | demo2!(foo"bar");
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo2!(foo"bar");
+LL + demo2!(foo "bar");
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:18:12
+ |
+LL | demo2!(foo'b');
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo2!(foo'b');
+LL + demo2!(foo 'b');
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:20:12
+ |
+LL | demo2!(foo'b);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo2!(foo'b);
+LL + demo2!(foo 'b);
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:21:12
+ |
+LL | demo3!(foo# bar);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo3!(foo# bar);
+LL + demo3!(foo # bar);
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:22:12
+ |
+LL | demo4!(foo#! bar);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo4!(foo#! bar);
+LL + demo4!(foo #! bar);
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:23:12
+ |
+LL | demo4!(foo## bar);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo4!(foo## bar);
+LL + demo4!(foo ## bar);
+ |
+
+error: prefix `foo` is unknown
+ --> $DIR/reserved-prefixes.rs:25:12
+ |
+LL | demo4!(foo#bar#);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo4!(foo#bar#);
+LL + demo4!(foo #bar#);
+ |
+
+error: prefix `bar` is unknown
+ --> $DIR/reserved-prefixes.rs:25:16
+ |
+LL | demo4!(foo#bar#);
+ | ^^^ unknown prefix
+ |
+ = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+ |
+LL - demo4!(foo#bar#);
+LL + demo4!(foo#bar #);
+ |
+
+error: aborting due to 9 previous errors
+