diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index c8caf228ffb5b..53f66f70298b2 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -9,7 +9,7 @@ use rustc_errors::ErrorGuaranteed; use crate::ty; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::{HashStable, TypeVisitable}; use rustc_query_system::cache::Cache; @@ -17,7 +17,7 @@ pub type SelectionCache<'tcx> = Cache< // This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace // caller bounds with an empty list if the `TraitPredicate` looks global, which may happen // after erasing lifetimes from the predicate. - (ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>), + (&'tcx ty::List, ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>), SelectionResult<'tcx, SelectionCandidate<'tcx>>, >; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2489b8916d181..ddfd02330fa4a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -49,6 +49,7 @@ use rustc_middle::ty::{self, PolyProjectionPredicate, Upcast}; use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::Symbol; +use rustc_type_ir::InferCtxtLike as _; use std::cell::{Cell, RefCell}; use std::cmp; @@ -1559,13 +1560,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } let tcx = self.tcx(); let pred = cache_fresh_trait_pred.skip_binder(); + let opaques = self.infcx.defining_opaque_types(); if self.can_use_global_caches(param_env) { - if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) { + if let Some(res) = tcx.selection_cache.get(&(opaques, param_env, pred), tcx) { return Some(res); } } - self.infcx.selection_cache.get(&(param_env, pred), tcx) + self.infcx.selection_cache.get(&(opaques, param_env, pred), tcx) } /// Determines whether can we safely cache the result @@ -1611,6 +1613,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) { let tcx = self.tcx(); let pred = cache_fresh_trait_pred.skip_binder(); + let opaques = self.infcx.defining_opaque_types(); if !self.can_cache_candidate(&candidate) { debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable"); @@ -1624,14 +1627,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if !candidate.has_infer() { debug!(?pred, ?candidate, "insert_candidate_cache global"); // This may overwrite the cache with the same value. - tcx.selection_cache.insert((param_env, pred), dep_node, candidate); + tcx.selection_cache.insert((opaques, param_env, pred), dep_node, candidate); return; } } } debug!(?pred, ?candidate, "insert_candidate_cache local"); - self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate); + self.infcx.selection_cache.insert((opaques, param_env, pred), dep_node, candidate); } /// Looks at the item bounds of the projection or opaque type. diff --git a/tests/crashes/119272.rs b/tests/ui/auto-traits/opaque_type_candidate_selection.rs similarity index 86% rename from tests/crashes/119272.rs rename to tests/ui/auto-traits/opaque_type_candidate_selection.rs index 02e2cfd09e2f8..5ccd8a9b8ba4f 100644 --- a/tests/crashes/119272.rs +++ b/tests/ui/auto-traits/opaque_type_candidate_selection.rs @@ -1,10 +1,11 @@ -//@ known-bug: #119272 +//! used to ICE: #119272 #![feature(type_alias_impl_trait)] mod defining_scope { use super::*; pub type Alias = impl Sized; pub fn cast(x: Container, T>) -> Container { + //~^ ERROR: type annotations needed x } } diff --git a/tests/ui/auto-traits/opaque_type_candidate_selection.stderr b/tests/ui/auto-traits/opaque_type_candidate_selection.stderr new file mode 100644 index 0000000000000..997e81cf898a4 --- /dev/null +++ b/tests/ui/auto-traits/opaque_type_candidate_selection.stderr @@ -0,0 +1,21 @@ +error[E0284]: type annotations needed + --> $DIR/opaque_type_candidate_selection.rs:7:20 + | +LL | pub fn cast(x: Container, T>) -> Container { + | ^ cannot infer type + | + = note: cannot satisfy ` as Trait>::Assoc == _` +note: required because it appears within the type `Container, T>` + --> $DIR/opaque_type_candidate_selection.rs:13:8 + | +LL | struct Container, U> { + | ^^^^^^^^^ + = help: unsized fn params are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | pub fn cast(x: &Container, T>) -> Container { + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index 11d1edcca2f91..3de479963bb44 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:30:1 + --> $DIR/opaques.rs:28:1 | LL | impl Trait for T { | ---------------------- first implementation here @@ -8,7 +8,7 @@ LL | impl Trait for defining_scope::Alias { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0282]: type annotations needed - --> $DIR/opaques.rs:13:20 + --> $DIR/opaques.rs:11:20 | LL | pub fn cast(x: Container, T>) -> Container { | ^ cannot infer type diff --git a/tests/ui/coherence/occurs-check/opaques.old.stderr b/tests/ui/coherence/occurs-check/opaques.old.stderr new file mode 100644 index 0000000000000..faade2747f281 --- /dev/null +++ b/tests/ui/coherence/occurs-check/opaques.old.stderr @@ -0,0 +1,21 @@ +error[E0284]: type annotations needed + --> $DIR/opaques.rs:11:20 + | +LL | pub fn cast(x: Container, T>) -> Container { + | ^ cannot infer type + | + = note: cannot satisfy ` as Trait>::Assoc == _` +note: required because it appears within the type `Container, T>` + --> $DIR/opaques.rs:17:8 + | +LL | struct Container, U> { + | ^^^^^^^^^ + = help: unsized fn params are gated as an unstable feature +help: function arguments must have a statically known size, borrowed types always have a known size + | +LL | pub fn cast(x: &Container, T>) -> Container { + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs index 241a247c84130..eacb61fabc64e 100644 --- a/tests/ui/coherence/occurs-check/opaques.rs +++ b/tests/ui/coherence/occurs-check/opaques.rs @@ -3,15 +3,13 @@ // A regression test for #105787 -//@[old] known-bug: #105787 -//@[old] check-pass #![feature(type_alias_impl_trait)] mod defining_scope { use super::*; pub type Alias = impl Sized; pub fn cast(x: Container, T>) -> Container { - //[next]~^ ERROR type annotations needed + //~^ ERROR type annotations needed x } }