From 456007af125d3822285135659ea5ea0b67084b66 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Tue, 29 Aug 2023 19:29:14 +0200 Subject: [PATCH 1/5] Emit error instead of ICE when optimized MIR is missing Closes 51388. --- compiler/rustc_monomorphize/messages.ftl | 4 ++++ compiler/rustc_monomorphize/src/collector.rs | 8 ++++++-- compiler/rustc_monomorphize/src/errors.rs | 10 +++++++++- tests/ui/rmeta/auxiliary/rmeta-meta.rs | 4 ++++ tests/ui/rmeta/no_optitimized_mir.rs | 11 +++++++++++ tests/ui/rmeta/no_optitimized_mir.stderr | 10 ++++++++++ 6 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 tests/ui/rmeta/no_optitimized_mir.rs create mode 100644 tests/ui/rmeta/no_optitimized_mir.stderr diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index fdd47e6f79b..2b7d9bd3413 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -14,6 +14,10 @@ monomorphize_large_assignments = .label = value moved from here .note = The current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` +monomorphize_no_optimized_mir = + missing optimized MIR for an item in the crate `{$crate_name}` + .note = missing optimized MIR for this item (was the crate `{$crate_name}` compiled with `--emit=metadata`?) + monomorphize_recursion_limit = reached the recursion limit while instantiating `{$shrunk}` .note = `{$def_path_str}` defined here diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f917e52109a..dfe534d5b65 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -192,7 +192,8 @@ use std::path::PathBuf; use crate::errors::{ - EncounteredErrorWhileInstantiating, LargeAssignmentsLint, RecursionLimit, TypeLengthLimit, + EncounteredErrorWhileInstantiating, LargeAssignmentsLint, NoOptimizedMir, RecursionLimit, + TypeLengthLimit, }; #[derive(PartialEq)] @@ -950,7 +951,10 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> } if !tcx.is_mir_available(def_id) { - bug!("no MIR available for {:?}", def_id); + tcx.sess.emit_fatal(NoOptimizedMir { + span: tcx.def_span(def_id), + crate_name: tcx.crate_name(def_id.krate), + }); } true diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 495a73490a2..fdcc95f137f 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -4,7 +4,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_errors::IntoDiagnostic; use rustc_macros::{Diagnostic, LintDiagnostic}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag(monomorphize_recursion_limit)] @@ -33,6 +33,14 @@ pub struct TypeLengthLimit { pub type_length: usize, } +#[derive(Diagnostic)] +#[diag(monomorphize_no_optimized_mir)] +pub struct NoOptimizedMir { + #[note] + pub span: Span, + pub crate_name: Symbol, +} + pub struct UnusedGenericParamsHint { pub span: Span, pub param_spans: Vec, diff --git a/tests/ui/rmeta/auxiliary/rmeta-meta.rs b/tests/ui/rmeta/auxiliary/rmeta-meta.rs index 6d8ed95bd38..6d435049527 100644 --- a/tests/ui/rmeta/auxiliary/rmeta-meta.rs +++ b/tests/ui/rmeta/auxiliary/rmeta-meta.rs @@ -6,3 +6,7 @@ pub struct Foo { pub field: i32, } + +pub fn missing_optimized_mir() { + println!("indeed"); +} diff --git a/tests/ui/rmeta/no_optitimized_mir.rs b/tests/ui/rmeta/no_optitimized_mir.rs new file mode 100644 index 00000000000..c503005f16b --- /dev/null +++ b/tests/ui/rmeta/no_optitimized_mir.rs @@ -0,0 +1,11 @@ +// aux-build:rmeta-meta.rs +// no-prefer-dynamic +// build-fail + +// Check that we do not ICE when we need optimized MIR but it is missing. + +extern crate rmeta_meta; + +fn main() { + rmeta_meta::missing_optimized_mir(); +} diff --git a/tests/ui/rmeta/no_optitimized_mir.stderr b/tests/ui/rmeta/no_optitimized_mir.stderr new file mode 100644 index 00000000000..a17024c5310 --- /dev/null +++ b/tests/ui/rmeta/no_optitimized_mir.stderr @@ -0,0 +1,10 @@ +error: missing optimized MIR for an item in the crate `rmeta_meta` + | +note: missing optimized MIR for this item (was the crate `rmeta_meta` compiled with `--emit=metadata`?) + --> $DIR/auxiliary/rmeta-meta.rs:10:1 + | +LL | pub fn missing_optimized_mir() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From f686bd89494b21819e78cc4f89ebcd0e448d8809 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sat, 2 Sep 2023 19:11:54 -0400 Subject: [PATCH 2/5] Take `&mut Results` in `ResultsVisitor` --- compiler/rustc_borrowck/src/lib.rs | 6 +++--- .../rustc_mir_dataflow/src/framework/graphviz.rs | 12 ++++++------ compiler/rustc_mir_dataflow/src/framework/visitor.rs | 12 ++++++------ .../rustc_mir_transform/src/dataflow_const_prop.rs | 6 +++--- compiler/rustc_mir_transform/src/generator.rs | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 770c180ff2c..8115c61e89d 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -603,7 +603,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro fn visit_statement_before_primary_effect( &mut self, - _results: &R, + _results: &mut R, flow_state: &Flows<'cx, 'tcx>, stmt: &'cx Statement<'tcx>, location: Location, @@ -673,7 +673,7 @@ fn visit_statement_before_primary_effect( fn visit_terminator_before_primary_effect( &mut self, - _results: &R, + _results: &mut R, flow_state: &Flows<'cx, 'tcx>, term: &'cx Terminator<'tcx>, loc: Location, @@ -784,7 +784,7 @@ fn visit_terminator_before_primary_effect( fn visit_terminator_after_primary_effect( &mut self, - _results: &R, + _results: &mut R, flow_state: &Flows<'cx, 'tcx>, term: &'cx Terminator<'tcx>, loc: Location, diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 1421d9b45cd..bdddaaebca4 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -538,7 +538,7 @@ impl<'tcx, A> ResultsVisitor<'_, 'tcx, Results<'tcx, A>> for StateDiffCollector< fn visit_block_start( &mut self, - _results: &Results<'tcx, A>, + _results: &mut Results<'tcx, A>, state: &Self::FlowState, _block_data: &mir::BasicBlockData<'tcx>, _block: BasicBlock, @@ -550,7 +550,7 @@ fn visit_block_start( fn visit_block_end( &mut self, - _results: &Results<'tcx, A>, + _results: &mut Results<'tcx, A>, state: &Self::FlowState, _block_data: &mir::BasicBlockData<'tcx>, _block: BasicBlock, @@ -562,7 +562,7 @@ fn visit_block_end( fn visit_statement_before_primary_effect( &mut self, - results: &Results<'tcx, A>, + results: &mut Results<'tcx, A>, state: &Self::FlowState, _statement: &mir::Statement<'tcx>, _location: Location, @@ -575,7 +575,7 @@ fn visit_statement_before_primary_effect( fn visit_statement_after_primary_effect( &mut self, - results: &Results<'tcx, A>, + results: &mut Results<'tcx, A>, state: &Self::FlowState, _statement: &mir::Statement<'tcx>, _location: Location, @@ -586,7 +586,7 @@ fn visit_statement_after_primary_effect( fn visit_terminator_before_primary_effect( &mut self, - results: &Results<'tcx, A>, + results: &mut Results<'tcx, A>, state: &Self::FlowState, _terminator: &mir::Terminator<'tcx>, _location: Location, @@ -599,7 +599,7 @@ fn visit_terminator_before_primary_effect( fn visit_terminator_after_primary_effect( &mut self, - results: &Results<'tcx, A>, + results: &mut Results<'tcx, A>, state: &Self::FlowState, _terminator: &mir::Terminator<'tcx>, _location: Location, diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs index 76a72982781..3cfa7cc1c02 100644 --- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs @@ -35,7 +35,7 @@ pub trait ResultsVisitor<'mir, 'tcx, R> { fn visit_block_start( &mut self, - _results: &R, + _results: &mut R, _state: &Self::FlowState, _block_data: &'mir mir::BasicBlockData<'tcx>, _block: BasicBlock, @@ -46,7 +46,7 @@ fn visit_block_start( /// its `statement_effect`. fn visit_statement_before_primary_effect( &mut self, - _results: &R, + _results: &mut R, _state: &Self::FlowState, _statement: &'mir mir::Statement<'tcx>, _location: Location, @@ -57,7 +57,7 @@ fn visit_statement_before_primary_effect( /// statement applied to `state`. fn visit_statement_after_primary_effect( &mut self, - _results: &R, + _results: &mut R, _state: &Self::FlowState, _statement: &'mir mir::Statement<'tcx>, _location: Location, @@ -68,7 +68,7 @@ fn visit_statement_after_primary_effect( /// its `terminator_effect`. fn visit_terminator_before_primary_effect( &mut self, - _results: &R, + _results: &mut R, _state: &Self::FlowState, _terminator: &'mir mir::Terminator<'tcx>, _location: Location, @@ -81,7 +81,7 @@ fn visit_terminator_before_primary_effect( /// The `call_return_effect` (if one exists) will *not* be applied to `state`. fn visit_terminator_after_primary_effect( &mut self, - _results: &R, + _results: &mut R, _state: &Self::FlowState, _terminator: &'mir mir::Terminator<'tcx>, _location: Location, @@ -90,7 +90,7 @@ fn visit_terminator_after_primary_effect( fn visit_block_end( &mut self, - _results: &R, + _results: &mut R, _state: &Self::FlowState, _block_data: &'mir mir::BasicBlockData<'tcx>, _block: BasicBlock, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 3a1ef3e7d64..d4c9163b571 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -401,7 +401,7 @@ impl<'mir, 'tcx> fn visit_statement_before_primary_effect( &mut self, - results: &Results<'tcx, ValueAnalysisWrapper>>, + results: &mut Results<'tcx, ValueAnalysisWrapper>>, state: &Self::FlowState, statement: &'mir Statement<'tcx>, location: Location, @@ -417,7 +417,7 @@ fn visit_statement_before_primary_effect( fn visit_statement_after_primary_effect( &mut self, - results: &Results<'tcx, ValueAnalysisWrapper>>, + results: &mut Results<'tcx, ValueAnalysisWrapper>>, state: &Self::FlowState, statement: &'mir Statement<'tcx>, location: Location, @@ -443,7 +443,7 @@ fn visit_statement_after_primary_effect( fn visit_terminator_before_primary_effect( &mut self, - results: &Results<'tcx, ValueAnalysisWrapper>>, + results: &mut Results<'tcx, ValueAnalysisWrapper>>, state: &Self::FlowState, terminator: &'mir Terminator<'tcx>, location: Location, diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 1e7161189c3..eae83448c46 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -814,7 +814,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> fn visit_statement_before_primary_effect( &mut self, - _results: &R, + _results: &mut R, state: &Self::FlowState, _statement: &'mir Statement<'tcx>, loc: Location, @@ -824,7 +824,7 @@ fn visit_statement_before_primary_effect( fn visit_terminator_before_primary_effect( &mut self, - _results: &R, + _results: &mut R, state: &Self::FlowState, _terminator: &'mir Terminator<'tcx>, loc: Location, From 789451b43a068b10b7073b8a3194c1c2128b48b2 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sun, 3 Sep 2023 08:15:25 +0200 Subject: [PATCH 3/5] Allow `large_assignments` for Box/Arc/Rc initialization Does the `stop linting in box/arc initialization` task of 83518. --- compiler/rustc_monomorphize/src/collector.rs | 101 ++++++++++++++++-- .../async-await/large_moves.attribute.stderr | 22 +++- .../ui/async-await/large_moves.option.stderr | 22 +++- tests/ui/async-await/large_moves.rs | 18 ++++ 4 files changed, 147 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index bf88360a8c1..77f19423318 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -179,8 +179,8 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, - VtblEntry, + self, AssocKind, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, VtblEntry, }; use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; @@ -188,6 +188,7 @@ use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; use rustc_session::Limit; use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP}; +use rustc_span::symbol::{sym, Ident}; use rustc_target::abi::Size; use std::path::PathBuf; @@ -431,7 +432,7 @@ fn collect_items_rec<'tcx>( hir::InlineAsmOperand::SymFn { anon_const } => { let fn_ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); - visit_fn_use(tcx, fn_ty, false, *op_sp, &mut used_items); + visit_fn_use(tcx, fn_ty, false, *op_sp, &mut used_items, &[]); } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { let instance = Instance::mono(tcx, *def_id); @@ -592,6 +593,11 @@ struct MirUsedCollector<'a, 'tcx> { instance: Instance<'tcx>, /// Spans for move size lints already emitted. Helps avoid duplicate lints. move_size_spans: Vec, + /// If true, we should temporarily skip move size checks, because we are + /// processing an operand to a `skip_move_check_fns` function call. + skip_move_size_check: bool, + /// Set of functions for which it is OK to move large data into. + skip_move_check_fns: Vec, } impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { @@ -690,7 +696,14 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) { ) => { let fn_ty = operand.ty(self.body, self.tcx); let fn_ty = self.monomorphize(fn_ty); - visit_fn_use(self.tcx, fn_ty, false, span, &mut self.output); + visit_fn_use( + self.tcx, + fn_ty, + false, + span, + &mut self.output, + &self.skip_move_check_fns, + ); } mir::Rvalue::Cast( mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)), @@ -789,7 +802,14 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc mir::TerminatorKind::Call { ref func, .. } => { let callee_ty = func.ty(self.body, tcx); let callee_ty = self.monomorphize(callee_ty); - visit_fn_use(self.tcx, callee_ty, true, source, &mut self.output) + self.skip_move_size_check = visit_fn_use( + self.tcx, + callee_ty, + true, + source, + &mut self.output, + &self.skip_move_check_fns, + ) } mir::TerminatorKind::Drop { ref place, .. } => { let ty = place.ty(self.body, self.tcx).ty; @@ -801,7 +821,7 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc match *op { mir::InlineAsmOperand::SymFn { ref value } => { let fn_ty = self.monomorphize(value.literal.ty()); - visit_fn_use(self.tcx, fn_ty, false, source, &mut self.output); + visit_fn_use(self.tcx, fn_ty, false, source, &mut self.output, &[]); } mir::InlineAsmOperand::SymStatic { def_id } => { let instance = Instance::mono(self.tcx, def_id); @@ -840,12 +860,13 @@ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Loc } self.super_terminator(terminator, location); + self.skip_move_size_check = false; } fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) { self.super_operand(operand, location); let move_size_limit = self.tcx.move_size_limit().0; - if move_size_limit > 0 { + if move_size_limit > 0 && !self.skip_move_size_check { self.check_move_size(move_size_limit, operand, location); } } @@ -876,8 +897,11 @@ fn visit_fn_use<'tcx>( is_direct_call: bool, source: Span, output: &mut MonoItems<'tcx>, -) { + skip_move_check_fns: &[DefId], +) -> bool { + let mut skip_move_size_check = false; if let ty::FnDef(def_id, args) = *ty.kind() { + skip_move_size_check = skip_move_check_fns.contains(&def_id); let instance = if is_direct_call { ty::Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args) } else { @@ -888,6 +912,7 @@ fn visit_fn_use<'tcx>( }; visit_instance_use(tcx, instance, is_direct_call, source, output); } + skip_move_size_check } fn visit_instance_use<'tcx>( @@ -1365,6 +1390,31 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt } } +fn add_assoc_fn<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: Option, + fn_ident: Ident, + skip_move_check_fns: &mut Vec, +) { + if let Some(def_id) = def_id.and_then(|def_id| assoc_fn_of_type(tcx, def_id, fn_ident)) { + skip_move_check_fns.push(def_id); + } +} + +fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option { + for impl_def_id in tcx.inherent_impls(def_id) { + if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind( + tcx, + fn_ident, + AssocKind::Fn, + def_id, + ) { + return Some(new.def_id); + } + } + return None; +} + /// Scans the MIR in order to find function calls, closures, and drop-glue. #[instrument(skip(tcx, output), level = "debug")] fn collect_used_items<'tcx>( @@ -1373,8 +1423,39 @@ fn collect_used_items<'tcx>( output: &mut MonoItems<'tcx>, ) { let body = tcx.instance_mir(instance.def); - MirUsedCollector { tcx, body: &body, output, instance, move_size_spans: vec![] } - .visit_body(&body); + + let mut skip_move_check_fns = vec![]; + if tcx.move_size_limit().0 > 0 { + add_assoc_fn( + tcx, + tcx.lang_items().owned_box(), + Ident::from_str("new"), + &mut skip_move_check_fns, + ); + add_assoc_fn( + tcx, + tcx.get_diagnostic_item(sym::Arc), + Ident::from_str("new"), + &mut skip_move_check_fns, + ); + add_assoc_fn( + tcx, + tcx.get_diagnostic_item(sym::Rc), + Ident::from_str("new"), + &mut skip_move_check_fns, + ); + } + + MirUsedCollector { + tcx, + body: &body, + output, + instance, + move_size_spans: vec![], + skip_move_size_check: false, + skip_move_check_fns, + } + .visit_body(&body); } #[instrument(skip(tcx, output), level = "debug")] diff --git a/tests/ui/async-await/large_moves.attribute.stderr b/tests/ui/async-await/large_moves.attribute.stderr index ef9fd78ffe3..1d1999462ce 100644 --- a/tests/ui/async-await/large_moves.attribute.stderr +++ b/tests/ui/async-await/large_moves.attribute.stderr @@ -1,5 +1,5 @@ error: moving 10024 bytes - --> $DIR/large_moves.rs:19:14 + --> $DIR/large_moves.rs:21:14 | LL | let z = (x, 42); | ^ value moved from here @@ -12,12 +12,28 @@ LL | #![deny(large_assignments)] | ^^^^^^^^^^^^^^^^^ error: moving 10024 bytes - --> $DIR/large_moves.rs:20:13 + --> $DIR/large_moves.rs:22:13 | LL | let a = z.0; | ^^^ 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: aborting due to 2 previous errors +error: moving 9999 bytes + --> $DIR/large_moves.rs:27:13 + | +LL | let _ = NotBox::new([0; 9999]); + | ^^^^^^^^^^^^^^^^^^^^^^ 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 9999 bytes + --> $DIR/large_moves.rs:41:13 + | +LL | data, + | ^^^^ 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: aborting due to 4 previous errors diff --git a/tests/ui/async-await/large_moves.option.stderr b/tests/ui/async-await/large_moves.option.stderr index ef9fd78ffe3..1d1999462ce 100644 --- a/tests/ui/async-await/large_moves.option.stderr +++ b/tests/ui/async-await/large_moves.option.stderr @@ -1,5 +1,5 @@ error: moving 10024 bytes - --> $DIR/large_moves.rs:19:14 + --> $DIR/large_moves.rs:21:14 | LL | let z = (x, 42); | ^ value moved from here @@ -12,12 +12,28 @@ LL | #![deny(large_assignments)] | ^^^^^^^^^^^^^^^^^ error: moving 10024 bytes - --> $DIR/large_moves.rs:20:13 + --> $DIR/large_moves.rs:22:13 | LL | let a = z.0; | ^^^ 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: aborting due to 2 previous errors +error: moving 9999 bytes + --> $DIR/large_moves.rs:27:13 + | +LL | let _ = NotBox::new([0; 9999]); + | ^^^^^^^^^^^^^^^^^^^^^^ 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 9999 bytes + --> $DIR/large_moves.rs:41:13 + | +LL | data, + | ^^^^ 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: aborting due to 4 previous errors diff --git a/tests/ui/async-await/large_moves.rs b/tests/ui/async-await/large_moves.rs index faf6c66c612..62b12104694 100644 --- a/tests/ui/async-await/large_moves.rs +++ b/tests/ui/async-await/large_moves.rs @@ -9,6 +9,8 @@ // edition:2018 // compile-flags: -Zmir-opt-level=0 +use std::{sync::Arc, rc::Rc}; + fn main() { let x = async { let y = [0; 9999]; @@ -19,8 +21,24 @@ fn main() { let z = (x, 42); //~ ERROR large_assignments let a = z.0; //~ ERROR large_assignments let b = z.1; + let _ = Arc::new([0; 9999]); // OK! + let _ = Box::new([0; 9999]); // OK! + let _ = Rc::new([0; 9999]); // OK! + let _ = NotBox::new([0; 9999]); //~ ERROR large_assignments } async fn thing(y: &[u8]) { dbg!(y); } + +struct NotBox { + data: [u8; 9999], +} + +impl NotBox { + fn new(data: [u8; 9999]) -> Self { + Self { + data, //~ ERROR large_assignments + } + } +} From 8c667febbd77547dddd8d4170541b1c43626b9f6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 3 Sep 2023 19:43:51 +0000 Subject: [PATCH 4/5] Don't ICE on associated type projection without feature gate --- .../src/solve/project_goals.rs | 16 +++++++++++++- .../dont-ice-on-assoc-projection.rs | 19 +++++++++++++++++ .../dont-ice-on-assoc-projection.stderr | 21 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs create mode 100644 tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index e47e228774e..df094af4f1f 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -244,7 +244,21 @@ fn consider_impl_candidate( // Finally we construct the actual value of the associated type. let term = match assoc_def.item.kind { ty::AssocKind::Type => tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into()), - ty::AssocKind::Const => bug!("associated const projection is not supported yet"), + ty::AssocKind::Const => { + if tcx.features().associated_const_equality { + bug!("associated const projection is not supported yet") + } else { + ty::EarlyBinder::bind( + ty::Const::new_error_with_message( + tcx, + tcx.type_of(assoc_def.item.def_id).instantiate_identity(), + DUMMY_SP, + "associated const projection is not supported yet", + ) + .into(), + ) + } + } ty::AssocKind::Fn => unreachable!("we should never project to a fn"), }; diff --git a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs b/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs new file mode 100644 index 00000000000..b9798c79d5e --- /dev/null +++ b/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.rs @@ -0,0 +1,19 @@ +// compile-flags: -Ztrait-solver=next-coherence + +// Makes sure we don't ICE on associated const projection when the feature gate +// is not enabled, since we should avoid encountering ICEs on stable if possible. + +trait Bar { + const ASSOC: usize; +} +impl Bar for () { + const ASSOC: usize = 1; +} + +trait Foo {} +impl Foo for () {} +impl Foo for T where T: Bar {} +//~^ ERROR associated const equality is incomplete +//~| ERROR conflicting implementations of trait `Foo` for type `()` + +fn main() {} diff --git a/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr new file mode 100644 index 00000000000..7ad495a35e0 --- /dev/null +++ b/tests/ui/traits/new-solver/dont-ice-on-assoc-projection.stderr @@ -0,0 +1,21 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/dont-ice-on-assoc-projection.rs:15:32 + | +LL | impl Foo for T where T: Bar {} + | ^^^^^^^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error[E0119]: conflicting implementations of trait `Foo` for type `()` + --> $DIR/dont-ice-on-assoc-projection.rs:15:1 + | +LL | impl Foo for () {} + | --------------- first implementation here +LL | impl Foo for T where T: Bar {} + | ^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0658. +For more information about an error, try `rustc --explain E0119`. From 56d10a883e716fe252a60622d1e117a6f1970e3a Mon Sep 17 00:00:00 2001 From: ouz-a Date: Mon, 4 Sep 2023 13:06:36 +0300 Subject: [PATCH 5/5] provide more useful info for DefId Debug --- compiler/rustc_smir/src/rustc_smir/mod.rs | 5 +++++ compiler/rustc_smir/src/stable_mir/mod.rs | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 822a6e48658..b4c150c591c 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -37,9 +37,14 @@ fn find_crate(&self, name: &str) -> Option { }) } + fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String { + self.tcx.def_path_str(self[def_id]) + } + fn all_local_items(&mut self) -> stable_mir::CrateItems { self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect() } + fn entry_fn(&mut self) -> Option { Some(self.crate_item(self.tcx.entry_fn(())?.0)) } diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index dad7c75c340..bfc2c15a42e 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -12,6 +12,8 @@ //! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. use std::cell::Cell; +use std::fmt; +use std::fmt::Debug; use self::ty::{ GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, @@ -29,9 +31,18 @@ pub type CrateNum = usize; /// A unique identification number for each item accessible for the current compilation unit. -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct DefId(pub(crate) usize); +impl Debug for DefId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("DefId:") + .field("id", &self.0) + .field("name", &with(|cx| cx.name_of_def_id(*self))) + .finish() + } +} + /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct AllocId(pub(crate) usize); @@ -127,6 +138,9 @@ pub trait Context { /// Find a crate with the given name. fn find_crate(&self, name: &str) -> Option; + /// Prints the name of given `DefId` + fn name_of_def_id(&self, def_id: DefId) -> String; + /// Obtain the representation of a type. fn ty_kind(&mut self, ty: Ty) -> TyKind;