mirror of
https://github.com/servo/servo.git
synced 2025-09-27 23:30:08 +01:00
cargo: Bump rustc to 1.89 (#36818)
Update Rustc to 1.89. Reviewable by commit. Leftover work: - #37330 - #38777 --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> Co-authored-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
8587536755
commit
3225d19907
126 changed files with 408 additions and 610 deletions
|
@ -1,5 +1,5 @@
|
|||
[toolchain]
|
||||
channel = "1.85.0"
|
||||
channel = "1.89.0"
|
||||
|
||||
components = [
|
||||
"clippy",
|
||||
|
|
|
@ -2,19 +2,17 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::{ImplItemRef, ItemKind, Node, OwnerId, PrimTy, TraitItemRef};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{EvaluationResult, Obligation, ObligationCause};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::fast_reject::SimplifiedType;
|
||||
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt, TypeVisitableExt, TypingEnv};
|
||||
use rustc_middle::ty::{self, GenericArg, TraitRef, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_type_ir::{FloatTy, IntTy, UintTy};
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use rustc_type_ir::Upcast as _;
|
||||
|
||||
/// check if a DefId's path matches the given absolute type path
|
||||
/// usage e.g. with
|
||||
|
@ -65,286 +63,101 @@ macro_rules! symbols {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn find_first_crate<'tcx>(tcx: &TyCtxt<'tcx>, crate_name: Symbol) -> Option<CrateNum> {
|
||||
tcx.crates(())
|
||||
.iter()
|
||||
.find(|c| tcx.crate_name(**c) == crate_name)
|
||||
.copied()
|
||||
}
|
||||
|
||||
pub fn trait_in_crate<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
krate: CrateNum,
|
||||
trait_sym: Symbol,
|
||||
) -> Option<DefId> {
|
||||
tcx.traits(krate)
|
||||
.iter()
|
||||
.find(|id| tcx.opt_item_name(**id) == Some(trait_sym))
|
||||
.copied()
|
||||
}
|
||||
|
||||
/*
|
||||
Stuff copied from clippy:
|
||||
*/
|
||||
|
||||
// This is adapted from
|
||||
// https://github.com/rust-lang/rust-clippy/blob/546408be416f0355a39601c1457b37727bc74395/clippy_utils/src/lib.rs#L517.
|
||||
fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
let ty = match name {
|
||||
"bool" => SimplifiedType::Bool,
|
||||
"char" => SimplifiedType::Char,
|
||||
"str" => SimplifiedType::Str,
|
||||
"array" => SimplifiedType::Array,
|
||||
"slice" => SimplifiedType::Slice,
|
||||
// FIXME: rustdoc documents these two using just `pointer`.
|
||||
//
|
||||
// Maybe this is something we should do here too.
|
||||
"const_ptr" => SimplifiedType::Ptr(Mutability::Not),
|
||||
"mut_ptr" => SimplifiedType::Ptr(Mutability::Mut),
|
||||
"isize" => SimplifiedType::Int(IntTy::Isize),
|
||||
"i8" => SimplifiedType::Int(IntTy::I8),
|
||||
"i16" => SimplifiedType::Int(IntTy::I16),
|
||||
"i32" => SimplifiedType::Int(IntTy::I32),
|
||||
"i64" => SimplifiedType::Int(IntTy::I64),
|
||||
"i128" => SimplifiedType::Int(IntTy::I128),
|
||||
"usize" => SimplifiedType::Uint(UintTy::Usize),
|
||||
"u8" => SimplifiedType::Uint(UintTy::U8),
|
||||
"u16" => SimplifiedType::Uint(UintTy::U16),
|
||||
"u32" => SimplifiedType::Uint(UintTy::U32),
|
||||
"u64" => SimplifiedType::Uint(UintTy::U64),
|
||||
"u128" => SimplifiedType::Uint(UintTy::U128),
|
||||
"f32" => SimplifiedType::Float(FloatTy::F32),
|
||||
"f64" => SimplifiedType::Float(FloatTy::F64),
|
||||
#[allow(trivial_casts)]
|
||||
_ => {
|
||||
return [].iter().copied();
|
||||
},
|
||||
};
|
||||
|
||||
tcx.incoherent_impls(ty).iter().copied()
|
||||
}
|
||||
|
||||
fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx
|
||||
.module_children(def_id)
|
||||
.iter()
|
||||
.filter(|item| item.ident.name == name)
|
||||
.map(|child| child.res.expect_non_local())
|
||||
.collect(),
|
||||
DefKind::Impl { .. } => tcx
|
||||
.associated_item_def_ids(def_id)
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|assoc_def_id| tcx.item_name(*assoc_def_id) == name)
|
||||
.map(|assoc_def_id| Res::Def(tcx.def_kind(assoc_def_id), assoc_def_id))
|
||||
.collect(),
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// This is adapted from clippy:
|
||||
// https://github.com/rust-lang/rust-clippy/blob/546408be416f0355a39601c1457b37727bc74395/clippy_utils/src/lib.rs#L574.
|
||||
fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symbol) -> Vec<Res> {
|
||||
let hir = tcx.hir();
|
||||
|
||||
let root_mod;
|
||||
let item_kind = match tcx.hir_node_by_def_id(local_id) {
|
||||
Node::Crate(r#mod) => {
|
||||
root_mod = ItemKind::Mod(r#mod);
|
||||
&root_mod
|
||||
},
|
||||
Node::Item(item) => &item.kind,
|
||||
_ => return Vec::new(),
|
||||
};
|
||||
|
||||
let res = |ident: Ident, owner_id: OwnerId| {
|
||||
if ident.name == name {
|
||||
let def_id = owner_id.to_def_id();
|
||||
Some(Res::Def(tcx.def_kind(def_id), def_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
match item_kind {
|
||||
ItemKind::Mod(r#mod) => r#mod
|
||||
.item_ids
|
||||
.iter()
|
||||
.filter_map(|&item_id| res(hir.item(item_id).ident, item_id.owner_id))
|
||||
.collect(),
|
||||
ItemKind::Impl(r#impl) => r#impl
|
||||
.items
|
||||
.iter()
|
||||
.filter_map(|&ImplItemRef { ident, id, .. }| res(ident, id.owner_id))
|
||||
.collect(),
|
||||
ItemKind::Trait(.., trait_item_refs) => trait_item_refs
|
||||
.iter()
|
||||
.filter_map(|&TraitItemRef { ident, id, .. }| res(ident, id.owner_id))
|
||||
.collect(),
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
|
||||
if let Some(local_id) = def_id.as_local() {
|
||||
local_item_children_by_name(tcx, local_id, name)
|
||||
} else {
|
||||
non_local_item_children_by_name(tcx, def_id, name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves a def path like `std::vec::Vec`.
|
||||
///
|
||||
/// Can return multiple resolutions when there are multiple versions of the same crate, e.g.
|
||||
/// `memchr::memchr` could return the functions from both memchr 1.0 and memchr 2.0.
|
||||
///
|
||||
/// Also returns multiple results when there are multiple paths under the same name e.g. `std::vec`
|
||||
/// would have both a [`DefKind::Mod`] and [`DefKind::Macro`].
|
||||
///
|
||||
/// This function is expensive and should be used sparingly.
|
||||
pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Vec<Res> {
|
||||
fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
|
||||
tcx.crates(())
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(move |&num| tcx.crate_name(num) == name)
|
||||
.map(CrateNum::as_def_id)
|
||||
}
|
||||
|
||||
let tcx = cx.tcx;
|
||||
|
||||
let (base, mut path) = match *path {
|
||||
[primitive] => {
|
||||
return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
|
||||
},
|
||||
[base, ref path @ ..] => (base, path),
|
||||
_ => return Vec::new(),
|
||||
};
|
||||
|
||||
let base_sym = Symbol::intern(base);
|
||||
|
||||
let local_crate = if tcx.crate_name(LOCAL_CRATE) == base_sym {
|
||||
Some(LOCAL_CRATE.as_def_id())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let starts = find_primitive_impls(tcx, base)
|
||||
.chain(find_crates(tcx, base_sym))
|
||||
.chain(local_crate)
|
||||
.map(|id| Res::Def(tcx.def_kind(id), id));
|
||||
|
||||
let mut resolutions: Vec<Res> = starts.collect();
|
||||
|
||||
while let [segment, rest @ ..] = path {
|
||||
path = rest;
|
||||
let segment = Symbol::intern(segment);
|
||||
|
||||
resolutions = resolutions
|
||||
.into_iter()
|
||||
.filter_map(|res| res.opt_def_id())
|
||||
.flat_map(|def_id| {
|
||||
// When the current def_id is e.g. `struct S`, check the impl items in
|
||||
// `impl S { ... }`
|
||||
let inherent_impl_children = tcx
|
||||
.inherent_impls(def_id)
|
||||
.into_iter()
|
||||
.flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
|
||||
|
||||
let direct_children = item_children_by_name(tcx, def_id, segment);
|
||||
|
||||
inherent_impl_children.chain(direct_children)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
resolutions
|
||||
}
|
||||
|
||||
pub fn get_trait_def_id(cx: &LateContext<'_>, path: &[&str]) -> Option<DefId> {
|
||||
def_path_res(cx, path)
|
||||
.into_iter()
|
||||
.find_map(|res| match res {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, trait_id) => Some(trait_id),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
// These are special variants made from the above functions.
|
||||
/// Resolves a def path like `std::vec::Vec`, but searches only local crate
|
||||
///
|
||||
/// Also returns multiple results when there are multiple paths under the same name e.g. `std::vec`
|
||||
/// would have both a [`DefKind::Mod`] and [`DefKind::Macro`].
|
||||
///
|
||||
/// This function is less expensive than `def_path_res` and should be used sparingly.
|
||||
pub fn def_local_res(cx: &LateContext<'_>, path: &str) -> Vec<Res> {
|
||||
let tcx = cx.tcx;
|
||||
let local_crate = LOCAL_CRATE.as_def_id();
|
||||
let starts = Res::Def(tcx.def_kind(local_crate), local_crate);
|
||||
let mut resolutions: Vec<Res> = vec![starts];
|
||||
let segment = Symbol::intern(path);
|
||||
|
||||
resolutions = resolutions
|
||||
.into_iter()
|
||||
.filter_map(|res| res.opt_def_id())
|
||||
.flat_map(|def_id| {
|
||||
// When the current def_id is e.g. `struct S`, check the impl items in
|
||||
// `impl S { ... }`
|
||||
let inherent_impl_children = tcx
|
||||
.inherent_impls(def_id)
|
||||
.into_iter()
|
||||
.flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
|
||||
|
||||
let direct_children = item_children_by_name(tcx, def_id, segment);
|
||||
|
||||
inherent_impl_children.chain(direct_children)
|
||||
})
|
||||
.collect();
|
||||
|
||||
resolutions
|
||||
}
|
||||
|
||||
pub fn get_local_trait_def_id(cx: &LateContext<'_>, path: &str) -> Option<DefId> {
|
||||
def_local_res(cx, path)
|
||||
.into_iter()
|
||||
.find_map(|res| match res {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, trait_id) => Some(trait_id),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Checks whether a type implements a trait.
|
||||
/// The function returns false in case the type contains an inference variable.
|
||||
///
|
||||
/// See:
|
||||
/// * [`get_trait_def_id`](super::get_trait_def_id) to get a trait [`DefId`].
|
||||
/// * [Common tools for writing lints] for an example how to use this function and other options.
|
||||
/// See [Common tools for writing lints] for an example how to use this function and other options.
|
||||
///
|
||||
/// [Common tools for writing lints]: https://github.com/rust-lang/rust-clippy/blob/master/book/src/development/common_tools_writing_lints.md#checking-if-a-type-implements-a-specific-trait
|
||||
pub fn implements_trait<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
trait_id: DefId,
|
||||
ty_params: &[GenericArg<'tcx>],
|
||||
args: &[GenericArg<'tcx>],
|
||||
) -> bool {
|
||||
implements_trait_with_env(
|
||||
implements_trait_with_env_from_iter(
|
||||
cx.tcx,
|
||||
cx.typing_env(),
|
||||
ty,
|
||||
trait_id,
|
||||
ty_params.iter().map(|&arg| Some(arg)),
|
||||
None,
|
||||
args.iter().map(|&x| Some(x)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
|
||||
pub fn implements_trait_with_env<'tcx>(
|
||||
/// Same as `implements_trait_from_env` but takes the arguments as an iterator.
|
||||
pub fn implements_trait_with_env_from_iter<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: TypingEnv<'tcx>,
|
||||
ty: ty::Ty<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
trait_id: DefId,
|
||||
ty_params: impl IntoIterator<Item = Option<GenericArg<'tcx>>>,
|
||||
callee_id: Option<DefId>,
|
||||
args: impl IntoIterator<Item = impl Into<Option<GenericArg<'tcx>>>>,
|
||||
) -> bool {
|
||||
// Clippy shouldn't have infer types
|
||||
assert!(!ty.has_infer());
|
||||
|
||||
// If a `callee_id` is passed, then we assert that it is a body owner
|
||||
// through calling `body_owner_kind`, which would panic if the callee
|
||||
// does not have a body.
|
||||
if let Some(callee_id) = callee_id {
|
||||
let _ = tcx.hir_body_owner_kind(callee_id);
|
||||
}
|
||||
|
||||
let ty = tcx.erase_regions(ty);
|
||||
if ty.has_escaping_bound_vars() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let ty_params = tcx.mk_args_from_iter(
|
||||
ty_params
|
||||
.into_iter()
|
||||
.map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into())),
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|arg| {
|
||||
arg.into()
|
||||
.unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let trait_ref = TraitRef::new(
|
||||
tcx,
|
||||
trait_id,
|
||||
[GenericArg::from(ty)].into_iter().chain(args),
|
||||
);
|
||||
|
||||
debug_assert!(
|
||||
matches!(tcx.def_kind(trait_id), DefKind::Trait | DefKind::TraitAlias),
|
||||
"`DefId` must belong to a trait or trait alias"
|
||||
);
|
||||
|
||||
let obligation = Obligation {
|
||||
cause: ObligationCause::dummy(),
|
||||
param_env,
|
||||
recursion_depth: 0,
|
||||
predicate: trait_ref.upcast(tcx),
|
||||
};
|
||||
infcx
|
||||
.type_implements_trait(
|
||||
trait_id,
|
||||
// for some unknown reason we need to have vec here
|
||||
// clippy has array
|
||||
vec![ty.into()].into_iter().chain(ty_params),
|
||||
param_env,
|
||||
)
|
||||
.must_apply_modulo_regions()
|
||||
.evaluate_obligation(&obligation)
|
||||
.is_ok_and(EvaluationResult::must_apply_modulo_regions)
|
||||
}
|
||||
|
|
|
@ -72,5 +72,5 @@ fn main() {
|
|||
// Pass cfg(crown) to rustc
|
||||
args.extend(["--cfg".to_owned(), "crown".to_owned()]);
|
||||
|
||||
rustc_driver::RunCompiler::new(&args, &mut MyCallbacks).run()
|
||||
rustc_driver::run_compiler(&args, &mut MyCallbacks)
|
||||
}
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
use rustc_ast::token::TokenKind;
|
||||
use rustc_ast::tokenstream::TokenTree;
|
||||
use rustc_error_messages::MultiSpan;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::{self as hir};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext, LintPass, LintStore};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::declare_tool_lint;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
use crate::common::{get_local_trait_def_id, get_trait_def_id, implements_trait};
|
||||
use crate::common::{find_first_crate, implements_trait, trait_in_crate};
|
||||
use crate::symbols;
|
||||
|
||||
declare_tool_lint! {
|
||||
|
@ -67,14 +68,11 @@ fn get_must_not_have_traceable(sym: &Symbols, attrs: &[hir::Attribute]) -> Optio
|
|||
attrs
|
||||
.iter()
|
||||
.find(|attr| {
|
||||
matches!(
|
||||
&attr.kind,
|
||||
hir::AttrKind::Normal(normal)
|
||||
if normal.path.segments.len() == 3 &&
|
||||
normal.path.segments[0].name == sym.crown &&
|
||||
normal.path.segments[1].name == sym.trace_in_no_trace_lint &&
|
||||
normal.path.segments[2].name == sym.must_not_have_traceable
|
||||
)
|
||||
attr.path_matches(&[
|
||||
sym.crown,
|
||||
sym.trace_in_no_trace_lint,
|
||||
sym.must_not_have_traceable,
|
||||
])
|
||||
})
|
||||
.map(|x| match &x.get_normal_item().args {
|
||||
hir::AttrArgs::Empty => 0,
|
||||
|
@ -98,13 +96,17 @@ fn get_must_not_have_traceable(sym: &Symbols, attrs: &[hir::Attribute]) -> Optio
|
|||
})
|
||||
}
|
||||
|
||||
fn is_jstraceable<'tcx>(cx: &LateContext<'tcx>, ty: ty::Ty<'tcx>) -> bool {
|
||||
// TODO(sagudev): get_trait_def_id is expensive, use lazy and cache it for whole pass
|
||||
if let Some(trait_id) = get_trait_def_id(cx, &["mozjs", "gc", "Traceable"]) {
|
||||
return implements_trait(cx, ty, trait_id, &[]);
|
||||
fn find_jstraceable<'tcx>(cx: &LateContext<'tcx>) -> Option<DefId> {
|
||||
// mozjs_sys::trace::Traceable
|
||||
if let Some(mozjs) = find_first_crate(&cx.tcx, Symbol::intern("mozjs_sys")) {
|
||||
return trait_in_crate(&cx.tcx, mozjs, Symbol::intern("Traceable"));
|
||||
}
|
||||
// when running tests
|
||||
if let Some(trait_id) = get_local_trait_def_id(cx, "JSTraceable") {
|
||||
trait_in_crate(&cx.tcx, LOCAL_CRATE, Symbol::intern("JSTraceable"))
|
||||
}
|
||||
|
||||
fn is_jstraceable<'tcx>(cx: &LateContext<'tcx>, ty: ty::Ty<'tcx>) -> bool {
|
||||
if let Some(trait_id) = find_jstraceable(cx) {
|
||||
return implements_trait(cx, ty, trait_id, &[]);
|
||||
}
|
||||
panic!("JSTraceable not found");
|
||||
|
@ -119,7 +121,7 @@ fn incorrect_no_trace<'tcx, I: Into<MultiSpan> + Copy>(
|
|||
) {
|
||||
let mut walker = ty.walk();
|
||||
while let Some(generic_arg) = walker.next() {
|
||||
let t = match generic_arg.unpack() {
|
||||
let t = match generic_arg.kind() {
|
||||
rustc_middle::ty::GenericArgKind::Type(t) => t,
|
||||
_ => {
|
||||
walker.skip_current_subtree();
|
||||
|
@ -168,8 +170,8 @@ impl<'tcx> LateLintPass<'tcx> for NotracePass {
|
|||
if has_lint_attr(&self.symbols, &attrs, self.symbols.must_root) {
|
||||
return;
|
||||
}*/
|
||||
if let hir::ItemKind::Struct(def, ..) = &item.kind {
|
||||
for field in def.fields() {
|
||||
if let hir::ItemKind::Struct(_, _, variant_data) = &item.kind {
|
||||
for field in variant_data.fields() {
|
||||
let field_type = cx.tcx.type_of(field.def_id);
|
||||
incorrect_no_trace(&self.symbols, cx, field_type.skip_binder(), field.span);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use rustc_hir::{self as hir, intravisit as visit, ExprKind};
|
||||
use rustc_hir::{self as hir, intravisit as visit, AmbigArg, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext, LintPass, LintStore};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::declare_tool_lint;
|
||||
|
@ -61,7 +61,7 @@ fn associated_type_has_attr<'tcx>(
|
|||
) -> bool {
|
||||
let mut walker = ty.walk();
|
||||
while let Some(generic_arg) = walker.next() {
|
||||
let t = match generic_arg.unpack() {
|
||||
let t = match generic_arg.kind() {
|
||||
rustc_middle::ty::GenericArgKind::Type(t) => t,
|
||||
_ => {
|
||||
walker.skip_current_subtree();
|
||||
|
@ -76,7 +76,7 @@ fn associated_type_has_attr<'tcx>(
|
|||
);
|
||||
},
|
||||
ty::Alias(
|
||||
ty::AliasTyKind::Projection | ty::AliasTyKind::Inherent | ty::AliasTyKind::Weak,
|
||||
ty::AliasTyKind::Projection | ty::AliasTyKind::Inherent | ty::AliasTyKind::Free,
|
||||
ty,
|
||||
) => {
|
||||
return cx.tcx.has_attrs_with_path(
|
||||
|
@ -100,7 +100,7 @@ fn is_unrooted_ty<'tcx>(
|
|||
let mut ret = false;
|
||||
let mut walker = ty.walk();
|
||||
while let Some(generic_arg) = walker.next() {
|
||||
let t = match generic_arg.unpack() {
|
||||
let t = match generic_arg.kind() {
|
||||
rustc_middle::ty::GenericArgKind::Type(t) => t,
|
||||
_ => {
|
||||
walker.skip_current_subtree();
|
||||
|
@ -126,7 +126,7 @@ fn is_unrooted_ty<'tcx>(
|
|||
ty::Alias(
|
||||
ty::AliasTyKind::Projection |
|
||||
ty::AliasTyKind::Inherent |
|
||||
ty::AliasTyKind::Weak,
|
||||
ty::AliasTyKind::Free,
|
||||
ty,
|
||||
) => !has_attr(ty.def_id, sym.allow_unrooted_in_rc),
|
||||
_ => true,
|
||||
|
@ -194,7 +194,7 @@ fn is_unrooted_ty<'tcx>(
|
|||
ty::Alias(
|
||||
kind @ ty::AliasTyKind::Projection |
|
||||
kind @ ty::AliasTyKind::Inherent |
|
||||
kind @ ty::AliasTyKind::Weak,
|
||||
kind @ ty::AliasTyKind::Free,
|
||||
ty,
|
||||
) => {
|
||||
if has_attr(ty.def_id, sym.must_root) {
|
||||
|
@ -242,8 +242,8 @@ impl<'tcx> LateLintPass<'tcx> for UnrootedPass {
|
|||
if has_attr(sym.must_root) || has_attr(sym.allow_unrooted_interior) {
|
||||
return;
|
||||
}
|
||||
if let hir::ItemKind::Struct(def, ..) = &item.kind {
|
||||
for field in def.fields() {
|
||||
if let hir::ItemKind::Struct(_, _, variant_data) = &item.kind {
|
||||
for field in variant_data.fields() {
|
||||
let field_type = cx.tcx.type_of(field.def_id);
|
||||
if is_unrooted_ty(&self.symbols, cx, field_type.skip_binder(), false) {
|
||||
cx.lint(UNROOTED_MUST_ROOT, |lint| {
|
||||
|
@ -261,8 +261,8 @@ impl<'tcx> LateLintPass<'tcx> for UnrootedPass {
|
|||
/// All enums containing #[crown::unrooted_must_root_lint::must_root] types
|
||||
/// must be #[crown::unrooted_must_root_lint::must_root] themselves
|
||||
fn check_variant(&mut self, cx: &LateContext, var: &hir::Variant) {
|
||||
let map = &cx.tcx.hir();
|
||||
let parent_item = map.expect_item(map.get_parent_item(var.hir_id).def_id);
|
||||
let parent = cx.tcx.hir_get_parent_item(var.hir_id).def_id;
|
||||
let parent_item = cx.tcx.hir_expect_item(parent);
|
||||
let sym = &self.symbols;
|
||||
if !cx.tcx.has_attrs_with_path(
|
||||
parent_item.hir_id().expect_owner(),
|
||||
|
@ -324,7 +324,7 @@ impl<'tcx> LateLintPass<'tcx> for UnrootedPass {
|
|||
let type_impl = cx
|
||||
.tcx
|
||||
.associated_items(impl_def_id)
|
||||
.find_by_name_and_kind(cx.tcx, trait_item.ident, ty::AssocKind::Type, trait_id)
|
||||
.find_by_ident_and_kind(cx.tcx, trait_item.ident, ty::AssocTag::Type, trait_id)
|
||||
.unwrap();
|
||||
|
||||
let mir_ty = cx.tcx.type_of(type_impl.def_id).skip_binder();
|
||||
|
@ -440,7 +440,14 @@ struct FnDefVisitor<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'tcx> {
|
||||
type Map = rustc_middle::hir::map::Map<'tcx>;
|
||||
// TODO: https://github.com/servo/servo/issues/37330
|
||||
/*
|
||||
type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
|
||||
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
||||
self.cx.tcx
|
||||
}
|
||||
*/
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
let cx = self.cx;
|
||||
|
@ -504,11 +511,7 @@ impl<'a, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'tcx> {
|
|||
visit::walk_pat(self, pat);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, _: &'tcx hir::Ty) {}
|
||||
|
||||
fn nested_visit_map(&mut self) -> Self::Map {
|
||||
self.cx.tcx.hir()
|
||||
}
|
||||
fn visit_ty(&mut self, _: &'tcx rustc_hir::Ty<'tcx, AmbigArg>) {}
|
||||
}
|
||||
|
||||
symbols! {
|
||||
|
|
|
@ -43,7 +43,7 @@ fn run_mode(mode: &'static str, bless: bool) {
|
|||
|
||||
#[test]
|
||||
fn compile_test() {
|
||||
let bless = env::var("BLESS").map_or(false, |x| !x.trim().is_empty());
|
||||
let bless = env::var("BLESS").is_ok_and(|x| !x.trim().is_empty());
|
||||
run_mode("compile-fail", bless);
|
||||
run_mode("run-pass", bless);
|
||||
// UI test fails on windows
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue