Auto merge of #8656 - flip1995:rustup, r=flip1995
Rustup r? `@ghost` changelog: none
This commit is contained in:
commit
abc59bb914
34 changed files with 196 additions and 157 deletions
|
|
@ -8,10 +8,10 @@
|
|||
//! Thank you!
|
||||
//! ~The `INTERNAL_METADATA_COLLECTOR` lint
|
||||
|
||||
use rustc_errors::{emitter::MAX_SUGGESTION_HIGHLIGHT_LINES, Applicability, Diagnostic};
|
||||
use rustc_errors::{emitter::MAX_SUGGESTION_HIGHLIGHT_LINES, Applicability, Diagnostic, MultiSpan};
|
||||
use rustc_hir::HirId;
|
||||
use rustc_lint::{LateContext, Lint, LintContext};
|
||||
use rustc_span::source_map::{MultiSpan, Span};
|
||||
use rustc_span::source_map::Span;
|
||||
use std::env;
|
||||
|
||||
fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) {
|
||||
|
|
|
|||
|
|
@ -77,17 +77,22 @@ use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
|||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
|
||||
use rustc_hir::{
|
||||
def, lang_items, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr,
|
||||
ExprKind, FnDecl, ForeignItem, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local,
|
||||
MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Target,
|
||||
TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
|
||||
def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl,
|
||||
ForeignItem, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
|
||||
Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
|
||||
TraitRef, TyKind, UnOp,
|
||||
};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
use rustc_middle::ty as rustc_ty;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||
use rustc_middle::ty::binding::BindingMode;
|
||||
use rustc_middle::ty::fast_reject::SimplifiedTypeGen::{
|
||||
ArraySimplifiedType, BoolSimplifiedType, CharSimplifiedType, FloatSimplifiedType, IntSimplifiedType,
|
||||
PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType,
|
||||
};
|
||||
use rustc_middle::ty::{layout::IntegerExt, BorrowKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeFoldable, UpvarCapture};
|
||||
use rustc_middle::ty::{FloatTy, IntTy, UintTy};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
|
|
@ -455,14 +460,6 @@ pub fn path_def_id<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>
|
|||
/// Resolves a def path like `std::vec::Vec`.
|
||||
/// This function is expensive and should be used sparingly.
|
||||
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> {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
||||
|
|
@ -479,11 +476,35 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
fn find_primitive(tcx: TyCtxt<'_>, name: &str) -> Option<DefId> {
|
||||
if let Some(&(index, Target::Impl)) = lang_items::ITEM_REFS.get(&Symbol::intern(name)) {
|
||||
tcx.lang_items().items()[index]
|
||||
} else {
|
||||
None
|
||||
fn find_primitive<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
let single = |ty| tcx.incoherent_impls(ty).iter().copied();
|
||||
let empty = || [].iter().copied();
|
||||
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> {
|
||||
|
|
@ -502,30 +523,35 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
|
|||
_ => return Res::Err,
|
||||
};
|
||||
let tcx = cx.tcx;
|
||||
let first = try_res!(
|
||||
find_primitive(tcx, base)
|
||||
.or_else(|| find_crate(tcx, base))
|
||||
.and_then(|id| item_child_by_name(tcx, id, first))
|
||||
);
|
||||
let starts = find_primitive(tcx, base)
|
||||
.chain(find_crate(tcx, base))
|
||||
.filter_map(|id| item_child_by_name(tcx, id, first));
|
||||
|
||||
let last = path
|
||||
.iter()
|
||||
.copied()
|
||||
// for each segment, find the child item
|
||||
.try_fold(first, |res, segment| {
|
||||
let def_id = res.def_id();
|
||||
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
||||
Some(item)
|
||||
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
// it is not a child item so check inherent impl items
|
||||
tcx.inherent_impls(def_id)
|
||||
.iter()
|
||||
.find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
try_res!(last).expect_non_local()
|
||||
for first in starts {
|
||||
let last = path
|
||||
.iter()
|
||||
.copied()
|
||||
// for each segment, find the child item
|
||||
.try_fold(first, |res, segment| {
|
||||
let def_id = res.def_id();
|
||||
if let Some(item) = item_child_by_name(tcx, def_id, segment) {
|
||||
Some(item)
|
||||
} else if matches!(res, Res::Def(DefKind::Enum | DefKind::Struct, _)) {
|
||||
// it is not a child item so check inherent impl items
|
||||
tcx.inherent_impls(def_id)
|
||||
.iter()
|
||||
.find_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, segment))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(last) = last {
|
||||
return last;
|
||||
}
|
||||
}
|
||||
|
||||
Res::Err
|
||||
}
|
||||
|
||||
/// Convenience function to get the `DefId` of a trait by path.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue