Do not assemble candidates for auto traits of opaque types in their defining scope

This commit is contained in:
Oli Scherer 2024-06-04 16:20:01 +00:00
parent 548c44760f
commit 8ea461da55
16 changed files with 93 additions and 54 deletions

View File

@ -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)
}

View File

@ -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`

View 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`.

View File

@ -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() {}

View File

@ -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`

View 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`.

View File

@ -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() {}

View File

@ -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

View File

@ -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`.

View File

@ -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

View File

@ -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`.

View File

@ -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)
}

View File

@ -10,6 +10,7 @@ where
Bar: Send,
{
[0; 1 + 2]
//~^ ERROR: type annotations needed: cannot satisfy `Bar: Send`
}
fn main() {}

View File

@ -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`.

View File

@ -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
}

View File

@ -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`.