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 .skip_norm_wip();
91 let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() {
92 ty::ReErased => self.next_region_var(),
93 _ => re,
94 });
95 self.eq(goal.param_env, expected, actual)?;
96 }
97 TypingMode::Coherence
98 | TypingMode::PostBorrowckAnalysis { .. }
99 | TypingMode::PostAnalysis => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
100 }
101 }
102
103 self.add_item_bounds_for_hidden_type(
104 def_id.into(),
105 normalized_args,
106 goal.param_env,
107 expected,
108 );
109 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
110 }
111 TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
112 let Some(def_id) = opaque_ty
113 .def_id()
114 .as_local()
115 .filter(|&def_id| defined_opaque_types.contains(&def_id))
116 else {
117 self.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias);
118 return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
119 };
120
121 let actual =
122 cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args).skip_norm_wip();
123 let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() {
127 ty::ReErased => self.next_region_var(),
128 _ => re,
129 });
130 self.eq(goal.param_env, expected, actual)?;
131 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
132 }
133 TypingMode::PostAnalysis => {
134 let actual =
136 cx.type_of(opaque_ty.def_id()).instantiate(cx, opaque_ty.args).skip_norm_wip();
137 self.eq(goal.param_env, expected, actual)?;
138 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
139 }
140 }
141 }
142}