diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index c293fbe4ef8ca..f2f7242a8fdde 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -438,18 +438,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - #[inline] - pub fn optimized_mir_or_const_arg_mir( - self, - def: ty::WithOptConstParam, - ) -> &'tcx Body<'tcx> { - if let Some((did, param_did)) = def.as_const_arg() { - self.mir_for_ctfe_of_const_arg((did, param_did)) - } else { - self.optimized_mir(def.did) - } - } - #[inline] pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam) -> &'tcx Body<'tcx> { if let Some((did, param_did)) = def.as_const_arg() { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index de012a6957419..23cedfd499eaa 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -499,7 +499,7 @@ impl<'tcx> Instance<'tcx> { } /// Returns a new `Instance` where generic parameters in `instance.substs` are replaced by - /// identify parameters if they are determined to be unused in `instance.def`. + /// identity parameters if they are determined to be unused in `instance.def`. pub fn polymorphize(self, tcx: TyCtxt<'tcx>) -> Self { debug!("polymorphize: running polymorphization analysis"); if !tcx.sess.opts.debugging_opts.polymorphize { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2e077827873d1..c27a337554e67 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2963,7 +2963,10 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::AnonConst => self.mir_for_ctfe_opt_const_arg(def), // If the caller wants `mir_for_ctfe` of a function they should not be using // `instance_mir`, so we'll assume const fn also wants the optimized version. - _ => self.optimized_mir_or_const_arg_mir(def), + _ => { + assert_eq!(def.const_param_did, None); + self.optimized_mir(def.did) + } }, ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) diff --git a/compiler/rustc_mir/src/monomorphize/polymorphize.rs b/compiler/rustc_mir/src/monomorphize/polymorphize.rs index 4ad71ab4913ba..05b0e3a7dab95 100644 --- a/compiler/rustc_mir/src/monomorphize/polymorphize.rs +++ b/compiler/rustc_mir/src/monomorphize/polymorphize.rs @@ -30,9 +30,8 @@ pub fn provide(providers: &mut Providers) { /// Determine which generic parameters are used by the function/method/closure represented by /// `def_id`. Returns a bitset where bits representing unused parameters are set (`is_empty` /// indicates all parameters are used). +#[instrument(skip(tcx))] fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet { - debug!("unused_generic_params({:?})", def_id); - if !tcx.sess.opts.debugging_opts.polymorphize { // If polymorphization disabled, then all parameters are used. return FiniteBitSet::new_empty(); @@ -46,7 +45,7 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet { } let generics = tcx.generics_of(def_id); - debug!("unused_generic_params: generics={:?}", generics); + debug!(?generics); // Exit early when there are no parameters to be unused. if generics.count() == 0 { @@ -57,11 +56,11 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet { let context = tcx.hir().body_const_context(def_id.expect_local()); match context { Some(ConstContext::ConstFn) | None if !tcx.is_mir_available(def_id) => { - debug!("unused_generic_params: (no mir available) def_id={:?}", def_id); + debug!("no mir available"); return FiniteBitSet::new_empty(); } Some(_) if !tcx.is_ctfe_mir_available(def_id) => { - debug!("unused_generic_params: (no ctfe mir available) def_id={:?}", def_id); + debug!("no ctfe mir available"); return FiniteBitSet::new_empty(); } _ => {} @@ -72,9 +71,9 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet { generics.count().try_into().expect("more generic parameters than can fit into a `u32`"); let mut unused_parameters = FiniteBitSet::::new_empty(); unused_parameters.set_range(0..generics_count); - debug!("unused_generic_params: (start) unused_parameters={:?}", unused_parameters); + debug!(?unused_parameters, "(start)"); mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters); - debug!("unused_generic_params: (after default) unused_parameters={:?}", unused_parameters); + debug!(?unused_parameters, "(after default)"); // Visit MIR and accumululate used generic parameters. let body = match context { @@ -85,10 +84,10 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet { }; let mut vis = MarkUsedGenericParams { tcx, def_id, unused_parameters: &mut unused_parameters }; vis.visit_body(body); - debug!("unused_generic_params: (after visitor) unused_parameters={:?}", unused_parameters); + debug!(?unused_parameters, "(after visitor)"); mark_used_by_predicates(tcx, def_id, &mut unused_parameters); - debug!("unused_generic_params: (end) unused_parameters={:?}", unused_parameters); + debug!(?unused_parameters, "(end)"); // Emit errors for debugging and testing if enabled. if !unused_parameters.is_empty() { @@ -101,24 +100,55 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet { /// Some parameters are considered used-by-default, such as non-generic parameters and the dummy /// generic parameters from closures, this function marks them as used. `leaf_is_closure` should /// be `true` if the item that `unused_generic_params` was invoked on is a closure. +#[instrument(skip(tcx, def_id, generics, unused_parameters))] fn mark_used_by_default_parameters<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, generics: &'tcx ty::Generics, unused_parameters: &mut FiniteBitSet, ) { - if !tcx.is_trait(def_id) && (tcx.is_closure(def_id) || tcx.type_of(def_id).is_generator()) { - for param in &generics.params { - debug!("mark_used_by_default_parameters: (closure/gen) param={:?}", param); - unused_parameters.clear(param.index); - } - } else { - for param in &generics.params { - debug!("mark_used_by_default_parameters: (other) param={:?}", param); - if let ty::GenericParamDefKind::Lifetime = param.kind { + match tcx.def_kind(def_id) { + DefKind::Closure | DefKind::Generator => { + for param in &generics.params { + debug!(?param, "(closure/gen)"); unused_parameters.clear(param.index); } } + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::Fn + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static + | DefKind::Ctor(_, _) + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::OpaqueTy + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Impl => { + for param in &generics.params { + debug!(?param, "(other)"); + if let ty::GenericParamDefKind::Lifetime = param.kind { + unused_parameters.clear(param.index); + } + } + } } if let Some(parent) = generics.parent { @@ -128,6 +158,7 @@ fn mark_used_by_default_parameters<'tcx>( /// Search the predicates on used generic parameters for any unused generic parameters, and mark /// those as used. +#[instrument(skip(tcx, def_id))] fn mark_used_by_predicates<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, @@ -135,16 +166,12 @@ fn mark_used_by_predicates<'tcx>( ) { let def_id = tcx.closure_base_def_id(def_id); let predicates = tcx.explicit_predicates_of(def_id); - debug!("mark_used_by_predicates: predicates_of={:?}", predicates); let mut current_unused_parameters = FiniteBitSet::new_empty(); // Run to a fixed point to support `where T: Trait, U: Trait`, starting with an empty // bit set so that this is skipped if all parameters are already used. while current_unused_parameters != *unused_parameters { - debug!( - "mark_used_by_predicates: current_unused_parameters={:?} = unused_parameters={:?}", - current_unused_parameters, unused_parameters - ); + debug!(?current_unused_parameters, ?unused_parameters); current_unused_parameters = *unused_parameters; for (predicate, _) in predicates.predicates { @@ -169,13 +196,13 @@ fn mark_used_by_predicates<'tcx>( /// Emit errors for the function annotated by `#[rustc_polymorphize_error]`, labelling each generic /// parameter which was unused. +#[instrument(skip(tcx, generics))] fn emit_unused_generic_params_error<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, generics: &'tcx ty::Generics, unused_parameters: &FiniteBitSet, ) { - debug!("emit_unused_generic_params_error: def_id={:?}", def_id); let base_def_id = tcx.closure_base_def_id(def_id); if !tcx .get_attrs(base_def_id) @@ -185,7 +212,6 @@ fn emit_unused_generic_params_error<'tcx>( return; } - debug!("emit_unused_generic_params_error: unused_parameters={:?}", unused_parameters); let fn_span = match tcx.opt_item_name(def_id) { Some(ident) => ident.span, _ => tcx.def_span(def_id), @@ -197,7 +223,7 @@ fn emit_unused_generic_params_error<'tcx>( while let Some(generics) = next_generics { for param in &generics.params { if unused_parameters.contains(param.index).unwrap_or(false) { - debug!("emit_unused_generic_params_error: param={:?}", param); + debug!(?param); let def_span = tcx.def_span(param.def_id); err.span_label(def_span, &format!("generic parameter `{}` is unused", param.name)); } @@ -219,25 +245,23 @@ struct MarkUsedGenericParams<'a, 'tcx> { impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> { /// Invoke `unused_generic_params` on a body contained within the current item (e.g. /// a closure, generator or constant). + #[instrument(skip(self, def_id, substs))] fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) { let unused = self.tcx.unused_generic_params(def_id); - debug!( - "visit_child_body: unused_parameters={:?} unused={:?}", - self.unused_parameters, unused - ); + debug!(?self.unused_parameters, ?unused); for (i, arg) in substs.iter().enumerate() { let i = i.try_into().unwrap(); if !unused.contains(i).unwrap_or(false) { arg.visit_with(self); } } - debug!("visit_child_body: unused_parameters={:?}", self.unused_parameters); + debug!(?self.unused_parameters); } } impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { + #[instrument(skip(self, local))] fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - debug!("visit_local_decl: local_decl={:?}", local_decl); if local == Local::from_usize(1) { let def_kind = self.tcx.def_kind(self.def_id); if matches!(def_kind, DefKind::Closure | DefKind::Generator) { @@ -245,7 +269,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { // happens because the first argument to the closure is a reference to itself and // that will call `visit_substs`, resulting in each generic parameter captured being // considered used by default. - debug!("visit_local_decl: skipping closure substs"); + debug!("skipping closure substs"); return; } } @@ -263,15 +287,15 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { + #[instrument(skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { - debug!("visit_const: c={:?}", c); if !c.has_param_types_or_consts() { return ControlFlow::CONTINUE; } match c.val { ty::ConstKind::Param(param) => { - debug!("visit_const: param={:?}", param); + debug!(?param); self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } @@ -296,15 +320,15 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } } + #[instrument(skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - debug!("visit_ty: ty={:?}", ty); if !ty.has_param_types_or_consts() { return ControlFlow::CONTINUE; } match *ty.kind() { ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => { - debug!("visit_ty: def_id={:?}", def_id); + debug!(?def_id); // Avoid cycle errors with generators. if def_id == self.def_id { return ControlFlow::CONTINUE; @@ -316,7 +340,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { ControlFlow::CONTINUE } ty::Param(param) => { - debug!("visit_ty: param={:?}", param); + debug!(?param); self.unused_parameters.clear(param.index); ControlFlow::CONTINUE } @@ -333,8 +357,8 @@ struct HasUsedGenericParams<'a> { impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { type BreakTy = (); + #[instrument(skip(self))] fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow { - debug!("visit_const: c={:?}", c); if !c.has_param_types_or_consts() { return ControlFlow::CONTINUE; } @@ -351,8 +375,8 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { } } + #[instrument(skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - debug!("visit_ty: ty={:?}", ty); if !ty.has_param_types_or_consts() { return ControlFlow::CONTINUE; }