use let chains in hir, lint, mir
This commit is contained in:
parent
43725ed819
commit
bae38bad78
24 changed files with 278 additions and 307 deletions
|
|
@ -3008,13 +3008,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
/// Returns whether the given expression is an `else if`.
|
||||
fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
|
||||
if let hir::ExprKind::If(..) = expr.kind {
|
||||
if let Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::If(_, _, Some(else_expr)), ..
|
||||
}) = self.tcx.parent_hir_node(expr.hir_id)
|
||||
{
|
||||
return else_expr.hir_id == expr.hir_id;
|
||||
}
|
||||
if let hir::ExprKind::If(..) = expr.kind
|
||||
&& let Node::Expr(hir::Expr { kind: hir::ExprKind::If(_, _, Some(else_expr)), .. }) =
|
||||
self.tcx.parent_hir_node(expr.hir_id)
|
||||
{
|
||||
return else_expr.hir_id == expr.hir_id;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -669,17 +669,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
|
||||
fn check_for_illegal_method_calls(&self, pick: &probe::Pick<'_>) {
|
||||
// Disallow calls to the method `drop` defined in the `Drop` trait.
|
||||
if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
|
||||
if let Err(e) = callee::check_legal_trait_for_method_call(
|
||||
if let Some(trait_def_id) = pick.item.trait_container(self.tcx)
|
||||
&& let Err(e) = callee::check_legal_trait_for_method_call(
|
||||
self.tcx,
|
||||
self.span,
|
||||
Some(self.self_expr.span),
|
||||
self.call_expr.span,
|
||||
trait_def_id,
|
||||
self.body_id.to_def_id(),
|
||||
) {
|
||||
self.set_tainted_by_errors(e);
|
||||
}
|
||||
)
|
||||
{
|
||||
self.set_tainted_by_errors(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,13 +165,12 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
|
|||
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) =
|
||||
obligation.predicate.kind().skip_binder()
|
||||
{
|
||||
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
|
||||
// we need to make it into one.
|
||||
if let Some(vid) = predicate.term.as_type().and_then(|ty| ty.ty_vid()) {
|
||||
debug!("infer_var_info: {:?}.output = true", vid);
|
||||
infer_var_info.entry(vid).or_default().output = true;
|
||||
}
|
||||
&& let Some(vid) = predicate.term.as_type().and_then(|ty| ty.ty_vid())
|
||||
{
|
||||
debug!("infer_var_info: {:?}.output = true", vid);
|
||||
infer_var_info.entry(vid).or_default().output = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,21 +227,19 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
|
||||
self.typeck_results.node_args_mut().remove(e.hir_id);
|
||||
|
||||
if let Some(a) = self.typeck_results.adjustments_mut().get_mut(base.hir_id) {
|
||||
if let Some(a) = self.typeck_results.adjustments_mut().get_mut(base.hir_id)
|
||||
// Discard the need for a mutable borrow
|
||||
|
||||
// Extra adjustment made when indexing causes a drop
|
||||
// of size information - we need to get rid of it
|
||||
// Since this is "after" the other adjustment to be
|
||||
// discarded, we do an extra `pop()`
|
||||
if let Some(Adjustment {
|
||||
&& let Some(Adjustment {
|
||||
kind: Adjust::Pointer(PointerCoercion::Unsize),
|
||||
..
|
||||
}) = a.pop()
|
||||
{
|
||||
// So the borrow discard actually happens here
|
||||
a.pop();
|
||||
}
|
||||
{
|
||||
// So the borrow discard actually happens here
|
||||
a.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2446,16 +2446,16 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
|||
|
||||
/// Determine if this expression is a "dangerous initialization".
|
||||
fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<InitKind> {
|
||||
if let hir::ExprKind::Call(path_expr, args) = expr.kind {
|
||||
if let hir::ExprKind::Call(path_expr, args) = expr.kind
|
||||
// Find calls to `mem::{uninitialized,zeroed}` methods.
|
||||
if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
|
||||
let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
|
||||
match cx.tcx.get_diagnostic_name(def_id) {
|
||||
Some(sym::mem_zeroed) => return Some(InitKind::Zeroed),
|
||||
Some(sym::mem_uninitialized) => return Some(InitKind::Uninit),
|
||||
Some(sym::transmute) if is_zero(&args[0]) => return Some(InitKind::Zeroed),
|
||||
_ => {}
|
||||
}
|
||||
&& let hir::ExprKind::Path(ref qpath) = path_expr.kind
|
||||
{
|
||||
let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
|
||||
match cx.tcx.get_diagnostic_name(def_id) {
|
||||
Some(sym::mem_zeroed) => return Some(InitKind::Zeroed),
|
||||
Some(sym::mem_uninitialized) => return Some(InitKind::Uninit),
|
||||
Some(sym::transmute) if is_zero(&args[0]) => return Some(InitKind::Zeroed),
|
||||
_ => {}
|
||||
}
|
||||
} else if let hir::ExprKind::MethodCall(_, receiver, ..) = expr.kind {
|
||||
// Find problematic calls to `MaybeUninit::assume_init`.
|
||||
|
|
@ -2463,14 +2463,14 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
|
|||
if cx.tcx.is_diagnostic_item(sym::assume_init, def_id) {
|
||||
// This is a call to *some* method named `assume_init`.
|
||||
// See if the `self` parameter is one of the dangerous constructors.
|
||||
if let hir::ExprKind::Call(path_expr, _) = receiver.kind {
|
||||
if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
|
||||
let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
|
||||
match cx.tcx.get_diagnostic_name(def_id) {
|
||||
Some(sym::maybe_uninit_zeroed) => return Some(InitKind::Zeroed),
|
||||
Some(sym::maybe_uninit_uninit) => return Some(InitKind::Uninit),
|
||||
_ => {}
|
||||
}
|
||||
if let hir::ExprKind::Call(path_expr, _) = receiver.kind
|
||||
&& let hir::ExprKind::Path(ref qpath) = path_expr.kind
|
||||
{
|
||||
let def_id = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
|
||||
match cx.tcx.get_diagnostic_name(def_id) {
|
||||
Some(sym::maybe_uninit_zeroed) => return Some(InitKind::Zeroed),
|
||||
Some(sym::maybe_uninit_uninit) => return Some(InitKind::Uninit),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2724,13 +2724,13 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr {
|
|||
}
|
||||
// check for call to `core::ptr::null` or `core::ptr::null_mut`
|
||||
hir::ExprKind::Call(path, _) => {
|
||||
if let hir::ExprKind::Path(ref qpath) = path.kind {
|
||||
if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() {
|
||||
return matches!(
|
||||
cx.tcx.get_diagnostic_name(def_id),
|
||||
Some(sym::ptr_null | sym::ptr_null_mut)
|
||||
);
|
||||
}
|
||||
if let hir::ExprKind::Path(ref qpath) = path.kind
|
||||
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
||||
{
|
||||
return matches!(
|
||||
cx.tcx.get_diagnostic_name(def_id),
|
||||
Some(sym::ptr_null | sym::ptr_null_mut)
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -411,22 +411,21 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
|
|||
|
||||
impl EarlyLintPass for LintPassImpl {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
|
||||
if let ast::ItemKind::Impl(box ast::Impl { of_trait: Some(lint_pass), .. }) = &item.kind {
|
||||
if let Some(last) = lint_pass.path.segments.last() {
|
||||
if last.ident.name == sym::LintPass {
|
||||
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
|
||||
let call_site = expn_data.call_site;
|
||||
if expn_data.kind != ExpnKind::Macro(MacroKind::Bang, sym::impl_lint_pass)
|
||||
&& call_site.ctxt().outer_expn_data().kind
|
||||
!= ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass)
|
||||
{
|
||||
cx.emit_span_lint(
|
||||
LINT_PASS_IMPL_WITHOUT_MACRO,
|
||||
lint_pass.path.span,
|
||||
LintPassByHand,
|
||||
);
|
||||
}
|
||||
}
|
||||
if let ast::ItemKind::Impl(box ast::Impl { of_trait: Some(lint_pass), .. }) = &item.kind
|
||||
&& let Some(last) = lint_pass.path.segments.last()
|
||||
&& last.ident.name == sym::LintPass
|
||||
{
|
||||
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
|
||||
let call_site = expn_data.call_site;
|
||||
if expn_data.kind != ExpnKind::Macro(MacroKind::Bang, sym::impl_lint_pass)
|
||||
&& call_site.ctxt().outer_expn_data().kind
|
||||
!= ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass)
|
||||
{
|
||||
cx.emit_span_lint(
|
||||
LINT_PASS_IMPL_WITHOUT_MACRO,
|
||||
lint_pass.path.span,
|
||||
LintPassByHand,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,56 +43,50 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
|
|||
return;
|
||||
}
|
||||
|
||||
if let StmtKind::Semi(expr) = stmt.kind {
|
||||
if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind {
|
||||
if path.ident.name.as_str() == "map" {
|
||||
if receiver.span.from_expansion()
|
||||
|| args.iter().any(|e| e.span.from_expansion())
|
||||
|| !is_impl_slice(cx, receiver)
|
||||
|| !is_diagnostic_name(cx, expr.hir_id, "IteratorMap")
|
||||
{
|
||||
return;
|
||||
if let StmtKind::Semi(expr) = stmt.kind
|
||||
&& let ExprKind::MethodCall(path, receiver, args, span) = expr.kind
|
||||
{
|
||||
if path.ident.name.as_str() == "map" {
|
||||
if receiver.span.from_expansion()
|
||||
|| args.iter().any(|e| e.span.from_expansion())
|
||||
|| !is_impl_slice(cx, receiver)
|
||||
|| !is_diagnostic_name(cx, expr.hir_id, "IteratorMap")
|
||||
{
|
||||
return;
|
||||
}
|
||||
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
|
||||
let default_span = args[0].span;
|
||||
if let ty::FnDef(id, _) = arg_ty.kind() {
|
||||
let fn_ty = cx.tcx.fn_sig(id).skip_binder();
|
||||
let ret_ty = fn_ty.output().skip_binder();
|
||||
if is_unit_type(ret_ty) {
|
||||
cx.emit_span_lint(
|
||||
MAP_UNIT_FN,
|
||||
span,
|
||||
MappingToUnit {
|
||||
function_label: cx.tcx.span_of_impl(*id).unwrap_or(default_span),
|
||||
argument_label: args[0].span,
|
||||
map_label: span,
|
||||
suggestion: path.ident.span,
|
||||
replace: "for_each".to_string(),
|
||||
},
|
||||
)
|
||||
}
|
||||
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
|
||||
let default_span = args[0].span;
|
||||
if let ty::FnDef(id, _) = arg_ty.kind() {
|
||||
let fn_ty = cx.tcx.fn_sig(id).skip_binder();
|
||||
let ret_ty = fn_ty.output().skip_binder();
|
||||
if is_unit_type(ret_ty) {
|
||||
cx.emit_span_lint(
|
||||
MAP_UNIT_FN,
|
||||
span,
|
||||
MappingToUnit {
|
||||
function_label: cx
|
||||
.tcx
|
||||
.span_of_impl(*id)
|
||||
.unwrap_or(default_span),
|
||||
argument_label: args[0].span,
|
||||
map_label: span,
|
||||
suggestion: path.ident.span,
|
||||
replace: "for_each".to_string(),
|
||||
},
|
||||
)
|
||||
}
|
||||
} else if let ty::Closure(id, subs) = arg_ty.kind() {
|
||||
let cl_ty = subs.as_closure().sig();
|
||||
let ret_ty = cl_ty.output().skip_binder();
|
||||
if is_unit_type(ret_ty) {
|
||||
cx.emit_span_lint(
|
||||
MAP_UNIT_FN,
|
||||
span,
|
||||
MappingToUnit {
|
||||
function_label: cx
|
||||
.tcx
|
||||
.span_of_impl(*id)
|
||||
.unwrap_or(default_span),
|
||||
argument_label: args[0].span,
|
||||
map_label: span,
|
||||
suggestion: path.ident.span,
|
||||
replace: "for_each".to_string(),
|
||||
},
|
||||
)
|
||||
}
|
||||
} else if let ty::Closure(id, subs) = arg_ty.kind() {
|
||||
let cl_ty = subs.as_closure().sig();
|
||||
let ret_ty = cl_ty.output().skip_binder();
|
||||
if is_unit_type(ret_ty) {
|
||||
cx.emit_span_lint(
|
||||
MAP_UNIT_FN,
|
||||
span,
|
||||
MappingToUnit {
|
||||
function_label: cx.tcx.span_of_impl(*id).unwrap_or(default_span),
|
||||
argument_label: args[0].span,
|
||||
map_label: span,
|
||||
suggestion: path.ident.span,
|
||||
replace: "for_each".to_string(),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,10 +95,10 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
|
|||
}
|
||||
|
||||
fn is_impl_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
|
||||
if let Some(impl_id) = cx.tcx.impl_of_method(method_id) {
|
||||
return cx.tcx.type_of(impl_id).skip_binder().is_slice();
|
||||
}
|
||||
if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id)
|
||||
{
|
||||
return cx.tcx.type_of(impl_id).skip_binder().is_slice();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
@ -114,11 +108,11 @@ fn is_unit_type(ty: Ty<'_>) -> bool {
|
|||
}
|
||||
|
||||
fn is_diagnostic_name(cx: &LateContext<'_>, id: HirId, name: &str) -> bool {
|
||||
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(id) {
|
||||
if let Some(item) = cx.tcx.get_diagnostic_name(def_id) {
|
||||
if item.as_str() == name {
|
||||
return true;
|
||||
}
|
||||
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(id)
|
||||
&& let Some(item) = cx.tcx.get_diagnostic_name(def_id)
|
||||
{
|
||||
if item.as_str() == name {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
|
|
|
|||
|
|
@ -48,38 +48,38 @@ declare_lint_pass!(NonPanicFmt => [NON_FMT_PANICS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for NonPanicFmt {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let hir::ExprKind::Call(f, [arg]) = &expr.kind {
|
||||
if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() {
|
||||
let f_diagnostic_name = cx.tcx.get_diagnostic_name(def_id);
|
||||
if let hir::ExprKind::Call(f, [arg]) = &expr.kind
|
||||
&& let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind()
|
||||
{
|
||||
let f_diagnostic_name = cx.tcx.get_diagnostic_name(def_id);
|
||||
|
||||
if cx.tcx.is_lang_item(def_id, LangItem::BeginPanic)
|
||||
|| cx.tcx.is_lang_item(def_id, LangItem::Panic)
|
||||
|| f_diagnostic_name == Some(sym::panic_str_2015)
|
||||
if cx.tcx.is_lang_item(def_id, LangItem::BeginPanic)
|
||||
|| cx.tcx.is_lang_item(def_id, LangItem::Panic)
|
||||
|| f_diagnostic_name == Some(sym::panic_str_2015)
|
||||
{
|
||||
if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id {
|
||||
if matches!(
|
||||
cx.tcx.get_diagnostic_name(id),
|
||||
Some(sym::core_panic_2015_macro | sym::std_panic_2015_macro)
|
||||
) {
|
||||
check_panic(cx, f, arg);
|
||||
}
|
||||
}
|
||||
} else if f_diagnostic_name == Some(sym::unreachable_display) {
|
||||
if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id
|
||||
&& cx.tcx.is_diagnostic_item(sym::unreachable_2015_macro, id)
|
||||
{
|
||||
if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id {
|
||||
if matches!(
|
||||
cx.tcx.get_diagnostic_name(id),
|
||||
Some(sym::core_panic_2015_macro | sym::std_panic_2015_macro)
|
||||
) {
|
||||
check_panic(cx, f, arg);
|
||||
}
|
||||
}
|
||||
} else if f_diagnostic_name == Some(sym::unreachable_display) {
|
||||
if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id {
|
||||
if cx.tcx.is_diagnostic_item(sym::unreachable_2015_macro, id) {
|
||||
check_panic(
|
||||
cx,
|
||||
f,
|
||||
// This is safe because we checked above that the callee is indeed
|
||||
// unreachable_display
|
||||
match &arg.kind {
|
||||
// Get the borrowed arg not the borrow
|
||||
hir::ExprKind::AddrOf(ast::BorrowKind::Ref, _, arg) => arg,
|
||||
_ => bug!("call to unreachable_display without borrow"),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
check_panic(
|
||||
cx,
|
||||
f,
|
||||
// This is safe because we checked above that the callee is indeed
|
||||
// unreachable_display
|
||||
match &arg.kind {
|
||||
// Get the borrowed arg not the borrow
|
||||
hir::ExprKind::AddrOf(ast::BorrowKind::Ref, _, arg) => arg,
|
||||
_ => bug!("call to unreachable_display without borrow"),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -623,15 +623,15 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
|
|||
..
|
||||
}) = p.kind
|
||||
{
|
||||
if let Res::Def(DefKind::Const, _) = path.res {
|
||||
if let [segment] = path.segments {
|
||||
NonUpperCaseGlobals::check_upper_case(
|
||||
cx,
|
||||
"constant in pattern",
|
||||
None,
|
||||
&segment.ident,
|
||||
);
|
||||
}
|
||||
if let Res::Def(DefKind::Const, _) = path.res
|
||||
&& let [segment] = path.segments
|
||||
{
|
||||
NonUpperCaseGlobals::check_upper_case(
|
||||
cx,
|
||||
"constant in pattern",
|
||||
None,
|
||||
&segment.ident,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -562,20 +562,19 @@ declare_lint_pass!(PathStatements => [PATH_STATEMENTS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for PathStatements {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
|
||||
if let hir::StmtKind::Semi(expr) = s.kind {
|
||||
if let hir::ExprKind::Path(_) = expr.kind {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if ty.needs_drop(cx.tcx, cx.typing_env()) {
|
||||
let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span)
|
||||
{
|
||||
PathStatementDropSub::Suggestion { span: s.span, snippet }
|
||||
} else {
|
||||
PathStatementDropSub::Help { span: s.span }
|
||||
};
|
||||
cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementDrop { sub })
|
||||
if let hir::StmtKind::Semi(expr) = s.kind
|
||||
&& let hir::ExprKind::Path(_) = expr.kind
|
||||
{
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
if ty.needs_drop(cx.tcx, cx.typing_env()) {
|
||||
let sub = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) {
|
||||
PathStatementDropSub::Suggestion { span: s.span, snippet }
|
||||
} else {
|
||||
cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementNoEffect);
|
||||
}
|
||||
PathStatementDropSub::Help { span: s.span }
|
||||
};
|
||||
cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementDrop { sub })
|
||||
} else {
|
||||
cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementNoEffect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1509,21 +1508,19 @@ impl UnusedDelimLint for UnusedBraces {
|
|||
// let _: A<{produces_literal!()}>;
|
||||
// ```
|
||||
// FIXME(const_generics): handle paths when #67075 is fixed.
|
||||
if let [stmt] = inner.stmts.as_slice() {
|
||||
if let ast::StmtKind::Expr(ref expr) = stmt.kind {
|
||||
if !Self::is_expr_delims_necessary(expr, ctx, followed_by_block)
|
||||
&& (ctx != UnusedDelimsCtx::AnonConst
|
||||
|| (matches!(expr.kind, ast::ExprKind::Lit(_))
|
||||
&& !expr.span.from_expansion()))
|
||||
&& ctx != UnusedDelimsCtx::ClosureBody
|
||||
&& !cx.sess().source_map().is_multiline(value.span)
|
||||
&& value.attrs.is_empty()
|
||||
&& !value.span.from_expansion()
|
||||
&& !inner.span.from_expansion()
|
||||
{
|
||||
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
|
||||
}
|
||||
}
|
||||
if let [stmt] = inner.stmts.as_slice()
|
||||
&& let ast::StmtKind::Expr(ref expr) = stmt.kind
|
||||
&& !Self::is_expr_delims_necessary(expr, ctx, followed_by_block)
|
||||
&& (ctx != UnusedDelimsCtx::AnonConst
|
||||
|| (matches!(expr.kind, ast::ExprKind::Lit(_))
|
||||
&& !expr.span.from_expansion()))
|
||||
&& ctx != UnusedDelimsCtx::ClosureBody
|
||||
&& !cx.sess().source_map().is_multiline(value.span)
|
||||
&& value.attrs.is_empty()
|
||||
&& !value.span.from_expansion()
|
||||
&& !inner.span.from_expansion()
|
||||
{
|
||||
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Let(_, ref expr, _, _) => {
|
||||
|
|
|
|||
|
|
@ -370,12 +370,11 @@ impl<'a> CrateLocator<'a> {
|
|||
return self.find_commandline_library(crate_rejections);
|
||||
}
|
||||
let mut seen_paths = FxHashSet::default();
|
||||
if let Some(extra_filename) = self.extra_filename {
|
||||
if let library @ Some(_) =
|
||||
if let Some(extra_filename) = self.extra_filename
|
||||
&& let library @ Some(_) =
|
||||
self.find_library_crate(crate_rejections, extra_filename, &mut seen_paths)?
|
||||
{
|
||||
return Ok(library);
|
||||
}
|
||||
{
|
||||
return Ok(library);
|
||||
}
|
||||
self.find_library_crate(crate_rejections, "", &mut seen_paths)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2141,10 +2141,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
.push((id.owner_id.def_id.local_def_index, simplified_self_ty));
|
||||
|
||||
let trait_def = tcx.trait_def(trait_ref.def_id);
|
||||
if let Ok(mut an) = trait_def.ancestors(tcx, def_id) {
|
||||
if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) {
|
||||
self.tables.impl_parent.set_some(def_id.index, parent.into());
|
||||
}
|
||||
if let Ok(mut an) = trait_def.ancestors(tcx, def_id)
|
||||
&& let Some(specialization_graph::Node::Impl(parent)) = an.nth(1)
|
||||
{
|
||||
self.tables.impl_parent.set_some(def_id.index, parent.into());
|
||||
}
|
||||
|
||||
// if this is an impl of `CoerceUnsized`, create its
|
||||
|
|
|
|||
|
|
@ -175,23 +175,22 @@ impl Scope {
|
|||
return DUMMY_SP;
|
||||
};
|
||||
let span = tcx.hir_span(hir_id);
|
||||
if let ScopeData::Remainder(first_statement_index) = self.data {
|
||||
if let Node::Block(blk) = tcx.hir_node(hir_id) {
|
||||
// Want span for scope starting after the
|
||||
// indexed statement and ending at end of
|
||||
// `blk`; reuse span of `blk` and shift `lo`
|
||||
// forward to end of indexed statement.
|
||||
//
|
||||
// (This is the special case alluded to in the
|
||||
// doc-comment for this method)
|
||||
if let ScopeData::Remainder(first_statement_index) = self.data
|
||||
// Want span for scope starting after the
|
||||
// indexed statement and ending at end of
|
||||
// `blk`; reuse span of `blk` and shift `lo`
|
||||
// forward to end of indexed statement.
|
||||
//
|
||||
// (This is the special case alluded to in the
|
||||
// doc-comment for this method)
|
||||
&& let Node::Block(blk) = tcx.hir_node(hir_id)
|
||||
{
|
||||
let stmt_span = blk.stmts[first_statement_index.index()].span;
|
||||
|
||||
let stmt_span = blk.stmts[first_statement_index.index()].span;
|
||||
|
||||
// To avoid issues with macro-generated spans, the span
|
||||
// of the statement must be nested in that of the block.
|
||||
if span.lo() <= stmt_span.lo() && stmt_span.lo() <= span.hi() {
|
||||
return span.with_lo(stmt_span.lo());
|
||||
}
|
||||
// To avoid issues with macro-generated spans, the span
|
||||
// of the statement must be nested in that of the block.
|
||||
if span.lo() <= stmt_span.lo() && stmt_span.lo() <= span.hi() {
|
||||
return span.with_lo(stmt_span.lo());
|
||||
}
|
||||
}
|
||||
span
|
||||
|
|
|
|||
|
|
@ -566,10 +566,10 @@ impl<'tcx> AdtDef<'tcx> {
|
|||
let mut prev_discr = None::<Discr<'tcx>>;
|
||||
self.variants().iter_enumerated().map(move |(i, v)| {
|
||||
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
|
||||
if let VariantDiscr::Explicit(expr_did) = v.discr {
|
||||
if let Ok(new_discr) = self.eval_explicit_discr(tcx, expr_did) {
|
||||
discr = new_discr;
|
||||
}
|
||||
if let VariantDiscr::Explicit(expr_did) = v.discr
|
||||
&& let Ok(new_discr) = self.eval_explicit_discr(tcx, expr_did)
|
||||
{
|
||||
discr = new_discr;
|
||||
}
|
||||
prev_discr = Some(discr);
|
||||
|
||||
|
|
|
|||
|
|
@ -1055,11 +1055,11 @@ where
|
|||
_ => Some(this),
|
||||
};
|
||||
|
||||
if let Some(variant) = data_variant {
|
||||
if let Some(variant) = data_variant
|
||||
// We're not interested in any unions.
|
||||
if let FieldsShape::Union(_) = variant.fields {
|
||||
data_variant = None;
|
||||
}
|
||||
&& let FieldsShape::Union(_) = variant.fields
|
||||
{
|
||||
data_variant = None;
|
||||
}
|
||||
|
||||
let mut result = None;
|
||||
|
|
|
|||
|
|
@ -225,10 +225,10 @@ impl<'tcx> RegionHighlightMode<'tcx> {
|
|||
region: Option<ty::Region<'tcx>>,
|
||||
number: Option<usize>,
|
||||
) {
|
||||
if let Some(k) = region {
|
||||
if let Some(n) = number {
|
||||
self.highlighting_region(k, n);
|
||||
}
|
||||
if let Some(k) = region
|
||||
&& let Some(n) = number
|
||||
{
|
||||
self.highlighting_region(k, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,28 +76,24 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
let mut pattern = self.pattern_from_hir(local.pat);
|
||||
debug!(?pattern);
|
||||
|
||||
if let Some(ty) = &local.ty {
|
||||
if let Some(&user_ty) =
|
||||
if let Some(ty) = &local.ty
|
||||
&& let Some(&user_ty) =
|
||||
self.typeck_results.user_provided_types().get(ty.hir_id)
|
||||
{
|
||||
debug!("mirror_stmts: user_ty={:?}", user_ty);
|
||||
let annotation = CanonicalUserTypeAnnotation {
|
||||
user_ty: Box::new(user_ty),
|
||||
span: ty.span,
|
||||
inferred_ty: self.typeck_results.node_type(ty.hir_id),
|
||||
};
|
||||
pattern = Box::new(Pat {
|
||||
ty: pattern.ty,
|
||||
span: pattern.span,
|
||||
kind: PatKind::AscribeUserType {
|
||||
ascription: Ascription {
|
||||
annotation,
|
||||
variance: ty::Covariant,
|
||||
},
|
||||
subpattern: pattern,
|
||||
},
|
||||
});
|
||||
}
|
||||
{
|
||||
debug!("mirror_stmts: user_ty={:?}", user_ty);
|
||||
let annotation = CanonicalUserTypeAnnotation {
|
||||
user_ty: Box::new(user_ty),
|
||||
span: ty.span,
|
||||
inferred_ty: self.typeck_results.node_type(ty.hir_id),
|
||||
};
|
||||
pattern = Box::new(Pat {
|
||||
ty: pattern.ty,
|
||||
span: pattern.span,
|
||||
kind: PatKind::AscribeUserType {
|
||||
ascription: Ascription { annotation, variance: ty::Covariant },
|
||||
subpattern: pattern,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let span = match local.init {
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
// // ^ error message points at this expression.
|
||||
// }
|
||||
let mut adjust_span = |expr: &mut Expr<'tcx>| {
|
||||
if let ExprKind::Block { block } = expr.kind {
|
||||
if let Some(last_expr) = self.thir[block].expr {
|
||||
span = self.thir[last_expr].span;
|
||||
expr.span = span;
|
||||
}
|
||||
if let ExprKind::Block { block } = expr.kind
|
||||
&& let Some(last_expr) = self.thir[block].expr
|
||||
{
|
||||
span = self.thir[last_expr].span;
|
||||
expr.span = span;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -956,10 +956,10 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
|||
};
|
||||
|
||||
fn local(expr: &rustc_hir::Expr<'_>) -> Option<hir::HirId> {
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind {
|
||||
if let Res::Local(hir_id) = path.res {
|
||||
return Some(hir_id);
|
||||
}
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
|
||||
&& let Res::Local(hir_id) = path.res
|
||||
{
|
||||
return Some(hir_id);
|
||||
}
|
||||
|
||||
None
|
||||
|
|
|
|||
|
|
@ -1155,14 +1155,12 @@ fn find_fallback_pattern_typo<'tcx>(
|
|||
}
|
||||
hir::Node::Block(hir::Block { stmts, .. }) => {
|
||||
for stmt in *stmts {
|
||||
if let hir::StmtKind::Let(let_stmt) = stmt.kind {
|
||||
if let hir::PatKind::Binding(_, _, binding_name, _) =
|
||||
if let hir::StmtKind::Let(let_stmt) = stmt.kind
|
||||
&& let hir::PatKind::Binding(_, _, binding_name, _) =
|
||||
let_stmt.pat.kind
|
||||
{
|
||||
if name == binding_name.name {
|
||||
lint.pattern_let_binding = Some(binding_name.span);
|
||||
}
|
||||
}
|
||||
&& name == binding_name.name
|
||||
{
|
||||
lint.pattern_let_binding = Some(binding_name.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,10 +124,9 @@ pub fn drop_flag_effects_for_location<'tcx, F>(
|
|||
// Drop does not count as a move but we should still consider the variable uninitialized.
|
||||
if let Some(Terminator { kind: TerminatorKind::Drop { place, .. }, .. }) =
|
||||
body.stmt_at(loc).right()
|
||||
&& let LookupResult::Exact(mpi) = move_data.rev_lookup.find(place.as_ref())
|
||||
{
|
||||
if let LookupResult::Exact(mpi) = move_data.rev_lookup.find(place.as_ref()) {
|
||||
on_all_children_bits(move_data, mpi, |mpi| callback(mpi, DropFlagState::Absent))
|
||||
}
|
||||
on_all_children_bits(move_data, mpi, |mpi| callback(mpi, DropFlagState::Absent))
|
||||
}
|
||||
|
||||
debug!("drop_flag_effects: assignment for location({:?})", loc);
|
||||
|
|
|
|||
|
|
@ -637,16 +637,13 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
|||
debug!("initializes move_indexes {:?}", init_loc_map[location]);
|
||||
state.gen_all(init_loc_map[location].iter().copied());
|
||||
|
||||
if let mir::StatementKind::StorageDead(local) = stmt.kind {
|
||||
if let mir::StatementKind::StorageDead(local) = stmt.kind
|
||||
// End inits for StorageDead, so that an immutable variable can
|
||||
// be reinitialized on the next iteration of the loop.
|
||||
if let Some(move_path_index) = rev_lookup.find_local(local) {
|
||||
debug!(
|
||||
"clears the ever initialized status of {:?}",
|
||||
init_path_map[move_path_index]
|
||||
);
|
||||
state.kill_all(init_path_map[move_path_index].iter().copied());
|
||||
}
|
||||
&& let Some(move_path_index) = rev_lookup.find_local(local)
|
||||
{
|
||||
debug!("clears the ever initialized status of {:?}", init_path_map[move_path_index]);
|
||||
state.kill_all(init_path_map[move_path_index].iter().copied());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,12 +135,11 @@ fn value_assigned_to_local<'a, 'tcx>(
|
|||
stmt: &'a mir::Statement<'tcx>,
|
||||
local: Local,
|
||||
) -> Option<&'a mir::Rvalue<'tcx>> {
|
||||
if let mir::StatementKind::Assign(box (place, rvalue)) = &stmt.kind {
|
||||
if let Some(l) = place.as_local() {
|
||||
if local == l {
|
||||
return Some(&*rvalue);
|
||||
}
|
||||
}
|
||||
if let mir::StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
||||
&& let Some(l) = place.as_local()
|
||||
&& local == l
|
||||
{
|
||||
return Some(&*rvalue);
|
||||
}
|
||||
|
||||
None
|
||||
|
|
@ -178,31 +177,30 @@ impl PeekCall {
|
|||
let span = terminator.source_info.span;
|
||||
if let mir::TerminatorKind::Call { func: Operand::Constant(func), args, .. } =
|
||||
&terminator.kind
|
||||
&& let ty::FnDef(def_id, fn_args) = *func.const_.ty().kind()
|
||||
{
|
||||
if let ty::FnDef(def_id, fn_args) = *func.const_.ty().kind() {
|
||||
if tcx.intrinsic(def_id)?.name != sym::rustc_peek {
|
||||
return None;
|
||||
}
|
||||
if tcx.intrinsic(def_id)?.name != sym::rustc_peek {
|
||||
return None;
|
||||
}
|
||||
|
||||
assert_eq!(fn_args.len(), 1);
|
||||
let kind = PeekCallKind::from_arg_ty(fn_args.type_at(0));
|
||||
let arg = match &args[0].node {
|
||||
Operand::Copy(place) | Operand::Move(place) => {
|
||||
if let Some(local) = place.as_local() {
|
||||
local
|
||||
} else {
|
||||
tcx.dcx().emit_err(PeekMustBeNotTemporary { span });
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(fn_args.len(), 1);
|
||||
let kind = PeekCallKind::from_arg_ty(fn_args.type_at(0));
|
||||
let arg = match &args[0].node {
|
||||
Operand::Copy(place) | Operand::Move(place) => {
|
||||
if let Some(local) = place.as_local() {
|
||||
local
|
||||
} else {
|
||||
tcx.dcx().emit_err(PeekMustBeNotTemporary { span });
|
||||
return None;
|
||||
}
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
tcx.dcx().emit_err(PeekMustBeNotTemporary { span });
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
return Some(PeekCall { arg, kind, span });
|
||||
}
|
||||
return Some(PeekCall { arg, kind, span });
|
||||
}
|
||||
|
||||
None
|
||||
|
|
|
|||
|
|
@ -215,10 +215,10 @@ impl<V: Clone + HasBottom> State<V> {
|
|||
// If both places are tracked, we copy the value to the target.
|
||||
// If the target is tracked, but the source is not, we do nothing, as invalidation has
|
||||
// already been performed.
|
||||
if let Some(target_value) = map.places[target].value_index {
|
||||
if let Some(source_value) = map.places[source].value_index {
|
||||
values.insert(target_value, values.get(source_value).clone());
|
||||
}
|
||||
if let Some(target_value) = map.places[target].value_index
|
||||
&& let Some(source_value) = map.places[source].value_index
|
||||
{
|
||||
values.insert(target_value, values.get(source_value).clone());
|
||||
}
|
||||
for target_child in map.children(target) {
|
||||
// Try to find corresponding child and recurse. Reasoning is similar as above.
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ impl<'tcx> MutVisitor<'tcx> for FixReturnPendingVisitor<'tcx> {
|
|||
}
|
||||
|
||||
// Converting `_0 = Poll::<Rv>::Pending` to `_0 = Poll::<()>::Pending`
|
||||
if let Rvalue::Aggregate(kind, _) = rvalue {
|
||||
if let AggregateKind::Adt(_, _, ref mut args, _, _) = **kind {
|
||||
*args = self.tcx.mk_args(&[self.tcx.types.unit.into()]);
|
||||
}
|
||||
if let Rvalue::Aggregate(kind, _) = rvalue
|
||||
&& let AggregateKind::Adt(_, _, ref mut args, _, _) = **kind
|
||||
{
|
||||
*args = self.tcx.mk_args(&[self.tcx.types.unit.into()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue