diff options
Diffstat (limited to 'compiler/rustc_traits')
-rw-r--r-- | compiler/rustc_traits/src/chalk/db.rs | 30 | ||||
-rw-r--r-- | compiler/rustc_traits/src/chalk/lowering.rs | 63 | ||||
-rw-r--r-- | compiler/rustc_traits/src/codegen.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_traits/src/dropck_outlives.rs | 8 | ||||
-rw-r--r-- | compiler/rustc_traits/src/implied_outlives_bounds.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_traits/src/normalize_erasing_regions.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_traits/src/type_op.rs | 59 |
7 files changed, 105 insertions, 70 deletions
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 344c8b93c..f146de396 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -7,7 +7,7 @@ //! `crate::chalk::lowering` (to lower rustc types into Chalk types). use rustc_middle::traits::ChalkRustInterner as RustInterner; -use rustc_middle::ty::{self, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_target::abi::{Integer, IntegerType}; @@ -38,13 +38,12 @@ impl<'tcx> RustIrDatabase<'tcx> { def_id: DefId, bound_vars: SubstsRef<'tcx>, ) -> Vec<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> { - let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates; - predicates - .iter() - .map(|(wc, _)| EarlyBinder(*wc).subst(self.interner.tcx, bound_vars)) - .filter_map(|wc| LowerInto::< - Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> - >::lower_into(wc, self.interner)).collect() + self.interner + .tcx + .predicates_defined_on(def_id) + .instantiate_own(self.interner.tcx, bound_vars) + .filter_map(|(wc, _)| LowerInto::lower_into(wc, self.interner)) + .collect() } fn bounds_for<T>(&self, def_id: DefId, bound_vars: SubstsRef<'tcx>) -> Vec<T> @@ -309,7 +308,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(self.interner, bound_vars); - let trait_ref = self.interner.tcx.bound_impl_trait_ref(def_id).expect("not an impl"); + let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl"); let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); let where_clauses = self.where_clauses_for(def_id, bound_vars); @@ -351,7 +350,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t let all_impls = self.interner.tcx.all_impls(def_id); let matched_impls = all_impls.filter(|impl_def_id| { use chalk_ir::could_match::CouldMatch; - let trait_ref = self.interner.tcx.bound_impl_trait_ref(*impl_def_id).unwrap(); + let trait_ref = self.interner.tcx.impl_trait_ref(*impl_def_id).unwrap(); let bound_vars = bound_vars_for_item(self.interner.tcx, *impl_def_id); let self_ty = trait_ref.map_bound(|t| t.self_ty()); @@ -380,7 +379,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t let trait_def_id = auto_trait_id.0; let all_impls = self.interner.tcx.all_impls(trait_def_id); for impl_def_id in all_impls { - let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(); let self_ty = trait_ref.self_ty(); let provides = match (self_ty.kind(), chalk_ty) { (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did() == id.0.did(), @@ -432,7 +431,10 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, } } - (&ty::Opaque(def_id, ..), OpaqueType(opaque_ty_id, ..)) => def_id == opaque_ty_id.0, + ( + &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), + OpaqueType(opaque_ty_id, ..), + ) => def_id == opaque_ty_id.0, (&ty::FnDef(def_id, ..), FnDef(fn_def_id, ..)) => def_id == fn_def_id.0, (&ty::Str, Str) => true, (&ty::Never, Never) => true, @@ -716,7 +718,7 @@ impl<'tcx> chalk_ir::UnificationDatabase<RustInterner<'tcx>> for RustIrDatabase< /// var bound at index `0`. For types, we use a `BoundVar` index equal to /// the type parameter index. For regions, we use the `BoundRegionKind::BrNamed` /// variant (which has a `DefId`). -fn bound_vars_for_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { +fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind { ty::GenericParamDefKind::Type { .. } => tcx .mk_ty(ty::Bound( @@ -786,7 +788,7 @@ impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> { } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Opaque(def_id, substs) = *ty.kind() { + if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) = *ty.kind() { if def_id == self.opaque_ty_id.0 && substs == self.identity_substs { return self.tcx.mk_ty(ty::Bound( self.binder_index, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index c4ab86e9e..9712abb70 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -66,15 +66,6 @@ impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInte } } -impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy<RustInterner<'tcx>>> for ty::ProjectionTy<'tcx> { - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::AliasTy<RustInterner<'tcx>> { - chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(self.item_def_id), - substitution: self.substs.lower_into(interner), - }) - } -} - impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>>> for ChalkEnvironmentAndGoal<'tcx> { @@ -255,7 +246,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>> // FIXME(associated_const_equality): teach chalk about terms for alias eq. chalk_ir::AliasEq { ty: self.term.ty().unwrap().lower_into(interner), - alias: self.projection_ty.lower_into(interner), + alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { + associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.def_id), + substitution: self.projection_ty.substs.lower_into(interner), + }), } } } @@ -353,8 +347,13 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { ty::Tuple(types) => { chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner)) } - ty::Projection(proj) => chalk_ir::TyKind::Alias(proj.lower_into(interner)), - ty::Opaque(def_id, substs) => { + ty::Alias(ty::Projection, ty::AliasTy { def_id, substs, .. }) => { + chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { + associated_ty_id: chalk_ir::AssocTypeId(def_id), + substitution: substs.lower_into(interner), + })) + } + ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id: chalk_ir::OpaqueTyId(def_id), substitution: substs.lower_into(interner), @@ -442,13 +441,14 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { mutbl.lower_into(interner), ), TyKind::Str => ty::Str, - TyKind::OpaqueType(opaque_ty, substitution) => { - ty::Opaque(opaque_ty.0, substitution.lower_into(interner)) - } - TyKind::AssociatedType(assoc_ty, substitution) => ty::Projection(ty::ProjectionTy { - substs: substitution.lower_into(interner), - item_def_id: assoc_ty.0, - }), + TyKind::OpaqueType(opaque_ty, substitution) => ty::Alias( + ty::Opaque, + interner.tcx.mk_alias_ty(opaque_ty.0, substitution.lower_into(interner)), + ), + TyKind::AssociatedType(assoc_ty, substitution) => ty::Alias( + ty::Projection, + interner.tcx.mk_alias_ty(assoc_ty.0, substitution.lower_into(interner)), + ), TyKind::Foreign(def_id) => ty::Foreign(def_id.0), TyKind::Error => return interner.tcx.ty_error(), TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { @@ -456,13 +456,20 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { name: ty::BoundVar::from_usize(placeholder.idx), }), TyKind::Alias(alias_ty) => match alias_ty { - chalk_ir::AliasTy::Projection(projection) => ty::Projection(ty::ProjectionTy { - item_def_id: projection.associated_ty_id.0, - substs: projection.substitution.lower_into(interner), - }), - chalk_ir::AliasTy::Opaque(opaque) => { - ty::Opaque(opaque.opaque_ty_id.0, opaque.substitution.lower_into(interner)) - } + chalk_ir::AliasTy::Projection(projection) => ty::Alias( + ty::Projection, + interner.tcx.mk_alias_ty( + projection.associated_ty_id.0, + projection.substitution.lower_into(interner), + ), + ), + chalk_ir::AliasTy::Opaque(opaque) => ty::Alias( + ty::Opaque, + interner.tcx.mk_alias_ty( + opaque.opaque_ty_id.0, + opaque.substitution.lower_into(interner), + ), + ), }, TyKind::Function(_quantified_ty) => unimplemented!(), TyKind::BoundVar(_bound) => ty::Bound( @@ -688,7 +695,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru binders.clone(), chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(predicate.item_def_id), + associated_ty_id: chalk_ir::AssocTypeId(predicate.def_id), substitution: interner .tcx .mk_substs_trait(self_ty, predicate.substs) @@ -844,7 +851,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx> let (trait_ref, own_substs) = self.projection_ty.trait_ref_and_own_substs(interner.tcx); chalk_solve::rust_ir::AliasEqBound { trait_bound: trait_ref.lower_into(interner), - associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id), + associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.def_id), parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(), value: self.term.ty().unwrap().lower_into(interner), } diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index f8f74b732..c0da8a816 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -1,5 +1,5 @@ // This file contains various trait resolution methods used by codegen. -// They all assume regions can be erased and monomorphic types. It +// They all assume regions can be erased and monomorphic types. It // seems likely that they should eventually be merged into more // general routines. @@ -82,7 +82,7 @@ pub fn codegen_select_candidate<'tcx>( // Opaque types may have gotten their hidden types constrained, but we can ignore them safely // as they will get constrained elsewhere, too. // (ouz-a) This is required for `type-alias-impl-trait/assoc-projection-ice.rs` to pass - let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + let _ = infcx.take_opaque_types(); Ok(&*tcx.arena.alloc(impl_source)) } diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 66ab742f1..481b56e11 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -112,7 +112,7 @@ fn dropck_outlives<'tcx>( // A projection that we couldn't resolve - it // might have a destructor. - ty::Projection(..) | ty::Opaque(..) => { + ty::Alias(..) => { result.kinds.push(ty.into()); } @@ -189,7 +189,7 @@ fn dtorck_constraint_for_ty<'tcx>( tcx.sess.delay_span_bug( span, - &format!("upvar_tys for closure not found. Expected capture information for closure {}", ty,), + &format!("upvar_tys for closure not found. Expected capture information for closure {ty}",), ); return Err(NoSolution); } @@ -231,7 +231,7 @@ fn dtorck_constraint_for_ty<'tcx>( // be fully resolved. tcx.sess.delay_span_bug( span, - &format!("upvar_tys for generator not found. Expected capture information for generator {}", ty,), + &format!("upvar_tys for generator not found. Expected capture information for generator {ty}",), ); return Err(NoSolution); } @@ -268,7 +268,7 @@ fn dtorck_constraint_for_ty<'tcx>( } // Types that can't be resolved. Pass them forward. - ty::Projection(..) | ty::Opaque(..) | ty::Param(..) => { + ty::Alias(..) | ty::Param(..) => { constraints.dtorck_types.push(ty); } diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 010233d77..7d2d8433c 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -154,11 +154,8 @@ fn implied_bounds_from_components<'tcx>( match component { Component::Region(r) => Some(OutlivesBound::RegionSubRegion(sub_region, r)), Component::Param(p) => Some(OutlivesBound::RegionSubParam(sub_region, p)), - Component::Projection(p) => Some(OutlivesBound::RegionSubProjection(sub_region, p)), - Component::Opaque(def_id, substs) => { - Some(OutlivesBound::RegionSubOpaque(sub_region, def_id, substs)) - } - Component::EscapingProjection(_) => + Component::Alias(p) => Some(OutlivesBound::RegionSubAlias(sub_region, p)), + Component::EscapingAlias(_) => // If the projection has escaping regions, don't // try to infer any implied bounds even for its // free components. This is conservative, because diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 44fd8bfb3..5cad2c2cc 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -47,14 +47,14 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + // us a test case. debug_assert_eq!(normalized_value, resolved_value); let erased = infcx.tcx.erase_regions(resolved_value); - debug_assert!(!erased.needs_infer(), "{:?}", erased); + debug_assert!(!erased.needs_infer(), "{erased:?}"); Ok(erased) } Err(NoSolution) => Err(NoSolution), } } -fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool { +fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { match p.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => false, 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<Span>, ) -> 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(()) } |