Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions compiler/rustc_middle/src/query/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::fmt::Debug;
use std::hash::Hash;

use rustc_ast::tokenstream::TokenStream;
use rustc_data_structures::sso::SsoHashSet;
use rustc_data_structures::stable_hasher::HashStable;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
use rustc_hir::hir_id::OwnerId;
Expand Down Expand Up @@ -257,8 +258,8 @@ impl<'tcx> QueryKey for GenericArg<'tcx> {
}

impl<'tcx> QueryKey for Ty<'tcx> {
fn default_span(&self, _: TyCtxt<'_>) -> Span {
DUMMY_SP
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
def_id_of_type(*self).map(|def_id| tcx.def_span(def_id)).unwrap_or(DUMMY_SP)
}
}

Expand Down Expand Up @@ -361,3 +362,58 @@ impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) {
self.0.default_span(tcx)
}
}

/// Gets a `DefId` associated with a type
///
/// Visited set is needed to avoid full iteration over
/// deeply nested tuples that have no DefId.
fn def_id_of_type_cached<'a>(ty: Ty<'a>, visited: &mut SsoHashSet<Ty<'a>>) -> Option<DefId> {
match *ty.kind() {
ty::Adt(adt_def, _) => Some(adt_def.did()),

ty::Dynamic(data, ..) => data.principal_def_id(),

ty::Pat(subty, _) | ty::Array(subty, _) | ty::Slice(subty) => {
def_id_of_type_cached(subty, visited)
}

ty::RawPtr(ty, _) => def_id_of_type_cached(ty, visited),

ty::Ref(_, ty, _) => def_id_of_type_cached(ty, visited),

ty::Tuple(tys) => tys.iter().find_map(|ty| {
if visited.insert(ty) {
return def_id_of_type_cached(ty, visited);
}
return None;
}),

ty::FnDef(def_id, _)
| ty::Closure(def_id, _)
| ty::CoroutineClosure(def_id, _)
| ty::Coroutine(def_id, _)
| ty::CoroutineWitness(def_id, _)
| ty::Foreign(def_id) => Some(def_id),

ty::Alias(_, ty) => Some(ty.def_id),

ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Str
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Placeholder(..)
| ty::Param(_)
| ty::Infer(_)
| ty::Bound(..)
| ty::Error(_)
| ty::Never
| ty::Float(_) => None,
}
}

