Skip to content

Commit 470e9fa

Browse files
Shallowly match opaque key in storage
1 parent 8f8bee4 commit 470e9fa

File tree

2 files changed

+42
-43
lines changed

2 files changed

+42
-43
lines changed

Diff for: compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+17-34
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use derive_where::derive_where;
44
#[cfg(feature = "nightly")]
55
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
66
use rustc_type_ir::data_structures::{HashMap, HashSet, ensure_sufficient_stack};
7+
use rustc_type_ir::fast_reject::DeepRejectCtxt;
78
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
89
use rustc_type_ir::inherent::*;
910
use rustc_type_ir::relate::Relate;
@@ -18,9 +19,9 @@ use crate::delegate::SolverDelegate;
1819
use crate::solve::inspect::{self, ProofTreeBuilder};
1920
use crate::solve::search_graph::SearchGraph;
2021
use crate::solve::{
21-
CanonicalInput, CanonicalResponse, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind,
22-
GoalSource, HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData,
23-
QueryResult, SolverMode,
22+
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource,
23+
HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult,
24+
SolverMode,
2425
};
2526

2627
pub(super) mod canonical;
@@ -987,40 +988,22 @@ where
987988

988989
// Do something for each opaque/hidden pair defined with `def_id` in the
989990
// current inference context.
990-
pub(super) fn unify_existing_opaque_tys(
991+
pub(super) fn probe_existing_opaque_ty(
991992
&mut self,
992-
param_env: I::ParamEnv,
993993
key: ty::OpaqueTypeKey<I>,
994-
ty: I::Ty,
995-
) -> Vec<CanonicalResponse<I>> {
996-
// FIXME: Super inefficient to be cloning this...
997-
let opaques = self.delegate.clone_opaque_types_for_query_response();
998-
999-
let mut values = vec![];
1000-
for (candidate_key, candidate_ty) in opaques {
1001-
if candidate_key.def_id != key.def_id {
1002-
continue;
1003-
}
1004-
values.extend(
1005-
self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
1006-
result: *result,
1007-
})
1008-
.enter(|ecx| {
1009-
for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) {
1010-
ecx.eq(param_env, a, b)?;
1011-
}
1012-
ecx.eq(param_env, candidate_ty, ty)?;
1013-
ecx.add_item_bounds_for_hidden_type(
1014-
candidate_key.def_id.into(),
1015-
candidate_key.args,
1016-
param_env,
1017-
candidate_ty,
1018-
);
1019-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1020-
}),
994+
) -> Option<(ty::OpaqueTypeKey<I>, I::Ty)> {
995+
let mut matching =
996+
self.delegate.clone_opaque_types_for_query_response().into_iter().filter(
997+
|(candidate_key, _)| {
998+
candidate_key.def_id == key.def_id
999+
&& DeepRejectCtxt::relate_rigid_rigid(self.cx())
1000+
.args_may_unify(candidate_key.args, key.args)
1001+
},
10211002
);
1022-
}
1023-
values
1003+
let first = matching.next();
1004+
let second = matching.next();
1005+
assert_eq!(second, None);
1006+
first
10241007
}
10251008

10261009
// Try to evaluate a const, or return `None` if the const is too generic.

Diff for: compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use rustc_type_ir::inherent::*;
77
use rustc_type_ir::{self as ty, Interner};
88

99
use crate::delegate::SolverDelegate;
10-
use crate::solve::{Certainty, EvalCtxt, Goal, NoSolution, QueryResult, Reveal, SolverMode};
10+
use crate::solve::{
11+
Certainty, EvalCtxt, Goal, NoSolution, QueryResult, Reveal, SolverMode, inspect,
12+
};
1113

1214
impl<D, I> EvalCtxt<'_, D>
1315
where
@@ -52,14 +54,28 @@ where
5254
//
5355
// If that fails, we insert `expected` as a new hidden type instead of
5456
// eagerly emitting an error.
55-
let matches =
56-
self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
57-
if !matches.is_empty() {
58-
if let Some(response) = self.try_merge_responses(&matches) {
59-
return Ok(response);
60-
} else {
61-
return self.flounder(&matches);
62-
}
57+
let existing = self.probe_existing_opaque_ty(opaque_type_key);
58+
if let Some((candidate_key, candidate_ty)) = existing {
59+
return self
60+
.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
61+
result: *result,
62+
})
63+
.enter(|ecx| {
64+
for (a, b) in std::iter::zip(
65+
candidate_key.args.iter(),
66+
opaque_type_key.args.iter(),
67+
) {
68+
ecx.eq(goal.param_env, a, b)?;
69+
}
70+
ecx.eq(goal.param_env, candidate_ty, expected)?;
71+
ecx.add_item_bounds_for_hidden_type(
72+
candidate_key.def_id.into(),
73+
candidate_key.args,
74+
goal.param_env,
75+
candidate_ty,
76+
);
77+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
78+
});
6379
}
6480

6581
// Otherwise, define a new opaque type

0 commit comments

Comments
 (0)