Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,9 +757,11 @@ macro_rules! common_visitor_and_walkers {
) -> 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@ use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind, f
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 },
);
}
}
Expand All @@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue {
}
}

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(_)) => {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod context;
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;
Expand Down Expand Up @@ -65,7 +66,6 @@ mod non_local_def;
mod nonstandard_style;
mod noop_method_call;
mod opaque_hidden_inferred_bound;
mod pass_by_value;
mod passes;
mod precedence;
mod ptr_nulls;
Expand All @@ -88,6 +88,7 @@ use builtin::*;
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::*;
Expand All @@ -109,7 +110,6 @@ use non_local_def::*;
use nonstandard_style::*;
use noop_method_call::*;
use opaque_hidden_inferred_bound::*;
use pass_by_value::*;
use precedence::*;
use ptr_nulls::*;
use redundant_semicolon::*;
Expand Down Expand Up @@ -657,8 +657,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());
Expand All @@ -676,7 +676,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),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1806,10 +1806,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,
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_macros/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ impl<'a, 'tcx> ValueSet<'a, 'tcx> {

/// 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,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui-fulldeps/internal-lints/rustc_pass_by_value.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui-fulldeps/internal-lints/rustc_pass_by_value.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/internal-lints/rustc_pass_by_value_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/internal-lints/rustc_pass_by_value_self.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading