Skip to content

Commit

Permalink
Shallowly match opaque key in storage
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 12, 2024
1 parent 8f8bee4 commit 470e9fa
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 43 deletions.
51 changes: 17 additions & 34 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use derive_where::derive_where;
#[cfg(feature = "nightly")]
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
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::inherent::*;
use rustc_type_ir::relate::Relate;
Expand All @@ -18,9 +19,9 @@ use crate::delegate::SolverDelegate;
use crate::solve::inspect::{self, ProofTreeBuilder};
use crate::solve::search_graph::SearchGraph;
use crate::solve::{
CanonicalInput, CanonicalResponse, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind,
GoalSource, HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData,
QueryResult, SolverMode,
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource,
HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult,
SolverMode,
};

pub(super) mod canonical;
Expand Down Expand Up @@ -987,40 +988,22 @@ where

// Do something for each opaque/hidden pair defined with `def_id` in the
// current inference context.
pub(super) fn unify_existing_opaque_tys(
pub(super) fn probe_existing_opaque_ty(
&mut self,
param_env: I::ParamEnv,
key: ty::OpaqueTypeKey<I>,
ty: I::Ty,
) -> Vec<CanonicalResponse<I>> {
// FIXME: Super inefficient to be cloning this...
let opaques = self.delegate.clone_opaque_types_for_query_response();

let mut values = vec![];
for (candidate_key, candidate_ty) in opaques {
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)
}),
) -> Option<(ty::OpaqueTypeKey<I>, I::Ty)> {
let mut matching =
self.delegate.clone_opaque_types_for_query_response().into_iter().filter(
|(candidate_key, _)| {
candidate_key.def_id == key.def_id
&& DeepRejectCtxt::relate_rigid_rigid(self.cx())
.args_may_unify(candidate_key.args, key.args)
},
);
}
values
let first = matching.next();
let second = matching.next();
assert_eq!(second, None);
first
}

// Try to evaluate a const, or return `None` if the const is too generic.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use rustc_type_ir::inherent::*;
use rustc_type_ir::{self as ty, Interner};

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>
where
Expand Down Expand Up @@ -52,14 +54,28 @@ where
//
// If that fails, we insert `expected` as a new hidden type instead of
// eagerly emitting an error.
let matches =
self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
if !matches.is_empty() {
if let Some(response) = self.try_merge_responses(&matches) {
return Ok(response);
} else {
return self.flounder(&matches);
}
let existing = self.probe_existing_opaque_ty(opaque_type_key);
if let Some((candidate_key, candidate_ty)) = existing {
return self
.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
result: *result,
})
.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
Expand Down

0 comments on commit 470e9fa

Please sign in to comment.