1use std::hash::{Hash, Hasher};
23use derive_where::derive_where;
4#[cfg(feature = "nightly")]
5use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
67use crate::fold::TypeFoldable;
8use crate::inherent::*;
9use crate::relate::RelateResult;
10use crate::relate::combine::PredicateEmittingRelation;
11use crate::solve::VisibleForLeakCheck;
12use crate::{selfas ty, Interner, TyVid};
1314/// The current typing mode of an inference context. We unfortunately have some
15/// slightly different typing rules depending on the current context. See the
16/// doc comment for each variant for how and why they are used.
17///
18/// In most cases you can get the correct typing mode automatically via:
19/// - `mir::Body::typing_mode`
20/// - `rustc_lint::LateContext::typing_mode`
21///
22/// If neither of these functions are available, feel free to reach out to
23/// t-types for help.
24///
25/// Because typing rules get subtly different based on what typing mode we're in,
26/// subtle enough that changing the behavior of typing modes can sometimes cause
27/// changes that we don't even have tests for, we'd like to enforce the rule that
28/// any place where we specialize behavior based on the typing mode, we match
29/// *exhaustively* on the typing mode. That way, it's easy to determine all the
30/// places that must change when anything about typing modes changes.
31///
32/// Hence, `TypingMode` does not implement `Eq`, though [`TypingModeEqWrapper`] is available
33/// in the rare case that you do need this. Most cases where this currently matters is
34/// where we pass typing modes through the query system and want to cache based on it.
35/// See also `#[rustc_must_match_exhaustively]`, which tries to detect non-exhaustive
36/// matches.
37///
38/// Since matching on typing mode to single out `Coherence` is so common, and `Coherence`
39/// is so different from the other modes: see also [`is_coherence`](TypingMode::is_coherence)
40#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for TypingMode<I> 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"),
}
}
}#[derive_where(Clone, Copy, Hash, Debug; I: Interner)]41#[cfg_attr(
42 feature = "nightly",
43 derive(const _: () =
{
impl<I: Interner, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for TypingMode<I> where
I::LocalDefIds: ::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 }
};
::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 => {}
}
}
}
};Encodable_NoContext, const _: () =
{
impl<I: Interner, __D: ::rustc_serialize::Decoder>
::rustc_serialize::Decodable<__D> for TypingMode<I> where
I::LocalDefIds: ::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 }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `TypingMode`, expected 0..5, actual {0}",
n));
}
}
}
}
};Decodable_NoContext, const _: () =
{
impl<I: Interner> ::rustc_data_structures::stable_hasher::StableHash
for TypingMode<I> where
I::LocalDefIds: ::rustc_data_structures::stable_hasher::StableHash
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hasher::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 => {}
}
}
}
};StableHash_NoContext)
44)]
45#[cfg_attr(feature = "nightly", rustc_must_match_exhaustively)]
46pub enum TypingMode<I: Interner> {
47/// When checking whether impls overlap, we check whether any obligations
48 /// are guaranteed to never hold when unifying the impls. This requires us
49 /// to be complete: we must never fail to prove something which may actually
50 /// hold.
51 ///
52 /// In this typing mode we bail with ambiguity in case its not knowable
53 /// whether a trait goal may hold, e.g. because the trait may get implemented
54 /// in a downstream or sibling crate.
55 ///
56 /// We also have to be careful when generalizing aliases inside of higher-ranked
57 /// types to not unnecessarily constrain any inference variables.
58Coherence,
59/// Analysis includes type inference, checking that items are well-formed, and
60 /// pretty much everything else which may emit proper type errors to the user.
61 ///
62 /// We only normalize opaque types which may get defined by the current body,
63 /// which are stored in `defining_opaque_types`.
64 ///
65 /// We also refuse to project any associated type that is marked `default`.
66 /// Non-`default` ("final") types are always projected. This is necessary in
67 /// general for soundness of specialization. However, we *could* allow projections
68 /// in fully-monomorphic cases. We choose not to, because we prefer for `default type`
69 /// to force the type definition to be treated abstractly by any consumers of the
70 /// impl. Concretely, that means that the following example will
71 /// fail to compile:
72 ///
73 /// ```compile_fail,E0308
74 /// #![feature(specialization)]
75 /// trait Assoc {
76 /// type Output;
77 /// }
78 ///
79 /// impl<T> Assoc for T {
80 /// default type Output = bool;
81 /// }
82 ///
83 /// fn main() {
84 /// let x: <() as Assoc>::Output = true;
85 /// }
86 /// ```
87Analysis { defining_opaque_types_and_generators: I::LocalDefIds },
88/// The behavior during MIR borrowck is identical to `TypingMode::Analysis`
89 /// except that the initial value for opaque types is the type computed during
90 /// HIR typeck with unique unconstrained region inference variables.
91 ///
92 /// This is currently only used with by the new solver as it results in new
93 /// non-universal defining uses of opaque types, which is a breaking change.
94 /// See tests/ui/impl-trait/non-defining-use/as-projection-term.rs.
95Borrowck { defining_opaque_types: I::LocalDefIds },
96/// Any analysis after borrowck for a given body should be able to use all the
97 /// hidden types defined by borrowck, without being able to define any new ones.
98 ///
99 /// This is currently only used by the new solver, but should be implemented in
100 /// the old solver as well.
101PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
102/// After analysis, mostly during codegen and MIR optimizations, we're able to
103 /// reveal all opaque types. As the hidden type should *never* be observable
104 /// directly by the user, this should not be used by checks which may expose
105 /// such details to the user.
106 ///
107 /// There are some exceptions to this as for example `layout_of` and const-evaluation
108 /// always run in `PostAnalysis` mode, even when used during analysis. This exposes
109 /// some information about the underlying type to users, but not the type itself.
110PostAnalysis,
111}
112113/// We want to highly discourage using equality checks on typing modes.
114/// Instead you should match, **exhaustively**, so when we ever modify the enum we get a compile
115/// error. Only use `TypingModeEqWrapper` when you really really really have to.
116/// Prefer unwrapping `TypingModeEqWrapper` in apis that should return a `TypingMode` whenever
117/// possible, and if you ever get an `TypingModeEqWrapper`, prefer unwrapping it and matching on it **exhaustively**.
118#[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)]119#[cfg_attr(
120 feature = "nightly",
121 derive(const _: () =
{
impl<I: Interner, __E: ::rustc_serialize::Encoder>
::rustc_serialize::Encodable<__E> for TypingModeEqWrapper<I> where
TypingMode<I>: ::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>: ::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_hasher::StableHash
for TypingModeEqWrapper<I> where
TypingMode<I>: ::rustc_data_structures::stable_hasher::StableHash
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hasher::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
TypingModeEqWrapper(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash_NoContext)
122)]
123pub struct TypingModeEqWrapper<I: Interner>(pub TypingMode<I>);
124125impl<I: Interner> Hashfor TypingModeEqWrapper<I> {
126fn hash<H: Hasher>(&self, state: &mut H) {
127self.0.hash(state);
128 }
129}
130131impl<I: Interner> PartialEqfor TypingModeEqWrapper<I> {
132fn eq(&self, other: &Self) -> bool {
133match (self.0, other.0) {
134 (TypingMode::Coherence, TypingMode::Coherence) => true,
135 (
136 TypingMode::Analysis { defining_opaque_types_and_generators: l },
137 TypingMode::Analysis { defining_opaque_types_and_generators: r },
138 ) => l == r,
139 (
140 TypingMode::Borrowck { defining_opaque_types: l },
141 TypingMode::Borrowck { defining_opaque_types: r },
142 ) => l == r,
143 (
144 TypingMode::PostBorrowckAnalysis { defined_opaque_types: l },
145 TypingMode::PostBorrowckAnalysis { defined_opaque_types: r },
146 ) => l == r,
147 (TypingMode::PostAnalysis, TypingMode::PostAnalysis) => true,
148 (
149 TypingMode::Coherence150 | TypingMode::Analysis { .. }
151 | TypingMode::Borrowck { .. }
152 | TypingMode::PostBorrowckAnalysis { .. }
153 | TypingMode::PostAnalysis,
154_,
155 ) => false,
156 }
157 }
158}
159160impl<I: Interner> Eqfor TypingModeEqWrapper<I> {}
161162impl<I: Interner> TypingMode<I> {
163/// There are a bunch of places in the compiler where we single out `Coherence`,
164 /// and alter behavior. We'd like to *always* match on `TypingMode` exhaustively,
165 /// but not having this method leads to a bunch of noisy code.
166 ///
167 /// See also the documentation on [`TypingMode`] about exhaustive matching.
168pub fn is_coherence(&self) -> bool {
169match self {
170 TypingMode::Coherence => true,
171 TypingMode::Analysis { .. }
172 | TypingMode::Borrowck { .. }
173 | TypingMode::PostBorrowckAnalysis { .. }
174 | TypingMode::PostAnalysis => false,
175 }
176 }
177178/// Analysis outside of a body does not define any opaque types.
179pub fn non_body_analysis() -> TypingMode<I> {
180 TypingMode::Analysis { defining_opaque_types_and_generators: Default::default() }
181 }
182183pub fn typeck_for_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
184 TypingMode::Analysis {
185 defining_opaque_types_and_generators: cx186 .opaque_types_and_coroutines_defined_by(body_def_id),
187 }
188 }
189190/// While typechecking a body, we need to be able to define the opaque
191 /// types defined by that body.
192 ///
193 /// FIXME: This will be removed because it's generally not correct to define
194 /// opaques outside of HIR typeck.
195pub fn analysis_in_body(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
196 TypingMode::Analysis {
197 defining_opaque_types_and_generators: cx.opaque_types_defined_by(body_def_id),
198 }
199 }
200201pub fn borrowck(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
202let defining_opaque_types = cx.opaque_types_defined_by(body_def_id);
203if defining_opaque_types.is_empty() {
204TypingMode::non_body_analysis()
205 } else {
206 TypingMode::Borrowck { defining_opaque_types }
207 }
208 }
209210pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I> {
211let defined_opaque_types = cx.opaque_types_defined_by(body_def_id);
212if defined_opaque_types.is_empty() {
213TypingMode::non_body_analysis()
214 } else {
215 TypingMode::PostBorrowckAnalysis { defined_opaque_types }
216 }
217 }
218}
219220#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_infer_ctxt_like")]
221pub trait InferCtxtLike: Sized {
222type Interner: Interner;
223fn cx(&self) -> Self::Interner;
224225/// Whether the new trait solver is enabled. This only exists because rustc
226 /// shares code between the new and old trait solvers; for all other users,
227 /// this should always be true. If this is unknowingly false and you try to
228 /// use the new trait solver, things will break badly.
229fn next_trait_solver(&self) -> bool {
230true
231}
232233fn typing_mode(&self) -> TypingMode<Self::Interner>;
234235fn universe(&self) -> ty::UniverseIndex;
236fn create_next_universe(&self) -> ty::UniverseIndex;
237238fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
239fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
240fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
241242fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid;
243fn sub_unification_table_root_var(&self, var: ty::TyVid) -> ty::TyVid;
244fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid;
245246fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> <Self::Interner as Interner>::Ty;
247fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> <Self::Interner as Interner>::Ty;
248fn opportunistic_resolve_float_var(
249&self,
250 vid: ty::FloatVid,
251 ) -> <Self::Interner as Interner>::Ty;
252fn opportunistic_resolve_ct_var(
253&self,
254 vid: ty::ConstVid,
255 ) -> <Self::Interner as Interner>::Const;
256fn opportunistic_resolve_lt_var(
257&self,
258 vid: ty::RegionVid,
259 ) -> <Self::Interner as Interner>::Region;
260261fn is_changed_arg(&self, arg: <Self::Interner as Interner>::GenericArg) -> bool;
262263fn next_region_infer(&self) -> <Self::Interner as Interner>::Region;
264fn next_ty_infer(&self) -> <Self::Interner as Interner>::Ty;
265fn next_const_infer(&self) -> <Self::Interner as Interner>::Const;
266fn fresh_args_for_item(
267&self,
268 def_id: <Self::Interner as Interner>::DefId,
269 ) -> <Self::Interner as Interner>::GenericArgs;
270271fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
272&self,
273 value: ty::Binder<Self::Interner, T>,
274 ) -> T;
275276fn enter_forall<T: TypeFoldable<Self::Interner>, U>(
277&self,
278 value: ty::Binder<Self::Interner, T>,
279 f: impl FnOnce(T) -> U,
280 ) -> U;
281282fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
283fn sub_unify_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid);
284fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid);
285fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid);
286fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid);
287288fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
289&self,
290 relation: &mut R,
291 target_is_expected: bool,
292 target_vid: ty::TyVid,
293 instantiation_variance: ty::Variance,
294 source_ty: <Self::Interner as Interner>::Ty,
295 ) -> RelateResult<Self::Interner, ()>;
296fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue);
297fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue);
298fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
299&self,
300 relation: &mut R,
301 target_is_expected: bool,
302 target_vid: ty::ConstVid,
303 source_ct: <Self::Interner as Interner>::Const,
304 ) -> RelateResult<Self::Interner, ()>;
305306fn set_tainted_by_errors(&self, e: <Self::Interner as Interner>::ErrorGuaranteed);
307308fn shallow_resolve(
309&self,
310 ty: <Self::Interner as Interner>::Ty,
311 ) -> <Self::Interner as Interner>::Ty;
312fn shallow_resolve_const(
313&self,
314 ty: <Self::Interner as Interner>::Const,
315 ) -> <Self::Interner as Interner>::Const;
316317fn resolve_vars_if_possible<T>(&self, value: T) -> T
318where
319T: TypeFoldable<Self::Interner>;
320321fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
322323fn sub_regions(
324&self,
325 sub: <Self::Interner as Interner>::Region,
326 sup: <Self::Interner as Interner>::Region,
327 vis: VisibleForLeakCheck,
328 span: <Self::Interner as Interner>::Span,
329 );
330331fn equate_regions(
332&self,
333 a: <Self::Interner as Interner>::Region,
334 b: <Self::Interner as Interner>::Region,
335 vis: VisibleForLeakCheck,
336 span: <Self::Interner as Interner>::Span,
337 );
338339fn register_ty_outlives(
340&self,
341 ty: <Self::Interner as Interner>::Ty,
342 r: <Self::Interner as Interner>::Region,
343 span: <Self::Interner as Interner>::Span,
344 );
345346type OpaqueTypeStorageEntries: OpaqueTypeStorageEntries;
347fn opaque_types_storage_num_entries(&self) -> Self::OpaqueTypeStorageEntries;
348fn clone_opaque_types_lookup_table(
349&self,
350 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
351fn clone_duplicate_opaque_types(
352&self,
353 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
354fn clone_opaque_types_added_since(
355&self,
356 prev_entries: Self::OpaqueTypeStorageEntries,
357 ) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
358fn opaques_with_sub_unified_hidden_type(&self, ty: TyVid) -> Vec<ty::AliasTy<Self::Interner>>;
359360fn register_hidden_type_in_storage(
361&self,
362 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
363 hidden_ty: <Self::Interner as Interner>::Ty,
364 span: <Self::Interner as Interner>::Span,
365 ) -> Option<<Self::Interner as Interner>::Ty>;
366fn add_duplicate_opaque_type(
367&self,
368 opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
369 hidden_ty: <Self::Interner as Interner>::Ty,
370 span: <Self::Interner as Interner>::Span,
371 );
372373fn reset_opaque_types(&self);
374}
375376pub fn may_use_unstable_feature<'a, I: Interner, Infcx>(
377 infcx: &'a Infcx,
378 param_env: I::ParamEnv,
379 symbol: I::Symbol,
380) -> bool381where
382Infcx: InferCtxtLike<Interner = I>,
383{
384// Iterate through all goals in param_env to find the one that has the same symbol.
385for pred in param_env.caller_bounds().iter() {
386if let ty::ClauseKind::UnstableFeature(sym) = pred.kind().skip_binder() {
387if sym == symbol {
388return true;
389 }
390 }
391 }
392393// During codegen we must assume that all feature bounds hold as we may be
394 // monomorphizing a body from an upstream crate which had an unstable feature
395 // enabled that we do not.
396 //
397 // Coherence should already report overlap errors involving unstable impls
398 // as the affected code would otherwise break when stabilizing this feature.
399 // It is also easily possible to accidentally cause unsoundness this way as
400 // we have to always enable unstable impls during codegen.
401 //
402 // Return ambiguity can also prevent people from writing code which depends on inference guidance
403 // that might no longer work after the impl is stabilised,
404 // tests/ui/unstable-feature-bound/unstable_impl_method_selection.rs is one of the example.
405 //
406 // Note: `feature_bound_holds_in_crate` does not consider a feature to be enabled
407 // if we are in std/core even if there is a corresponding `feature` attribute on the crate.
408409match infcx.typing_mode() {
410 TypingMode::Coherence411 | TypingMode::Analysis { .. }
412 | TypingMode::Borrowck { .. }
413 | TypingMode::PostBorrowckAnalysis { .. } => {
414infcx.cx().features().feature_bound_holds_in_crate(symbol)
415 }
416 TypingMode::PostAnalysis => true,
417 }
418}