From 60535441c8c8f9190ae0fbf62f6f1de75e414b9d Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 6 Jul 2021 13:41:22 +0000 Subject: [PATCH 1/5] Check FromIterator trait impl in prelude collision check. --- compiler/rustc_span/src/symbol.rs | 1 + .../src/check/method/prelude2021.rs | 21 +++++++++++++++++++ library/core/src/iter/traits/collect.rs | 1 + 3 files changed, 23 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index be4f12c6d1cb8..085e3811ac1a3 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -155,6 +155,7 @@ symbols! { FormatSpec, Formatter, From, + FromIterator, Future, FxHashMap, FxHashSet, diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index 6ca0b3ed66b39..f853c0fd9ccdb 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -4,11 +4,13 @@ use hir::ItemKind; 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_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::Underscore; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; +use rustc_trait_selection::infer::InferCtxtExt; use crate::check::{ method::probe::{self, Pick}, @@ -206,6 +208,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } + // For from_iter, check if the type actualy implements FromIterator. + // If we know it does not, we don't need to warn. + if method_name.name == sym::from_iter { + if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) { + if !self + .infcx + .type_implements_trait( + trait_def_id, + self_ty, + InternalSubsts::empty(), + self.param_env, + ) + .may_apply() + { + return; + } + } + } + // No need to lint if this is an inherent method called on a specific type, like `Vec::foo(...)`, // since such methods take precedence over trait methods. if matches!(pick.kind, probe::PickKind::InherentImplPick) { diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 348e1f7e3f23d..7f87ead6feed6 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -89,6 +89,7 @@ over elements of type `{A}`", label = "value of type `{Self}` cannot be built from `std::iter::Iterator`" )] +#[rustc_diagnostic_item = "FromIterator"] pub trait FromIterator: Sized { /// Creates a value from an iterator. /// From f77dd5ac9371897d30dd3a8c43023e14f86dd0bf Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 6 Jul 2021 13:51:25 +0000 Subject: [PATCH 2/5] Add test for trait check in prelude collision lint. --- .../future-prelude-collision-unneeded.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs index 4be82056ad59b..8b3b7e74a7f95 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs @@ -11,8 +11,23 @@ impl S { } } -// See https://github.com/rust-lang/rust/issues/86633 +struct X; + +trait Hey { + fn from_iter(_: i32) -> Self; +} + +impl Hey for X { + fn from_iter(_: i32) -> Self { + X + } +} + fn main() { + // See https://github.com/rust-lang/rust/issues/86633 let s = S; let s2 = s.try_into(); + + // See https://github.com/rust-lang/rust/issues/86902 + X::from_iter(1); } From 10d6b34d32e377798868586d2d8e25d972cbeb0d Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 7 Jul 2021 13:25:48 +0000 Subject: [PATCH 3/5] Add generic types to prelude collision lint test. --- .../future-prelude-collision-unneeded.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs index 8b3b7e74a7f95..6e20767998664 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs @@ -23,6 +23,28 @@ impl Hey for X { } } +struct Y(T); + +impl Hey for Y { + fn from_iter(_: i32) -> Self { + Y(0) + } +} + +struct Z(T); + +impl Hey for Z { + fn from_iter(_: i32) -> Self { + Z(0) + } +} + +impl std::iter::FromIterator for Z { + fn from_iter>(_: T) -> Self { + todo!() + } +} + fn main() { // See https://github.com/rust-lang/rust/issues/86633 let s = S; @@ -30,4 +52,7 @@ fn main() { // See https://github.com/rust-lang/rust/issues/86902 X::from_iter(1); + Y::from_iter(1); + Y::::from_iter(1); + Z::::from_iter(1); } From 99b5d2a88ffae4923a0076bc2c669cc3cc0affed Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 8 Jul 2021 11:33:33 +0200 Subject: [PATCH 4/5] Fix typo in comment. --- compiler/rustc_typeck/src/check/method/prelude2021.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index f853c0fd9ccdb..f13e23914f7ab 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -208,7 +208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - // For from_iter, check if the type actualy implements FromIterator. + // For from_iter, check if the type actually implements FromIterator. // If we know it does not, we don't need to warn. if method_name.name == sym::from_iter { if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) { From 2083207536e710071475dc489f155c574951e3fd Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 8 Jul 2021 12:31:56 -0400 Subject: [PATCH 5/5] Update src/test/ui/rust-2021/future-prelude-collision-unneeded.rs --- src/test/ui/rust-2021/future-prelude-collision-unneeded.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs index 6e20767998664..247d5884b868a 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-unneeded.rs @@ -50,6 +50,8 @@ fn main() { 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);