rustc_next_trait_solver/solve/project_goals/
opaque_types.rs1use rustc_type_ir::inherent::*;
5use rustc_type_ir::solve::{GoalSource, QueryResultOrRerunNonErased, RerunReason};
6use rustc_type_ir::{self as ty, Interner, MayBeErased, TypingMode, fold_regions};
7
8use crate::delegate::SolverDelegate;
9use crate::solve::{Certainty, EvalCtxt, Goal};
10
11impl<D, I> EvalCtxt<'_, D>
12where
13 D: SolverDelegate<Interner = I>,
14 I: Interner,
15{
16 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::INFO <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("normalize_opaque_type",
"rustc_next_trait_solver::solve::project_goals::opaque_types",
::tracing::Level::INFO,
::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(16u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::project_goals::opaque_types"),
::tracing_core::field::FieldSet::new(&["goal"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::INFO <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::INFO <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: QueryResultOrRerunNonErased<I> =
loop {};
return __tracing_attr_fake_return;
}
{
let cx = self.cx();
let opaque_ty = goal.predicate.projection_term;
let expected =
goal.predicate.term.as_type().expect("no such thing as an opaque const");
let def_id = opaque_ty.expect_opaque_ty_def_id();
match self.typing_mode() {
TypingMode::Coherence => {
self.add_item_bounds_for_hidden_type(def_id, opaque_ty.args,
goal.param_env, expected)?;
self.add_goal(GoalSource::Misc,
goal.with(cx, ty::PredicateKind::Ambiguous))?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
}
TypingMode::Typeck {
defining_opaque_types_and_generators: defining_opaque_types
} | TypingMode::PostTypeckUntilBorrowck {
defining_opaque_types } => {
let Some(def_id) =
def_id.as_local().filter(|&def_id|
defining_opaque_types.contains(&def_id.into())) else {
self.eq(goal.param_env,
opaque_ty.to_term(cx, ty::IsRigid::Yes),
goal.predicate.term)?;
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into);
};
let normalized_args =
cx.mk_args_from_iter(opaque_ty.args.iter().map(|arg|
match arg.kind() {
ty::GenericArgKind::Lifetime(lt) => Ok(lt.into()),
ty::GenericArgKind::Type(ty) => {
self.structurally_normalize_ty(goal.param_env,
ty).map(Into::into)
}
ty::GenericArgKind::Const(ct) => {
self.structurally_normalize_const(goal.param_env,
ct).map(Into::into)
}
}))?;
let opaque_type_key =
ty::OpaqueTypeKey { def_id, args: normalized_args };
if let Some(prev) =
self.register_hidden_type_in_storage(opaque_type_key,
expected) {
self.eq(goal.param_env, expected, prev)?;
} else {
match self.typing_mode().assert_not_erased() {
TypingMode::Typeck { .. } => {}
TypingMode::PostTypeckUntilBorrowck { .. } => {
let actual =
cx.type_of_opaque_hir_typeck(def_id).instantiate(cx,
opaque_ty.args);
let actual =
actual.map(|v|
{
fold_regions(cx, v,
|re, _dbi|
match re.kind() {
ty::ReErased => self.next_region_var(),
_ => re,
})
});
let actual =
self.normalize(GoalSource::Misc, goal.param_env, actual)?;
self.eq(goal.param_env, expected, actual)?;
}
TypingMode::Coherence | TypingMode::PostBorrowck { .. } |
TypingMode::PostAnalysis | TypingMode::Codegen =>
::core::panicking::panic("internal error: entered unreachable code"),
}
}
self.add_item_bounds_for_hidden_type(def_id.into(),
normalized_args, goal.param_env, expected)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
}
TypingMode::PostBorrowck { defined_opaque_types } => {
let Some(def_id) =
def_id.as_local().filter(|&def_id|
defined_opaque_types.contains(&def_id.into())) else {
self.eq(goal.param_env,
opaque_ty.to_term(cx, ty::IsRigid::Yes),
goal.predicate.term)?;
return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into);
};
let actual =
cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args);
let actual =
actual.map(|v|
{
fold_regions(cx, v,
|re, _dbi|
match re.kind() {
ty::ReErased => self.next_region_var(),
_ => re,
})
});
let actual =
self.normalize(GoalSource::Misc, goal.param_env, actual)?;
self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
}
TypingMode::PostAnalysis | TypingMode::Codegen => {
let actual =
cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args);
let actual =
self.normalize(GoalSource::Misc, goal.param_env, actual)?;
self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
}
TypingMode::ErasedNotCoherence(MayBeErased) => {
if let Some(def_id) = def_id.as_local() {
self.opaque_accesses.rerun_if_opaque_in_opaque_type_storage(RerunReason::NormalizeOpaqueType,
def_id)?;
} else {
self.opaque_accesses.rerun_if_in_post_analysis(RerunReason::NormalizeOpaqueTypeRemoteCrate)?;
}
self.eq(goal.param_env,
opaque_ty.to_term(cx, ty::IsRigid::Yes),
goal.predicate.term)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
}
}
}
}
}#[tracing::instrument(skip(self))]
17 pub(super) fn normalize_opaque_type(
18 &mut self,
19 goal: Goal<I, ty::ProjectionPredicate<I>>,
20 ) -> QueryResultOrRerunNonErased<I> {
21 let cx = self.cx();
22 let opaque_ty = goal.predicate.projection_term;
23 let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const");
24 let def_id = opaque_ty.expect_opaque_ty_def_id();
25
26 match self.typing_mode() {
27 TypingMode::Coherence => {
28 self.add_item_bounds_for_hidden_type(
31 def_id,
32 opaque_ty.args,
33 goal.param_env,
34 expected,
35 )?;
36 self.add_goal(GoalSource::Misc, goal.with(cx, ty::PredicateKind::Ambiguous))?;
41 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
42 .map_err(Into::into)
43 }
44 TypingMode::Typeck { defining_opaque_types_and_generators: defining_opaque_types }
45 | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types } => {
46 let Some(def_id) = def_id
47 .as_local()
48 .filter(|&def_id| defining_opaque_types.contains(&def_id.into()))
49 else {
50 self.eq(
52 goal.param_env,
53 opaque_ty.to_term(cx, ty::IsRigid::Yes),
54 goal.predicate.term,
55 )?;
56 return self
57 .evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
58 .map_err(Into::into);
59 };
60
61 let normalized_args =
72 cx.mk_args_from_iter(opaque_ty.args.iter().map(|arg| match arg.kind() {
73 ty::GenericArgKind::Lifetime(lt) => Ok(lt.into()),
74 ty::GenericArgKind::Type(ty) => {
75 self.structurally_normalize_ty(goal.param_env, ty).map(Into::into)
76 }
77 ty::GenericArgKind::Const(ct) => {
78 self.structurally_normalize_const(goal.param_env, ct).map(Into::into)
79 }
80 }))?;
81
82 let opaque_type_key = ty::OpaqueTypeKey { def_id, args: normalized_args };
83 if let Some(prev) = self.register_hidden_type_in_storage(opaque_type_key, expected)
84 {
85 self.eq(goal.param_env, expected, prev)?;
86 } else {
87 match self.typing_mode().assert_not_erased() {
91 TypingMode::Typeck { .. } => {}
92 TypingMode::PostTypeckUntilBorrowck { .. } => {
93 let actual = cx
94 .type_of_opaque_hir_typeck(def_id)
95 .instantiate(cx, opaque_ty.args);
96 let actual = actual.map(|v| {
97 fold_regions(cx, v, |re, _dbi| match re.kind() {
98 ty::ReErased => self.next_region_var(),
99 _ => re,
100 })
101 });
102 let actual =
103 self.normalize(GoalSource::Misc, goal.param_env, actual)?;
104 self.eq(goal.param_env, expected, actual)?;
105 }
106 TypingMode::Coherence
107 | TypingMode::PostBorrowck { .. }
108 | TypingMode::PostAnalysis
109 | TypingMode::Codegen => unreachable!(),
110 }
111 }
112
113 self.add_item_bounds_for_hidden_type(
114 def_id.into(),
115 normalized_args,
116 goal.param_env,
117 expected,
118 )?;
119 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
120 .map_err(Into::into)
121 }
122 TypingMode::PostBorrowck { defined_opaque_types } => {
123 let Some(def_id) = def_id
124 .as_local()
125 .filter(|&def_id| defined_opaque_types.contains(&def_id.into()))
126 else {
127 self.eq(
128 goal.param_env,
129 opaque_ty.to_term(cx, ty::IsRigid::Yes),
130 goal.predicate.term,
131 )?;
132 return self
133 .evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
134 .map_err(Into::into);
135 };
136
137 let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args);
138 let actual = actual.map(|v| {
142 fold_regions(cx, v, |re, _dbi| match re.kind() {
143 ty::ReErased => self.next_region_var(),
144 _ => re,
145 })
146 });
147 let actual = self.normalize(GoalSource::Misc, goal.param_env, actual)?;
148 self.eq(goal.param_env, expected, actual)?;
149 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
150 .map_err(Into::into)
151 }
152 TypingMode::PostAnalysis | TypingMode::Codegen => {
153 let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args);
155 let actual = self.normalize(GoalSource::Misc, goal.param_env, actual)?;
156 self.eq(goal.param_env, expected, actual)?;
157 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
158 .map_err(Into::into)
159 }
160 TypingMode::ErasedNotCoherence(MayBeErased) => {
161 if let Some(def_id) = def_id.as_local() {
168 self.opaque_accesses.rerun_if_opaque_in_opaque_type_storage(
169 RerunReason::NormalizeOpaqueType,
170 def_id,
171 )?;
172 } else {
173 self.opaque_accesses
174 .rerun_if_in_post_analysis(RerunReason::NormalizeOpaqueTypeRemoteCrate)?;
175 }
176
177 self.eq(
179 goal.param_env,
180 opaque_ty.to_term(cx, ty::IsRigid::Yes),
181 goal.predicate.term,
182 )?;
183 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
184 .map_err(Into::into)
185 }
186 }
187 }
188}