mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-26 13:54:06 +00:00
Merge remote-tracking branch 'origin/master' into relicense-rewrite
This commit is contained in:
commit
1544a1a681
@ -57,11 +57,9 @@ script:
|
|||||||
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib
|
export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib
|
||||||
- |
|
- |
|
||||||
if [ -z ${INTEGRATION} ]; then
|
if [ -z ${INTEGRATION} ]; then
|
||||||
./ci/base-tests.sh
|
./ci/base-tests.sh && sleep 5
|
||||||
sleep 5
|
|
||||||
else
|
else
|
||||||
./ci/integration-tests.sh
|
./ci/integration-tests.sh && sleep 5
|
||||||
sleep 5
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
after_success: |
|
after_success: |
|
||||||
|
@ -4,7 +4,6 @@ use crate::rustc::{declare_tool_lint, lint_array};
|
|||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use crate::rustc::ty;
|
use crate::rustc::ty;
|
||||||
use crate::syntax::ast::LitKind;
|
use crate::syntax::ast::LitKind;
|
||||||
use crate::syntax_pos::Span;
|
|
||||||
use crate::utils::paths;
|
use crate::utils::paths;
|
||||||
use crate::utils::{in_macro, is_expn_of, last_path_segment, match_def_path, match_type, opt_def_id, resolve_node, snippet, span_lint_and_then, walk_ptrs_ty};
|
use crate::utils::{in_macro, is_expn_of, last_path_segment, match_def_path, match_type, opt_def_id, resolve_node, snippet, span_lint_and_then, walk_ptrs_ty};
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
@ -47,7 +46,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match expr.node {
|
match expr.node {
|
||||||
|
|
||||||
// `format!("{}", foo)` expansion
|
// `format!("{}", foo)` expansion
|
||||||
ExprKind::Call(ref fun, ref args) => {
|
ExprKind::Call(ref fun, ref args) => {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
@ -58,12 +56,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
if check_single_piece(&args[0]);
|
if check_single_piece(&args[0]);
|
||||||
if let Some(format_arg) = get_single_string_arg(cx, &args[1]);
|
if let Some(format_arg) = get_single_string_arg(cx, &args[1]);
|
||||||
if check_unformatted(&args[2]);
|
if check_unformatted(&args[2]);
|
||||||
|
if let ExprKind::AddrOf(_, ref format_arg) = format_arg.node;
|
||||||
then {
|
then {
|
||||||
let sugg = format!("{}.to_string()", snippet(cx, format_arg, "<arg>").into_owned());
|
let (message, sugg) = if_chain! {
|
||||||
|
if let ExprKind::MethodCall(ref path, _, _) = format_arg.node;
|
||||||
|
if path.ident.as_interned_str() == "to_string";
|
||||||
|
then {
|
||||||
|
("`to_string()` is enough",
|
||||||
|
snippet(cx, format_arg.span, "<arg>").to_string())
|
||||||
|
} else {
|
||||||
|
("consider using .to_string()",
|
||||||
|
format!("{}.to_string()", snippet(cx, format_arg.span, "<arg>")))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| {
|
span_lint_and_then(cx, USELESS_FORMAT, span, "useless use of `format!`", |db| {
|
||||||
db.span_suggestion_with_applicability(
|
db.span_suggestion_with_applicability(
|
||||||
expr.span,
|
expr.span,
|
||||||
"consider using .to_string()",
|
message,
|
||||||
sugg,
|
sugg,
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
@ -114,9 +124,9 @@ fn check_single_piece(expr: &Expr) -> bool {
|
|||||||
/// ::std::fmt::Display::fmt)],
|
/// ::std::fmt::Display::fmt)],
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// and that type of `__arg0` is `&str` or `String`
|
/// and that the type of `__arg0` is `&str` or `String`,
|
||||||
/// then returns the span of first element of the matched tuple
|
/// then returns the span of first element of the matched tuple.
|
||||||
fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span> {
|
fn get_single_string_arg<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr) -> Option<&'a Expr> {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if let ExprKind::AddrOf(_, ref expr) = expr.node;
|
if let ExprKind::AddrOf(_, ref expr) = expr.node;
|
||||||
if let ExprKind::Match(ref match_expr, ref arms, _) = expr.node;
|
if let ExprKind::Match(ref match_expr, ref arms, _) = expr.node;
|
||||||
@ -135,7 +145,7 @@ fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span>
|
|||||||
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
||||||
if ty.sty == ty::Str || match_type(cx, ty, &paths::STRING) {
|
if ty.sty == ty::Str || match_type(cx, ty, &paths::STRING) {
|
||||||
if let ExprKind::Tup(ref values) = match_expr.node {
|
if let ExprKind::Tup(ref values) = match_expr.node {
|
||||||
return Some(values[0].span);
|
return Some(&values[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,9 +172,12 @@ fn check_unformatted(expr: &Expr) -> bool {
|
|||||||
if let ExprKind::Struct(_, ref fields, _) = exprs[0].node;
|
if let ExprKind::Struct(_, ref fields, _) = exprs[0].node;
|
||||||
if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format");
|
if let Some(format_field) = fields.iter().find(|f| f.ident.name == "format");
|
||||||
if let ExprKind::Struct(_, ref fields, _) = format_field.expr.node;
|
if let ExprKind::Struct(_, ref fields, _) = format_field.expr.node;
|
||||||
if let Some(align_field) = fields.iter().find(|f| f.ident.name == "width");
|
if let Some(width_field) = fields.iter().find(|f| f.ident.name == "width");
|
||||||
if let ExprKind::Path(ref qpath) = align_field.expr.node;
|
if let ExprKind::Path(ref width_qpath) = width_field.expr.node;
|
||||||
if last_path_segment(qpath).ident.name == "Implied";
|
if last_path_segment(width_qpath).ident.name == "Implied";
|
||||||
|
if let Some(precision_field) = fields.iter().find(|f| f.ident.name == "precision");
|
||||||
|
if let ExprKind::Path(ref precision_path) = precision_field.expr.node;
|
||||||
|
if last_path_segment(precision_path).ident.name == "Implied";
|
||||||
then {
|
then {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -882,12 +882,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
let ty = cx.tcx.type_of(def_id);
|
let ty = cx.tcx.type_of(def_id);
|
||||||
let is_copy = is_copy(cx, ty);
|
let is_copy = is_copy(cx, ty);
|
||||||
for &(ref conv, self_kinds) in &CONVENTIONS {
|
for &(ref conv, self_kinds) in &CONVENTIONS {
|
||||||
if_chain! {
|
if conv.check(&name.as_str()) {
|
||||||
if conv.check(&name.as_str());
|
|
||||||
if !self_kinds
|
if !self_kinds
|
||||||
.iter()
|
.iter()
|
||||||
.any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
|
.any(|k| k.matches(cx, first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics)) {
|
||||||
then {
|
|
||||||
let lint = if item.vis.node.is_pub() {
|
let lint = if item.vis.node.is_pub() {
|
||||||
WRONG_PUB_SELF_CONVENTION
|
WRONG_PUB_SELF_CONVENTION
|
||||||
} else {
|
} else {
|
||||||
@ -904,6 +902,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(" or ")));
|
.join(" or ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only check the first convention to match (CONVENTIONS should be listed from most to least specific)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1183,8 +1184,8 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
|
|||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
db.span_suggestion_with_applicability(
|
db.span_suggestion_with_applicability(
|
||||||
expr.span,
|
expr.span,
|
||||||
"or try being explicit about what type to clone",
|
"or try being explicit about what type to clone",
|
||||||
explicit,
|
explicit,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
@ -2067,12 +2068,13 @@ enum Convention {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const CONVENTIONS: [(Convention, &[SelfKind]); 6] = [
|
const CONVENTIONS: [(Convention, &[SelfKind]); 7] = [
|
||||||
(Convention::Eq("new"), &[SelfKind::No]),
|
(Convention::Eq("new"), &[SelfKind::No]),
|
||||||
(Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]),
|
(Convention::StartsWith("as_"), &[SelfKind::Ref, SelfKind::RefMut]),
|
||||||
(Convention::StartsWith("from_"), &[SelfKind::No]),
|
(Convention::StartsWith("from_"), &[SelfKind::No]),
|
||||||
(Convention::StartsWith("into_"), &[SelfKind::Value]),
|
(Convention::StartsWith("into_"), &[SelfKind::Value]),
|
||||||
(Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]),
|
(Convention::StartsWith("is_"), &[SelfKind::Ref, SelfKind::No]),
|
||||||
|
(Convention::Eq("to_mut"), &[SelfKind::RefMut]),
|
||||||
(Convention::StartsWith("to_"), &[SelfKind::Ref]),
|
(Convention::StartsWith("to_"), &[SelfKind::Ref]),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ pub fn in_macro(span: Span) -> bool {
|
|||||||
pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool {
|
pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool {
|
||||||
use crate::syntax::symbol;
|
use crate::syntax::symbol;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct AbsolutePathBuffer {
|
struct AbsolutePathBuffer {
|
||||||
names: Vec<symbol::LocalInternedString>,
|
names: Vec<symbol::LocalInternedString>,
|
||||||
}
|
}
|
||||||
@ -89,7 +90,7 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) ->
|
|||||||
|
|
||||||
let mut apb = AbsolutePathBuffer { names: vec![] };
|
let mut apb = AbsolutePathBuffer { names: vec![] };
|
||||||
|
|
||||||
tcx.push_item_path(&mut apb, def_id);
|
tcx.push_item_path(&mut apb, def_id, false);
|
||||||
|
|
||||||
apb.names.len() == path.len()
|
apb.names.len() == path.len()
|
||||||
&& apb.names
|
&& apb.names
|
||||||
|
@ -21,6 +21,7 @@ fn show_version() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
rustc_driver::init_rustc_env_logger();
|
||||||
exit(rustc_driver::run(move || {
|
exit(rustc_driver::run(move || {
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ fn main() {
|
|||||||
format!("{}", "foo");
|
format!("{}", "foo");
|
||||||
format!("{:?}", "foo"); // don't warn about debug
|
format!("{:?}", "foo"); // don't warn about debug
|
||||||
format!("{:8}", "foo");
|
format!("{:8}", "foo");
|
||||||
|
format!("{:width$}", "foo", width = 8);
|
||||||
format!("{:+}", "foo"); // warn when the format makes no difference
|
format!("{:+}", "foo"); // warn when the format makes no difference
|
||||||
format!("{:<}", "foo"); // warn when the format makes no difference
|
format!("{:<}", "foo"); // warn when the format makes no difference
|
||||||
format!("foo {}", "bar");
|
format!("foo {}", "bar");
|
||||||
@ -23,6 +24,7 @@ fn main() {
|
|||||||
format!("{}", arg);
|
format!("{}", arg);
|
||||||
format!("{:?}", arg); // don't warn about debug
|
format!("{:?}", arg); // don't warn about debug
|
||||||
format!("{:8}", arg);
|
format!("{:8}", arg);
|
||||||
|
format!("{:width$}", arg, width = 8);
|
||||||
format!("{:+}", arg); // warn when the format makes no difference
|
format!("{:+}", arg); // warn when the format makes no difference
|
||||||
format!("{:<}", arg); // warn when the format makes no difference
|
format!("{:<}", arg); // warn when the format makes no difference
|
||||||
format!("foo {}", arg);
|
format!("foo {}", arg);
|
||||||
@ -44,4 +46,14 @@ fn main() {
|
|||||||
|
|
||||||
// A format! inside a macro should not trigger a warning
|
// A format! inside a macro should not trigger a warning
|
||||||
foo!("should not warn");
|
foo!("should not warn");
|
||||||
|
|
||||||
|
// precision on string means slicing without panicking on size:
|
||||||
|
format!("{:.1}", "foo"); // could be "foo"[..1]
|
||||||
|
format!("{:.10}", "foo"); // could not be "foo"[..10]
|
||||||
|
format!("{:.prec$}", "foo", prec = 1);
|
||||||
|
format!("{:.prec$}", "foo", prec = 10);
|
||||||
|
|
||||||
|
format!("{}", 42.to_string());
|
||||||
|
let x = std::path::PathBuf::from("/bar/foo/qux");
|
||||||
|
format!("{}", x.display().to_string());
|
||||||
}
|
}
|
||||||
|
@ -14,45 +14,61 @@ error: useless use of `format!`
|
|||||||
|
|
|
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
error: useless use of `format!`
|
|
||||||
--> $DIR/format.rs:17:5
|
|
||||||
|
|
|
||||||
17 | format!("{:+}", "foo"); // warn when the format makes no difference
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()`
|
|
||||||
|
|
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: useless use of `format!`
|
error: useless use of `format!`
|
||||||
--> $DIR/format.rs:18:5
|
--> $DIR/format.rs:18:5
|
||||||
|
|
|
|
||||||
18 | format!("{:<}", "foo"); // warn when the format makes no difference
|
18 | format!("{:+}", "foo"); // warn when the format makes no difference
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()`
|
||||||
|
|
|
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
error: useless use of `format!`
|
error: useless use of `format!`
|
||||||
--> $DIR/format.rs:23:5
|
--> $DIR/format.rs:19:5
|
||||||
|
|
|
|
||||||
23 | format!("{}", arg);
|
19 | format!("{:<}", "foo"); // warn when the format makes no difference
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `"foo".to_string()`
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: useless use of `format!`
|
||||||
|
--> $DIR/format.rs:24:5
|
||||||
|
|
|
||||||
|
24 | format!("{}", arg);
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
|
| ^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
|
||||||
|
|
|
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
error: useless use of `format!`
|
error: useless use of `format!`
|
||||||
--> $DIR/format.rs:26:5
|
--> $DIR/format.rs:28:5
|
||||||
|
|
|
|
||||||
26 | format!("{:+}", arg); // warn when the format makes no difference
|
28 | format!("{:+}", arg); // warn when the format makes no difference
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
|
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
|
||||||
|
|
|
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
error: useless use of `format!`
|
error: useless use of `format!`
|
||||||
--> $DIR/format.rs:27:5
|
--> $DIR/format.rs:29:5
|
||||||
|
|
|
|
||||||
27 | format!("{:<}", arg); // warn when the format makes no difference
|
29 | format!("{:<}", arg); // warn when the format makes no difference
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
|
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using .to_string(): `arg.to_string()`
|
||||||
|
|
|
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: useless use of `format!`
|
||||||
|
--> $DIR/format.rs:56:5
|
||||||
|
|
|
||||||
|
56 | format!("{}", 42.to_string());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `to_string()` is enough: `42.to_string()`
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: useless use of `format!`
|
||||||
|
--> $DIR/format.rs:58:5
|
||||||
|
|
|
||||||
|
58 | format!("{}", x.display().to_string());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `to_string()` is enough: `x.display().to_string()`
|
||||||
|
|
|
||||||
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
@ -59,4 +59,5 @@ impl Bar {
|
|||||||
fn is_(self) {}
|
fn is_(self) {}
|
||||||
fn to_(self) {}
|
fn to_(self) {}
|
||||||
fn from_(self) {}
|
fn from_(self) {}
|
||||||
|
fn to_mut(&mut self) {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user