Skip to content

Commit 701674f

Browse files
Implement BOXED_SLICE_INTO_ITER
1 parent bb9ca9f commit 701674f

File tree

23 files changed

+443
-175
lines changed

23 files changed

+443
-175
lines changed

compiler/rustc_ast/src/ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl<'a, T> IntoIterator for &'a P<[T]> {
184184
type Item = &'a T;
185185
type IntoIter = slice::Iter<'a, T>;
186186
fn into_iter(self) -> Self::IntoIter {
187-
self.ptr.into_iter()
187+
self.ptr.iter()
188188
}
189189
}
190190

compiler/rustc_feature/src/builtin_attrs.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -900,10 +900,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
900900
"the `#[rustc_main]` attribute is used internally to specify test entry point function",
901901
),
902902
rustc_attr!(
903-
rustc_skip_array_during_method_dispatch, Normal, template!(Word),
904-
WarnFollowing, EncodeCrossCrate::No,
905-
"the `#[rustc_skip_array_during_method_dispatch]` attribute is used to exclude a trait \
906-
from method dispatch when the receiver is an array, for compatibility in editions < 2021."
903+
rustc_skip_during_method_dispatch, Normal, template!(List: "array, boxed_slice"), WarnFollowing,
904+
EncodeCrossCrate::No,
905+
"the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \
906+
from method dispatch when the receiver is of the following type, for compatibility in \
907+
editions < 2021 (array) or editions < 2024 (boxed_slice)."
907908
),
908909
rustc_attr!(
909910
rustc_must_implement_one_of, Normal, template!(List: "function1, function2, ..."),

compiler/rustc_hir_analysis/src/collect.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1116,8 +1116,24 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
11161116

11171117
let is_marker = tcx.has_attr(def_id, sym::marker);
11181118
let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive);
1119-
let skip_array_during_method_dispatch =
1120-
tcx.has_attr(def_id, sym::rustc_skip_array_during_method_dispatch);
1119+
1120+
// FIXME: We could probably do way better attribute validation here.
1121+
let mut skip_array_during_method_dispatch = false;
1122+
let mut skip_boxed_slice_during_method_dispatch = false;
1123+
for attr in tcx.get_attrs(def_id, sym::rustc_skip_during_method_dispatch) {
1124+
if let Some(lst) = attr.meta_item_list() {
1125+
for item in lst {
1126+
if let Some(ident) = item.ident() {
1127+
match ident.as_str() {
1128+
"array" => skip_array_during_method_dispatch = true,
1129+
"boxed_slice" => skip_boxed_slice_during_method_dispatch = true,
1130+
_ => (),
1131+
}
1132+
}
1133+
}
1134+
}
1135+
}
1136+
11211137
let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
11221138
ty::trait_def::TraitSpecializationKind::Marker
11231139
} else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
@@ -1252,6 +1268,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
12521268
is_marker,
12531269
is_coinductive: rustc_coinductive || is_auto,
12541270
skip_array_during_method_dispatch,
1271+
skip_boxed_slice_during_method_dispatch,
12551272
specialization_kind,
12561273
must_implement_one_of,
12571274
implement_via_object,

compiler/rustc_hir_typeck/src/method/probe.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
16011601
return ProbeResult::NoMatch;
16021602
}
16031603
}
1604+
1605+
// Some trait methods are excluded for boxed slices before 2024.
1606+
// (`boxed_slice.into_iter()` wants a slice iterator for compatibility.)
1607+
if self_ty.is_box()
1608+
&& self_ty.boxed_ty().is_slice()
1609+
&& !method_name.span.at_least_rust_2024()
1610+
{
1611+
let trait_def = self.tcx.trait_def(trait_ref.def_id);
1612+
if trait_def.skip_boxed_slice_during_method_dispatch {
1613+
return ProbeResult::NoMatch;
1614+
}
1615+
}
16041616
}
1617+
16051618
let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx);
16061619
parent_pred = Some(predicate);
16071620
let obligation =

