Skip to content
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

Monomorphize in check mode to report (almost) all PMEs #107510

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
13 changes: 4 additions & 9 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ pub fn crates_export_threshold(crate_types: &[CrateType]) -> SymbolExportLevel {
fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<SymbolExportInfo> {
assert_eq!(cnum, LOCAL_CRATE);

if !tcx.sess.opts.output_types.should_codegen() {
return Default::default();
}

// Check to see if this crate is a "special runtime crate". These
// crates, implementation details of the standard library, typically
// have a bunch of `pub extern` and `#[no_mangle]` functions as the
Expand Down Expand Up @@ -172,10 +168,6 @@ fn exported_symbols_provider_local(
) -> &[(ExportedSymbol<'_>, SymbolExportInfo)] {
assert_eq!(cnum, LOCAL_CRATE);

if !tcx.sess.opts.output_types.should_codegen() {
return &[];
}

// FIXME: Sorting this is unnecessary since we are sorting later anyway.
// Can we skip the later sorting?
let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| {
Expand Down Expand Up @@ -289,7 +281,10 @@ fn exported_symbols_provider_local(
));
}

if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() {
if tcx.sess.opts.share_generics()
&& tcx.local_crate_exports_generics()
&& tcx.sess.opts.output_types.should_codegen()
{
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
use rustc_middle::ty::InstanceDef;

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ fn run_compiler(

queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?;

if !sess.opts.output_types.should_codegen() && sess.compile_status().is_ok() {
queries.global_ctxt()?.enter(|tcx| tcx.collect_crate_mono_items_for_check(()));
}

if callbacks.after_analysis(compiler, queries) == Compilation::Stop {
return early_exit();
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,11 @@ rustc_queries! {
desc { "collect_and_partition_mono_items" }
}

query collect_crate_mono_items_for_check(_: ()) {
eval_always
desc { "monomorphize the crate graph" }
}

query is_codegened_item(def_id: DefId) -> bool {
desc { |tcx| "determining whether `{}` needs codegen", tcx.def_path_str(def_id) }
}
Expand Down
51 changes: 42 additions & 9 deletions compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,14 @@ use crate::errors::{
EncounteredErrorWhileInstantiating, LargeAssignmentsLint, RecursionLimit, TypeLengthLimit,
};

#[derive(PartialEq)]
#[derive(Debug, Copy, Clone)]
pub enum MonoItemCollectionMode {
Eager,
Eager {
/// Whether to use optimized mir for collection or just analyis MIR.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Whether to use optimized mir for collection or just analyis MIR.
/// Whether to use optimized mir for collection or just analysis MIR.

/// By default uses optimized mir, but for `cargo check` we use unoptimized mir,
/// as that is faster.
optimized_mir: bool,
},
Lazy,
}

Expand Down Expand Up @@ -351,6 +356,7 @@ pub fn collect_crate_mono_items(
&mut recursion_depths,
recursion_limit,
inlining_map,
mode,
);
});
});
Expand Down Expand Up @@ -408,6 +414,7 @@ fn collect_items_rec<'tcx>(
recursion_depths: &mut DefIdMap<usize>,
recursion_limit: Limit,
inlining_map: MTRef<'_, MTLock<InliningMap<'tcx>>>,
mode: MonoItemCollectionMode,
) {
if !visited.lock_mut().insert(starting_point.node) {
// We've been here already, no need to search again.
Expand Down Expand Up @@ -476,7 +483,7 @@ fn collect_items_rec<'tcx>(
check_type_length_limit(tcx, instance);

rustc_data_structures::stack::ensure_sufficient_stack(|| {
collect_neighbours(tcx, instance, &mut neighbors);
collect_neighbours(tcx, instance, &mut neighbors, mode);
});
}
MonoItem::GlobalAsm(item_id) => {
Expand Down Expand Up @@ -532,7 +539,15 @@ fn collect_items_rec<'tcx>(
inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors.items);

for (neighbour, _) in neighbors.items {
collect_items_rec(tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map);
collect_items_rec(
tcx,
neighbour,
visited,
recursion_depths,
recursion_limit,
inlining_map,
mode,
);
}

if let Some((def_id, depth)) = recursion_depth_reset {
Expand Down Expand Up @@ -1191,7 +1206,7 @@ impl<'v> RootCollector<'_, 'v> {
fn process_item(&mut self, id: hir::ItemId) {
match self.tcx.def_kind(id.owner_id) {
DefKind::Enum | DefKind::Struct | DefKind::Union => {
if self.mode == MonoItemCollectionMode::Eager
if let MonoItemCollectionMode::Eager { .. } = self.mode
&& self.tcx.generics_of(id.owner_id).count() == 0
{
debug!("RootCollector: ADT drop-glue for `{id:?}`",);
Expand Down Expand Up @@ -1224,7 +1239,7 @@ impl<'v> RootCollector<'_, 'v> {
}
}
DefKind::Impl { .. } => {
if self.mode == MonoItemCollectionMode::Eager {
if let MonoItemCollectionMode::Eager { .. } = self.mode {
create_mono_items_for_default_impls(self.tcx, id, self.output);
}
}
Expand All @@ -1244,7 +1259,7 @@ impl<'v> RootCollector<'_, 'v> {
fn is_root(&self, def_id: LocalDefId) -> bool {
!item_requires_monomorphization(self.tcx, def_id)
&& match self.mode {
MonoItemCollectionMode::Eager => true,
MonoItemCollectionMode::Eager { .. } => true,
MonoItemCollectionMode::Lazy => {
self.entry_fn.and_then(|(id, _)| id.as_local()) == Some(def_id)
|| self.tcx.is_reachable_non_generic(def_id)
Expand Down Expand Up @@ -1396,9 +1411,27 @@ fn collect_neighbours<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
output: &mut MonoItems<'tcx>,
mode: MonoItemCollectionMode,
) {
let body = tcx.instance_mir(instance.def);
MirNeighborCollector { tcx, body: &body, output, instance }.visit_body(&body);
let mut collect = |body: &mir::Body<'tcx>| {
MirNeighborCollector { tcx, body: &body, output, instance }.visit_body(body)
};
if let MonoItemCollectionMode::Eager { optimized_mir: false } = mode {
if let ty::InstanceDef::Item(def) = instance.def {
let def_kind = tcx.def_kind(def.did);
match def_kind {
// Generators get their optimized_mir taken (and thus drop elab mir stolen) in order
// to compute their Send/Sync bounds.
DefKind::Generator |
DefKind::Ctor(..) => {},
_ => if let Some(def) = def.as_local() && !tcx.sess.opts.unstable_opts.polymorphize {
collect(&*tcx.mir_drops_elaborated_and_const_checked(def).borrow());
return;
},
}
}
}
collect(tcx.instance_mir(instance.def));
}

#[instrument(skip(tcx, output), level = "debug")]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_monomorphize/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(array_windows)]
#![feature(let_chains)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_monomorphize/src/partitioning/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,20 @@ where
}
}

fn collect_crate_mono_items_for_check(tcx: TyCtxt<'_>, (): ()) {
collector::collect_crate_mono_items(
tcx,
MonoItemCollectionMode::Eager { optimized_mir: false },
);
}

fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[CodegenUnit<'_>]) {
let collection_mode = match tcx.sess.opts.unstable_opts.print_mono_items {
Some(ref s) => {
let mode = s.to_lowercase();
let mode = mode.trim();
if mode == "eager" {
MonoItemCollectionMode::Eager
MonoItemCollectionMode::Eager { optimized_mir: true }
} else {
if mode != "lazy" {
tcx.sess.emit_warning(UnknownCguCollectionMode { mode });
Expand All @@ -364,7 +371,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
}
None => {
if tcx.sess.link_dead_code() {
MonoItemCollectionMode::Eager
MonoItemCollectionMode::Eager { optimized_mir: true }
} else {
MonoItemCollectionMode::Lazy
}
Expand Down Expand Up @@ -582,6 +589,7 @@ fn codegened_and_inlined_items(tcx: TyCtxt<'_>, (): ()) -> &DefIdSet {

pub fn provide(providers: &mut Providers) {
providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
providers.collect_crate_mono_items_for_check = collect_crate_mono_items_for_check;
providers.codegened_and_inlined_items = codegened_and_inlined_items;

providers.is_codegened_item = |tcx, def_id| {
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/associated-consts/defaults-cyclic-fail.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// build-fail

// Cyclic assoc. const defaults don't error unless *used*
trait Tr {
const A: u8 = Self::B;
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/associated-consts/defaults-cyclic-fail.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0391]: cycle detected when const-evaluating + checking `Tr::A`
--> $DIR/defaults-cyclic-fail.rs:5:19
--> $DIR/defaults-cyclic-fail.rs:3:19
|
LL | const A: u8 = Self::B;
| ^^^^^^^
|
note: ...which requires const-evaluating + checking `Tr::B`...
--> $DIR/defaults-cyclic-fail.rs:8:19
--> $DIR/defaults-cyclic-fail.rs:6:19
|
LL | const B: u8 = Self::A;
| ^^^^^^^
= note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle
note: cycle used when const-evaluating + checking `main::promoted[1]`
--> $DIR/defaults-cyclic-fail.rs:16:16
--> $DIR/defaults-cyclic-fail.rs:14:16
|
LL | assert_eq!(<() as Tr>::A, 0);
| ^^^^^^^^^^^^^
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/associated-consts/defaults-not-assumed-fail.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// build-fail

trait Tr {
const A: u8 = 255;

Expand Down
16 changes: 4 additions & 12 deletions tests/ui/associated-consts/defaults-not-assumed-fail.stderr
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
error[E0080]: evaluation of `<() as Tr>::B` failed
--> $DIR/defaults-not-assumed-fail.rs:8:19
--> $DIR/defaults-not-assumed-fail.rs:6:19
|
LL | const B: u8 = Self::A + 1;
| ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow

note: erroneous constant used
--> $DIR/defaults-not-assumed-fail.rs:33:16
--> $DIR/defaults-not-assumed-fail.rs:31:16
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^

note: erroneous constant used
--> $DIR/defaults-not-assumed-fail.rs:33:5
--> $DIR/defaults-not-assumed-fail.rs:31:5
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
--> $DIR/defaults-not-assumed-fail.rs:33:5
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
--> $DIR/defaults-not-assumed-fail.rs:33:5
--> $DIR/defaults-not-assumed-fail.rs:31:5
|
LL | assert_eq!(<() as Tr>::B, 0); // causes the error above
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/async-await/large_moves.attribute.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: moving 10024 bytes
--> $DIR/large_moves.rs:13:13
--> $DIR/large_moves.rs:12:13
|
LL | let x = async {
| _____________^
Expand All @@ -18,23 +18,23 @@ LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^

error: moving 10024 bytes
--> $DIR/large_moves.rs:19:14
--> $DIR/large_moves.rs:18:14
|
LL | let z = (x, 42);
| ^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`

error: moving 10024 bytes
--> $DIR/large_moves.rs:19:13
--> $DIR/large_moves.rs:18:13
|
LL | let z = (x, 42);
| ^^^^^^^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`

error: moving 10024 bytes
--> $DIR/large_moves.rs:21:13
--> $DIR/large_moves.rs:20:13
|
LL | let a = z.0;
| ^^^ value moved from here
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/async-await/large_moves.option.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: moving 10024 bytes
--> $DIR/large_moves.rs:13:13
--> $DIR/large_moves.rs:12:13
|
LL | let x = async {
| _____________^
Expand All @@ -18,23 +18,23 @@ LL | #![deny(large_assignments)]
| ^^^^^^^^^^^^^^^^^

error: moving 10024 bytes
--> $DIR/large_moves.rs:19:14
--> $DIR/large_moves.rs:18:14
|
LL | let z = (x, 42);
| ^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`

error: moving 10024 bytes
--> $DIR/large_moves.rs:19:13
--> $DIR/large_moves.rs:18:13
|
LL | let z = (x, 42);
| ^^^^^^^ value moved from here
|
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`

error: moving 10024 bytes
--> $DIR/large_moves.rs:21:13
--> $DIR/large_moves.rs:20:13
|
LL | let a = z.0;
| ^^^ value moved from here
Expand Down
1 change: 0 additions & 1 deletion tests/ui/async-await/large_moves.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![deny(large_assignments)]
#![feature(large_assignments)]
#![cfg_attr(attribute, move_size_limit = "1000")]
// build-fail
// only-x86_64
// revisions: attribute option
// [option]compile-flags: -Zmove-size-limit=1000
Expand Down

This file was deleted.

12 changes: 0 additions & 12 deletions tests/ui/async-await/recursive-async-impl-trait-type.stderr

This file was deleted.

Loading