Resolve field, struct and function renaming

Addresses the errors produced by (re)moving, merging or renaming
structs, fields and methods by rust-lang/rust#48149 and rust-lang/rust#51580
This commit is contained in:
flip1995 2018-06-24 15:32:40 +02:00
parent 5f5fa084ec
commit d9a80d2f84
No known key found for this signature in database
GPG Key ID: 9F184E1164831181
22 changed files with 106 additions and 94 deletions

View File

@ -207,7 +207,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
}
fn is_relevant_item(tcx: TyCtxt, item: &Item) -> bool {
if let ItemFn(_, _, _, _, _, eid) = item.node {
if let ItemFn(_, _, _, eid) = item.node {
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
} else {
true

View File

@ -124,7 +124,7 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
fn visit_expr(&mut self, e: &'tcx Expr) {
match e.node {
ExprAgain(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
ExprContinue(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
ExprCall(ref func, _) => {
let typ = self.cx.tables.expr_ty(func);
match typ.sty {

View File

@ -92,8 +92,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
};
let unsafety = match kind {
hir::intravisit::FnKind::ItemFn(_, _, unsafety, _, _, _, _) => unsafety,
hir::intravisit::FnKind::Method(_, sig, _, _) => sig.unsafety,
hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
hir::intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
hir::intravisit::FnKind::Closure(_) => return,
};
@ -101,8 +101,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
if !is_impl {
// don't lint extern functions decls, it's not their fault either
match kind {
hir::intravisit::FnKind::Method(_, &hir::MethodSig { abi: Abi::Rust, .. }, _, _) |
hir::intravisit::FnKind::ItemFn(_, _, _, _, Abi::Rust, _, _) => self.check_arg_number(cx, decl, span),
hir::intravisit::FnKind::Method(_, &hir::MethodSig { header: hir::FnHeader { abi: Abi::Rust, .. }, .. }, _, _) |
hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => self.check_arg_number(cx, decl, span),
_ => {},
}
}
@ -113,13 +113,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
if let hir::TraitItemKind::Method(ref sig, ref eid) = item.node {
// don't lint extern functions decls, it's not their fault
if sig.abi == Abi::Rust {
if sig.header.abi == Abi::Rust {
self.check_arg_number(cx, &sig.decl, item.span);
}
if let hir::TraitMethod::Provided(eid) = *eid {
let body = cx.tcx.hir.body(eid);
self.check_raw_ptr(cx, sig.unsafety, &sig.decl, body, item.id);
self.check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.id);
}
}
}

View File

@ -59,7 +59,7 @@ impl LintPass for LifetimePass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
if let ItemFn(ref decl, _, _, _, ref generics, id) = item.node {
if let ItemFn(ref decl, _, ref generics, id) = item.node {
check_fn_inner(cx, decl, Some(id), generics, item.span);
}
}
@ -101,21 +101,23 @@ fn check_fn_inner<'a, 'tcx>(
}
let mut bounds_lts = Vec::new();
for typ in generics.ty_params() {
for bound in &typ.bounds {
generics.params.iter().for_each(|param| match param.kind {
GenericParamKind::Lifetime { .. } => {},
GenericParamKind::Type { .. } => {
for bound in &param.bounds {
let mut visitor = RefVisitor::new(cx);
walk_ty_param_bound(&mut visitor, bound);
walk_param_bound(&mut visitor, bound);
if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) {
return;
}
if let TraitTyParamBound(ref trait_ref, _) = *bound {
if let GenericBound::Trait(ref trait_ref, _) = *bound {
let params = &trait_ref
.trait_ref
.path
.segments
.last()
.expect("a path must have at least one segment")
.parameters;
.args;
if let Some(ref params) = *params {
for bound in &params.lifetimes {
if bound.name.name() != "'static" && !bound.is_elided() {
@ -126,7 +128,8 @@ fn check_fn_inner<'a, 'tcx>(
}
}
}
}
},
});
if could_use_elision(cx, decl, body, &generics.params, bounds_lts) {
span_lint(
cx,
@ -295,7 +298,7 @@ impl<'v, 't> RefVisitor<'v, 't> {
}
fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) {
if let Some(ref last_path_segment) = last_path_segment(qpath).parameters {
if let Some(ref last_path_segment) = last_path_segment(qpath).args {
if !last_path_segment.parenthesized && last_path_segment.lifetimes.is_empty() {
let hir_id = self.cx.tcx.hir.node_to_hir_id(ty.id);
match self.cx.tables.qpath_def(qpath, hir_id) {
@ -335,7 +338,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
TyImplTraitExistential(exist_ty_id, _, _) => {
if let ItemExistential(ref exist_ty) = self.cx.tcx.hir.expect_item(exist_ty_id.id).node {
for bound in &exist_ty.bounds {
if let RegionTyParamBound(_) = *bound {
if let GenericBound::Outlives(_) = *bound {
self.record(&None);
}
}
@ -377,7 +380,7 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: &
let allowed_lts = allowed_lts_from(&pred.bound_generic_params);
// now walk the bounds
for bound in pred.bounds.iter() {
walk_ty_param_bound(&mut visitor, bound);
walk_param_bound(&mut visitor, bound);
}
// and check that all lifetimes are allowed
match visitor.into_vec() {
@ -418,7 +421,7 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker {
// don't want to spuriously remove them
// `'b` in `'a: 'b` is useless unless used elsewhere in
// a non-lifetime bound
if param.is_type_param() {
if let GenericParamKind::Type { .. } = param.kind {
walk_generic_param(self, param)
}
}

View File

@ -640,7 +640,7 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
}
},
ExprBlock(ref b, _) => never_loop_block(b, main_loop_id),
ExprAgain(d) => {
ExprContinue(d) => {
let id = d.target_id
.expect("target id can only be missing in the presence of compilation errors");
if id == main_loop_id {

View File

@ -104,7 +104,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool {
let arg_segment = [
PathSegment {
name: id,
parameters: None,
args: None,
infer_types: true,
},
];

View File

@ -2091,12 +2091,13 @@ impl SelfKind {
fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Generics, name: &[&str]) -> bool {
single_segment_ty(ty).map_or(false, |seg| {
generics.ty_params().any(|param| {
param.name == seg.name && param.bounds.iter().any(|bound| {
if let hir::TyParamBound::TraitTyParamBound(ref ptr, ..) = *bound {
generics.params.iter().any(|param| match param.kind {
hir::GenericParamKind::Type { .. } => {
param.name.name() == seg.name && param.bounds.iter().any(|bound| {
if let hir::GenericBound::Trait(ref ptr, ..) = *bound {
let path = &ptr.trait_ref.path;
match_path(path, name) && path.segments.last().map_or(false, |s| {
if let Some(ref params) = s.parameters {
if let Some(ref params) = s.args {
if params.parenthesized {
false
} else {
@ -2111,6 +2112,8 @@ fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Gener
false
}
})
},
_ => false,
})
})
}

View File

@ -189,13 +189,13 @@ impl LintPass for MiscEarly {
impl EarlyLintPass for MiscEarly {
fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) {
for param in &gen.params {
if let GenericParam::Type(ref ty) = *param {
let name = ty.ident.name.as_str();
if let GenericParamKind::Type { .. } = param.kind {
let name = param.ident.name.as_str();
if constants::BUILTIN_TYPES.contains(&&*name) {
span_lint(
cx,
BUILTIN_TYPE_SHADOW,
ty.ident.span,
param.ident.span,
&format!("This generic shadows the built-in type `{}`", name),
);
}
@ -296,7 +296,7 @@ impl EarlyLintPass for MiscEarly {
}
match expr.node {
ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node {
if let ExprKind::Closure(_, _, ref decl, ref block, _) = closure.node {
if let ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.node {
span_lint_and_then(
cx,
REDUNDANT_CLOSURE_CALL,
@ -327,7 +327,7 @@ impl EarlyLintPass for MiscEarly {
if_chain! {
if let StmtKind::Local(ref local) = w[0].node;
if let Option::Some(ref t) = local.init;
if let ExprKind::Closure(_, _, _, _, _) = t.node;
if let ExprKind::Closure(..) = t.node;
if let PatKind::Ident(_, ident, _) = local.pat.node;
if let StmtKind::Semi(ref second) = w[1].node;
if let ExprKind::Assign(_, ref call) = second.node;

View File

@ -72,8 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
}
match kind {
FnKind::ItemFn(.., abi, _, attrs) => {
if abi != Abi::Rust {
FnKind::ItemFn(.., header, _, attrs) => {
if header.abi != Abi::Rust {
return;
}
for a in attrs {
@ -218,7 +218,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
if let TyPath(QPath::Resolved(_, ref path)) = input.node;
if let Some(elem_ty) = path.segments.iter()
.find(|seg| seg.name == "Vec")
.and_then(|ps| ps.parameters.as_ref())
.and_then(|ps| ps.args.as_ref())
.map(|params| &params.types[0]);
then {
let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_"));

View File

@ -99,11 +99,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
let name = impl_item.name;
let id = impl_item.id;
if sig.constness == hir::Constness::Const {
if sig.header.constness == hir::Constness::Const {
// can't be implemented by default
return;
}
if impl_item.generics.params.iter().any(|gen| gen.is_type_param()) {
if impl_item.generics.params.iter().any(|gen| match gen.kind {
hir::GenericParamKind::Type { .. } => true,
_ => false
}) {
// when the result of `new()` depends on a type parameter we should not require
// an
// impl of `Default`

View File

@ -312,7 +312,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {
impl EarlyLintPass for NonExpressiveNames {
fn check_item(&mut self, cx: &EarlyContext, item: &Item) {
if let ItemKind::Fn(ref decl, _, _, _, _, ref blk) = item.node {
if let ItemKind::Fn(ref decl, _, _, ref blk) = item.node {
do_check(self, cx, &item.attrs, decl, blk);
}
}

View File

@ -103,7 +103,7 @@ impl LintPass for PointerPass {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass {
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
if let ItemFn(ref decl, _, _, _, _, body_id) = item.node {
if let ItemFn(ref decl, _, _, body_id) = item.node {
check_fn(cx, decl, item.id, Some(body_id));
}
}
@ -160,7 +160,7 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
let mut ty_snippet = None;
if_chain! {
if let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node;
if let Some(&PathSegment{parameters: Some(ref parameters), ..}) = path.segments.last();
if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last();
if parameters.types.len() == 1;
then {
ty_snippet = snippet_opt(cx, parameters.types[0].span);
@ -218,7 +218,7 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
if let TyPath(ref path) = ty.node;
if let QPath::Resolved(None, ref pp) = *path;
if let [ref bx] = *pp.segments;
if let Some(ref params) = bx.parameters;
if let Some(ref params) = bx.args;
if !params.parenthesized;
if let [ref inner] = *params.types;
then {

View File

@ -455,7 +455,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
fn get_type_snippet(cx: &LateContext, path: &QPath, to_ref_ty: Ty) -> String {
let seg = last_path_segment(path);
if_chain! {
if let Some(ref params) = seg.parameters;
if let Some(ref params) = seg.args;
if !params.parenthesized;
if let Some(to_ty) = params.types.get(1);
if let TyRptr(_, ref to_ty) = to_ty.node;

View File

@ -84,8 +84,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef {
}
match kind {
FnKind::ItemFn(.., abi, _, attrs) => {
if abi != Abi::Rust {
FnKind::ItemFn(.., header, _, attrs) => {
if header.abi != Abi::Rust {
return;
}
for a in attrs {

View File

@ -180,7 +180,7 @@ fn check_fn_decl(cx: &LateContext, decl: &FnDecl) {
fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool {
let last = last_path_segment(qpath);
if_chain! {
if let Some(ref params) = last.parameters;
if let Some(ref params) = last.args;
if !params.parenthesized;
if let Some(ty) = params.types.get(0);
if let TyPath(ref qpath) = ty.node;
@ -244,7 +244,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
QPath::Resolved(Some(ref ty), ref p) => {
check_ty(cx, ty, is_local);
for ty in p.segments.iter().flat_map(|seg| {
seg.parameters
seg.args
.as_ref()
.map_or_else(|| [].iter(), |params| params.types.iter())
}) {
@ -252,7 +252,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
}
},
QPath::Resolved(None, ref p) => for ty in p.segments.iter().flat_map(|seg| {
seg.parameters
seg.args
.as_ref()
.map_or_else(|| [].iter(), |params| params.types.iter())
}) {
@ -260,7 +260,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
},
QPath::TypeRelative(ref ty, ref seg) => {
check_ty(cx, ty, is_local);
if let Some(ref params) = seg.parameters {
if let Some(ref params) = seg.args {
for ty in params.types.iter() {
check_ty(cx, ty, is_local);
}
@ -288,7 +288,7 @@ fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifeti
if Some(def_id) == cx.tcx.lang_items().owned_box();
if let QPath::Resolved(None, ref path) = *qpath;
if let [ref bx] = *path.segments;
if let Some(ref params) = bx.parameters;
if let Some(ref params) = bx.args;
if !params.parenthesized;
if let [ref inner] = *params.types;
then {
@ -1208,7 +1208,10 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
TyTraitObject(ref param_bounds, _) => {
let has_lifetime_parameters = param_bounds
.iter()
.any(|bound| bound.bound_generic_params.iter().any(|gen| gen.is_lifetime_param()));
.any(|bound| bound.bound_generic_params.iter().any(|gen| match gen.kind {
GenericParamKind::Lifetime { .. } => true,
_ => false,
}));
if has_lifetime_parameters {
// complex trait bounds like A<'a, 'b>
(50 * self.nest, 1)
@ -1859,7 +1862,7 @@ impl<'tcx> ImplicitHasherType<'tcx> {
/// Checks that `ty` is a target type without a BuildHasher.
fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty) -> Option<Self> {
if let TyPath(QPath::Resolved(None, ref path)) = hir_ty.node {
let params = &path.segments.last().as_ref()?.parameters.as_ref()?.types;
let params = &path.segments.last().as_ref()?.args.as_ref()?.types;
let params_len = params.len();
let ty = hir_ty_to_ty(cx.tcx, hir_ty);

View File

@ -69,7 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel {
impl<'a, 'tcx: 'a> Visitor<'tcx> for UnusedLabelVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprBreak(destination, _) | hir::ExprAgain(destination) => if let Some(label) = destination.label {
hir::ExprBreak(destination, _) | hir::ExprContinue(destination) => if let Some(label) = destination.label {
self.labels.remove(&label.name.as_str());
},
hir::ExprLoop(_, Some(label), _) | hir::ExprWhile(_, _, Some(label)) => {

View File

@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
if let ItemImpl(.., ref item_type, ref refs) = item.node;
if let Ty_::TyPath(QPath::Resolved(_, ref item_path)) = item_type.node;
then {
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).parameters;
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
let should_check = if let Some(ref params) = *parameters {
!params.parenthesized && params.lifetimes.len() == 0
} else {

View File

@ -432,7 +432,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
}
// FIXME: implement label printing
},
Expr_::ExprAgain(ref _destination) => {
Expr_::ExprContinue(ref _destination) => {
let destination_pat = self.next("destination");
println!("Again(ref {}) = {};", destination_pat, current);
// FIXME: implement label printing

View File

@ -76,7 +76,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
match (&left.node, &right.node) {
(&ExprAddrOf(l_mut, ref le), &ExprAddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re),
(&ExprAgain(li), &ExprAgain(ri)) => {
(&ExprContinue(li), &ExprContinue(ri)) => {
both(&li.label, &ri.label, |l, r| l.name.as_str() == r.name.as_str())
},
(&ExprAssign(ref ll, ref lr), &ExprAssign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, rr),
@ -201,7 +201,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
&& over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r))
}
fn eq_path_parameters(&mut self, left: &PathParameters, right: &PathParameters) -> bool {
fn eq_path_parameters(&mut self, left: &GenericArgs, right: &GenericArgs) -> bool {
if !(left.parenthesized || right.parenthesized) {
over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r))
&& over(&left.types, &right.types, |l, r| self.eq_ty(l, r))
@ -224,7 +224,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
if left.name.as_str() != right.name.as_str() {
return false;
}
match (&left.parameters, &right.parameters) {
match (&left.args, &right.args) {
(&None, &None) => true,
(&Some(ref l), &Some(ref r)) => self.eq_path_parameters(l, r),
_ => false,
@ -345,8 +345,8 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
m.hash(&mut self.s);
self.hash_expr(e);
},
ExprAgain(i) => {
let c: fn(_) -> _ = ExprAgain;
ExprContinue(i) => {
let c: fn(_) -> _ = ExprContinue;
c.hash(&mut self.s);
if let Some(i) = i.label {
self.hash_name(i.name);

View File

@ -300,7 +300,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
print_expr(cx, e, indent + 1);
}
},
hir::ExprAgain(_) => println!("{}Again", ind),
hir::ExprContinue(_) => println!("{}Again", ind),
hir::ExprRet(ref e) => {
println!("{}Ret", ind);
if let Some(ref e) = *e {

View File

@ -524,7 +524,7 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeI
match node {
Node::NodeBlock(block) => Some(block),
Node::NodeItem(&Item {
node: ItemFn(_, _, _, _, _, eid),
node: ItemFn(_, _, _, eid),
..
}) | Node::NodeImplItem(&ImplItem {
node: ImplItemKind::Method(_, eid),

View File

@ -52,7 +52,7 @@ impl<'a> Sugg<'a> {
hir::ExprIf(..) |
hir::ExprUnary(..) |
hir::ExprMatch(..) => Sugg::MaybeParen(snippet),
hir::ExprAgain(..) |
hir::ExprContinue(..) |
hir::ExprYield(..) |
hir::ExprArray(..) |
hir::ExprBlock(..) |