Update to rustc 1.19.0-nightly (826d8f385 2017-05-13)

fixes #1759, #1758
This commit is contained in:
Oliver Schneider 2017-05-14 09:56:10 +02:00
parent dfc7d2afd4
commit 4d5e25f31d
14 changed files with 57 additions and 42 deletions

View File

@ -384,9 +384,10 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
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());
});
}
}

View File

@ -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;
}

View File

@ -136,7 +136,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
&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();

View File

@ -76,6 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
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) {

View File

@ -873,7 +873,7 @@ impl<'tcx> Visitor<'tcx> for UsedVisitor {
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?
}

View File

@ -657,8 +657,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
}
// 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 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
}
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,

View File

@ -369,11 +369,11 @@ impl MiscEarly {
"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 */
);
});
}
}}

View File

@ -79,15 +79,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
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 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
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 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
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,

View File

@ -108,12 +108,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
// 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)
], {

View File

@ -7,7 +7,7 @@ use rustc::lint::{LintContext, LateContext, Level, Lint};
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::mem;
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.

View File

@ -47,7 +47,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
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");

View File

@ -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

View File

@ -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

View File

@ -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