clippy: nameres for primitive type impls
This commit is contained in:
parent
01d4e835c1
commit
46340f2049
3 changed files with 75 additions and 38 deletions
|
@ -87,6 +87,8 @@ use rustc_middle::hir::place::PlaceBase;
|
||||||
use rustc_middle::ty as rustc_ty;
|
use rustc_middle::ty as rustc_ty;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||||
use rustc_middle::ty::binding::BindingMode;
|
use rustc_middle::ty::binding::BindingMode;
|
||||||
|
use rustc_middle::ty::{IntTy, UintTy, FloatTy};
|
||||||
|
use rustc_middle::ty::fast_reject::SimplifiedTypeGen::*;
|
||||||
use rustc_middle::ty::{layout::IntegerExt, BorrowKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeFoldable, UpvarCapture};
|
use rustc_middle::ty::{layout::IntegerExt, BorrowKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeFoldable, UpvarCapture};
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_semver::RustcVersion;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
@ -455,14 +457,6 @@ pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>
|
||||||
/// Resolves a def path like `std::vec::Vec`.
|
/// Resolves a def path like `std::vec::Vec`.
|
||||||
/// This function is expensive and should be used sparingly.
|
/// This function is expensive and should be used sparingly.
|
||||||
pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||||
macro_rules! try_res {
|
|
||||||
($e:expr) => {
|
|
||||||
match $e {
|
|
||||||
Some(e) => e,
|
|
||||||
None => return Res::Err,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Option<Res> {
|
fn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Option<Res> {
|
||||||
match tcx.def_kind(def_id) {
|
match tcx.def_kind(def_id) {
|
||||||
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
||||||
|
@ -479,10 +473,36 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn find_primitive(_tcx: TyCtxt<'_>, _name: &str) -> Option<DefId> {
|
fn find_primitive<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
|
||||||
// FIXME: Deal with this without relying on lang items or by only
|
let single = |ty| tcx.incoherent_impls(ty).iter().copied();
|
||||||
// looking at a single impl.
|
let empty = || [].iter().copied();
|
||||||
None
|
match name {
|
||||||
|
"bool" => single(BoolSimplifiedType),
|
||||||
|
"char" => single(CharSimplifiedType),
|
||||||
|
"str" => single(StrSimplifiedType),
|
||||||
|
"array" => single(ArraySimplifiedType),
|
||||||
|
"slice" => single(SliceSimplifiedType),
|
||||||
|
// FIXME: rustdoc documents these two using just `pointer`.
|
||||||
|
//
|
||||||
|
// Maybe this is something we should do here too.
|
||||||
|
"const_ptr" => single(PtrSimplifiedType(Mutability::Not)),
|
||||||
|
"mut_ptr" => single(PtrSimplifiedType(Mutability::Mut)),
|
||||||
|
"isize" => single(IntSimplifiedType(IntTy::Isize)),
|
||||||
|
"i8" => single(IntSimplifiedType(IntTy::I8)),
|
||||||
|
"i16" => single(IntSimplifiedType(IntTy::I16)),
|
||||||
|
"i32" => single(IntSimplifiedType(IntTy::I32)),
|
||||||
|
"i64" => single(IntSimplifiedType(IntTy::I64)),
|
||||||
|
"i128" => single(IntSimplifiedType(IntTy::I128)),
|
||||||
|
"usize" => single(UintSimplifiedType(UintTy::Usize)),
|
||||||
|
"u8" => single(UintSimplifiedType(UintTy::U8)),
|
||||||
|
"u16" => single(UintSimplifiedType(UintTy::U16)),
|
||||||
|
"u32" => single(UintSimplifiedType(UintTy::U32)),
|
||||||
|
"u64" => single(UintSimplifiedType(UintTy::U64)),
|
||||||
|
"u128" => single(UintSimplifiedType(UintTy::U128)),
|
||||||
|
"f32" => single(FloatSimplifiedType(FloatTy::F32)),
|
||||||
|
"f64" => single(FloatSimplifiedType(FloatTy::F64)),
|
||||||
|
_ => empty(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn find_crate(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
fn find_crate(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
||||||
tcx.crates(())
|
tcx.crates(())
|
||||||
|
@ -500,30 +520,35 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
||||||
_ => return Res::Err,
|
_ => return Res::Err,
|
||||||
};
|
};
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
let first = try_res!(
|
let starts = find_primitive(tcx, base)
|
||||||
find_primitive(tcx, base)
|
.chain(find_crate(tcx, base))
|
||||||
.or_else(|| find_crate(tcx, base))
|
.flat_map(|id| item_child_by_name(tcx, id, first));
|
||||||
.and_then(|id| item_child_by_name(tcx, id, first))
|
|
||||||
);
|
|
||||||
|
|
||||||
let last = path
|
for first in starts {
|
||||||
.iter()
|
let last = path
|
||||||
.copied()
|
.iter()
|
||||||
// for each segment, find the child item
|
.copied()
|
||||||
.try_fold(first, |res, segment| {
|
// for each segment, find the child item
|
||||||
let def_id = res.def_id();
|
.try_fold(first, |res, segment| {
|
||||||
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
let def_id = res.def_id();
|
||||||
Some(item)
|
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
||||||
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
Some(item)
|
||||||
// it is not a child item so check inherent impl items
|
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||||
tcx.inherent_impls(def_id)
|
// it is not a child item so check inherent impl items
|
||||||
.iter()
|
tcx.inherent_impls(def_id)
|
||||||
.find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment))
|
.iter()
|
||||||
} else {
|
.find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment))
|
||||||
None
|
} else {
|
||||||
}
|
None
|
||||||
});
|
}
|
||||||
try_res!(last).expect_non_local()
|
});
|
||||||
|
|
||||||
|
if let Some(last) = last {
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Res::Err
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to get the `DefId` of a trait by path.
|
/// Convenience function to get the `DefId` of a trait by path.
|
||||||
|
|
|
@ -10,8 +10,8 @@ fn main() {
|
||||||
let mut a = vec![1, 2, 3, 4];
|
let mut a = vec![1, 2, 3, 4];
|
||||||
a.iter().sum::<i32>();
|
a.iter().sum::<i32>();
|
||||||
|
|
||||||
a.sort_unstable(); // FIXME: Warn here
|
a.sort_unstable();
|
||||||
|
|
||||||
let _ = 2.0f32.clamp(3.0f32, 4.0f32); // FIXME: Warn here
|
let _ = 2.0f32.clamp(3.0f32, 4.0f32);
|
||||||
let _ = 2.0f64.clamp(3.0f64, 4.0f64);
|
let _ = 2.0f64.clamp(3.0f64, 4.0f64);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,5 +20,17 @@ error: use of a disallowed method `std::iter::Iterator::sum`
|
||||||
LL | a.iter().sum::<i32>();
|
LL | a.iter().sum::<i32>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: use of a disallowed method `slice::sort_unstable`
|
||||||
|
--> $DIR/conf_disallowed_methods.rs:13:5
|
||||||
|
|
|
||||||
|
LL | a.sort_unstable();
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: use of a disallowed method `f32::clamp`
|
||||||
|
--> $DIR/conf_disallowed_methods.rs:15:13
|
||||||
|
|
|
||||||
|
LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue