forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#82795 - m-ou-se:rollup-uzx0b92, r=m-ou-se
Rollup of 10 pull requests Successful merges: - rust-lang#80723 (Implement NOOP_METHOD_CALL lint) - rust-lang#80763 (resolve: Reduce scope of `pub_use_of_private_extern_crate` deprecation lint) - rust-lang#81136 (Improved IO Bytes Size Hint) - rust-lang#81939 (Add suggestion `.collect()` for iterators in iterators) - rust-lang#82289 (Fix underflow in specialized ZipImpl::size_hint) - rust-lang#82728 (Avoid unnecessary Vec construction in BufReader) - rust-lang#82764 (Add {BTreeMap,HashMap}::try_insert) - rust-lang#82770 (Add assert_matches macro.) - rust-lang#82773 (Add diagnostic item to `Default` trait) - rust-lang#82787 (Remove unused code from main.js) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
- Loading branch information
Showing
46 changed files
with
776 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
use crate::context::LintContext; | ||
use crate::rustc_middle::ty::TypeFoldable; | ||
use crate::LateContext; | ||
use crate::LateLintPass; | ||
use rustc_hir::def::DefKind; | ||
use rustc_hir::{Expr, ExprKind}; | ||
use rustc_middle::ty; | ||
use rustc_span::symbol::sym; | ||
|
||
declare_lint! { | ||
/// The `noop_method_call` lint detects specific calls to noop methods | ||
/// such as a calling `<&T as Clone>::clone` where `T: !Clone`. | ||
/// | ||
/// ### Example | ||
/// | ||
/// ```rust | ||
/// # #![allow(unused)] | ||
/// #![warn(noop_method_call)] | ||
/// struct Foo; | ||
/// let foo = &Foo; | ||
/// let clone: &Foo = foo.clone(); | ||
/// ``` | ||
/// | ||
/// {{produces}} | ||
/// | ||
/// ### Explanation | ||
/// | ||
/// Some method calls are noops meaning that they do nothing. Usually such methods | ||
/// are the result of blanket implementations that happen to create some method invocations | ||
/// that end up not doing anything. For instance, `Clone` is implemented on all `&T`, but | ||
/// calling `clone` on a `&T` where `T` does not implement clone, actually doesn't do anything | ||
/// as references are copy. This lint detects these calls and warns the user about them. | ||
pub NOOP_METHOD_CALL, | ||
Allow, | ||
"detects the use of well-known noop methods" | ||
} | ||
|
||
declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]); | ||
|
||
impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { | ||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { | ||
// We only care about method calls. | ||
let (call, elements) = match expr.kind { | ||
ExprKind::MethodCall(call, _, elements, _) => (call, elements), | ||
_ => return, | ||
}; | ||
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow` | ||
// traits and ignore any other method call. | ||
let (trait_id, did) = match cx.typeck_results().type_dependent_def(expr.hir_id) { | ||
// Verify we are dealing with a method/associated function. | ||
Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) { | ||
// Check that we're dealing with a trait method for one of the traits we care about. | ||
Some(trait_id) | ||
if [sym::Clone, sym::Deref, sym::Borrow] | ||
.iter() | ||
.any(|s| cx.tcx.is_diagnostic_item(*s, trait_id)) => | ||
{ | ||
(trait_id, did) | ||
} | ||
_ => return, | ||
}, | ||
_ => return, | ||
}; | ||
let substs = cx.typeck_results().node_substs(expr.hir_id); | ||
if substs.needs_subst() { | ||
// We can't resolve on types that require monomorphization, so we don't handle them if | ||
// we need to perfom substitution. | ||
return; | ||
} | ||
let param_env = cx.tcx.param_env(trait_id); | ||
// Resolve the trait method instance. | ||
let i = match ty::Instance::resolve(cx.tcx, param_env, did, substs) { | ||
Ok(Some(i)) => i, | ||
_ => return, | ||
}; | ||
// (Re)check that it implements the noop diagnostic. | ||
for s in [sym::noop_method_clone, sym::noop_method_deref, sym::noop_method_borrow].iter() { | ||
if cx.tcx.is_diagnostic_item(*s, i.def_id()) { | ||
let method = &call.ident.name; | ||
let receiver = &elements[0]; | ||
let receiver_ty = cx.typeck_results().expr_ty(receiver); | ||
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr); | ||
if receiver_ty != expr_ty { | ||
// This lint will only trigger if the receiver type and resulting expression \ | ||
// type are the same, implying that the method call is unnecessary. | ||
return; | ||
} | ||
let expr_span = expr.span; | ||
let note = format!( | ||
"the type `{:?}` which `{}` is being called on is the same as \ | ||
the type returned from `{}`, so the method call does not do \ | ||
anything and can be removed", | ||
receiver_ty, method, method, | ||
); | ||
|
||
let span = expr_span.with_lo(receiver.span.hi()); | ||
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| { | ||
let method = &call.ident.name; | ||
let message = format!( | ||
"call to `.{}()` on a reference in this situation does nothing", | ||
&method, | ||
); | ||
lint.build(&message) | ||
.span_label(span, "unnecessary method call") | ||
.note(¬e) | ||
.emit() | ||
}); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.