rustc_next_trait_solver/solve/normalizes_to/
opaque_types.rs1use rustc_type_ir::inherent::*;
5use rustc_type_ir::solve::GoalSource;
6use rustc_type_ir::{self as ty, Interner, TypingMode, fold_regions};
7
8use crate::delegate::SolverDelegate;
9use crate::solve::{Certainty, EvalCtxt, Goal, QueryResult};
10
11impl<D, I> EvalCtxt<'_, D>
12where
13 D: SolverDelegate<Interner = I>,
14 I: Interner,
15{
16 pub(super) fn normalize_opaque_type(
17 &mut self,
18 goal: Goal<I, ty::NormalizesTo<I>>,
19 ) -> QueryResult<I> {
20 let cx = self.cx();
21 let opaque_ty = goal.predicate.alias;
22 let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const");
23
24 match self.typing_mode() {
25 TypingMode::Coherence => {
26 self.add_item_bounds_for_hidden_type(
29 opaque_ty.def_id,
30 opaque_ty.args,
31 goal.param_env,
32 expected,
33 );
34 self.add_goal(GoalSource::Misc, goal.with(cx, ty::PredicateKind::Ambiguous));
39 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
40 }
41 TypingMode::Analysis {
42 defining_opaque_types_and_generators: defining_opaque_types,
43 }
44 | TypingMode::Borrowck { defining_opaque_types } => {
45 let Some(def_id) = opaque_ty
46 .def_id
47 .as_local()
48 .filter(|&def_id| defining_opaque_types.contains(&def_id))
49 else {
50 self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
52 return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
53 };
54
55 let normalized_args =
66 cx.mk_args_from_iter(opaque_ty.args.iter().map(|arg| match arg.kind() {
67 ty::GenericArgKind::Lifetime(lt) => Ok(lt.into()),
68 ty::GenericArgKind::Type(ty) => {
69 self.structurally_normalize_ty(goal.param_env, ty).map(Into::into)
70 }
71 ty::GenericArgKind::Const(ct) => {
72 self.structurally_normalize_const(goal.param_env, ct).map(Into::into)
73 }
74 }))?;
75
76 let opaque_type_key = ty::OpaqueTypeKey { def_id, args: normalized_args };
77 if let Some(prev) = self.register_hidden_type_in_storage(opaque_type_key, expected)
78 {
79 self.eq(goal.param_env, expected, prev)?;
80 } else {
81 match self.typing_mode() {
85 TypingMode::Analysis { .. } => {}
86 TypingMode::Borrowck { .. } => {
87 let actual = cx
88 .type_of_opaque_hir_typeck(def_id)
89 .instantiate(cx, opaque_ty.args);
90 let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() {
91 ty::ReErased => self.next_region_var(),
92 _ => re,
93 });
94 self.eq(goal.param_env, expected, actual)?;
95 }
96 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
97 }
98 }
99
100 self.add_item_bounds_for_hidden_type(
101 def_id.into(),
102 normalized_args,
103 goal.param_env,
104 expected,
105 );
106 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
107 }
108 TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
109 let Some(def_id) = opaque_ty
110 .def_id
111 .as_local()
112 .filter(|&def_id| defined_opaque_types.contains(&def_id))
113 else {
114 self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
115 return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
116 };
117
118 let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args);
119 let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() {
123 ty::ReErased => self.next_region_var(),
124 _ => re,
125 });
126 self.eq(goal.param_env, expected, actual)?;
127 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
128 }
129 TypingMode::PostAnalysis => {
130 let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args);
132 self.eq(goal.param_env, expected, actual)?;
133 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
134 }
135 }
136 }
137}