Skip to content
Open
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
411 changes: 410 additions & 1 deletion compiler/rustc_lint/src/builtin.rs

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions compiler/rustc_lint/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,44 @@ pub(crate) enum ShadowedIntoIterDiagSub {
},
}

#[derive(Diagnostic)]
#[diag("useless conversion to the same type: `{$ty}`")]
#[note(
"this method call relies on the `impl<T> Into<T> for T` blanket implementation and type \
inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be \
added in the future causing type inference errors"
)]
pub(crate) struct SelfTypeConversionDiag<'t> {
pub ty: Ty<'t>,
#[suggestion(
"consider removing the conversion call",
style = "verbose",
code = "",
applicability = "machine-applicable"
)]
Comment on lines +178 to +183

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an alternative suggestion to expect the lint on the enclosing item too, with an explanation that the lint can sometimes be over-eager?

pub removal_span: Option<Span>,
#[subdiagnostic]
pub fully_qualified_path: Option<FullyQualifiedPathSuggestion<'t>>,
#[note(
"you can instead use the fully-qualified path `<{$ty} as Into<{$ty}>::into(val) to avoid \
triggering this lint"
)]
pub fully_qualified_path_note: bool,
}

#[derive(Subdiagnostic)]
#[multipart_suggestion(
"you can use the fully-qualified path to avoid triggering this lint",
applicability = "maybe-incorrect"
)]
pub(crate) struct FullyQualifiedPathSuggestion<'t> {
pub ty: Ty<'t>,
#[suggestion_part(code = "<{ty} as Into<_>>::into(")]
pub pre: Span,
#[suggestion_part(code = ")")]
pub post: Span,
}

// autorefs.rs
#[derive(Diagnostic)]
#[diag("implicit autoref creates a reference to the dereference of a raw pointer")]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ fn register_builtins(store: &mut LintStore) {
store.register_lints(&BuiltinCombinedLateLintModPass::lint_vec());
store.register_lints(&foreign_modules::lint_vec());
store.register_lints(&hardwired::lint_vec());
store.register_lints(&SelfTypeConversion::lint_vec());
store.register_late_lint_pass(Box::new(|_| Box::new(SelfTypeConversion::new())));

add_lint_group!(
"nonstandard_style",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/host_dylib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ pub(crate) fn dlsym_proc_macros(
}
Err(err) => {
debug!("failed to dlsym proc_macros {} for symbol `{}`", path.display(), sym_name);
Err(err.into())
Err(err)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/hir/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

/// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`.
/// Walks the contents of the local crate. See also `hir_visit_all_item_likes_in_crate`.
pub fn hir_walk_toplevel_module<V>(self, visitor: &mut V) -> V::Result
where
V: Visitor<'tcx>,
Expand Down Expand Up @@ -473,7 +473,7 @@ impl<'tcx> TyCtxt<'tcx> {
V::Result::output()
}

/// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to
/// This method is the equivalent of `hir_visit_all_item_likes_in_crate` but restricted to
/// item-likes in a single module.
pub fn hir_visit_item_likes_in_module<V>(self, module: LocalModId, visitor: &mut V) -> V::Result
where
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/inhabitedness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ impl<'tcx> OpsemInhabitedCtx<'tcx> {
args.upvar_tys().iter().all(|ty| self.is_inhabited_ty(ty))
}
ty::UnsafeBinder(base) => {
let base = tcx.instantiate_bound_regions_with_erased((*base).into());
let base = tcx.instantiate_bound_regions_with_erased(*base);
self.is_inhabited_ty(base)
}
ty::Adt(def, args) => self.is_inhabited_adt_ty(def, args),
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ where
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
},
)
.map_err(Into::into)
});

Ok(match result.map_err_to_rerun()? {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,6 @@ where
pred,
requirements,
)
.map_err(Into::into)
}

