diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index d6836d2ee3665..480c8967eb9f9 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -221,6 +221,16 @@ rustc_queries! { } } + /// Finds call targets in `key`s MIR body that are guaranteed to be called when the function + /// is entered. + query inevitable_calls(key: DefId) -> &'tcx [(DefId, SubstsRef<'tcx>, &'tcx [Span])] { + desc { + |tcx| "computing call targets of `{}`", + tcx.def_path_str(key), + } + no_hash + } + /// Fetch the MIR for a given `DefId` right after it's built - this includes /// unreachable code. query mir_built(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> { @@ -233,7 +243,7 @@ rustc_queries! { /// See the README for the `mir` module for details. query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> { desc { - |tcx| "processing MIR for {}`{}`", + |tcx| "const-processing MIR for {}`{}`", if key.const_param_did.is_some() { "the const argument " } else { "" }, tcx.def_path_str(key.did.to_def_id()), } @@ -254,7 +264,7 @@ rustc_queries! { ) { no_hash desc { - |tcx| "processing {}`{}`", + |tcx| "validating MIR for {}`{}`", if key.const_param_did.is_some() { "the const argument " } else { "" }, tcx.def_path_str(key.did.to_def_id()), } diff --git a/src/librustc_middle/ty/steal.rs b/src/librustc_middle/ty/steal.rs index 224e76845d708..535cc145c3706 100644 --- a/src/librustc_middle/ty/steal.rs +++ b/src/librustc_middle/ty/steal.rs @@ -39,6 +39,6 @@ impl<T> Steal<T> { pub fn steal(&self) -> T { let value_ref = &mut *self.value.try_write().expect("stealing value which is locked"); let value = value_ref.take(); - value.expect("attempt to read from stolen value") + value.expect("attempt to steal stolen value again") } } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 3118e7ac3ab17..42c173531b160 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -38,6 +38,7 @@ mod borrow_check; pub mod const_eval; pub mod dataflow; pub mod interpret; +mod lints; pub mod monomorphize; mod shim; pub mod transform; @@ -59,4 +60,5 @@ pub fn provide(providers: &mut Providers) { let (param_env, value) = param_env_and_value.into_parts(); const_eval::destructure_const(tcx, param_env, value) }; + providers.inevitable_calls = lints::inevitable_calls; } diff --git a/src/librustc_mir/lints.rs b/src/librustc_mir/lints.rs new file mode 100644 index 0000000000000..b60599d756b0e --- /dev/null +++ b/src/librustc_mir/lints.rs @@ -0,0 +1,452 @@ +use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet}; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::FnKind; +use rustc_index::vec::IndexVec; +use rustc_middle::hir::map::blocks::FnLikeNode; +use rustc_middle::mir::{self, BasicBlock, Body, TerminatorKind, START_BLOCK}; +use rustc_middle::ty::subst::InternalSubsts; +use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt}; +use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION; +use rustc_span::{MultiSpan, Span}; +use std::collections::VecDeque; +use std::{iter, mem, rc::Rc}; +use ty::{subst::SubstsRef, WithOptConstParam}; + +const MAX_DEPTH: usize = 4; + +crate fn check<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + + if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) { + if let FnKind::Closure(_) = fn_like_node.kind() { + // closures can't recur, so they don't matter. + return; + } + + debug!("MIR-linting {}", tcx.def_path_str(def_id.to_def_id())); + + // If this is trait/impl method, extract the trait's substs. + let trait_substs = match tcx.opt_associated_item(def_id.to_def_id()) { + Some(AssocItem { + container: AssocItemContainer::TraitContainer(trait_def_id), .. + }) => { + let trait_substs_count = tcx.generics_of(*trait_def_id).count(); + &InternalSubsts::identity_for_item(tcx, def_id.to_def_id())[..trait_substs_count] + } + _ => &[], + }; + + // Keep track of instances we've already visited to avoid running in circles. + let mut seen = FxHashSet::default(); + + // Worklist of instances to search for recursive calls. Starts out with just the original + // item. + let mut worklist = VecDeque::new(); + worklist.push_back(Rc::new(Item { + depth: 0, + def_id: def_id.to_def_id(), + // Initially, we use the identity substs, but calls inside the function can provide + // concrete types for callees. + substs: InternalSubsts::identity_for_item(tcx, def_id.to_def_id()), + caller: None, + caller_spans: &[], + })); + + while let Some(item) = worklist.pop_front() { + if !seen.insert((item.def_id, item.substs)) { + // Already processed this instance. + continue; + } + + if item.depth > MAX_DEPTH { + // Call stack too deep, bail out. + continue; + } + + // FIXME: Apply substs as appropriate to look into generic functions and trait methods. + // This is not done at the moment, since `Instance::resolve` would be called with + // partially monomorphized arguments, which would allow *resolving* the instance, but + // not *normalizing* the result, causing ICEs. + + let param_env = tcx.param_env(item.def_id); + + debug!("processing callees of {} - {:?}", tcx.def_path_str(item.def_id), item); + for &(callee_def_id, callee_substs, spans) in tcx.inevitable_calls(item.def_id) { + let (call_fn_id, call_substs) = + match Instance::resolve(tcx, param_env, callee_def_id, callee_substs) { + Ok(Some(instance)) => { + // The precise callee is statically known. We only handle callees for + // which there's MIR available (those are the only ones that can cause + // cycles anyways). + if tcx.is_mir_available(instance.def_id()) { + debug!( + "call target of {:?} {:?} is {:?}", + callee_def_id, callee_substs, instance + ); + (instance.def_id(), instance.substs) + } else { + debug!("no MIR for instance {:?}, skipping", instance); + continue; + } + } + _ if callee_def_id == def_id.to_def_id() => { + // If the instance fails to resolve, we might be a specializable or + // defaulted function. However, if we know we're calling *ourselves* + // only, we still lint, since any use without overriding the impl will + // result in self-recursion. + (callee_def_id, callee_substs) + } + _ => { + // Otherwise, this call does not have a statically known target, so we + // cannot lint it. + debug!( + "call target unknown: {:?} ({:?}) in {:#?}", + callee_def_id, callee_substs, param_env + ); + continue; + } + }; + + // We have found a self-call that we want to lint when a (resolved) `Callee` has our + // `DefId` and (if it's a trait/impl method) the same trait-level substs. + let is_self_call = call_fn_id == def_id.to_def_id() + && &call_substs[..trait_substs.len()] == trait_substs; + + if is_self_call { + item.lint_self_call(tcx, spans); + return; + } + + // Put this callee at the end of the worklist. + worklist.push_back(Rc::new(Item { + depth: item.depth + 1, + def_id: call_fn_id, + substs: call_substs, + caller: Some(item.clone()), + caller_spans: spans, + })); + } + } + } +} + +/// A node in the call tree. +/// +/// As the lint runs, we'll create a call tree as we look for cycles. We add items in a +/// breadth-first manner, so this does *not* create a stack. +#[derive(Clone, Debug)] +struct Item<'tcx> { + /// Depth in the call stack/tree. Starts out at 0 for the root node, and is incremented for each + /// level in the tree. This is used to limit the amount of work we do. + depth: usize, + /// The function being called. + def_id: DefId, + /// The substs applied to the called function. + substs: SubstsRef<'tcx>, + /// The `Item` from which the call is made. `None` if this is the tree root (in which case it + /// describes the original function we're linting). + caller: Option<Rc<Item<'tcx>>>, + /// List of spans in `caller` that are the call-sites at which this particular `Item` is called. + /// Empty if this is the root. + caller_spans: &'tcx [Span], +} + +impl<'tcx> Item<'tcx> { + fn lint_self_call(&self, tcx: TyCtxt<'tcx>, final_spans: &[Span]) { + // Collect the call stack, reversing the tree order. + let mut cur = Rc::new(self.clone()); + let mut stack = vec![cur.clone()]; + while let Some(caller) = &cur.caller { + stack.push(caller.clone()); + cur = caller.clone(); + } + stack.reverse(); + + let spans = stack + .iter() + .skip(1) + .map(|item| item.caller_spans) + .chain(iter::once(final_spans)) + .collect::<Vec<_>>(); + + // First item is the original function we're linting. + let target_def_id = stack[0].def_id; + let hir_id = tcx.hir().local_def_id_to_hir_id(target_def_id.expect_local()); + let sp = tcx.sess.source_map().guess_head_span(tcx.hir().span_with_body(hir_id)); + tcx.struct_span_lint_hir(UNCONDITIONAL_RECURSION, hir_id, sp, |lint| { + let mut db = lint.build("function cannot return without recursing"); + + for (i, item) in stack.iter().enumerate() { + let is_first = i == 0; + let is_last = i == stack.len() - 1; + + let fn_span = item.def_id.as_local().map(|local| { + let hir_id = tcx.hir().local_def_id_to_hir_id(local); + let sp = tcx.sess.source_map().guess_head_span(tcx.hir().span(hir_id)); + sp + }); + + // For each function, collect the contained call sites leading to the next function. + let call_spans = match fn_span { + Some(fn_span) => { + let mut call_spans = MultiSpan::from_span(fn_span); + for &span in spans[i] { + let msg = if stack.len() == 1 { + "recursive call site" + } else if is_last { + "call completing the cycle" + } else { + "call into the next function in the cycle" + }; + call_spans.push_span_label(span, msg.into()); + } + call_spans + } + None => MultiSpan::new(), + }; + + // Put the collected labels on the corresponding function. + if is_first { + db.span_label(fn_span.unwrap(), "cannot return without recursing"); + for lab in call_spans.span_labels() { + if let Some(label) = lab.label { + db.span_label(lab.span, label); + } + } + } else if fn_span.is_some() { + // We have useful spans in `call_spans`. + db.span_note(call_spans, "next function in the cycle"); + } else { + db.note(&format!( + "next function in the cycle is `{}`", + tcx.def_path_str(item.def_id) + )); + } + } + + if stack.len() == 1 { + // A single self-calling function may be rewritten via `loop`. + db.help("a `loop` may express intention better if this is on purpose"); + } + + db.emit(); + }); + } +} + +/// Query provider. +/// +/// This query is forced before `mir_validated` steals the `mir_built` results, so `mir_built` is +/// always available for local items here. +crate fn inevitable_calls<'tcx>( + tcx: TyCtxt<'tcx>, + key: DefId, +) -> &'tcx [(DefId, SubstsRef<'tcx>, &'tcx [Span])] { + tcx.arena.alloc_from_iter( + find_inevitable_calls(tcx, key) + .into_iter() + .flatten() + .map(|(callee, spans)| (callee.def_id, callee.substs, &*tcx.arena.alloc_slice(&spans))), + ) +} + +/// Computes the set of callees that are known to be called whenever this function is entered. +fn find_inevitable_calls<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> Option<impl Iterator<Item = (Callee<'tcx>, Vec<Span>)>> { + debug!("find_inevitable_calls({})", tcx.def_path_str(def_id)); + + assert!(tcx.is_mir_available(def_id), "MIR unavailable for {:?}", def_id); + + let steal; + let steal_ref; + let body = match def_id.as_local() { + Some(local) => { + // Call the actual MIR building query for items in the local crate. + + // For some reason `is_mir_available` will return true for items where `mir_built` + // will then panic with "can't build MIR for X" (for example, tuple struct/variant + // ctors). Check that the item in question is an actual function-like thingy. + let hir_id = tcx.hir().local_def_id_to_hir_id(local); + match FnLikeNode::from_node(tcx.hir().get(hir_id)) { + Some(_) => { + debug!("find_inevitable_calls: local node, using `mir_built`"); + steal = tcx.mir_built(WithOptConstParam::unknown(local)); + steal_ref = steal.borrow(); + &*steal_ref + } + None => { + debug!("{:?} not an `FnLikeNode`, not linting", local); + return None; + } + } + } + None => { + // Right now, external functions cannot cause cycles since we can't look into trait + // impls or anything generic. Also, it turns out that `is_mir_available` is not + // sufficient to determine whether `optimized_mir` will succeed (we hit "unwrap on a + // None value" in the metadata decoder). + debug!("external function {:?}, not linting", def_id); + return None; + } + }; + + Some(find_inevitable_calls_in_body(tcx, body)) +} + +fn find_inevitable_calls_in_body<'tcx>( + tcx: TyCtxt<'tcx>, + body: &Body<'tcx>, +) -> impl Iterator<Item = (Callee<'tcx>, Vec<Span>)> { + // Maps from BasicBlocks to the set of callees they are guaranteed to reach. Starts out as a map + // from BasicBlocks whose terminators *are* calls. + let mut inevitable_calls = + IndexVec::from_elem_n(FxHashSet::default(), body.basic_blocks().len()); + let mut span_map: FxHashMap<Callee<'_>, Vec<_>> = FxHashMap::default(); + + for (bb, callee, span) in collect_outgoing_calls(tcx, body) { + inevitable_calls[bb].insert(callee); + span_map.entry(callee).or_default().push(span); + } + + let predecessors = body.predecessors(); + + // Worklist of block to propagate inevitable callees into. Propagation runs backwards starting + // at the call sites. + let mut worklist: VecDeque<_> = + inevitable_calls.indices().flat_map(|bb| &predecessors[bb]).collect(); + + let mut successors = Vec::with_capacity(2); + + while let Some(&bb) = worklist.pop_front() { + // Determine all "relevant" successors. We ignore successors only reached via unwinding. + let terminator = body[bb].terminator(); + let relevant_successors = match &terminator.kind { + TerminatorKind::Call { destination: None, .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::GeneratorDrop => None.into_iter().chain(&[]), + TerminatorKind::SwitchInt { targets, .. } => None.into_iter().chain(targets), + TerminatorKind::Goto { target } + | TerminatorKind::Drop { target, .. } + | TerminatorKind::DropAndReplace { target, .. } + | TerminatorKind::Assert { target, .. } + | TerminatorKind::FalseEdge { real_target: target, .. } + | TerminatorKind::FalseUnwind { real_target: target, .. } + | TerminatorKind::Call { destination: Some((_, target)), .. } => { + Some(target).into_iter().chain(&[]) + } + TerminatorKind::InlineAsm { destination: Some(dest), .. } => { + Some(dest).into_iter().chain(&[]) + } + TerminatorKind::InlineAsm { destination: None, .. } => None.into_iter().chain(&[]), + TerminatorKind::Resume + | TerminatorKind::Abort + | TerminatorKind::Return + | TerminatorKind::Unreachable => { + // We propagate backwards, so these should never be encountered here. + unreachable!("unexpected terminator {:?}", terminator.kind) + } + }; + + successors.clear(); + successors.extend(relevant_successors.copied()); + + let mut dest_set = mem::take(&mut inevitable_calls[bb]); + + let changed = propagate_successors(&mut dest_set, &inevitable_calls, &successors); + + inevitable_calls[bb] = dest_set; + if changed { + // `bb`s inevitable callees were modified, so propagate that backwards. + worklist.extend(&predecessors[bb]); + } + } + + mem::take(&mut inevitable_calls[START_BLOCK]).into_iter().map(move |callee| { + let spans = &span_map[&callee]; + (callee, spans.clone()) + }) +} + +/// Propagates inevitable calls from `successors` into their predecessor's `dest_set`. +/// +/// Returns `true` if `dest_set` was changed. +fn propagate_successors<'tcx>( + dest_set: &mut FxHashSet<Callee<'tcx>>, + inevitable_calls: &IndexVec<BasicBlock, FxHashSet<Callee<'tcx>>>, + successors: &[BasicBlock], +) -> bool { + let len = dest_set.len(); + + match successors { + [successor] => { + // If there's only one successor, just add all of its calls to `dest_set`. + dest_set.extend(inevitable_calls[*successor].iter().copied()); + } + _ => { + // All callees that are guaranteed to be reached by every successor will also be reached by + // `bb`. Compute the intersection. + // For efficiency, we initially only consider the smallest set. + let (smallest_successor_set_index, smallest_successor_set_bb) = match successors + .iter() + .enumerate() + .min_by_key(|(_, &bb)| inevitable_calls[bb].len()) + { + Some((i, bb)) => (i, *bb), + None => return false, // No callees will be added + }; + + for callee in &inevitable_calls[smallest_successor_set_bb] { + if dest_set.contains(callee) { + continue; + } + + // `callee` must be contained in *every* successor's set. + let add = successors.iter().enumerate().all(|(i, bb)| { + if i == smallest_successor_set_index { + return true; + } + let callee_set = &inevitable_calls[*bb]; + callee_set.contains(callee) + }); + + if add { + dest_set.insert(callee.clone()); + } + } + } + } + + dest_set.len() != len +} + +/// Information about a callee tracked by this algorithm. +#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] +struct Callee<'tcx> { + def_id: DefId, + substs: SubstsRef<'tcx>, +} + +/// Walks `body` to collect all known callees. +fn collect_outgoing_calls<'a, 'tcx>( + tcx: TyCtxt<'tcx>, + body: &'a Body<'tcx>, +) -> impl Iterator<Item = (BasicBlock, Callee<'tcx>, Span)> + 'a { + mir::traversal::preorder(body).filter_map(move |(bb, data)| { + if data.is_cleanup { + return None; + } + + if let TerminatorKind::Call { func, .. } = &data.terminator().kind { + let func_ty = func.ty(body, tcx); + if let ty::FnDef(def_id, substs) = func_ty.kind { + let callee = Callee { def_id, substs }; + let span = data.terminator().source_info.span; + return Some((bb, callee, span)); + } + } + + None + }) +} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 0db5bd662ca39..84a2f7e11c4ec 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -285,6 +285,10 @@ fn mir_const<'tcx>( tcx.ensure().unsafety_check_result(def.did); } + // Ensure that `inevitable_calls` is computed before stealing the MIR as it is used by MIR + // lints. + let _ = tcx.inevitable_calls(def.did.to_def_id()); + let mut body = tcx.mir_built(def).steal(); util::dump_mir( @@ -297,6 +301,8 @@ fn mir_const<'tcx>( |_, _| Ok(()), ); + crate::lints::check(tcx, def.did); + run_passes( tcx, &mut body, diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index d3c1aa50400e4..6c64d09314d71 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -19,8 +19,6 @@ use rustc_span::Span; use rustc_target::spec::abi::Abi; use rustc_target::spec::PanicStrategy; -use super::lints; - crate fn mir_built<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>, @@ -200,8 +198,6 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_ build::construct_const(cx, body_id, return_ty, return_ty_span) }; - lints::check(tcx, &body, def.did); - // The borrow checker will replace all the regions here with its own // inference variables. There's no point having non-erased regions here. // The exception is `body.user_type_annotations`, which is used unmodified diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs index 313bb979a5161..26cf5b1ef66c9 100644 --- a/src/librustc_mir_build/lib.rs +++ b/src/librustc_mir_build/lib.rs @@ -17,7 +17,6 @@ extern crate tracing; extern crate rustc_middle; mod build; -mod lints; mod thir; use rustc_middle::ty::query::Providers; diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.rs b/src/test/ui/consts/uninhabited-const-issue-61744.rs index 15436f9c1b2cf..35dd2520a1bd8 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.rs +++ b/src/test/ui/consts/uninhabited-const-issue-61744.rs @@ -1,5 +1,7 @@ // build-fail +#![allow(unconditional_recursion)] + pub const unsafe fn fake_type<T>() -> T { hint_unreachable() } diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index 024f9782d4a67..0dc050a825df1 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -1,145 +1,145 @@ error[E0080]: evaluation of constant value failed - --> $DIR/uninhabited-const-issue-61744.rs:8:5 + --> $DIR/uninhabited-const-issue-61744.rs:10:5 | LL | hint_unreachable() | ------------------ | | - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5 - | inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:6:5 + | inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:6:5 ... LL | fake_type() | ^^^^^^^^^^^ | | | reached the configured maximum number of stack frames - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 - | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:10:5 error: any use of this value will cause an error - --> $DIR/uninhabited-const-issue-61744.rs:12:36 + --> $DIR/uninhabited-const-issue-61744.rs:14:36 | LL | const CONSTANT: i32 = unsafe { fake_type() }; | -------------------------------^^^^^^^^^^^--- @@ -149,7 +149,7 @@ LL | const CONSTANT: i32 = unsafe { fake_type() }; = note: `#[deny(const_err)]` on by default error[E0080]: erroneous constant used - --> $DIR/uninhabited-const-issue-61744.rs:18:10 + --> $DIR/uninhabited-const-issue-61744.rs:20:10 | LL | dbg!(i32::CONSTANT); | ^^^^^^^^^^^^^ referenced constant has errors diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 679b26efe5933..9aef8194f0966 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -9,12 +9,12 @@ note: ...which requires borrow-checking `cycle1`... | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle1`... +note: ...which requires validating MIR for `cycle1`... --> $DIR/auto-trait-leak.rs:12:1 | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... +note: ...which requires const-processing MIR for `cycle1`... --> $DIR/auto-trait-leak.rs:12:1 | LL | fn cycle1() -> impl Clone { @@ -45,12 +45,12 @@ note: ...which requires borrow-checking `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing `cycle2`... +note: ...which requires validating MIR for `cycle2`... --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... +note: ...which requires const-processing MIR for `cycle2`... --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { diff --git a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs index 451ddb3cce0e0..f97d7e6ab6eab 100644 --- a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs +++ b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs @@ -3,6 +3,8 @@ // // Regression test for #38064. +#![allow(unconditional_recursion)] + trait Quux {} fn foo() -> impl Quux { //~ ERROR cannot resolve opaque type diff --git a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr index c538b77098a2d..154b8123e6318 100644 --- a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr +++ b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr @@ -1,5 +1,5 @@ error[E0720]: cannot resolve opaque type - --> $DIR/infinite-impl-trait-issue-38064.rs:8:13 + --> $DIR/infinite-impl-trait-issue-38064.rs:10:13 | LL | fn foo() -> impl Quux { | ^^^^^^^^^ recursive opaque type @@ -11,7 +11,7 @@ LL | fn bar() -> impl Quux { | --------- returning this opaque type `foo::Foo<impl Quux>` error[E0720]: cannot resolve opaque type - --> $DIR/infinite-impl-trait-issue-38064.rs:14:13 + --> $DIR/infinite-impl-trait-issue-38064.rs:16:13 | LL | fn foo() -> impl Quux { | --------- returning this opaque type `bar::Bar<impl Quux>` diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs index e3c621f0c5742..d7786ececa890 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs @@ -89,7 +89,6 @@ fn mutual_recursion() -> impl Sync { } fn mutual_recursion_b() -> impl Sized { - //~^ ERROR mutual_recursion() } diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr index 75ff9e078cc2c..3f3a470ab4bb1 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr @@ -119,30 +119,51 @@ LL | | x; LL | | } | |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:74:5: 78:6 {impl Sized, ()}]` -error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-indirect.rs:86:26 +error[E0391]: cycle detected when building MIR for `mutual_recursion` + --> $DIR/recursive-impl-trait-type-indirect.rs:86:1 | LL | fn mutual_recursion() -> impl Sync { - | ^^^^^^^^^ recursive opaque type -LL | -LL | mutual_recursion_b() - | -------------------- returning here with type `impl Sized` -... -LL | fn mutual_recursion_b() -> impl Sized { - | ---------- returning this opaque type `impl Sized` - -error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-indirect.rs:91:28 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `mutual_recursion`... + --> $DIR/recursive-impl-trait-type-indirect.rs:86:1 | LL | fn mutual_recursion() -> impl Sync { - | --------- returning this opaque type `impl std::marker::Sync` -... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `impl Sized: std::marker::Sync`... +note: ...which requires computing type of `mutual_recursion_b::{{opaque}}#0`... + --> $DIR/recursive-impl-trait-type-indirect.rs:91:28 + | LL | fn mutual_recursion_b() -> impl Sized { - | ^^^^^^^^^^ recursive opaque type -LL | -LL | mutual_recursion() - | ------------------ returning here with type `impl std::marker::Sync` + | ^^^^^^^^^^ +note: ...which requires borrow-checking `mutual_recursion_b`... + --> $DIR/recursive-impl-trait-type-indirect.rs:91:1 + | +LL | fn mutual_recursion_b() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires validating MIR for `mutual_recursion_b`... + --> $DIR/recursive-impl-trait-type-indirect.rs:91:1 + | +LL | fn mutual_recursion_b() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const-processing MIR for `mutual_recursion_b`... + --> $DIR/recursive-impl-trait-type-indirect.rs:91:1 + | +LL | fn mutual_recursion_b() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing call targets of `mutual_recursion`... + --> $DIR/recursive-impl-trait-type-indirect.rs:86:1 + | +LL | fn mutual_recursion() -> impl Sync { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires building MIR for `mutual_recursion`, completing the cycle +note: cycle used when unsafety-checking `mutual_recursion` + --> $DIR/recursive-impl-trait-type-indirect.rs:86:1 + | +LL | fn mutual_recursion() -> impl Sync { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 14 previous errors +error: aborting due to 13 previous errors -For more information about this error, try `rustc --explain E0720`. +Some errors have detailed explanations: E0391, E0720. +For more information about an error, try `rustc --explain E0391`. diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs index 818e40365394d..d937440d157f7 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs @@ -2,6 +2,8 @@ // otherwise forbidden. Even when there's an opaque type in another crate // hiding this. +#![allow(unconditional_recursion)] + fn id<T>(t: T) -> impl Sized { t } fn recursive_id() -> impl Sized { //~ ERROR cannot resolve opaque type diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr index fbc58837a8e94..65f540eb030b2 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr @@ -1,5 +1,5 @@ error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:7:22 + --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:9:22 | LL | fn id<T>(t: T) -> impl Sized { t } | ---------- returning this opaque type `impl Sized` @@ -10,7 +10,7 @@ LL | id(recursive_id2()) | ------------------- returning here with type `impl Sized` error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:11:23 + --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:13:23 | LL | fn id<T>(t: T) -> impl Sized { t } | ---------- returning this opaque type `impl Sized` @@ -21,7 +21,7 @@ LL | id(recursive_id()) | ------------------ returning here with type `impl Sized` error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:17:24 + --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:19:24 | LL | fn wrap<T>(t: T) -> impl Sized { (t,) } | ---------- returning this opaque type `impl Sized` @@ -32,7 +32,7 @@ LL | wrap(recursive_wrap2()) | ----------------------- returning here with type `impl Sized` error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:21:25 + --> $DIR/recursive-impl-trait-type-through-non-recursive.rs:23:25 | LL | fn wrap<T>(t: T) -> impl Sized { (t,) } | ---------- returning this opaque type `impl Sized` diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.rs b/src/test/ui/infinite/infinite-recursion-const-fn.rs index 8289a3db6fc5b..3c5a80561f780 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.rs +++ b/src/test/ui/infinite/infinite-recursion-const-fn.rs @@ -1,5 +1,7 @@ //https://github.com/rust-lang/rust/issues/31364 +#![allow(unconditional_recursion)] + const fn a() -> usize { b() } //~ ERROR cycle detected when const-evaluating `a` [E0391] const fn b() -> usize { a() } const ARR: [i32; a()] = [5; 6]; diff --git a/src/test/ui/infinite/infinite-recursion-const-fn.stderr b/src/test/ui/infinite/infinite-recursion-const-fn.stderr index de0c579f63089..2b0f4caf864f2 100644 --- a/src/test/ui/infinite/infinite-recursion-const-fn.stderr +++ b/src/test/ui/infinite/infinite-recursion-const-fn.stderr @@ -1,17 +1,17 @@ error[E0391]: cycle detected when const-evaluating `a` - --> $DIR/infinite-recursion-const-fn.rs:3:1 + --> $DIR/infinite-recursion-const-fn.rs:5:1 | LL | const fn a() -> usize { b() } | ^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires const-evaluating `b`... - --> $DIR/infinite-recursion-const-fn.rs:4:1 + --> $DIR/infinite-recursion-const-fn.rs:6:1 | LL | const fn b() -> usize { a() } | ^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `a`, completing the cycle note: cycle used when const-evaluating `ARR::{{constant}}#0` - --> $DIR/infinite-recursion-const-fn.rs:5:18 + --> $DIR/infinite-recursion-const-fn.rs:7:18 | LL | const ARR: [i32; a()] = [5; 6]; | ^^^ diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.rs b/src/test/ui/lint/dead-code/lint-dead-code-1.rs index 896147fcc7738..397e90b4e3d4f 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-1.rs +++ b/src/test/ui/lint/dead-code/lint-dead-code-1.rs @@ -2,6 +2,7 @@ #![allow(unused_variables)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] +#![allow(unconditional_recursion)] #![deny(dead_code)] #![crate_type="lib"] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr index af97ea98b2b6d..92c318e4195c3 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr @@ -1,65 +1,65 @@ error: struct is never constructed: `Bar` - --> $DIR/lint-dead-code-1.rs:12:16 + --> $DIR/lint-dead-code-1.rs:13:16 | LL | pub struct Bar; | ^^^ | note: the lint level is defined here - --> $DIR/lint-dead-code-1.rs:5:9 + --> $DIR/lint-dead-code-1.rs:6:9 | LL | #![deny(dead_code)] | ^^^^^^^^^ error: static is never used: `priv_static` - --> $DIR/lint-dead-code-1.rs:20:1 + --> $DIR/lint-dead-code-1.rs:21:1 | LL | static priv_static: isize = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant is never used: `priv_const` - --> $DIR/lint-dead-code-1.rs:27:1 + --> $DIR/lint-dead-code-1.rs:28:1 | LL | const priv_const: isize = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: struct is never constructed: `PrivStruct` - --> $DIR/lint-dead-code-1.rs:35:8 + --> $DIR/lint-dead-code-1.rs:36:8 | LL | struct PrivStruct; | ^^^^^^^^^^ error: enum is never used: `priv_enum` - --> $DIR/lint-dead-code-1.rs:64:6 + --> $DIR/lint-dead-code-1.rs:65:6 | LL | enum priv_enum { foo2, bar2 } | ^^^^^^^^^ error: variant is never constructed: `bar3` - --> $DIR/lint-dead-code-1.rs:67:5 + --> $DIR/lint-dead-code-1.rs:68:5 | LL | bar3 | ^^^^ error: function is never used: `priv_fn` - --> $DIR/lint-dead-code-1.rs:88:4 + --> $DIR/lint-dead-code-1.rs:89:4 | LL | fn priv_fn() { | ^^^^^^^ error: function is never used: `foo` - --> $DIR/lint-dead-code-1.rs:93:4 + --> $DIR/lint-dead-code-1.rs:94:4 | LL | fn foo() { | ^^^ error: function is never used: `bar` - --> $DIR/lint-dead-code-1.rs:98:4 + --> $DIR/lint-dead-code-1.rs:99:4 | LL | fn bar() { | ^^^ error: function is never used: `baz` - --> $DIR/lint-dead-code-1.rs:102:4 + --> $DIR/lint-dead-code-1.rs:103:4 | LL | fn baz() -> impl Copy { | ^^^ diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.rs b/src/test/ui/lint/dead-code/lint-dead-code-3.rs index fe3c392ccf100..420270ed25b19 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-3.rs +++ b/src/test/ui/lint/dead-code/lint-dead-code-3.rs @@ -1,6 +1,7 @@ #![allow(unused_variables)] #![allow(non_camel_case_types)] #![allow(clashing_extern_declarations)] +#![allow(unconditional_recursion)] #![deny(dead_code)] #![crate_type="lib"] diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr index cf8f01ea19f0c..e2a028f027e37 100644 --- a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr +++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr @@ -1,35 +1,35 @@ error: struct is never constructed: `Foo` - --> $DIR/lint-dead-code-3.rs:14:8 + --> $DIR/lint-dead-code-3.rs:15:8 | LL | struct Foo; | ^^^ | note: the lint level is defined here - --> $DIR/lint-dead-code-3.rs:4:9 + --> $DIR/lint-dead-code-3.rs:5:9 | LL | #![deny(dead_code)] | ^^^^^^^^^ error: associated function is never used: `foo` - --> $DIR/lint-dead-code-3.rs:16:8 + --> $DIR/lint-dead-code-3.rs:17:8 | LL | fn foo(&self) { | ^^^ error: function is never used: `bar` - --> $DIR/lint-dead-code-3.rs:21:4 + --> $DIR/lint-dead-code-3.rs:22:4 | LL | fn bar() { | ^^^ error: enum is never used: `c_void` - --> $DIR/lint-dead-code-3.rs:60:6 + --> $DIR/lint-dead-code-3.rs:61:6 | LL | enum c_void {} | ^^^^^^ error: function is never used: `free` - --> $DIR/lint-dead-code-3.rs:62:5 + --> $DIR/lint-dead-code-3.rs:63:5 | LL | fn free(p: *const c_void); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/lint/lint-unconditional-recursion.rs b/src/test/ui/lint/lint-unconditional-recursion.rs index d2a0329585b71..d1d4edaa8d260 100644 --- a/src/test/ui/lint/lint-unconditional-recursion.rs +++ b/src/test/ui/lint/lint-unconditional-recursion.rs @@ -1,7 +1,9 @@ -#![deny(unconditional_recursion)] +#![warn(unconditional_recursion)] + +// check-pass #![allow(dead_code)] -fn foo() { //~ ERROR function cannot return without recursing +fn foo() { //~ WARN function cannot return without recursing foo(); } @@ -11,7 +13,7 @@ fn bar() { } } -fn baz() { //~ ERROR function cannot return without recursing +fn baz() { //~ WARN function cannot return without recursing if true { baz() } else { @@ -23,7 +25,7 @@ fn qux() { loop {} } -fn quz() -> bool { //~ ERROR function cannot return without recursing +fn quz() -> bool { //~ WARN function cannot return without recursing if true { while quz() {} true @@ -34,13 +36,13 @@ fn quz() -> bool { //~ ERROR function cannot return without recursing // Trait method calls. trait Foo { - fn bar(&self) { //~ ERROR function cannot return without recursing + fn bar(&self) { //~ WARN function cannot return without recursing self.bar() } } impl Foo for Box<dyn Foo + 'static> { - fn bar(&self) { //~ ERROR function cannot return without recursing + fn bar(&self) { //~ WARN function cannot return without recursing loop { self.bar() } @@ -49,7 +51,7 @@ impl Foo for Box<dyn Foo + 'static> { // Trait method call with integer fallback after method resolution. impl Foo for i32 { - fn bar(&self) { //~ ERROR function cannot return without recursing + fn bar(&self) { //~ WARN function cannot return without recursing 0.bar() } } @@ -62,13 +64,13 @@ impl Foo for u32 { // Trait method calls via paths. trait Foo2 { - fn bar(&self) { //~ ERROR function cannot return without recursing + fn bar(&self) { //~ WARN function cannot return without recursing Foo2::bar(self) } } impl Foo2 for Box<dyn Foo2 + 'static> { - fn bar(&self) { //~ ERROR function cannot return without recursing + fn bar(&self) { //~ WARN function cannot return without recursing loop { Foo2::bar(self) } @@ -78,19 +80,19 @@ impl Foo2 for Box<dyn Foo2 + 'static> { struct Baz; impl Baz { // Inherent method call. - fn qux(&self) { //~ ERROR function cannot return without recursing + fn qux(&self) { //~ WARN function cannot return without recursing self.qux(); } // Inherent method call via path. - fn as_ref(&self) -> &Self { //~ ERROR function cannot return without recursing + fn as_ref(&self) -> &Self { //~ WARN function cannot return without recursing Baz::as_ref(self) } } // Trait method calls to impls via paths. impl Default for Baz { - fn default() -> Baz { //~ ERROR function cannot return without recursing + fn default() -> Baz { //~ WARN function cannot return without recursing let x = Default::default(); x } @@ -99,14 +101,14 @@ impl Default for Baz { // Overloaded operators. impl std::ops::Deref for Baz { type Target = (); - fn deref(&self) -> &() { //~ ERROR function cannot return without recursing + fn deref(&self) -> &() { //~ WARN function cannot return without recursing &**self } } impl std::ops::Index<usize> for Baz { type Output = Baz; - fn index(&self, x: usize) -> &Baz { //~ ERROR function cannot return without recursing + fn index(&self, x: usize) -> &Baz { //~ WARN function cannot return without recursing &self[x] } } @@ -115,7 +117,7 @@ impl std::ops::Index<usize> for Baz { struct Quux; impl std::ops::Deref for Quux { type Target = Baz; - fn deref(&self) -> &Baz { //~ ERROR function cannot return without recursing + fn deref(&self) -> &Baz { //~ WARN function cannot return without recursing self.as_ref() } } @@ -149,4 +151,12 @@ pub fn panics(x: bool) { } } +fn cycle1() { //~ WARN function cannot return without recursing + cycle2(); +} + +fn cycle2() { //~ WARN function cannot return without recursing + cycle1(); +} + fn main() {} diff --git a/src/test/ui/lint/lint-unconditional-recursion.stderr b/src/test/ui/lint/lint-unconditional-recursion.stderr index 1770d71e2e2fe..a6d2d8247d66f 100644 --- a/src/test/ui/lint/lint-unconditional-recursion.stderr +++ b/src/test/ui/lint/lint-unconditional-recursion.stderr @@ -1,5 +1,5 @@ -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:4:1 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:6:1 | LL | fn foo() { | ^^^^^^^^ cannot return without recursing @@ -9,12 +9,12 @@ LL | foo(); note: the lint level is defined here --> $DIR/lint-unconditional-recursion.rs:1:9 | -LL | #![deny(unconditional_recursion)] +LL | #![warn(unconditional_recursion)] | ^^^^^^^^^^^^^^^^^^^^^^^ = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:14:1 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:16:1 | LL | fn baz() { | ^^^^^^^^ cannot return without recursing @@ -27,8 +27,8 @@ LL | baz() | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:26:1 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:28:1 | LL | fn quz() -> bool { | ^^^^^^^^^^^^^^^^ cannot return without recursing @@ -41,8 +41,8 @@ LL | loop { quz(); } | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:37:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:39:5 | LL | fn bar(&self) { | ^^^^^^^^^^^^^ cannot return without recursing @@ -51,8 +51,8 @@ LL | self.bar() | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:43:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:45:5 | LL | fn bar(&self) { | ^^^^^^^^^^^^^ cannot return without recursing @@ -62,8 +62,8 @@ LL | self.bar() | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:52:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:54:5 | LL | fn bar(&self) { | ^^^^^^^^^^^^^ cannot return without recursing @@ -72,8 +72,8 @@ LL | 0.bar() | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:65:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:67:5 | LL | fn bar(&self) { | ^^^^^^^^^^^^^ cannot return without recursing @@ -82,8 +82,8 @@ LL | Foo2::bar(self) | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:71:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:73:5 | LL | fn bar(&self) { | ^^^^^^^^^^^^^ cannot return without recursing @@ -93,8 +93,8 @@ LL | Foo2::bar(self) | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:81:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:83:5 | LL | fn qux(&self) { | ^^^^^^^^^^^^^ cannot return without recursing @@ -103,8 +103,8 @@ LL | self.qux(); | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:86:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:88:5 | LL | fn as_ref(&self) -> &Self { | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -113,8 +113,8 @@ LL | Baz::as_ref(self) | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:93:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:95:5 | LL | fn default() -> Baz { | ^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -123,8 +123,8 @@ LL | let x = Default::default(); | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:102:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:104:5 | LL | fn deref(&self) -> &() { | ^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -133,8 +133,8 @@ LL | &**self | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:109:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:111:5 | LL | fn index(&self, x: usize) -> &Baz { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -143,8 +143,8 @@ LL | &self[x] | = help: a `loop` may express intention better if this is on purpose -error: function cannot return without recursing - --> $DIR/lint-unconditional-recursion.rs:118:5 +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:120:5 | LL | fn deref(&self) -> &Baz { | ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing @@ -153,5 +153,37 @@ LL | self.as_ref() | = help: a `loop` may express intention better if this is on purpose -error: aborting due to 14 previous errors +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:154:1 + | +LL | fn cycle1() { + | ^^^^^^^^^^^ cannot return without recursing +LL | cycle2(); + | -------- call into the next function in the cycle + | +note: next function in the cycle + --> $DIR/lint-unconditional-recursion.rs:158:1 + | +LL | fn cycle2() { + | ^^^^^^^^^^^ +LL | cycle1(); + | -------- call completing the cycle + +warning: function cannot return without recursing + --> $DIR/lint-unconditional-recursion.rs:158:1 + | +LL | fn cycle2() { + | ^^^^^^^^^^^ cannot return without recursing +LL | cycle1(); + | -------- call into the next function in the cycle + | +note: next function in the cycle + --> $DIR/lint-unconditional-recursion.rs:154:1 + | +LL | fn cycle1() { + | ^^^^^^^^^^^ +LL | cycle2(); + | -------- call completing the cycle + +warning: 16 warnings emitted