From 70b9dad3dc3cf756bc6aeeeda75d08954487c303 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 15 Dec 2023 03:19:46 +0000 Subject: [PATCH 1/2] Annotate some bugs --- compiler/rustc_hir/src/hir.rs | 2 +- .../rustc_hir_analysis/src/astconv/mod.rs | 22 ++- .../src/astconv/object_safety.rs | 2 +- .../src/check/compare_impl_item.rs | 177 +++++++++--------- .../src/check/compare_impl_item/refine.rs | 7 +- .../src/check/intrinsicck.rs | 17 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 41 ++-- compiler/rustc_hir_analysis/src/collect.rs | 4 +- .../src/collect/item_bounds.rs | 8 +- .../src/collect/predicates_of.rs | 7 +- .../src/collect/resolve_bound_vars.rs | 14 +- .../rustc_hir_analysis/src/collect/type_of.rs | 8 +- compiler/rustc_hir_pretty/src/lib.rs | 28 ++- compiler/rustc_hir_typeck/src/cast.rs | 12 +- compiler/rustc_hir_typeck/src/coercion.rs | 6 +- compiler/rustc_hir_typeck/src/demand.rs | 10 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 4 +- .../src/fn_ctxt/suggestions.rs | 3 +- .../rustc_hir_typeck/src/method/confirm.rs | 4 +- compiler/rustc_hir_typeck/src/pat.rs | 6 +- compiler/rustc_infer/src/infer/combine.rs | 22 ++- .../infer/error_reporting/need_type_info.rs | 4 +- .../src/infer/error_reporting/note.rs | 4 +- .../rustc_infer/src/infer/nll_relate/mod.rs | 8 +- .../src/infer/outlives/components.rs | 4 +- .../src/solve/normalizes_to/mod.rs | 6 +- .../src/solve/trait_goals.rs | 5 +- .../src/traits/coherence.rs | 6 +- .../error_reporting/type_err_ctxt_ext.rs | 7 +- .../src/traits/project.rs | 40 ++-- .../src/traits/query/normalize.rs | 2 +- .../query/type_op/implied_outlives_bounds.rs | 4 +- .../src/traits/select/confirmation.rs | 8 +- 34 files changed, 301 insertions(+), 203 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 01508375b1ace..5c252c3f9f2ce 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2815,7 +2815,7 @@ impl TraitRef<'_> { match self.path.res { Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did), Res::Err => None, - _ => unreachable!(), + res => panic!("{res:?} did not resolve to a trait or trait alias"), } } } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index caae6fa4f065e..2ae9f87f296ba 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -477,7 +477,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Const::new_misc_error(tcx, ty).into() } } - _ => unreachable!(), + (kind, arg) => span_bug!( + self.span, + "mismatched path argument for kind {kind:?}: found arg {arg:?}" + ), } } @@ -1946,7 +1949,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "s", ), [only] => (only.to_string(), ""), - [] => unreachable!(), + [] => unreachable!("expected at least one generic to prohibit"), }; let last_span = *arg_spans.last().unwrap(); let span: MultiSpan = arg_spans.into(); @@ -2555,8 +2558,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len()) { // Resolve our own lifetime parameters. - let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() }; - let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() }; + let GenericParamDefKind::Lifetime { .. } = param.kind else { + span_bug!( + tcx.def_span(param.def_id), + "only expected lifetime for opaque's own generics, got {:?}", + param.kind + ); + }; + let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { + bug!( + "expected lifetime argument for param {param:?}, found {:?}", + &lifetimes[i] + ) + }; self.ast_region_to_region(lifetime, None).into() } else { tcx.mk_param_from_def(param) diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index ce5426b51427f..dd5deb6f24455 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -73,7 +73,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) | ty::ClauseKind::ConstEvaluatable(_) => { - bug!() + span_bug!(span, "did not expect {pred} clause in object bounds"); } } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 00302ec831cef..4705d9350b0a3 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1086,8 +1086,14 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { _ => return Ok(region), } - let e = if let Some(region) = self.map.get(®ion) { - if let ty::ReEarlyParam(e) = region.kind() { e } else { bug!() } + let e = if let Some(id_region) = self.map.get(®ion) { + if let ty::ReEarlyParam(e) = id_region.kind() { + e + } else { + bug!( + "expected to map region {region} to early-bound identity region, but got {id_region}" + ); + } } else { let guar = match region.kind() { ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) @@ -1710,92 +1716,87 @@ fn compare_synthetic_generics<'tcx>( trait_m.name ); err.span_label(trait_span, "declaration in trait here"); - match (impl_synthetic, trait_synthetic) { + if impl_synthetic { // The case where the impl method uses `impl Trait` but the trait method uses // explicit generics - (true, false) => { - err.span_label(impl_span, "expected generic parameter, found `impl Trait`"); - let _: Option<_> = try { - // try taking the name from the trait impl - // FIXME: this is obviously suboptimal since the name can already be used - // as another generic argument - let new_name = tcx.opt_item_name(trait_def_id)?; - let trait_m = trait_m.def_id.as_local()?; - let trait_m = tcx.hir().expect_trait_item(trait_m); - - let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); - - // in case there are no generics, take the spot between the function name - // and the opening paren of the argument list - let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi(); - // in case there are generics, just replace them - let generics_span = - impl_m.generics.span.substitute_dummy(new_generics_span); - // replace with the generics from the trait - let new_generics = - tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?; - - err.multipart_suggestion( - "try changing the `impl Trait` argument to a generic parameter", - vec![ - // replace `impl Trait` with `T` - (impl_span, new_name.to_string()), - // replace impl method generics with trait method generics - // This isn't quite right, as users might have changed the names - // of the generics, but it works for the common case - (generics_span, new_generics), - ], - Applicability::MaybeIncorrect, - ); - }; - } + err.span_label(impl_span, "expected generic parameter, found `impl Trait`"); + let _: Option<_> = try { + // try taking the name from the trait impl + // FIXME: this is obviously suboptimal since the name can already be used + // as another generic argument + let new_name = tcx.opt_item_name(trait_def_id)?; + let trait_m = trait_m.def_id.as_local()?; + let trait_m = tcx.hir().expect_trait_item(trait_m); + + let impl_m = impl_m.def_id.as_local()?; + let impl_m = tcx.hir().expect_impl_item(impl_m); + + // in case there are no generics, take the spot between the function name + // and the opening paren of the argument list + let new_generics_span = tcx.def_ident_span(impl_def_id)?.shrink_to_hi(); + // in case there are generics, just replace them + let generics_span = impl_m.generics.span.substitute_dummy(new_generics_span); + // replace with the generics from the trait + let new_generics = + tcx.sess.source_map().span_to_snippet(trait_m.generics.span).ok()?; + + err.multipart_suggestion( + "try changing the `impl Trait` argument to a generic parameter", + vec![ + // replace `impl Trait` with `T` + (impl_span, new_name.to_string()), + // replace impl method generics with trait method generics + // This isn't quite right, as users might have changed the names + // of the generics, but it works for the common case + (generics_span, new_generics), + ], + Applicability::MaybeIncorrect, + ); + }; + } else { // The case where the trait method uses `impl Trait`, but the impl method uses // explicit generics. - (false, true) => { - err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); - let _: Option<_> = try { - let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); - let (sig, _) = impl_m.expect_fn(); - let input_tys = sig.decl.inputs; - - struct Visitor(Option, hir::def_id::LocalDefId); - impl<'v> intravisit::Visitor<'v> for Visitor { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - intravisit::walk_ty(self, ty); - if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind - && let Res::Def(DefKind::TyParam, def_id) = path.res - && def_id == self.1.to_def_id() - { - self.0 = Some(ty.span); - } + err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); + let _: Option<_> = try { + let impl_m = impl_m.def_id.as_local()?; + let impl_m = tcx.hir().expect_impl_item(impl_m); + let (sig, _) = impl_m.expect_fn(); + let input_tys = sig.decl.inputs; + + struct Visitor(Option, hir::def_id::LocalDefId); + impl<'v> intravisit::Visitor<'v> for Visitor { + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { + intravisit::walk_ty(self, ty); + if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = ty.kind + && let Res::Def(DefKind::TyParam, def_id) = path.res + && def_id == self.1.to_def_id() + { + self.0 = Some(ty.span); } } + } - let mut visitor = Visitor(None, impl_def_id); - for ty in input_tys { - intravisit::Visitor::visit_ty(&mut visitor, ty); - } - let span = visitor.0?; - - let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds; - let bounds = bounds.first()?.span().to(bounds.last()?.span()); - let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?; - - err.multipart_suggestion( - "try removing the generic parameter and using `impl Trait` instead", - vec![ - // delete generic parameters - (impl_m.generics.span, String::new()), - // replace param usage with `impl Trait` - (span, format!("impl {bounds}")), - ], - Applicability::MaybeIncorrect, - ); - }; - } - _ => unreachable!(), + let mut visitor = Visitor(None, impl_def_id); + for ty in input_tys { + intravisit::Visitor::visit_ty(&mut visitor, ty); + } + let span = visitor.0?; + + let bounds = impl_m.generics.bounds_for_param(impl_def_id).next()?.bounds; + let bounds = bounds.first()?.span().to(bounds.last()?.span()); + let bounds = tcx.sess.source_map().span_to_snippet(bounds).ok()?; + + err.multipart_suggestion( + "try removing the generic parameter and using `impl Trait` instead", + vec![ + // delete generic parameters + (impl_m.generics.span, String::new()), + // replace param usage with `impl Trait` + (span, format!("impl {bounds}")), + ], + Applicability::MaybeIncorrect, + ); + }; } error_found = Some(err.emit_unless(delay)); } @@ -1859,7 +1860,9 @@ fn compare_generic_param_kinds<'tcx>( // this is exhaustive so that anyone adding new generic param kinds knows // to make sure this error is reported for them. (Const { .. }, Const { .. }) | (Type { .. }, Type { .. }) => false, - (Lifetime { .. }, _) | (_, Lifetime { .. }) => unreachable!(), + (Lifetime { .. }, _) | (_, Lifetime { .. }) => { + bug!("lifetime params are expected to be filtered by `ty_const_params_of`") + } } { let param_impl_span = tcx.def_span(param_impl.def_id); let param_trait_span = tcx.def_span(param_trait.def_id); @@ -1883,7 +1886,10 @@ fn compare_generic_param_kinds<'tcx>( ) } Type { .. } => format!("{prefix} type parameter"), - Lifetime { .. } => unreachable!(), + Lifetime { .. } => span_bug!( + tcx.def_span(param.def_id), + "lifetime params are expected to be filtered by `ty_const_params_of`" + ), }; let trait_header_span = tcx.def_ident_span(tcx.parent(trait_item.def_id)).unwrap(); @@ -2187,7 +2193,10 @@ pub(super) fn check_type_bounds<'tcx>( .. }) => ty.span, hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span, - _ => bug!(), + item => span_bug!( + tcx.def_span(impl_ty_def_id), + "cannot call `check_type_bounds` on item: {item:?}", + ), } }; let assumed_wf_types = ocx.assumed_wf_types_and_report_errors(param_env, impl_ty_def_id)?; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index f866543dd0d63..67796855ece85 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -262,7 +262,10 @@ fn report_mismatched_rpitit_signature<'tcx>( if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() { let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else { - bug!(); + span_bug!( + tcx.def_span(trait_m_def_id), + "expected return type of async fn in trait to be a AFIT projection" + ); }; let Some(future_output_ty) = tcx .explicit_item_bounds(future_ty.def_id) @@ -272,7 +275,7 @@ fn report_mismatched_rpitit_signature<'tcx>( _ => None, }) else { - bug!() + span_bug!(tcx.def_span(trait_m_def_id), "expected `Future` projection bound in AFIT"); }; return_ty = future_output_ty; } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 2428fe6ae790a..7c9624206e539 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -49,7 +49,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, 64 => InlineAsmType::I64, - _ => unreachable!(), + width => bug!("unsupported pointer width: {width}"), }; match *ty.kind() { @@ -101,7 +101,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { 16 => InlineAsmType::VecI16(size), 32 => InlineAsmType::VecI32(size), 64 => InlineAsmType::VecI64(size), - _ => unreachable!(), + width => bug!("unsupported pointer width: {width}"), }) } ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)), @@ -109,7 +109,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { _ => None, } } - ty::Infer(_) => unreachable!(), + ty::Infer(_) => bug!("unexpected infer ty in asm operand"), _ => None, } } @@ -136,8 +136,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => { let fields = &adt.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args); - let ty::Adt(ty, args) = ty.kind() else { unreachable!() }; - assert!(ty.is_manually_drop()); + // FIXME: Are we just trying to map to the `T` in `MaybeUninit`? + // If so, just get it from the args. + let ty::Adt(ty, args) = ty.kind() else { + unreachable!("expected first field of `MaybeUninit` to be an ADT") + }; + assert!( + ty.is_manually_drop(), + "expected first field of `MaybeUnit` to be `ManuallyDrop`" + ); let fields = &ty.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args); self.get_asm_ty(ty) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1686479bd0e5a..ed67b5f177ebb 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -204,11 +204,14 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() res = Err(err.emit()); } // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. - match (tcx.impl_polarity(def_id), impl_.polarity) { - (ty::ImplPolarity::Positive, _) => { + match tcx.impl_polarity(def_id) { + ty::ImplPolarity::Positive => { res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait)); } - (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => { + ty::ImplPolarity::Negative => { + let ast::ImplPolarity::Negative(span) = impl_.polarity else { + bug!("impl_polarity query disagrees with impl's polarity in AST"); + }; // FIXME(#27579): what amount of WF checking do we need for neg impls? if let hir::Defaultness::Default { .. } = impl_.defaultness { let mut spans = vec![span]; @@ -222,10 +225,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() .emit()); } } - (ty::ImplPolarity::Reservation, _) => { + ty::ImplPolarity::Reservation => { // FIXME: what amount of WF checking do we need for reservation impls? } - _ => unreachable!(), } res } @@ -1068,9 +1070,14 @@ fn check_type_defn<'tcx>( hir_ty.span, wfcx.body_def_id, traits::FieldSized { - adt_kind: match item_adt_kind(&item.kind) { - Some(i) => i, - None => bug!(), + adt_kind: match &item.kind { + ItemKind::Struct(..) => AdtKind::Struct, + ItemKind::Union(..) => AdtKind::Union, + ItemKind::Enum(..) => AdtKind::Enum, + kind => span_bug!( + item.span, + "should be wfchecking an ADT, got {kind:?}" + ), }, span: hir_ty.span, last, @@ -1302,7 +1309,9 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id | GenericParamDefKind::Const { has_default, .. } => { has_default && def.index >= generics.parent_count as u32 } - GenericParamDefKind::Lifetime => unreachable!(), + GenericParamDefKind::Lifetime => { + span_bug!(tcx.def_span(def.def_id), "lifetime params can have no default") + } }; // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. @@ -1750,15 +1759,15 @@ fn check_variances_for_type_defn<'tcx>( } } ItemKind::TyAlias(..) => { - if tcx.type_alias_is_lazy(item.owner_id) { - if tcx.type_of(item.owner_id).skip_binder().references_error() { - return; - } - } else { - bug!(); + assert!( + tcx.type_alias_is_lazy(item.owner_id), + "should not be computing variance of non-weak type alias" + ); + if tcx.type_of(item.owner_id).skip_binder().references_error() { + return; } } - _ => bug!(), + kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"), } let ty_predicates = tcx.predicates_of(item.owner_id); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index fdd6424a19e2d..d176665e4c078 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -836,7 +836,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { use rustc_hir::*; let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else { - bug!(); + bug!("expected ADT to be an item"); }; let repr = tcx.repr_options_of_def(def_id.to_def_id()); @@ -887,7 +887,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { (adt_kind, variants) } - _ => bug!(), + _ => bug!("{:?} is not an ADT", item.owner_id.def_id), }; tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr) } diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 0053af2b7dfe0..39ca1bba06545 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -97,8 +97,10 @@ pub(super) fn explicit_item_bounds( item.span, )); } - // These should have been fed! - Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(), + Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!( + tcx.def_span(def_id), + "item bounds for RPITIT in impl to be fed on def-id creation" + ), None => {} } @@ -128,7 +130,7 @@ pub(super) fn explicit_item_bounds( let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) = *origin else { - bug!() + span_bug!(*span, "RPITIT cannot be a TAIT, but got origin {origin:?}"); }; let args = GenericArgs::identity_for_item(tcx, def_id); let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index de85a5d8626fa..41520718aa8d1 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -296,7 +296,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen hir::GenericBound::Outlives(lt) => { (icx.astconv().ast_region_to_region(lt, None), lt.ident.span) } - _ => bug!(), + bound => { + span_bug!( + bound.span(), + "lifetime param bounds must be outlives, but found {bound:?}" + ) + } }; let pred = ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)) .to_predicate(tcx); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index a972c51e3eea0..5769fc5fe6408 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1300,7 +1300,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { what, }) } - _ => unreachable!(), + kind => span_bug!( + use_span, + "did not expect to resolve lifetime to {}", + kind.descr(param_def_id) + ), }; def = ResolvedArg::Error(guar); } else if let Some(body_id) = outermost_body { @@ -1441,7 +1445,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { what, }) } - _ => unreachable!(), + kind => span_bug!( + use_span, + "did not expect to resolve non-lifetime param to {}", + kind.descr(param_def_id.to_def_id()) + ), }; self.map.defs.insert(hir_id, ResolvedArg::Error(guar)); } else { @@ -2123,7 +2131,7 @@ pub fn deny_non_region_late_bound( for (var, arg) in bound_vars { let Node::GenericParam(param) = tcx.hir_node_by_def_id(*var) else { - bug!(); + span_bug!(tcx.def_span(*var), "expected bound-var def-id to resolve to param"); }; let what = match param.kind { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 4b2ace748df3b..174217d3b70d1 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -20,7 +20,13 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { use rustc_middle::ty::Ty; let hir_id = tcx.local_def_id_to_hir_id(def_id); - let Node::AnonConst(_) = tcx.hir_node(hir_id) else { panic!() }; + let node = tcx.hir_node(hir_id); + let Node::AnonConst(_) = node else { + span_bug!( + tcx.def_span(def_id), + "expected anon const in `anon_const_type_of`, got {node:?}" + ); + }; let parent_node_id = tcx.hir().parent_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 8701626058d43..82e687135eb29 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2003,18 +2003,14 @@ impl<'a> State<'a> { }); self.word("|"); - if let hir::FnRetTy::DefaultReturn(..) = decl.output { - return; - } - - self.space_if_not_bol(); - self.word_space("->"); match decl.output { hir::FnRetTy::Return(ty) => { + self.space_if_not_bol(); + self.word_space("->"); self.print_type(ty); self.maybe_print_comment(ty.span.lo()); } - hir::FnRetTy::DefaultReturn(..) => unreachable!(), + hir::FnRetTy::DefaultReturn(..) => {} } } @@ -2179,7 +2175,7 @@ impl<'a> State<'a> { GenericBound::Outlives(lt) => { self.print_lifetime(lt); } - _ => panic!(), + _ => panic!("unexpected bound on lifetime param: {bound:?}"), } if i != 0 { @@ -2216,16 +2212,14 @@ impl<'a> State<'a> { } fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { - if let hir::FnRetTy::DefaultReturn(..) = decl.output { - return; - } - - self.space_if_not_bol(); - self.ibox(INDENT_UNIT); - self.word_space("->"); match decl.output { - hir::FnRetTy::DefaultReturn(..) => unreachable!(), - hir::FnRetTy::Return(ty) => self.print_type(ty), + hir::FnRetTy::Return(ty) => { + self.space_if_not_bol(); + self.ibox(INDENT_UNIT); + self.word_space("->"); + self.print_type(ty); + } + hir::FnRetTy::DefaultReturn(..) => return, } self.end(); diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index d89af297560b4..e88dc4be97b2a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -271,7 +271,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { match e { CastError::NeedViaPtr => "a raw pointer", CastError::NeedViaThinPtr => "a thin pointer", - _ => bug!(), + e => unreachable!("control flow means we should never encounter a {e:?}"), } )); } @@ -288,13 +288,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.cast_ty, fcx, ) - .help(format!( - "cast through {} first", - match e { - CastError::NeedViaInt => "an integer", - _ => bug!(), - } - )) + .help("cast through an integer first") .emit(); } CastError::IllegalCast => { @@ -534,7 +528,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let unknown_cast_to = match e { CastError::UnknownCastPtrKind => true, CastError::UnknownExprPtrKind => false, - _ => bug!(), + e => unreachable!("control flow means we should never encounter a {e:?}"), }; let (span, sub) = if unknown_cast_to { (self.cast_span, errors::CastUnknownPointerSub::To(self.cast_span)) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 22af79e02a70f..61236c07135cd 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1182,14 +1182,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Adjust::Pointer(PointerCoercion::ClosureFnPointer(a_sig.unsafety())) } ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer), - _ => unreachable!(), + _ => span_bug!(cause.span, "should not try to coerce a {prev_ty} to a fn pointer"), }; let next_adjustment = match new_ty.kind() { ty::Closure(..) => { Adjust::Pointer(PointerCoercion::ClosureFnPointer(b_sig.unsafety())) } ty::FnDef(..) => Adjust::Pointer(PointerCoercion::ReifyFnPointer), - _ => unreachable!(), + _ => span_bug!(new.span, "should not try to coerce a {new_ty} to a fn pointer"), }; for expr in exprs.iter().map(|e| e.as_coercion_site()) { self.apply_adjustments( @@ -1918,7 +1918,7 @@ where impl AsCoercionSite for ! { fn as_coercion_site(&self) -> &hir::Expr<'_> { - unreachable!() + *self } } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 580586f626771..8b666c634257f 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -331,13 +331,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty_op: |ty| { if let ty::Infer(infer) = ty.kind() { match infer { - ty::InferTy::TyVar(_) => self.next_ty_var(TypeVariableOrigin { + ty::TyVar(_) => self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, }), - ty::InferTy::IntVar(_) => self.next_int_var(), - ty::InferTy::FloatVar(_) => self.next_float_var(), - _ => bug!(), + ty::IntVar(_) => self.next_int_var(), + ty::FloatVar(_) => self.next_float_var(), + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { + bug!("unexpected fresh ty outside of the trait solver") + } } } else { ty diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 725f327d835dc..80265cf31e672 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2087,7 +2087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let names = names.iter().map(|name| format!("`{name}`")).collect::>(); format!("{} and `{last}` ", names.join(", ")) } - [] => unreachable!(), + [] => bug!("expected at least one private field to report"), }; err.note(format!( "{}private field{s} {names}that {were} not provided", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 2ab7bb86354c6..3f97b24aa59bf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -993,7 +993,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) { match e { Error::Missing(expected_idx) => missing_idxs.push(expected_idx), - _ => unreachable!(), + _ => unreachable!( + "control flow ensures that we should always get an `Error::Missing`" + ), } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 28f377083f68f..1650aaeb4957a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2072,8 +2072,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(CtorKind::Fn) => ("(".to_owned(), ")"), None => (format!(" {{ {field_name}: "), " }"), - // unit variants don't have fields - Some(CtorKind::Const) => unreachable!(), + Some(CtorKind::Const) => unreachable!("unit variants don't have fields"), }; // Suggest constructor as deep into the block tree as possible. diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index e7af7da205c61..b2ead3cd40b74 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -415,7 +415,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { ) .into() } - _ => unreachable!(), + (kind, arg) => { + bug!("mismatched method arg kind {kind:?} in turbofish: {arg:?}") + } } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 165fc630787e7..be21fd5f0a630 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1820,7 +1820,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn joined_uncovered_patterns(witnesses: &[&Ident]) -> String { const LIMIT: usize = 3; match witnesses { - [] => bug!(), + [] => { + unreachable!( + "expected an uncovered pattern, otherwise why are we emitting an error?" + ) + } [witness] => format!("`{witness}`"), [head @ .., tail] if head.len() < LIMIT => { let head: Vec<_> = head.iter().map(<_>::to_string).collect(); diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6608fdab9d087..fe58fc7122c59 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -103,15 +103,19 @@ impl<'tcx> InferCtxt<'tcx> { } // We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm. - ( - ty::Alias(..), - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), - ) - | ( - ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), - ty::Alias(..), - ) if self.next_trait_solver() => { - bug!() + (ty::Alias(..), ty::Infer(ty::TyVar(_))) | (ty::Infer(ty::TyVar(_)), ty::Alias(..)) + if self.next_trait_solver() => + { + bug!( + "We do not expect to encounter `TyVar` this late in combine \ + -- they should have been handled earlier" + ) + } + (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))) + | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _) + if self.next_trait_solver() => + { + bug!("We do not expect to encounter `Fresh` variables in the new solver") } (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => { diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 8fe6c1b0d86fd..1caa9aa8cd688 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -232,7 +232,9 @@ fn ty_to_string<'tcx>( /// something users are familiar with. Directly printing the `fn_sig` of closures also /// doesn't work as they actually use the "rust-call" API. fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { - let ty::Closure(_, args) = ty.kind() else { unreachable!() }; + let ty::Closure(_, args) = ty.kind() else { + bug!("cannot convert non-closure to fn str in `closure_as_fn_str`") + }; let fn_sig = args.as_closure().sig(); let args = fn_sig .inputs() diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 362bb8169102c..1e365848e070d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -375,7 +375,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.span_note(span, "the lifetime requirement is introduced here"); err } else { - unreachable!() + unreachable!( + "control flow ensures we have a `BindingObligation` or `ExprBindingObligation` here..." + ) } } infer::Subtype(box trace) => { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index d707c30206df9..ab3c976a351a0 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -247,7 +247,9 @@ where let (a, b) = match (a.kind(), b.kind()) { (&ty::Alias(ty::Opaque, ..), _) => (a, generalize(b, false)?), (_, &ty::Alias(ty::Opaque, ..)) => (generalize(a, true)?, b), - _ => unreachable!(), + _ => unreachable!( + "expected at least one opaque type in `relate_opaques`, got {a} and {b}." + ), }; let cause = ObligationCause::dummy_with_span(self.delegate.span()); let obligations = self @@ -707,7 +709,9 @@ where ), // FIXME(deferred_projection_equality): Implement this when we trigger it. // Probably just need to do nothing here. - ty::Variance::Bivariant => unreachable!(), + ty::Variance::Bivariant => { + unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)") + } })]); } } diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index 45df22d44e810..47038cfd46878 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -203,7 +203,9 @@ pub(super) fn compute_alias_components_recursive<'tcx>( out: &mut SmallVec<[Component<'tcx>; 4]>, visited: &mut SsoHashSet>, ) { - let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() }; + let ty::Alias(kind, alias_ty) = alias_ty.kind() else { + unreachable!("can only call `compute_alias_components_recursive` on an alias type") + }; let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; for (index, child) in alias_ty.args.iter().enumerate() { if opt_variances.get(index) == Some(&ty::Bivariant) { diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 2fe51b400ec21..980ef86236656 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -203,7 +203,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ) .into(), ty::AssocKind::Type => Ty::new_error(tcx, guar).into(), - ty::AssocKind::Fn => unreachable!(), + // This makes no sense... + ty::AssocKind::Fn => span_bug!( + tcx.def_span(assoc_def.item.def_id), + "cannot project to an associated function" + ), }; ecx.eq(goal.param_env, goal.predicate.term, error_term) .expect("expected goal term to be fully unconstrained"); diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 9536fde7c93d1..deb50e6aefdb3 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -256,7 +256,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { Err(NoSolution) } } - ty::ImplPolarity::Reservation => bug!(), + // FIXME: Goal polarity should be split from impl polarity + ty::ImplPolarity::Reservation => { + bug!("we never expect a `Reservation` polarity in a trait goal") + } } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 88ebea700210b..818d14366596c 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -487,7 +487,7 @@ fn plug_infer_with_placeholders<'tcx>( ), ) else { - bug!() + bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations, &[]); ControlFlow::Continue(()) @@ -510,7 +510,7 @@ fn plug_infer_with_placeholders<'tcx>( ), ) else { - bug!() + bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations, &[]); ControlFlow::Continue(()) @@ -544,7 +544,7 @@ fn plug_infer_with_placeholders<'tcx>( ), ) else { - bug!() + bug!("we always expect to be able to plug an infer var with placeholder") }; assert_eq!(obligations, &[]); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index b3bb0a9fcb770..5cc934e7bc52a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -250,7 +250,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.emit(); self.tcx.sess.abort_if_errors(); - bug!(); + // FIXME: this should be something like `build_overflow_error_fatal`, which returns + // `DiagnosticBuilder<', !>`. Then we don't even need anything after that `emit()`. + unreachable!( + "did not expect compilation to continue after `abort_if_errors`, \ + since an error was definitely emitted!" + ); } fn build_overflow_error( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4c3eb05819f33..d5635812c7405 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -191,7 +191,9 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { match (current, candidate) { (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (), (ParamEnv(..), _) => return false, - (_, ParamEnv(..)) => unreachable!(), + (_, ParamEnv(..)) => bug!( + "should never prefer non-param-env candidates over param-env candidates" + ), (_, _) => convert_to_ambiguous = (), } } @@ -2080,10 +2082,11 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { - let ty::Coroutine(_, args, _) = - selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Coroutine(_, args, _) = self_ty.kind() else { + unreachable!( + "expected coroutine self type for built-in coroutine candidate, found {self_ty}" + ) }; let coroutine_sig = args.as_coroutine().sig(); let Normalized { value: coroutine_sig, obligations } = normalize_with_depth( @@ -2113,7 +2116,10 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( } else if name == sym::Yield { yield_ty } else { - bug!() + span_bug!( + tcx.def_span(obligation.predicate.def_id), + "unexpected associated type: `Coroutine::{name}`" + ); }; let predicate = ty::ProjectionPredicate { @@ -2131,10 +2137,11 @@ fn confirm_future_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { - let ty::Coroutine(_, args, _) = - selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Coroutine(_, args, _) = self_ty.kind() else { + unreachable!( + "expected coroutine self type for built-in async future candidate, found {self_ty}" + ) }; let coroutine_sig = args.as_coroutine().sig(); let Normalized { value: coroutine_sig, obligations } = normalize_with_depth( @@ -2174,10 +2181,9 @@ fn confirm_iterator_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { - let ty::Coroutine(_, args, _) = - selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Coroutine(_, args, _) = self_ty.kind() else { + unreachable!("expected coroutine self type for built-in gen candidate, found {self_ty}") }; let gen_sig = args.as_coroutine().sig(); let Normalized { value: gen_sig, obligations } = normalize_with_depth( @@ -2341,9 +2347,9 @@ fn confirm_closure_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { - let ty::Closure(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() - else { - unreachable!() + let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); + let ty::Closure(_, args) = self_ty.kind() else { + unreachable!("expected closure self type for closure candidate, found {self_ty}") }; let closure_sig = args.as_closure().sig(); let Normalized { value: closure_sig, obligations } = normalize_with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 4728fcf3301c0..ed55533bc551a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -285,7 +285,7 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> ty::Projection => tcx.normalize_projection_ty(c_data), ty::Weak => tcx.normalize_weak_ty(c_data), ty::Inherent => tcx.normalize_inherent_projection_ty(c_data), - _ => unreachable!(), + kind => unreachable!("did not expect {kind:?} due to match arm above"), }?; // We don't expect ambiguity. if !result.value.is_proven() { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 10528696b2d70..ba6ed29877409 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -184,7 +184,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( push_outlives_components(tcx, ty_a, &mut components); implied_bounds.extend(implied_bounds_from_components(r_b, components)) } - ty::GenericArgKind::Const(_) => unreachable!(), + ty::GenericArgKind::Const(_) => { + unreachable!("consts do not participate in outlives bounds") + } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4a342a7f6b146..7e3d304d1cdf0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -942,8 +942,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let a_ty = self.infcx.shallow_resolve(predicate.self_ty()); let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1)); - let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else { bug!() }; - let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else { bug!() }; + let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else { + bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`") + }; + let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else { + bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`") + }; let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty); let unnormalized_upcast_principal = From 1cc0d7d56cbaadfdb2652c73a959edd91d7bd721 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 15 Dec 2023 03:34:37 +0000 Subject: [PATCH 2/2] Annotate some more bugs --- compiler/rustc_ast_lowering/src/asm.rs | 4 ++-- compiler/rustc_ast_lowering/src/item.rs | 9 +++++++-- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 9 --------- compiler/rustc_hir_typeck/src/cast.rs | 2 +- compiler/rustc_middle/src/ty/consts/int.rs | 4 ++-- compiler/rustc_middle/src/ty/util.rs | 7 ++----- compiler/rustc_mir_build/src/build/mod.rs | 8 ++++++-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- .../rustc_mir_build/src/thir/pattern/const_to_pat.rs | 5 +++-- 9 files changed, 24 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 7111daa2ea9ab..4c81983c24296 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -336,7 +336,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymFn { .. } | hir::InlineAsmOperand::SymStatic { .. } => { - unreachable!() + unreachable!("{op:?} is not a register operand"); } }; @@ -380,7 +380,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { { reg_sym.as_str() } else { - unreachable!(); + unreachable!("{op:?} is not a register operand"); } }; diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7c05724f64c95..83452c2228029 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -421,8 +421,13 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::MacroDef(MacroDef { body, macro_rules }) => { let body = P(self.lower_delim_args(body)); - let DefKind::Macro(macro_kind) = self.tcx.def_kind(self.local_def_id(id)) else { - unreachable!() + let def_id = self.local_def_id(id); + let def_kind = self.tcx.def_kind(def_id); + let DefKind::Macro(macro_kind) = def_kind else { + unreachable!( + "expected DefKind::Macro for macro item, found {}", + def_kind.descr(def_id.to_def_id()) + ); }; let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); hir::ItemKind::Macro(macro_def, macro_kind) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ed67b5f177ebb..64026cdfff417 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -994,15 +994,6 @@ fn check_associated_item( }) } -fn item_adt_kind(kind: &ItemKind<'_>) -> Option { - match kind { - ItemKind::Struct(..) => Some(AdtKind::Struct), - ItemKind::Union(..) => Some(AdtKind::Union), - ItemKind::Enum(..) => Some(AdtKind::Enum), - _ => None, - } -} - /// In a type definition, we check that to ensure that the types of the fields are well-formed. fn check_type_defn<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index e88dc4be97b2a..0de0365364c6a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum CastError { ErrorGuaranteed(ErrorGuaranteed), diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 9d99344d5bdfb..310cf113b11b6 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -71,7 +71,7 @@ impl std::fmt::Debug for ConstInt { (4, _) => write!(fmt, "_i32")?, (8, _) => write!(fmt, "_i64")?, (16, _) => write!(fmt, "_i128")?, - _ => bug!(), + (sz, _) => bug!("unexpected int size i{sz}"), } } Ok(()) @@ -105,7 +105,7 @@ impl std::fmt::Debug for ConstInt { (4, _) => write!(fmt, "_u32")?, (8, _) => write!(fmt, "_u64")?, (16, _) => write!(fmt, "_u128")?, - _ => bug!(), + (sz, _) => bug!("unexpected unsigned int size u{sz}"), } } Ok(()) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 8b1d33848eab3..8b2b76764e646 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -421,13 +421,10 @@ impl<'tcx> TyCtxt<'tcx> { let impl_args = match *self.type_of(impl_def_id).instantiate_identity().kind() { ty::Adt(def_, args) if def_ == def => args, - _ => bug!(), + _ => span_bug!(self.def_span(impl_def_id), "expected ADT for self type of `Drop` impl"), }; - let item_args = match *self.type_of(def.did()).instantiate_identity().kind() { - ty::Adt(def_, args) if def_ == def => args, - _ => bug!(), - }; + let item_args = ty::GenericArgs::identity_for_item(self, def.did()); let result = iter::zip(item_args, impl_args) .filter(|&(_, k)| { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index c63c7987f5efb..dae83d4b41b23 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -640,7 +640,9 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - } DefKind::Closure if coroutine_kind.is_some() => { let coroutine_ty = tcx.type_of(def_id).instantiate_identity(); - let ty::Coroutine(_, args, _) = coroutine_ty.kind() else { bug!() }; + let ty::Coroutine(_, args, _) = coroutine_ty.kind() else { + bug!("expected type of coroutine-like closure to be a coroutine") + }; let args = args.as_coroutine(); let yield_ty = args.yield_ty(); let return_ty = args.return_ty(); @@ -648,7 +650,9 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - } DefKind::Closure => { let closure_ty = tcx.type_of(def_id).instantiate_identity(); - let ty::Closure(_, args) = closure_ty.kind() else { bug!() }; + let ty::Closure(_, args) = closure_ty.kind() else { + bug!("expected type of closure to be a closure") + }; let args = args.as_closure(); let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), args.sig()); let self_ty = match args.kind() { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 31874b29bb3b8..ab88463826a2b 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -782,7 +782,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Tup(fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) }, hir::ExprKind::Yield(v, _) => ExprKind::Yield { value: self.mirror_expr(v) }, - hir::ExprKind::Err(_) => unreachable!(), + hir::ExprKind::Err(_) => unreachable!("cannot lower a `hir::ExprKind::Err` to THIR"), }; Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 391d65b338d55..a7f2377219304 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -492,8 +492,9 @@ impl<'tcx> ConstToPat<'tcx> { PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } } ty::FnPtr(..) => { - // Valtree construction would never succeed for these, so this is unreachable. - unreachable!() + unreachable!( + "Valtree construction would never succeed for FnPtr, so this is unreachable." + ) } _ => { let err = InvalidPattern { span, non_sm_ty: ty };