fn consider_builtin_async_fn_trait_candidates(
Expand Down Expand Up @@ -487,7 +486,7 @@ where
let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
let trait_goal: Goal<I, ty::TraitClause<I>> =
goal.with(ecx.cx(), goal.predicate.trait_ref);
ecx.compute_trait_goal(trait_goal).map_err(Into::into)
ecx.compute_trait_goal(trait_goal)
})?;
self.assemble_and_merge_candidates(
proven_via,
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_next_trait_solver/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,10 @@ where

let ct_ty = match ct.kind() {
ty::ConstKind::Infer(_) => {
return self
.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
.map_err(Into::into);
return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
}
ty::ConstKind::Error(_) => {
return self
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into);
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
}
ty::ConstKind::Alias(ty::IsRigid::Yes, alias_const) => {
alias_const.type_of(self.cx()).skip_norm_wip()
Expand All @@ -318,7 +314,7 @@ where
};

self.eq(goal.param_env, ct_ty, ty)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ where
}
ty::AliasTermKind::OpaqueTy { .. } => self.normalize_opaque_type(goal),
ty::AliasTermKind::FreeTy { .. } | ty::AliasTermKind::FreeConst { .. } => {
self.normalize_free_alias(goal).map_err(Into::into)
}
ty::AliasTermKind::AnonConst { .. } => {
self.normalize_anon_const(goal).map_err(Into::into)
self.normalize_free_alias(goal)
}
ty::AliasTermKind::AnonConst { .. } => self.normalize_anon_const(goal),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ where
// This can then allow nested goals to fail after we've constrained the `term`.
self.add_goal(GoalSource::Misc, goal.with(cx, ty::PredicateKind::Ambiguous))?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into)
}
TypingMode::Typeck { defining_opaque_types_and_generators: defining_opaque_types }
| TypingMode::PostTypeckUntilBorrowck { defining_opaque_types } => {
Expand All @@ -53,9 +52,7 @@ where
opaque_ty.to_term(cx, ty::IsRigid::Yes),
goal.predicate.term,
)?;
return self
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into);
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
};

// We structurally normalize the args so that we're able to detect defining uses
Expand Down Expand Up @@ -117,7 +114,6 @@ where
expected,
)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into)
}
TypingMode::PostBorrowck { defined_opaque_types } => {
let Some(def_id) = def_id
Expand All @@ -129,9 +125,7 @@ where
opaque_ty.to_term(cx, ty::IsRigid::Yes),
goal.predicate.term,
)?;
return self
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into);
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
};

