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::FUTURE_PRELUDE_COLLISION;
+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},
// Inherent impls only require not relying on autoref and autoderef in order to
// ensure that the trait implementation won't be used
self.tcx.struct_span_lint_hir(
- FUTURE_PRELUDE_COLLISION,
+ RUST_2021_PRELUDE_COLLISIONS,
self_expr.hir_id,
self_expr.span,
|lint| {
// trait implementations require full disambiguation to not clash with the new prelude
// additions (i.e. convert from dot-call to fully-qualified call)
self.tcx.struct_span_lint_hir(
- FUTURE_PRELUDE_COLLISION,
+ RUST_2021_PRELUDE_COLLISIONS,
call_expr.hir_id,
call_expr.span,
|lint| {
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) {
return;
}
- self.tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| {
+ self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
// "type" refers to either a type or, more likely, a trait from which
// the associated function or method is from.
let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());