Update to rustc 1.19.0-nightly (826d8f385
2017-05-13)
fixes #1759, #1758
This commit is contained in:
parent
dfc7d2afd4
commit
4d5e25f31d
@ -384,9 +384,10 @@ fn bool_expr(&self, e: &Expr) {
|
||||
NONMINIMAL_BOOL,
|
||||
e.span,
|
||||
"this boolean expression can be simplified",
|
||||
|db| for suggestion in &improvements {
|
||||
db.span_suggestion(e.span, "try", suggest(self.cx, suggestion, &h2q.terminals));
|
||||
break; // FIXME: multiple suggestions in rustc are broken
|
||||
|db| {
|
||||
db.span_suggestions(e.span, "try", improvements.into_iter().map(|suggestion| {
|
||||
suggest(self.cx, suggestion, &h2q.terminals)
|
||||
}).collect());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,8 @@ fn check_hash_peq<'a, 'tcx>(
|
||||
/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
|
||||
fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: ty::Ty<'tcx>) {
|
||||
if match_path_old(&trait_ref.path, &paths::CLONE_TRAIT) {
|
||||
if !is_copy(cx, ty, item.id) {
|
||||
let def_id = cx.tcx.hir.local_def_id(item.id);
|
||||
if !is_copy(cx, ty, def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
&msg,
|
||||
arg.span,
|
||||
&format!("argument has type {}", arg_ty.sty));
|
||||
} else if is_copy(cx, arg_ty, cx.tcx.hir.get_parent(arg.id)) {
|
||||
} else if is_copy(cx, arg_ty, cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(arg.id))) {
|
||||
if match_def_path(cx.tcx, def_id, &paths::DROP) {
|
||||
lint = DROP_COPY;
|
||||
msg = DROP_COPY_SUMMARY.to_string();
|
||||
|
@ -76,6 +76,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
BiLt | BiLe | BiGe | BiGt => (cx.tcx.lang_items.ord_trait(), true),
|
||||
};
|
||||
let parent = cx.tcx.hir.get_parent(e.id);
|
||||
let parent = cx.tcx.hir.local_def_id(parent);
|
||||
if let Some(trait_id) = trait_id {
|
||||
#[allow(match_same_arms)]
|
||||
match (&left.node, &right.node) {
|
||||
|
@ -873,7 +873,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
||||
struct VarVisitor<'a, 'tcx: 'a> {
|
||||
cx: &'a LateContext<'a, 'tcx>, // context reference
|
||||
var: DefId, // var name to look for as index
|
||||
indexed: HashMap<Name, Option<CodeExtent<'tcx>>>, // indexed variables, the extent is None for global
|
||||
indexed: HashMap<Name, Option<CodeExtent>>, // indexed variables, the extent is None for global
|
||||
nonindex: bool, // has the var been used otherwise?
|
||||
}
|
||||
|
||||
|
@ -657,8 +657,9 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
|
||||
}
|
||||
|
||||
// check conventions w.r.t. conversion method names and predicates
|
||||
let ty = cx.tcx.type_of(cx.tcx.hir.local_def_id(item.id));
|
||||
let is_copy = is_copy(cx, ty, item.id);
|
||||
let def_id = cx.tcx.hir.local_def_id(item.id);
|
||||
let ty = cx.tcx.type_of(def_id);
|
||||
let is_copy = is_copy(cx, ty, def_id);
|
||||
for &(ref conv, self_kinds) in &CONVENTIONS {
|
||||
if_let_chain! {[
|
||||
conv.check(&name.as_str()),
|
||||
@ -683,8 +684,9 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
|
||||
}
|
||||
|
||||
let ret_ty = return_ty(cx, implitem.id);
|
||||
let implitem_defid = cx.tcx.hir.local_def_id(implitem.id);
|
||||
if name == "new" &&
|
||||
!ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id)) {
|
||||
!ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem_defid)) {
|
||||
span_lint(cx,
|
||||
NEW_RET_NO_SELF,
|
||||
implitem.span,
|
||||
@ -837,7 +839,7 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
|
||||
}
|
||||
}
|
||||
|
||||
if is_copy(cx, ty, parent) {
|
||||
if is_copy(cx, ty, cx.tcx.hir.local_def_id(parent)) {
|
||||
span_lint_and_then(cx,
|
||||
CLONE_ON_COPY,
|
||||
expr.span,
|
||||
|
@ -369,11 +369,11 @@ fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
|
||||
"if you mean to use a decimal constant, remove the `0` to remove confusion:",
|
||||
src[1..].to_string(),
|
||||
);
|
||||
/*db.span_suggestion(
|
||||
db.span_suggestion(
|
||||
lit.span,
|
||||
"if you mean to use an octal constant, use `0o`:",
|
||||
format!("0o{}", &src[1..]),
|
||||
); FIXME: rustc doesn't support multiple suggestions anymore */
|
||||
);
|
||||
});
|
||||
}
|
||||
}}
|
||||
|
@ -79,15 +79,15 @@ fn check_fn(
|
||||
let asref_trait = need!(get_trait_def_id(cx, &paths::ASREF_TRAIT));
|
||||
let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT));
|
||||
|
||||
let fn_def_id = cx.tcx.hir.local_def_id(node_id);
|
||||
|
||||
let preds: Vec<ty::Predicate> = {
|
||||
let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, node_id);
|
||||
let parameter_env = cx.tcx.parameter_environment(fn_def_id);
|
||||
traits::elaborate_predicates(cx.tcx, parameter_env.caller_bounds.to_vec())
|
||||
.filter(|p| !p.is_global())
|
||||
.collect()
|
||||
};
|
||||
|
||||
let fn_def_id = cx.tcx.hir.local_def_id(node_id);
|
||||
|
||||
// Collect moved variables and spans which will need dereferencings from the function body.
|
||||
let MovedVariablesCtxt { moved_vars, spans_need_deref, .. } = {
|
||||
let mut ctx = MovedVariablesCtxt::new(cx);
|
||||
@ -100,9 +100,8 @@ fn check_fn(
|
||||
ctx
|
||||
};
|
||||
|
||||
let param_env = ty::ParameterEnvironment::for_item(cx.tcx, node_id);
|
||||
let fn_sig = cx.tcx.type_of(fn_def_id).fn_sig();
|
||||
let fn_sig = cx.tcx.liberate_late_bound_regions(param_env.free_id_outlive, &fn_sig);
|
||||
let fn_sig = cx.tcx.erase_late_bound_regions(&fn_sig);
|
||||
|
||||
for ((input, &ty), arg) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.arguments) {
|
||||
|
||||
@ -120,7 +119,7 @@ fn check_fn(
|
||||
if_let_chain! {[
|
||||
!is_self(arg),
|
||||
!ty.is_mutable_pointer(),
|
||||
!is_copy(cx, ty, node_id),
|
||||
!is_copy(cx, ty, fn_def_id),
|
||||
!implements_trait(cx, ty, fn_trait, &[], Some(node_id)),
|
||||
!implements_trait(cx, ty, asref_trait, &[], Some(node_id)),
|
||||
!implements_borrow_trait,
|
||||
|
@ -108,12 +108,13 @@ fn check_fn(
|
||||
// can't be implemented by default
|
||||
return;
|
||||
}
|
||||
let def_id = cx.tcx.hir.local_def_id(id);
|
||||
if decl.inputs.is_empty() && name == "new" && cx.access_levels.is_reachable(id) {
|
||||
let self_ty = cx.tcx
|
||||
.type_of(cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(id)));
|
||||
if_let_chain!{[
|
||||
self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics
|
||||
same_tys(cx, self_ty, return_ty(cx, id), id),
|
||||
same_tys(cx, self_ty, return_ty(cx, id), def_id),
|
||||
let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT),
|
||||
!implements_trait(cx, self_ty, default_trait_id, &[], None)
|
||||
], {
|
||||
|
@ -7,7 +7,7 @@
|
||||
use rustc::session::Session;
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::traits;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::TargetDataLayout;
|
||||
use rustc::mir::transform::MirSource;
|
||||
@ -18,7 +18,7 @@
|
||||
use std::str::FromStr;
|
||||
use syntax::ast::{self, LitKind};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::{ExpnFormat, ExpnInfo, MultiSpan, Span, DUMMY_SP};
|
||||
use syntax::codemap::{ExpnFormat, ExpnInfo, Span, DUMMY_SP};
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::keywords;
|
||||
@ -594,12 +594,10 @@ pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>(
|
||||
/// replacement. In human-readable format though, it only appears once before the whole suggestion.
|
||||
pub fn multispan_sugg(db: &mut DiagnosticBuilder, help_msg: String, sugg: Vec<(Span, String)>) {
|
||||
let sugg = rustc_errors::CodeSuggestion {
|
||||
msp: MultiSpan::from_spans(sugg.iter().map(|&(span, _)| span).collect()),
|
||||
substitutes: sugg.into_iter().map(|(_, subs)| subs).collect(),
|
||||
substitution_parts: sugg.into_iter().map(|(span, sub)| rustc_errors::Substitution { span, substitutions: vec![sub] }).collect(),
|
||||
msg: help_msg,
|
||||
};
|
||||
assert!(db.suggestion.is_none());
|
||||
db.suggestion = Some(sugg);
|
||||
db.suggestions.push(sugg);
|
||||
}
|
||||
|
||||
/// Return the base type for references and raw pointers.
|
||||
@ -777,11 +775,9 @@ pub fn camel_case_from(s: &str) -> usize {
|
||||
|
||||
/// Convenience function to get the return type of a function
|
||||
pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> ty::Ty<'tcx> {
|
||||
let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, fn_item);
|
||||
let fn_def_id = cx.tcx.hir.local_def_id(fn_item);
|
||||
let fn_sig = cx.tcx.type_of(fn_def_id).fn_sig();
|
||||
let fn_sig = cx.tcx.liberate_late_bound_regions(parameter_env.free_id_outlive, &fn_sig);
|
||||
fn_sig.output()
|
||||
let ret_ty = cx.tcx.type_of(fn_def_id).fn_sig().output();
|
||||
cx.tcx.erase_late_bound_regions(&ret_ty)
|
||||
}
|
||||
|
||||
/// Check if two types are the same.
|
||||
@ -791,12 +787,13 @@ pub fn same_tys<'a, 'tcx>(
|
||||
cx: &LateContext<'a, 'tcx>,
|
||||
a: ty::Ty<'tcx>,
|
||||
b: ty::Ty<'tcx>,
|
||||
parameter_item: NodeId
|
||||
parameter_item: DefId
|
||||
) -> bool {
|
||||
let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, parameter_item);
|
||||
let parameter_env = cx.tcx.parameter_environment(parameter_item);
|
||||
cx.tcx.infer_ctxt(parameter_env, Reveal::All).enter(|infcx| {
|
||||
let new_a = a.subst(infcx.tcx, infcx.parameter_environment.free_substs);
|
||||
let new_b = b.subst(infcx.tcx, infcx.parameter_environment.free_substs);
|
||||
let substs = Substs::identity_for_item(cx.tcx, parameter_item);
|
||||
let new_a = a.subst(infcx.tcx, substs);
|
||||
let new_b = b.subst(infcx.tcx, substs);
|
||||
infcx.can_equate(&new_a, &new_b).is_ok()
|
||||
})
|
||||
}
|
||||
@ -810,9 +807,10 @@ pub fn type_is_unsafe_function(ty: ty::Ty) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, env: NodeId) -> bool {
|
||||
let env = ty::ParameterEnvironment::for_item(cx.tcx, env);
|
||||
!ty.subst(cx.tcx, env.free_substs).moves_by_default(cx.tcx.global_tcx(), &env, DUMMY_SP)
|
||||
pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: ty::Ty<'tcx>, env: DefId) -> bool {
|
||||
let substs = Substs::identity_for_item(cx.tcx, env);
|
||||
let env = cx.tcx.parameter_environment(env);
|
||||
!ty.subst(cx.tcx, substs).moves_by_default(cx.tcx.global_tcx(), &env, DUMMY_SP)
|
||||
}
|
||||
|
||||
/// Return whether a pattern is refutable.
|
||||
|
@ -47,7 +47,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if_let_chain!{[
|
||||
let Some((_, arg, _)) = higher::for_loop(expr),
|
||||
let Some(vec_args) = higher::vec_macro(cx, arg),
|
||||
is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)), cx.tcx.hir.get_parent(expr.id)),
|
||||
is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)), cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(expr.id))),
|
||||
], {
|
||||
// report the error around the `vec!` not inside `<std macros>:`
|
||||
let span = arg.span.ctxt.outer().expn_info().map(|info| info.call_site).expect("unable to get call_site");
|
||||
|
@ -79,13 +79,21 @@ error: this boolean expression can be simplified
|
||||
--> $DIR/booleans.rs:34:13
|
||||
|
|
||||
34 | let _ = a == b && c == 5 && a == b;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `a == b && c == 5`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try
|
||||
| let _ = a == b && c == 5;
|
||||
| let _ = !(c != 5 || a != b);
|
||||
|
||||
error: this boolean expression can be simplified
|
||||
--> $DIR/booleans.rs:35:13
|
||||
|
|
||||
35 | let _ = a == b && c == 5 && b == a;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `a == b && c == 5`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try
|
||||
| let _ = a == b && c == 5;
|
||||
| let _ = !(c != 5 || a != b);
|
||||
|
||||
error: this boolean expression contains a logic bug
|
||||
--> $DIR/booleans.rs:36:13
|
||||
@ -115,7 +123,11 @@ error: this boolean expression can be simplified
|
||||
--> $DIR/booleans.rs:39:13
|
||||
|
|
||||
39 | let _ = a != b || !(a != b || c == d);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `c != d || a != b`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: try
|
||||
| let _ = c != d || a != b;
|
||||
| let _ = !(a == b && c == d);
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
@ -71,6 +71,8 @@ note: lint level defined here
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
help: if you mean to use a decimal constant, remove the `0` to remove confusion:
|
||||
| let fail8 = 123;
|
||||
help: if you mean to use an octal constant, use `0o`:
|
||||
| let fail8 = 0o123;
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
|
@ -11,7 +11,6 @@ note: lint level defined here
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: try this
|
||||
| #[derive(Default)]
|
||||
| pub struct Foo;
|
||||
|
||||
error: you should consider deriving a `Default` implementation for `Bar`
|
||||
--> $DIR/new_without_default.rs:16:5
|
||||
@ -21,7 +20,6 @@ error: you should consider deriving a `Default` implementation for `Bar`
|
||||
|
|
||||
help: try this
|
||||
| #[derive(Default)]
|
||||
| pub struct Bar;
|
||||
|
||||
error: you should consider adding a `Default` implementation for `LtKo<'c>`
|
||||
--> $DIR/new_without_default.rs:64:5
|
||||
|
Loading…
Reference in New Issue
Block a user