diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 095c3c03c307b..e6560771c0ee7 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -93,12 +93,12 @@ static NIGHTLY_TOOLS: &[(&str, &str)] = &[ ]; fn print_error(tool: &str, submodule: &str) { - eprintln!(""); + eprintln!(); eprintln!("We detected that this PR updated '{}', but its tests failed.", tool); - eprintln!(""); + eprintln!(); eprintln!("If you do intend to update '{}', please check the error messages above and", tool); eprintln!("commit another update."); - eprintln!(""); + eprintln!(); eprintln!("If you do NOT intend to update '{}', please ensure you did not accidentally", tool); eprintln!("change the submodule at '{}'. You may ask your reviewer for the", submodule); eprintln!("proper steps."); diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index 03c9164fb9095..8e170d970bc57 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -665,6 +665,34 @@ impl BinaryHeap { pub fn drain_sorted(&mut self) -> DrainSorted<'_, T> { DrainSorted { inner: self } } + + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all elements `e` such that `f(&e)` returns + /// `false`. The elements are visited in unsorted (and unspecified) order. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(binary_heap_retain)] + /// use std::collections::BinaryHeap; + /// + /// let mut heap = BinaryHeap::from(vec![-10, -5, 1, 2, 4, 13]); + /// + /// heap.retain(|x| x % 2 == 0); // only keep even numbers + /// + /// assert_eq!(heap.into_sorted_vec(), [-10, 2, 4]) + /// ``` + #[unstable(feature = "binary_heap_retain", issue = "71503")] + pub fn retain(&mut self, f: F) + where + F: FnMut(&T) -> bool, + { + self.data.retain(f); + self.rebuild(); + } } impl BinaryHeap { diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 057afd41824e7..62084ccf53c59 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -372,6 +372,14 @@ fn assert_covariance() { } } +#[test] +fn test_retain() { + let mut a = BinaryHeap::from(vec![-10, -5, 1, 2, 4, 13]); + a.retain(|x| x % 2 == 0); + + assert_eq!(a.into_sorted_vec(), [-10, 2, 4]) +} + // old binaryheap failed this test // // Integrity means that all elements are present after a comparison panics, diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index ad6feaeebc67f..78d49558262e3 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -14,6 +14,7 @@ #![feature(binary_heap_drain_sorted)] #![feature(vec_remove_item)] #![feature(split_inclusive)] +#![feature(binary_heap_retain)] use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index dbfcbca3ffcbf..575f51d0a7d56 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -77,7 +77,11 @@ impl<'a> PanicInfo<'a> { /// use std::panic; /// /// panic::set_hook(Box::new(|panic_info| { - /// println!("panic occurred: {:?}", panic_info.payload().downcast_ref::<&str>().unwrap()); + /// if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + /// println!("panic occurred: {:?}", s); + /// } else { + /// println!("panic occurred"); + /// } /// })); /// /// panic!("Normal panic"); @@ -112,8 +116,10 @@ impl<'a> PanicInfo<'a> { /// /// panic::set_hook(Box::new(|panic_info| { /// if let Some(location) = panic_info.location() { - /// println!("panic occurred in file '{}' at line {}", location.file(), - /// location.line()); + /// println!("panic occurred in file '{}' at line {}", + /// location.file(), + /// location.line(), + /// ); /// } else { /// println!("panic occurred but can't get location information..."); /// } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 1cd01c8c5bcb0..00b4bf96afa59 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -157,7 +157,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let cleanup_kinds = analyze::cleanup_kinds(&mir); // Allocate a `Block` for every basic block, except // the start block, if nothing loops back to it. - let reentrant_start_block = !mir.predecessors_for(mir::START_BLOCK).is_empty(); + let reentrant_start_block = !mir.predecessors()[mir::START_BLOCK].is_empty(); let block_bxs: IndexVec = mir .basic_blocks() .indices() diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 341fec0c07b36..34c05ec59f388 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -23,14 +23,12 @@ use rustc_ast::ast::Name; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::graph::{self, GraphSuccessors}; -use rustc_data_structures::sync::MappedLockGuard; use rustc_index::bit_set::BitMatrix; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_serialize::{Decodable, Encodable}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; -use smallvec::SmallVec; use std::borrow::Cow; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::ops::{Index, IndexMut}; @@ -170,7 +168,7 @@ pub struct Body<'tcx> { /// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components. pub ignore_interior_mut_in_const_validation: bool, - pub predecessor_cache: PredecessorCache, + predecessor_cache: PredecessorCache, } impl<'tcx> Body<'tcx> { @@ -398,15 +396,6 @@ impl<'tcx> Body<'tcx> { Location { block: bb, statement_index: self[bb].statements.len() } } - #[inline] - pub fn predecessors_for( - &self, - bb: BasicBlock, - ) -> impl std::ops::Deref> + '_ { - let predecessors = self.predecessor_cache.compute(&self.basic_blocks); - MappedLockGuard::map(predecessors, |preds| &mut preds[bb]) - } - #[inline] pub fn predecessors(&self) -> impl std::ops::Deref + '_ { self.predecessor_cache.compute(&self.basic_blocks) @@ -2684,7 +2673,7 @@ impl graph::GraphPredecessors<'graph> for Body<'tcx> { impl graph::WithPredecessors for Body<'tcx> { #[inline] fn predecessors(&self, node: Self::Node) -> >::Iter { - self.predecessors_for(node).clone().into_iter() + self.predecessors()[node].clone().into_iter() } } diff --git a/src/librustc_middle/mir/predecessors.rs b/src/librustc_middle/mir/predecessors.rs index 629b5c2efb711..9508365886aa7 100644 --- a/src/librustc_middle/mir/predecessors.rs +++ b/src/librustc_middle/mir/predecessors.rs @@ -1,5 +1,7 @@ +//! Lazily compute the reverse control-flow graph for the MIR. + use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{Lock, LockGuard, MappedLockGuard}; +use rustc_data_structures::sync::{Lock, Lrc}; use rustc_index::vec::IndexVec; use rustc_serialize as serialize; use smallvec::SmallVec; @@ -10,40 +12,49 @@ use crate::mir::{BasicBlock, BasicBlockData}; pub type Predecessors = IndexVec>; #[derive(Clone, Debug)] -pub struct PredecessorCache { - cache: Lock>, +pub(super) struct PredecessorCache { + cache: Lock>>, } impl PredecessorCache { #[inline] - pub fn new() -> Self { + pub(super) fn new() -> Self { PredecessorCache { cache: Lock::new(None) } } + /// Invalidates the predecessor cache. + /// + /// Invalidating the predecessor cache requires mutating the MIR, which in turn requires a + /// unique reference (`&mut`) to the `mir::Body`. Because of this, we can assume that all + /// callers of `invalidate` have a unique reference to the MIR and thus to the predecessor + /// cache. This means we don't actually need to take a lock when `invalidate` is called. #[inline] - pub fn invalidate(&mut self) { + pub(super) fn invalidate(&mut self) { *self.cache.get_mut() = None; } + /// Returns a ref-counted smart pointer containing the predecessor graph for this MIR. + /// + /// We use ref-counting instead of a mapped `LockGuard` here to ensure that the lock for + /// `cache` is only held inside this function. As long as no other locks are taken while + /// computing the predecessor graph, deadlock is impossible. #[inline] - pub fn compute( + pub(super) fn compute( &self, basic_blocks: &IndexVec>, - ) -> MappedLockGuard<'_, Predecessors> { - LockGuard::map(self.cache.lock(), |cache| { - cache.get_or_insert_with(|| { - let mut preds = IndexVec::from_elem(SmallVec::new(), basic_blocks); - for (bb, data) in basic_blocks.iter_enumerated() { - if let Some(term) = &data.terminator { - for &succ in term.successors() { - preds[succ].push(bb); - } + ) -> Lrc { + Lrc::clone(self.cache.lock().get_or_insert_with(|| { + let mut preds = IndexVec::from_elem(SmallVec::new(), basic_blocks); + for (bb, data) in basic_blocks.iter_enumerated() { + if let Some(term) = &data.terminator { + for &succ in term.successors() { + preds[succ].push(bb); } } + } - preds - }) - }) + Lrc::new(preds) + })) } } diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 6cc4ee432a58c..d424d0525fdd8 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1269,7 +1269,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, ) -> impl Iterator + 'a { if location.statement_index == 0 { - let predecessors = body.predecessors_for(location.block).to_vec(); + let predecessors = body.predecessors()[location.block].to_vec(); Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb))) } else { Either::Right(std::iter::once(Location { diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs index 57a3fa6f79b50..6cd814962c613 100644 --- a/src/librustc_mir/borrow_check/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/region_infer/values.rs @@ -89,7 +89,7 @@ impl RegionValueElements { // If this is a basic block head, then the predecessors are // the terminators of other basic blocks stack.extend( - body.predecessors_for(block) + body.predecessors()[block] .iter() .map(|&pred_bb| body.terminator_loc(pred_bb)) .map(|pred_loc| self.point_from_location(pred_loc)), diff --git a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/type_check/liveness/trace.rs index af09dc5b8039e..ec52a08c7b216 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/type_check/liveness/trace.rs @@ -303,7 +303,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } let body = self.cx.body; - for &pred_block in body.predecessors_for(block).iter() { + for &pred_block in body.predecessors()[block].iter() { debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,); // Check whether the variable is (at least partially) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index f9f32247c9487..004d685c8f81a 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -3,7 +3,6 @@ use rustc_errors::struct_span_err; use rustc_hir::lang_items; use rustc_hir::{def_id::DefId, HirId}; -use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -28,70 +27,100 @@ use crate::dataflow::{self, Analysis}; // We are using `MaybeMutBorrowedLocals` as a proxy for whether an item may have been mutated // through a pointer prior to the given point. This is okay even though `MaybeMutBorrowedLocals` // kills locals upon `StorageDead` because a local will never be used after a `StorageDead`. -pub type IndirectlyMutableResults<'mir, 'tcx> = +type IndirectlyMutableResults<'mir, 'tcx> = dataflow::ResultsCursor<'mir, 'tcx, MaybeMutBorrowedLocals<'mir, 'tcx>>; -struct QualifCursor<'a, 'mir, 'tcx, Q: Qualif> { - cursor: dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'a, 'mir, 'tcx, Q>>, - in_any_value_of_ty: BitSet, -} - -impl QualifCursor<'a, 'mir, 'tcx, Q> { - pub fn new(q: Q, ccx: &'a ConstCx<'mir, 'tcx>) -> Self { - let cursor = FlowSensitiveAnalysis::new(q, ccx) - .into_engine(ccx.tcx, ccx.body, ccx.def_id) - .iterate_to_fixpoint() - .into_results_cursor(ccx.body); - - let mut in_any_value_of_ty = BitSet::new_empty(ccx.body.local_decls.len()); - for (local, decl) in ccx.body.local_decls.iter_enumerated() { - if Q::in_any_value_of_ty(ccx, decl.ty) { - in_any_value_of_ty.insert(local); - } - } +type QualifResults<'mir, 'tcx, Q> = + dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>; - QualifCursor { cursor, in_any_value_of_ty } - } +#[derive(Default)] +pub struct Qualifs<'mir, 'tcx> { + has_mut_interior: Option>, + needs_drop: Option>, + indirectly_mutable: Option>, } -pub struct Qualifs<'a, 'mir, 'tcx> { - has_mut_interior: QualifCursor<'a, 'mir, 'tcx, HasMutInterior>, - needs_drop: QualifCursor<'a, 'mir, 'tcx, NeedsDrop>, - indirectly_mutable: IndirectlyMutableResults<'mir, 'tcx>, -} - -impl Qualifs<'a, 'mir, 'tcx> { - fn indirectly_mutable(&mut self, local: Local, location: Location) -> bool { - self.indirectly_mutable.seek_before(location); - self.indirectly_mutable.get().contains(local) +impl Qualifs<'mir, 'tcx> { + fn indirectly_mutable( + &mut self, + ccx: &'mir ConstCx<'mir, 'tcx>, + local: Local, + location: Location, + ) -> bool { + let indirectly_mutable = self.indirectly_mutable.get_or_insert_with(|| { + let ConstCx { tcx, body, def_id, param_env, .. } = *ccx; + + // We can use `unsound_ignore_borrow_on_drop` here because custom drop impls are not + // allowed in a const. + // + // FIXME(ecstaticmorse): Someday we want to allow custom drop impls. How do we do this + // without breaking stable code? + MaybeMutBorrowedLocals::mut_borrows_only(tcx, &body, param_env) + .unsound_ignore_borrow_on_drop() + .into_engine(tcx, &body, def_id) + .iterate_to_fixpoint() + .into_results_cursor(&body) + }); + + indirectly_mutable.seek_before(location); + indirectly_mutable.get().contains(local) } /// Returns `true` if `local` is `NeedsDrop` at the given `Location`. /// /// Only updates the cursor if absolutely necessary - fn needs_drop(&mut self, local: Local, location: Location) -> bool { - if !self.needs_drop.in_any_value_of_ty.contains(local) { + fn needs_drop( + &mut self, + ccx: &'mir ConstCx<'mir, 'tcx>, + local: Local, + location: Location, + ) -> bool { + let ty = ccx.body.local_decls[local].ty; + if !NeedsDrop::in_any_value_of_ty(ccx, ty) { return false; } - self.needs_drop.cursor.seek_before(location); - self.needs_drop.cursor.get().contains(local) || self.indirectly_mutable(local, location) + let needs_drop = self.needs_drop.get_or_insert_with(|| { + let ConstCx { tcx, body, def_id, .. } = *ccx; + + FlowSensitiveAnalysis::new(NeedsDrop, ccx) + .into_engine(tcx, &body, def_id) + .iterate_to_fixpoint() + .into_results_cursor(&body) + }); + + needs_drop.seek_before(location); + needs_drop.get().contains(local) || self.indirectly_mutable(ccx, local, location) } /// Returns `true` if `local` is `HasMutInterior` at the given `Location`. /// /// Only updates the cursor if absolutely necessary. - fn has_mut_interior(&mut self, local: Local, location: Location) -> bool { - if !self.has_mut_interior.in_any_value_of_ty.contains(local) { + fn has_mut_interior( + &mut self, + ccx: &'mir ConstCx<'mir, 'tcx>, + local: Local, + location: Location, + ) -> bool { + let ty = ccx.body.local_decls[local].ty; + if !HasMutInterior::in_any_value_of_ty(ccx, ty) { return false; } - self.has_mut_interior.cursor.seek_before(location); - self.has_mut_interior.cursor.get().contains(local) - || self.indirectly_mutable(local, location) + let has_mut_interior = self.has_mut_interior.get_or_insert_with(|| { + let ConstCx { tcx, body, def_id, .. } = *ccx; + + FlowSensitiveAnalysis::new(HasMutInterior, ccx) + .into_engine(tcx, &body, def_id) + .iterate_to_fixpoint() + .into_results_cursor(&body) + }); + + has_mut_interior.seek_before(location); + has_mut_interior.get().contains(local) || self.indirectly_mutable(ccx, local, location) } - fn in_return_place(&mut self, ccx: &ConstCx<'_, 'tcx>) -> ConstQualifs { + fn in_return_place(&mut self, ccx: &'mir ConstCx<'mir, 'tcx>) -> ConstQualifs { // Find the `Return` terminator if one exists. // // If no `Return` terminator exists, this MIR is divergent. Just return the conservative @@ -114,21 +143,21 @@ impl Qualifs<'a, 'mir, 'tcx> { let return_loc = ccx.body.terminator_loc(return_block); ConstQualifs { - needs_drop: self.needs_drop(RETURN_PLACE, return_loc), - has_mut_interior: self.has_mut_interior(RETURN_PLACE, return_loc), + needs_drop: self.needs_drop(ccx, RETURN_PLACE, return_loc), + has_mut_interior: self.has_mut_interior(ccx, RETURN_PLACE, return_loc), } } } -pub struct Validator<'a, 'mir, 'tcx> { - ccx: &'a ConstCx<'mir, 'tcx>, - qualifs: Qualifs<'a, 'mir, 'tcx>, +pub struct Validator<'mir, 'tcx> { + ccx: &'mir ConstCx<'mir, 'tcx>, + qualifs: Qualifs<'mir, 'tcx>, /// The span of the current statement. span: Span, } -impl Deref for Validator<'_, 'mir, 'tcx> { +impl Deref for Validator<'mir, 'tcx> { type Target = ConstCx<'mir, 'tcx>; fn deref(&self) -> &Self::Target { @@ -136,27 +165,9 @@ impl Deref for Validator<'_, 'mir, 'tcx> { } } -impl Validator<'a, 'mir, 'tcx> { - pub fn new(ccx: &'a ConstCx<'mir, 'tcx>) -> Self { - let ConstCx { tcx, body, def_id, param_env, .. } = *ccx; - - let needs_drop = QualifCursor::new(NeedsDrop, ccx); - let has_mut_interior = QualifCursor::new(HasMutInterior, ccx); - - // We can use `unsound_ignore_borrow_on_drop` here because custom drop impls are not - // allowed in a const. - // - // FIXME(ecstaticmorse): Someday we want to allow custom drop impls. How do we do this - // without breaking stable code? - let indirectly_mutable = MaybeMutBorrowedLocals::mut_borrows_only(tcx, body, param_env) - .unsound_ignore_borrow_on_drop() - .into_engine(tcx, body, def_id) - .iterate_to_fixpoint() - .into_results_cursor(body); - - let qualifs = Qualifs { needs_drop, has_mut_interior, indirectly_mutable }; - - Validator { span: ccx.body.span, ccx, qualifs } +impl Validator<'mir, 'tcx> { + pub fn new(ccx: &'mir ConstCx<'mir, 'tcx>) -> Self { + Validator { span: ccx.body.span, ccx, qualifs: Default::default() } } pub fn check_body(&mut self) { @@ -239,7 +250,7 @@ impl Validator<'a, 'mir, 'tcx> { } } -impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { +impl Visitor<'tcx> for Validator<'mir, 'tcx> { fn visit_basic_block_data(&mut self, bb: BasicBlock, block: &BasicBlockData<'tcx>) { trace!("visit_basic_block_data: bb={:?} is_cleanup={:?}", bb, block.is_cleanup); @@ -345,7 +356,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { | Rvalue::AddressOf(Mutability::Not, ref place) => { let borrowed_place_has_mut_interior = qualifs::in_place::( &self.ccx, - &mut |local| self.qualifs.has_mut_interior(local, location), + &mut |local| self.qualifs.has_mut_interior(self.ccx, local, location), place.as_ref(), ); @@ -571,7 +582,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { let needs_drop = if let Some(local) = dropped_place.as_local() { // Use the span where the local was declared as the span of the drop error. err_span = self.body.local_decls[local].source_info.span; - self.qualifs.needs_drop(local, location) + self.qualifs.needs_drop(self.ccx, local, location) } else { true }; diff --git a/src/test/ui/issues/issue-17252.stderr b/src/test/ui/issues/issue-17252.stderr index 8fd67b19d6a5a..ee621a8cb1473 100644 --- a/src/test/ui/issues/issue-17252.stderr +++ b/src/test/ui/issues/issue-17252.stderr @@ -1,11 +1,22 @@ -error[E0391]: cycle detected when const checking `FOO` - --> $DIR/issue-17252.rs:1:20 +error[E0391]: cycle detected when normalizing `FOO` + | +note: ...which requires const-evaluating + checking `FOO`... + --> $DIR/issue-17252.rs:1:1 + | +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `FOO`... + --> $DIR/issue-17252.rs:1:1 | LL | const FOO: usize = FOO; - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating `FOO`... + --> $DIR/issue-17252.rs:1:1 | - = note: ...which again requires const checking `FOO`, completing the cycle -note: cycle used when const checking `main::{{constant}}#0` +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires normalizing `FOO`, completing the cycle +note: cycle used when const-evaluating `main::{{constant}}#0` --> $DIR/issue-17252.rs:4:18 | LL | let _x: [u8; FOO]; // caused stack overflow prior to fix diff --git a/src/test/ui/issues/issue-23302-1.stderr b/src/test/ui/issues/issue-23302-1.stderr index f2457774326dd..b6c85b9e22749 100644 --- a/src/test/ui/issues/issue-23302-1.stderr +++ b/src/test/ui/issues/issue-23302-1.stderr @@ -1,15 +1,26 @@ -error[E0391]: cycle detected when const checking `X::A::{{constant}}#0` +error[E0391]: cycle detected when const-evaluating + checking `X::A::{{constant}}#0` --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ | - = note: ...which again requires const checking `X::A::{{constant}}#0`, completing the cycle -note: cycle used when processing `X::A::{{constant}}#0` +note: ...which requires const-evaluating + checking `X::A::{{constant}}#0`... --> $DIR/issue-23302-1.rs:4:9 | LL | A = X::A as isize, | ^^^^^^^^^^^^^ +note: ...which requires const-evaluating `X::A::{{constant}}#0`... + --> $DIR/issue-23302-1.rs:4:9 + | +LL | A = X::A as isize, + | ^^^^^^^^^^^^^ + = note: ...which requires normalizing `X::A as isize`... + = note: ...which again requires const-evaluating + checking `X::A::{{constant}}#0`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/issue-23302-1.rs:3:1 + | +LL | enum X { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-2.stderr b/src/test/ui/issues/issue-23302-2.stderr index c121c17b904ea..d014922fe2069 100644 --- a/src/test/ui/issues/issue-23302-2.stderr +++ b/src/test/ui/issues/issue-23302-2.stderr @@ -1,15 +1,26 @@ -error[E0391]: cycle detected when const checking `Y::A::{{constant}}#0` +error[E0391]: cycle detected when const-evaluating + checking `Y::A::{{constant}}#0` --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ | - = note: ...which again requires const checking `Y::A::{{constant}}#0`, completing the cycle -note: cycle used when processing `Y::A::{{constant}}#0` +note: ...which requires const-evaluating + checking `Y::A::{{constant}}#0`... --> $DIR/issue-23302-2.rs:4:9 | LL | A = Y::B as isize, | ^^^^^^^^^^^^^ +note: ...which requires const-evaluating `Y::A::{{constant}}#0`... + --> $DIR/issue-23302-2.rs:4:9 + | +LL | A = Y::B as isize, + | ^^^^^^^^^^^^^ + = note: ...which requires normalizing `Y::B as isize`... + = note: ...which again requires const-evaluating + checking `Y::A::{{constant}}#0`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/issue-23302-2.rs:3:1 + | +LL | enum Y { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index 0229469f04140..b30b1214271a0 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -1,20 +1,38 @@ -error[E0391]: cycle detected when const checking `A` - --> $DIR/issue-23302-3.rs:1:16 +error[E0391]: cycle detected when const-evaluating + checking `A` + --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; - | ^ + | ^^^^^^^^^^^^^^^^^ | -note: ...which requires const checking `B`... - --> $DIR/issue-23302-3.rs:3:16 +note: ...which requires const-evaluating + checking `A`... + --> $DIR/issue-23302-3.rs:1:1 | -LL | const B: i32 = A; - | ^ - = note: ...which again requires const checking `A`, completing the cycle -note: cycle used when processing `A` +LL | const A: i32 = B; + | ^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating `A`... --> $DIR/issue-23302-3.rs:1:1 | LL | const A: i32 = B; | ^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `B`... +note: ...which requires const-evaluating + checking `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating `B`... + --> $DIR/issue-23302-3.rs:3:1 + | +LL | const B: i32 = A; + | ^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `A`... + = note: ...which again requires const-evaluating + checking `A`, completing the cycle + = note: cycle used when running analysis passes on this crate error: aborting due to previous error diff --git a/src/test/ui/issues/issue-36163.stderr b/src/test/ui/issues/issue-36163.stderr index 3866243914b89..7c2da9dce6e9d 100644 --- a/src/test/ui/issues/issue-36163.stderr +++ b/src/test/ui/issues/issue-36163.stderr @@ -1,20 +1,48 @@ -error[E0391]: cycle detected when const checking `Foo::B::{{constant}}#0` +error[E0391]: cycle detected when const-evaluating + checking `Foo::B::{{constant}}#0` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | -note: ...which requires const checking `A`... - --> $DIR/issue-36163.rs:1:18 +note: ...which requires const-evaluating + checking `Foo::B::{{constant}}#0`... + --> $DIR/issue-36163.rs:4:9 | -LL | const A: isize = Foo::B as isize; - | ^^^^^^^^^^^^^^^ - = note: ...which again requires const checking `Foo::B::{{constant}}#0`, completing the cycle -note: cycle used when processing `Foo::B::{{constant}}#0` +LL | B = A, + | ^ +note: ...which requires const-evaluating `Foo::B::{{constant}}#0`... --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ + = note: ...which requires normalizing `A`... +note: ...which requires const-evaluating + checking `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating + checking `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-evaluating `A`... + --> $DIR/issue-36163.rs:1:1 + | +LL | const A: isize = Foo::B as isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `A`... + = note: ...which again requires const-evaluating + checking `Foo::B::{{constant}}#0`, completing the cycle +note: cycle used when collecting item types in top-level module + --> $DIR/issue-36163.rs:1:1 + | +LL | / const A: isize = Foo::B as isize; +LL | | +LL | | enum Foo { +LL | | B = A, +LL | | } +LL | | +LL | | fn main() {} + | |____________^ error: aborting due to previous error