Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Sized coinductive, again #100386

Merged
merged 4 commits into from Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Expand Up @@ -2506,6 +2506,10 @@ impl<'tcx> TyCtxt<'tcx> {
self.trait_def(trait_def_id).has_auto_impl
}

pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
self.trait_is_auto(trait_def_id) || self.lang_items().sized_trait() == Some(trait_def_id)
}

/// Returns layout of a generator. Layout might be unavailable if the
/// generator is tainted by errors.
pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Expand Up @@ -959,7 +959,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
let result = match predicate.kind().skip_binder() {
ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()),
ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_coinductive(data.def_id()),
ty::PredicateKind::WellFormed(_) => true,
_ => false,
};
Expand Down
7 changes: 2 additions & 5 deletions src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -1,15 +1,12 @@
// check-fail
// known-bug: #80626

// This should pass, but it requires `Sized` to be coinductive.
// check-pass

trait Allocator {
type Allocated<T>;
}

enum LinkedList<A: Allocator> {
Head,
Next(A::Allocated<Self>)
Next(A::Allocated<Self>),
}

fn main() {}
15 changes: 0 additions & 15 deletions src/test/ui/generic-associated-types/bugs/issue-80626.stderr

This file was deleted.

8 changes: 6 additions & 2 deletions src/test/ui/generic-associated-types/issue-87750.rs
@@ -1,3 +1,5 @@
// check-pass

trait PointerFamily {
type Pointer<T>;
}
Expand All @@ -10,11 +12,13 @@ impl PointerFamily for RcFamily {
}

