1
Fork 0

Auto merge of #77124 - spastorino:const-exprs-rfc-2920, r=oli-obk

Implement const expressions and patterns (RFC 2920)

cc `@ecstatic-morse` `@lcnr` `@oli-obk` `@petrochenkov`
This commit is contained in:
bors 2020-10-17 14:44:51 +00:00
commit 6af9846fcc
48 changed files with 301 additions and 36 deletions

View file

@ -195,6 +195,11 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
run_early_pass!(self, check_expr_post, e);
}
fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
run_early_pass!(self, check_generic_arg, arg);
ast_visit::walk_generic_arg(self, arg);
}
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
run_early_pass!(self, check_generic_param, param);
ast_visit::walk_generic_param(self, param);

View file

@ -33,6 +33,7 @@ macro_rules! late_lint_methods {
fn check_expr(a: &$hir hir::Expr<$hir>);
fn check_expr_post(a: &$hir hir::Expr<$hir>);
fn check_ty(a: &$hir hir::Ty<$hir>);
fn check_generic_arg(a: &$hir hir::GenericArg<$hir>);
fn check_generic_param(a: &$hir hir::GenericParam<$hir>);
fn check_generics(a: &$hir hir::Generics<$hir>);
fn check_where_predicate(a: &$hir hir::WherePredicate<$hir>);
@ -176,6 +177,7 @@ macro_rules! early_lint_methods {
fn check_expr(a: &ast::Expr);
fn check_expr_post(a: &ast::Expr);
fn check_ty(a: &ast::Ty);
fn check_generic_arg(a: &ast::GenericArg);
fn check_generic_param(a: &ast::GenericParam);
fn check_generics(a: &ast::Generics);
fn check_where_predicate(a: &ast::WherePredicate);

View file

@ -839,10 +839,6 @@ impl EarlyLintPass for UnusedParens {
}
}
fn check_anon_const(&mut self, cx: &EarlyContext<'_>, c: &ast::AnonConst) {
self.check_unused_delims_expr(cx, &c.value, UnusedDelimsCtx::AnonConst, false, None, None);
}
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
if let StmtKind::Local(ref local) = s.kind {
self.check_unused_parens_pat(cx, &local.pat, false, false);
@ -965,13 +961,6 @@ impl UnusedDelimLint for UnusedBraces {
if !Self::is_expr_delims_necessary(expr, followed_by_block)
&& (ctx != UnusedDelimsCtx::AnonConst
|| matches!(expr.kind, ast::ExprKind::Lit(_)))
// array length expressions are checked during `check_anon_const` and `check_ty`,
// once as `ArrayLenExpr` and once as `AnonConst`.
//
// As we do not want to lint this twice, we do not emit an error for
// `ArrayLenExpr` if `AnonConst` would do the same.
&& (ctx != UnusedDelimsCtx::ArrayLenExpr
|| !matches!(expr.kind, ast::ExprKind::Lit(_)))
&& !cx.sess().source_map().is_multiline(value.span)
&& value.attrs.is_empty()
&& !value.span.from_expansion()
@ -999,21 +988,54 @@ impl UnusedDelimLint for UnusedBraces {
}
impl EarlyLintPass for UnusedBraces {
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
<Self as UnusedDelimLint>::check_expr(self, cx, e)
}
fn check_anon_const(&mut self, cx: &EarlyContext<'_>, c: &ast::AnonConst) {
self.check_unused_delims_expr(cx, &c.value, UnusedDelimsCtx::AnonConst, false, None, None);
}
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
<Self as UnusedDelimLint>::check_stmt(self, cx, s)
}
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
<Self as UnusedDelimLint>::check_expr(self, cx, e);
if let ExprKind::Repeat(_, ref anon_const) = e.kind {
self.check_unused_delims_expr(
cx,
&anon_const.value,
UnusedDelimsCtx::AnonConst,
false,
None,
None,
);
}
}
fn check_generic_arg(&mut self, cx: &EarlyContext<'_>, arg: &ast::GenericArg) {
if let ast::GenericArg::Const(ct) = arg {
self.check_unused_delims_expr(
cx,
&ct.value,
UnusedDelimsCtx::AnonConst,
false,
None,
None,
);
}
}
fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &ast::Variant) {
if let Some(anon_const) = &v.disr_expr {
self.check_unused_delims_expr(
cx,
&anon_const.value,
UnusedDelimsCtx::AnonConst,
false,
None,
None,
);
}
}
fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
if let &ast::TyKind::Paren(ref r) = &ty.kind {
if let ast::TyKind::Array(_, ref len) = r.kind {
match ty.kind {
ast::TyKind::Array(_, ref len) => {
self.check_unused_delims_expr(
cx,
&len.value,
@ -1023,6 +1045,19 @@ impl EarlyLintPass for UnusedBraces {
None,
);
}
ast::TyKind::Typeof(ref anon_const) => {
self.check_unused_delims_expr(
cx,
&anon_const.value,
UnusedDelimsCtx::AnonConst,
false,
None,
None,
);
}
_ => {}
}
}