let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args);
Expand All @@ -147,7 +141,6 @@ where
let actual = self.normalize(goal.param_env, actual)?;
self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into)
}
// FIXME(try_as_dyn): probably want to treat opaques opaquely and rigid
TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => {
Expand All @@ -156,7 +149,6 @@ where
let actual = self.normalize(goal.param_env, actual)?;
self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into)
}
TypingMode::ErasedNotCoherence(MayBeErased) => {
// If we have a local defid, in other typing modes we check whether
Expand Down Expand Up @@ -185,7 +177,6 @@ where
goal.predicate.term,
)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
.map_err(Into::into)
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ symbols! {
internal_features,
interrupt,
into_async_iter_into_iter,
into_fn,
into_future,
into_iter,
into_try_type,
Expand Down Expand Up @@ -1537,6 +1538,7 @@ symbols! {
optin_builtin_traits,
option,
option_env,
option_map,
options,
or,
or_patterns,
Expand Down Expand Up @@ -1767,6 +1769,8 @@ symbols! {
residual,
result,
result_ffi_guarantees,
result_map,
result_map_err,
return_address,
return_position_impl_trait_in_trait,
return_type_notation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ fn foo(&self) -> Self::T { String::new() }
}
};
diag.span_context(tcx.def_span(tcx.parent(assoc_item.def_id)));
diag.span_label(tcx.def_span(assoc_item.def_id).into(), msg);
diag.span_label(tcx.def_span(assoc_item.def_id), msg);
return true;
}
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ pub const trait AsMut<T: PointeeSized>: PointeeSized {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
pub const trait Into<T>: Sized {
/// Converts this type into the (usually inferred) input type.
#[rustc_diagnostic_item = "into_fn"]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn into(self) -> T;
Expand Down
1 change: 1 addition & 0 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@ impl<T> Option<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
#[rustc_diagnostic_item = "option_map"]
pub const fn map<U, F>(self, f: F) -> Option<U>
where
F: [const] FnOnce(T) -> U + [const] Destruct,
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ impl<T, E> Result<T, E> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
#[rustc_diagnostic_item = "result_map"]
pub const fn map<U, F>(self, op: F) -> Result<U, E>
where
F: [const] FnOnce(T) -> U + [const] Destruct,
Expand Down Expand Up @@ -958,6 +959,7 @@ impl<T, E> Result<T, E> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_result_trait_fn", issue = "144211")]
#[rustc_diagnostic_item = "result_map_err"]
pub const fn map_err<F, O>(self, op: O) -> Result<T, F>
where
O: [const] FnOnce(E) -> F + [const] Destruct,
Expand Down
1 change: 1 addition & 0 deletions library/coretests/tests/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fn convert() {
assert_eq!(FOO, 42);

const fn into(x: Vec<String>) -> Vec<String> {
#[allow(self_type_conversion)]
x.into()
}

Expand Down
1 change: 1 addition & 0 deletions library/std/src/os/unix/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ impl ExitStatusExt for process::ExitStatus {
}

fn into_raw(self) -> i32 {
#[allow(self_type_conversion)]
self.as_inner().into_raw().into()
}
Comment on lines 436 to 439

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The level of indirection I need to account for to correctly allow this case seems a bit more than what we'd want to encode in the lint, unless it is a common pattern out in the ecosystem.

}
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/process/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl CommandEnv {
let mut result = BTreeMap::<EnvKey, OsString>::new();
if !self.clear {
for (k, v) in env::vars_os() {
#[allow(self_type_conversion)]
result.insert(k.into(), v);
}
}
Expand Down Expand Up @@ -137,6 +138,7 @@ impl Iterator for CommandResolvedEnvs {
type Item = (OsString, OsString);

fn next(&mut self) -> Option<Self::Item> {
#[allow(self_type_conversion)]
self.inner.next().map(|(key, value)| (key.into(), value))
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_config/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ macro_rules! define_Conf {
$name = Some(
<$ty as DeserializeOrDefault<_>>::deserialize_or_default(
dcx,
value.into(),
value,
first_expr!($($default,)? ()),
),
);
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_config/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ macro_rules! deserialize_table {
match &**key.get_ref() {
$($name_str => {
// Duplicate keys are handled by the toml parser
$name = <$ty as crate::de::Deserialize>::deserialize($dcx, value.into());
$name = <$ty as crate::de::Deserialize>::deserialize($dcx, value);
},)+
_ => {
const NAMES: &[&str] = &[$($name_str),*];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
clippy::needless_return,
clippy::no_effect,
clippy::unit_arg,
clippy::useless_conversion
clippy::useless_conversion,
self_type_conversion,
unused
)]

#[macro_use]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
clippy::needless_return,
clippy::no_effect,
clippy::unit_arg,
clippy::useless_conversion
clippy::useless_conversion,
self_type_conversion,
unused
)]

#[macro_use]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: unneeded `return` statement with `?` operator
--> tests/ui/needless_return_with_question_mark.rs:28:5
--> tests/ui/needless_return_with_question_mark.rs:30:5
|
LL | return Err(())?;
| ^^^^^^^ help: remove it
Expand All @@ -8,25 +8,25 @@ LL | return Err(())?;
= help: to override `-D warnings` add `#[allow(clippy::needless_return_with_question_mark)]`

error: unneeded `return` statement with `?` operator
--> tests/ui/needless_return_with_question_mark.rs:69:9
--> tests/ui/needless_return_with_question_mark.rs:71:9
|
LL | return Err(())?;
| ^^^^^^^ help: remove it

error: unneeded `return` statement with `?` operator
--> tests/ui/needless_return_with_question_mark.rs:133:9
--> tests/ui/needless_return_with_question_mark.rs:135:9
|
LL | return Err(())?;
| ^^^^^^^ help: remove it

error: unneeded `return` statement with `?` operator
--> tests/ui/needless_return_with_question_mark.rs:142:13
--> tests/ui/needless_return_with_question_mark.rs:144:13
|
LL | return Err(())?;
| ^^^^^^^ help: remove it

error: unneeded `return` statement with `?` operator
--> tests/ui/needless_return_with_question_mark.rs:162:5
--> tests/ui/needless_return_with_question_mark.rs:164:5
|
LL | return Err(())?;
| ^^^^^^^ help: remove it
Expand Down
Loading
Loading