Auto merge of #88121 - camelid:better-recursive-alias-error, r=estebank
Improve errors for recursive type aliases Fixes #17539.
This commit is contained in:
commit
c4f26b15e3
23 changed files with 227 additions and 25 deletions
|
@ -120,7 +120,18 @@ rustc_queries! {
|
||||||
|
|
||||||
/// Records the type of every item.
|
/// Records the type of every item.
|
||||||
query type_of(key: DefId) -> Ty<'tcx> {
|
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() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,12 @@ pub trait Key {
|
||||||
/// In the event that a cycle occurs, if no explicit span has been
|
/// 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?
|
/// given for a query with key `self`, what span should we use?
|
||||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
|
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 () {
|
impl Key for () {
|
||||||
|
@ -95,6 +101,9 @@ impl Key for LocalDefId {
|
||||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||||
self.to_def_id().default_span(tcx)
|
self.to_def_id().default_span(tcx)
|
||||||
}
|
}
|
||||||
|
fn key_as_def_id(&self) -> Option<DefId> {
|
||||||
|
Some(self.to_def_id())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key for DefId {
|
impl Key for DefId {
|
||||||
|
@ -105,6 +114,10 @@ impl Key for DefId {
|
||||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||||
tcx.def_span(*self)
|
tcx.def_span(*self)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn key_as_def_id(&self) -> Option<DefId> {
|
||||||
|
Some(*self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key for ty::WithOptConstParam<LocalDefId> {
|
impl Key for ty::WithOptConstParam<LocalDefId> {
|
||||||
|
@ -165,6 +178,10 @@ impl Key for (DefId, Option<Ident>) {
|
||||||
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||||
tcx.def_span(self.0)
|
tcx.def_span(self.0)
|
||||||
}
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn key_as_def_id(&self) -> Option<DefId> {
|
||||||
|
Some(self.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key for (DefId, LocalDefId, Ident) {
|
impl Key for (DefId, LocalDefId, Ident) {
|
||||||
|
|
|
@ -51,6 +51,8 @@ pub use on_disk_cache::OnDiskCache;
|
||||||
mod profiling_support;
|
mod profiling_support;
|
||||||
pub use self::profiling_support::alloc_self_profile_query_strings;
|
pub use self::profiling_support::alloc_self_profile_query_strings;
|
||||||
|
|
||||||
|
mod util;
|
||||||
|
|
||||||
rustc_query_append! { [define_queries!][<'tcx>] }
|
rustc_query_append! { [define_queries!][<'tcx>] }
|
||||||
|
|
||||||
impl<'tcx> Queries<'tcx> {
|
impl<'tcx> Queries<'tcx> {
|
||||||
|
|
|
@ -337,6 +337,13 @@ macro_rules! define_queries {
|
||||||
} else {
|
} else {
|
||||||
Some(key.default_span(*tcx))
|
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 hash = || {
|
||||||
let mut hcx = tcx.create_stable_hashing_context();
|
let mut hcx = tcx.create_stable_hashing_context();
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
|
@ -345,7 +352,7 @@ macro_rules! define_queries {
|
||||||
hasher.finish::<u64>()
|
hasher.finish::<u64>()
|
||||||
};
|
};
|
||||||
|
|
||||||
QueryStackFrame::new(name, description, span, hash)
|
QueryStackFrame::new(name, description, span, def_kind, hash)
|
||||||
})*
|
})*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
compiler/rustc_query_impl/src/util.rs
Normal file
18
compiler/rustc_query_impl/src/util.rs
Normal file
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::dep_graph::DepContext;
|
use crate::dep_graph::DepContext;
|
||||||
use crate::query::plumbing::CycleError;
|
use crate::query::plumbing::CycleError;
|
||||||
use crate::query::{QueryContext, QueryStackFrame};
|
use crate::query::{QueryContext, QueryStackFrame, SimpleDefKind};
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level};
|
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.span_note(span, &format!("...which requires {}...", query.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if stack.len() == 1 {
|
||||||
|
err.note(&format!("...which immediately requires {} again", stack[0].query.description));
|
||||||
|
} else {
|
||||||
err.note(&format!(
|
err.note(&format!(
|
||||||
"...which again requires {}, completing the cycle",
|
"...which again requires {}, completing the cycle",
|
||||||
stack[0].query.description
|
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 {
|
if let Some((span, query)) = usage {
|
||||||
err.span_note(fix_span(span, &query), &format!("cycle used when {}", query.description));
|
err.span_note(fix_span(span, &query), &format!("cycle used when {}", query.description));
|
||||||
|
|
|
@ -29,24 +29,53 @@ pub struct QueryStackFrame {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
span: Option<Span>,
|
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
|
/// This hash is used to deterministically pick
|
||||||
/// a query to remove cycles in the parallel compiler.
|
/// a query to remove cycles in the parallel compiler.
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
hash: u64,
|
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 {
|
impl QueryStackFrame {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
description: String,
|
description: String,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
|
def_kind: Option<SimpleDefKind>,
|
||||||
_hash: impl FnOnce() -> u64,
|
_hash: impl FnOnce() -> u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
span,
|
span,
|
||||||
|
def_kind,
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
hash: _hash(),
|
hash: _hash(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing the super traits of `Baz` with assoc
|
||||||
LL | trait Baz: Foo + Bar<Self::Item> {}
|
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`
|
note: cycle used when computing the super traits of `Baz`
|
||||||
--> $DIR/ambiguous-associated-type2.rs:7:1
|
--> $DIR/ambiguous-associated-type2.rs:7:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ error[E0391]: cycle detected when building specialization graph of trait `Trait`
|
||||||
LL | trait Trait<T> { type Assoc; }
|
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`
|
note: cycle used when coherence checking all impls of trait `Trait`
|
||||||
--> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1
|
--> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `Foo::X`
|
||||||
LL | trait Foo<X = Box<dyn Foo>> {
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/cycle-trait-default-type-trait.rs:4:1
|
--> $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>> {
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/cycle-trait-default-type-trait.rs:4:1
|
--> $DIR/cycle-trait-default-type-trait.rs:4:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ error[E0391]: cycle detected when computing drop-check constraints for `Take`
|
||||||
LL | struct Take(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 } }`
|
= 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
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -17,7 +17,7 @@ error[E0391]: cycle detected when computing drop-check constraints for `MList`
|
||||||
LL | enum MList { Cons(isize, MList), Nil }
|
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 } }`
|
= 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
|
error: aborting due to 2 previous errors
|
||||||
|
|
10
src/test/ui/infinite/infinite-trait-alias-recursion.rs
Normal file
10
src/test/ui/infinite/infinite-trait-alias-recursion.rs
Normal file
|
@ -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() {}
|
42
src/test/ui/infinite/infinite-trait-alias-recursion.stderr
Normal file
42
src/test/ui/infinite/infinite-trait-alias-recursion.stderr
Normal file
|
@ -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`.
|
|
@ -0,0 +1,6 @@
|
||||||
|
type X1 = X2;
|
||||||
|
//~^ ERROR cycle detected when expanding type alias `X1`
|
||||||
|
type X2 = X3;
|
||||||
|
type X3 = X1;
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -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`.
|
|
@ -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
|
--> $DIR/infinite-vec-type-recursion.rs:1:14
|
||||||
|
|
|
|
||||||
LL | type X = Vec<X>;
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/infinite-vec-type-recursion.rs:1:1
|
--> $DIR/infinite-vec-type-recursion.rs:1:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | |
|
||||||
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`
|
note: cycle used when computing the super traits of `T`
|
||||||
--> $DIR/issue-20772.rs:1:1
|
--> $DIR/issue-20772.rs:1:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing the super traits of `Processor` with
|
||||||
LL | pub trait Processor: Subscriber<Input = Self::Input> {
|
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`
|
note: cycle used when computing the super traits of `Processor`
|
||||||
--> $DIR/issue-20825.rs:5:1
|
--> $DIR/issue-20825.rs:5:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing the bounds for type parameter `T`
|
||||||
LL | fn foo<T: Trait<A = T::B>>() { }
|
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`
|
note: cycle used when computing explicit predicates of `foo`
|
||||||
--> $DIR/issue-21177.rs:6:21
|
--> $DIR/issue-21177.rs:6:21
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `Foo::T`
|
||||||
LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
|
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
|
--> $DIR/issue-34373.rs:8:19
|
||||||
|
|
|
|
||||||
LL | type DefaultFoo = Foo;
|
LL | type DefaultFoo = Foo;
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/issue-23305.r
|
||||||
LL | impl dyn ToNbt<Self> {}
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/issue-23305.rs:1:1
|
--> $DIR/issue-23305.rs:1:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0391]: cycle detected when computing type of `<impl at $DIR/resolve-self-
|
||||||
LL | impl Tr for 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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/resolve-self-in-impl.rs:1:1
|
--> $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> {}
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/resolve-self-in-impl.rs:1:1
|
--> $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 {}
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/resolve-self-in-impl.rs:1:1
|
--> $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> {}
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/resolve-self-in-impl.rs:1:1
|
--> $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 {}
|
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
|
note: cycle used when collecting item types in top-level module
|
||||||
--> $DIR/resolve-self-in-impl.rs:1:1
|
--> $DIR/resolve-self-in-impl.rs:1:1
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue