Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f373402

Browse files
committed
[Experimental] <T as Into<T>>::into lint
Running crater to see how common that pattern is. The Lint would have to be at most warn-by-default because there are a handful of cases detected that are actually perfectly reasonable (`type` aliases with per-platform `cfg`, or macros) which are now at best half-heartedly handled. I've detected a handful of cases where we're calling `.into()` unnecessarily in the `rustc` codebase as well, and changed those.
1 parent 6de928d commit f373402

File tree

28 files changed

+216
-34
lines changed

28 files changed

+216
-34
lines changed

‎compiler/rustc_ast/src/ast.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,7 +3464,7 @@ impl From<ForeignItemKind> for ItemKind {
34643464
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
34653465
match foreign_item_kind {
34663466
ForeignItemKind::Static(box static_foreign_item) => {
3467-
ItemKind::Static(Box::new(static_foreign_item.into()))
3467+
ItemKind::Static(Box::new(static_foreign_item))
34683468
}
34693469
ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
34703470
ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
@@ -3478,9 +3478,7 @@ impl TryFrom<ItemKind> for ForeignItemKind {
34783478

34793479
fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
34803480
Ok(match item_kind {
3481-
ItemKind::Static(box static_item) => {
3482-
ForeignItemKind::Static(Box::new(static_item.into()))
3483-
}
3481+
ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
34843482
ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
34853483
ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
34863484
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),

‎compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
7878
ecx.push_stack_frame_raw(
7979
cid.instance,
8080
body,
81-
&ret.clone().into(),
81+
&ret.clone(),
8282
StackPopCleanup::Root { cleanup: false },
8383
)?;
8484
ecx.storage_live_for_always_live_locals()?;

‎compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
854854
(Abi::Rust, fn_abi),
855855
&[FnArg::Copy(arg.into())],
856856
false,
857-
&ret.into(),
857+
&ret,
858858
Some(target),
859859
unwind,
860860
)

‎compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2533,7 +2533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25332533
other_generic_param.name.ident() == generic_param.name.ident()
25342534
},
25352535
) {
2536-
idxs_matched.push(other_idx.into());
2536+
idxs_matched.push(other_idx);
25372537
}
25382538

25392539
if idxs_matched.is_empty() {

‎compiler/rustc_lint/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ lint_builtin_no_mangle_static = declaration of a `no_mangle` static
129129
lint_builtin_non_shorthand_field_patterns = the `{$ident}:` in this pattern is redundant
130130
.suggestion = use shorthand field pattern
131131
132+
lint_self_type_conversion = this conversion is useless `{$source}` to `{$target}`
133+
132134
lint_builtin_overridden_symbol_name =
133135
the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
134136

‎compiler/rustc_lint/src/builtin.rs

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use crate::lints::{
6666
BuiltinTrivialBounds, BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller,
6767
BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub,
6868
BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
69-
BuiltinWhileTrue, InvalidAsmLabel,
69+
BuiltinWhileTrue, InvalidAsmLabel,SelfTypeConversionDiag,
7070
};
7171
use crate::nonstandard_style::{method_context, MethodLateContext};
7272
use crate::{
@@ -1604,6 +1604,7 @@ declare_lint_pass!(
16041604
SoftLints => [
16051605
WHILE_TRUE,
16061606
NON_SHORTHAND_FIELD_PATTERNS,
1607+
SELF_TYPE_CONVERSION,
16071608
UNSAFE_CODE,
16081609
MISSING_DOCS,
16091610
MISSING_COPY_IMPLEMENTATIONS,
@@ -3064,3 +3065,95 @@ impl EarlyLintPass for SpecialModuleName {
30643065
}
30653066
}
30663067
}
3068+
3069+
declare_lint! {
3070+
/// The `self_type_conversion` lint detects when a call to `.into()` does not have any effect.
3071+
///
3072+
/// ### Example
3073+
///
3074+
/// ```rust,compile_fail
3075+
/// fn main() {
3076+
/// let () = ().into();
3077+
/// }
3078+
/// ```
3079+
///
3080+
/// {{produces}}
3081+
///
3082+
/// ### Explanation
3083+
///
3084+
pub SELF_TYPE_CONVERSION,
3085+
Deny,
3086+
"",
3087+
}
3088+
3089+
pub struct SelfTypeConversion<'tcx> {
3090+
ignored_types: Vec<Ty<'tcx>>,
3091+
}
3092+
3093+
impl_lint_pass!(SelfTypeConversion<'_> => [SELF_TYPE_CONVERSION]);
3094+
3095+
impl SelfTypeConversion<'_> {
3096+
pub fn new() -> Self {
3097+
Self { ignored_types: vec![] }
3098+
}
3099+
}
3100+
3101+
impl<'tcx> LateLintPass<'tcx> for SelfTypeConversion<'tcx> {
3102+
fn check_item_post(&mut self, cx: &LateContext<'tcx>, item: &hir::Item<'_>) {
3103+
let hir::ItemKind::Use(path, kind) = item.kind else { return };
3104+
tracing::info!("{:#?}", item);
3105+
tracing::info!(?path, ?kind);
3106+
for res in &path.res {
3107+
let Res::Def(DefKind::TyAlias, def_id) = res else { continue };
3108+
let ty = cx.tcx.type_of(def_id).instantiate_identity();
3109+
let name = cx.tcx.item_name(*def_id);
3110+
// println!("{ty:?} {name:?}");
3111+
self.ignored_types.push(ty);
3112+
for stripped in cx.tcx.stripped_cfg_items(def_id.krate) {
3113+
if stripped.name.name == name {
3114+
tracing::info!("{name:#?}");
3115+
}
3116+
}
3117+
}
3118+
}
3119+
3120+
fn check_expr_post(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) {
3121+
let hir::ExprKind::MethodCall(_segment, rcvr, args, _) = expr.kind else { return };
3122+
if !args.is_empty() {
3123+
tracing::info!("non-empty args");
3124+
return;
3125+
}
3126+
let ty = cx.typeck_results().expr_ty(expr);
3127+
let rcvr_ty = cx.typeck_results().expr_ty(rcvr);
3128+
tracing::info!(?ty, ?rcvr_ty);
3129+
3130+
if ty != rcvr_ty {
3131+
tracing::info!("different types");
3132+
return;
3133+
}
3134+
if self.ignored_types.contains(&rcvr_ty) {
3135+
return;
3136+
}
3137+
let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) else {
3138+
tracing::info!("no type dependent def id");
3139+
return;
3140+
};
3141+
tracing::info!(?def_id);
3142+
if Some(def_id) != cx.tcx.get_diagnostic_item(sym::into_fn) {
3143+
tracing::info!("not into_fn {:?}", cx.tcx.get_diagnostic_item(sym::into_fn));
3144+
return;
3145+
}
3146+
tracing::info!(?def_id);
3147+
tracing::info!(?expr);
3148+
if expr.span.macro_backtrace().next().is_some() {
3149+
return;
3150+
}
3151+
// println!("{:#?}", self.ignored_types);
3152+
cx.emit_span_lint(
3153+
SELF_TYPE_CONVERSION,
3154+
expr.span,
3155+
SelfTypeConversionDiag { source: rcvr_ty, target: ty },
3156+
);
3157+
// bug!("asdf");
3158+
}
3159+
}

