Skip to content

instance: polymorphize shims #75414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ impl IntoArgs for (CrateNum, DefId) {
}
}

impl IntoArgs for ty::InstanceDef<'tcx> {
fn into_args(self) -> (DefId, DefId) {
(self.def_id(), self.def_id())
}
}

provide! { <'tcx> tcx, def_id, other, cdata,
type_of => { cdata.get_type(def_id.index, tcx) }
generics_of => { cdata.get_generics(def_id.index, tcx.sess) }
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,8 @@ impl EncodeContext<'a, 'tcx> {
debug!("EntryBuilder::encode_mir_for_ctfe({:?})", def_id);
record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));

let unused = self.tcx.unused_generic_params(def_id);
let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
let unused = self.tcx.unused_generic_params(instance);
if !unused.is_empty() {
record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
}
Expand All @@ -1153,7 +1154,8 @@ impl EncodeContext<'a, 'tcx> {
debug!("EntryBuilder::encode_optimized_mir({:?})", def_id);
record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));

let unused = self.tcx.unused_generic_params(def_id);
let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
let unused = self.tcx.unused_generic_params(instance);
if !unused.is_empty() {
record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1469,11 +1469,11 @@ rustc_queries! {
query codegen_unit(_: Symbol) -> &'tcx CodegenUnit<'tcx> {
desc { "codegen_unit" }
}
query unused_generic_params(key: DefId) -> FiniteBitSet<u32> {
cache_on_disk_if { key.is_local() }
query unused_generic_params(key: ty::InstanceDef<'tcx>) -> FiniteBitSet<u32> {
cache_on_disk_if { key.def_id().is_local() }
desc {
|tcx| "determining which generic parameters are unused by `{}`",
tcx.def_path_str(key)
tcx.def_path_str(key.def_id())
}
}
query backend_optimization_level(_: CrateNum) -> OptLevel {
Expand Down
47 changes: 35 additions & 12 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,22 @@ impl<'tcx> InstanceDef<'tcx> {
}
}

/// Returns the `DefId` of instances which might not require codegen locally.
pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
match self {
ty::InstanceDef::Item(def) => Some(def.did),
ty::InstanceDef::DropGlue(def_id, Some(_)) => Some(def_id),
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Intrinsic(_)
| ty::InstanceDef::CloneShim(..) => None,
}
}

#[inline]
pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
match self {
Expand Down Expand Up @@ -505,29 +521,26 @@ impl<'tcx> Instance<'tcx> {
return self;
}

if let InstanceDef::Item(def) = self.def {
let polymorphized_substs = polymorphize(tcx, def.did, self.substs);
debug!("polymorphize: self={:?} polymorphized_substs={:?}", self, polymorphized_substs);
Self { def: self.def, substs: polymorphized_substs }
} else {
self
}
let polymorphized_substs = polymorphize(tcx, self.def, self.substs);
debug!("polymorphize: self={:?} polymorphized_substs={:?}", self, polymorphized_substs);
Self { def: self.def, substs: polymorphized_substs }
}
}

fn polymorphize<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
instance: ty::InstanceDef<'tcx>,
substs: SubstsRef<'tcx>,
) -> SubstsRef<'tcx> {
debug!("polymorphize({:?}, {:?})", def_id, substs);
let unused = tcx.unused_generic_params(def_id);
debug!("polymorphize({:?}, {:?})", instance, substs);
let unused = tcx.unused_generic_params(instance);
debug!("polymorphize: unused={:?}", unused);

