Skip to content

Commit 31435cd

Browse files
committed
Reimplement AbsolutePathBuffer
1 parent 54e2051 commit 31435cd

File tree

6 files changed

+107
-34
lines changed

6 files changed

+107
-34
lines changed

clippy_lints/src/attrs.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,22 +352,22 @@ fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
352352
}
353353
}
354354

355-
fn is_relevant_item(tcx: TyCtxt<'_, '_, '_>, item: &Item) -> bool {
355+
fn is_relevant_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &Item) -> bool {
356356
if let ItemKind::Fn(_, _, _, eid) = item.node {
357357
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir().body(eid).value)
358358
} else {
359359
true
360360
}
361361
}
362362

363-
fn is_relevant_impl(tcx: TyCtxt<'_, '_, '_>, item: &ImplItem) -> bool {
363+
fn is_relevant_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &ImplItem) -> bool {
364364
match item.node {
365365
ImplItemKind::Method(_, eid) => is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir().body(eid).value),
366366
_ => false,
367367
}
368368
}
369369

370-
fn is_relevant_trait(tcx: TyCtxt<'_, '_, '_>, item: &TraitItem) -> bool {
370+
fn is_relevant_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &TraitItem) -> bool {
371371
match item.node {
372372
TraitItemKind::Method(_, TraitMethod::Required(_)) => true,
373373
TraitItemKind::Method(_, TraitMethod::Provided(eid)) => {
@@ -377,7 +377,7 @@ fn is_relevant_trait(tcx: TyCtxt<'_, '_, '_>, item: &TraitItem) -> bool {
377377
}
378378
}
379379

380-
fn is_relevant_block(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>, block: &Block) -> bool {
380+
fn is_relevant_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &ty::TypeckTables<'_>, block: &Block) -> bool {
381381
if let Some(stmt) = block.stmts.first() {
382382
match &stmt.node {
383383
StmtKind::Local(_) => true,
@@ -389,7 +389,7 @@ fn is_relevant_block(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>, blo
389389
}
390390
}
391391

392-
fn is_relevant_expr(tcx: TyCtxt<'_, '_, '_>, tables: &ty::TypeckTables<'_>, expr: &Expr) -> bool {
392+
fn is_relevant_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &ty::TypeckTables<'_>, expr: &Expr) -> bool {
393393
match &expr.node {
394394
ExprKind::Block(block, _) => is_relevant_block(tcx, tables, block),
395395
ExprKind::Ret(Some(e)) => is_relevant_expr(tcx, tables, e),

clippy_lints/src/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
245245
let def = self.tables.qpath_def(qpath, callee.hir_id);
246246
if let Some(def_id) = def.opt_def_id();
247247
let def_path = get_def_path(self.tcx, def_id);
248-
if let &["core", "num", impl_ty, "max_value"] = &def_path[..];
248+
if let &["core", "num", impl_ty, "max_value"] = &def_path.iter().map(|s| s.as_str()).collect::<Vec<_>>()[..];
249249
then {
250250
let value = match impl_ty {
251251
"<impl i8>" => i8::max_value() as u128,

clippy_lints/src/fallible_impl_from.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
132132
}
133133
}
134134

135-
fn match_type(tcx: ty::TyCtxt<'_, '_, '_>, ty: ty::Ty<'_>, path: &[&str]) -> bool {
135+
fn match_type<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, ty: ty::Ty<'_>, path: &[&str]) -> bool {
136136
match ty.sty {
137137
ty::Adt(adt, _) => match_def_path(tcx, adt.did, path),
138138
_ => false,

clippy_lints/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// error-pattern:cargo-clippy
22

33
#![feature(box_syntax)]
4+
#![feature(never_type)]
45
#![feature(rustc_private)]
56
#![feature(slice_patterns)]
67
#![feature(stmt_expr_attributes)]

clippy_lints/src/types.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintC
1212
use rustc::ty::layout::LayoutOf;
1313
use rustc::ty::{self, InferTy, Ty, TyCtxt, TypeckTables};
1414
use rustc::{declare_tool_lint, lint_array};
15+
use rustc::ty::print::Printer;
1516
use rustc_errors::Applicability;
1617
use rustc_target::spec::abi::Abi;
1718
use rustc_typeck::hir_ty_to_ty;
@@ -1135,15 +1136,14 @@ impl LintPass for CastPass {
11351136

11361137
// Check if the given type is either `core::ffi::c_void` or
11371138
// one of the platform specific `libc::<platform>::c_void` of libc.
1138-
fn is_c_void(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
1139+
fn is_c_void<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'_>) -> bool {
11391140
if let ty::Adt(adt, _) = ty.sty {
1140-
let mut apb = AbsolutePathBuffer { names: vec![] };
1141-
tcx.push_item_path(&mut apb, adt.did, false);
1141+
let names = AbsolutePathBuffer { tcx }.print_def_path(adt.did, &[]).unwrap();
11421142

1143-
if apb.names.is_empty() {
1143+
if names.is_empty() {
11441144
return false;
11451145
}
1146-
if apb.names[0] == "libc" || apb.names[0] == "core" && *apb.names.last().unwrap() == "c_void" {
1146+
if names[0] == "libc" || names[0] == "core" && *names.last().unwrap() == "c_void" {
11471147
return true;
11481148
}
11491149
}

clippy_lints/src/utils/mod.rs

Lines changed: 94 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ use if_chain::if_chain;
2424
use matches::matches;
2525
use rustc::hir;
2626
use rustc::hir::def::Def;
27+
use rustc::hir::map::DisambiguatedDefPathData;
28+
use rustc::hir::def_id::CrateNum;
2729
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
2830
use rustc::hir::intravisit::{NestedVisitorMap, Visitor};
2931
use rustc::hir::Node;
@@ -41,7 +43,6 @@ use rustc_errors::Applicability;
4143
use syntax::ast::{self, LitKind};
4244
use syntax::attr;
4345
use syntax::source_map::{Span, DUMMY_SP};
44-
use syntax::symbol;
4546
use syntax::symbol::{keywords, Symbol};
4647

4748
use crate::reexport::*;
@@ -97,19 +98,97 @@ pub fn in_macro(span: Span) -> bool {
9798
/// Used to store the absolute path to a type.
9899
///
99100
/// See `match_def_path` for usage.
100-
#[derive(Debug)]
101-
pub struct AbsolutePathBuffer {
102-
pub names: Vec<symbol::LocalInternedString>,
101+
pub struct AbsolutePathBuffer<'a, 'tcx> {
102+
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
103103
}
104104

105-
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
106-
fn root_mode(&self) -> &ty::item_path::RootMode {
107-
const ABSOLUTE: &ty::item_path::RootMode = &ty::item_path::RootMode::Absolute;
108-
ABSOLUTE
105+
use rustc::ty::print::Printer;
106+
107+
impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathBuffer<'_, 'tcx> {
108+
type Error = !;
109+
110+
type Path = Vec<String>;
111+
type Region = ();
112+
type Type = ();
113+
type DynExistential = ();
114+
115+
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
116+
self.tcx
117+
}
118+
119+
fn print_region(
120+
self,
121+
_region: ty::Region<'_>,
122+
) -> Result<Self::Region, Self::Error> {
123+
Ok(())
124+
}
125+
126+
fn print_type(
127+
self,
128+
_ty: Ty<'tcx>,
129+
) -> Result<Self::Type, Self::Error> {
130+
Ok(())
131+
}
132+
133+
fn print_dyn_existential(
134+
self,
135+
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
136+
) -> Result<Self::DynExistential, Self::Error> {
137+
Ok(())
109138
}
110139

111-
fn push(&mut self, text: &str) {
112-
self.names.push(symbol::Symbol::intern(text).as_str());
140+
fn path_crate(
141+
self,
142+
cnum: CrateNum,
143+
) -> Result<Self::Path, Self::Error> {
144+
Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
145+
}
146+
fn path_qualified(
147+
self,
148+
self_ty: Ty<'tcx>,
149+
trait_ref: Option<ty::TraitRef<'tcx>>,
150+
) -> Result<Self::Path, Self::Error> {
151+
// This shouldn't ever be needed, but just in case:
152+
Ok(vec![match trait_ref {
153+
Some(trait_ref) => format!("{:?}", trait_ref),
154+
None => format!("<{}>", self_ty),
155+
}])
156+
}
157+
158+
fn path_append_impl(
159+
self,
160+
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
161+
_disambiguated_data: &DisambiguatedDefPathData,
162+
self_ty: Ty<'tcx>,
163+
trait_ref: Option<ty::TraitRef<'tcx>>,
164+
) -> Result<Self::Path, Self::Error> {
165+
let mut path = print_prefix(self)?;
166+
167+
// This shouldn't ever be needed, but just in case:
168+
path.push(match trait_ref {
169+
Some(trait_ref) => {
170+
format!("<impl {} for {}>", trait_ref, self_ty)
171+
}
172+
None => format!("<impl {}>", self_ty),
173+
});
174+
175+
Ok(path)
176+
}
177+
fn path_append(
178+
self,
179+
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
180+
disambiguated_data: &DisambiguatedDefPathData,
181+
) -> Result<Self::Path, Self::Error> {
182+
let mut path = print_prefix(self)?;
183+
path.push(disambiguated_data.data.as_interned_str().to_string());
184+
Ok(path)
185+
}
186+
fn path_generic_args(
187+
self,
188+
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
189+
_args: &[Kind<'tcx>],
190+
) -> Result<Self::Path, Self::Error> {
191+
print_prefix(self)
113192
}
114193
}
115194

@@ -121,12 +200,10 @@ impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
121200
/// ```
122201
///
123202
/// See also the `paths` module.
124-
pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool {
125-
let mut apb = AbsolutePathBuffer { names: vec![] };
203+
pub fn match_def_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, path: &[&str]) -> bool {
204+
let names = AbsolutePathBuffer { tcx }.print_def_path(def_id, &[]).unwrap();
126205

127-
tcx.push_item_path(&mut apb, def_id, false);
128-
129-
apb.names.len() == path.len() && apb.names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
206+
names.len() == path.len() && names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
130207
}
131208

132209
/// Gets the absolute path of `def_id` as a vector of `&str`.
@@ -138,13 +215,8 @@ pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) ->
138215
/// // The given `def_id` is that of an `Option` type
139216
/// };
140217
/// ```
141-
pub fn get_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Vec<&'static str> {
142-
let mut apb = AbsolutePathBuffer { names: vec![] };
143-
tcx.push_item_path(&mut apb, def_id, false);
144-
apb.names
145-
.iter()
146-
.map(syntax_pos::symbol::LocalInternedString::get)
147-
.collect()
218+
pub fn get_def_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Vec<String> {
219+
AbsolutePathBuffer { tcx }.print_def_path(def_id, &[]).unwrap()
148220
}
149221

150222
/// Checks if type is struct, enum or union type with the given def path.

0 commit comments

Comments
 (0)