Skip to content

Commit 232d370

Browse files
committed
Do not assemble candidates for auto traits of opaque types in their defining scope
1 parent 763d2ab commit 232d370

16 files changed

+93
-54
lines changed

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
772772
);
773773
}
774774

775-
ty::Alias(ty::Opaque, _) => {
775+
ty::Alias(ty::Opaque, alias) => {
776776
if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
777777
// We do not generate an auto impl candidate for `impl Trait`s which already
778778
// reference our auto trait.
@@ -787,6 +787,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
787787
// We do not emit auto trait candidates for opaque types in coherence.
788788
// Doing so can result in weird dependency cycles.
789789
candidates.ambiguous = true;
790+
} else if self.infcx.can_define_opaque_ty(alias.def_id) {
791+
// We do not emit auto trait candidates for opaque types in their defining scope, as
792+
// we need to know the hidden type first, which we can't reliably know within the defining
793+
// scope.
794+
candidates.ambiguous = true;
790795
} else {
791796
candidates.vec.push(AutoImplCandidate)
792797
}

tests/ui/impl-trait/auto-trait-selection-freeze.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0283]: type annotations needed
2-
--> $DIR/auto-trait-selection-freeze.rs:20:16
2+
--> $DIR/auto-trait-selection-freeze.rs:19:16
33
|
44
LL | if false { is_trait(foo()) } else { Default::default() }
55
| ^^^^^^^^ ----- type must be known at this point
@@ -8,7 +8,7 @@ LL | if false { is_trait(foo()) } else { Default::default() }
88
|
99
= note: cannot satisfy `_: Trait<_>`
1010
note: required by a bound in `is_trait`
11-
--> $DIR/auto-trait-selection-freeze.rs:12:16
11+
--> $DIR/auto-trait-selection-freeze.rs:11:16
1212
|
1313
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
1414
| ^^^^^^^^ required by this bound in `is_trait`
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/auto-trait-selection-freeze.rs:19:16
3+
|
4+
LL | if false { is_trait(foo()) } else { Default::default() }
5+
| ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
6+
|
7+
note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
8+
--> $DIR/auto-trait-selection-freeze.rs:16:1
9+
|
10+
LL | impl<T: Freeze> Trait<u32> for T {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
LL | impl<T> Trait<i32> for T {}
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^
14+
note: required by a bound in `is_trait`
15+
--> $DIR/auto-trait-selection-freeze.rs:11:16
16+
|
17+
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
18+
| ^^^^^^^^ required by this bound in `is_trait`
19+
help: consider specifying the generic arguments
20+
|
21+
LL | if false { is_trait::<_, U>(foo()) } else { Default::default() }
22+
| ++++++++
23+
24+
error: aborting due to 1 previous error
25+
26+
For more information about this error, try `rustc --explain E0283`.

tests/ui/impl-trait/auto-trait-selection-freeze.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
44
//@ revisions: next old
55
//@[next] compile-flags: -Znext-solver
6-
//@[old]check-pass
76

87
#![feature(freeze)]
98

@@ -18,7 +17,7 @@ impl<T: Freeze> Trait<u32> for T {}
1817
impl<T> Trait<i32> for T {}
1918
fn foo() -> impl Sized {
2019
if false { is_trait(foo()) } else { Default::default() }
21-
//[next]~^ ERROR: type annotations needed
20+
//~^ ERROR: type annotations needed
2221
}
2322

2423
fn main() {}

tests/ui/impl-trait/auto-trait-selection.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0283]: type annotations needed
2-
--> $DIR/auto-trait-selection.rs:16:16
2+
--> $DIR/auto-trait-selection.rs:15:16
33
|
44
LL | if false { is_trait(foo()) } else { Default::default() }
55
| ^^^^^^^^ ----- type must be known at this point
@@ -8,7 +8,7 @@ LL | if false { is_trait(foo()) } else { Default::default() }
88
|
99
= note: cannot satisfy `_: Trait<_>`
1010
note: required by a bound in `is_trait`
11-
--> $DIR/auto-trait-selection.rs:8:16
11+
--> $DIR/auto-trait-selection.rs:7:16
1212
|
1313
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
1414
| ^^^^^^^^ required by this bound in `is_trait`
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error[E0283]: type annotations needed
2+
--> $DIR/auto-trait-selection.rs:15:16
3+
|
4+
LL | if false { is_trait(foo()) } else { Default::default() }
5+
| ^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `is_trait`
6+
|
7+
note: multiple `impl`s satisfying `impl Sized: Trait<_>` found
8+
--> $DIR/auto-trait-selection.rs:12:1
9+
|
10+
LL | impl<T: Send> Trait<u32> for T {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
LL | impl<T> Trait<i32> for T {}
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^
14+
note: required by a bound in `is_trait`
15+
--> $DIR/auto-trait-selection.rs:7:16
16+
|
17+
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
18+
| ^^^^^^^^ required by this bound in `is_trait`
19+
help: consider specifying the generic arguments
20+
|
21+
LL | if false { is_trait::<_, U>(foo()) } else { Default::default() }
22+
| ++++++++
23+
24+
error: aborting due to 1 previous error
25+
26+
For more information about this error, try `rustc --explain E0283`.

tests/ui/impl-trait/auto-trait-selection.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
44
//@ revisions: next old
55
//@[next] compile-flags: -Znext-solver
6-
//@[old]check-pass
76

87
fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
98
Default::default()
@@ -14,7 +13,7 @@ impl<T: Send> Trait<u32> for T {}
1413
impl<T> Trait<i32> for T {}
1514
fn foo() -> impl Sized {
1615
if false { is_trait(foo()) } else { Default::default() }
17-
//[next]~^ ERROR: type annotations needed
16+
//~^ ERROR: type annotations needed
1817
}
1918

2019
fn main() {}

tests/ui/impl-trait/unsized_coercion3.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | let x = hello();
55
| ^^^^^^^ types differ
66

77
error[E0308]: mismatched types
8-
--> $DIR/unsized_coercion3.rs:19:14
8+
--> $DIR/unsized_coercion3.rs:18:14
99
|
1010
LL | fn hello() -> Box<impl Trait + ?Sized> {
1111
| ------------------- the expected opaque type
@@ -21,7 +21,7 @@ note: associated function defined here
2121
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
2222

2323
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
24-
--> $DIR/unsized_coercion3.rs:19:14
24+
--> $DIR/unsized_coercion3.rs:18:14
2525
|
2626
LL | Box::new(1u32)
2727
| -------- ^^^^ doesn't have a size known at compile-time
Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
error: cannot check whether the hidden type of opaque type satisfies auto traits
2-
--> $DIR/unsized_coercion3.rs:15:32
3-
|
4-
LL | let y: Box<dyn Send> = x;
5-
| ^
6-
|
7-
= 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
8-
note: opaque type is declared here
9-
--> $DIR/unsized_coercion3.rs:11:19
10-
|
11-
LL | fn hello() -> Box<impl Trait + ?Sized> {
12-
| ^^^^^^^^^^^^^^^^^^^
13-
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
14-
151
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
162
--> $DIR/unsized_coercion3.rs:15:32
173
|
@@ -21,6 +7,6 @@ LL | let y: Box<dyn Send> = x;
217
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
228
= note: required for the cast from `Box<impl Trait + ?Sized>` to `Box<dyn Send>`
239

24-
error: aborting due to 2 previous errors
10+
error: aborting due to 1 previous error
2511

2612
For more information about this error, try `rustc --explain E0277`.

tests/ui/impl-trait/unsized_coercion3.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ fn hello() -> Box<impl Trait + ?Sized> {
1414
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
1515
let y: Box<dyn Send> = x;
1616
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
17-
//[old]~| ERROR: cannot check whether the hidden type of opaque type satisfies auto traits
1817
}
1918
Box::new(1u32)
2019
//[next]~^ ERROR: mismatched types

0 commit comments

Comments
 (0)