Skip to content

Commit 76ce198

Browse files
authored
Rollup merge of #100386 - compiler-errors:sized-coinductive-redux, r=lcnr
Make `Sized` coinductive, again A revival of #83647 --- What exactly makes co-induction sound? Better question: are there any unsoundness risks from this? `Sized` can't be implemented by custom `impl` blocks, nor can it be conditionally implemented based on anything other than child fields being `Sized`, right? r? `@nikomatsakis` for whenever he gets back from vacation
2 parents cd30ccf + fea8d0e commit 76ce198

18 files changed

+118
-70
lines changed

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,6 +2506,10 @@ impl<'tcx> TyCtxt<'tcx> {
25062506
self.trait_def(trait_def_id).has_auto_impl
25072507
}
25082508

2509+
pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
2510+
self.trait_is_auto(trait_def_id) || self.lang_items().sized_trait() == Some(trait_def_id)
2511+
}
2512+
25092513
/// Returns layout of a generator. Layout might be unavailable if the
25102514
/// generator is tainted by errors.
25112515
pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
959959

960960
fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
961961
let result = match predicate.kind().skip_binder() {
962-
ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()),
962+
ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_coinductive(data.def_id()),
963963
ty::PredicateKind::WellFormed(_) => true,
964964
_ => false,
965965
};
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
// check-fail
2-
// known-bug: #80626
3-
4-
// This should pass, but it requires `Sized` to be coinductive.
1+
// check-pass
52

63
trait Allocator {
74
type Allocated<T>;
85
}
96

107
enum LinkedList<A: Allocator> {
118
Head,
12-
Next(A::Allocated<Self>)
9+
Next(A::Allocated<Self>),
1310
}
1411

1512
fn main() {}

src/test/ui/generic-associated-types/bugs/issue-80626.stderr

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/test/ui/generic-associated-types/issue-87750.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
trait PointerFamily {
24
type Pointer<T>;
35
}
@@ -10,11 +12,13 @@ impl PointerFamily for RcFamily {
1012
}
1113

1214
#[allow(dead_code)]
13-
enum Node<T, P: PointerFamily> where P::Pointer<Node<T, P>>: Sized {
15+
enum Node<T, P: PointerFamily>
16+
where
17+
P::Pointer<Node<T, P>>: Sized,
18+
{
1419
Cons(P::Pointer<Node<T, P>>),
1520
}
1621

1722
fn main() {
1823
let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
19-
//~^ ERROR overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
2024
}

src/test/ui/generic-associated-types/issue-87750.stderr

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ impl<T> Foo for Number<T> {
2121
// ```
2222
// which it is :)
2323
type Item = [T] where [T]: Sized;
24+
//~^ ERROR overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
2425
}
2526

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

4646
fn foo<T: Print>() {

src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
2-
--> $DIR/projection-bound-cycle-generic.rs:42:18
1+
error[E0275]: overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
2+
--> $DIR/projection-bound-cycle-generic.rs:23:5
33
|
4-
LL | type Assoc = OnlySized<<T as Foo>::Item>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
note: required by a bound in `OnlySized`
8-
--> $DIR/projection-bound-cycle-generic.rs:26:18
9-
|
10-
LL | struct OnlySized<T> where T: Sized { f: T }
11-
| ^ required by this bound in `OnlySized`
4+
LL | type Item = [T] where [T]: Sized;
5+
| ^^^^^^^^^
126

137
error: aborting due to previous error
148

src/test/ui/generic-associated-types/projection-bound-cycle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl Foo for Number {
2424
// ```
2525
// which it is :)
2626
type Item = str where str: Sized;
27+
//~^ ERROR overflow evaluating the requirement `<Number as Foo>::Item == _`
2728
}
2829

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

4949
fn foo<T: Print>() {

src/test/ui/generic-associated-types/projection-bound-cycle.stderr

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
2-
--> $DIR/projection-bound-cycle.rs:45:18
1+
error[E0275]: overflow evaluating the requirement `<Number as Foo>::Item == _`
2+
--> $DIR/projection-bound-cycle.rs:26:5
33
|
4-
LL | type Assoc = OnlySized<<T as Foo>::Item>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
note: required by a bound in `OnlySized`
8-
--> $DIR/projection-bound-cycle.rs:29:18
9-
|
10-
LL | struct OnlySized<T> where T: Sized { f: T }
11-
| ^ required by this bound in `OnlySized`
4+
LL | type Item = str where str: Sized;
5+
| ^^^^^^^^^
126

137
error: aborting due to previous error
148

0 commit comments

Comments
 (0)