Skip to content

Commit

Permalink
Auto merge of #4776 - mikerite:fix-4727, r=flip1995
Browse files Browse the repository at this point in the history
Fix crash in `use-self` lint

Fixes #4727

changelog: Fix crash in `use-self` lint
  • Loading branch information
bors committed Nov 8, 2019
2 parents 37fa1e2 + cc6e27f commit b0b3dc6
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 56 deletions.
40 changes: 21 additions & 19 deletions clippy_lints/src/use_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,30 +223,32 @@ struct UseSelfVisitor<'a, 'tcx> {

impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> {
fn visit_path(&mut self, path: &'tcx Path, _id: HirId) {
if path.segments.len() >= 2 {
let last_but_one = &path.segments[path.segments.len() - 2];
if last_but_one.ident.name != kw::SelfUpper {
let enum_def_id = match path.res {
Res::Def(DefKind::Variant, variant_def_id) => self.cx.tcx.parent(variant_def_id),
Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), ctor_def_id) => {
let variant_def_id = self.cx.tcx.parent(ctor_def_id);
variant_def_id.and_then(|def_id| self.cx.tcx.parent(def_id))
},
_ => None,
};
if !path.segments.iter().any(|p| p.ident.span.is_dummy()) {
if path.segments.len() >= 2 {
let last_but_one = &path.segments[path.segments.len() - 2];
if last_but_one.ident.name != kw::SelfUpper {
let enum_def_id = match path.res {
Res::Def(DefKind::Variant, variant_def_id) => self.cx.tcx.parent(variant_def_id),
Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), ctor_def_id) => {
let variant_def_id = self.cx.tcx.parent(ctor_def_id);
variant_def_id.and_then(|def_id| self.cx.tcx.parent(def_id))
},
_ => None,
};

if self.item_path.res.opt_def_id() == enum_def_id {
span_use_self_lint(self.cx, path, Some(last_but_one));
if self.item_path.res.opt_def_id() == enum_def_id {
span_use_self_lint(self.cx, path, Some(last_but_one));
}
}
}
}

if path.segments.last().expect(SEGMENTS_MSG).ident.name != kw::SelfUpper {
if self.item_path.res == path.res {
span_use_self_lint(self.cx, path, None);
} else if let Res::Def(DefKind::Ctor(def::CtorOf::Struct, _), ctor_def_id) = path.res {
if self.item_path.res.opt_def_id() == self.cx.tcx.parent(ctor_def_id) {
if path.segments.last().expect(SEGMENTS_MSG).ident.name != kw::SelfUpper {
if self.item_path.res == path.res {
span_use_self_lint(self.cx, path, None);
} else if let Res::Def(DefKind::Ctor(def::CtorOf::Struct, _), ctor_def_id) = path.res {
if self.item_path.res.opt_def_id() == self.cx.tcx.parent(ctor_def_id) {
span_use_self_lint(self.cx, path, None);
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/crashes/auxiliary/ice-4727-aux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub trait Trait {
fn fun(par: &str) -> &str;
}

impl Trait for str {
fn fun(par: &str) -> &str {
&par[0..1]
}
}
8 changes: 8 additions & 0 deletions tests/ui/crashes/ice-4727.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-pass

#![warn(clippy::use_self)]

#[path = "auxiliary/ice-4727-aux.rs"]
mod aux;

fn main() {}
30 changes: 30 additions & 0 deletions tests/ui/use_self.fixed
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// run-rustfix
// compile-flags: --edition 2018

#![warn(clippy::use_self)]
#![allow(dead_code)]
Expand Down Expand Up @@ -332,3 +333,32 @@ mod issue3567 {
}
}
}

mod paths_created_by_lowering {
use std::ops::Range;

struct S {}

impl S {
const A: usize = 0;
const B: usize = 1;

async fn g() -> Self {
Self {}
}

fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
&p[Self::A..Self::B]
}
}

trait T {
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];
}

impl T for Range<u8> {
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
&p[0..1]
}
}
}
30 changes: 30 additions & 0 deletions tests/ui/use_self.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// run-rustfix
// compile-flags: --edition 2018

#![warn(clippy::use_self)]
#![allow(dead_code)]
Expand Down Expand Up @@ -332,3 +333,32 @@ mod issue3567 {
}
}
}

mod paths_created_by_lowering {
use std::ops::Range;

struct S {}

impl S {
const A: usize = 0;
const B: usize = 1;

async fn g() -> S {
S {}
}

fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
&p[S::A..S::B]
}
}

trait T {
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];
}

impl T for Range<u8> {
fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
&p[0..1]
}
}
}
Loading

0 comments on commit b0b3dc6

Please sign in to comment.