update auto trait handling
This commit is contained in:
parent
b112bc5529
commit
3adedc93a9
11 changed files with 339 additions and 78 deletions
|
@ -124,11 +124,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
|
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
|
||||||
self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
|
self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
|
||||||
// Auto implementations have lower priority, so we only
|
self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
|
||||||
// consider triggering a default if there is no other impl that can apply.
|
|
||||||
if candidates.vec.is_empty() {
|
|
||||||
self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
debug!("candidate list size: {}", candidates.vec.len());
|
debug!("candidate list size: {}", candidates.vec.len());
|
||||||
Ok(candidates)
|
Ok(candidates)
|
||||||
|
@ -516,7 +512,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// for an example of a test case that exercises
|
// for an example of a test case that exercises
|
||||||
// this path.
|
// this path.
|
||||||
}
|
}
|
||||||
ty::Infer(ty::TyVar(_)) => {
|
ty::Infer(ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_)) => {
|
||||||
// The auto impl might apply; we don't know.
|
// The auto impl might apply; we don't know.
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
}
|
}
|
||||||
|
@ -536,7 +532,49 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => candidates.vec.push(AutoImplCandidate),
|
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||||
|
bug!(
|
||||||
|
"asked to assemble auto trait candidates of unexpected type: {:?}",
|
||||||
|
self_ty
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
ty::Bool
|
||||||
|
| ty::Char
|
||||||
|
| ty::Int(_)
|
||||||
|
| ty::Uint(_)
|
||||||
|
| ty::Float(_)
|
||||||
|
| ty::Str
|
||||||
|
| ty::Array(_, _)
|
||||||
|
| ty::Slice(_)
|
||||||
|
| ty::Adt(..)
|
||||||
|
| ty::RawPtr(_)
|
||||||
|
| ty::Ref(..)
|
||||||
|
| ty::FnDef(..)
|
||||||
|
| ty::FnPtr(_)
|
||||||
|
| ty::Closure(_, _)
|
||||||
|
| ty::Generator(..)
|
||||||
|
| ty::Never
|
||||||
|
| ty::Tuple(_)
|
||||||
|
| ty::Alias(_, _)
|
||||||
|
| ty::GeneratorWitness(_)
|
||||||
|
| ty::GeneratorWitnessMIR(..) => {
|
||||||
|
let mut has_impl = false;
|
||||||
|
self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
|
||||||
|
if !has_impl {
|
||||||
|
candidates.vec.push(AutoImplCandidate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::Error(_) => {} // do not add an auto trait impl for `ty::Error` for now.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1814,6 +1814,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
/// candidates and prefer where-clause candidates.
|
/// candidates and prefer where-clause candidates.
|
||||||
///
|
///
|
||||||
/// See the comment for "SelectionCandidate" for more details.
|
/// See the comment for "SelectionCandidate" for more details.
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn candidate_should_be_dropped_in_favor_of(
|
fn candidate_should_be_dropped_in_favor_of(
|
||||||
&mut self,
|
&mut self,
|
||||||
victim: &EvaluatedCandidate<'tcx>,
|
victim: &EvaluatedCandidate<'tcx>,
|
||||||
|
@ -1837,13 +1838,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
// This is a fix for #53123 and prevents winnowing from accidentally extending the
|
// This is a fix for #53123 and prevents winnowing from accidentally extending the
|
||||||
// lifetime of a variable.
|
// lifetime of a variable.
|
||||||
match (&other.candidate, &victim.candidate) {
|
match (&other.candidate, &victim.candidate) {
|
||||||
(_, AutoImplCandidate) | (AutoImplCandidate, _) => {
|
|
||||||
bug!(
|
|
||||||
"default implementations shouldn't be recorded \
|
|
||||||
when there are other valid candidates"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(@jswrenn): this should probably be more sophisticated
|
// FIXME(@jswrenn): this should probably be more sophisticated
|
||||||
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No,
|
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No,
|
||||||
|
|
||||||
|
@ -1885,6 +1879,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
(
|
(
|
||||||
ParamCandidate(ref other_cand),
|
ParamCandidate(ref other_cand),
|
||||||
ImplCandidate(..)
|
ImplCandidate(..)
|
||||||
|
| AutoImplCandidate
|
||||||
| ClosureCandidate { .. }
|
| ClosureCandidate { .. }
|
||||||
| GeneratorCandidate
|
| GeneratorCandidate
|
||||||
| FutureCandidate
|
| FutureCandidate
|
||||||
|
@ -1912,6 +1907,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
ImplCandidate(_)
|
ImplCandidate(_)
|
||||||
|
| AutoImplCandidate
|
||||||
| ClosureCandidate { .. }
|
| ClosureCandidate { .. }
|
||||||
| GeneratorCandidate
|
| GeneratorCandidate
|
||||||
| FutureCandidate
|
| FutureCandidate
|
||||||
|
@ -1945,6 +1941,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
(
|
(
|
||||||
ObjectCandidate(_) | ProjectionCandidate(..),
|
ObjectCandidate(_) | ProjectionCandidate(..),
|
||||||
ImplCandidate(..)
|
ImplCandidate(..)
|
||||||
|
| AutoImplCandidate
|
||||||
| ClosureCandidate { .. }
|
| ClosureCandidate { .. }
|
||||||
| GeneratorCandidate
|
| GeneratorCandidate
|
||||||
| FutureCandidate
|
| FutureCandidate
|
||||||
|
@ -1958,6 +1955,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
|
|
||||||
(
|
(
|
||||||
ImplCandidate(..)
|
ImplCandidate(..)
|
||||||
|
| AutoImplCandidate
|
||||||
| ClosureCandidate { .. }
|
| ClosureCandidate { .. }
|
||||||
| GeneratorCandidate
|
| GeneratorCandidate
|
||||||
| FutureCandidate
|
| FutureCandidate
|
||||||
|
@ -2048,6 +2046,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(AutoImplCandidate, ImplCandidate(_)) | (ImplCandidate(_), AutoImplCandidate) => {
|
||||||
|
DropVictim::No
|
||||||
|
}
|
||||||
|
|
||||||
|
(AutoImplCandidate, _) | (_, AutoImplCandidate) => {
|
||||||
|
bug!(
|
||||||
|
"default implementations shouldn't be recorded \
|
||||||
|
when there are other global candidates: {:?} {:?}",
|
||||||
|
other,
|
||||||
|
victim
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Everything else is ambiguous
|
// Everything else is ambiguous
|
||||||
(
|
(
|
||||||
ImplCandidate(_)
|
ImplCandidate(_)
|
||||||
|
|
31
tests/ui/auto-traits/issue-83857-ub.rs
Normal file
31
tests/ui/auto-traits/issue-83857-ub.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#![allow(suspicious_auto_trait_impls)]
|
||||||
|
|
||||||
|
struct Always<T, U>(T, U);
|
||||||
|
unsafe impl<T, U> Send for Always<T, U> {}
|
||||||
|
struct Foo<T, U>(Always<T, U>);
|
||||||
|
|
||||||
|
trait False {}
|
||||||
|
unsafe impl<U: False> Send for Foo<u32, U> {}
|
||||||
|
|
||||||
|
trait WithAssoc {
|
||||||
|
type Output;
|
||||||
|
}
|
||||||
|
impl<T: Send> WithAssoc for T {
|
||||||
|
type Output = Self;
|
||||||
|
}
|
||||||
|
impl WithAssoc for Foo<u32, ()> {
|
||||||
|
type Output = Box<i32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
|
||||||
|
//~^ ERROR `Foo<T, U>` cannot be sent between threads safely
|
||||||
|
f(foo(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
generic(Foo(Always(0, ())), |b| *b);
|
||||||
|
}
|
22
tests/ui/auto-traits/issue-83857-ub.stderr
Normal file
22
tests/ui/auto-traits/issue-83857-ub.stderr
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
||||||
|
--> $DIR/issue-83857-ub.rs:20:38
|
||||||
|
|
|
||||||
|
LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo<T, U>` cannot be sent between threads safely
|
||||||
|
|
|
||||||
|
= help: the trait `Send` is not implemented for `Foo<T, U>`
|
||||||
|
note: required for `Foo<T, U>` to implement `WithAssoc`
|
||||||
|
--> $DIR/issue-83857-ub.rs:13:15
|
||||||
|
|
|
||||||
|
LL | impl<T: Send> WithAssoc for T {
|
||||||
|
| ---- ^^^^^^^^^ ^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) where Foo<T, U>: Send {
|
||||||
|
| +++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -26,7 +26,7 @@ fn assert_foo<T: Foo>(f: T) {}
|
||||||
fn main() {
|
fn main() {
|
||||||
// Make sure 'static is erased for generator interiors so we can't match it in trait selection
|
// Make sure 'static is erased for generator interiors so we can't match it in trait selection
|
||||||
let x: &'static _ = &OnlyFooIfStaticRef(No);
|
let x: &'static _ = &OnlyFooIfStaticRef(No);
|
||||||
let gen = || {
|
let gen = move || {
|
||||||
let x = x;
|
let x = x;
|
||||||
yield;
|
yield;
|
||||||
assert_foo(x);
|
assert_foo(x);
|
||||||
|
@ -36,7 +36,7 @@ fn main() {
|
||||||
|
|
||||||
// Allow impls which matches any lifetime
|
// Allow impls which matches any lifetime
|
||||||
let x = &OnlyFooIfRef(No);
|
let x = &OnlyFooIfRef(No);
|
||||||
let gen = || {
|
let gen = move || {
|
||||||
let x = x;
|
let x = x;
|
||||||
yield;
|
yield;
|
||||||
assert_foo(x);
|
assert_foo(x);
|
||||||
|
@ -44,7 +44,7 @@ fn main() {
|
||||||
assert_foo(gen); // ok
|
assert_foo(gen); // ok
|
||||||
|
|
||||||
// Disallow impls which relates lifetimes in the generator interior
|
// Disallow impls which relates lifetimes in the generator interior
|
||||||
let gen = || {
|
let gen = move || {
|
||||||
let a = A(&mut true, &mut true, No);
|
let a = A(&mut true, &mut true, No);
|
||||||
//~^ temporary value dropped while borrowed
|
//~^ temporary value dropped while borrowed
|
||||||
//~| temporary value dropped while borrowed
|
//~| temporary value dropped while borrowed
|
||||||
|
|
0
tests/ui/impl-trait/auto-trait-leak
Normal file
0
tests/ui/impl-trait/auto-trait-leak
Normal file
|
@ -123,30 +123,32 @@ 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[E0720]: cannot resolve opaque type
|
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
||||||
--> $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 |
|
|
|
||||||
LL | mutual_recursion_b()
|
note: ...which requires type-checking `mutual_recursion`...
|
||||||
| -------------------- returning here with type `impl Sized`
|
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
||||||
...
|
|
||||||
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`...
|
||||||
LL | fn mutual_recursion_b() -> impl Sized {
|
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
note: cycle used when checking item types in top-level module
|
||||||
LL |
|
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
||||||
LL | mutual_recursion()
|
|
|
||||||
| ------------------ returning here with type `impl Sync`
|
LL | / #![feature(generators)]
|
||||||
|
LL | | #![allow(unconditional_recursion)]
|
||||||
|
LL | |
|
||||||
|
LL | | fn option(i: i32) -> impl Sized {
|
||||||
|
... |
|
||||||
|
LL | |
|
||||||
|
LL | | fn main() {}
|
||||||
|
| |____________^
|
||||||
|
|
||||||
error: aborting due to 14 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0720`.
|
Some errors have detailed explanations: E0391, E0720.
|
||||||
|
For more information about an error, try `rustc --explain E0391`.
|
||||||
|
|
|
@ -118,30 +118,32 @@ 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[E0720]: cannot resolve opaque type
|
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
||||||
--> $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 |
|
|
|
||||||
LL | mutual_recursion_b()
|
note: ...which requires type-checking `mutual_recursion`...
|
||||||
| -------------------- returning here with type `impl Sized`
|
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
||||||
...
|
|
||||||
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`...
|
||||||
LL | fn mutual_recursion_b() -> impl Sized {
|
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
note: cycle used when checking item types in top-level module
|
||||||
LL |
|
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
||||||
LL | mutual_recursion()
|
|
|
||||||
| ------------------ returning here with type `impl Sync`
|
LL | / #![feature(generators)]
|
||||||
|
LL | | #![allow(unconditional_recursion)]
|
||||||
|
LL | |
|
||||||
|
LL | | fn option(i: i32) -> impl Sized {
|
||||||
|
... |
|
||||||
|
LL | |
|
||||||
|
LL | | fn main() {}
|
||||||
|
| |____________^
|
||||||
|
|
||||||
error: aborting due to 14 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0720`.
|
Some errors have detailed explanations: E0391, E0720.
|
||||||
|
For more information about an error, try `rustc --explain E0391`.
|
||||||
|
|
|
@ -123,30 +123,32 @@ 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[E0720]: cannot resolve opaque type
|
error[E0391]: cycle detected when computing type of `mutual_recursion::{opaque#0}`
|
||||||
--> $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 |
|
|
|
||||||
LL | mutual_recursion_b()
|
note: ...which requires type-checking `mutual_recursion`...
|
||||||
| -------------------- returning here with type `impl Sized`
|
--> $DIR/recursive-impl-trait-type-indirect.rs:90:26
|
||||||
...
|
|
||||||
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`...
|
||||||
LL | fn mutual_recursion_b() -> impl Sized {
|
= note: ...which again requires computing type of `mutual_recursion::{opaque#0}`, completing the cycle
|
||||||
| ^^^^^^^^^^ recursive opaque type
|
note: cycle used when checking item types in top-level module
|
||||||
LL |
|
--> $DIR/recursive-impl-trait-type-indirect.rs:8:1
|
||||||
LL | mutual_recursion()
|
|
|
||||||
| ------------------ returning here with type `impl Sync`
|
LL | / #![feature(generators)]
|
||||||
|
LL | | #![allow(unconditional_recursion)]
|
||||||
|
LL | |
|
||||||
|
LL | | fn option(i: i32) -> impl Sized {
|
||||||
|
... |
|
||||||
|
LL | |
|
||||||
|
LL | | fn main() {}
|
||||||
|
| |____________^
|
||||||
|
|
||||||
error: aborting due to 14 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0720`.
|
Some errors have detailed explanations: E0391, E0720.
|
||||||
|
For more information about an error, try `rustc --explain E0391`.
|
||||||
|
|
|
@ -93,7 +93,6 @@ fn mutual_recursion() -> impl Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mutual_recursion_b() -> impl Sized {
|
fn mutual_recursion_b() -> impl Sized {
|
||||||
//~^ ERROR
|
|
||||||
mutual_recursion()
|
mutual_recursion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
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…
Add table
Add a link
Reference in a new issue