Skip to content

Commit a502e7a

Browse files
Implement BOXED_SLICE_INTO_ITER
1 parent 1a81092 commit a502e7a

File tree

22 files changed

+446
-173
lines changed

22 files changed

+446
-173
lines changed

compiler/rustc_ast/src/ptr.rs

Lines changed: 1 addition & 1 deletion
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

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

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,8 +1117,24 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
11171117

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

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14441444
return ProbeResult::NoMatch;
14451445
}
14461446
}
1447+
1448+
// Some trait methods are excluded for boxed slices before 2024.
1449+
// (`boxed_slice.into_iter()` wants a slice iterator for compatibility.)
1450+
if self_ty.is_box()
1451+
&& self_ty.boxed_ty().is_slice()
1452+
&& !method_name.span.at_least_rust_2024()
1453+
{
1454+
let trait_def = self.tcx.trait_def(poly_trait_ref.def_id());
1455+
if trait_def.skip_boxed_slice_during_method_dispatch {
1456+
return ProbeResult::NoMatch;
1457+
}
1458+
}
14471459
}
14481460

14491461
let trait_ref = self.instantiate_binder_with_fresh_vars(

compiler/rustc_lint/messages.ftl

Lines changed: 7 additions & 7 deletions
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
@@ -565,6 +558,13 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}`
565558
566559
lint_requested_level = requested on the command line with `{$level} {$lint_name}`
567560
561+
lint_shadowed_into_iter =
562+
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}
563+
.use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
564+
.remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
565+
.use_explicit_into_iter_suggestion =
566+
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
567+
568568
lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
569569
570570
lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion

compiler/rustc_lint/src/array_into_iter.rs

Lines changed: 0 additions & 144 deletions
This file was deleted.

compiler/rustc_lint/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#[macro_use]
4343
extern crate tracing;
4444

45-
mod array_into_iter;
4645
mod async_fn_in_trait;
4746
pub mod builtin;
4847
mod context;
@@ -76,18 +75,18 @@ mod passes;
7675
mod ptr_nulls;
7776
mod redundant_semicolon;
7877
mod reference_casting;
78+
mod shadowed_into_iter;
7979
mod traits;
8080
mod types;
8181
mod unit_bindings;
8282
mod unused;
8383

84-
pub use array_into_iter::ARRAY_INTO_ITER;
84+
pub use shadowed_into_iter::ARRAY_INTO_ITER;
8585

8686
use rustc_hir::def_id::LocalModDefId;
8787
use rustc_middle::query::Providers;
8888
use rustc_middle::ty::TyCtxt;
8989

90-
use array_into_iter::ArrayIntoIter;
9190
use async_fn_in_trait::AsyncFnInTrait;
9291
use builtin::*;
9392
use deref_into_dyn_supertrait::*;
@@ -112,6 +111,7 @@ use pass_by_value::*;
112111
use ptr_nulls::*;
113112
use redundant_semicolon::*;
114113
use reference_casting::*;
114+
use shadowed_into_iter::ShadowedIntoIter;
115115
use traits::*;
116116
use types::*;
117117
use unit_bindings::*;
@@ -215,7 +215,7 @@ late_lint_methods!(
215215
DerefNullPtr: DerefNullPtr,
216216
UnstableFeatures: UnstableFeatures,
217217
UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller,
218-
ArrayIntoIter: ArrayIntoIter::default(),
218+
ShadowedIntoIter: ShadowedIntoIter,
219219
DropTraitConstraints: DropTraitConstraints,
220220
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
221221
NonPanicFmt: NonPanicFmt,

compiler/rustc_lint/src/lints.rs

Lines changed: 6 additions & 5 deletions
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)