1use core::fmt;
2use std::hash::{Hash, Hasher};
34use derive_where::derive_where;
5#[cfg(feature = "nightly")]
6use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
78use crate::fold::TypeFoldable;
9use crate::inherent::*;
10use crate::relate::RelateResult;
11use crate::relate::combine::PredicateEmittingRelation;
12use crate::solve::VisibleForLeakCheck;
13use crate::{selfas ty, Interner, TyVid};
1415mod private {
16pub trait Sealed {}
1718impl Sealedfor super::CantBeErased {}
19impl Sealedfor super::MayBeErased {}
20}
21pub trait TypingModeErasedStatus: private::Sealed + Clone + Copy + Hash + fmt::Debug {}
2223#[derive(#[automatically_derived]
impl ::core::clone::Clone for CantBeErased {
#[inline]
fn clone(&self) -> CantBeErased { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CantBeErased { }Copy, #[automatically_derived]
impl ::core::hash::Hash for CantBeErased {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
match *self {}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CantBeErased {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match *self {}
}
}Debug)]
24pub enum CantBeErased {}
25#[derive(#[automatically_derived]
impl ::core::clone::Clone for MayBeErased {
#[inline]
fn clone(&self) -> MayBeErased { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MayBeErased { }Copy, #[automatically_derived]
impl ::core::hash::Hash for MayBeErased {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for MayBeErased {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "MayBeErased")
}
}Debug)]
26#[cfg_attr(
27 feature = "nightly",
28 derive(const _: () =
{
impl<__E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for MayBeErased {
fn encode(&self, __encoder: &mut __E) {
match *self { MayBeErased => {} }
}
}
};Encodable_NoContext, const _: () =
{
impl<__D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for MayBeErased {
fn decode(__decoder: &mut __D) -> Self { MayBeErased }
}
};Decodable_NoContext, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for MayBeErased
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self { MayBeErased => {} }
}
}
};StableHash_NoContext)
29)]
30pub struct MayBeErased;
3132impl TypingModeErasedStatusfor CantBeErased {}
33impl TypingModeErasedStatusfor MayBeErased {}
3435/// The current typing mode of an inference context. We unfortunately have some
36/// slightly different typing rules depending on the current context. See the
37/// doc comment for each variant for how and why they are used.
38///
39/// In most cases you can get the correct typing mode automatically via:
40/// - `mir::Body::typing_mode`
41/// - `rustc_lint::LateContext::typing_mode`
42///
43/// If neither of these functions are available, feel free to reach out to
44/// t-types for help.
45///
46/// Because typing rules get subtly different based on what typing mode we're in,
47/// subtle enough that changing the behavior of typing modes can sometimes cause
48/// changes that we don't even have tests for, we'd like to enforce the rule that
49/// any place where we specialize behavior based on the typing mode, we match
50/// *exhaustively* on the typing mode. That way, it's easy to determine all the
51/// places that must change when anything about typing modes changes.
52///
53/// Hence, `TypingMode` does not implement `Eq`, though [`TypingModeEqWrapper`] is available
54/// in the rare case that you do need this. Most cases where this currently matters is
55/// where we pass typing modes through the query system and want to cache based on it.
56/// See also `#[rustc_must_match_exhaustively]`, which tries to detect non-exhaustive
57/// matches.
58///
59/// Since matching on typing mode to single out `Coherence` is so common, and `Coherence`
60/// is so different from the other modes: see also [`is_coherence`](TypingMode::is_coherence)
61#[automatically_derived]
impl<I: Interner, S: TypingModeErasedStatus> ::core::fmt::Debug for
TypingMode<I, S> where I: Interner {
fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
-> ::core::fmt::Result {
match self {
TypingMode::Coherence =>
::core::fmt::Formatter::write_str(__f, "Coherence"),
TypingMode::Analysis {
defining_opaque_types_and_generators: ref __field_defining_opaque_types_and_generators
} => {
let mut __builder =
::core::fmt::Formatter::debug_struct(__f, "Analysis");
::core::fmt::DebugStruct::field(&mut __builder,
"defining_opaque_types_and_generators",
__field_defining_opaque_types_and_generators);
::core::fmt::DebugStruct::finish(&mut __builder)
}
TypingMode::Borrowck {
defining_opaque_types: ref __field_defining_opaque_types } =>
{
let mut __builder =
::core::fmt::Formatter::debug_struct(__f, "Borrowck");
::core::fmt::DebugStruct::field(&mut __builder,
"defining_opaque_types", __field_defining_opaque_types);
::core::fmt::DebugStruct::finish(&mut __builder)
}
TypingMode::PostBorrowckAnalysis {
defined_opaque_types: ref __field_defined_opaque_types } => {
let mut __builder =
::core::fmt::Formatter::debug_struct(__f,
"PostBorrowckAnalysis");
::core::fmt::DebugStruct::field(&mut __builder,
"defined_opaque_types", __field_defined_opaque_types);
::core::fmt::DebugStruct::finish(&mut __builder)
}
TypingMode::PostAnalysis =>
::core::fmt::Formatter::write_str(__f, "PostAnalysis"),
TypingMode::Codegen =>
::core::fmt::Formatter::write_str(__f, "Codegen"),
TypingMode::ErasedNotCoherence(ref __field_0) => {
let mut __builder =
::core::fmt::Formatter::debug_tuple(__f,
"ErasedNotCoherence");
::core::fmt::DebugTuple::field(&mut __builder, __field_0);
::core::fmt::DebugTuple::finish(&mut __builder)
}
}
}
}#[derive_where(Clone, Copy, Hash, Debug; I: Interner)]62#[cfg_attr(
63 feature = "nightly",
64 derive(const _: () =
{
impl<I: Interner, S: TypingModeErasedStatus,
__E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<__E>
for TypingMode<I, S> where
I::LocalDefIds: ::rustc_serialize::Encodable<__E>,
S: ::rustc_serialize::Encodable<__E> {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
TypingMode::Coherence => { 0usize }
TypingMode::Analysis {
defining_opaque_types_and_generators: ref __binding_0 } => {
1usize
}
TypingMode::Borrowck {
defining_opaque_types: ref __binding_0 } => {
2usize
}
TypingMode::PostBorrowckAnalysis {
defined_opaque_types: ref __binding_0 } => {
3usize
}
TypingMode::PostAnalysis => { 4usize }
TypingMode::Codegen => { 5usize }
TypingMode::ErasedNotCoherence(ref __binding_0) => {
6usize
}
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
TypingMode::Coherence => {}
TypingMode::Analysis {
defining_opaque_types_and_generators: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
TypingMode::Borrowck {
defining_opaque_types: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
TypingMode::PostBorrowckAnalysis {
defined_opaque_types: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
TypingMode::PostAnalysis => {}
TypingMode::Codegen => {}
TypingMode::ErasedNotCoherence(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<I: Interner, S: TypingModeErasedStatus,
__D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<__D>
for TypingMode<I, S> where
I::LocalDefIds: ::rustc_serialize::Decodable<__D>,
S: ::rustc_serialize::Decodable<__D> {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { TypingMode::Coherence }
1usize => {
TypingMode::Analysis {
defining_opaque_types_and_generators: ::rustc_serialize::Decodable::decode(__decoder),
}
}
2usize => {
TypingMode::Borrowck {
defining_opaque_types: ::rustc_serialize::Decodable::decode(__decoder),
}
}
3usize => {
TypingMode::PostBorrowckAnalysis {
defined_opaque_types: ::rustc_serialize::Decodable::decode(__decoder),
}
}
4usize => { TypingMode::PostAnalysis }
5usize => { TypingMode::Codegen }
6usize => {
TypingMode::ErasedNotCoherence(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `TypingMode`, expected 0..7, actual {0}",
n));
}
}
}
}
};Decodable_NoContext, const _: () =
{
impl<I: Interner, S: TypingModeErasedStatus>
::rustc_data_structures::stable_hash::StableHash for
TypingMode<I, S> where
I::LocalDefIds: ::rustc_data_structures::stable_hash::StableHash,
S: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
TypingMode::Coherence => {}
TypingMode::Analysis {
defining_opaque_types_and_generators: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
TypingMode::Borrowck {
defining_opaque_types: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
TypingMode::PostBorrowckAnalysis {
defined_opaque_types: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
TypingMode::PostAnalysis => {}
TypingMode::Codegen => {}
TypingMode::ErasedNotCoherence(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash_NoContext)
65)]
66#[cfg_attr(feature = "nightly", rustc_must_match_exhaustively)]
67pub enum TypingMode<I: Interner, S: TypingModeErasedStatus = MayBeErased> {
68/// When checking whether impls overlap, we check whether any obligations
69 /// are guaranteed to never hold when unifying the impls. This requires us
70 /// to be complete: we must never fail to prove something which may actually
71 /// hold.
72 ///
73 /// In this typing mode we bail with ambiguity in case its not knowable
74 /// whether a trait goal may hold, e.g. because the trait may get implemented
75 /// in a downstream or sibling crate.
76 ///
77 /// We also have to be careful when generalizing aliases inside of higher-ranked
78 /// types to not unnecessarily constrain any inference variables.
79Coherence,
80/// Analysis includes type inference, checking that items are well-formed, and
81 /// pretty much everything else which may emit proper type errors to the user.
82 ///
83 /// We only normalize opaque types which may get defined by the current body,
84 /// which are stored in `defining_opaque_types`.
85 ///
86 /// We also refuse to project any associated type that is marked `default`.
87 /// Non-`default` ("final") types are always projected. This is necessary in
88 /// general for soundness of specialization. However, we *could* allow projections
89 /// in fully-monomorphic cases. We choose not to, because we prefer for `default type`
90 /// to force the type definition to be treated abstractly by any consumers of the
91 /// impl. Concretely, that means that the following example will
92 /// fail to compile:
93 ///
94 /// ```compile_fail,E0308
95 /// #![feature(specialization)]
96 /// trait Assoc {
97 /// type Output;
98 /// }
99 ///
100 /// impl<T> Assoc for T {
101 /// default type Output = bool;
102 /// }
103 ///
104 /// fn main() {
105 /// let x: <() as Assoc>::Output = true;
106 /// }
107 /// ```
108Analysis { defining_opaque_types_and_generators: I::LocalDefIds },
109/// The behavior during MIR borrowck is identical to `TypingMode::Analysis`
110 /// except that the initial value for opaque types is the type computed during
111 /// HIR typeck with unique unconstrained region inference variables.
112 ///
113 /// This is currently only used with by the new solver as it results in new
114 /// non-universal defining uses of opaque types, which is a breaking change.
115 /// See tests/ui/impl-trait/non-defining-use/as-projection-term.rs.
116Borrowck { defining_opaque_types: I::LocalDefIds },
117/// Any analysis after borrowck for a given body should be able to use all the
118 /// hidden types defined by borrowck, without being able to define any new ones.
119 ///
120 /// This is currently only used by the new solver, but should be implemented in
121 /// the old solver as well.
122PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
123/// After analysis, mostly during MIR optimizations, we're able to
124 /// reveal all opaque types. As the hidden type should *never* be observable
125 /// directly by the user, this should not be used by checks which may expose
126 /// such details to the user.
127 ///
128 /// However, we restrict `layout_of` and const-evaluation from exposing some information like
129 /// coroutine layout which requires optimized MIR.
130PostAnalysis,
131132/// During codegen and MIR optimizations, we're able to reveal all opaque types and compute all
133 /// layouts.
134Codegen,
135136/// The typing modes above (except coherence) only differ in how they handle
137 ///
138 /// - Generators
139 /// - Opaque types
140 /// - Specialization (in `PostAnalysis`)
141 ///
142 /// We replace all of them with this `TypingMode` in the first attempt at canonicalization.
143 /// If, during that attempt, we try to access information about opaques or generators
144 /// we bail out, setting a field on `EvalCtxt` that indicates the canonicalization must be
145 /// rerun in the original typing mode.
146 ///
147 /// `TypingMode::Coherence` is not replaced by this and is always kept as-is.
148ErasedNotCoherence(S),
149}
150151/// We want to highly discourage using equality checks on typing modes.
152/// Instead you should match, **exhaustively**, so when we ever modify the enum we get a compile
153/// error. Only use `TypingModeEqWrapper` when you really really really have to.
154/// Prefer unwrapping `TypingModeEqWrapper` in apis that should return a `TypingMode` whenever
155/// possible, and if you ever get an `TypingModeEqWrapper`, prefer unwrapping it and matching on it **exhaustively**.
156#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for TypingModeEqWrapper<I> where
I: Interner {
fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
-> ::core::fmt::Result {
match self {
TypingModeEqWrapper(ref __field_0) => {
let mut __builder =
::core::fmt::Formatter::debug_tuple(__f,
"TypingModeEqWrapper");
::core::fmt::DebugTuple::field(&mut __builder, __field_0);
::core::fmt::DebugTuple::finish(&mut __builder)
}
}
}
}#[derive_where(Clone, Copy, Debug; I: Interner)]157#[cfg_attr(
158 feature = "nightly",
159 derive(const _: () =
{
impl<I: Interner, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for TypingModeEqWrapper<I> where
TypingMode<I, MayBeErased>: ::rustc_serialize::Encodable<__E> {
fn encode(&self, __encoder: &mut __E) {
match *self {
TypingModeEqWrapper(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<I: Interner, __D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for TypingModeEqWrapper<I> where
TypingMode<I, MayBeErased>: ::rustc_serialize::Decodable<__D> {
fn decode(__decoder: &mut __D) -> Self {
TypingModeEqWrapper(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable_NoContext, const _: () =
{
impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
TypingModeEqWrapper<I> where
TypingMode<I,
MayBeErased>: ::rustc_data_structures::stable_hash::StableHash {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
TypingModeEqWrapper(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash_NoContext)
160)]
161pub struct TypingModeEqWrapper<I: Interner>(pub TypingMode<I, MayBeErased>);
162163impl<I: Interner> Hashfor TypingModeEqWrapper<I> {
164fn hash<H: Hasher>(&self, state: &mut H) {
165self.0.hash(state);
166 }
167}
168169impl<I: Interner> PartialEqfor TypingModeEqWrapper<I> {
170fn eq(&self, other: &Self) -> bool {
171match (self.0, other.0) {
172 (TypingMode::Coherence, TypingMode::Coherence) => true,
173 (
174 TypingMode::Analysis { defining_opaque_types_and_generators: l },
175 TypingMode::Analysis { defining_opaque_types_and_generators: r },
176 ) => l == r,
177 (
178 TypingMode::Borrowck { defining_opaque_types: l },
179 TypingMode::Borrowck { defining_opaque_types: r },
180 ) => l == r,
181 (
182 TypingMode::PostBorrowckAnalysis { defined_opaque_types: l },
183 TypingMode::PostBorrowckAnalysis { defined_opaque_types: r },
184 ) => l == r,
185 (TypingMode::PostAnalysis, TypingMode::PostAnalysis) => true,
186 (TypingMode::Codegen, TypingMode::Codegen) => true,
187 (
188 TypingMode::ErasedNotCoherence(MayBeErased),
189 TypingMode::ErasedNotCoherence(MayBeErased),
190 ) => true,
191 (
192 TypingMode::Coherence193 | TypingMode::Analysis { .. }
194 | TypingMode::Borrowck { .. }
195 | TypingMode::PostBorrowckAnalysis { .. }
196 | TypingMode::PostAnalysis197 | TypingMode::Codegen198 | TypingMode::ErasedNotCoherence(MayBeErased),
199_,
200 ) => false,
201 }
202 }
203}
204205impl<I: Interner> Eqfor TypingModeEqWrapper<I> {}
206207impl<I: Interner, S: TypingModeErasedStatus> TypingMode<I, S> {
208/// There are a bunch of places in the compiler where we single out `Coherence`,
209 /// and alter behavior. We'd like to *always* match on `TypingMode` exhaustively,
210 /// but not having this method leads to a bunch of noisy code.
211 ///
212 /// See also the documentation on [`TypingMode`] about exhaustive matching.
213pub fn is_coherence(&self) -> bool {
214match self {
215 TypingMode::Coherence => true,
216 TypingMode::Analysis { .. }
217 | TypingMode::Borrowck { .. }
218 | TypingMode::PostBorrowckAnalysis { .. }
219 | TypingMode::PostAnalysis220 | TypingMode::Codegen221 | TypingMode::ErasedNotCoherence(_) => false,
222 }
223 }
224225/// There are a bunch of places in the trait solver where we single out `Coherence`,
226 /// and alter behavior. We'd like to *always* match on `TypingMode` exhaustively,
227 /// but not having this method leads to a bunch of noisy code.
228 ///
229 /// See also the documentation on [`TypingMode`] about exhaustive matching.
230pub fn is_erased_not_coherence(&self) -> bool {
231match self {
232 TypingMode::ErasedNotCoherence(_) => true,
233 TypingMode::Coherence234 | TypingMode::Analysis { .. }
235 | TypingMode::Borrowck { .. }
236 | TypingMode::PostBorrowckAnalysis { .. }
237 | TypingMode::PostAnalysis238 | TypingMode::Codegen => false,
239 }
240 }
241}
242243impl<I: Interner> TypingMode<I, MayBeErased> {
244/// Only call this when you're sure you're outside the next trait solver!
245 /// That means either not in the trait solver, or in code that is old-solver only.
246 ///
247 /// See the comment on `InferCtxt::typing_mode_raw`
248pub fn assert_not_erased(self) -> TypingMode<I, CantBeErased> {
249match self {
250 TypingMode::Coherence => TypingMode::Coherence,
251 TypingMode::Analysis { defining_opaque_types_and_generators } => {
252 TypingMode::Analysis { defining_opaque_types_and_generators }
253 }
254 TypingMode::Borrowck { defining_opaque_types } => {
255 TypingMode::Borrowck { defining_opaque_types }
256 }
257 TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
258 TypingMode::PostBorrowckAnalysis { defined_opaque_types }
259 }
260 TypingMode::PostAnalysis => TypingMode::PostAnalysis,
261 TypingMode::Codegen => TypingMode::Codegen,
262 TypingMode::ErasedNotCoherence(MayBeErased) => {
::core::panicking::panic_fmt(format_args!("Called `assert_not_erased` from a place that can be called by the trait solver in `TypingMode::ErasedNotCoherence`. `TypingMode` is `ErasedNotCoherence` in a place where that should be impossible"));
}panic!(
263"Called `assert_not_erased` from a place that can be called by the trait solver in `TypingMode::ErasedNotCoherence`. `TypingMode` is `ErasedNotCoherence` in a place where that should be impossible"
264),
265 }
266 }
267}
268269impl<I: Interner> TypingMode<I, CantBeErased> {
270/// Analysis outside of a body does not define any opaque types.
271pub fn non_body_analysis() -> TypingMode<I> {
272 TypingMode::Analysis { defining_opaque_types_and_generators: Default::default() }
273 }
274275pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
276 TypingMode::Analysis {
277 defining_opaque_types_and_generators: cx278 .opaque_types_and_coroutines_defined_by(body_def_id),
279 }
280 }
281282/// While typechecking a body, we need to be able to define the opaque
283 /// types defined by that body.
284 ///
285 /// FIXME: This will be removed because it's generally not correct to define
286 /// opaques outside of HIR typeck.
287pub fn analysis_in_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
288 TypingMode::Analysis {
289 defining_opaque_types_and_generators: cx.opaque_types_defined_by(body_def_id),
290 }
291 }
292293pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
294let defining_opaque_types = cx.opaque_types_defined_by(body_def_id);
295if defining_opaque_types.is_empty() {
296TypingMode::non_body_analysis()
297 } else {
298 TypingMode::Borrowck { defining_opaque_types }
299 }
300 }
301302pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
303let defined_opaque_types = cx.opaque_types_defined_by(body_def_id);
304if defined_opaque_types.is_empty() {
305TypingMode::non_body_analysis()
306 } else {
307 TypingMode::PostBorrowckAnalysis { defined_opaque_types }
308 }
309 }
310}
311312impl<I: Interner> From<TypingMode<I, CantBeErased>> for TypingMode<I, MayBeErased> {
313fn from(value: TypingMode<I, CantBeErased>) -> Self {
314match value {
315 TypingMode::Coherence => TypingMode::Coherence,
316 TypingMode::Analysis { defining_opaque_types_and_generators } => {
317 TypingMode::Analysis { defining_opaque_types_and_generators }
318 }
319 TypingMode::Borrowck { defining_opaque_types } => {
320 TypingMode::Borrowck { defining_opaque_types }
321 }
322 TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
323 TypingMode::PostBorrowckAnalysis { defined_opaque_types }
324 }
325 TypingMode::PostAnalysis => TypingMode::PostAnalysis,
326 TypingMode::Codegen => TypingMode::Codegen,
327 }
328 }
329}
330331#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_infer_ctxt_like")]
332pub trait InferCtxtLike: Sized {
333type Interner: Interner;
334fn cx(&self) -> Self::Interner;
335336/// Whether the new trait solver is enabled. This only exists because rustc
337 /// shares code between the new and old trait solvers; for all other users,
338 /// this should always be true. If this is unknowingly false and you try to
339 /// use the new trait solver, things will break badly.
340fn next_trait_solver(&self) -> bool {
341true
342}
343344fn disable_trait_solver_fast_paths(&self) -> bool;
345346fn typing_mode_raw(&self) -> TypingMode<Self::Interner>;
347348fn universe(&self) -> ty::UniverseIndex;
349fn create_next_universe(&self) -> ty::UniverseIndex;
350351fn insert_placeholder_assumptions(
352&self,
353 u: ty::UniverseIndex,
354 assumptions: Option<crate::region_constraint::Assumptions<Self::Interner>>,
355 );
356fn get_placeholder_assumptions(
357&self,
358 u: ty::UniverseIndex,
359 ) -> Option<crate::region_constraint::Assumptions<Self::Interner>>;
360fn get_solver_region_constraint(
361&self,
362 ) -> crate::region_constraint::RegionConstraint<Self::Interner>;
363fn overwrite_solver_region_constraint(
364&self,
365 constraint: crate::region_constraint::RegionConstraint<Self::Interner>,
366 );
367368fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
369fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
370fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
371372fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid;
373fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid;
374fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid;
375376fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty;
377fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty;
378fn opportunistic_resolve_float_var(
379&self,
380 vid: ty::FloatVid,
381 ) -> <Self::Interner as Interner>::Ty;
382fn opportunistic_resolve_ct_var(
383&self,
384 vid: ty::ConstVid,
385 ) -> <Self::Interner as Interner>::Const;
386fn opportunistic_resolve_lt_var(
387&self,
388 vid: ty::RegionVid,
389 ) -> <Self::Interner as Interner>::Region;
390391fn is_changed_arg(&self, arg: <Self::Interner as Interner>::GenericArg) -> bool;
392393fn next_region_infer(&self) -> <Self::Interner as Interner>::Region;
394fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty;
395fn next_const_infer(&self) -> <Self::Interner as Interner>::Const;
396fn fresh_args_for_item(
397&self,
398 def_id: <Self::Interner as Interner>::DefId,
399 ) -> <Self::Interner as Interner>::GenericArgs;
400401fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
402&self,
403 value: ty::Binder<Self::Interner, T>,
404 ) -> T;
405406fn enter_forall<T: TypeFoldable<Self::Interner>, U>(
407&self,
408 value: ty::Binder<Self::Interner, T>,
409 f: impl FnOnce(T) -> U,
410 ) -> U;
411412fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
413fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
414fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid);
415fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid);
416fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid);
417418fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
419&self,
420 relation: &mut R,
421 target_is_expected: bool,
422 target_vid: ty::TyVid,
423 instantiation_variance: ty::Variance,
424 source_ty: <Self::Interner as Interner>::Ty,
425 ) -> RelateResult<Self::Interner, ()>;
426fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue);
427fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue);
428fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
429&self,
430 relation: &mut R,
431 target_is_expected: bool,
432 target_vid: ty::ConstVid,
433 source_ct: <Self::Interner as Interner>::Const,
434 ) -> RelateResult<Self::Interner, ()>;
435436fn set_tainted_by_errors(&self, e: <Self::Interner as Interner>::ErrorGuaranteed);
437438fn shallow_resolve(
439&self,
440 ty: <Self::Interner as Interner>::Ty,
441 ) -> <Self::Interner as Interner>::Ty;
442fn shallow_resolve_const(
443&self,
444 ty: <Self::Interner as Interner>::Const,
445 ) -> <Self::Interner as Interner>::Const;
446447fn resolve_vars_if_possible<T>(&self, value: T) -> T
448where
449T: TypeFoldable<Self::Interner>;
450451fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
452453fn sub_regions(
454&self,
455 sub: <Self::Interner as Interner>::Region,
456 sup: <Self::Interner as Interner>::Region,
457 vis: VisibleForLeakCheck,
458 span: <Self::Interner as Interner>::Span,
459 );
460461fn equate_regions(
462&self,
463 a: <Self::Interner as Interner>::Region,
464 b: <Self::Interner as Interner>::Region,
465 vis: VisibleForLeakCheck,
466 span: <Self::Interner as Interner>::Span,
467 );
468469fn register_solver_region_constraint(
470&self,
471 c: crate::region_constraint::RegionConstraint<Self::Interner>,
472 );
473474fn register_ty_outlives(
475&self,
476 ty: <Self::Interner as Interner>::Ty,
477 r: <Self::Interner as Interner>::Region,
478 span: <Self::Interner as Interner>::Span,
479 );
480481type OpaqueTypeStorageEntries: OpaqueTypeStorageEntries;
482fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries;
483fn clone_opaque_types_lookup_table(
484&self,
485 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
486fn clone_duplicate_opaque_types(
487&self,
488 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
489fn clone_opaque_types_added_since(
490&self,
491 prev_entries: Self::OpaqueTypeStorageEntries,
492 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
493fn opaques_with_sub_unified_hidden_type(&self, ty: TyVid) -> Vec<ty::AliasTy<Self::Interner>>;
494495fn register_hidden_type_in_storage(
496&self,
497 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
498 hidden_ty: <Self::Interner as Interner>::Ty,
499 span: <Self::Interner as Interner>::Span,
500 ) -> Option<<Self::Interner as Interner>::Ty>;
501fn add_duplicate_opaque_type(
502&self,
503 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
504 hidden_ty: <Self::Interner as Interner>::Ty,
505 span: <Self::Interner as Interner>::Span,
506 );
507508fn reset_opaque_types(&self);
509}
510511pub fn may_use_unstable_feature<'a, I: Interner, Infcx>(
512 infcx: &'a Infcx,
513 param_env: I::ParamEnv,
514 symbol: I::Symbol,
515) -> bool516where
517Infcx: InferCtxtLike<Interner = I>,
518{
519// Iterate through all goals in param_env to find the one that has the same symbol.
520for pred in param_env.caller_bounds().iter() {
521if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
522if sym == symbol {
523return true;
524 }
525 }
526 }
527528// During codegen we must assume that all feature bounds hold as we may be
529 // monomorphizing a body from an upstream crate which had an unstable feature
530 // enabled that we do not.
531 //
532 // Coherence should already report overlap errors involving unstable impls
533 // as the affected code would otherwise break when stabilizing this feature.
534 // It is also easily possible to accidentally cause unsoundness this way as
535 // we have to always enable unstable impls during codegen.
536 //
537 // Return ambiguity can also prevent people from writing code which depends on inference guidance
538 // that might no longer work after the impl is stabilised,
539 // tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs is one of the example.
540 //
541 // Note: `feature_bound_holds_in_crate` does not consider a feature to be enabled
542 // if we are in std/core even if there is a corresponding `feature` attribute on the crate.
543544match infcx.typing_mode_raw().assert_not_erased() {
545 TypingMode::Coherence546 | TypingMode::Analysis { .. }
547 | TypingMode::Borrowck { .. }
548 | TypingMode::PostBorrowckAnalysis { .. }
549 | TypingMode::PostAnalysis => infcx.cx().features().feature_bound_holds_in_crate(symbol),
550 TypingMode::Codegen => true,
551 }
552}