Auto merge of #86904 - m-ou-se:prelude-collision-check-trait, r=nikomatsakis
Check FromIterator trait impl in prelude collision check. Fixes #86902.
This commit is contained in:
commit
95fb131521
4 changed files with 66 additions and 1 deletions
|
@ -155,6 +155,7 @@ symbols! {
|
||||||
FormatSpec,
|
FormatSpec,
|
||||||
Formatter,
|
Formatter,
|
||||||
From,
|
From,
|
||||||
|
FromIterator,
|
||||||
Future,
|
Future,
|
||||||
FxHashMap,
|
FxHashMap,
|
||||||
FxHashSet,
|
FxHashSet,
|
||||||
|
|
|
@ -4,11 +4,13 @@ use hir::ItemKind;
|
||||||
use rustc_ast::Mutability;
|
use rustc_ast::Mutability;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_middle::ty::subst::InternalSubsts;
|
||||||
use rustc_middle::ty::{Ref, Ty};
|
use rustc_middle::ty::{Ref, Ty};
|
||||||
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
||||||
use rustc_span::symbol::kw::Underscore;
|
use rustc_span::symbol::kw::Underscore;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
|
|
||||||
use crate::check::{
|
use crate::check::{
|
||||||
method::probe::{self, Pick},
|
method::probe::{self, Pick},
|
||||||
|
@ -206,6 +208,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
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(...)`,
|
// 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.
|
// since such methods take precedence over trait methods.
|
||||||
if matches!(pick.kind, probe::PickKind::InherentImplPick) {
|
if matches!(pick.kind, probe::PickKind::InherentImplPick) {
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
over elements of type `{A}`",
|
over elements of type `{A}`",
|
||||||
label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
|
label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
|
||||||
)]
|
)]
|
||||||
|
#[rustc_diagnostic_item = "FromIterator"]
|
||||||
pub trait FromIterator<A>: Sized {
|
pub trait FromIterator<A>: Sized {
|
||||||
/// Creates a value from an iterator.
|
/// Creates a value from an iterator.
|
||||||
///
|
///
|
||||||
|
|
|
@ -11,8 +11,50 @@ 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
fn main() {
|
||||||
|
// See https://github.com/rust-lang/rust/issues/86633
|
||||||
let s = S;
|
let s = S;
|
||||||
let s2 = s.try_into();
|
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue