Skip to content

Commit 0714168

Browse files
committed
Do not use global cache for selection candidates if opaque types can be constrained
1 parent a330e49 commit 0714168

File tree

8 files changed

+50
-9
lines changed

8 files changed

+50
-9
lines changed

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

+13
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use rustc_middle::ty::{self, PolyProjectionPredicate, Upcast};
4949
use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
5050
use rustc_span::symbol::sym;
5151
use rustc_span::Symbol;
52+
use rustc_type_ir::InferCtxtLike as _;
5253

5354
use std::cell::{Cell, RefCell};
5455
use std::cmp;
@@ -1557,6 +1558,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15571558
if self.is_intercrate() {
15581559
return None;
15591560
}
1561+
1562+
// Opaque types are not part of the global cache key, so we'd be caching and loading
1563+
// values, even though we don't have all the information that went into them.
1564+
if !self.infcx.defining_opaque_types().is_empty() {
1565+
return None;
1566+
}
1567+
15601568
let tcx = self.tcx();
15611569
let pred = cache_fresh_trait_pred.skip_binder();
15621570

@@ -1595,6 +1603,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15951603
if self.is_intercrate() {
15961604
return false;
15971605
}
1606+
// Opaque types are not part of the global cache key, so we'd be caching and loading
1607+
// values, even though we don't have all the information that went into them.
1608+
if !self.infcx.defining_opaque_types().is_empty() {
1609+
return false;
1610+
}
15981611
match result {
15991612
Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => !trait_ref.has_infer(),
16001613
_ => true,

tests/ui/coherence/occurs-check/opaques.next.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0119]: conflicting implementations of trait `Trait<_>`
2-
--> $DIR/opaques.rs:30:1
2+
--> $DIR/opaques.rs:28:1
33
|
44
LL | impl<T> Trait<T> for T {
55
| ---------------------- first implementation here
@@ -8,7 +8,7 @@ LL | impl<T> Trait<T> for defining_scope::Alias<T> {
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
99

1010
error[E0282]: type annotations needed
11-
--> $DIR/opaques.rs:13:20
11+
--> $DIR/opaques.rs:11:20
1212
|
1313
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
1414
| ^ cannot infer type
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0284]: type annotations needed
2+
--> $DIR/opaques.rs:11:20
3+
|
4+
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
5+
| ^ cannot infer type
6+
|
7+
= note: cannot satisfy `<Alias<T> as Trait<T>>::Assoc == _`
8+
note: required because it appears within the type `Container<Alias<T>, T>`
9+
--> $DIR/opaques.rs:17:8
10+
|
11+
LL | struct Container<T: Trait<U>, U> {
12+
| ^^^^^^^^^
13+
= help: unsized fn params are gated as an unstable feature
14+
help: function arguments must have a statically known size, borrowed types always have a known size
15+
|
16+
LL | pub fn cast<T>(x: &Container<Alias<T>, T>) -> Container<T, T> {
17+
| +
18+
19+
error: aborting due to 1 previous error
20+
21+
For more information about this error, try `rustc --explain E0284`.

tests/ui/coherence/occurs-check/opaques.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33

44
// A regression test for #105787
55

6-
//@[old] known-bug: #105787
7-
//@[old] check-pass
86
#![feature(type_alias_impl_trait)]
97
mod defining_scope {
108
use super::*;
119
pub type Alias<T> = impl Sized;
1210

1311
pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
14-
//[next]~^ ERROR type annotations needed
12+
//~^ ERROR type annotations needed
1513
x
1614
}
1715
}

tests/ui/impl-trait/equality.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo {
2222
0
2323
} else {
2424
n + sum_to(n - 1)
25-
//~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
25+
//~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == u32`
2626
}
2727
}
2828

tests/ui/impl-trait/equality.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ help: change the type of the numeric literal from `u32` to `i32`
2222
LL | 0_i32
2323
| ~~~
2424

25-
error[E0284]: type annotations needed: cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
25+
error[E0284]: type annotations needed: cannot satisfy `<u32 as Add<impl Foo>>::Output == u32`
2626
--> $DIR/equality.rs:24:11
2727
|
2828
LL | n + sum_to(n - 1)
29-
| ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
29+
| ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == u32`
3030

3131
error: aborting due to 2 previous errors; 1 warning emitted
3232

tests/ui/type-alias-impl-trait/escaping-bound-var.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trait Test<'a> {}
88

99
pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
1010
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
11+
//~| ERROR unconstrained opaque type
1112

1213
impl Trait<'_> for () {
1314
type Assoc = ();

tests/ui/type-alias-impl-trait/escaping-bound-var.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ note: lifetime declared here
1010
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
1111
| ^^
1212

13-
error: aborting due to 1 previous error
13+
error: unconstrained opaque type
14+
--> $DIR/escaping-bound-var.rs:9:47
15+
|
16+
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
17+
| ^^^^^^^^^^^^^
18+
|
19+
= note: `Foo` must be used in combination with a concrete type within the same module
20+
21+
error: aborting due to 2 previous errors
1422

1523
For more information about this error, try `rustc --explain E0657`.

0 commit comments

Comments
 (0)