summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_traits/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_traits/src')
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs30
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs63
-rw-r--r--compiler/rustc_traits/src/codegen.rs4
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs8
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs7
-rw-r--r--compiler/rustc_traits/src/normalize_erasing_regions.rs4
-rw-r--r--compiler/rustc_traits/src/type_op.rs59
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(())
}