fn def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
def_id_of_type_cached(ty, &mut SsoHashSet::new())
}
6 changes: 5 additions & 1 deletion tests/ui/consts/const-size_of-cycle.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ note: ...which requires simplifying constant for the type system `core::mem::Siz
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
note: ...which requires const-evaluating + checking `core::mem::SizedTypeProperties::SIZE`...
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
= note: ...which requires computing layout of `Foo`...
note: ...which requires computing layout of `Foo`...
--> $DIR/const-size_of-cycle.rs:1:1
|
LL | struct Foo {
| ^^^^^^^^^^
= note: ...which requires computing layout of `[u8; std::mem::size_of::<Foo>()]`...
note: ...which requires normalizing `[u8; std::mem::size_of::<Foo>()]`...
--> $DIR/const-size_of-cycle.rs:2:17
Expand Down
6 changes: 5 additions & 1 deletion tests/ui/consts/issue-44415.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`..
|
LL | bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `Foo`...
note: ...which requires computing layout of `Foo`...
--> $DIR/issue-44415.rs:5:1
|
LL | struct Foo {
| ^^^^^^^^^^
= note: ...which requires computing layout of `[u8; unsafe { intrinsics::size_of::<Foo>() }]`...
note: ...which requires normalizing `[u8; unsafe { intrinsics::size_of::<Foo>() }]`...
--> $DIR/issue-44415.rs:6:17
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/layout/layout-cycle.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//@ build-fail
//~^ ERROR: cycle detected when computing layout of

// Issue #111176 -- ensure that we do not emit ICE on layout cycles

use std::mem;

pub struct S<T: Tr> {
//~^ ERROR: cycle detected when computing layout of
pub f: <T as Tr>::I,
}

Expand Down
10 changes: 9 additions & 1 deletion tests/ui/layout/layout-cycle.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
error[E0391]: cycle detected when computing layout of `S<S<()>>`
--> $DIR/layout-cycle.rs:7:1
|
= note: ...which requires computing layout of `<S<()> as Tr>::I`...
LL | pub struct S<T: Tr> {
| ^^^^^^^^^^^^^^^^^^^
|
note: ...which requires computing layout of `<S<()> as Tr>::I`...
--> $DIR/layout-cycle.rs:13:5
|
LL | type I: Tr;
| ^^^^^^^^^^
= note: ...which again requires computing layout of `S<S<()>>`, completing the cycle
note: cycle used when const-evaluating + checking `core::mem::SizedTypeProperties::SIZE`
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/layout/post-mono-layout-cycle.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@ build-fail
//~^ ERROR cycle detected when computing layout of `Wrapper<()>`

trait Trait {
type Assoc;
Expand All @@ -10,6 +9,7 @@ impl Trait for () {
}

struct Wrapper<T: Trait> {
//~^ ERROR cycle detected when computing layout of `Wrapper<()>`
_x: <T as Trait>::Assoc,
}

Expand Down
13 changes: 11 additions & 2 deletions tests/ui/layout/post-mono-layout-cycle.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
error[E0391]: cycle detected when computing layout of `Wrapper<()>`
--> $DIR/post-mono-layout-cycle.rs:11:1
|
= note: ...which requires computing layout of `<() as Trait>::Assoc`...
LL | struct Wrapper<T: Trait> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires computing layout of `<() as Trait>::Assoc`...
--> $DIR/post-mono-layout-cycle.rs:4:5
|
LL | type Assoc;
| ^^^^^^^^^^
= note: ...which again requires computing layout of `Wrapper<()>`, completing the cycle
= note: cycle used when computing layout of `core::option::Option<Wrapper<()>>`
note: cycle used when computing layout of `core::option::Option<Wrapper<()>>`
--> $SRC_DIR/core/src/option.rs:LL:COL
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error
Expand Down
9 changes: 7 additions & 2 deletions tests/ui/pattern/non-structural-match-types-cycle-err.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ note: ...which requires const-evaluating + checking `<impl at $DIR/non-structura
|
LL | const NONE: Option<T> = None;
| ^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `core::option::Option<{async block@$DIR/non-structural-match-types-cycle-err.rs:18:16: 18:21}>`...
= note: ...which requires computing layout of `{async block@$DIR/non-structural-match-types-cycle-err.rs:18:16: 18:21}`...
note: ...which requires computing layout of `core::option::Option<{async block@$DIR/non-structural-match-types-cycle-err.rs:18:16: 18:21}>`...
--> $SRC_DIR/core/src/option.rs:LL:COL
note: ...which requires computing layout of `{async block@$DIR/non-structural-match-types-cycle-err.rs:18:16: 18:21}`...
--> $DIR/non-structural-match-types-cycle-err.rs:18:16
|
LL | match Some(async {}) {
| ^^^^^
note: ...which requires optimizing MIR for `defines::{closure#0}`...
--> $DIR/non-structural-match-types-cycle-err.rs:18:16
|
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/recursion/issue-26548-recursion-via-normalize.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//~ ERROR cycle detected when computing layout of `core::option::Option<S>`
//~| NOTE see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
//~| NOTE ...which requires computing layout of `S`...
//~| NOTE ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
//~| NOTE ...which again requires computing layout of `core::option::Option<S>`, completing the cycle
//~| NOTE cycle used when computing layout of `core::option::Option<<S as Mirror>::It>`
//~? ERROR cycle detected when computing layout of `core::option::Option<S>`
//~? NOTE see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
//~? NOTE ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
//~? NOTE ...which again requires computing layout of `core::option::Option<S>`, completing the cycle
//~? NOTE cycle used when computing layout of `core::option::Option<<S as Mirror>::It>`

trait Mirror {
type It: ?Sized;
Expand All @@ -12,6 +11,7 @@ impl<T: ?Sized> Mirror for T {
type It = Self;
}
struct S(Option<<S as Mirror>::It>);
//~^ NOTE ...which requires computing layout of `S`...

fn main() {
let _s = S(None);
Expand Down
13 changes: 10 additions & 3 deletions tests/ui/recursion/issue-26548-recursion-via-normalize.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
error[E0391]: cycle detected when computing layout of `core::option::Option<S>`
--> $SRC_DIR/core/src/option.rs:LL:COL
|
= note: ...which requires computing layout of `S`...
= note: ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
note: ...which requires computing layout of `S`...
--> $DIR/issue-26548-recursion-via-normalize.rs:13:1
|
LL | struct S(Option<<S as Mirror>::It>);
| ^^^^^^^^
note: ...which requires computing layout of `core::option::Option<<S as Mirror>::It>`...
--> $SRC_DIR/core/src/option.rs:LL:COL
= note: ...which again requires computing layout of `core::option::Option<S>`, completing the cycle
= note: cycle used when computing layout of `core::option::Option<<S as Mirror>::It>`
note: cycle used when computing layout of `core::option::Option<<S as Mirror>::It>`
--> $SRC_DIR/core/src/option.rs:LL:COL
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/sized/recursive-type-binding.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//@ build-fail
//~^ ERROR cycle detected when computing layout of `Foo<()>`

trait A { type Assoc: ?Sized; }
trait A {
type Assoc: ?Sized;
}

impl A for () {
type Assoc = Foo<()>;
}
struct Foo<T: A>(T::Assoc);
//~^ ERROR cycle detected when computing layout of `Foo<()>`

fn main() {
let x: Foo<()>;
Expand Down
12 changes: 10 additions & 2 deletions tests/ui/sized/recursive-type-binding.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
error[E0391]: cycle detected when computing layout of `Foo<()>`
--> $DIR/recursive-type-binding.rs:10:1
|
= note: ...which requires computing layout of `<() as A>::Assoc`...
LL | struct Foo<T: A>(T::Assoc);
| ^^^^^^^^^^^^^^^^
|
note: ...which requires computing layout of `<() as A>::Assoc`...
--> $DIR/recursive-type-binding.rs:4:5
|
LL | type Assoc: ?Sized;
| ^^^^^^^^^^^^^^^^^^
= note: ...which again requires computing layout of `Foo<()>`, completing the cycle
note: cycle used when elaborating drops for `main`
--> $DIR/recursive-type-binding.rs:11:1
--> $DIR/recursive-type-binding.rs:13:1
|
LL | fn main() {
| ^^^^^^^^^
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/sized/recursive-type-coercion-from-never.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
//@ build-fail
//~^ ERROR cycle detected when computing layout of `Foo<()>`

// Regression test for a stack overflow: https://github.com/rust-lang/rust/issues/113197

trait A { type Assoc; }
trait A {
type Assoc;
}

impl A for () {
type Assoc = Foo<()>;
}

struct Foo<T: A>(T::Assoc);
//~^ ERROR cycle detected when computing layout of `Foo<()>`

fn main() {
Foo::<()>(todo!());
Expand Down
12 changes: 10 additions & 2 deletions tests/ui/sized/recursive-type-coercion-from-never.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
error[E0391]: cycle detected when computing layout of `Foo<()>`
--> $DIR/recursive-type-coercion-from-never.rs:13:1
|
= note: ...which requires computing layout of `<() as A>::Assoc`...
LL | struct Foo<T: A>(T::Assoc);
| ^^^^^^^^^^^^^^^^
|
note: ...which requires computing layout of `<() as A>::Assoc`...
--> $DIR/recursive-type-coercion-from-never.rs:6:5
|
LL | type Assoc;
| ^^^^^^^^^^
= note: ...which again requires computing layout of `Foo<()>`, completing the cycle
note: cycle used when elaborating drops for `main`
--> $DIR/recursive-type-coercion-from-never.rs:14:1
--> $DIR/recursive-type-coercion-from-never.rs:16:1
|
LL | fn main() {
| ^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/sized/stack-overflow-trait-infer-98842.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// issue: rust-lang/rust#98842
//@ check-fail
//@ edition:2021
//~^^^^ ERROR cycle detected when computing layout of `Foo`

// If the inner `Foo` is named through an associated type,
// the "infinite size" error does not occur.
struct Foo(<&'static Foo as ::core::ops::Deref>::Target);
//~^ ERROR cycle detected when computing layout of `Foo`
// But Rust will be unable to know whether `Foo` is sized or not,
// and it will infinitely recurse somewhere trying to figure out the
// size of this pointer (is my guess):
Expand Down
7 changes: 6 additions & 1 deletion tests/ui/sized/stack-overflow-trait-infer-98842.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
error[E0391]: cycle detected when computing layout of `Foo`
--> $DIR/stack-overflow-trait-infer-98842.rs:8:1
|
= note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
LL | struct Foo(<&'static Foo as ::core::ops::Deref>::Target);
| ^^^^^^^^^^
|
note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
= note: ...which again requires computing layout of `Foo`, completing the cycle
note: cycle used when const-evaluating + checking `_`
--> $DIR/stack-overflow-trait-infer-98842.rs:13:1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
error[E0391]: cycle detected when computing layout of `<[Hello] as Normalize>::Assoc`
--> $DIR/129541-recursive-enum-and-array-impl.rs:8:5
|
= note: ...which requires computing layout of `Hello`...
LL | type Assoc;
| ^^^^^^^^^^
|
note: ...which requires computing layout of `Hello`...
--> $DIR/129541-recursive-enum-and-array-impl.rs:21:1
|
LL | enum Hello {
| ^^^^^^^^^^
= note: ...which again requires computing layout of `<[Hello] as Normalize>::Assoc`, completing the cycle
= note: cycle used when computing layout of `Hello`
note: cycle used when computing layout of `Hello`
--> $DIR/129541-recursive-enum-and-array-impl.rs:21:1
|
LL | enum Hello {
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
error[E0391]: cycle detected when computing layout of `<[Hello] as Normalize>::Assoc`
--> $DIR/129541-recursive-enum-and-array-impl.rs:8:5
|
= note: ...which requires computing layout of `Hello`...
LL | type Assoc;
| ^^^^^^^^^^
|
note: ...which requires computing layout of `Hello`...
--> $DIR/129541-recursive-enum-and-array-impl.rs:21:1
|
LL | enum Hello {
| ^^^^^^^^^^
= note: ...which again requires computing layout of `<[Hello] as Normalize>::Assoc`, completing the cycle
= note: cycle used when computing layout of `Hello`
note: cycle used when computing layout of `Hello`
--> $DIR/129541-recursive-enum-and-array-impl.rs:21:1
|
LL | enum Hello {
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Regression test for #129541
//~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391]

//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

trait Bound {}
trait Normalize {
type Assoc;
//~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391]
}

impl<T: Bound> Normalize for T {
Expand Down
Loading
Loading