mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
ty::Alias(ty::Opaque, _) => {
|
||||
ty::Alias(ty::Opaque, alias) => {
|
||||
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
|
||||
// We do not generate an auto impl candidate for `impl Trait`s which already
|
||||
// reference our auto trait.
|
||||
@ -787,6 +787,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// We do not emit auto trait candidates for opaque types in coherence.
|
||||
// Doing so can result in weird dependency cycles.
|
||||
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 {
|
||||
candidates.vec.push(AutoImplCandidate)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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() }
|
||||
| ^^^^^^^^ ----- 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: 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 {
|
||||
| ^^^^^^^^ 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
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[old]check-pass
|
||||
|
||||
#![feature(freeze)]
|
||||
|
||||
@ -18,7 +17,7 @@ impl<T: Freeze> Trait<u32> for T {}
|
||||
impl<T> Trait<i32> for T {}
|
||||
fn foo() -> impl Sized {
|
||||
if false { is_trait(foo()) } else { Default::default() }
|
||||
//[next]~^ ERROR: type annotations needed
|
||||
//~^ ERROR: type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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() }
|
||||
| ^^^^^^^^ ----- 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: 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 {
|
||||
| ^^^^^^^^ 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
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[old]check-pass
|
||||
|
||||
fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
|
||||
Default::default()
|
||||
@ -14,7 +13,7 @@ impl<T: Send> Trait<u32> for T {}
|
||||
impl<T> Trait<i32> for T {}
|
||||
fn foo() -> impl Sized {
|
||||
if false { is_trait(foo()) } else { Default::default() }
|
||||
//[next]~^ ERROR: type annotations needed
|
||||
//~^ ERROR: type annotations needed
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -5,7 +5,7 @@ LL | let x = hello();
|
||||
| ^^^^^^^ types differ
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsized_coercion3.rs:19:14
|
||||
--> $DIR/unsized_coercion3.rs:18:14
|
||||
|
|
||||
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
||||
| ------------------- the expected opaque type
|
||||
@ -21,7 +21,7 @@ note: associated function defined here
|
||||
--> $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
|
||||
--> $DIR/unsized_coercion3.rs:19:14
|
||||
--> $DIR/unsized_coercion3.rs:18:14
|
||||
|
|
||||
LL | Box::new(1u32)
|
||||
| -------- ^^^^ 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
|
||||
--> $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`
|
||||
= 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`.
|
||||
|
@ -14,7 +14,6 @@ fn hello() -> Box<impl Trait + ?Sized> {
|
||||
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
|
||||
let y: Box<dyn Send> = x;
|
||||
//[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)
|
||||
//[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>`
|
||||
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
|
||||
--> $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`
|
||||
= 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.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -15,8 +15,7 @@ fn hello() -> Box<impl Trait + ?Sized> {
|
||||
let x = hello();
|
||||
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: cannot check whether the hidden type of opaque type satisfies auto traits
|
||||
//~^^^ ERROR: mismatched types
|
||||
//~^^ ERROR: mismatched types
|
||||
}
|
||||
Box::new(1u32)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ where
|
||||
Bar: Send,
|
||||
{
|
||||
[0; 1 + 2]
|
||||
//~^ ERROR: type annotations needed: cannot satisfy `Bar: Send`
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
// need extra roundabout logic to support it.
|
||||
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
|
||||
}
|
||||
|
@ -16,18 +16,13 @@ note: required by a bound in `is_send`
|
||||
LL | fn is_send<T: 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
|
||||
|
|
||||
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: opaque type is declared here
|
||||
--> $DIR/reveal_local.rs:5:12
|
||||
|
|
||||
LL | type Foo = impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
= note: cannot satisfy `Foo: Send`
|
||||
note: required by a bound in `is_send`
|
||||
--> $DIR/reveal_local.rs:7:15
|
||||
|
|
||||
@ -36,3 +31,4 @@ LL | fn is_send<T: Send>() {}
|
||||
|
||||
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