deal with opaque types without cycling
This commit is contained in:
parent
3adedc93a9
commit
b5b3f33940
@ -532,22 +532,27 @@ fn assemble_candidates_from_auto_impls(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||||
bug!(
|
bug!(
|
||||||
"asked to assemble auto trait candidates of unexpected type: {:?}",
|
"asked to assemble auto trait candidates of unexpected type: {:?}",
|
||||||
self_ty
|
self_ty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only consider auto impls if there are no manual impls for the root of `self_ty`.
|
ty::Alias(_, _)
|
||||||
//
|
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) =>
|
||||||
// For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
|
{
|
||||||
// for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
|
// We do not generate an auto impl candidate for `impl Trait`s which already
|
||||||
// for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
|
// reference our auto trait.
|
||||||
//
|
//
|
||||||
// Generally, we have to guarantee that for all `SimplifiedType`s the only crate
|
// For example during candidate assembly for `impl Send: Send`, we don't have
|
||||||
// which may define impls for that type is either the crate defining the type
|
// to look at the constituent types for this opaque types to figure out that this
|
||||||
// or the trait. This should be guaranteed by the orphan check.
|
// trivially holds.
|
||||||
|
//
|
||||||
|
// Note that this is only sound as projection candidates of opaque types
|
||||||
|
// are always applicable for auto traits.
|
||||||
|
}
|
||||||
|
|
||||||
ty::Bool
|
ty::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
@ -568,6 +573,15 @@ fn assemble_candidates_from_auto_impls(
|
|||||||
| ty::Alias(_, _)
|
| ty::Alias(_, _)
|
||||||
| ty::GeneratorWitness(_)
|
| ty::GeneratorWitness(_)
|
||||||
| ty::GeneratorWitnessMIR(..) => {
|
| ty::GeneratorWitnessMIR(..) => {
|
||||||
|
// Only consider auto impls if there are no manual impls for the root of `self_ty`.
|
||||||
|
//
|
||||||
|
// For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
|
||||||
|
// for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
|
||||||
|
// for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
|
||||||
|
//
|
||||||
|
// Generally, we have to guarantee that for all `SimplifiedType`s the only crate
|
||||||
|
// which may define impls for that type is either the crate defining the type
|
||||||
|
// or the trait. This should be guaranteed by the orphan check.
|
||||||
let mut has_impl = false;
|
let mut has_impl = false;
|
||||||
self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
|
self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
|
||||||
if !has_impl {
|
if !has_impl {
|
||||||
|
10
tests/ui/impl-trait/recursive-auto-trait.rs
Normal file
10
tests/ui/impl-trait/recursive-auto-trait.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// check-pass
|
||||||
|
fn is_send<T: Send>(_: T) {}
|
||||||
|
fn foo() -> impl Send {
|
||||||
|
if false {
|
||||||
|
is_send(foo());
|
||||||
|
}
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -123,32 +123,30 @@ LL | | x;
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
|
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
error[E0720]: cannot resolve opaque type
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
||||||
|
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
LL | fn mutual_recursion() -> impl Sync {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ recursive opaque type
|
||||||
|
|
LL |
|
||||||
note: ...which requires type-checking `mutual_recursion`...
|
LL | mutual_recursion_b()
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
| -------------------- returning here with type `impl Sized`
|
||||||
|
...
|
||||||
|
LL | fn mutual_recursion_b() -> impl Sized {
|
||||||
|
| ---------- returning this opaque type `impl Sized`
|
||||||
|
|
||||||
|
error[E0720]: cannot resolve opaque type
|
||||||
|
--> $DIR/recursive-impl-trait-type-indirect.rs:95:28
|
||||||
|
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
LL | fn mutual_recursion() -> impl Sync {
|
||||||
| ^^^^^^^^^
|
| --------- returning this opaque type `impl Sync`
|
||||||
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
|
...
|
||||||
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
LL | fn mutual_recursion_b() -> impl Sized {
|
||||||
note: cycle used when checking item types in top-level module
|
| ^^^^^^^^^^ recursive opaque type
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
LL |
|
||||||
|
|
LL | mutual_recursion()
|
||||||
LL | / #![feature(generators)]
|
| ------------------ returning here with type `impl Sync`
|
||||||
LL | | #![allow(unconditional_recursion)]
|
|
||||||
LL | |
|
|
||||||
LL | | fn option(i: i32) -> impl Sized {
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error: aborting due to 14 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0391, E0720.
|
For more information about this error, try `rustc --explain E0720`.
|
||||||
For more information about an error, try `rustc --explain E0391`.
|
|
||||||
|
@ -118,32 +118,30 @@ LL | fn generator_hold() -> impl Sized {
|
|||||||
LL | let x = generator_hold();
|
LL | let x = generator_hold();
|
||||||
| - generator captures itself here
|
| - generator captures itself here
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
error[E0720]: cannot resolve opaque type
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
||||||
|
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
LL | fn mutual_recursion() -> impl Sync {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ recursive opaque type
|
||||||
|
|
LL |
|
||||||
note: ...which requires type-checking `mutual_recursion`...
|
LL | mutual_recursion_b()
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
| -------------------- returning here with type `impl Sized`
|
||||||
|
...
|
||||||
|
LL | fn mutual_recursion_b() -> impl Sized {
|
||||||
|
| ---------- returning this opaque type `impl Sized`
|
||||||
|
|
||||||
|
error[E0720]: cannot resolve opaque type
|
||||||
|
--> $DIR/recursive-impl-trait-type-indirect.rs:95:28
|
||||||
|
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
LL | fn mutual_recursion() -> impl Sync {
|
||||||
| ^^^^^^^^^
|
| --------- returning this opaque type `impl Sync`
|
||||||
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
|
...
|
||||||
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
LL | fn mutual_recursion_b() -> impl Sized {
|
||||||
note: cycle used when checking item types in top-level module
|
| ^^^^^^^^^^ recursive opaque type
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
LL |
|
||||||
|
|
LL | mutual_recursion()
|
||||||
LL | / #![feature(generators)]
|
| ------------------ returning here with type `impl Sync`
|
||||||
LL | | #![allow(unconditional_recursion)]
|
|
||||||
LL | |
|
|
||||||
LL | | fn option(i: i32) -> impl Sized {
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error: aborting due to 14 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0391, E0720.
|
For more information about this error, try `rustc --explain E0720`.
|
||||||
For more information about an error, try `rustc --explain E0391`.
|
|
||||||
|
@ -123,32 +123,30 @@ LL | | x;
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
|
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
error[E0720]: cannot resolve opaque type
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
||||||
|
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
LL | fn mutual_recursion() -> impl Sync {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ recursive opaque type
|
||||||
|
|
LL |
|
||||||
note: ...which requires type-checking `mutual_recursion`...
|
LL | mutual_recursion_b()
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
| -------------------- returning here with type `impl Sized`
|
||||||
|
...
|
||||||
|
LL | fn mutual_recursion_b() -> impl Sized {
|
||||||
|
| ---------- returning this opaque type `impl Sized`
|
||||||
|
|
||||||
|
error[E0720]: cannot resolve opaque type
|
||||||
|
--> $DIR/recursive-impl-trait-type-indirect.rs:95:28
|
||||||
|
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
LL | fn mutual_recursion() -> impl Sync {
|
||||||
| ^^^^^^^^^
|
| --------- returning this opaque type `impl Sync`
|
||||||
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
|
...
|
||||||
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
LL | fn mutual_recursion_b() -> impl Sized {
|
||||||
note: cycle used when checking item types in top-level module
|
| ^^^^^^^^^^ recursive opaque type
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
LL |
|
||||||
|
|
LL | mutual_recursion()
|
||||||
LL | / #![feature(generators)]
|
| ------------------ returning here with type `impl Sync`
|
||||||
LL | | #![allow(unconditional_recursion)]
|
|
||||||
LL | |
|
|
||||||
LL | | fn option(i: i32) -> impl Sized {
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error: aborting due to 14 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0391, E0720.
|
For more information about this error, try `rustc --explain E0720`.
|
||||||
For more information about an error, try `rustc --explain E0391`.
|
|
||||||
|
@ -93,6 +93,7 @@ fn mutual_recursion() -> impl Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn mutual_recursion_b() -> impl Sized {
|
fn mutual_recursion_b() -> impl Sized {
|
||||||
|
//~^ ERROR
|
||||||
mutual_recursion()
|
mutual_recursion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,154 +0,0 @@
|
|||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:11:22
|
|
||||||
|
|
|
||||||
LL | fn option(i: i32) -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | if i < 0 { None } else { Some((option(i - 1), i)) }
|
|
||||||
| ---- ------------------------ returning here with type `Option<(impl Sized, i32)>`
|
|
||||||
| |
|
|
||||||
| returning here with type `Option<(impl Sized, i32)>`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:16:15
|
|
||||||
|
|
|
||||||
LL | fn tuple() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | (tuple(),)
|
|
||||||
| ---------- returning here with type `(impl Sized,)`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:21:15
|
|
||||||
|
|
|
||||||
LL | fn array() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | [array()]
|
|
||||||
| --------- returning here with type `[impl Sized; 1]`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:26:13
|
|
||||||
|
|
|
||||||
LL | fn ptr() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | &ptr() as *const _
|
|
||||||
| ------------------ returning here with type `*const impl Sized`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:31:16
|
|
||||||
|
|
|
||||||
LL | fn fn_ptr() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | fn_ptr as fn() -> _
|
|
||||||
| ------------------- returning here with type `fn() -> impl Sized`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:36:25
|
|
||||||
|
|
|
||||||
LL | fn closure_capture() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
...
|
|
||||||
LL | / move || {
|
|
||||||
LL | | x;
|
|
||||||
| | - closure captures itself here
|
|
||||||
LL | | }
|
|
||||||
| |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:39:5: 39:12]`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:44:29
|
|
||||||
|
|
|
||||||
LL | fn closure_ref_capture() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
...
|
|
||||||
LL | / move || {
|
|
||||||
LL | | &x;
|
|
||||||
| | - closure captures itself here
|
|
||||||
LL | | }
|
|
||||||
| |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:47:5: 47:12]`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:52:21
|
|
||||||
|
|
|
||||||
LL | fn closure_sig() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | || closure_sig()
|
|
||||||
| ---------------- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7]`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:57:23
|
|
||||||
|
|
|
||||||
LL | fn generator_sig() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | || generator_sig()
|
|
||||||
| ------------------ returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:59:5: 59:7]`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:62:27
|
|
||||||
|
|
|
||||||
LL | fn generator_capture() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
...
|
|
||||||
LL | / move || {
|
|
||||||
LL | | yield;
|
|
||||||
LL | | x;
|
|
||||||
| | - generator captures itself here
|
|
||||||
LL | | }
|
|
||||||
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:65:5: 65:12]`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:71:35
|
|
||||||
|
|
|
||||||
LL | fn substs_change<T: 'static>() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | (substs_change::<&T>(),)
|
|
||||||
| ------------------------ returning here with type `(impl Sized,)`
|
|
||||||
|
|
||||||
error[E0720]: cannot resolve opaque type
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:76:24
|
|
||||||
|
|
|
||||||
LL | fn generator_hold() -> impl Sized {
|
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
|
||||||
LL |
|
|
||||||
LL | / move || {
|
|
||||||
LL | | let x = generator_hold();
|
|
||||||
| | - generator captures itself here
|
|
||||||
LL | | yield;
|
|
||||||
LL | | x;
|
|
||||||
LL | | }
|
|
||||||
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12]`
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
|
||||||
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: ...which requires type-checking `mutual_recursion`...
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
|
||||||
|
|
|
||||||
LL | fn mutual_recursion() -> impl Sync {
|
|
||||||
| ^^^^^^^^^
|
|
||||||
= note: ...which requires evaluating trait selection obligation `mutual_recursion_b::{opaque#0}: core::marker::Sync`...
|
|
||||||
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
|
||||||
note: cycle used when checking item types in top-level module
|
|
||||||
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
|
||||||
|
|
|
||||||
LL | / #![feature(generators)]
|
|
||||||
LL | | #![allow(unconditional_recursion)]
|
|
||||||
LL | |
|
|
||||||
LL | | fn option(i: i32) -> impl Sized {
|
|
||||||
... |
|
|
||||||
LL | |
|
|
||||||
LL | | fn main() {}
|
|
||||||
| |____________^
|
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0391, E0720.
|
|
||||||
For more information about an error, try `rustc --explain E0391`.
|
|
Loading…
Reference in New Issue
Block a user