mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Shallowly match opaque key in storage
This commit is contained in:
parent
8f8bee4f60
commit
470e9fa1af
@ -4,6 +4,7 @@ use derive_where::derive_where;
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||||
use rustc_type_ir::data_structures::{HashMap, HashSet, ensure_sufficient_stack};
|
use rustc_type_ir::data_structures::{HashMap, HashSet, ensure_sufficient_stack};
|
||||||
|
use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
||||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||||
use rustc_type_ir::inherent::*;
|
use rustc_type_ir::inherent::*;
|
||||||
use rustc_type_ir::relate::Relate;
|
use rustc_type_ir::relate::Relate;
|
||||||
@ -18,9 +19,9 @@ use crate::delegate::SolverDelegate;
|
|||||||
use crate::solve::inspect::{self, ProofTreeBuilder};
|
use crate::solve::inspect::{self, ProofTreeBuilder};
|
||||||
use crate::solve::search_graph::SearchGraph;
|
use crate::solve::search_graph::SearchGraph;
|
||||||
use crate::solve::{
|
use crate::solve::{
|
||||||
CanonicalInput, CanonicalResponse, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind,
|
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource,
|
||||||
GoalSource, HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData,
|
HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult,
|
||||||
QueryResult, SolverMode,
|
SolverMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) mod canonical;
|
pub(super) mod canonical;
|
||||||
@ -987,40 +988,22 @@ where
|
|||||||
|
|
||||||
// Do something for each opaque/hidden pair defined with `def_id` in the
|
// Do something for each opaque/hidden pair defined with `def_id` in the
|
||||||
// current inference context.
|
// current inference context.
|
||||||
pub(super) fn unify_existing_opaque_tys(
|
pub(super) fn probe_existing_opaque_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
param_env: I::ParamEnv,
|
|
||||||
key: ty::OpaqueTypeKey<I>,
|
key: ty::OpaqueTypeKey<I>,
|
||||||
ty: I::Ty,
|
) -> Option<(ty::OpaqueTypeKey<I>, I::Ty)> {
|
||||||
) -> Vec<CanonicalResponse<I>> {
|
let mut matching =
|
||||||
// FIXME: Super inefficient to be cloning this...
|
self.delegate.clone_opaque_types_for_query_response().into_iter().filter(
|
||||||
let opaques = self.delegate.clone_opaque_types_for_query_response();
|
|(candidate_key, _)| {
|
||||||
|
candidate_key.def_id == key.def_id
|
||||||
let mut values = vec![];
|
&& DeepRejectCtxt::relate_rigid_rigid(self.cx())
|
||||||
for (candidate_key, candidate_ty) in opaques {
|
.args_may_unify(candidate_key.args, key.args)
|
||||||
if candidate_key.def_id != key.def_id {
|
},
|
||||||
continue;
|
|
||||||
}
|
|
||||||
values.extend(
|
|
||||||
self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
|
|
||||||
result: *result,
|
|
||||||
})
|
|
||||||
.enter(|ecx| {
|
|
||||||
for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) {
|
|
||||||
ecx.eq(param_env, a, b)?;
|
|
||||||
}
|
|
||||||
ecx.eq(param_env, candidate_ty, ty)?;
|
|
||||||
ecx.add_item_bounds_for_hidden_type(
|
|
||||||
candidate_key.def_id.into(),
|
|
||||||
candidate_key.args,
|
|
||||||
param_env,
|
|
||||||
candidate_ty,
|
|
||||||
);
|
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
let first = matching.next();
|
||||||
values
|
let second = matching.next();
|
||||||
|
assert_eq!(second, None);
|
||||||
|
first
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to evaluate a const, or return `None` if the const is too generic.
|
// Try to evaluate a const, or return `None` if the const is too generic.
|
||||||
|
@ -7,7 +7,9 @@ use rustc_type_ir::inherent::*;
|
|||||||
use rustc_type_ir::{self as ty, Interner};
|
use rustc_type_ir::{self as ty, Interner};
|
||||||
|
|
||||||
use crate::delegate::SolverDelegate;
|
use crate::delegate::SolverDelegate;
|
||||||
use crate::solve::{Certainty, EvalCtxt, Goal, NoSolution, QueryResult, Reveal, SolverMode};
|
use crate::solve::{
|
||||||
|
Certainty, EvalCtxt, Goal, NoSolution, QueryResult, Reveal, SolverMode, inspect,
|
||||||
|
};
|
||||||
|
|
||||||
impl<D, I> EvalCtxt<'_, D>
|
impl<D, I> EvalCtxt<'_, D>
|
||||||
where
|
where
|
||||||
@ -52,14 +54,28 @@ where
|
|||||||
//
|
//
|
||||||
// If that fails, we insert `expected` as a new hidden type instead of
|
// If that fails, we insert `expected` as a new hidden type instead of
|
||||||
// eagerly emitting an error.
|
// eagerly emitting an error.
|
||||||
let matches =
|
let existing = self.probe_existing_opaque_ty(opaque_type_key);
|
||||||
self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
|
if let Some((candidate_key, candidate_ty)) = existing {
|
||||||
if !matches.is_empty() {
|
return self
|
||||||
if let Some(response) = self.try_merge_responses(&matches) {
|
.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
|
||||||
return Ok(response);
|
result: *result,
|
||||||
} else {
|
})
|
||||||
return self.flounder(&matches);
|
.enter(|ecx| {
|
||||||
}
|
for (a, b) in std::iter::zip(
|
||||||
|
candidate_key.args.iter(),
|
||||||
|
opaque_type_key.args.iter(),
|
||||||
|
) {
|
||||||
|
ecx.eq(goal.param_env, a, b)?;
|
||||||
|
}
|
||||||
|
ecx.eq(goal.param_env, candidate_ty, expected)?;
|
||||||
|
ecx.add_item_bounds_for_hidden_type(
|
||||||
|
candidate_key.def_id.into(),
|
||||||
|
candidate_key.args,
|
||||||
|
goal.param_env,
|
||||||
|
candidate_ty,
|
||||||
|
);
|
||||||
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, define a new opaque type
|
// Otherwise, define a new opaque type
|
||||||
|
Loading…
Reference in New Issue
Block a user