Skip to content

Commit

Permalink
Implement BOXED_SLICE_INTO_ITER
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Apr 17, 2024
1 parent bb9ca9f commit bd12444
Show file tree
Hide file tree
Showing 23 changed files with 443 additions and 175 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<'a, T> IntoIterator for &'a P<[T]> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.ptr.into_iter()
self.ptr.iter()
}
}

Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -900,10 +900,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"the `#[rustc_main]` attribute is used internally to specify test entry point function",
),
rustc_attr!(
rustc_skip_array_during_method_dispatch, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No,
"the `#[rustc_skip_array_during_method_dispatch]` attribute is used to exclude a trait \
from method dispatch when the receiver is an array, for compatibility in editions < 2021."
rustc_skip_during_method_dispatch, Normal, template!(List: "array, boxed_slice"), WarnFollowing,
EncodeCrossCrate::No,
"the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \
from method dispatch when the receiver is of the following type, for compatibility in \
editions < 2021 (array) or editions < 2024 (boxed_slice)."
),
rustc_attr!(
rustc_must_implement_one_of, Normal, template!(List: "function1, function2, ..."),
Expand Down
21 changes: 19 additions & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1116,8 +1116,24 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {

let is_marker = tcx.has_attr(def_id, sym::marker);
let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive);
let skip_array_during_method_dispatch =
tcx.has_attr(def_id, sym::rustc_skip_array_during_method_dispatch);

// FIXME: We could probably do way better attribute validation here.
let mut skip_array_during_method_dispatch = false;
let mut skip_boxed_slice_during_method_dispatch = false;
for attr in tcx.get_attrs(def_id, sym::rustc_skip_during_method_dispatch) {
if let Some(lst) = attr.meta_item_list() {
for item in lst {
if let Some(ident) = item.ident() {
match ident.as_str() {
"array" => skip_array_during_method_dispatch = true,
"boxed_slice" => skip_boxed_slice_during_method_dispatch = true,
_ => (),
}
}
}
}
}

let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
ty::trait_def::TraitSpecializationKind::Marker
} else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
Expand Down Expand Up @@ -1252,6 +1268,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
is_marker,
is_coinductive: rustc_coinductive || is_auto,
skip_array_during_method_dispatch,
skip_boxed_slice_during_method_dispatch,
specialization_kind,
must_implement_one_of,
implement_via_object,
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,20 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return ProbeResult::NoMatch;
}
}

// Some trait methods are excluded for boxed slices before 2024.
// (`boxed_slice.into_iter()` wants a slice iterator for compatibility.)
if self_ty.is_box()
&& self_ty.boxed_ty().is_slice()
&& !method_name.span.at_least_rust_2024()
{
let trait_def = self.tcx.trait_def(trait_ref.def_id);
if trait_def.skip_boxed_slice_during_method_dispatch {
return ProbeResult::NoMatch;
}
}
}

let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx);
parent_pred = Some(predicate);
let obligation =
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ lint_ambiguous_wide_pointer_comparisons = ambiguous wide pointer comparison, the
.addr_metadata_suggestion = use explicit `std::ptr::eq` method to compare metadata and addresses
.addr_suggestion = use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
lint_array_into_iter =
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
.use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
.remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
.use_explicit_into_iter_suggestion =
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
lint_async_fn_in_trait = use of `async fn` in public traits is discouraged as auto trait bounds cannot be specified
.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`
.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
Expand Down Expand Up @@ -552,6 +545,13 @@ lint_renamed_lint = lint `{$name}` has been renamed to `{$replace}`
lint_requested_level = requested on the command line with `{$level} {$lint_name}`
lint_shadowed_into_iter =
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}
.use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
.remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
.use_explicit_into_iter_suggestion =
or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion
Expand Down
142 changes: 0 additions & 142 deletions compiler/rustc_lint/src/array_into_iter.rs

This file was deleted.

8 changes: 4 additions & 4 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ extern crate rustc_session;
#[macro_use]
extern crate tracing;

mod array_into_iter;
mod async_fn_in_trait;
pub mod builtin;
mod context;
Expand Down Expand Up @@ -80,18 +79,18 @@ mod passes;
mod ptr_nulls;
mod redundant_semicolon;
mod reference_casting;
mod shadowed_into_iter;
mod traits;
mod types;
mod unit_bindings;
mod unused;

pub use array_into_iter::ARRAY_INTO_ITER;
pub use shadowed_into_iter::ARRAY_INTO_ITER;

use rustc_hir::def_id::LocalModDefId;
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;

use array_into_iter::ArrayIntoIter;
use async_fn_in_trait::AsyncFnInTrait;
use builtin::*;
use deref_into_dyn_supertrait::*;
Expand All @@ -115,6 +114,7 @@ use pass_by_value::*;
use ptr_nulls::*;
use redundant_semicolon::*;
use reference_casting::*;
use shadowed_into_iter::ShadowedIntoIter;
use traits::*;
use types::*;
use unit_bindings::*;
Expand Down Expand Up @@ -218,7 +218,7 @@ late_lint_methods!(
DerefNullPtr: DerefNullPtr,
UnstableFeatures: UnstableFeatures,
UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller,
ArrayIntoIter: ArrayIntoIter::default(),
ShadowedIntoIter: ShadowedIntoIter,
DropTraitConstraints: DropTraitConstraints,
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
NonPanicFmt: NonPanicFmt,
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ use crate::{

// array_into_iter.rs
#[derive(LintDiagnostic)]
#[diag(lint_array_into_iter)]
pub struct ArrayIntoIterDiag<'a> {
pub target: &'a str,
#[diag(lint_shadowed_into_iter)]
pub struct ShadowedIntoIterDiag {
pub target: &'static str,
pub edition: &'static str,
#[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
pub suggestion: Span,
#[subdiagnostic]
pub sub: Option<ArrayIntoIterDiagSub>,
pub sub: Option<ShadowedIntoIterDiagSub>,
}

#[derive(Subdiagnostic)]
pub enum ArrayIntoIterDiagSub {
pub enum ShadowedIntoIterDiagSub {
#[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
RemoveIntoIter {
#[primary_span]
Expand Down
Loading

0 comments on commit bd12444

Please sign in to comment.