// If this is a closure or generator then we need to handle the case where another closure
// from the function is captured as an upvar and hasn't been polymorphized. In this case,
// the unpolymorphized upvar closure would result in a polymorphized closure producing
// multiple mono items (and eventually symbol clashes).
let def_id = instance.def_id();
let upvars_ty = if tcx.is_closure(def_id) {
Some(substs.as_closure().tupled_upvars_ty())
} else if tcx.type_of(def_id).is_generator() {
Expand All @@ -551,15 +564,25 @@ fn polymorphize<'tcx>(
debug!("fold_ty: ty={:?}", ty);
match ty.kind {
ty::Closure(def_id, substs) => {
let polymorphized_substs = polymorphize(self.tcx, def_id, substs);
let polymorphized_substs = polymorphize(
self.tcx,
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
substs,
);

if substs == polymorphized_substs {
ty
} else {
self.tcx.mk_closure(def_id, polymorphized_substs)
}
}
ty::Generator(def_id, substs, movability) => {
let polymorphized_substs = polymorphize(self.tcx, def_id, substs);
let polymorphized_substs = polymorphize(
self.tcx,
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
substs,
);

if substs == polymorphized_substs {
ty
} else {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ where
ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, ..)
| ty::FnDef(def_id, substs) => {
let unused_params = self.tcx.unused_generic_params(def_id);
let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id));
let unused_params = self.tcx.unused_generic_params(instance);
for (index, subst) in substs.into_iter().enumerate() {
let index = index
.try_into()
Expand Down
20 changes: 6 additions & 14 deletions compiler/rustc_mir/src/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,21 +788,13 @@ fn visit_instance_use<'tcx>(
}
}

// Returns `true` if we should codegen an instance in the local crate.
// Returns `false` if we can just link to the upstream crate and therefore don't
// need a mono item.
/// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we
/// can just link to the upstream crate and therefore don't need a mono item.
fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool {
let def_id = match instance.def {
ty::InstanceDef::Item(def) => def.did,
ty::InstanceDef::DropGlue(def_id, Some(_)) => def_id,
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
| ty::InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::Virtual(..)
| ty::InstanceDef::FnPtrShim(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Intrinsic(_)
| ty::InstanceDef::CloneShim(..) => return true,
let def_id = if let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() {
def_id
} else {
return true;
};

if tcx.is_foreign_item(def_id) {
Expand Down
92 changes: 64 additions & 28 deletions compiler/rustc_mir/src/monomorphize/polymorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustc_middle::ty::{
fold::{TypeFoldable, TypeVisitor},
query::Providers,
subst::SubstsRef,
Const, Ty, TyCtxt,
Const, InstanceDef, Ty, TyCtxt,
};
use rustc_span::symbol::sym;
use std::convert::TryInto;
Expand All @@ -27,21 +27,25 @@ pub fn provide(providers: &mut Providers) {
providers.unused_generic_params = unused_generic_params;
}

/// 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`
/// Determine which generic parameters are used by the `instance`.
///
/// Returns a bitset where bits representing unused parameters are set (`is_empty`
/// indicates all parameters are used).
fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
debug!("unused_generic_params({:?})", def_id);
fn unused_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
instance: InstanceDef<'tcx>,
) -> FiniteBitSet<u32> {
debug!("unused_generic_params({:?})", instance);

// If polymorphization disabled, then all parameters are used.
if !tcx.sess.opts.debugging_opts.polymorphize {
// If polymorphization disabled, then all parameters are used.
return FiniteBitSet::new_empty();
}

// Polymorphization results are stored in cross-crate metadata only when there are unused
// parameters, so assume that non-local items must have only used parameters (else this query
// would not be invoked, and the cross-crate metadata used instead).
if !def_id.is_local() {
// Exit early if this instance should not be polymorphized.
let def_id = instance.def_id();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before rebasing, should_polymorphize invoked def_id_if_not_guaranteed_local_codegen instead of using this value. It returned true whenever def_id_if_not_guaranteed_local_codegen returned None, which meant that a ClosureOnceShim (particularly, the shim for FnOnce::fn_once) wasn't being checked for available MIR, which was causing an ICE after I rebased.

if !should_polymorphize(tcx, def_id, instance) {
debug!("unused_generic_params: skipping");
return FiniteBitSet::new_empty();
}

Expand All @@ -53,36 +57,24 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
return FiniteBitSet::new_empty();
}

// Exit early when there is no MIR available.
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);
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);
return FiniteBitSet::new_empty();
}
_ => {}
}

// Create a bitset with N rightmost ones for each parameter.
let generics_count: u32 =
generics.count().try_into().expect("more generic parameters than can fit into a `u32`");
let mut unused_parameters = FiniteBitSet::<u32>::new_empty();
unused_parameters.set_range(0..generics_count);
debug!("unused_generic_params: (start) unused_parameters={:?}", unused_parameters);

mark_used_by_default_parameters(tcx, def_id, generics, &mut unused_parameters);
debug!("unused_generic_params: (after default) unused_parameters={:?}", unused_parameters);

// Visit MIR and accumululate used generic parameters.
let body = match context {
let body = match tcx.hir().body_const_context(def_id.expect_local()) {
// Const functions are actually called and should thus be considered for polymorphization
// via their runtime MIR
// via their runtime MIR.
Some(ConstContext::ConstFn) | None => tcx.optimized_mir(def_id),
Some(_) => tcx.mir_for_ctfe(def_id),
};

// Visit MIR and accumululate used generic parameters.
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);
Expand All @@ -98,6 +90,48 @@ fn unused_generic_params(tcx: TyCtxt<'_>, def_id: DefId) -> FiniteBitSet<u32> {
unused_parameters
}

/// Returns `true` if the `InstanceDef` should be polymorphized.
fn should_polymorphize<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
instance: ty::InstanceDef<'tcx>,
) -> bool {
// If a instance's MIR body is not polymorphic then the modified substitutions that are derived
// from polymorphization's result won't make any difference.
if !instance.has_polymorphic_mir_body() {
return false;
}

// Don't polymorphize intrinsics or virtual calls - calling `instance_mir` will panic.
if matches!(instance, ty::InstanceDef::Intrinsic(..) | ty::InstanceDef::Virtual(..)) {
return false;
}

// Polymorphization results are stored in cross-crate metadata only when there are unused
// parameters, so assume that non-local items must have only used parameters (else this query
// would not be invoked, and the cross-crate metadata used instead).
if !def_id.is_local() {
return false;
}

// Foreign items don't have a body to analyze.
if tcx.is_foreign_item(def_id) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After rebasing, this line was necessary to avoid body_const_context from causing an ICE.

return false;
}

