about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/query/mod.rs13
-rw-r--r--compiler/rustc_query_impl/src/keys.rs17
-rw-r--r--compiler/rustc_query_impl/src/lib.rs2
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs9
-rw-r--r--compiler/rustc_query_impl/src/util.rs18
-rw-r--r--compiler/rustc_query_system/src/query/job.rs33
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs29
-rw-r--r--src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr2
-rw-r--r--src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr2
-rw-r--r--src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr4
-rw-r--r--src/test/ui/infinite/infinite-struct.stderr2
-rw-r--r--src/test/ui/infinite/infinite-tag-type-recursion.stderr2
-rw-r--r--src/test/ui/infinite/infinite-trait-alias-recursion.rs10
-rw-r--r--src/test/ui/infinite/infinite-trait-alias-recursion.stderr42
-rw-r--r--src/test/ui/infinite/infinite-type-alias-mutual-recursion.rs6
-rw-r--r--src/test/ui/infinite/infinite-type-alias-mutual-recursion.stderr34
-rw-r--r--src/test/ui/infinite/infinite-vec-type-recursion.stderr7
-rw-r--r--src/test/ui/issues/issue-20772.stderr2
-rw-r--r--src/test/ui/issues/issue-20825.stderr2
-rw-r--r--src/test/ui/issues/issue-21177.stderr2
-rw-r--r--src/test/ui/issues/issue-34373.stderr2
-rw-r--r--src/test/ui/resolve/issue-23305.stderr2
-rw-r--r--src/test/ui/resolve/resolve-self-in-impl.stderr10
23 files changed, 227 insertions, 25 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 07407540975..dada94edc95 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -120,7 +120,18 @@ rustc_queries! {
 
     /// Records the type of every item.
     query type_of(key: DefId) -> Ty<'tcx> {
-        desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
+        desc { |tcx|
+            "{action} `{path}`",
+            action = {
+                use rustc_hir::def::DefKind;
+                match tcx.def_kind(key) {
+                    DefKind::TyAlias => "expanding type alias",
+                    DefKind::TraitAlias => "expanding trait alias",
+                    _ => "computing type of",
+                }
+            },
+            path = tcx.def_path_str(key),
+        }
         cache_on_disk_if { key.is_local() }
     }
 
diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs
index d85f1c04524..c973eae6b06 100644
--- a/compiler/rustc_query_impl/src/keys.rs
+++ b/compiler/rustc_query_impl/src/keys.rs
@@ -20,6 +20,12 @@ pub trait Key {
     /// In the event that a cycle occurs, if no explicit span has been
     /// given for a query with key `self`, what span should we use?
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
+
+    /// If the key is a [`DefId`] or `DefId`--equivalent, return that `DefId`.
+    /// Otherwise, return `None`.
+    fn key_as_def_id(&self) -> Option<DefId> {
+        None
+    }
 }
 
 impl Key for () {
@@ -95,6 +101,9 @@ impl Key for LocalDefId {
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.to_def_id().default_span(tcx)
     }
+    fn key_as_def_id(&self) -> Option<DefId> {
+        Some(self.to_def_id())
+    }
 }
 
 impl Key for DefId {
@@ -105,6 +114,10 @@ impl Key for DefId {
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(*self)
     }
+    #[inline(always)]
+    fn key_as_def_id(&self) -> Option<DefId> {
+        Some(*self)
+    }
 }
 
 impl Key for ty::WithOptConstParam<LocalDefId> {
@@ -165,6 +178,10 @@ impl Key for (DefId, Option<Ident>) {
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(self.0)
     }
+    #[inline(always)]
+    fn key_as_def_id(&self) -> Option<DefId> {
+        Some(self.0)
+    }
 }
 
 impl Key for (DefId, LocalDefId, Ident) {
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 5022bf26532..bb0e6511159 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -51,6 +51,8 @@ pub use on_disk_cache::OnDiskCache;
 mod profiling_support;
 pub use self::profiling_support::alloc_self_profile_query_strings;
 
+mod util;
+
 rustc_query_append! { [define_queries!][<'tcx>] }
 
 impl<'tcx> Queries<'tcx> {
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 5774d021373..90a6ba474b4 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -337,6 +337,13 @@ macro_rules! define_queries {
                 } else {
                     Some(key.default_span(*tcx))
                 };
+                let def_id = key.key_as_def_id();
+                let def_kind = def_id
+                    .and_then(|def_id| def_id.as_local())
+                    // Use `tcx.hir().opt_def_kind()` to reduce the chance of
+                    // accidentally triggering an infinite query loop.
+                    .and_then(|def_id| tcx.hir().opt_def_kind(def_id))
+                    .map(|def_kind| $crate::util::def_kind_to_simple_def_kind(def_kind));
                 let hash = || {
                     let mut hcx = tcx.create_stable_hashing_context();
                     let mut hasher = StableHasher::new();
@@ -345,7 +352,7 @@ macro_rules! define_queries {
                     hasher.finish::<u64>()
                 };
 
-                QueryStackFrame::new(name, description, span, hash)
+                QueryStackFrame::new(name, description, span, def_kind, hash)
             })*
         }
 
diff --git a/compiler/rustc_query_impl/src/util.rs b/compiler/rustc_query_impl/src/util.rs
new file mode 100644
index 00000000000..517c107b5d9
--- /dev/null
+++ b/compiler/rustc_query_impl/src/util.rs
@@ -0,0 +1,18 @@
+use rustc_hir::def::DefKind;
+use rustc_query_system::query::SimpleDefKind;
+
+/// Convert a [`DefKind`] to a [`SimpleDefKind`].
+///
+/// *See [`SimpleDefKind`]'s docs for more information.*
+pub(crate) fn def_kind_to_simple_def_kind(def_kind: DefKind) -> SimpleDefKind {
+    match def_kind {
+        DefKind::Struct => SimpleDefKind::Struct,
+        DefKind::Enum => SimpleDefKind::Enum,
+        DefKind::Union => SimpleDefKind::Union,
+        DefKind::Trait => SimpleDefKind::Trait,
+        DefKind::TyAlias => SimpleDefKind::TyAlias,
+        DefKind::TraitAlias => SimpleDefKind::TraitAlias,
+
+        _ => SimpleDefKind::Other,
+    }
+}
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index a967670280f..63a8f062475 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -1,6 +1,6 @@
 use crate::dep_graph::DepContext;
 use crate::query::plumbing::CycleError;
-use crate::query::{QueryContext, QueryStackFrame};
+use crate::query::{QueryContext, QueryStackFrame, SimpleDefKind};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level};
@@ -591,10 +591,33 @@ pub(crate) fn report_cycle<'a>(
         err.span_note(span, &format!("...which requires {}...", query.description));
     }
 
