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(_))) { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// 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)
} }

View File

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

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

View File

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

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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