#[allow(dead_code)]
enum Node<T, P: PointerFamily> where P::Pointer<Node<T, P>>: Sized {
enum Node<T, P: PointerFamily>
where
P::Pointer<Node<T, P>>: Sized,
{
Cons(P::Pointer<Node<T, P>>),
}

fn main() {
let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
//~^ ERROR overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
}
9 changes: 0 additions & 9 deletions src/test/ui/generic-associated-types/issue-87750.stderr

This file was deleted.

Expand Up @@ -21,6 +21,7 @@ impl<T> Foo for Number<T> {
// ```
// which it is :)
type Item = [T] where [T]: Sized;
//~^ ERROR overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
}

struct OnlySized<T> where T: Sized { f: T }
Expand All @@ -40,7 +41,6 @@ impl<T> Bar for T where T: Foo {
// can use the bound on `Foo::Item` for this, but that requires
// `wf(<T as Foo>::Item)`, which is an invalid cycle.
type Assoc = OnlySized<<T as Foo>::Item>;
//~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
}

fn foo<T: Print>() {
Expand Down
@@ -1,14 +1,8 @@
error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
--> $DIR/projection-bound-cycle-generic.rs:42:18
error[E0275]: overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
--> $DIR/projection-bound-cycle-generic.rs:23:5
|
LL | type Assoc = OnlySized<<T as Foo>::Item>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `OnlySized`
--> $DIR/projection-bound-cycle-generic.rs:26:18
|
LL | struct OnlySized<T> where T: Sized { f: T }
| ^ required by this bound in `OnlySized`
LL | type Item = [T] where [T]: Sized;
| ^^^^^^^^^

error: aborting due to previous error

Expand Down
Expand Up @@ -24,6 +24,7 @@ impl Foo for Number {
// ```
// which it is :)
type Item = str where str: Sized;
//~^ ERROR overflow evaluating the requirement `<Number as Foo>::Item == _`
}

struct OnlySized<T> where T: Sized { f: T }
Expand All @@ -43,7 +44,6 @@ impl<T> Bar for T where T: Foo {
// can use the bound on `Foo::Item` for this, but that requires
// `wf(<T as Foo>::Item)`, which is an invalid cycle.
type Assoc = OnlySized<<T as Foo>::Item>;
//~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
}

fn foo<T: Print>() {
Expand Down
14 changes: 4 additions & 10 deletions src/test/ui/generic-associated-types/projection-bound-cycle.stderr
@@ -1,14 +1,8 @@
error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
--> $DIR/projection-bound-cycle.rs:45:18
error[E0275]: overflow evaluating the requirement `<Number as Foo>::Item == _`
--> $DIR/projection-bound-cycle.rs:26:5
|
LL | type Assoc = OnlySized<<T as Foo>::Item>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `OnlySized`
--> $DIR/projection-bound-cycle.rs:29:18
|
LL | struct OnlySized<T> where T: Sized { f: T }
| ^ required by this bound in `OnlySized`
LL | type Item = str where str: Sized;
| ^^^^^^^^^

error: aborting due to previous error

Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/sized/coinductive-1-gat.rs
@@ -0,0 +1,14 @@
// check-pass
struct Node<C: Trait>(C::Assoc::<Self>);

trait Trait {
type Assoc<T>;
}

impl Trait for Vec<()> {
type Assoc<T> = Vec<T>;
}

fn main() {
let _ = Node::<Vec<()>>(Vec::new());
}
14 changes: 14 additions & 0 deletions src/test/ui/sized/coinductive-1.rs
@@ -0,0 +1,14 @@
// check-pass
struct Node<C: Trait<Self>>(C::Assoc);

trait Trait<T> {
type Assoc;
}

impl<T> Trait<T> for Vec<()> {
type Assoc = Vec<T>;
}

fn main() {
let _ = Node::<Vec<()>>(Vec::new());
}
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
28 changes: 28 additions & 0 deletions src/test/ui/sized/coinductive-2.rs
@@ -0,0 +1,28 @@
// run-pass
struct Node<C: CollectionFactory<Self>> {
_children: C::Collection,
}

trait CollectionFactory<T> {
type Collection;
}

impl<T> CollectionFactory<T> for Vec<()> {
type Collection = Vec<T>;
}

trait Collection<T>: Sized {
fn push(&mut self, v: T);
}

impl<T> Collection<T> for Vec<T> {
fn push(&mut self, v: T) {
self.push(v)
}
}

fn main() {
let _ = Node::<Vec<()>> {
_children: Vec::new(),
};
}
10 changes: 10 additions & 0 deletions src/test/ui/sized/recursive-type-1.rs
@@ -0,0 +1,10 @@
// check-pass
trait A { type Assoc; }

impl A for () {
// FIXME: it would be nice for this to at least cause a warning.
type Assoc = Foo<()>;
}
struct Foo<T: A>(T::Assoc);

fn main() {}
13 changes: 13 additions & 0 deletions src/test/ui/sized/recursive-type-2.rs
@@ -0,0 +1,13 @@
// build-fail
//~^ ERROR cycle detected when computing layout of `Foo<()>`

trait A { type Assoc: ?Sized; }

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

fn main() {
let x: Foo<()>;
}
13 changes: 13 additions & 0 deletions src/test/ui/sized/recursive-type-2.stderr
@@ -0,0 +1,13 @@
error[E0391]: cycle detected when computing layout of `Foo<()>`
|
= note: ...which requires computing layout of `<() as A>::Assoc`...
= note: ...which again requires computing layout of `Foo<()>`, completing the cycle
note: cycle used when elaborating drops for `main`
--> $DIR/recursive-type-2.rs:11:1
|
LL | fn main() {
| ^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
4 changes: 3 additions & 1 deletion src/test/ui/traits/issue-82830.rs
@@ -1,10 +1,12 @@
// check-pass

trait A<Y, N> {
type B;
}

type MaybeBox<T> = <T as A<T, Box<T>>>::B;
struct P {
t: MaybeBox<P>, //~ ERROR: overflow evaluating the requirement `P: Sized`
t: MaybeBox<P>,
}

impl<Y, N> A<Y, N> for P {
Expand Down
15 changes: 0 additions & 15 deletions src/test/ui/traits/issue-82830.stderr

This file was deleted.