about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyan Levick <me@ryanlevick.com>2021-07-28 18:34:19 +0200
committerRyan Levick <me@ryanlevick.com>2021-07-30 17:18:43 +0200
commit578fcbdb3c4cb893f5bd1d884788d60e2a2b6786 (patch)
tree1474fdfc968dd3a3f9a2a1425242b534ff6f7b59
parenteba3228b2a9875d268ff3990903d04e19f6cdb0c (diff)
downloadrust-578fcbdb3c4cb893f5bd1d884788d60e2a2b6786.tar.gz
rust-578fcbdb3c4cb893f5bd1d884788d60e2a2b6786.zip
Fix error with suggestion for how to disambiguate associated function when struct is generic
-rw-r--r--compiler/rustc_typeck/src/check/method/prelude2021.rs21
-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/prelude2021.rs (renamed from src/test/ui/prelude2021.rs)0
5 files changed, 126 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs
index f13e23914f7..6eb8af98640 100644
--- a/compiler/rustc_typeck/src/check/method/prelude2021.rs
+++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs
@@ -5,7 +5,7 @@ use rustc_ast::Mutability;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{Ref, Ty};
+use rustc_middle::ty::{Adt, Ref, Ty};
 use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
 use rustc_span::symbol::kw::Underscore;
 use rustc_span::symbol::{sym, Ident};
@@ -255,16 +255,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 method_name.name
             ));
 
-            let self_ty = self
+            let self_ty_name = self
                 .sess()
                 .source_map()
                 .span_to_snippet(self_ty_span)
                 .unwrap_or_else(|_| self_ty.to_string());
 
+            let self_ty_generics_count = match self_ty.kind() {
+                // Get the number of generics the self type has (if an Adt) unless we can determine that
+                // the user has written the self type with generics already which we (naively) do by looking
+                // for a "<" in `self_ty_name`.
+                Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(),
+                _ => 0,
+            };
+            let self_ty_generics = if self_ty_generics_count > 0 {
+                format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
+            } else {
+                String::new()
+            };
             lint.span_suggestion(
                 span,
                 "disambiguate the associated function",
-                format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
+                format!(
+                    "<{}{} as {}>::{}",
+                    self_ty_name, self_ty_generics, trait_name, method_name.name,
+                ),
                 Applicability::MachineApplicable,
             );
 
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 00000000000..f0d8cb944cf
--- /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<T, U>(T, U);
+
+trait MyFromIter {
+    fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<i32, i32> {
+    fn from_iter(x: i32) -> Self {
+        Self(x, x)
+    }
+}
+
+impl std::iter::FromIterator<i32> for Generic<i32, 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::<i32, 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 00000000000..19840537059
--- /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<T, U>(T, U);
+
+trait MyFromIter {
+    fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<i32, i32> {
+    fn from_iter(x: i32) -> Self {
+        Self(x, x)
+    }
+}
+
+impl std::iter::FromIterator<i32> for Generic<i32, 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::<i32, 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 00000000000..2c6a63df42f
--- /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 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-generic.rs:31:5
+   |
+LL |     Generic::<i32, i32>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, 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 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-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 issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/prelude2021.rs b/src/test/ui/rust-2021/prelude2021.rs
index 3a9fd693228..3a9fd693228 100644
--- a/src/test/ui/prelude2021.rs
+++ b/src/test/ui/rust-2021/prelude2021.rs