From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_traits/src/type_op.rs | 59 +++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'compiler/rustc_traits/src/type_op.rs') diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 7f964afde..f35c5e448 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -4,8 +4,8 @@ use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable}; -use rustc_middle::ty::{ParamEnvAnd, Predicate, ToPredicate}; -use rustc_middle::ty::{UserSelfTy, UserSubsts}; +use rustc_middle::ty::{ParamEnvAnd, Predicate}; +use rustc_middle::ty::{UserSelfTy, UserSubsts, UserType}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; @@ -17,7 +17,6 @@ use rustc_trait_selection::traits::query::type_op::subtype::Subtype; use rustc_trait_selection::traits::query::{Fallible, NoSolution}; use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt}; use std::fmt; -use std::iter::zip; pub(crate) fn provide(p: &mut Providers) { *p = Providers { @@ -50,13 +49,46 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>( key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>, span: Option, ) -> Result<(), NoSolution> { - let (param_env, AscribeUserType { mir_ty, def_id, user_substs }) = key.into_parts(); - debug!( - "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}", - mir_ty, def_id, user_substs - ); + let (param_env, AscribeUserType { mir_ty, user_ty }) = key.into_parts(); + debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty); let span = span.unwrap_or(DUMMY_SP); + match user_ty { + UserType::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?, + UserType::TypeOf(def_id, user_substs) => { + relate_mir_and_user_substs(ocx, param_env, span, mir_ty, def_id, user_substs)? + } + }; + Ok(()) +} + +#[instrument(level = "debug", skip(ocx, param_env, span))] +fn relate_mir_and_user_ty<'tcx>( + ocx: &ObligationCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + span: Span, + mir_ty: Ty<'tcx>, + user_ty: Ty<'tcx>, +) -> Result<(), NoSolution> { + let cause = ObligationCause::dummy_with_span(span); + let user_ty = ocx.normalize(&cause, param_env, user_ty); + ocx.eq(&cause, param_env, mir_ty, user_ty)?; + // FIXME(#104764): We should check well-formedness before normalization. + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(user_ty.into())); + ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate)); + + Ok(()) +} + +#[instrument(level = "debug", skip(ocx, param_env, span))] +fn relate_mir_and_user_substs<'tcx>( + ocx: &ObligationCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + span: Span, + mir_ty: Ty<'tcx>, + def_id: hir::def_id::DefId, + user_substs: UserSubsts<'tcx>, +) -> Result<(), NoSolution> { let UserSubsts { user_self_ty, substs } = user_substs; let tcx = ocx.infcx.tcx; let cause = ObligationCause::dummy_with_span(span); @@ -75,9 +107,7 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>( let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); debug!(?instantiated_predicates); - for (instantiated_predicate, predicate_span) in - zip(instantiated_predicates.predicates, instantiated_predicates.spans) - { + for (instantiated_predicate, predicate_span) in instantiated_predicates { let span = if span == DUMMY_SP { predicate_span } else { span }; let cause = ObligationCause::new( span, @@ -91,13 +121,13 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>( } if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { + let self_ty = ocx.normalize(&cause, param_env, self_ty); let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs); let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty); ocx.eq(&cause, param_env, self_ty, impl_self_ty)?; - let predicate: Predicate<'tcx> = - ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into())).to_predicate(tcx); + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into())); ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate)); } @@ -112,8 +142,7 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>( // them? This would only be relevant if some input // type were ill-formed but did not appear in `ty`, // which...could happen with normalization... - let predicate: Predicate<'tcx> = - ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(tcx); + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())); ocx.register_obligation(Obligation::new(tcx, cause, param_env, predicate)); Ok(()) } -- cgit v1.2.3