diff options
| author | Maybe Waffle <waffle.lapkin@gmail.com> | 2023-01-30 05:50:06 +0000 |
|---|---|---|
| committer | Maybe Waffle <waffle.lapkin@gmail.com> | 2023-01-30 05:50:06 +0000 |
| commit | a4aebf030e32d67e72db8b52be74fb6223a3006f (patch) | |
| tree | 3ebada40eab63ff791e1976d44c5cda7152cd2ab | |
| parent | 70f9d520793318617949e660458bd717548ec8d6 (diff) | |
| download | rust-a4aebf030e32d67e72db8b52be74fb6223a3006f.tar.gz rust-a4aebf030e32d67e72db8b52be74fb6223a3006f.zip | |
Improve ICE messages for `*::expect_*`
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 118 |
1 files changed, 69 insertions, 49 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4640317ac73..ef4a8754ac2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2277,23 +2277,28 @@ impl<'hir> TraitItem<'hir> { /// Expect an [`TraitItemKind::Const`] or panic. #[track_caller] pub fn expect_const(&self) -> (&'hir Ty<'hir>, Option<BodyId>) { - let TraitItemKind::Const(ty, body) = self.kind else { unreachable!() }; + let TraitItemKind::Const(ty, body) = self.kind else { self.expect_failed("a constant") }; (ty, body) } /// Expect an [`TraitItemKind::Fn`] or panic. #[track_caller] pub fn expect_fn(&self) -> (&FnSig<'hir>, &TraitFn<'hir>) { - let TraitItemKind::Fn(ty, trfn) = &self.kind else { unreachable!() }; + let TraitItemKind::Fn(ty, trfn) = &self.kind else { self.expect_failed("a function") }; (ty, trfn) } /// Expect an [`TraitItemKind::ExternCrate`] or panic. #[track_caller] pub fn expect_type(&self) -> (GenericBounds<'hir>, Option<&'hir Ty<'hir>>) { - let TraitItemKind::Type(bounds, ty) = self.kind else { unreachable!() }; + let TraitItemKind::Type(bounds, ty) = self.kind else { self.expect_failed("a type") }; (bounds, ty) } + + #[track_caller] + fn expect_failed(&self, expected: &'static str) -> ! { + panic!("expected {expected} item, found {self:?}") + } } /// Represents a trait method's body (or just argument names). @@ -2360,23 +2365,28 @@ impl<'hir> ImplItem<'hir> { /// Expect an [`ImplItemKind::Const`] or panic. #[track_caller] pub fn expect_const(&self) -> (&'hir Ty<'hir>, BodyId) { - let ImplItemKind::Const(ty, body) = self.kind else { unreachable!() }; + let ImplItemKind::Const(ty, body) = self.kind else { self.expect_failed("a constant") }; (ty, body) } /// Expect an [`ImplItemKind::Fn`] or panic. #[track_caller] pub fn expect_fn(&self) -> (&FnSig<'hir>, BodyId) { - let ImplItemKind::Fn(ty, body) = &self.kind else { unreachable!() }; + let ImplItemKind::Fn(ty, body) = &self.kind else { self.expect_failed("a function") }; (ty, *body) } - /// Expect an [`ImplItemKind::ExternCrate`] or panic. + /// Expect an [`ImplItemKind::Type`] or panic. #[track_caller] pub fn expect_type(&self) -> &'hir Ty<'hir> { - let ImplItemKind::Type(ty) = self.kind else { unreachable!() }; + let ImplItemKind::Type(ty) = self.kind else { self.expect_failed("a type") }; ty } + + #[track_caller] + fn expect_failed(&self, expected: &'static str) -> ! { + panic!("expected {expected} item, found {self:?}") + } } /// Represents various kinds of content within an `impl`. @@ -3051,68 +3061,68 @@ impl<'hir> Item<'hir> { /// Expect an [`ItemKind::ExternCrate`] or panic. #[track_caller] pub fn expect_extern_crate(&self) -> Option<Symbol> { - let ItemKind::ExternCrate(s) = self.kind else { unreachable!() }; + let ItemKind::ExternCrate(s) = self.kind else { self.expect_failed("an extern crate") }; s } /// Expect an [`ItemKind::Use`] or panic. #[track_caller] pub fn expect_use(&self) -> (&'hir UsePath<'hir>, UseKind) { - let ItemKind::Use(p, uk) = self.kind else { unreachable!() }; + let ItemKind::Use(p, uk) = self.kind else { self.expect_failed("a use") }; (p, uk) } /// Expect an [`ItemKind::Static`] or panic. #[track_caller] pub fn expect_static(&self) -> (&'hir Ty<'hir>, Mutability, BodyId) { - let ItemKind::Static(ty, mutbl, body) = self.kind else { unreachable!() }; + let ItemKind::Static(ty, mutbl, body) = self.kind else { self.expect_failed("a static") }; (ty, mutbl, body) } /// Expect an [`ItemKind::Const`] or panic. #[track_caller] pub fn expect_const(&self) -> (&'hir Ty<'hir>, BodyId) { - let ItemKind::Const(ty, body) = self.kind else { unreachable!() }; + let ItemKind::Const(ty, body) = self.kind else { self.expect_failed("a constant") }; (ty, body) } /// Expect an [`ItemKind::Fn`] or panic. #[track_caller] pub fn expect_fn(&self) -> (&FnSig<'hir>, &'hir Generics<'hir>, BodyId) { - let ItemKind::Fn(sig, gen, body) = &self.kind else { unreachable!() }; + let ItemKind::Fn(sig, gen, body) = &self.kind else { self.expect_failed("a function") }; (sig, gen, *body) } /// Expect an [`ItemKind::Macro`] or panic. #[track_caller] pub fn expect_macro(&self) -> (&ast::MacroDef, MacroKind) { - let ItemKind::Macro(def, mk) = &self.kind else { unreachable!() }; + let ItemKind::Macro(def, mk) = &self.kind else { self.expect_failed("a macro") }; (def, *mk) } /// Expect an [`ItemKind::Mod`] or panic. #[track_caller] pub fn expect_mod(&self) -> &'hir Mod<'hir> { - let ItemKind::Mod(m) = self.kind else { unreachable!() }; + let ItemKind::Mod(m) = self.kind else { self.expect_failed("a module") }; m } /// Expect an [`ItemKind::ForeignMod`] or panic. #[track_caller] pub fn expect_foreign_mod(&self) -> (Abi, &'hir [ForeignItemRef]) { - let ItemKind::ForeignMod { abi, items } = self.kind else { unreachable!() }; + let ItemKind::ForeignMod { abi, items } = self.kind else { self.expect_failed("a foreign module") }; (abi, items) } /// Expect an [`ItemKind::GlobalAsm`] or panic. #[track_caller] pub fn expect_global_asm(&self) -> &'hir InlineAsm<'hir> { - let ItemKind::GlobalAsm(asm) = self.kind else { unreachable!() }; + let ItemKind::GlobalAsm(asm) = self.kind else { self.expect_failed("a global asm") }; asm } /// Expect an [`ItemKind::TyAlias`] or panic. #[track_caller] pub fn expect_ty_alias(&self) -> (&'hir Ty<'hir>, &'hir Generics<'hir>) { - let ItemKind::TyAlias(ty, gen) = self.kind else { unreachable!() }; + let ItemKind::TyAlias(ty, gen) = self.kind else { self.expect_failed("a type alias") }; (ty, gen) } @@ -3120,21 +3130,21 @@ impl<'hir> Item<'hir> { /// Expect an [`ItemKind::OpaqueTy`] or panic. #[track_caller] pub fn expect_opaque_ty(&self) -> &OpaqueTy<'hir> { - let ItemKind::OpaqueTy(ty) = &self.kind else { unreachable!() }; + let ItemKind::OpaqueTy(ty) = &self.kind else { self.expect_failed("an opaque type") }; ty } /// Expect an [`ItemKind::Enum`] or panic. #[track_caller] pub fn expect_enum(&self) -> (&EnumDef<'hir>, &'hir Generics<'hir>) { - let ItemKind::Enum(def, gen) = &self.kind else { unreachable!() }; + let ItemKind::Enum(def, gen) = &self.kind else { self.expect_failed("an enum") }; (def, gen) } /// Expect an [`ItemKind::Struct`] or panic. #[track_caller] pub fn expect_struct(&self) -> (&VariantData<'hir>, &'hir Generics<'hir>) { - let ItemKind::Struct(data, gen) = &self.kind else { unreachable!() }; + let ItemKind::Struct(data, gen) = &self.kind else { self.expect_failed("a struct") }; (data, gen) } @@ -3142,7 +3152,7 @@ impl<'hir> Item<'hir> { /// Expect an [`ItemKind::Union`] or panic. #[track_caller] pub fn expect_union(&self) -> (&VariantData<'hir>, &'hir Generics<'hir>) { - let ItemKind::Union(data, gen) = &self.kind else { unreachable!() }; + let ItemKind::Union(data, gen) = &self.kind else { self.expect_failed("a union") }; (data, gen) } @@ -3151,23 +3161,28 @@ impl<'hir> Item<'hir> { pub fn expect_trait( self, ) -> (IsAuto, Unsafety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]) { - let ItemKind::Trait(is_auto, unsafety, gen, bounds, items) = self.kind else { unreachable!() }; + let ItemKind::Trait(is_auto, unsafety, gen, bounds, items) = self.kind else { self.expect_failed("a trait") }; (is_auto, unsafety, gen, bounds, items) } /// Expect an [`ItemKind::TraitAlias`] or panic. #[track_caller] pub fn expect_trait_alias(&self) -> (&'hir Generics<'hir>, GenericBounds<'hir>) { - let ItemKind::TraitAlias(gen, bounds) = self.kind else { unreachable!() }; + let ItemKind::TraitAlias(gen, bounds) = self.kind else { self.expect_failed("a trait alias") }; (gen, bounds) } /// Expect an [`ItemKind::Impl`] or panic. #[track_caller] pub fn expect_impl(&self) -> &'hir Impl<'hir> { - let ItemKind::Impl(imp) = self.kind else { unreachable!() }; + let ItemKind::Impl(imp) = self.kind else { self.expect_failed("an impl") }; imp } + + #[track_caller] + fn expect_failed(&self, expected: &'static str) -> ! { + panic!("expected {expected} item, found {self:?}") + } } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] @@ -3757,176 +3772,181 @@ impl<'hir> Node<'hir> { /// Expect a [`Node::Param`] or panic. #[track_caller] pub fn expect_param(self) -> &'hir Param<'hir> { - let Node::Param(this) = self else { unreachable!() }; + let Node::Param(this) = self else { self.expect_failed("a parameter") }; this } /// Expect a [`Node::Item`] or panic. #[track_caller] pub fn expect_item(self) -> &'hir Item<'hir> { - let Node::Item(this) = self else { unreachable!() }; + let Node::Item(this) = self else { self.expect_failed("a item") }; this } /// Expect a [`Node::ForeignItem`] or panic. #[track_caller] pub fn expect_foreign_item(self) -> &'hir ForeignItem<'hir> { - let Node::ForeignItem(this) = self else { unreachable!() }; + let Node::ForeignItem(this) = self else { self.expect_failed("a foreign item") }; this } /// Expect a [`Node::TraitItem`] or panic. #[track_caller] pub fn expect_trait_item(self) -> &'hir TraitItem<'hir> { - let Node::TraitItem(this) = self else { unreachable!() }; + let Node::TraitItem(this) = self else { self.expect_failed("a trait item") }; this } /// Expect a [`Node::ImplItem`] or panic. #[track_caller] pub fn expect_impl_item(self) -> &'hir ImplItem<'hir> { - let Node::ImplItem(this) = self else { unreachable!() }; + let Node::ImplItem(this) = self else { self.expect_failed("an implementation item") }; this } /// Expect a [`Node::Variant`] or panic. #[track_caller] pub fn expect_variant(self) -> &'hir Variant<'hir> { - let Node::Variant(this) = self else { unreachable!() }; + let Node::Variant(this) = self else { self.expect_failed("a variant") }; this } /// Expect a [`Node::Field`] or panic. #[track_caller] pub fn expect_field(self) -> &'hir FieldDef<'hir> { - let Node::Field(this) = self else { unreachable!() }; + let Node::Field(this) = self else { self.expect_failed("a field definition") }; this } /// Expect a [`Node::AnonConst`] or panic. #[track_caller] pub fn expect_anon_const(self) -> &'hir AnonConst { - let Node::AnonConst(this) = self else { unreachable!() }; + let Node::AnonConst(this) = self else { self.expect_failed("an anonymous constant") }; this } /// Expect a [`Node::Expr`] or panic. #[track_caller] pub fn expect_expr(self) -> &'hir Expr<'hir> { - let Node::Expr(this) = self else { unreachable!() }; + let Node::Expr(this) = self else { self.expect_failed("an expression") }; this } /// Expect a [`Node::ExprField`] or panic. #[track_caller] pub fn expect_expr_field(self) -> &'hir ExprField<'hir> { - let Node::ExprField(this) = self else { unreachable!() }; + let Node::ExprField(this) = self else { self.expect_failed("an expression field") }; this } /// Expect a [`Node::Stmt`] or panic. #[track_caller] pub fn expect_stmt(self) -> &'hir Stmt<'hir> { - let Node::Stmt(this) = self else { unreachable!() }; + let Node::Stmt(this) = self else { self.expect_failed("a statement") }; this } /// Expect a [`Node::PathSegment`] or panic. #[track_caller] pub fn expect_path_segment(self) -> &'hir PathSegment<'hir> { - let Node::PathSegment(this) = self else { unreachable!() }; + let Node::PathSegment(this) = self else { self.expect_failed("a path segment") }; this } /// Expect a [`Node::Ty`] or panic. #[track_caller] pub fn expect_ty(self) -> &'hir Ty<'hir> { - let Node::Ty(this) = self else { unreachable!() }; + let Node::Ty(this) = self else { self.expect_failed("a type") }; this } /// Expect a [`Node::TypeBinding`] or panic. #[track_caller] pub fn expect_type_binding(self) -> &'hir TypeBinding<'hir> { - let Node::TypeBinding(this) = self else { unreachable!() }; + let Node::TypeBinding(this) = self else { self.expect_failed("a type binding") }; this } /// Expect a [`Node::TraitRef`] or panic. #[track_caller] pub fn expect_trait_ref(self) -> &'hir TraitRef<'hir> { - let Node::TraitRef(this) = self else { unreachable!() }; + let Node::TraitRef(this) = self else { self.expect_failed("a trait reference") }; this } /// Expect a [`Node::Pat`] or panic. #[track_caller] pub fn expect_pat(self) -> &'hir Pat<'hir> { - let Node::Pat(this) = self else { unreachable!() }; + let Node::Pat(this) = self else { self.expect_failed("a pattern") }; this } /// Expect a [`Node::PatField`] or panic. #[track_caller] pub fn expect_pat_field(self) -> &'hir PatField<'hir> { - let Node::PatField(this) = self else { unreachable!() }; + let Node::PatField(this) = self else { self.expect_failed("a pattern field") }; this } /// Expect a [`Node::Arm`] or panic. #[track_caller] pub fn expect_arm(self) -> &'hir Arm<'hir> { - let Node::Arm(this) = self else { unreachable!() }; + let Node::Arm(this) = self else { self.expect_failed("an arm") }; this } /// Expect a [`Node::Block`] or panic. #[track_caller] pub fn expect_block(self) -> &'hir Block<'hir> { - let Node::Block(this) = self else { unreachable!() }; + let Node::Block(this) = self else { self.expect_failed("a block") }; this } /// Expect a [`Node::Local`] or panic. #[track_caller] pub fn expect_local(self) -> &'hir Local<'hir> { - let Node::Local(this) = self else { unreachable!() }; + let Node::Local(this) = self else { self.expect_failed("a local") }; this } /// Expect a [`Node::Ctor`] or panic. #[track_caller] pub fn expect_ctor(self) -> &'hir VariantData<'hir> { - let Node::Ctor(this) = self else { unreachable!() }; + let Node::Ctor(this) = self else { self.expect_failed("a constructor") }; this } /// Expect a [`Node::Lifetime`] or panic. #[track_caller] pub fn expect_lifetime(self) -> &'hir Lifetime { - let Node::Lifetime(this) = self else { unreachable!() }; + let Node::Lifetime(this) = self else { self.expect_failed("a lifetime") }; this } /// Expect a [`Node::GenericParam`] or panic. #[track_caller] pub fn expect_generic_param(self) -> &'hir GenericParam<'hir> { - let Node::GenericParam(this) = self else { unreachable!() }; + let Node::GenericParam(this) = self else { self.expect_failed("a generic parameter") }; this } /// Expect a [`Node::Crate`] or panic. #[track_caller] pub fn expect_crate(self) -> &'hir Mod<'hir> { - let Node::Crate(this) = self else { unreachable!() }; + let Node::Crate(this) = self else { self.expect_failed("a crate") }; this } /// Expect a [`Node::Infer`] or panic. #[track_caller] pub fn expect_infer(self) -> &'hir InferArg { - let Node::Infer(this) = self else { unreachable!() }; + let Node::Infer(this) = self else { self.expect_failed("an infer") }; this } + + #[track_caller] + fn expect_failed(&self, expected: &'static str) -> ! { + panic!("expected {expected} node, found {self:?}") + } } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. |
