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