mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #153029 - nnethercote:disallowed-pass-by-ref, r=Urgau
Rename `rustc::pass_by_value` lint as `rustc::disallowed_pass_by_ref`. The name `pass_by_value` is completely wrong. The lint actually checks for the use of pass by reference for types marked with `rustc_pass_by_value`. The hardest part of this was choosing the new name. The `disallowed_` part of the name closely matches the following clippy lints: - `disallowed_macros` - `disallowed_methods` - `disallowed_names` - `disallowed_script_idents` - `disallowed_types` The `pass_by_value` part of the name aligns with the following clippy lints: - `needless_pass_by_value` - `needless_pass_by_ref_mut` - `trivially_copy_pass_by_ref` - `large_types_passed_by_value` (less so) r? @Urgau
This commit is contained in:
@@ -757,9 +757,11 @@ fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
) -> V::Result;
|
||||
}
|
||||
|
||||
// this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
|
||||
// This is only used by the MutVisitor. We include this symmetry here to make writing other
|
||||
// functions easier.
|
||||
$(${ignore($lt)}
|
||||
#[expect(unused, rustc::pass_by_value)]
|
||||
#[cfg_attr(not(bootstrap), expect(unused, rustc::disallowed_pass_by_ref))]
|
||||
#[cfg_attr(bootstrap, expect(unused, rustc::pass_by_value))]
|
||||
#[inline]
|
||||
)?
|
||||
fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result {
|
||||
|
||||
+12
-12
@@ -3,34 +3,34 @@
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
use crate::lints::PassByValueDiag;
|
||||
use crate::lints::DisallowedPassByRefDiag;
|
||||
use crate::{LateContext, LateLintPass, LintContext};
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to
|
||||
/// always be passed by value. This is usually used for types that are thin wrappers around
|
||||
/// references, so there is no benefit to an extra layer of indirection. (Example: `Ty` which
|
||||
/// is a reference to an `Interned<TyKind>`)
|
||||
pub rustc::PASS_BY_VALUE,
|
||||
/// The `disallowed_pass_by_ref` lint detects if types marked with `#[rustc_pass_by_value]` are
|
||||
/// passed by reference. Types with this marker are usually thin wrappers around references, so
|
||||
/// there is no benefit to an extra layer of indirection. (Example: `Ty` which is a reference
|
||||
/// to an `Interned<TyKind>`)
|
||||
pub rustc::DISALLOWED_PASS_BY_REF,
|
||||
Warn,
|
||||
"pass by reference of a type flagged as `#[rustc_pass_by_value]`",
|
||||
report_in_external_macro: true
|
||||
}
|
||||
|
||||
declare_lint_pass!(PassByValue => [PASS_BY_VALUE]);
|
||||
declare_lint_pass!(DisallowedPassByRef => [DISALLOWED_PASS_BY_REF]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for PassByValue {
|
||||
impl<'tcx> LateLintPass<'tcx> for DisallowedPassByRef {
|
||||
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
|
||||
match &ty.kind {
|
||||
TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => {
|
||||
if cx.tcx.trait_impl_of_assoc(ty.hir_id.owner.to_def_id()).is_some() {
|
||||
return;
|
||||
}
|
||||
if let Some(t) = path_for_pass_by_value(cx, inner_ty) {
|
||||
if let Some(t) = path_for_rustc_pass_by_value(cx, inner_ty) {
|
||||
cx.emit_span_lint(
|
||||
PASS_BY_VALUE,
|
||||
DISALLOWED_PASS_BY_REF,
|
||||
ty.span,
|
||||
PassByValueDiag { ty: t, suggestion: ty.span },
|
||||
DisallowedPassByRefDiag { ty: t, suggestion: ty.span },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>)
|
||||
}
|
||||
}
|
||||
|
||||
fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> {
|
||||
fn path_for_rustc_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<String> {
|
||||
if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind {
|
||||
match path.res {
|
||||
Res::Def(_, def_id) if find_attr!(cx.tcx, def_id, RustcPassByValue(_)) => {
|
||||
@@ -37,6 +37,7 @@
|
||||
mod dangling;
|
||||
mod default_could_be_derived;
|
||||
mod deref_into_dyn_supertrait;
|
||||
mod disallowed_pass_by_ref;
|
||||
mod drop_forget_useless;
|
||||
mod early;
|
||||
mod enum_intrinsics_non_enums;
|
||||
@@ -65,7 +66,6 @@
|
||||
mod nonstandard_style;
|
||||
mod noop_method_call;
|
||||
mod opaque_hidden_inferred_bound;
|
||||
mod pass_by_value;
|
||||
mod passes;
|
||||
mod precedence;
|
||||
mod ptr_nulls;
|
||||
@@ -88,6 +88,7 @@
|
||||
use dangling::*;
|
||||
use default_could_be_derived::DefaultCouldBeDerived;
|
||||
use deref_into_dyn_supertrait::*;
|
||||
use disallowed_pass_by_ref::*;
|
||||
use drop_forget_useless::*;
|
||||
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
|
||||
use for_loops_over_fallibles::*;
|
||||
@@ -109,7 +110,6 @@
|
||||
use nonstandard_style::*;
|
||||
use noop_method_call::*;
|
||||
use opaque_hidden_inferred_bound::*;
|
||||
use pass_by_value::*;
|
||||
use precedence::*;
|
||||
use ptr_nulls::*;
|
||||
use redundant_semicolon::*;
|
||||
@@ -659,8 +659,8 @@ fn register_internals(store: &mut LintStore) {
|
||||
store.register_late_mod_pass(|_| Box::new(TypeIr));
|
||||
store.register_lints(&BadOptAccess::lint_vec());
|
||||
store.register_late_mod_pass(|_| Box::new(BadOptAccess));
|
||||
store.register_lints(&PassByValue::lint_vec());
|
||||
store.register_late_mod_pass(|_| Box::new(PassByValue));
|
||||
store.register_lints(&DisallowedPassByRef::lint_vec());
|
||||
store.register_late_mod_pass(|_| Box::new(DisallowedPassByRef));
|
||||
store.register_lints(&SpanUseEqCtxt::lint_vec());
|
||||
store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt));
|
||||
store.register_lints(&SymbolInternStringLiteral::lint_vec());
|
||||
@@ -678,7 +678,7 @@ fn register_internals(store: &mut LintStore) {
|
||||
LintId::of(POTENTIAL_QUERY_INSTABILITY),
|
||||
LintId::of(UNTRACKED_QUERY_INFORMATION),
|
||||
LintId::of(USAGE_OF_TY_TYKIND),
|
||||
LintId::of(PASS_BY_VALUE),
|
||||
LintId::of(DISALLOWED_PASS_BY_REF),
|
||||
LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
|
||||
LintId::of(USAGE_OF_QUALIFIED_TY),
|
||||
LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
|
||||
|
||||
@@ -1807,10 +1807,10 @@ pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
|
||||
pub end_span: Span,
|
||||
}
|
||||
|
||||
// pass_by_value.rs
|
||||
// disallowed_pass_by_ref.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag("passing `{$ty}` by reference")]
|
||||
pub(crate) struct PassByValueDiag {
|
||||
pub(crate) struct DisallowedPassByRefDiag {
|
||||
pub ty: String,
|
||||
#[suggestion("try passing by value", code = "{ty}", applicability = "maybe-incorrect")]
|
||||
pub suggestion: Span,
|
||||
|
||||
@@ -293,12 +293,10 @@ fn make_helpers_for_query(query: &Query, streams: &mut HelperTokenStreams) {
|
||||
|
||||
// Generate a function to check whether we should cache the query to disk, for some key.
|
||||
if let Some(CacheOnDiskIf { block, .. }) = modifiers.cache_on_disk_if.as_ref() {
|
||||
// `pass_by_value`: some keys are marked with `rustc_pass_by_value`, but we take keys by
|
||||
// reference here.
|
||||
// FIXME: `pass_by_value` is badly named; `allow(rustc::pass_by_value)` actually means
|
||||
// "allow pass by reference of `rustc_pass_by_value` types".
|
||||
// `disallowed_pass_by_ref` is needed because some keys are `rustc_pass_by_value`.
|
||||
streams.cache_on_disk_if_fns_stream.extend(quote! {
|
||||
#[allow(unused_variables, rustc::pass_by_value)]
|
||||
#[cfg_attr(not(bootstrap), allow(unused_variables, rustc::disallowed_pass_by_ref))]
|
||||
#[cfg_attr(bootstrap, allow(unused_variables, rustc::pass_by_value))]
|
||||
#[inline]
|
||||
pub fn #erased_name<'tcx>(tcx: TyCtxt<'tcx>, #key_pat: &#key_ty) -> bool
|
||||
#block
|
||||
|
||||
@@ -302,7 +302,8 @@ fn insert_unique(
|
||||
|
||||
/// Insert a `(Value, Ty)` pair to be deduplicated.
|
||||
/// Returns `true` as second tuple field if this value did not exist previously.
|
||||
#[allow(rustc::pass_by_value)] // closures take `&VnIndex`
|
||||
#[cfg_attr(not(bootstrap), allow(rustc::disallowed_pass_by_ref))] // closures take `&VnIndex`
|
||||
#[cfg_attr(bootstrap, allow(rustc::pass_by_value))]
|
||||
fn insert(&mut self, ty: Ty<'tcx>, value: Value<'a, 'tcx>) -> (VnIndex, bool) {
|
||||
debug_assert!(match value {
|
||||
Value::Opaque(_) | Value::Address { .. } => false,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//@ compile-flags: -Z unstable-options
|
||||
|
||||
//@ ignore-stage1 (this can be removed when nightly goes to 1.96)
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(rustc_private)]
|
||||
#![deny(rustc::pass_by_value)]
|
||||
#![deny(rustc::disallowed_pass_by_ref)]
|
||||
#![allow(unused)]
|
||||
|
||||
extern crate rustc_middle;
|
||||
|
||||
@@ -7,8 +7,8 @@ LL | ty_ref: &Ty<'_>,
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rustc_pass_by_value.rs:5:9
|
||||
|
|
||||
LL | #![deny(rustc::pass_by_value)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #![deny(rustc::disallowed_pass_by_ref)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: passing `TyCtxt<'_>` by reference
|
||||
--> $DIR/rustc_pass_by_value.rs:16:18
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Considering that all other `internal-lints` are tested here
|
||||
// this seems like the cleaner solution though.
|
||||
#![feature(rustc_attrs)]
|
||||
#![deny(rustc::pass_by_value)]
|
||||
#![deny(rustc::disallowed_pass_by_ref)]
|
||||
#![allow(unused)]
|
||||
|
||||
#[rustc_pass_by_value]
|
||||
|
||||
@@ -7,8 +7,8 @@ LL | fn by_ref(&self) {}
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rustc_pass_by_value_self.rs:8:9
|
||||
|
|
||||
LL | #![deny(rustc::pass_by_value)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #![deny(rustc::disallowed_pass_by_ref)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: passing `Ty<'tcx>` by reference
|
||||
--> $DIR/rustc_pass_by_value_self.rs:30:21
|
||||
|
||||
Reference in New Issue
Block a user