Merge commit '7248d06384' into sync-from-clippy

This commit is contained in:
David Koloski 2022-09-21 13:02:37 -04:00
parent 0dc24ca376
commit 4d015293d1
111 changed files with 2040 additions and 1674 deletions

View file

@ -501,8 +501,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
BinOpKind::Mul => l.checked_mul(r).map(zext),
BinOpKind::Div if r != 0 => l.checked_div(r).map(zext),
BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext),
BinOpKind::Shr => l.checked_shr(r.try_into().expect("invalid shift")).map(zext),
BinOpKind::Shl => l.checked_shl(r.try_into().expect("invalid shift")).map(zext),
BinOpKind::Shr => l.checked_shr(r.try_into().ok()?).map(zext),
BinOpKind::Shl => l.checked_shl(r.try_into().ok()?).map(zext),
BinOpKind::BitXor => Some(zext(l ^ r)),
BinOpKind::BitOr => Some(zext(l | r)),
BinOpKind::BitAnd => Some(zext(l & r)),
@ -521,8 +521,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
BinOpKind::Mul => l.checked_mul(r).map(Constant::Int),
BinOpKind::Div => l.checked_div(r).map(Constant::Int),
BinOpKind::Rem => l.checked_rem(r).map(Constant::Int),
BinOpKind::Shr => l.checked_shr(r.try_into().expect("shift too large")).map(Constant::Int),
BinOpKind::Shl => l.checked_shl(r.try_into().expect("shift too large")).map(Constant::Int),
BinOpKind::Shr => l.checked_shr(r.try_into().ok()?).map(Constant::Int),
BinOpKind::Shl => l.checked_shl(r.try_into().ok()?).map(Constant::Int),
BinOpKind::BitXor => Some(Constant::Int(l ^ r)),
BinOpKind::BitOr => Some(Constant::Int(l | r)),
BinOpKind::BitAnd => Some(Constant::Int(l & r)),

View file

@ -7,8 +7,8 @@ use crate::visitors::expr_visitor_no_bodies;
use arrayvec::ArrayVec;
use itertools::{izip, Either, Itertools};
use rustc_ast::ast::LitKind;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{self as hir, Expr, ExprField, ExprKind, HirId, Node, QPath};
use rustc_lexer::unescape::unescape_literal;
use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
use rustc_lint::LateContext;
@ -485,64 +485,49 @@ struct ParamPosition {
precision: Option<usize>,
}
/// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
fn parse_rt_fmt<'tcx>(fmt_arg: &'tcx Expr<'tcx>) -> Option<impl Iterator<Item = ParamPosition> + 'tcx> {
fn parse_count(expr: &Expr<'_>) -> Option<usize> {
// ::core::fmt::rt::v1::Count::Param(1usize),
if let ExprKind::Call(ctor, [val]) = expr.kind
&& let ExprKind::Path(QPath::Resolved(_, path)) = ctor.kind
&& path.segments.last()?.ident.name == sym::Param
&& let ExprKind::Lit(lit) = &val.kind
&& let LitKind::Int(pos, _) = lit.node
{
Some(pos as usize)
} else {
None
impl<'tcx> Visitor<'tcx> for ParamPosition {
fn visit_expr_field(&mut self, field: &'tcx ExprField<'tcx>) {
fn parse_count(expr: &Expr<'_>) -> Option<usize> {
// ::core::fmt::rt::v1::Count::Param(1usize),
if let ExprKind::Call(ctor, [val]) = expr.kind
&& let ExprKind::Path(QPath::Resolved(_, path)) = ctor.kind
&& path.segments.last()?.ident.name == sym::Param
&& let ExprKind::Lit(lit) = &val.kind
&& let LitKind::Int(pos, _) = lit.node
{
Some(pos as usize)
} else {
None
}
}
match field.ident.name {
sym::position => {
if let ExprKind::Lit(lit) = &field.expr.kind
&& let LitKind::Int(pos, _) = lit.node
{
self.value = pos as usize;
}
},
sym::precision => {
self.precision = parse_count(field.expr);
},
sym::width => {
self.width = parse_count(field.expr);
},
_ => walk_expr(self, field.expr),
}
}
}
/// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
fn parse_rt_fmt<'tcx>(fmt_arg: &'tcx Expr<'tcx>) -> Option<impl Iterator<Item = ParamPosition> + 'tcx> {
if let ExprKind::AddrOf(.., array) = fmt_arg.kind
&& let ExprKind::Array(specs) = array.kind
{
Some(specs.iter().map(|spec| {
let mut position = ParamPosition::default();
// ::core::fmt::rt::v1::Argument {
// position: 0usize,
// format: ::core::fmt::rt::v1::FormatSpec {
// ..
// precision: ::core::fmt::rt::v1::Count::Implied,
// width: ::core::fmt::rt::v1::Count::Implied,
// },
// }
// TODO: this can be made much nicer next sync with `Visitor::visit_expr_field`
if let ExprKind::Struct(_, fields, _) = spec.kind {
for field in fields {
match (field.ident.name, &field.expr.kind) {
(sym::position, ExprKind::Lit(lit)) => {
if let LitKind::Int(pos, _) = lit.node {
position.value = pos as usize;
}
},
(sym::format, &ExprKind::Struct(_, spec_fields, _)) => {
for spec_field in spec_fields {
match spec_field.ident.name {
sym::precision => {
position.precision = parse_count(spec_field.expr);
},
sym::width => {
position.width = parse_count(spec_field.expr);
},
_ => {},
}
}
},
_ => {},
}
}
}
position.visit_expr(spec);
position
}))
} else {
@ -711,9 +696,14 @@ impl<'tcx> FormatSpec<'tcx> {
})
}
/// Returns true if this format spec would change the contents of a string when formatted
pub fn has_string_formatting(&self) -> bool {
self.r#trait != sym::Display || !self.width.is_implied() || !self.precision.is_implied()
/// Returns true if this format spec is unchanged from the default. e.g. returns true for `{}`,
/// `{foo}` and `{2}`, but false for `{:?}`, `{foo:5}` and `{3:.5}`
pub fn is_default(&self) -> bool {
self.r#trait == sym::Display
&& self.width.is_implied()
&& self.precision.is_implied()
&& self.align == Alignment::AlignUnknown
&& self.flags == 0
}
}

View file

@ -22,7 +22,7 @@ use std::fmt::{Display, Write as _};
use std::ops::{Add, Neg, Not, Sub};
/// A helper type to build suggestion correctly handling parentheses.
#[derive(Clone, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
pub enum Sugg<'a> {
/// An expression that never needs parentheses such as `1337` or `[0; 42]`.
NonParen(Cow<'a, str>),
@ -155,8 +155,8 @@ impl<'a> Sugg<'a> {
| hir::ExprKind::Ret(..)
| hir::ExprKind::Struct(..)
| hir::ExprKind::Tup(..)
| hir::ExprKind::DropTemps(_)
| hir::ExprKind::Err => Sugg::NonParen(get_snippet(expr.span)),
hir::ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
hir::ExprKind::Assign(lhs, rhs, _) => {
Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))
},
@ -177,11 +177,11 @@ impl<'a> Sugg<'a> {
pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
use rustc_ast::ast::RangeLimits;
let get_whole_snippet = || {
if expr.span.from_expansion() {
snippet_with_macro_callsite(cx, expr.span, default)
let snippet_without_expansion = |cx, span: Span, default| {
if span.from_expansion() {
snippet_with_macro_callsite(cx, span, default)
} else {
snippet(cx, expr.span, default)
snippet(cx, span, default)
}
};
@ -192,7 +192,7 @@ impl<'a> Sugg<'a> {
| ast::ExprKind::If(..)
| ast::ExprKind::Let(..)
| ast::ExprKind::Unary(..)
| ast::ExprKind::Match(..) => Sugg::MaybeParen(get_whole_snippet()),
| ast::ExprKind::Match(..) => Sugg::MaybeParen(snippet_without_expansion(cx, expr.span, default)),
ast::ExprKind::Async(..)
| ast::ExprKind::Block(..)
| ast::ExprKind::Break(..)
@ -221,41 +221,45 @@ impl<'a> Sugg<'a> {
| ast::ExprKind::Array(..)
| ast::ExprKind::While(..)
| ast::ExprKind::Await(..)
| ast::ExprKind::Err => Sugg::NonParen(get_whole_snippet()),
| ast::ExprKind::Err => Sugg::NonParen(snippet_without_expansion(cx, expr.span, default)),
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
AssocOp::DotDot,
lhs.as_ref().map_or("".into(), |lhs| snippet(cx, lhs.span, default)),
rhs.as_ref().map_or("".into(), |rhs| snippet(cx, rhs.span, default)),
lhs.as_ref()
.map_or("".into(), |lhs| snippet_without_expansion(cx, lhs.span, default)),
rhs.as_ref()
.map_or("".into(), |rhs| snippet_without_expansion(cx, rhs.span, default)),
),
ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::Closed) => Sugg::BinOp(
AssocOp::DotDotEq,
lhs.as_ref().map_or("".into(), |lhs| snippet(cx, lhs.span, default)),
rhs.as_ref().map_or("".into(), |rhs| snippet(cx, rhs.span, default)),
lhs.as_ref()
.map_or("".into(), |lhs| snippet_without_expansion(cx, lhs.span, default)),
rhs.as_ref()
.map_or("".into(), |rhs| snippet_without_expansion(cx, rhs.span, default)),
),
ast::ExprKind::Assign(ref lhs, ref rhs, _) => Sugg::BinOp(
AssocOp::Assign,
snippet(cx, lhs.span, default),
snippet(cx, rhs.span, default),
snippet_without_expansion(cx, lhs.span, default),
snippet_without_expansion(cx, rhs.span, default),
),
ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => Sugg::BinOp(
astbinop2assignop(op),
snippet(cx, lhs.span, default),
snippet(cx, rhs.span, default),
snippet_without_expansion(cx, lhs.span, default),
snippet_without_expansion(cx, rhs.span, default),
),
ast::ExprKind::Binary(op, ref lhs, ref rhs) => Sugg::BinOp(
AssocOp::from_ast_binop(op.node),
snippet(cx, lhs.span, default),
snippet(cx, rhs.span, default),
snippet_without_expansion(cx, lhs.span, default),
snippet_without_expansion(cx, rhs.span, default),
),
ast::ExprKind::Cast(ref lhs, ref ty) => Sugg::BinOp(
AssocOp::As,
snippet(cx, lhs.span, default),
snippet(cx, ty.span, default),
snippet_without_expansion(cx, lhs.span, default),
snippet_without_expansion(cx, ty.span, default),
),
ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp(
AssocOp::Colon,
snippet(cx, lhs.span, default),
snippet(cx, ty.span, default),
snippet_without_expansion(cx, lhs.span, default),
snippet_without_expansion(cx, ty.span, default),
),
}
}

View file

@ -31,6 +31,13 @@ pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty.is_copy_modulo_regions(cx.tcx.at(DUMMY_SP), cx.param_env)
}
/// This checks whether a given type is known to implement Debug.
pub fn has_debug_impl<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
cx.tcx
.get_diagnostic_item(sym::Debug)
.map_or(false, |debug| implements_trait(cx, ty, debug, &[]))
}
/// Checks whether a type can be partially moved.
pub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
if has_drop(cx, ty) || is_copy(cx, ty) {