Skip to content
/ rust Public
forked from rust-lang/rust

Commit b5b3f33

Browse files
lcnrDdystopia
authored andcommitted
deal with opaque types without cycling
1 parent 3adedc9 commit b5b3f33

7 files changed

+95
-230
lines changed

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

+24-10
Original file line numberDiff line numberDiff line change
@@ -532,22 +532,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
532532
}
533533
}
534534

535-
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
535+
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
536536
bug!(
537537
"asked to assemble auto trait candidates of unexpected type: {:?}",
538538
self_ty
539539
);
540540
}
541541

542-
// Only consider auto impls if there are no manual impls for the root of `self_ty`.
543-
//
544-
// For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
545-
// for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
546-
// for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
547-
//
548-
// Generally, we have to guarantee that for all `SimplifiedType`s the only crate
549-
// which may define impls for that type is either the crate defining the type
550-
// or the trait. This should be guaranteed by the orphan check.
542+
ty::Alias(_, _)
543+
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) =>
544+
{
545+
// We do not generate an auto impl candidate for `impl Trait`s which already
546+
// reference our auto trait.
547+
//
548+
// For example during candidate assembly for `impl Send: Send`, we don't have
549+
// to look at the constituent types for this opaque types to figure out that this
550+
// trivially holds.
551+
//
552+
// Note that this is only sound as projection candidates of opaque types
553+
// are always applicable for auto traits.
554+
}
555+
551556
ty::Bool
552557
| ty::Char
553558
| ty::Int(_)
@@ -568,6 +573,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
568573
| ty::Alias(_, _)
569574
| ty::GeneratorWitness(_)
570575
| ty::GeneratorWitnessMIR(..) => {
576+
// Only consider auto impls if there are no manual impls for the root of `self_ty`.
577+
//
578+
// For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
579+
// for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
580+
// for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
581+
//
582+
// Generally, we have to guarantee that for all `SimplifiedType`s the only crate
583+
// which may define impls for that type is either the crate defining the type
584+
// or the trait. This should be guaranteed by the orphan check.
571585
let mut has_impl = false;
572586
self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
573587
if !has_impl {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
fn is_send<T: Send>(_: T) {}
3+
fn foo() -> impl Send {
4+
if false {
5+
is_send(foo());
6+
}
7+
()
8+
}
9+
10+
fn main() {}

tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking.stderr

+20-22
Original file line numberDiff line numberDiff line change
@@ -123,32 +123,30 @@ LL | | x;
123123
LL | | }
124124
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
125125

126-
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
126+
error[E0720]: cannot resolve opaque type
127127
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
128128
|
129129
LL | fn mutual_recursion() -> impl Sync {
130-
| ^^^^^^^^^
131-
|
132-
note: ...which requires type-checking `mutual_recursion`...
133-
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
130+
| ^^^^^^^^^ recursive opaque type
131+
LL |
132+
LL | mutual_recursion_b()
133+
| -------------------- returning here with type `impl Sized`
134+
...
135+
LL | fn mutual_recursion_b() -> impl Sized {
136+
| ---------- returning this opaque type `impl Sized`
137+
138+
error[E0720]: cannot resolve opaque type
139+
--> $DIR/recursive-impl-trait-type-indirect.rs:95:28
134140
|
135141
LL | fn mutual_recursion() -> impl Sync {
136-
| ^^^^^^^^^
137-
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
138-
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
139-
note: cycle used when checking item types in top-level module
140-
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
141-
|
142-
LL | / #![feature(generators)]
143-
LL | | #![allow(unconditional_recursion)]
144-
LL | |
145-
LL | | fn option(i: i32) -> impl Sized {
146-
... |
147-
LL | |
148-
LL | | fn main() {}
149-
| |____________^
142+
| --------- returning this opaque type `impl Sync`
143+
...
144+
LL | fn mutual_recursion_b() -> impl Sized {
145+
| ^^^^^^^^^^ recursive opaque type
146+
LL |
147+
LL | mutual_recursion()
148+
| ------------------ returning here with type `impl Sync`
150149

151-
error: aborting due to 13 previous errors
150+
error: aborting due to 14 previous errors
152151

153-
Some errors have detailed explanations: E0391, E0720.
154-
For more information about an error, try `rustc --explain E0391`.
152+
For more information about this error, try `rustc --explain E0720`.

tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking_mir.stderr

+20-22
Original file line numberDiff line numberDiff line change
@@ -118,32 +118,30 @@ LL | fn generator_hold() -> impl Sized {
118118
LL | let x = generator_hold();
119119
| - generator captures itself here
120120

121-
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
121+
error[E0720]: cannot resolve opaque type
122122
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
123123
|
124124
LL | fn mutual_recursion() -> impl Sync {
125-
| ^^^^^^^^^
126-
|
127-
note: ...which requires type-checking `mutual_recursion`...
128-
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
125+
| ^^^^^^^^^ recursive opaque type
126+
LL |
127+
LL | mutual_recursion_b()
128+
| -------------------- returning here with type `impl Sized`
129+
...
130+
LL | fn mutual_recursion_b() -> impl Sized {
131+
| ---------- returning this opaque type `impl Sized`
132+
133+
error[E0720]: cannot resolve opaque type
134+
--> $DIR/recursive-impl-trait-type-indirect.rs:95:28
129135
|
130136
LL | fn mutual_recursion() -> impl Sync {
131-
| ^^^^^^^^^
132-
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
133-
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
134-
note: cycle used when checking item types in top-level module
135-
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
136-
|
137-
LL | / #![feature(generators)]
138-
LL | | #![allow(unconditional_recursion)]
139-
LL | |
140-
LL | | fn option(i: i32) -> impl Sized {
141-
... |
142-
LL | |
143-
LL | | fn main() {}
144-
| |____________^
137+
| --------- returning this opaque type `impl Sync`
138+
...
139+
LL | fn mutual_recursion_b() -> impl Sized {
140+
| ^^^^^^^^^^ recursive opaque type
141+
LL |
142+
LL | mutual_recursion()
143+
| ------------------ returning here with type `impl Sync`
145144

146-
error: aborting due to 13 previous errors
145+
error: aborting due to 14 previous errors
147146

148-
Some errors have detailed explanations: E0391, E0720.
149-
For more information about an error, try `rustc --explain E0391`.
147+
For more information about this error, try `rustc --explain E0720`.

tests/ui/impl-trait/recursive-impl-trait-type-indirect.no_drop_tracking.stderr

+20-22
Original file line numberDiff line numberDiff line change
@@ -123,32 +123,30 @@ LL | | x;
123123
LL | | }
124124
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
125125

126-
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
126+
error[E0720]: cannot resolve opaque type
127127
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
128128
|
129129
LL | fn mutual_recursion() -> impl Sync {
130-
| ^^^^^^^^^
131-
|
132-
note: ...which requires type-checking `mutual_recursion`...
133-
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
130+
| ^^^^^^^^^ recursive opaque type
131+
LL |
132+
LL | mutual_recursion_b()
133+
| -------------------- returning here with type `impl Sized`
134+
...
135+
LL | fn mutual_recursion_b() -> impl Sized {
136+
| ---------- returning this opaque type `impl Sized`
137+
138+
error[E0720]: cannot resolve opaque type
139+
--> $DIR/recursive-impl-trait-type-indirect.rs:95:28
134140
|
135141
LL | fn mutual_recursion() -> impl Sync {
136-
| ^^^^^^^^^
137-
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
138-
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
139-
note: cycle used when checking item types in top-level module
140-
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
141-
|
142-
LL | / #![feature(generators)]
143-
LL | | #![allow(unconditional_recursion)]
144-
LL | |
145-
LL | | fn option(i: i32) -> impl Sized {
146-
... |
147-
LL | |
148-
LL | | fn main() {}
149-
| |____________^
142+
| --------- returning this opaque type `impl Sync`
143+
...
144+
LL | fn mutual_recursion_b() -> impl Sized {
145+
| ^^^^^^^^^^ recursive opaque type
146+
LL |
147+
LL | mutual_recursion()
148+
| ------------------ returning here with type `impl Sync`
150149

151-
error: aborting due to 13 previous errors
150+
error: aborting due to 14 previous errors
152151

153-
Some errors have detailed explanations: E0391, E0720.
154-
For more information about an error, try `rustc --explain E0391`.
152+
For more information about this error, try `rustc --explain E0720`.

tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ fn mutual_recursion() -> impl Sync {
9393
}
9494

9595
fn mutual_recursion_b() -> impl Sized {
96+
//~^ ERROR
9697
mutual_recursion()
9798
}
9899

tests/ui/impl-traitrecursive-impl-trait-type-indirect.no_drop_tracking.stderr

-154
This file was deleted.

0 commit comments

Comments
 (0)