// Without available MIR, polymorphization has nothing to analyze.
match tcx.hir().body_const_context(def_id.expect_local()) {
// FIXME(davidtwco): Disable polymorphization for any constant functions which, at the time
Copy link
Member Author

@davidtwco davidtwco Jan 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oli-obk: I've had to change this to avoid polymorphizing constant functions (which was changed in #78407 prompting the most recent rebase).

When changed, it results in a cycle error from one test:

---- [ui] ui/const-generics/const_evaluatable_checked/infer-too-generic.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit code: 1
command: "/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/home/david/Projects/rust/rust4/src/test/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-C" "prefer-dynamic" "-o" "/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/test/ui/const-generics/const_evaluatable_checked/infer-too-generic/a" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/test/ui/const-generics/const_evaluatable_checked/infer-too-generic/auxiliary"
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
error[E0391]: cycle detected when determining which generic parameters are unused by `split_first::{constant#0}`
  --> /home/david/Projects/rust/rust4/src/test/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs:9:9
   |
LL |     [T; N - 1]: Sized,
   |         ^^^^^
   |
   = note: ...which again requires determining which generic parameters are unused by `split_first::{constant#0}`, completing the cycle
note: cycle used when determining which generic parameters are unused by `split_first::{constant#3}`
  --> /home/david/Projects/rust/rust4/src/test/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs:14:68
   |
LL |         let tail = ptr::read(&arr[1..] as *const [T] as *const [T; N - 1]);
   |                                                                    ^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.

And in another, an ICE:

---- [ui] ui/const-generics/cross_crate_complex.rs#full stdout ----

error in revision `full`: auxiliary build of "/home/david/Projects/rust/rust4/src/test/ui/const-generics/auxiliary/crayte.rs" failed to compile:
status: exit code: 101
command: "/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/home/david/Projects/rust/rust4/src/test/ui/const-generics/auxiliary/crayte.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--cfg" "full" "--error-format" "json" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-C" "prefer-dynamic" "--out-dir" "/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/test/ui/const-generics/cross_crate_complex.full/auxiliary" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2018" "--crate-type" "dylib" "-L" "/home/david/Projects/rust/rust4/build/x86_64-unknown-linux-gnu/test/ui/const-generics/cross_crate_complex.full/auxiliary"
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
error: internal compiler error: compiler/rustc_typeck/src/collect/type_of.rs:212:17: associated type missing default
  --> /home/david/Projects/rust/rust4/src/test/ui/const-generics/auxiliary/crayte.rs:17:5
   |
LL |     type Assoc: Foo<N>;
   |     ^^^^^^^^^^^^^^^^^^^

thread 'rustc' panicked at 'Box<Any>', /home/david/Projects/rust/rust4/compiler/rustc_errors/src/lib.rs:904:9
stack backtrace:
   0: std::panicking::begin_panic
             at ./library/std/src/panicking.rs:519:12
   1: rustc_errors::HandlerInner::span_bug
             at ./compiler/rustc_errors/src/lib.rs:904:9
   2: rustc_errors::Handler::span_bug
             at ./compiler/rustc_errors/src/lib.rs:627:9
   3: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}}
             at ./compiler/rustc_middle/src/util/bug.rs:33:40
   4: rustc_middle::ty::context::tls::with_opt::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1797:40
   5: rustc_middle::ty::context::tls::with_context_opt
             at ./compiler/rustc_middle/src/ty/context.rs:1749:22
   6: rustc_middle::ty::context::tls::with_opt
             at ./compiler/rustc_middle/src/ty/context.rs:1797:9
   7: rustc_middle::util::bug::opt_span_bug_fmt
             at ./compiler/rustc_middle/src/util/bug.rs:30:5
   8: rustc_middle::util::bug::span_bug_fmt
             at ./compiler/rustc_middle/src/util/bug.rs:21:5
   9: rustc_typeck::collect::type_of::type_of
  10: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::type_of>::compute
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:377:17
  11: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
             at ./compiler/rustc_query_system/src/dep_graph/graph.rs:362:14
  12: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}::{{closure}}
  13: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}::{{closure}}
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:73:74
  14: stacker::maybe_grow
             at /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/stacker-0.1.12/src/lib.rs:55:9
  15: rustc_data_structures::stack::ensure_sufficient_stack
             at ./compiler/rustc_data_structures/src/stack.rs:16:5
  16: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:73:17
  17: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1732:50
  18: rustc_middle::ty::context::tls::set_tlv
             at ./compiler/rustc_middle/src/ty/context.rs:1716:9
  19: rustc_middle::ty::context::tls::enter_context
             at ./compiler/rustc_middle/src/ty/context.rs:1732:9
  20: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:72:13
  21: rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1776:13
  22: rustc_middle::ty::context::tls::with_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1760:40
  23: rustc_middle::ty::context::tls::with_context_opt
             at ./compiler/rustc_middle/src/ty/context.rs:1749:22
  24: rustc_middle::ty::context::tls::with_context
             at ./compiler/rustc_middle/src/ty/context.rs:1760:9
  25: rustc_middle::ty::context::tls::with_related_context
             at ./compiler/rustc_middle/src/ty/context.rs:1773:9
  26: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:61:9
  27: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}
             at ./compiler/rustc_query_system/src/query/plumbing.rs:597:9
  28: rustc_query_system::query::plumbing::with_diagnostics
             at ./compiler/rustc_query_system/src/query/plumbing.rs:302:18
  29: rustc_query_system::query::plumbing::force_query_with_job
             at ./compiler/rustc_query_system/src/query/plumbing.rs:596:51
  30: rustc_query_system::query::plumbing::try_execute_query
             at ./compiler/rustc_query_system/src/query/plumbing.rs:426:16
  31: rustc_query_system::query::plumbing::get_query_impl::{{closure}}
             at ./compiler/rustc_query_system/src/query/plumbing.rs:644:23
  32: <rustc_query_system::query::caches::DefaultCache<K,V> as rustc_query_system::query::caches::QueryCache>::lookup
             at ./compiler/rustc_query_system/src/query/caches.rs:114:79
  33: rustc_query_system::query::plumbing::try_get_cached
             at ./compiler/rustc_query_system/src/query/plumbing.rs:379:5
  34: rustc_query_system::query::plumbing::get_query_impl
             at ./compiler/rustc_query_system/src/query/plumbing.rs:636:5
  35: rustc_query_system::query::plumbing::get_query
             at ./compiler/rustc_query_system/src/query/plumbing.rs:738:5
  36: rustc_middle::ty::query::TyCtxtAt::type_of
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:487:17
  37: rustc_middle::ty::query::<impl rustc_middle::ty::context::TyCtxt>::type_of
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:448:17
  38: rustc_mir::monomorphize::polymorphize::mark_used_by_default_parameters
             at ./compiler/rustc_mir/src/monomorphize/polymorphize.rs:145:60
  39: rustc_mir::monomorphize::polymorphize::mark_used_by_default_parameters
             at ./compiler/rustc_mir/src/monomorphize/polymorphize.rs:160:9
  40: rustc_mir::monomorphize::polymorphize::unused_generic_params
             at ./compiler/rustc_mir/src/monomorphize/polymorphize.rs:67:5
  41: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::unused_generic_params>::compute
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:377:17
  42: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
             at ./compiler/rustc_query_system/src/dep_graph/graph.rs:362:14
  43: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
             at ./compiler/rustc_query_system/src/dep_graph/graph.rs:245:9
  44: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}::{{closure}}
             at ./compiler/rustc_query_system/src/query/plumbing.rs:607:17
  45: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}::{{closure}}
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:73:74
  46: stacker::maybe_grow
             at /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/stacker-0.1.12/src/lib.rs:55:9
  47: rustc_data_structures::stack::ensure_sufficient_stack
             at ./compiler/rustc_data_structures/src/stack.rs:16:5
  48: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}::{{closure}}
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:73:17
  49: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1732:50
  50: rustc_middle::ty::context::tls::set_tlv
             at ./compiler/rustc_middle/src/ty/context.rs:1716:9
  51: rustc_middle::ty::context::tls::enter_context
             at ./compiler/rustc_middle/src/ty/context.rs:1732:9
  52: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query::{{closure}}
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:72:13
  53: rustc_middle::ty::context::tls::with_related_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1776:13
  54: rustc_middle::ty::context::tls::with_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1760:40
  55: rustc_middle::ty::context::tls::with_context_opt
             at ./compiler/rustc_middle/src/ty/context.rs:1749:22
  56: rustc_middle::ty::context::tls::with_context
             at ./compiler/rustc_middle/src/ty/context.rs:1760:9
  57: rustc_middle::ty::context::tls::with_related_context
             at ./compiler/rustc_middle/src/ty/context.rs:1773:9
  58: rustc_middle::ty::query::plumbing::<impl rustc_query_system::query::QueryContext for rustc_middle::ty::context::TyCtxt>::start_query
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:61:9
  59: rustc_query_system::query::plumbing::force_query_with_job::{{closure}}
             at ./compiler/rustc_query_system/src/query/plumbing.rs:597:9
  60: rustc_query_system::query::plumbing::with_diagnostics
             at ./compiler/rustc_query_system/src/query/plumbing.rs:302:18
  61: rustc_query_system::query::plumbing::force_query_with_job
             at ./compiler/rustc_query_system/src/query/plumbing.rs:596:51
  62: rustc_query_system::query::plumbing::try_execute_query
             at ./compiler/rustc_query_system/src/query/plumbing.rs:426:16
  63: rustc_query_system::query::plumbing::get_query_impl::{{closure}}
             at ./compiler/rustc_query_system/src/query/plumbing.rs:644:23
  64: <rustc_query_system::query::caches::DefaultCache<K,V> as rustc_query_system::query::caches::QueryCache>::lookup
             at ./compiler/rustc_query_system/src/query/caches.rs:114:79
  65: rustc_query_system::query::plumbing::try_get_cached
             at ./compiler/rustc_query_system/src/query/plumbing.rs:379:5
  66: rustc_query_system::query::plumbing::get_query_impl
             at ./compiler/rustc_query_system/src/query/plumbing.rs:636:5
  67: rustc_query_system::query::plumbing::get_query
             at ./compiler/rustc_query_system/src/query/plumbing.rs:738:5
  68: rustc_middle::ty::query::TyCtxtAt::unused_generic_params
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:487:17
  69: rustc_middle::ty::query::<impl rustc_middle::ty::context::TyCtxt>::unused_generic_params
             at ./compiler/rustc_middle/src/ty/query/plumbing.rs:448:17
  70: rustc_metadata::rmeta::encoder::EncodeContext::encode_mir_for_ctfe
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1142:22
  71: rustc_metadata::rmeta::encoder::EncodeContext::encode_info_for_anon_const
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1524:9
  72: <rustc_metadata::rmeta::encoder::EncodeContext as rustc_hir::intravisit::Visitor>::visit_anon_const
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1817:9
  73: rustc_hir::intravisit::walk_generic_args
             at ./compiler/rustc_hir/src/intravisit.rs:774:5
  74: rustc_hir::intravisit::Visitor::visit_generic_args
             at ./compiler/rustc_hir/src/intravisit.rs:464:9
  75: rustc_hir::intravisit::walk_path_segment
             at ./compiler/rustc_hir/src/intravisit.rs:765:9
  76: rustc_hir::intravisit::Visitor::visit_path_segment
             at ./compiler/rustc_hir/src/intravisit.rs:461:9
  77: rustc_hir::intravisit::walk_path
             at ./compiler/rustc_hir/src/intravisit.rs:753:9
  78: rustc_hir::intravisit::Visitor::visit_path
             at ./compiler/rustc_hir/src/intravisit.rs:458:9
  79: rustc_hir::intravisit::walk_trait_ref
             at ./compiler/rustc_hir/src/intravisit.rs:554:5
  80: rustc_hir::intravisit::Visitor::visit_trait_ref
             at ./compiler/rustc_hir/src/intravisit.rs:408:9
  81: rustc_hir::intravisit::walk_poly_trait_ref
             at ./compiler/rustc_hir/src/intravisit.rs:549:5
  82: rustc_hir::intravisit::Visitor::visit_poly_trait_ref
             at ./compiler/rustc_hir/src/intravisit.rs:414:9
  83: rustc_hir::intravisit::walk_param_bound
             at ./compiler/rustc_hir/src/intravisit.rs:860:13
  84: rustc_hir::intravisit::walk_trait_item
             at ./compiler/rustc_hir/src/intravisit.rs:988:13
  85: rustc_hir::intravisit::Visitor::visit_trait_item
             at ./compiler/rustc_hir/src/intravisit.rs:393:9
  86: <rustc_hir::intravisit::DeepVisitor<V> as rustc_hir::itemlikevisit::ItemLikeVisitor>::visit_trait_item
             at ./compiler/rustc_hir/src/intravisit.rs:61:9
  87: rustc_hir::hir::Crate::visit_all_item_likes
             at ./compiler/rustc_hir/src/hir.rs:686:13
  88: rustc_metadata::rmeta::encoder::EncodeContext::encode_info_for_items
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:443:9
  89: rustc_metadata::rmeta::encoder::EncodeContext::encode_crate_root
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:578:9
  90: rustc_metadata::rmeta::encoder::encode_metadata_impl
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2160:16
  91: rustc_metadata::rmeta::encoder::encode_metadata::{{closure}}
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2100:12
  92: rustc_data_structures::sync::join
             at ./compiler/rustc_data_structures/src/sync.rs:159:14
  93: rustc_metadata::rmeta::encoder::encode_metadata
             at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2099:5
  94: rustc_metadata::rmeta::decoder::cstore_impl::<impl rustc_middle::middle::cstore::CrateStore for rustc_metadata::creader::CStore>::encode_metadata
             at ./compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs:530:9
  95: rustc_middle::ty::context::TyCtxt::encode_metadata
             at ./compiler/rustc_middle/src/ty/context.rs:1295:9
  96: rustc_interface::passes::encode_and_write_metadata
             at ./compiler/rustc_interface/src/passes.rs:965:66
  97: rustc_interface::passes::start_codegen
             at ./compiler/rustc_interface/src/passes.rs:1010:44
  98: rustc_interface::queries::Queries::ongoing_codegen::{{closure}}::{{closure}}
             at ./compiler/rustc_interface/src/queries.rs:286:20
  99: rustc_interface::passes::QueryContext::enter::{{closure}}
             at ./compiler/rustc_interface/src/passes.rs:742:42
 100: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at ./compiler/rustc_middle/src/ty/context.rs:1732:50
 101: rustc_middle::ty::context::tls::set_tlv
             at ./compiler/rustc_middle/src/ty/context.rs:1716:9
 102: rustc_middle::ty::context::tls::enter_context
             at ./compiler/rustc_middle/src/ty/context.rs:1732:9
 103: rustc_interface::passes::QueryContext::enter
             at ./compiler/rustc_interface/src/passes.rs:742:9
 104: rustc_interface::queries::Queries::ongoing_codegen::{{closure}}
             at ./compiler/rustc_interface/src/queries.rs:277:13
 105: rustc_interface::queries::Query<T>::compute
             at ./compiler/rustc_interface/src/queries.rs:39:28
 106: rustc_interface::queries::Queries::ongoing_codegen
             at ./compiler/rustc_interface/src/queries.rs:275:9
 107: rustc_driver::run_compiler::{{closure}}::{{closure}}
             at ./compiler/rustc_driver/src/lib.rs:446:13
 108: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
             at ./compiler/rustc_interface/src/queries.rs:418:19
 109: rustc_driver::run_compiler::{{closure}}
             at ./compiler/rustc_driver/src/lib.rs:341:22
 110: rustc_interface::interface::create_compiler_and_run::{{closure}}
             at ./compiler/rustc_interface/src/interface.rs:197:13
 111: rustc_span::with_source_map
             at ./compiler/rustc_span/src/lib.rs:787:5
 112: rustc_interface::interface::create_compiler_and_run
             at ./compiler/rustc_interface/src/interface.rs:191:5
 113: rustc_interface::interface::run_compiler::{{closure}}
             at ./compiler/rustc_interface/src/interface.rs:213:12
 114: rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals::{{closure}}::{{closure}}
             at ./compiler/rustc_interface/src/util.rs:152:13
 115: scoped_tls::ScopedKey<T>::set
             at /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137:9
 116: rustc_span::with_session_globals
             at ./compiler/rustc_span/src/lib.rs:103:5
 117: rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals::{{closure}}
             at ./compiler/rustc_interface/src/util.rs:150:9
 118: rustc_interface::util::scoped_thread::{{closure}}
             at ./compiler/rustc_interface/src/util.rs:125:24
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.51.0-dev running on x86_64-unknown-linux-gnu

