Adjust the method ambiguity lint too
This commit is contained in:
parent
a502e7ac1d
commit
bc6b70f1d1
6 changed files with 108 additions and 21 deletions
|
@ -3,7 +3,7 @@
|
||||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/method-lookup.html
|
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/method-lookup.html
|
||||||
|
|
||||||
mod confirm;
|
mod confirm;
|
||||||
mod prelude2021;
|
mod prelude_edition_lints;
|
||||||
pub mod probe;
|
pub mod probe;
|
||||||
mod suggest;
|
mod suggest;
|
||||||
|
|
||||||
|
@ -186,7 +186,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let pick =
|
let pick =
|
||||||
self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?;
|
self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?;
|
||||||
|
|
||||||
self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick, args);
|
self.lint_edition_dependent_dot_call(
|
||||||
|
self_ty, segment, span, call_expr, self_expr, &pick, args,
|
||||||
|
);
|
||||||
|
|
||||||
for &import_id in &pick.import_ids {
|
for &import_id in &pick.import_ids {
|
||||||
debug!("used_trait_import: {:?}", import_id);
|
debug!("used_trait_import: {:?}", import_id);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::{
|
use crate::method::probe::{self, Pick};
|
||||||
method::probe::{self, Pick},
|
use crate::FnCtxt;
|
||||||
FnCtxt,
|
|
||||||
};
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use hir::HirId;
|
use hir::HirId;
|
||||||
use hir::ItemKind;
|
use hir::ItemKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_lint::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
||||||
|
@ -17,7 +17,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
pub(super) fn lint_dot_call_from_2018(
|
pub(super) fn lint_edition_dependent_dot_call(
|
||||||
&self,
|
&self,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
segment: &hir::PathSegment<'_>,
|
segment: &hir::PathSegment<'_>,
|
||||||
|
@ -32,22 +32,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
segment.ident, self_ty, call_expr, self_expr
|
segment.ident, self_ty, call_expr, self_expr
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rust 2021 and later is already using the new prelude
|
let (prelude_or_array_lint, edition) = match segment.ident.name {
|
||||||
if span.at_least_rust_2021() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prelude_or_array_lint = match segment.ident.name {
|
|
||||||
// `try_into` was added to the prelude in Rust 2021.
|
// `try_into` was added to the prelude in Rust 2021.
|
||||||
sym::try_into => RUST_2021_PRELUDE_COLLISIONS,
|
sym::try_into if !span.at_least_rust_2021() => (RUST_2021_PRELUDE_COLLISIONS, "2021"),
|
||||||
// `into_iter` wasn't added to the prelude,
|
// `into_iter` wasn't added to the prelude,
|
||||||
// but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter
|
// but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter
|
||||||
// before Rust 2021, which results in the same problem.
|
// before Rust 2021, which results in the same problem.
|
||||||
// It is only a problem for arrays.
|
// It is only a problem for arrays.
|
||||||
sym::into_iter if let ty::Array(..) = self_ty.kind() => {
|
sym::into_iter => {
|
||||||
|
if let ty::Array(..) = self_ty.kind()
|
||||||
|
&& !span.at_least_rust_2021()
|
||||||
|
{
|
||||||
// In this case, it wasn't really a prelude addition that was the problem.
|
// In this case, it wasn't really a prelude addition that was the problem.
|
||||||
// Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021.
|
// Instead, the problem is that the array-into_iter hack will no longer
|
||||||
rustc_lint::ARRAY_INTO_ITER
|
// apply in Rust 2021.
|
||||||
|
(ARRAY_INTO_ITER, "2021")
|
||||||
|
} else if self_ty.is_box()
|
||||||
|
&& self_ty.boxed_ty().is_slice()
|
||||||
|
&& !span.at_least_rust_2024()
|
||||||
|
{
|
||||||
|
// In this case, it wasn't really a prelude addition that was the problem.
|
||||||
|
// Instead, the problem is that the boxed-slice-into_iter hack will no
|
||||||
|
// longer apply in Rust 2024.
|
||||||
|
(BOXED_SLICE_INTO_ITER, "2024")
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
@ -81,7 +91,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
prelude_or_array_lint,
|
prelude_or_array_lint,
|
||||||
self_expr.hir_id,
|
self_expr.hir_id,
|
||||||
self_expr.span,
|
self_expr.span,
|
||||||
format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
|
format!(
|
||||||
|
"trait method `{}` will become ambiguous in Rust {edition}",
|
||||||
|
segment.ident.name
|
||||||
|
),
|
||||||
|lint| {
|
|lint| {
|
||||||
let sp = self_expr.span;
|
let sp = self_expr.span;
|
||||||
|
|
||||||
|
@ -131,7 +144,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
prelude_or_array_lint,
|
prelude_or_array_lint,
|
||||||
call_expr.hir_id,
|
call_expr.hir_id,
|
||||||
call_expr.span,
|
call_expr.span,
|
||||||
format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
|
format!(
|
||||||
|
"trait method `{}` will become ambiguous in Rust {edition}",
|
||||||
|
segment.ident.name
|
||||||
|
),
|
||||||
|lint| {
|
|lint| {
|
||||||
let sp = call_expr.span;
|
let sp = call_expr.span;
|
||||||
let trait_name = self.trait_path_or_bare_name(
|
let trait_name = self.trait_path_or_bare_name(
|
|
@ -81,7 +81,7 @@ mod types;
|
||||||
mod unit_bindings;
|
mod unit_bindings;
|
||||||
mod unused;
|
mod unused;
|
||||||
|
|
||||||
pub use shadowed_into_iter::ARRAY_INTO_ITER;
|
pub use shadowed_into_iter::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER};
|
||||||
|
|
||||||
use rustc_hir::def_id::LocalModDefId;
|
use rustc_hir::def_id::LocalModDefId;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
|
|
27
tests/ui/rust-2024/box-slice-into-iter-ambiguous.fixed
Normal file
27
tests/ui/rust-2024/box-slice-into-iter-ambiguous.fixed
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// See https://github.com/rust-lang/rust/issues/88475
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ edition:2021
|
||||||
|
//@ check-pass
|
||||||
|
#![warn(boxed_slice_into_iter)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
struct FooIter;
|
||||||
|
|
||||||
|
trait MyIntoIter {
|
||||||
|
fn into_iter(self) -> FooIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MyIntoIter for Box<[T]> {
|
||||||
|
fn into_iter(self) -> FooIter {
|
||||||
|
FooIter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Point;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let points: Box<[_]> = vec![Point].into_boxed_slice();
|
||||||
|
let y = MyIntoIter::into_iter(points);
|
||||||
|
//~^ WARNING trait method `into_iter` will become ambiguous in Rust 2024
|
||||||
|
//~| WARNING this changes meaning in Rust 2024
|
||||||
|
}
|
27
tests/ui/rust-2024/box-slice-into-iter-ambiguous.rs
Normal file
27
tests/ui/rust-2024/box-slice-into-iter-ambiguous.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// See https://github.com/rust-lang/rust/issues/88475
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ edition:2021
|
||||||
|
//@ check-pass
|
||||||
|
#![warn(boxed_slice_into_iter)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
struct FooIter;
|
||||||
|
|
||||||
|
trait MyIntoIter {
|
||||||
|
fn into_iter(self) -> FooIter;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MyIntoIter for Box<[T]> {
|
||||||
|
fn into_iter(self) -> FooIter {
|
||||||
|
FooIter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Point;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let points: Box<[_]> = vec![Point].into_boxed_slice();
|
||||||
|
let y = points.into_iter();
|
||||||
|
//~^ WARNING trait method `into_iter` will become ambiguous in Rust 2024
|
||||||
|
//~| WARNING this changes meaning in Rust 2024
|
||||||
|
}
|
15
tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr
Normal file
15
tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
warning: trait method `into_iter` will become ambiguous in Rust 2024
|
||||||
|
--> $DIR/box-slice-into-iter-ambiguous.rs:24:13
|
||||||
|
|
|
||||||
|
LL | let y = points.into_iter();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/box-slice-into-iter-ambiguous.rs:5:9
|
||||||
|
|
|
||||||
|
LL | #![warn(boxed_slice_into_iter)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue