diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:11:28 +0000 |
commit | 94a0819fe3a0d679c3042a77bfe6a2afc505daea (patch) | |
tree | 2b827afe6a05f3538db3f7803a88c4587fe85648 /compiler/rustc_infer/src/infer/sub.rs | |
parent | Adding upstream version 1.64.0+dfsg1. (diff) | |
download | rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.tar.xz rustc-94a0819fe3a0d679c3042a77bfe6a2afc505daea.zip |
Adding upstream version 1.66.0+dfsg1.upstream/1.66.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_infer/src/infer/sub.rs | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index b27571275..97354ba5d 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -2,7 +2,6 @@ use super::combine::{CombineFields, RelationDir}; use super::SubregionOrigin; use crate::infer::combine::ConstEquateRelation; -use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::traits::Obligation; use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::TypeVisitable; @@ -11,8 +10,8 @@ use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use std::mem; /// Ensures `a` is made a subtype of `b`. Returns `a` on success. -pub struct Sub<'combine, 'infcx, 'tcx> { - fields: &'combine mut CombineFields<'infcx, 'tcx>, +pub struct Sub<'combine, 'a, 'tcx> { + fields: &'combine mut CombineFields<'a, 'tcx>, a_is_expected: bool, } @@ -129,30 +128,37 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if self.fields.define_opaque_types && did.is_local() => { - let mut generalize = |ty, ty_is_expected| { - let var = infcx.next_ty_var_id_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.fields.trace.cause.span, - }, - ty::UniverseIndex::ROOT, - ); - self.fields.instantiate(ty, RelationDir::SubtypeOf, var, ty_is_expected)?; - Ok(infcx.tcx.mk_ty_var(var)) - }; - let (a, b) = if self.a_is_expected { (a, b) } else { (b, a) }; - let (a, b) = match (a.kind(), b.kind()) { - (&ty::Opaque(..), _) => (a, generalize(b, true)?), - (_, &ty::Opaque(..)) => (generalize(a, false)?, b), - _ => unreachable!(), - }; self.fields.obligations.extend( infcx - .handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())? + .handle_opaque_type( + a, + b, + self.a_is_expected, + &self.fields.trace.cause, + self.param_env(), + )? .obligations, ); Ok(a) } + // Optimization of GeneratorWitness relation since we know that all + // free regions are replaced with bound regions during construction. + // This greatly speeds up subtyping of GeneratorWitness. + (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => { + let a_types = infcx.tcx.anonymize_bound_vars(a_types); + let b_types = infcx.tcx.anonymize_bound_vars(b_types); + if a_types.bound_vars() == b_types.bound_vars() { + let (a_types, b_types) = infcx.replace_bound_vars_with_placeholders( + a_types.map_bound(|a_types| (a_types, b_types.skip_binder())), + ); + for (a, b) in std::iter::zip(a_types, b_types) { + self.relate(a, b)?; + } + Ok(a) + } else { + Err(ty::error::TypeError::Sorts(ty::relate::expected_found(self, a, b))) + } + } _ => { self.fields.infcx.super_combine_tys(self, a, b)?; |