X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_lint%2Fsrc%2Funused.rs;h=4c9b3df2dbd33d706d04c3cc5e911ceeb9c70a2c;hb=1d3f5b49d6bdfb2a051ddbfb7ad4b4ad603e9908;hp=f2ee9ab1a19873cfac16b3e6f2c29c253a5267a5;hpb=884333545122b8a640a4c6644581f4cd56164d9e;p=rust.git diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index f2ee9ab1a19..4c9b3df2dbd 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -824,7 +824,17 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { "`if`, `match`, `while` and `return` do not need parentheses" } -declare_lint_pass!(UnusedParens => [UNUSED_PARENS]); +pub struct UnusedParens { + with_self_ty_parens: bool, +} + +impl UnusedParens { + pub fn new() -> Self { + Self { with_self_ty_parens: false } + } +} + +impl_lint_pass!(UnusedParens => [UNUSED_PARENS]); impl UnusedDelimLint for UnusedParens { const DELIM_STR: &'static str = "parentheses"; @@ -999,36 +1009,58 @@ fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) { } fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) { - if let ast::TyKind::Paren(r) = &ty.kind { - match &r.kind { - ast::TyKind::TraitObject(..) => {} - ast::TyKind::BareFn(b) if b.generic_params.len() > 0 => {} - ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} - ast::TyKind::Array(_, len) => { - self.check_unused_delims_expr( - cx, - &len.value, - UnusedDelimsCtx::ArrayLenExpr, - false, - None, - None, - ); - } - _ => { - let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) { - Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))) - } else { - None - }; - self.emit_unused_delims(cx, ty.span, spans, "type", (false, false)); + match &ty.kind { + ast::TyKind::Array(_, len) => { + self.check_unused_delims_expr( + cx, + &len.value, + UnusedDelimsCtx::ArrayLenExpr, + false, + None, + None, + ); + } + ast::TyKind::Paren(r) => { + match &r.kind { + ast::TyKind::TraitObject(..) => {} + ast::TyKind::BareFn(b) + if self.with_self_ty_parens && b.generic_params.len() > 0 => {} + ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} + _ => { + let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) { + Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))) + } else { + None + }; + self.emit_unused_delims(cx, ty.span, spans, "type", (false, false)); + } } + self.with_self_ty_parens = false; } + _ => {} } } fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { ::check_item(self, cx, item) } + + fn enter_where_predicate(&mut self, _: &EarlyContext<'_>, pred: &ast::WherePredicate) { + use rustc_ast::{WhereBoundPredicate, WherePredicate}; + if let WherePredicate::BoundPredicate(WhereBoundPredicate { + bounded_ty, + bound_generic_params, + .. + }) = pred && + let ast::TyKind::Paren(_) = &bounded_ty.kind && + bound_generic_params.is_empty() { + self.with_self_ty_parens = true; + } + } + + fn exit_where_predicate(&mut self, _: &EarlyContext<'_>, _: &ast::WherePredicate) { + assert!(!self.with_self_ty_parens); + } } declare_lint! { @@ -1095,17 +1127,21 @@ fn check_unused_delims_expr( // ``` // - the block has no attribute and was not created inside a macro // - if the block is an `anon_const`, the inner expr must be a literal - // (do not lint `struct A; let _: A<{ 2 + 3 }>;`) - // + // not created by a macro, i.e. do not lint on: + // ``` + // struct A; + // let _: A<{ 2 + 3 }>; + // 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, followed_by_block, false) && (ctx != UnusedDelimsCtx::AnonConst - || matches!(expr.kind, ast::ExprKind::Lit(_))) + || (matches!(expr.kind, ast::ExprKind::Lit(_)) + && !expr.span.from_expansion())) && !cx.sess().source_map().is_multiline(value.span) && value.attrs.is_empty() - && !expr.span.from_expansion() && !value.span.from_expansion() && !inner.span.from_expansion() {