Do not assemble candidates for auto traits of opaque types in their defining scope
This commit is contained in:
parent
548c44760f
commit
8ea461da55
@ -772,7 +772,7 @@ fn assemble_candidates_from_auto_impls(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Alias(ty::Opaque, _) => {
|
ty::Alias(ty::Opaque, alias) => {
|
||||||
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
|
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
|
||||||
// We do not generate an auto impl candidate for `impl Trait`s which already
|
// We do not generate an auto impl candidate for `impl Trait`s which already
|
||||||
// reference our auto trait.
|
// reference our auto trait.
|
||||||
@ -787,6 +787,11 @@ fn assemble_candidates_from_auto_impls(
|
|||||||
// We do not emit auto trait candidates for opaque types in coherence.
|
// We do not emit auto trait candidates for opaque types in coherence.
|
||||||
// Doing so can result in weird dependency cycles.
|
// Doing so can result in weird dependency cycles.
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
|
} else if self.infcx.can_define_opaque_ty(alias.def_id) {
|
||||||
|
// We do not emit auto trait candidates for opaque types in their defining scope, as
|
||||||
|
// we need to know the hidden type first, which we can't reliably know within the defining
|
||||||
|
// scope.
|
||||||
|
candidates.ambiguous = true;
|
||||||
} else {
|
} else {
|
||||||
candidates.vec.push(AutoImplCandidate)
|
candidates.vec.push(AutoImplCandidate)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0283]: type annotations needed
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/auto-trait-selection-freeze.rs:20:16
|
--> $DIR/auto-trait-selection-freeze.rs:19:16
|
||||||
|
|
|
|
||||||
LL | if false { is_trait(foo()) } else { Default::default() }
|
LL | if false { is_trait(foo()) } else { Default::default() }
|
||||||
| ^^^^^^^^ ----- type must be known at this point
|
| ^^^^^^^^ ----- type must be known at this point
|
||||||
@ -8,7 +8,7 @@ LL | if false { is_trait(foo()) } else { Default::default() }
|
|||||||
|
|
|
|
||||||
= note: cannot satisfy `_: Trait<_>`
|
= note: cannot satisfy `_: Trait<_>`
|
||||||
note: required by a bound in `is_trait`
|
note: required by a bound in `is_trait`
|
||||||
--> $DIR/auto-trait-selection-freeze.rs:12:16
|
--> $DIR/auto-trait-selection-freeze.rs:11:16
|
||||||
|
|
|
|
||||||
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
| ^^^^^^^^ required by this bound in `is_trait`
|
| ^^^^^^^^ required by this bound in `is_trait`
|
||||||
|
26
tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr
Normal file
26
tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
error[E0283]: type annotations needed
|
||||||
|
--> $DIR/auto-trait-selection-freeze.rs:19:16
|
||||||
|
|
|
||||||
|
LL | if false { is_trait(foo()) } else { Default::default() }
|
||||||
|
| ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
|
||||||
|
|
|
||||||
|
note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
|
||||||
|
--> $DIR/auto-trait-selection-freeze.rs:16:1
|
||||||
|
|
|
||||||
|
LL | impl<T: Freeze> Trait<u32> for T {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | impl<T> Trait<i32> for T {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: required by a bound in `is_trait`
|
||||||
|
--> $DIR/auto-trait-selection-freeze.rs:11:16
|
||||||
|
|
|
||||||
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
|
| ^^^^^^^^ required by this bound in `is_trait`
|
||||||
|
help: consider specifying the generic arguments
|
||||||
|
|
|
||||||
|
LL | if false { is_trait::<_, U>(foo()) } else { Default::default() }
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
//@ revisions: next old
|
//@ revisions: next old
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[old]check-pass
|
|
||||||
|
|
||||||
#![feature(freeze)]
|
#![feature(freeze)]
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ impl<T: Freeze> Trait<u32> for T {}
|
|||||||
impl<T> Trait<i32> for T {}
|
impl<T> Trait<i32> for T {}
|
||||||
fn foo() -> impl Sized {
|
fn foo() -> impl Sized {
|
||||||
if false { is_trait(foo()) } else { Default::default() }
|
if false { is_trait(foo()) } else { Default::default() }
|
||||||
//[next]~^ ERROR: type annotations needed
|
//~^ ERROR: type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0283]: type annotations needed
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/auto-trait-selection.rs:16:16
|
--> $DIR/auto-trait-selection.rs:15:16
|
||||||
|
|
|
|
||||||
LL | if false { is_trait(foo()) } else { Default::default() }
|
LL | if false { is_trait(foo()) } else { Default::default() }
|
||||||
| ^^^^^^^^ ----- type must be known at this point
|
| ^^^^^^^^ ----- type must be known at this point
|
||||||
@ -8,7 +8,7 @@ LL | if false { is_trait(foo()) } else { Default::default() }
|
|||||||
|
|
|
|
||||||
= note: cannot satisfy `_: Trait<_>`
|
= note: cannot satisfy `_: Trait<_>`
|
||||||
note: required by a bound in `is_trait`
|
note: required by a bound in `is_trait`
|
||||||
--> $DIR/auto-trait-selection.rs:8:16
|
--> $DIR/auto-trait-selection.rs:7:16
|
||||||
|
|
|
|
||||||
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
| ^^^^^^^^ required by this bound in `is_trait`
|
| ^^^^^^^^ required by this bound in `is_trait`
|
||||||
|
26
tests/ui/impl-trait/auto-trait-selection.old.stderr
Normal file
26
tests/ui/impl-trait/auto-trait-selection.old.stderr
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
error[E0283]: type annotations needed
|
||||||
|
--> $DIR/auto-trait-selection.rs:15:16
|
||||||
|
|
|
||||||
|
LL | if false { is_trait(foo()) } else { Default::default() }
|
||||||
|
| ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
|
||||||
|
|
|
||||||
|
note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
|
||||||
|
--> $DIR/auto-trait-selection.rs:12:1
|
||||||
|
|
|
||||||
|
LL | impl<T: Send> Trait<u32> for T {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | impl<T> Trait<i32> for T {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: required by a bound in `is_trait`
|
||||||
|
--> $DIR/auto-trait-selection.rs:7:16
|
||||||
|
|
|
||||||
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
|
| ^^^^^^^^ required by this bound in `is_trait`
|
||||||
|
help: consider specifying the generic arguments
|
||||||
|
|
|
||||||
|
LL | if false { is_trait::<_, U>(foo()) } else { Default::default() }
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
//@ revisions: next old
|
//@ revisions: next old
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[old]check-pass
|
|
||||||
|
|
||||||
fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||||
Default::default()
|
Default::default()
|
||||||
@ -14,7 +13,7 @@ impl<T: Send> Trait<u32> for T {}
|
|||||||
impl<T> Trait<i32> for T {}
|
impl<T> Trait<i32> for T {}
|
||||||
fn foo() -> impl Sized {
|
fn foo() -> impl Sized {
|
||||||
if false { is_trait(foo()) } else { Default::default() }
|
if false { is_trait(foo()) } else { Default::default() }
|
||||||
//[next]~^ ERROR: type annotations needed
|
//~^ ERROR: type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -5,7 +5,7 @@ LL | let x = hello();
|
|||||||
| ^^^^^^^ types differ
|
| ^^^^^^^ types differ
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/unsized_coercion3.rs:19:14
|
--> $DIR/unsized_coercion3.rs:18:14
|
||||||
|
|
|
|
||||||
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
||||||
| ------------------- the expected opaque type
|
| ------------------- the expected opaque type
|
||||||
@ -21,7 +21,7 @@ note: associated function defined here
|
|||||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||||
|
|
||||||
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
||||||
--> $DIR/unsized_coercion3.rs:19:14
|
--> $DIR/unsized_coercion3.rs:18:14
|
||||||
|
|
|
|
||||||
LL | Box::new(1u32)
|
LL | Box::new(1u32)
|
||||||
| -------- ^^^^ doesn't have a size known at compile-time
|
| -------- ^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -1,17 +1,3 @@
|
|||||||
error: cannot check whether the hidden type of opaque type satisfies auto traits
|
|
||||||
--> $DIR/unsized_coercion3.rs:15:32
|
|
||||||
|
|
|
||||||
LL | let y: Box<dyn Send> = x;
|
|
||||||
| ^
|
|
||||||
|
|
|
||||||
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
|
|
||||||
note: opaque type is declared here
|
|
||||||
--> $DIR/unsized_coercion3.rs:11:19
|
|
||||||
|
|
|
||||||
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
||||||
--> $DIR/unsized_coercion3.rs:15:32
|
--> $DIR/unsized_coercion3.rs:15:32
|
||||||
|
|
|
|
||||||
@ -21,6 +7,6 @@ LL | let y: Box<dyn Send> = x;
|
|||||||
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
|
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
|
||||||
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
|
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
@ -14,7 +14,6 @@ fn hello() -> Box<impl Trait + ?Sized> {
|
|||||||
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
|
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
|
||||||
let y: Box<dyn Send> = x;
|
let y: Box<dyn Send> = x;
|
||||||
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
||||||
//[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
|
|
||||||
}
|
}
|
||||||
Box::new(1u32)
|
Box::new(1u32)
|
||||||
//[next]~^ ERROR: mismatched types
|
//[next]~^ ERROR: mismatched types
|
||||||
|
@ -9,20 +9,6 @@ LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
|||||||
= note: expected struct `Box<dyn Send>`
|
= note: expected struct `Box<dyn Send>`
|
||||||
found struct `Box<dyn Trait + Send>`
|
found struct `Box<dyn Trait + Send>`
|
||||||
|
|
||||||
error: cannot check whether the hidden type of opaque type satisfies auto traits
|
|
||||||
--> $DIR/unsized_coercion5.rs:16:32
|
|
||||||
|
|
|
||||||
LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
|
||||||
| ^
|
|
||||||
|
|
|
||||||
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
|
|
||||||
note: opaque type is declared here
|
|
||||||
--> $DIR/unsized_coercion5.rs:13:19
|
|
||||||
|
|
|
||||||
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
||||||
--> $DIR/unsized_coercion5.rs:16:32
|
--> $DIR/unsized_coercion5.rs:16:32
|
||||||
|
|
|
|
||||||
@ -32,7 +18,7 @@ LL | let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
|||||||
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
|
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
|
||||||
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
|
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Trait + Send>`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0277, E0308.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
@ -15,8 +15,7 @@ fn hello() -> Box<impl Trait + ?Sized> {
|
|||||||
let x = hello();
|
let x = hello();
|
||||||
let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
let y: Box<dyn Send> = x as Box<dyn Trait + Send>;
|
||||||
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
||||||
//[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
|
//~^^ ERROR: mismatched types
|
||||||
//~^^^ ERROR: mismatched types
|
|
||||||
}
|
}
|
||||||
Box::new(1u32)
|
Box::new(1u32)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ fn foo() -> Bar
|
|||||||
Bar: Send,
|
Bar: Send,
|
||||||
{
|
{
|
||||||
[0; 1 + 2]
|
[0; 1 + 2]
|
||||||
|
//~^ ERROR: type annotations needed: cannot satisfy `Bar: Send`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -25,6 +25,23 @@ LL | type Bar = impl Sized;
|
|||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0283]: type annotations needed: cannot satisfy `Bar: Send`
|
||||||
|
--> $DIR/in-where-clause.rs:12:9
|
||||||
|
|
|
||||||
|
LL | [0; 1 + 2]
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
= note: cannot satisfy `Bar: Send`
|
||||||
|
note: required by a bound in `foo`
|
||||||
|
--> $DIR/in-where-clause.rs:10:10
|
||||||
|
|
|
||||||
|
LL | fn foo() -> Bar
|
||||||
|
| --- required by a bound in this function
|
||||||
|
LL | where
|
||||||
|
LL | Bar: Send,
|
||||||
|
| ^^^^ required by this bound in `foo`
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0391`.
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0283, E0391.
|
||||||
|
For more information about an error, try `rustc --explain E0283`.
|
||||||
|
@ -20,7 +20,7 @@ fn not_gooder() -> Foo {
|
|||||||
// while we could know this from the hidden type, it would
|
// while we could know this from the hidden type, it would
|
||||||
// need extra roundabout logic to support it.
|
// need extra roundabout logic to support it.
|
||||||
is_send::<Foo>();
|
is_send::<Foo>();
|
||||||
//~^ ERROR: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
|
//~^ ERROR: type annotations needed: cannot satisfy `Foo: Send`
|
||||||
|
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
@ -16,18 +16,13 @@ note: required by a bound in `is_send`
|
|||||||
LL | fn is_send<T: Send>() {}
|
LL | fn is_send<T: Send>() {}
|
||||||
| ^^^^ required by this bound in `is_send`
|
| ^^^^ required by this bound in `is_send`
|
||||||
|
|
||||||
error: cannot check whether the hidden type of `reveal_local[9507]::Foo::{opaque#0}` satisfies auto traits
|
error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
|
||||||
--> $DIR/reveal_local.rs:22:15
|
--> $DIR/reveal_local.rs:22:15
|
||||||
|
|
|
|
||||||
LL | is_send::<Foo>();
|
LL | is_send::<Foo>();
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: fetching the hidden types of an opaque inside of the defining scope is not supported. You can try moving the opaque type and the item that actually registers a hidden type into a new submodule
|
= note: cannot satisfy `Foo: Send`
|
||||||
note: opaque type is declared here
|
|
||||||
--> $DIR/reveal_local.rs:5:12
|
|
||||||
|
|
|
||||||
LL | type Foo = impl Debug;
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
note: required by a bound in `is_send`
|
note: required by a bound in `is_send`
|
||||||
--> $DIR/reveal_local.rs:7:15
|
--> $DIR/reveal_local.rs:7:15
|
||||||
|
|
|
|
||||||
@ -36,3 +31,4 @@ LL | fn is_send<T: Send>() {}
|
|||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0283`.
|
||||||
|
Loading…
Reference in New Issue
Block a user