‎compiler/rustc_lint/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ early_lint_methods!(
185185
late_lint_methods!(
186186
declare_combined_late_lint_pass,
187187
[
188-
BuiltinCombinedModuleLateLintPass,
188+
BuiltinCombinedModuleLateLintPass<'tcx>,
189189
[
190190
ForLoopsOverFallibles: ForLoopsOverFallibles,
191191
DerefIntoDynSupertrait: DerefIntoDynSupertrait,
@@ -203,6 +203,7 @@ late_lint_methods!(
203203
UnitBindings: UnitBindings,
204204
NonUpperCaseGlobals: NonUpperCaseGlobals,
205205
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
206+
SelfTypeConversion<'tcx>: SelfTypeConversion::new(),
206207
UnusedAllocation: UnusedAllocation,
207208
// Depends on types used in type definitions
208209
MissingCopyImplementations: MissingCopyImplementations,
@@ -268,6 +269,7 @@ fn register_builtins(store: &mut LintStore) {
268269
store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints());
269270
store.register_lints(&foreign_modules::get_lints());
270271

272+
store.register_late_pass(move |_tcx| Box::new(SelfTypeConversion::new()));
271273
add_lint_group!(
272274
"nonstandard_style",
273275
NON_CAMEL_CASE_TYPES,
@@ -298,6 +300,7 @@ fn register_builtins(store: &mut LintStore) {
298300
UNUSED_PARENS,
299301
UNUSED_BRACES,
300302
REDUNDANT_SEMICOLONS,
303+
// SELF_TYPE_CONVERSION,
301304
MAP_UNIT_FN
302305
);
303306

‎compiler/rustc_lint/src/lints.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ pub struct BuiltinNonShorthandFieldPatterns {
7272
pub prefix: &'static str,
7373
}
7474

75+
#[derive(LintDiagnostic)]
76+
#[diag(lint_self_type_conversion)]
77+
pub struct SelfTypeConversionDiag<'t> {
78+
pub source: Ty<'t>,
79+
pub target: Ty<'t>,
80+
}
81+
7582
#[derive(LintDiagnostic)]
7683
pub enum BuiltinUnsafe {
7784
#[diag(lint_builtin_allow_internal_unsafe)]

‎compiler/rustc_lint/src/passes.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ macro_rules! expand_combined_late_lint_pass_methods {
9393
/// runtime.
9494
#[macro_export]
9595
macro_rules! declare_combined_late_lint_pass {
96-
([$v:vis $name:ident, [$($pass:ident: $constructor:expr,)*]], $methods:tt) => (
96+
([$v:vis $name:ident$(<$lt:lifetime>)?, [$($pass:ident$(<$inner_lt:lifetime>)?: $constructor:expr,)*]], $methods:tt) => (
9797
#[allow(non_snake_case)]
98-
$v struct $name {
99-
$($pass: $pass,)*
98+
$v struct $name$(<$lt>)? {
99+
$($pass: $pass$(<$inner_lt>)?,)*
100100
}
101101

102-
impl $name {
102+
impl$(<$lt>)? $name$(<$lt>)? {
103103
$v fn new() -> Self {
104104
Self {
105105
$($pass: $constructor,)*
@@ -113,12 +113,12 @@ macro_rules! declare_combined_late_lint_pass {
113113
}
114114
}
115115

116-
impl<'tcx> $crate::LateLintPass<'tcx> for $name {
116+
impl<'tcx> $crate::LateLintPass<'tcx> for $name$(<$lt>)? {
117117
$crate::expand_combined_late_lint_pass_methods!([$($pass),*], $methods);
118118
}
119119

120120
#[allow(rustc::lint_pass_impl_without_macro)]
121-
impl $crate::LintPass for $name {
121+
impl$(<$lt>)? $crate::LintPass for $name$(<$lt>)? {
122122
fn name(&self) -> &'static str {
123123
panic!()
124124
}

‎compiler/rustc_middle/src/ty/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ impl<'tcx> Const<'tcx> {
384384
Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c))
385385
}
386386
Ok(Err(bad_ty)) => Err(Either::Left(bad_ty)),
387-
Err(err) => Err(Either::Right(err.into())),
387+
Err(err) => Err(Either::Right(err)),
388388
}
389389
}
390390
ConstKind::Value(ty, val) => Ok((ty, val)),

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /