rustc_infer/infer/relate/
generalize.rs

1use std::mem;
2
3use rustc_data_structures::sso::SsoHashMap;
4use rustc_data_structures::stack::ensure_sufficient_stack;
5use rustc_hir::def_id::DefId;
6use rustc_middle::bug;
7use rustc_middle::ty::error::TypeError;
8use rustc_middle::ty::{
9    self, AliasRelationDirection, InferConst, Term, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
10    TypeVisitableExt, TypeVisitor, TypingMode,
11};
12use rustc_span::Span;
13use tracing::{debug, instrument, warn};
14
15use super::{
16    PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation,
17};
18use crate::infer::type_variable::TypeVariableValue;
19use crate::infer::unify_key::ConstVariableValue;
20use crate::infer::{InferCtxt, RegionVariableOrigin, relate};
21
22#[derive(Copy, Clone, Eq, PartialEq, Debug)]
23enum TermVid {
24    Ty(ty::TyVid),
25    Const(ty::ConstVid),
26}
27
28impl From<ty::TyVid> for TermVid {
29    fn from(value: ty::TyVid) -> Self {
30        TermVid::Ty(value)
31    }
32}
33
34impl From<ty::ConstVid> for TermVid {
35    fn from(value: ty::ConstVid) -> Self {
36        TermVid::Const(value)
37    }
38}
39
40impl<'tcx> InferCtxt<'tcx> {
41    /// The idea is that we should ensure that the type variable `target_vid`
42    /// is equal to, a subtype of, or a supertype of `source_ty`.
43    ///
44    /// For this, we will instantiate `target_vid` with a *generalized* version
45    /// of `source_ty`. Generalization introduces other inference variables wherever
46    /// subtyping could occur. This also does the occurs checks, detecting whether
47    /// instantiating `target_vid` would result in a cyclic type. We eagerly error
48    /// in this case.
49    ///
50    /// This is *not* expected to be used anywhere except for an implementation of
51    /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
52    /// other usecases (i.e. setting the value of a type var).
53    #[instrument(level = "debug", skip(self, relation))]
54    pub fn instantiate_ty_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>(
55        &self,
56        relation: &mut R,
57        target_is_expected: bool,
58        target_vid: ty::TyVid,
59        instantiation_variance: ty::Variance,
60        source_ty: Ty<'tcx>,
61    ) -> RelateResult<'tcx, ()> {
62        debug_assert!(self.inner.borrow_mut().type_variables().probe(target_vid).is_unknown());
63
64        // Generalize `source_ty` depending on the current variance. As an example, assume
65        // `?target <: &'x ?1`, where `'x` is some free region and `?1` is an inference
66        // variable.
67        //
68        // Then the `generalized_ty` would be `&'?2 ?3`, where `'?2` and `?3` are fresh
69        // region/type inference variables.
70        //
71        // We then relate `generalized_ty <: source_ty`, adding constraints like `'x: '?2` and
72        // `?1 <: ?3`.
73        let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } = self
74            .generalize(
75                relation.span(),
76                relation.structurally_relate_aliases(),
77                target_vid,
78                instantiation_variance,
79                source_ty,
80            )?;
81
82        // Constrain `b_vid` to the generalized type `generalized_ty`.
83        if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
84            self.inner.borrow_mut().type_variables().equate(target_vid, generalized_vid);
85        } else {
86            self.inner.borrow_mut().type_variables().instantiate(target_vid, generalized_ty);
87        }
88
89        // See the comment on `Generalization::has_unconstrained_ty_var`.
90        if has_unconstrained_ty_var {
91            relation.register_predicates([ty::ClauseKind::WellFormed(generalized_ty.into())]);
92        }
93
94        // Finally, relate `generalized_ty` to `source_ty`, as described in previous comment.
95        //
96        // FIXME(#16847): This code is non-ideal because all these subtype
97        // relations wind up attributed to the same spans. We need
98        // to associate causes/spans with each of the relations in
99        // the stack to get this right.
100        if generalized_ty.is_ty_var() {
101            // This happens for cases like `<?0 as Trait>::Assoc == ?0`.
102            // We can't instantiate `?0` here as that would result in a
103            // cyclic type. We instead delay the unification in case
104            // the alias can be normalized to something which does not
105            // mention `?0`.
106            if self.next_trait_solver() {
107                let (lhs, rhs, direction) = match instantiation_variance {
108                    ty::Invariant => {
109                        (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
110                    }
111                    ty::Covariant => {
112                        (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype)
113                    }
114                    ty::Contravariant => {
115                        (source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype)
116                    }
117                    ty::Bivariant => unreachable!("bivariant generalization"),
118                };
119
120                relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
121            } else {
122                match source_ty.kind() {
123                    &ty::Alias(ty::Projection, data) => {
124                        // FIXME: This does not handle subtyping correctly, we could
125                        // instead create a new inference variable `?normalized_source`, emitting
126                        // `Projection(normalized_source, ?ty_normalized)` and
127                        // `?normalized_source <: generalized_ty`.
128                        relation.register_predicates([ty::ProjectionPredicate {
129                            projection_term: data.into(),
130                            term: generalized_ty.into(),
131                        }]);
132                    }
133                    // The old solver only accepts projection predicates for associated types.
134                    ty::Alias(ty::Inherent | ty::Free | ty::Opaque, _) => {
135                        return Err(TypeError::CyclicTy(source_ty));
136                    }
137                    _ => bug!("generalized `{source_ty:?} to infer, not an alias"),
138                }
139            }
140        } else {
141            // NOTE: The `instantiation_variance` is not the same variance as
142            // used by the relation. When instantiating `b`, `target_is_expected`
143            // is flipped and the `instantiation_variance` is also flipped. To
144            // constrain the `generalized_ty` while using the original relation,
145            // we therefore only have to flip the arguments.
146            //
147            // ```ignore (not code)
148            // ?a rel B
149            // instantiate_ty_var(?a, B) # expected and variance not flipped
150            // B' rel B
151            // ```
152            // or
153            // ```ignore (not code)
154            // A rel ?b
155            // instantiate_ty_var(?b, A) # expected and variance flipped
156            // A rel A'
157            // ```
158            if target_is_expected {
159                relation.relate(generalized_ty, source_ty)?;
160            } else {
161                debug!("flip relation");
162                relation.relate(source_ty, generalized_ty)?;
163            }
164        }
165
166        Ok(())
167    }
168
169    /// Instantiates the const variable `target_vid` with the given constant.
170    ///
171    /// This also tests if the given const `ct` contains an inference variable which was previously
172    /// unioned with `target_vid`. If this is the case, inferring `target_vid` to `ct`
173    /// would result in an infinite type as we continuously replace an inference variable
174    /// in `ct` with `ct` itself.
175    ///
176    /// This is especially important as unevaluated consts use their parents generics.
177    /// They therefore often contain unused args, making these errors far more likely.
178    ///
179    /// A good example of this is the following:
180    ///
181    /// ```compile_fail,E0308
182    /// #![feature(generic_const_exprs)]
183    ///
184    /// fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
185    ///     todo!()
186    /// }
187    ///
188    /// fn main() {
189    ///     let mut arr = Default::default();
190    ///     arr = bind(arr);
191    /// }
192    /// ```
193    ///
194    /// Here `3 + 4` ends up as `ConstKind::Unevaluated` which uses the generics
195    /// of `fn bind` (meaning that its args contain `N`).
196    ///
197    /// `bind(arr)` now infers that the type of `arr` must be `[u8; N]`.
198    /// The assignment `arr = bind(arr)` now tries to equate `N` with `3 + 4`.
199    ///
200    /// As `3 + 4` contains `N` in its args, this must not succeed.
201    ///
202    /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant.
203    #[instrument(level = "debug", skip(self, relation))]
204    pub(crate) fn instantiate_const_var<R: PredicateEmittingRelation<InferCtxt<'tcx>>>(
205        &self,
206        relation: &mut R,
207        target_is_expected: bool,
208        target_vid: ty::ConstVid,
209        source_ct: ty::Const<'tcx>,
210    ) -> RelateResult<'tcx, ()> {
211        // FIXME(generic_const_exprs): Occurs check failures for unevaluated
212        // constants and generic expressions are not yet handled correctly.
213        let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } = self
214            .generalize(
215                relation.span(),
216                relation.structurally_relate_aliases(),
217                target_vid,
218                ty::Invariant,
219                source_ct,
220            )?;
221
222        debug_assert!(!generalized_ct.is_ct_infer());
223        if has_unconstrained_ty_var {
224            bug!("unconstrained ty var when generalizing `{source_ct:?}`");
225        }
226
227        self.inner
228            .borrow_mut()
229            .const_unification_table()
230            .union_value(target_vid, ConstVariableValue::Known { value: generalized_ct });
231
232        // Make sure that the order is correct when relating the
233        // generalized const and the source.
234        if target_is_expected {
235            relation.relate_with_variance(
236                ty::Invariant,
237                ty::VarianceDiagInfo::default(),
238                generalized_ct,
239                source_ct,
240            )?;
241        } else {
242            relation.relate_with_variance(
243                ty::Invariant,
244                ty::VarianceDiagInfo::default(),
245                source_ct,
246                generalized_ct,
247            )?;
248        }
249
250        Ok(())
251    }
252
253    /// Attempts to generalize `source_term` for the type variable `target_vid`.
254    /// This checks for cycles -- that is, whether `source_term` references `target_vid`.
255    fn generalize<T: Into<Term<'tcx>> + Relate<TyCtxt<'tcx>>>(
256        &self,
257        span: Span,
258        structurally_relate_aliases: StructurallyRelateAliases,
259        target_vid: impl Into<TermVid>,
260        ambient_variance: ty::Variance,
261        source_term: T,
262    ) -> RelateResult<'tcx, Generalization<T>> {
263        assert!(!source_term.has_escaping_bound_vars());
264        let (for_universe, root_vid) = match target_vid.into() {
265            TermVid::Ty(ty_vid) => {
266                (self.probe_ty_var(ty_vid).unwrap_err(), TermVid::Ty(self.root_var(ty_vid)))
267            }
268            TermVid::Const(ct_vid) => (
269                self.probe_const_var(ct_vid).unwrap_err(),
270                TermVid::Const(self.inner.borrow_mut().const_unification_table().find(ct_vid).vid),
271            ),
272        };
273
274        let mut generalizer = Generalizer {
275            infcx: self,
276            span,
277            structurally_relate_aliases,
278            root_vid,
279            for_universe,
280            root_term: source_term.into(),
281            ambient_variance,
282            in_alias: false,
283            cache: Default::default(),
284            has_unconstrained_ty_var: false,
285        };
286
287        let value_may_be_infer = generalizer.relate(source_term, source_term)?;
288        let has_unconstrained_ty_var = generalizer.has_unconstrained_ty_var;
289        Ok(Generalization { value_may_be_infer, has_unconstrained_ty_var })
290    }
291}
292
293/// Finds the max universe present
294struct MaxUniverse {
295    max_universe: ty::UniverseIndex,
296}
297
298impl MaxUniverse {
299    fn new() -> Self {
300        MaxUniverse { max_universe: ty::UniverseIndex::ROOT }
301    }
302
303    fn max_universe(self) -> ty::UniverseIndex {
304        self.max_universe
305    }
306}
307
308impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
309    fn visit_ty(&mut self, t: Ty<'tcx>) {
310        if let ty::Placeholder(placeholder) = t.kind() {
311            self.max_universe = self.max_universe.max(placeholder.universe);
312        }
313
314        t.super_visit_with(self)
315    }
316
317    fn visit_const(&mut self, c: ty::Const<'tcx>) {
318        if let ty::ConstKind::Placeholder(placeholder) = c.kind() {
319            self.max_universe = self.max_universe.max(placeholder.universe);
320        }
321
322        c.super_visit_with(self)
323    }
324
325    fn visit_region(&mut self, r: ty::Region<'tcx>) {
326        if let ty::RePlaceholder(placeholder) = r.kind() {
327            self.max_universe = self.max_universe.max(placeholder.universe);
328        }
329    }
330}
331
332/// The "generalizer" is used when handling inference variables.
333///
334/// The basic strategy for handling a constraint like `?A <: B` is to
335/// apply a "generalization strategy" to the term `B` -- this replaces
336/// all the lifetimes in the term `B` with fresh inference variables.
337/// (You can read more about the strategy in this [blog post].)
338///
339/// As an example, if we had `?A <: &'x u32`, we would generalize `&'x
340/// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the
341/// value of `A`. Finally, we relate `&'0 u32 <: &'x u32`, which
342/// establishes `'0: 'x` as a constraint.
343///
344/// [blog post]: https://is.gd/0hKvIr
345struct Generalizer<'me, 'tcx> {
346    infcx: &'me InferCtxt<'tcx>,
347
348    span: Span,
349
350    /// Whether aliases should be related structurally. If not, we have to
351    /// be careful when generalizing aliases.
352    structurally_relate_aliases: StructurallyRelateAliases,
353
354    /// The vid of the type variable that is in the process of being
355    /// instantiated. If we find this within the value we are folding,
356    /// that means we would have created a cyclic value.
357    root_vid: TermVid,
358
359    /// The universe of the type variable that is in the process of being
360    /// instantiated. If we find anything that this universe cannot name,
361    /// we reject the relation.
362    for_universe: ty::UniverseIndex,
363
364    /// The root term (const or type) we're generalizing. Used for cycle errors.
365    root_term: Term<'tcx>,
366
367    /// After we generalize this type, we are going to relate it to
368    /// some other type. What will be the variance at this point?
369    ambient_variance: ty::Variance,
370
371    /// This is set once we're generalizing the arguments of an alias.
372    ///
373    /// This is necessary to correctly handle
374    /// `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`. This equality can
375    /// hold by either normalizing the outer or the inner associated type.
376    in_alias: bool,
377
378    cache: SsoHashMap<(Ty<'tcx>, ty::Variance, bool), Ty<'tcx>>,
379
380    /// See the field `has_unconstrained_ty_var` in `Generalization`.
381    has_unconstrained_ty_var: bool,
382}
383
384impl<'tcx> Generalizer<'_, 'tcx> {
385    /// Create an error that corresponds to the term kind in `root_term`
386    fn cyclic_term_error(&self) -> TypeError<'tcx> {
387        match self.root_term.kind() {
388            ty::TermKind::Ty(ty) => TypeError::CyclicTy(ty),
389            ty::TermKind::Const(ct) => TypeError::CyclicConst(ct),
390        }
391    }
392
393    /// Create a new type variable in the universe of the target when
394    /// generalizing an alias. This has to set `has_unconstrained_ty_var`
395    /// if we're currently in a bivariant context.
396    fn next_ty_var_for_alias(&mut self) -> Ty<'tcx> {
397        self.has_unconstrained_ty_var |= self.ambient_variance == ty::Bivariant;
398        self.infcx.next_ty_var_in_universe(self.span, self.for_universe)
399    }
400
401    /// An occurs check failure inside of an alias does not mean
402    /// that the types definitely don't unify. We may be able
403    /// to normalize the alias after all.
404    ///
405    /// We handle this by lazily equating the alias and generalizing
406    /// it to an inference variable. In the new solver, we always
407    /// generalize to an infer var unless the alias contains escaping
408    /// bound variables.
409    ///
410    /// Correctly handling aliases with escaping bound variables is
411    /// difficult and currently incomplete in two opposite ways:
412    /// - if we get an occurs check failure in the alias, replace it with a new infer var.
413    ///   This causes us to later emit an alias-relate goal and is incomplete in case the
414    ///   alias normalizes to type containing one of the bound variables.
415    /// - if the alias contains an inference variable not nameable by `for_universe`, we
416    ///   continue generalizing the alias. This ends up pulling down the universe of the
417    ///   inference variable and is incomplete in case the alias would normalize to a type
418    ///   which does not mention that inference variable.
419    fn generalize_alias_ty(
420        &mut self,
421        alias: ty::AliasTy<'tcx>,
422    ) -> Result<Ty<'tcx>, TypeError<'tcx>> {
423        // We do not eagerly replace aliases with inference variables if they have
424        // escaping bound vars, see the method comment for details. However, when we
425        // are inside of an alias with escaping bound vars replacing nested aliases
426        // with inference variables can cause incorrect ambiguity.
427        //
428        // cc trait-system-refactor-initiative#110
429        if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias {
430            return Ok(self.next_ty_var_for_alias());
431        }
432
433        let is_nested_alias = mem::replace(&mut self.in_alias, true);
434        let result = match self.relate(alias, alias) {
435            Ok(alias) => Ok(alias.to_ty(self.cx())),
436            Err(e) => {
437                if is_nested_alias {
438                    return Err(e);
439                } else {
440                    let mut visitor = MaxUniverse::new();
441                    alias.visit_with(&mut visitor);
442                    let infer_replacement_is_complete =
443                        self.for_universe.can_name(visitor.max_universe())
444                            && !alias.has_escaping_bound_vars();
445                    if !infer_replacement_is_complete {
446                        warn!("may incompletely handle alias type: {alias:?}");
447                    }
448
449                    debug!("generalization failure in alias");
450                    Ok(self.next_ty_var_for_alias())
451                }
452            }
453        };
454        self.in_alias = is_nested_alias;
455        result
456    }
457}
458
459impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
460    fn cx(&self) -> TyCtxt<'tcx> {
461        self.infcx.tcx
462    }
463
464    fn relate_item_args(
465        &mut self,
466        item_def_id: DefId,
467        a_arg: ty::GenericArgsRef<'tcx>,
468        b_arg: ty::GenericArgsRef<'tcx>,
469    ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
470        if self.ambient_variance == ty::Invariant {
471            // Avoid fetching the variance if we are in an invariant
472            // context; no need, and it can induce dependency cycles
473            // (e.g., #41849).
474            relate::relate_args_invariantly(self, a_arg, b_arg)
475        } else {
476            let tcx = self.cx();
477            let opt_variances = tcx.variances_of(item_def_id);
478            relate::relate_args_with_variances(
479                self,
480                item_def_id,
481                opt_variances,
482                a_arg,
483                b_arg,
484                false,
485            )
486        }
487    }
488
489    #[instrument(level = "debug", skip(self, variance, b), ret)]
490    fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
491        &mut self,
492        variance: ty::Variance,
493        _info: ty::VarianceDiagInfo<TyCtxt<'tcx>>,
494        a: T,
495        b: T,
496    ) -> RelateResult<'tcx, T> {
497        let old_ambient_variance = self.ambient_variance;
498        self.ambient_variance = self.ambient_variance.xform(variance);
499        debug!(?self.ambient_variance, "new ambient variance");
500        // Recursive calls to `relate` can overflow the stack. For example a deeper version of
501        // `ui/associated-consts/issue-93775.rs`.
502        let r = ensure_sufficient_stack(|| self.relate(a, b));
503        self.ambient_variance = old_ambient_variance;
504        r
505    }
506
507    #[instrument(level = "debug", skip(self, t2), ret)]
508    fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
509        assert_eq!(t, t2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
510
511        if let Some(&result) = self.cache.get(&(t, self.ambient_variance, self.in_alias)) {
512            return Ok(result);
513        }
514
515        // Check to see whether the type we are generalizing references
516        // any other type variable related to `vid` via
517        // subtyping. This is basically our "occurs check", preventing
518        // us from creating infinitely sized types.
519        let g = match *t.kind() {
520            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
521                bug!("unexpected infer type: {t}")
522            }
523
524            ty::Infer(ty::TyVar(vid)) => {
525                let mut inner = self.infcx.inner.borrow_mut();
526                let vid = inner.type_variables().root_var(vid);
527                if TermVid::Ty(vid) == self.root_vid {
528                    // If sub-roots are equal, then `root_vid` and
529                    // `vid` are related via subtyping.
530                    Err(self.cyclic_term_error())
531                } else {
532                    let probe = inner.type_variables().probe(vid);
533                    match probe {
534                        TypeVariableValue::Known { value: u } => {
535                            drop(inner);
536                            self.relate(u, u)
537                        }
538                        TypeVariableValue::Unknown { universe } => {
539                            match self.ambient_variance {
540                                // Invariant: no need to make a fresh type variable
541                                // if we can name the universe.
542                                ty::Invariant => {
543                                    if self.for_universe.can_name(universe) {
544                                        return Ok(t);
545                                    }
546                                }
547
548                                // Bivariant: make a fresh var, but remember that
549                                // it is unconstrained. See the comment in
550                                // `Generalization`.
551                                ty::Bivariant => self.has_unconstrained_ty_var = true,
552
553                                // Co/contravariant: this will be
554                                // sufficiently constrained later on.
555                                ty::Covariant | ty::Contravariant => (),
556                            }
557
558                            let origin = inner.type_variables().var_origin(vid);
559                            let new_var_id =
560                                inner.type_variables().new_var(self.for_universe, origin);
561                            // Record that `vid` and `new_var_id` have to be subtypes
562                            // of each other. This is currently only used for diagnostics.
563                            // To see why, see the docs in the `type_variables` module.
564                            inner.type_variables().sub_unify(vid, new_var_id);
565                            // If we're in the new solver and create a new inference
566                            // variable inside of an alias we eagerly constrain that
567                            // inference variable to prevent unexpected ambiguity errors.
568                            //
569                            // This is incomplete as it pulls down the universe of the
570                            // original inference variable, even though the alias could
571                            // normalize to a type which does not refer to that type at
572                            // all. I don't expect this to cause unexpected errors in
573                            // practice.
574                            //
575                            // We only need to do so for type and const variables, as
576                            // region variables do not impact normalization, and will get
577                            // correctly constrained by `AliasRelate` later on.
578                            //
579                            // cc trait-system-refactor-initiative#108
580                            if self.infcx.next_trait_solver()
581                                && !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
582                                && self.in_alias
583                            {
584                                inner.type_variables().equate(vid, new_var_id);
585                            }
586
587                            debug!("replacing original vid={:?} with new={:?}", vid, new_var_id);
588                            Ok(Ty::new_var(self.cx(), new_var_id))
589                        }
590                    }
591                }
592            }
593
594            ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
595                // No matter what mode we are in,
596                // integer/floating-point types must be equal to be
597                // relatable.
598                Ok(t)
599            }
600
601            ty::Placeholder(placeholder) => {
602                if self.for_universe.can_name(placeholder.universe) {
603                    Ok(t)
604                } else {
605                    debug!(
606                        "root universe {:?} cannot name placeholder in universe {:?}",
607                        self.for_universe, placeholder.universe
608                    );
609                    Err(TypeError::Mismatch)
610                }
611            }
612
613            ty::Alias(_, data) => match self.structurally_relate_aliases {
614                StructurallyRelateAliases::No => self.generalize_alias_ty(data),
615                StructurallyRelateAliases::Yes => relate::structurally_relate_tys(self, t, t),
616            },
617
618            _ => relate::structurally_relate_tys(self, t, t),
619        }?;
620
621        self.cache.insert((t, self.ambient_variance, self.in_alias), g);
622        Ok(g)
623    }
624
625    #[instrument(level = "debug", skip(self, r2), ret)]
626    fn regions(
627        &mut self,
628        r: ty::Region<'tcx>,
629        r2: ty::Region<'tcx>,
630    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
631        assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
632
633        match r.kind() {
634            // Never make variables for regions bound within the type itself,
635            // nor for erased regions.
636            ty::ReBound(..) | ty::ReErased => {
637                return Ok(r);
638            }
639
640            // It doesn't really matter for correctness if we generalize ReError,
641            // since we're already on a doomed compilation path.
642            ty::ReError(_) => {
643                return Ok(r);
644            }
645
646            ty::RePlaceholder(..)
647            | ty::ReVar(..)
648            | ty::ReStatic
649            | ty::ReEarlyParam(..)
650            | ty::ReLateParam(..) => {
651                // see common code below
652            }
653        }
654
655        // If we are in an invariant context, we can re-use the region
656        // as is, unless it happens to be in some universe that we
657        // can't name.
658        if let ty::Invariant = self.ambient_variance {
659            let r_universe = self.infcx.universe_of_region(r);
660            if self.for_universe.can_name(r_universe) {
661                return Ok(r);
662            }
663        }
664
665        Ok(self
666            .infcx
667            .next_region_var_in_universe(RegionVariableOrigin::Misc(self.span), self.for_universe))
668    }
669
670    #[instrument(level = "debug", skip(self, c2), ret)]
671    fn consts(
672        &mut self,
673        c: ty::Const<'tcx>,
674        c2: ty::Const<'tcx>,
675    ) -> RelateResult<'tcx, ty::Const<'tcx>> {
676        assert_eq!(c, c2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==
677
678        match c.kind() {
679            ty::ConstKind::Infer(InferConst::Var(vid)) => {
680                // If root const vids are equal, then `root_vid` and
681                // `vid` are related and we'd be inferring an infinitely
682                // deep const.
683                if TermVid::Const(
684                    self.infcx.inner.borrow_mut().const_unification_table().find(vid).vid,
685                ) == self.root_vid
686                {
687                    return Err(self.cyclic_term_error());
688                }
689
690                let mut inner = self.infcx.inner.borrow_mut();
691                let variable_table = &mut inner.const_unification_table();
692                match variable_table.probe_value(vid) {
693                    ConstVariableValue::Known { value: u } => {
694                        drop(inner);
695                        self.relate(u, u)
696                    }
697                    ConstVariableValue::Unknown { origin, universe } => {
698                        if self.for_universe.can_name(universe) {
699                            Ok(c)
700                        } else {
701                            let new_var_id = variable_table
702                                .new_key(ConstVariableValue::Unknown {
703                                    origin,
704                                    universe: self.for_universe,
705                                })
706                                .vid;
707
708                            // See the comment for type inference variables
709                            // for more details.
710                            if self.infcx.next_trait_solver()
711                                && !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
712                                && self.in_alias
713                            {
714                                variable_table.union(vid, new_var_id);
715                            }
716                            Ok(ty::Const::new_var(self.cx(), new_var_id))
717                        }
718                    }
719                }
720            }
721            // FIXME: Unevaluated constants are also not rigid, so the current
722            // approach of always relating them structurally is incomplete.
723            //
724            // FIXME: remove this branch once `structurally_relate_consts` is fully
725            // structural.
726            ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
727                let args = self.relate_with_variance(
728                    ty::Invariant,
729                    ty::VarianceDiagInfo::default(),
730                    args,
731                    args,
732                )?;
733                Ok(ty::Const::new_unevaluated(self.cx(), ty::UnevaluatedConst { def, args }))
734            }
735            ty::ConstKind::Placeholder(placeholder) => {
736                if self.for_universe.can_name(placeholder.universe) {
737                    Ok(c)
738                } else {
739                    debug!(
740                        "root universe {:?} cannot name placeholder in universe {:?}",
741                        self.for_universe, placeholder.universe
742                    );
743                    Err(TypeError::Mismatch)
744                }
745            }
746            _ => relate::structurally_relate_consts(self, c, c),
747        }
748    }
749
750    #[instrument(level = "debug", skip(self), ret)]
751    fn binders<T>(
752        &mut self,
753        a: ty::Binder<'tcx, T>,
754        _: ty::Binder<'tcx, T>,
755    ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
756    where
757        T: Relate<TyCtxt<'tcx>>,
758    {
759        let result = self.relate(a.skip_binder(), a.skip_binder())?;
760        Ok(a.rebind(result))
761    }
762}
763
764/// Result from a generalization operation. This includes
765/// not only the generalized type, but also a bool flag
766/// indicating whether further WF checks are needed.
767#[derive(Debug)]
768struct Generalization<T> {
769    /// When generalizing `<?0 as Trait>::Assoc` or
770    /// `<T as Bar<<?0 as Foo>::Assoc>>::Assoc`
771    /// for `?0` generalization returns an inference
772    /// variable.
773    ///
774    /// This has to be handled wotj care as it can
775    /// otherwise very easily result in infinite
776    /// recursion.
777    pub value_may_be_infer: T,
778
779    /// In general, we do not check whether all types which occur during
780    /// type checking are well-formed. We only check wf of user-provided types
781    /// and when actually using a type, e.g. for method calls.
782    ///
783    /// This means that when subtyping, we may end up with unconstrained
784    /// inference variables if a generalized type has bivariant parameters.
785    /// A parameter may only be bivariant if it is constrained by a projection
786    /// bound in a where-clause. As an example, imagine a type:
787    ///
788    ///     struct Foo<A, B> where A: Iterator<Item = B> {
789    ///         data: A
790    ///     }
791    ///
792    /// here, `A` will be covariant, but `B` is unconstrained.
793    ///
794    /// However, whatever it is, for `Foo` to be WF, it must be equal to `A::Item`.
795    /// If we have an input `Foo<?A, ?B>`, then after generalization we will wind
796    /// up with a type like `Foo<?C, ?D>`. When we enforce `Foo<?A, ?B> <: Foo<?C, ?D>`,
797    /// we will wind up with the requirement that `?A <: ?C`, but no particular
798    /// relationship between `?B` and `?D` (after all, these types may be completely
799    /// different). If we do nothing else, this may mean that `?D` goes unconstrained
800    /// (as in #41677). To avoid this we emit a `WellFormed` obligation in these cases.
801    pub has_unconstrained_ty_var: bool,
802}