diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 0c954ac6e5f6e..4c23f84bd0075 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::{ self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, }; -use rustc_mir_dataflow::storage::AlwaysLiveLocals; +use rustc_mir_dataflow::storage::always_live_locals; use rustc_query_system::ich::StableHashingContext; use rustc_session::Limit; use rustc_span::{Pos, Span}; @@ -715,7 +715,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now mark those locals as dead that we do not want to initialize // Mark locals that use `Storage*` annotations as dead on function entry. - let always_live = AlwaysLiveLocals::new(self.body()); + let always_live = always_live_locals(self.body()); for local in locals.indices() { if !always_live.contains(local) { locals[local].value = LocalValue::Dead; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 665b07c9f89ce..3f54d8642970c 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -14,7 +14,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_mir_dataflow::impls::MaybeStorageLive; -use rustc_mir_dataflow::storage::AlwaysLiveLocals; +use rustc_mir_dataflow::storage::always_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; use rustc_target::abi::{Size, VariantIdx}; @@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for Validator { let param_env = tcx.param_env(def_id); let mir_phase = self.mir_phase; - let always_live_locals = AlwaysLiveLocals::new(body); + let always_live_locals = always_live_locals(body); let storage_liveness = MaybeStorageLive::new(always_live_locals) .into_engine(tcx, body) .iterate_to_fixpoint() diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6d79e662a4279..f90bb7f236868 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1542,11 +1542,19 @@ extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *hig auto C = unwrap(CV); if (C->getBitWidth() > 128) { return false; } APInt AP; +#if LLVM_VERSION_GE(15, 0) + if (sext) { + AP = C->getValue().sext(128); + } else { + AP = C->getValue().zext(128); + } +#else if (sext) { AP = C->getValue().sextOrSelf(128); } else { AP = C->getValue().zextOrSelf(128); } +#endif *low = AP.getLoBits(64).getZExtValue(); *high = AP.getHiBits(64).getZExtValue(); return true; diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index 2de5a9d6991fe..f3b5544aa8b9d 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -109,7 +109,7 @@ where /// For backward analyses, this is the state that will be propagated to its /// predecessors (ignoring edge-specific effects). pub fn seek_to_block_start(&mut self, block: BasicBlock) { - if A::Direction::is_forward() { + if A::Direction::IS_FORWARD { self.seek_to_block_entry(block) } else { self.seek_after(Location { block, statement_index: 0 }, Effect::Primary) @@ -123,7 +123,7 @@ where /// For forward analyses, this is the state that will be propagated to its /// successors (ignoring edge-specific effects). pub fn seek_to_block_end(&mut self, block: BasicBlock) { - if A::Direction::is_backward() { + if A::Direction::IS_BACKWARD { self.seek_to_block_entry(block) } else { self.seek_after(self.body.terminator_loc(block), Effect::Primary) @@ -157,7 +157,7 @@ where self.seek_to_block_entry(target.block); } else if let Some(curr_effect) = self.pos.curr_effect_index { let mut ord = curr_effect.statement_index.cmp(&target.statement_index); - if A::Direction::is_backward() { + if A::Direction::IS_BACKWARD { ord = ord.reverse() } @@ -173,7 +173,7 @@ where debug_assert_eq!(target.block, self.pos.block); let block_data = &self.body[target.block]; - let next_effect = if A::Direction::is_forward() { + let next_effect = if A::Direction::IS_FORWARD { #[rustfmt::skip] self.pos.curr_effect_index.map_or_else( || Effect::Before.at_index(0), diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 3a492b45849c9..05a4d7bbf3e6f 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -9,11 +9,9 @@ use super::{ }; pub trait Direction { - fn is_forward() -> bool; + const IS_FORWARD: bool; - fn is_backward() -> bool { - !Self::is_forward() - } + const IS_BACKWARD: bool = !Self::IS_FORWARD; /// Applies all effects between the given `EffectIndex`s. /// @@ -68,9 +66,7 @@ pub trait Direction { pub struct Backward; impl Direction for Backward { - fn is_forward() -> bool { - false - } + const IS_FORWARD: bool = false; fn apply_effects_in_block<'tcx, A>( analysis: &A, @@ -338,9 +334,7 @@ where pub struct Forward; impl Direction for Forward { - fn is_forward() -> bool { - true - } + const IS_FORWARD: bool = true; fn apply_effects_in_block<'tcx, A>( analysis: &A, diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index 50efb4c1dc42a..20e14a77c1e57 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -147,7 +147,7 @@ where let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks()); analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); - if A::Direction::is_backward() && entry_sets[mir::START_BLOCK] != bottom_value { + if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value { bug!("`initialize_start_block` is not yet supported for backward dataflow analyses"); } @@ -200,7 +200,7 @@ where let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks().len()); - if A::Direction::is_forward() { + if A::Direction::IS_FORWARD { for (bb, _) in traversal::reverse_postorder(body) { dirty_queue.insert(bb); } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index 3834c232ab6ba..59a2053ec7000 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -216,7 +216,7 @@ where // Write the full dataflow state immediately after the terminator if it differs from the // state at block entry. self.results.seek_to_block_end(block); - if self.results.get() != &block_start_state || A::Direction::is_backward() { + if self.results.get() != &block_start_state || A::Direction::IS_BACKWARD { let after_terminator_name = match terminator.kind { mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)", _ => "(on end)", @@ -390,7 +390,7 @@ where let mut afters = diffs.after.into_iter(); let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| { - if A::Direction::is_forward() { it.next().unwrap() } else { it.next_back().unwrap() } + if A::Direction::IS_FORWARD { it.next().unwrap() } else { it.next_back().unwrap() } }; for (i, statement) in body[block].statements.iter().enumerate() { @@ -527,7 +527,7 @@ where _block_data: &mir::BasicBlockData<'tcx>, _block: BasicBlock, ) { - if A::Direction::is_forward() { + if A::Direction::IS_FORWARD { self.prev_state.clone_from(state); } } @@ -538,7 +538,7 @@ where _block_data: &mir::BasicBlockData<'tcx>, _block: BasicBlock, ) { - if A::Direction::is_backward() { + if A::Direction::IS_BACKWARD { self.prev_state.clone_from(state); } } diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 74c3b44f4250e..d9461fd3abd81 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -140,7 +140,7 @@ impl MockAnalysis<'_, D> { SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index), }; - let mut pos = if D::is_forward() { + let mut pos = if D::IS_FORWARD { Effect::Before.at_index(0) } else { Effect::Before.at_index(self.body[block].statements.len()) @@ -153,7 +153,7 @@ impl MockAnalysis<'_, D> { return ret; } - if D::is_forward() { + if D::IS_FORWARD { pos = pos.next_in_forward_order(); } else { pos = pos.next_in_backward_order(); diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 356a6b7765e16..33d2941814729 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -1,6 +1,5 @@ pub use super::*; -use crate::storage::AlwaysLiveLocals; use crate::{CallReturnPlaces, GenKill, Results, ResultsRefCursor}; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -8,11 +7,11 @@ use std::cell::RefCell; #[derive(Clone)] pub struct MaybeStorageLive { - always_live_locals: AlwaysLiveLocals, + always_live_locals: BitSet, } impl MaybeStorageLive { - pub fn new(always_live_locals: AlwaysLiveLocals) -> Self { + pub fn new(always_live_locals: BitSet) -> Self { MaybeStorageLive { always_live_locals } } } diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs index 218d4557215fb..4a354c4c65b08 100644 --- a/compiler/rustc_mir_dataflow/src/storage.rs +++ b/compiler/rustc_mir_dataflow/src/storage.rs @@ -7,35 +7,17 @@ use rustc_middle::mir::{self, Local}; // // FIXME: Currently, we need to traverse the entire MIR to compute this. We should instead store it // as a field in the `LocalDecl` for each `Local`. -#[derive(Debug, Clone)] -pub struct AlwaysLiveLocals(BitSet); +pub fn always_live_locals(body: &mir::Body<'_>) -> BitSet { + let mut always_live_locals = BitSet::new_filled(body.local_decls.len()); -impl AlwaysLiveLocals { - pub fn new(body: &mir::Body<'_>) -> Self { - let mut always_live_locals = AlwaysLiveLocals(BitSet::new_filled(body.local_decls.len())); - - for block in body.basic_blocks() { - for statement in &block.statements { - use mir::StatementKind::{StorageDead, StorageLive}; - if let StorageLive(l) | StorageDead(l) = statement.kind { - always_live_locals.0.remove(l); - } + for block in body.basic_blocks() { + for statement in &block.statements { + use mir::StatementKind::{StorageDead, StorageLive}; + if let StorageLive(l) | StorageDead(l) = statement.kind { + always_live_locals.remove(l); } } - - always_live_locals } - pub fn into_inner(self) -> BitSet { - self.0 - } -} - -impl std::ops::Deref for AlwaysLiveLocals { - type Target = BitSet; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } + always_live_locals } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 9eb77f6021373..89895fddd0cfa 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -228,7 +228,7 @@ struct TransformVisitor<'tcx> { suspension_points: Vec>, // The set of locals that have no `StorageLive`/`StorageDead` annotations. - always_live_locals: storage::AlwaysLiveLocals, + always_live_locals: BitSet, // The original RETURN_PLACE local new_ret_local: Local, @@ -450,7 +450,7 @@ struct LivenessInfo { fn locals_live_across_suspend_points<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - always_live_locals: &storage::AlwaysLiveLocals, + always_live_locals: &BitSet, movable: bool, ) -> LivenessInfo { let body_ref: &Body<'_> = &body; @@ -615,7 +615,7 @@ impl ops::Deref for GeneratorSavedLocals { fn compute_storage_conflicts<'mir, 'tcx>( body: &'mir Body<'tcx>, saved_locals: &GeneratorSavedLocals, - always_live_locals: storage::AlwaysLiveLocals, + always_live_locals: BitSet, requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>, ) -> BitMatrix { assert_eq!(body.local_decls.len(), saved_locals.domain_size()); @@ -625,7 +625,7 @@ fn compute_storage_conflicts<'mir, 'tcx>( // Locals that are always live or ones that need to be stored across // suspension points are not eligible for overlap. - let mut ineligible_locals = always_live_locals.into_inner(); + let mut ineligible_locals = always_live_locals; ineligible_locals.intersect(&**saved_locals); // Compute the storage conflicts for all eligible locals. @@ -1300,7 +1300,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { }, ); - let always_live_locals = storage::AlwaysLiveLocals::new(&body); + let always_live_locals = storage::always_live_locals(&body); let liveness_info = locals_live_across_suspend_points(tcx, body, &always_live_locals, movable); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b83fdd02da915..b9f49c19465d5 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1577,18 +1577,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { name: Symbol, ) -> ErrorGuaranteed { let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); - if let (true, Ok(snippet)) = ( - self.tcx() - .resolutions(()) - .confused_type_with_std_module - .keys() - .any(|full_span| full_span.contains(span)), - self.tcx().sess.source_map().span_to_snippet(span), - ) { + if self + .tcx() + .resolutions(()) + .confused_type_with_std_module + .keys() + .any(|full_span| full_span.contains(span)) + { err.span_suggestion( - span, + span.shrink_to_lo(), "you are looking for the module in `std`, not the primitive type", - format!("std::{}", snippet), + "std::".to_string(), Applicability::MachineApplicable, ); } else { diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 0e198907c8d50..4071c389266d3 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -327,26 +327,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } if let Some(span) = tcx.resolutions(()).confused_type_with_std_module.get(&span) { - if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) { - err.span_suggestion( - *span, - "you are looking for the module in `std`, \ - not the primitive type", - format!("std::{}", snippet), - Applicability::MachineApplicable, - ); - } + err.span_suggestion( + span.shrink_to_lo(), + "you are looking for the module in `std`, not the primitive type", + "std::".to_string(), + Applicability::MachineApplicable, + ); } if let ty::RawPtr(_) = &actual.kind() { err.note( "try using `<*const T>::as_ref()` to get a reference to the \ - type behind the pointer: https://doc.rust-lang.org/std/\ - primitive.pointer.html#method.as_ref", + type behind the pointer: https://doc.rust-lang.org/std/\ + primitive.pointer.html#method.as_ref", ); err.note( - "using `<*const T>::as_ref()` on a pointer \ - which is unaligned or points to invalid \ - or uninitialized memory is undefined behavior", + "using `<*const T>::as_ref()` on a pointer which is unaligned or points \ + to invalid or uninitialized memory is undefined behavior", ); } diff --git a/src/test/ui/async-await/issues/issue-95307.rs b/src/test/ui/async-await/issues/issue-95307.rs new file mode 100644 index 0000000000000..f7e48070ccde6 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-95307.rs @@ -0,0 +1,13 @@ +// edition:2018 + +// Regression test for #95307. +// The ICE occurred on all the editions, specifying edition:2018 to reduce diagnostics. + +pub trait C { + async fn new() -> [u8; _]; + //~^ ERROR: functions in traits cannot be declared `async` + //~| ERROR: using `_` for array lengths is unstable + //~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment +} + +fn main() {} diff --git a/src/test/ui/async-await/issues/issue-95307.stderr b/src/test/ui/async-await/issues/issue-95307.stderr new file mode 100644 index 0000000000000..60fca71eb4b62 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-95307.stderr @@ -0,0 +1,30 @@ +error[E0706]: functions in traits cannot be declared `async` + --> $DIR/issue-95307.rs:7:5 + | +LL | async fn new() -> [u8; _]; + | -----^^^^^^^^^^^^^^^^^^^^^ + | | + | `async` because of this + | + = note: `async` trait functions are not currently supported + = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait + +error[E0658]: using `_` for array lengths is unstable + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ + | + = note: see issue #85077 for more information + = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable + +error: in expressions, `_` can only be used on the left-hand side of an assignment + --> $DIR/issue-95307.rs:7:28 + | +LL | async fn new() -> [u8; _]; + | ^ `_` not allowed here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0658, E0706. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/suggest-std-when-using-type.stderr b/src/test/ui/suggestions/suggest-std-when-using-type.stderr index 4255281d9a7ac..2840fa121a75f 100644 --- a/src/test/ui/suggestions/suggest-std-when-using-type.stderr +++ b/src/test/ui/suggestions/suggest-std-when-using-type.stderr @@ -7,7 +7,7 @@ LL | let pi = f32::consts::PI; help: you are looking for the module in `std`, not the primitive type | LL | let pi = std::f32::consts::PI; - | ~~~~~~~~~~~~~~~~ + | +++++ error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope --> $DIR/suggest-std-when-using-type.rs:5:14 @@ -18,7 +18,7 @@ LL | str::from_utf8(bytes) help: you are looking for the module in `std`, not the primitive type | LL | std::str::from_utf8(bytes) - | ~~~~~~~~~~~~~~~~~~~ + | +++++ error: aborting due to 2 previous errors