compiler/rustc_lint/messages.ftl

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,6 @@ lint_ambiguous_wide_pointer_comparisons = ambiguous wide pointer comparison, the
22
.addr_metadata_suggestion = use explicit `std::ptr::eq` method to compare metadata and addresses
33
.addr_suggestion = use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
44
5-
lint_array_into_iter =
6-
this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<{$target} as IntoIterator>::into_iter` in Rust 2021
7-
.use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
8-
.remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
9-
.use_explicit_into_iter_suggestion =
10-
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
11-
125
lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified
136
.note = you can suppress this lint if you plan to use the trait only in your own code, or do not care about auto traits like `Send` on the `Future`
147
.suggestion = you can alternatively desugar to a normal `fn` that returns `impl Future` and add any desired bounds such as `Send`, but these cannot be relaxed without a breaking API change
@@ -552,6 +545,13 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}`
552545
553546
lint_requested_level = requested on the command line with `{$level} {$lint_name}`
554547
548+
lint_shadowed_into_iter =
549+
this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<{$target} as IntoIterator>::into_iter` in Rust {$edition}
550+
.use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
551+
.remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
552+
.use_explicit_into_iter_suggestion =
553+
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
554+
555555
lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
556556
557557
lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion

compiler/rustc_lint/src/array_into_iter.rs

-142
This file was deleted.

compiler/rustc_lint/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ extern crate rustc_session;
4747
#[macro_use]
4848
extern crate tracing;
4949

50-
mod array_into_iter;
5150
mod async_fn_in_trait;
5251
pub mod builtin;
5352
mod context;
@@ -80,18 +79,18 @@ mod passes;
8079
mod ptr_nulls;
8180
mod redundant_semicolon;
8281
mod reference_casting;
82+
mod shadowed_into_iter;
8383
mod traits;
8484
mod types;
8585
mod unit_bindings;
8686
mod unused;
8787

88-
pub use array_into_iter::ARRAY_INTO_ITER;
88+
pub use shadowed_into_iter::ARRAY_INTO_ITER;
8989

9090
use rustc_hir::def_id::LocalModDefId;
9191
use rustc_middle::query::Providers;
9292
use rustc_middle::ty::TyCtxt;
9393

94-
use array_into_iter::ArrayIntoIter;
9594
use async_fn_in_trait::AsyncFnInTrait;
9695
use builtin::*;
9796
use deref_into_dyn_supertrait::*;
@@ -115,6 +114,7 @@ use pass_by_value::*;
115114
use ptr_nulls::*;
116115
use redundant_semicolon::*;
117116
use reference_casting::*;
117+
use shadowed_into_iter::ShadowedIntoIter;
118118
use traits::*;
119119
use types::*;
120120
use unit_bindings::*;
@@ -218,7 +218,7 @@ late_lint_methods!(
218218
DerefNullPtr: DerefNullPtr,
219219
UnstableFeatures: UnstableFeatures,
220220
UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller,
221-
ArrayIntoIter: ArrayIntoIter::default(),
221+
ShadowedIntoIter: ShadowedIntoIter,
222222
DropTraitConstraints: DropTraitConstraints,
223223
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
224224
NonPanicFmt: NonPanicFmt,

compiler/rustc_lint/src/lints.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,18 @@ use crate::{
2222

2323
// array_into_iter.rs
2424
#[derive(LintDiagnostic)]
25-
#[diag(lint_array_into_iter)]
26-
pub struct ArrayIntoIterDiag<'a> {
27-
pub target: &'a str,
25+
#[diag(lint_shadowed_into_iter)]
26+
pub struct ShadowedIntoIterDiag {
27+
pub target: &'static str,
28+
pub edition: &'static str,
2829
#[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
2930
pub suggestion: Span,
3031
#[subdiagnostic]
31-
pub sub: Option<ArrayIntoIterDiagSub>,
32+
pub sub: Option<ShadowedIntoIterDiagSub>,
3233
}
3334

3435
#[derive(Subdiagnostic)]
35-
pub enum ArrayIntoIterDiagSub {
36+
pub enum ShadowedIntoIterDiagSub {
3637
#[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
3738
RemoveIntoIter {
3839
#[primary_span]

0 commit comments

Comments
 (0)