diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 3713883eb00d7..60e675bca94f6 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -135,6 +135,7 @@ impl<'tcx> Const<'tcx> { uv: ty::UnevaluatedConst<'tcx>, ty: Ty<'tcx>, ) -> Const<'tcx> { + tcx.debug_assert_args_compatible(uv.def, uv.args); Const::new(tcx, ty::ConstKind::Unevaluated(uv), ty) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9f33609eae6bd..c14a346a8940f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2009,19 +2009,38 @@ impl<'tcx> TyCtxt<'tcx> { true } - pub fn assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) { - if !self.check_args_compatible(def_id, args) { - if let DefKind::AssocTy = self.def_kind(def_id) - && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) - { - bug!() - } else { - bug!( - "args not compatible with generics for {}: args={:#?}, generics={:#?}", - self.def_path_str(def_id), - args, - ty::GenericArgs::identity_for_item(self, def_id) - ); + /// With `cfg(debug_assertions)`, assert that args are compatible with their generics, + /// and print out the args if not. + #[cfg_attr(not(debug_assertions), allow(unused_variables))] + pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) { + #[cfg(debug_assertions)] + { + if !self.check_args_compatible(def_id, args) { + if let DefKind::AssocTy = self.def_kind(def_id) + && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) + { + bug!( + "args not compatible with generics for {}: args={:#?}, generics={:#?}", + self.def_path_str(def_id), + args, + // Make `[Self, GAT_ARGS...]` (this could be simplified) + self.mk_args_from_iter( + [self.types.self_param.into()].into_iter().chain( + self.generics_of(def_id) + .own_args(ty::GenericArgs::identity_for_item(self, def_id)) + .iter() + .copied() + ) + ) + ); + } else { + bug!( + "args not compatible with generics for {}: args={:#?}, generics={:#?}", + self.def_path_str(def_id), + args, + ty::GenericArgs::identity_for_item(self, def_id) + ); + } } } } @@ -2029,14 +2048,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline(always)] pub(crate) fn check_and_mk_args( self, - _def_id: DefId, + def_id: DefId, args: impl IntoIterator>>, ) -> GenericArgsRef<'tcx> { let args = self.mk_args_from_iter(args.into_iter().map(Into::into)); - #[cfg(debug_assertions)] - { - self.assert_args_compatible(_def_id, args); - } + self.debug_assert_args_compatible(def_id, args); args } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index dc1ad1da7e1fb..30997d1350d9d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1624,9 +1624,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> { - if cfg!(debug_assertions) { - tcx.assert_args_compatible(def.did(), args); - } + tcx.debug_assert_args_compatible(def.did(), args); Ty::new(tcx, Adt(def, args)) } @@ -1707,9 +1705,7 @@ impl<'tcx> Ty<'tcx> { def_id: DefId, closure_args: GenericArgsRef<'tcx>, ) -> Ty<'tcx> { - if cfg!(debug_assertions) { - tcx.assert_args_compatible(def_id, closure_args); - } + tcx.debug_assert_args_compatible(def_id, closure_args); Ty::new(tcx, Closure(def_id, closure_args)) } @@ -1719,9 +1715,7 @@ impl<'tcx> Ty<'tcx> { def_id: DefId, closure_args: GenericArgsRef<'tcx>, ) -> Ty<'tcx> { - if cfg!(debug_assertions) { - tcx.assert_args_compatible(def_id, closure_args); - } + tcx.debug_assert_args_compatible(def_id, closure_args); Ty::new(tcx, CoroutineClosure(def_id, closure_args)) } @@ -1731,9 +1725,7 @@ impl<'tcx> Ty<'tcx> { def_id: DefId, coroutine_args: GenericArgsRef<'tcx>, ) -> Ty<'tcx> { - if cfg!(debug_assertions) { - tcx.assert_args_compatible(def_id, coroutine_args); - } + tcx.debug_assert_args_compatible(def_id, coroutine_args); Ty::new(tcx, Coroutine(def_id, coroutine_args)) }