note: compiler flags: -Z threads=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z emit-future-incompat-report -Z unstable-options -C prefer-dynamic -C rpath -C debuginfo=0 --crate-type dylib

query stack during panic:
#0 [type_of] computing type of `Bar::Assoc`
#1 [unused_generic_params] determining which generic parameters are unused by `Bar::Assoc::{constant#0}`
end of query stack
error: aborting due to previous error


------------------------------------------

I'll spend some time looking into these but given that they were essentially regressions in polymorphization introduced from #78407 (unfortunately, polymorphization has a habit of producing the strangest errors so any change to polymorphization really needs to be tested with polymorphization enabled), I've just disabled checking constants for now so that this PR can proceed :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh... I did touch the _with_const_arg logic, I'll run tests with polymorphization and look into fixing that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did some digging. The cycle error with polymorphization occurs since this test was created 5 months ago, so it's not caused by my PR. Since it works otherwise, polymorphization will need duplicate the cycle prevention logic we have for wf-checks of const_evaluatable_checked

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ICE is also unrelated to my PR, but in contrast to the cycle, I know exactly how to fix it:

if !tcx.is_trait(def_id) && (tcx.is_closure(def_id) || tcx.type_of(def_id).is_generator()) {

should be a match on tcx.def_kind(def_id) instead of invoking type_of, which can fail if the item has no type (like here, an associated type in a trait declaration)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And since I already had a worktree open for this: #82765

// of writing, can result in an ICE from typeck in one test and a cycle error in another.
Some(_) => false,
None if !tcx.is_mir_available(def_id) => {
debug!("should_polymorphize: (no mir available) def_id={:?}", def_id);
false
}
None => true,
}
}

/// 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.
Expand Down Expand Up @@ -220,7 +254,9 @@ 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).
fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) {
let unused = self.tcx.unused_generic_params(def_id);
let unused = self
.tcx
.unused_generic_params(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)));
debug!(
"visit_child_body: unused_parameters={:?} unused={:?}",
self.unused_parameters, unused
Expand Down