rustc: Panic by default in DefIdTree::parent

Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root.
So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root.

Same applies to `local_parent`/`opt_local_parent`.
This commit is contained in:
Vadim Petrochenkov 2022-04-25 22:08:45 +03:00
parent defc537a2e
commit 8172166f34
6 changed files with 9 additions and 9 deletions

View file

@ -193,7 +193,7 @@ fn find_sugg_for_if_let<'tcx>(
PatKind::TupleStruct(ref qpath, [sub_pat], _) => { PatKind::TupleStruct(ref qpath, [sub_pat], _) => {
if let PatKind::Wild = sub_pat.kind { if let PatKind::Wild = sub_pat.kind {
let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id); let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id);
let Some(id) = res.opt_def_id().and_then(|ctor_id| cx.tcx.parent(ctor_id)) else { return }; let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else { return };
let lang_items = cx.tcx.lang_items(); let lang_items = cx.tcx.lang_items();
if Some(id) == lang_items.result_ok_variant() { if Some(id) == lang_items.result_ok_variant() {
("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty)) ("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty))

View file

@ -42,7 +42,7 @@ pub(crate) trait BindInsteadOfMap {
fn no_op_msg(cx: &LateContext<'_>) -> Option<String> { fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?; let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
let item_id = cx.tcx.parent(variant_id)?; let item_id = cx.tcx.parent(variant_id);
Some(format!( Some(format!(
"using `{}.{}({})`, which is a no-op", "using `{}.{}({})`, which is a no-op",
cx.tcx.item_name(item_id), cx.tcx.item_name(item_id),
@ -53,7 +53,7 @@ pub(crate) trait BindInsteadOfMap {
fn lint_msg(cx: &LateContext<'_>) -> Option<String> { fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?; let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
let item_id = cx.tcx.parent(variant_id)?; let item_id = cx.tcx.parent(variant_id);
Some(format!( Some(format!(
"using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`", "using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
cx.tcx.item_name(item_id), cx.tcx.item_name(item_id),
@ -145,7 +145,7 @@ pub(crate) trait BindInsteadOfMap {
if_chain! { if_chain! {
if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def(); if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM); if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
if Some(adt.did()) == cx.tcx.parent(vid); if adt.did() == cx.tcx.parent(vid);
then {} else { return false; } then {} else { return false; }
} }
@ -182,7 +182,7 @@ pub(crate) trait BindInsteadOfMap {
fn is_variant(cx: &LateContext<'_>, res: Res) -> bool { fn is_variant(cx: &LateContext<'_>, res: Res) -> bool {
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res { if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) { if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) {
return cx.tcx.parent(id) == Some(variant_id); return cx.tcx.parent(id) == variant_id;
} }
} }
false false

View file

@ -19,7 +19,7 @@ pub(super) fn check(
if_chain! { if_chain! {
if let Some(args) = method_chain_args(info.chain, chain_methods); if let Some(args) = method_chain_args(info.chain, chain_methods);
if let hir::ExprKind::Call(fun, [arg_char]) = info.other.kind; if let hir::ExprKind::Call(fun, [arg_char]) = info.other.kind;
if let Some(id) = path_def_id(cx, fun).and_then(|ctor_id| cx.tcx.parent(ctor_id)); if let Some(id) = path_def_id(cx, fun).map(|ctor_id| cx.tcx.parent(ctor_id));
if Some(id) == cx.tcx.lang_items().option_some_variant(); if Some(id) == cx.tcx.lang_items().option_some_variant();
then { then {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;

View file

@ -75,7 +75,7 @@ pub(super) fn check<'tcx>(
let arg_snippet = snippet(cx, span, ".."); let arg_snippet = snippet(cx, span, "..");
let body = cx.tcx.hir().body(id); let body = cx.tcx.hir().body(id);
if let Some((func, [arg_char])) = reduce_unit_expression(&body.value); if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);
if let Some(id) = path_def_id(cx, func).and_then(|ctor_id| cx.tcx.parent(ctor_id)); if let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id));
if Some(id) == cx.tcx.lang_items().option_some_variant(); if Some(id) == cx.tcx.lang_items().option_some_variant();
then { then {
let func_snippet = snippet(cx, arg_char.span, ".."); let func_snippet = snippet(cx, arg_char.span, "..");

View file

@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
hir::ItemKind::Fn(..) => { hir::ItemKind::Fn(..) => {
// ignore main() // ignore main()
if it.ident.name == sym::main { if it.ident.name == sym::main {
let at_root = cx.tcx.local_parent(it.def_id) == Some(CRATE_DEF_ID); let at_root = cx.tcx.local_parent(it.def_id) == CRATE_DEF_ID;
if at_root { if at_root {
return; return;
} }

View file

@ -235,7 +235,7 @@ pub fn is_lang_ctor(cx: &LateContext<'_>, qpath: &QPath<'_>, lang_item: LangItem
if let QPath::Resolved(_, path) = qpath { if let QPath::Resolved(_, path) = qpath {
if let Res::Def(DefKind::Ctor(..), ctor_id) = path.res { if let Res::Def(DefKind::Ctor(..), ctor_id) = path.res {
if let Ok(item_id) = cx.tcx.lang_items().require(lang_item) { if let Ok(item_id) = cx.tcx.lang_items().require(lang_item) {
return cx.tcx.parent(ctor_id) == Some(item_id); return cx.tcx.parent(ctor_id) == item_id;
} }
} }
} }