Skip to content

Commit 319843a

Browse files
committed
Add definable opaque types to the selection cache key
1 parent a330e49 commit 319843a

File tree

7 files changed

+56
-12
lines changed

7 files changed

+56
-12
lines changed

compiler/rustc_middle/src/traits/select.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ use rustc_errors::ErrorGuaranteed;
99

1010
use crate::ty;
1111

12-
use rustc_hir::def_id::DefId;
12+
use rustc_hir::def_id::{DefId, LocalDefId};
1313
use rustc_macros::{HashStable, TypeVisitable};
1414
use rustc_query_system::cache::Cache;
1515

1616
pub type SelectionCache<'tcx> = Cache<
1717
// This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace
1818
// caller bounds with an empty list if the `TraitPredicate` looks global, which may happen
1919
// after erasing lifetimes from the predicate.
20-
(ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>),
20+
(&'tcx ty::List<LocalDefId>, ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>),
2121
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
2222
>;
2323

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

+7-4
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;
@@ -1559,13 +1560,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15591560
}
15601561
let tcx = self.tcx();
15611562
let pred = cache_fresh_trait_pred.skip_binder();
1563+
let opaques = self.infcx.defining_opaque_types();
15621564

15631565
if self.can_use_global_caches(param_env) {
1564-
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
1566+
if let Some(res) = tcx.selection_cache.get(&(opaques, param_env, pred), tcx) {
15651567
return Some(res);
15661568
}
15671569
}
1568-
self.infcx.selection_cache.get(&(param_env, pred), tcx)
1570+
self.infcx.selection_cache.get(&(opaques, param_env, pred), tcx)
15691571
}
15701572

15711573
/// Determines whether can we safely cache the result
@@ -1611,6 +1613,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16111613
) {
16121614
let tcx = self.tcx();
16131615
let pred = cache_fresh_trait_pred.skip_binder();
1616+
let opaques = self.infcx.defining_opaque_types();
16141617

16151618
if !self.can_cache_candidate(&candidate) {
16161619
debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");
@@ -1624,14 +1627,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16241627
if !candidate.has_infer() {
16251628
debug!(?pred, ?candidate, "insert_candidate_cache global");
16261629
// This may overwrite the cache with the same value.
1627-
tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
1630+
tcx.selection_cache.insert((opaques, param_env, pred), dep_node, candidate);
16281631
return;
16291632
}
16301633
}
16311634
}
16321635

16331636
debug!(?pred, ?candidate, "insert_candidate_cache local");
1634-
self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
1637+
self.infcx.selection_cache.insert((opaques, param_env, pred), dep_node, candidate);
16351638
}
16361639

16371640
/// Looks at the item bounds of the projection or opaque type.

tests/crashes/119272.rs renamed to tests/ui/auto-traits/opaque_type_candidate_selection.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
//@ known-bug: #119272
1+
//! used to ICE: #119272
22
#![feature(type_alias_impl_trait)]
33
mod defining_scope {
44
use super::*;
55
pub type Alias<T> = impl Sized;
66

77
pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
8+
//~^ ERROR: type annotations needed
89
x
910
}
1011
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0284]: type annotations needed
2+
--> $DIR/opaque_type_candidate_selection.rs:7: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/opaque_type_candidate_selection.rs:13: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.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
}

0 commit comments

Comments
 (0)