-    err.note(&format!(
-        "...which again requires {}, completing the cycle",
-        stack[0].query.description
-    ));
+    if stack.len() == 1 {
+        err.note(&format!("...which immediately requires {} again", stack[0].query.description));
+    } else {
+        err.note(&format!(
+            "...which again requires {}, completing the cycle",
+            stack[0].query.description
+        ));
+    }
+
+    if stack.iter().all(|entry| {
+        entry.query.def_kind.map_or(false, |def_kind| {
+            matches!(def_kind, SimpleDefKind::TyAlias | SimpleDefKind::TraitAlias)
+        })
+    }) {
+        if stack.iter().all(|entry| {
+            entry
+                .query
+                .def_kind
+                .map_or(false, |def_kind| matches!(def_kind, SimpleDefKind::TyAlias))
+        }) {
+            err.note("type aliases cannot be recursive");
+            err.help("consider using a struct, enum, or union instead to break the cycle");
+            err.help("see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information");
+        } else {
+            err.note("trait aliases cannot be recursive");
+        }
+    }
 
     if let Some((span, query)) = usage {
         err.span_note(fix_span(span, &query), &format!("cycle used when {}", query.description));
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 7288aaef8f2..dffe7f3689f 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -29,24 +29,53 @@ pub struct QueryStackFrame {
     pub name: &'static str,
     pub description: String,
     span: Option<Span>,
+    /// The `DefKind` this query frame is associated with, if applicable.
+    ///
+    /// We can't use `rustc_hir::def::DefKind` because `rustc_hir` is not
+    /// available in `rustc_query_system`. Instead, we have a simplified
+    /// custom version of it, called [`SimpleDefKind`].
+    def_kind: Option<SimpleDefKind>,
     /// This hash is used to deterministically pick
     /// a query to remove cycles in the parallel compiler.
     #[cfg(parallel_compiler)]
     hash: u64,
 }
 
+/// A simplified version of `rustc_hir::def::DefKind`.
+///
+/// It was added to help improve cycle errors caused by recursive type aliases.
+/// As of August 2021, `rustc_query_system` cannot depend on `rustc_hir`
+/// because it would create a dependency cycle. So, instead, a simplified
+/// version of `DefKind` was added to `rustc_query_system`.
+///
+/// `DefKind`s are converted to `SimpleDefKind`s in `rustc_query_impl`.
+#[derive(Debug, Copy, Clone)]
+pub enum SimpleDefKind {
+    Struct,
+    Enum,
+    Union,
+    Trait,
+    TyAlias,
+    TraitAlias,
+
+    // FIXME: add more from `rustc_hir::def::DefKind` and then remove `Other`
+    Other,
+}
+
 impl QueryStackFrame {
     #[inline]
     pub fn new(
         name: &'static str,
         description: String,
         span: Option<Span>,
+        def_kind: Option<SimpleDefKind>,
         _hash: impl FnOnce() -> u64,
     ) -> Self {
         Self {
             name,
             description,
             span,
+            def_kind,
             #[cfg(parallel_compiler)]
             hash: _hash(),
         }
diff --git a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr
index e72ef0e4b33..4162cdaa8dc 100644
--- a/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr
+++ b/src/test/ui/associated-type-bounds/ambiguous-associated-type2.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing the super traits of `Baz` with assoc
 LL | trait Baz: Foo + Bar<Self::Item> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: ...which again requires computing the super traits of `Baz` with associated type name `Item`, completing the cycle
+   = note: ...which immediately requires computing the super traits of `Baz` with associated type name `Item` again
 note: cycle used when computing the super traits of `Baz`
   --> $DIR/ambiguous-associated-type2.rs:7:1
    |
diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
index f3edf1c350f..97f3c759355 100644
--- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
+++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
@@ -14,7 +14,7 @@ error[E0391]: cycle detected when building specialization graph of trait `Trait`
 LL | trait Trait<T> { type Assoc; }
    | ^^^^^^^^^^^^^^
    |
-   = note: ...which again requires building specialization graph of trait `Trait`, completing the cycle
+   = note: ...which immediately requires building specialization graph of trait `Trait` again
 note: cycle used when coherence checking all impls of trait `Trait`
   --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1
    |
diff --git a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
index 58c458709a8..fc842fada5a 100644
--- a/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
+++ b/src/test/ui/cycle-trait/cycle-trait-default-type-trait.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `Foo::X`
 LL | trait Foo<X = Box<dyn Foo>> {
    |                       ^^^
    |
-   = note: ...which again requires computing type of `Foo::X`, completing the cycle
+   = note: ...which immediately requires computing type of `Foo::X` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/cycle-trait-default-type-trait.rs:4:1
    |
@@ -17,7 +17,7 @@ error[E0391]: cycle detected when computing type of `Foo::X`
 LL | trait Foo<X = Box<dyn Foo>> {
    |                       ^^^
    |
-   = note: ...which again requires computing type of `Foo::X`, completing the cycle
+   = note: ...which immediately requires computing type of `Foo::X` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/cycle-trait-default-type-trait.rs:4:1
    |
diff --git a/src/test/ui/infinite/infinite-struct.stderr b/src/test/ui/infinite/infinite-struct.stderr
index 7ffb51061b7..369645f9030 100644
--- a/src/test/ui/infinite/infinite-struct.stderr
+++ b/src/test/ui/infinite/infinite-struct.stderr
@@ -18,7 +18,7 @@ error[E0391]: cycle detected when computing drop-check constraints for `Take`
 LL | struct Take(Take);
    | ^^^^^^^^^^^^^^^^^^
    |
-   = note: ...which again requires computing drop-check constraints for `Take`, completing the cycle
+   = note: ...which immediately requires computing drop-check constraints for `Take` again
    = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: Take } }`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/infinite/infinite-tag-type-recursion.stderr b/src/test/ui/infinite/infinite-tag-type-recursion.stderr
index 1f147e070b4..61b5e946775 100644
--- a/src/test/ui/infinite/infinite-tag-type-recursion.stderr
+++ b/src/test/ui/infinite/infinite-tag-type-recursion.stderr
@@ -17,7 +17,7 @@ error[E0391]: cycle detected when computing drop-check constraints for `MList`
 LL | enum MList { Cons(isize, MList), Nil }
    | ^^^^^^^^^^
    |
-   = note: ...which again requires computing drop-check constraints for `MList`, completing the cycle
+   = note: ...which immediately requires computing drop-check constraints for `MList` again
    = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: MList } }`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/infinite/infinite-trait-alias-recursion.rs b/src/test/ui/infinite/infinite-trait-alias-recursion.rs
new file mode 100644
index 00000000000..ec86744e68c
--- /dev/null
+++ b/src/test/ui/infinite/infinite-trait-alias-recursion.rs
@@ -0,0 +1,10 @@
+#![feature(trait_alias)]
+
+trait T1 = T2;
+//~^ ERROR cycle detected when computing the super predicates of `T1`
+
+trait T2 = T3;
+
+trait T3 = T1 + T3;
+
+fn main() {}
diff --git a/src/test/ui/infinite/infinite-trait-alias-recursion.stderr b/src/test/ui/infinite/infinite-trait-alias-recursion.stderr
new file mode 100644
index 00000000000..5ecaedb3cb2
--- /dev/null
+++ b/src/test/ui/infinite/infinite-trait-alias-recursion.stderr
@@ -0,0 +1,42 @@
+error[E0391]: cycle detected when computing the super predicates of `T1`
+  --> $DIR/infinite-trait-alias-recursion.rs:3:1
+   |
+LL | trait T1 = T2;
+   | ^^^^^^^^^^^^^^
+   |
+note: ...which requires computing the super traits of `T1`...
+  --> $DIR/infinite-trait-alias-recursion.rs:3:12
+   |
+LL | trait T1 = T2;
+   |            ^^
+note: ...which requires computing the super predicates of `T2`...
+  --> $DIR/infinite-trait-alias-recursion.rs:6:1
+   |
+LL | trait T2 = T3;
+   | ^^^^^^^^^^^^^^
+note: ...which requires computing the super traits of `T2`...
+  --> $DIR/infinite-trait-alias-recursion.rs:6:12
+   |
+LL | trait T2 = T3;
+   |            ^^
+note: ...which requires computing the super predicates of `T3`...
+  --> $DIR/infinite-trait-alias-recursion.rs:8:1
+   |
+LL | trait T3 = T1 + T3;
+   | ^^^^^^^^^^^^^^^^^^^
+note: ...which requires computing the super traits of `T3`...
+  --> $DIR/infinite-trait-alias-recursion.rs:8:12
+   |
+LL | trait T3 = T1 + T3;
+   |            ^^
+   = note: ...which again requires computing the super predicates of `T1`, completing the cycle
+   = note: trait aliases cannot be recursive
+note: cycle used when collecting item types in top-level module
+  --> $DIR/infinite-trait-alias-recursion.rs:3:1
+   |
+LL | trait T1 = T2;
+   | ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/infinite/infinite-type-alias-mutual-recursion.rs b/src/test/ui/infinite/infinite-type-alias-mutual-recursion.rs
new file mode 100644
index 00000000000..5381eedcfac
--- /dev/null
+++ b/src/test/ui/infinite/infinite-type-alias-mutual-recursion.rs
@@ -0,0 +1,6 @@
+type X1 = X2;
+//~^ ERROR cycle detected when expanding type alias `X1`
+type X2 = X3;
+type X3 = X1;
+
+fn main() {}
diff --git a/src/test/ui/infinite/infinite-type-alias-mutual-recursion.stderr b/src/test/ui/infinite/infinite-type-alias-mutual-recursion.stderr
new file mode 100644
index 00000000000..7f82b294434
--- /dev/null
+++ b/src/test/ui/infinite/infinite-type-alias-mutual-recursion.stderr
@@ -0,0 +1,34 @@
+error[E0391]: cycle detected when expanding type alias `X1`
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:1:11
+   |
+LL | type X1 = X2;
+   |           ^^
+   |
+note: ...which requires expanding type alias `X2`...
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:3:11
+   |
+LL | type X2 = X3;
+   |           ^^
+note: ...which requires expanding type alias `X3`...
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:4:11
+   |
+LL | type X3 = X1;
+   |           ^^
+   = note: ...which again requires expanding type alias `X1`, completing the cycle
+   = note: type aliases cannot be recursive
+   = help: consider using a struct, enum, or union instead to break the cycle
+   = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
+note: cycle used when collecting item types in top-level module
+  --> $DIR/infinite-type-alias-mutual-recursion.rs:1:1
+   |
+LL | / type X1 = X2;
+LL | |
+LL | | type X2 = X3;
+LL | | type X3 = X1;
+LL | |
+LL | | fn main() {}
+   | |____________^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/infinite/infinite-vec-type-recursion.stderr b/src/test/ui/infinite/infinite-vec-type-recursion.stderr
index 77adefeb124..1e487a5b11c 100644
--- a/src/test/ui/infinite/infinite-vec-type-recursion.stderr
+++ b/src/test/ui/infinite/infinite-vec-type-recursion.stderr
@@ -1,10 +1,13 @@
-error[E0391]: cycle detected when computing type of `X`
+error[E0391]: cycle detected when expanding type alias `X`
   --> $DIR/infinite-vec-type-recursion.rs:1:14
    |
 LL | type X = Vec<X>;
    |              ^
    |
-   = note: ...which again requires computing type of `X`, completing the cycle
+   = note: ...which immediately requires expanding type alias `X` again
+   = note: type aliases cannot be recursive
+   = help: consider using a struct, enum, or union instead to break the cycle
+   = help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
 note: cycle used when collecting item types in top-level module
   --> $DIR/infinite-vec-type-recursion.rs:1:1
    |
diff --git a/src/test/ui/issues/issue-20772.stderr b/src/test/ui/issues/issue-20772.stderr
index 4aecc7eab46..c964dc41dce 100644
--- a/src/test/ui/issues/issue-20772.stderr
+++ b/src/test/ui/issues/issue-20772.stderr
@@ -6,7 +6,7 @@ LL | |
 LL | | {}
    | |__^
    |
-   = note: ...which again requires computing the super traits of `T` with associated type name `Item`, completing the cycle
+   = note: ...which immediately requires computing the super traits of `T` with associated type name `Item` again
 note: cycle used when computing the super traits of `T`
   --> $DIR/issue-20772.rs:1:1
    |
diff --git a/src/test/ui/issues/issue-20825.stderr b/src/test/ui/issues/issue-20825.stderr
index ccbe06d9c0d..be2bbd44800 100644
--- a/src/test/ui/issues/issue-20825.stderr
+++ b/src/test/ui/issues/issue-20825.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing the super traits of `Processor` with
 LL | pub trait Processor: Subscriber<Input = Self::Input> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: ...which again requires computing the super traits of `Processor` with associated type name `Input`, completing the cycle
+   = note: ...which immediately requires computing the super traits of `Processor` with associated type name `Input` again
 note: cycle used when computing the super traits of `Processor`
   --> $DIR/issue-20825.rs:5:1
    |
diff --git a/src/test/ui/issues/issue-21177.stderr b/src/test/ui/issues/issue-21177.stderr
index 59cc6550a8b..6877a184605 100644
--- a/src/test/ui/issues/issue-21177.stderr
+++ b/src/test/ui/issues/issue-21177.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing the bounds for type parameter `T`
 LL | fn foo<T: Trait<A = T::B>>() { }
    |                     ^^^^
    |
-   = note: ...which again requires computing the bounds for type parameter `T`, completing the cycle
+   = note: ...which immediately requires computing the bounds for type parameter `T` again
 note: cycle used when computing explicit predicates of `foo`
   --> $DIR/issue-21177.rs:6:21
    |
diff --git a/src/test/ui/issues/issue-34373.stderr b/src/test/ui/issues/issue-34373.stderr
index e8c1e8f9669..8be3cfa72fb 100644
--- a/src/test/ui/issues/issue-34373.stderr
+++ b/src/test/ui/issues/issue-34373.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `Foo::T`
 LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
    |                              ^^^^^^^^^^
    |
-note: ...which requires computing type of `DefaultFoo`...
+note: ...which requires expanding type alias `DefaultFoo`...
   --> $DIR/issue-34373.rs:8:19
    |
 LL | type DefaultFoo = Foo;
diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr
index 525b5cf7d84..0dcf0184db1 100644
--- a/src/test/ui/resolve/issue-23305.stderr
+++ b/src/test/ui/resolve/issue-23305.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/issue-23305.r
 LL | impl dyn ToNbt<Self> {}
    |                ^^^^
    |
-   = note: ...which again requires computing type of `<impl at $DIR/issue-23305.rs:5:1: 5:24>`, completing the cycle
+   = note: ...which immediately requires computing type of `<impl at $DIR/issue-23305.rs:5:1: 5:24>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/issue-23305.rs:1:1
    |
diff --git a/src/test/ui/resolve/resolve-self-in-impl.stderr b/src/test/ui/resolve/resolve-self-in-impl.stderr
index 5b5c1834cad..7f623e47353 100644
--- a/src/test/ui/resolve/resolve-self-in-impl.stderr
+++ b/src/test/ui/resolve/resolve-self-in-impl.stderr
@@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-
 LL | impl Tr for Self {}
    |             ^^^^
    |
-   = note: ...which again requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:14:1: 14:20>`, completing the cycle
+   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:14:1: 14:20>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/resolve-self-in-impl.rs:1:1
    |
@@ -23,7 +23,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-
 LL | impl Tr for S<Self> {}
    |               ^^^^
    |
-   = note: ...which again requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:23>`, completing the cycle
+   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:15:1: 15:23>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/resolve-self-in-impl.rs:1:1
    |
@@ -42,7 +42,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-
 LL | impl Self {}
    |      ^^^^
    |
-   = note: ...which again requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:13>`, completing the cycle
+   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:16:1: 16:13>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/resolve-self-in-impl.rs:1:1
    |
@@ -61,7 +61,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-
 LL | impl S<Self> {}
    |        ^^^^
    |
-   = note: ...which again requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:16>`, completing the cycle
+   = note: ...which immediately requires computing type of `<impl at $DIR/resolve-self-in-impl.rs:17:1: 17:16>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/resolve-self-in-impl.rs:1:1
    |
@@ -80,7 +80,7 @@ error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/
 LL | impl Tr<Self::A> for S {}
    | ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: ...which again requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:26>`, completing the cycle
+   = note: ...which immediately requires computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:18:1: 18:26>` again
 note: cycle used when collecting item types in top-level module
   --> $DIR/resolve-self-in-impl.rs:1:1
    |