X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_hir_typeck%2Fsrc%2Fcoercion.rs;h=c1e4ab600f34f204242165cba1ed560b1fd580cb;hb=9db23f8d30e8d00e2e5e18b51f7bb8e582520600;hp=71949b4211819b79d08c09b5b32872504294a3a7;hpb=1521795a7da083a16329bcb27d81d34434cfc6d0;p=rust.git diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 71949b42118..c1e4ab600f3 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -55,7 +55,7 @@ use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, ToPredicate, Ty, TypeAndMut}; +use rustc_middle::ty::{self, Ty, TypeAndMut}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::{self, BytePos, DesugaringKind, Span}; @@ -278,13 +278,13 @@ fn coerce_from_inference_variable( for &source_ty in &[a, b] { if source_ty != target_ty { obligations.push(Obligation::new( + self.tcx(), self.cause.clone(), self.param_env, ty::Binder::dummy(ty::PredicateKind::Coerce(ty::CoercePredicate { a: source_ty, b: target_ty, - })) - .to_predicate(self.tcx()), + })), )); } } @@ -669,7 +669,7 @@ fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceRe continue; } }; - match selcx.select(&obligation.with(trait_pred)) { + match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) { // Uncertain or unimplemented. Ok(None) => { if trait_pred.def_id() == unsize_did { @@ -775,7 +775,7 @@ fn coerce_dyn_star( // Check the obligations of the cast -- for example, when casting // `usize` to `dyn* Clone + 'static`: - let obligations = predicates + let mut obligations: Vec<_> = predicates .iter() .map(|predicate| { // For each existential predicate (e.g., `?Self: Clone`) substitute @@ -783,17 +783,35 @@ fn coerce_dyn_star( // and then require that the resulting predicate (e.g., `usize: Clone`) // holds (it does). let predicate = predicate.with_self_ty(self.tcx, a); - Obligation::new(self.cause.clone(), self.param_env, predicate) + Obligation::new(self.tcx, self.cause.clone(), self.param_env, predicate) }) - // Enforce the region bound (e.g., `usize: 'static`, in our example). - .chain([Obligation::new( + .chain([ + // Enforce the region bound (e.g., `usize: 'static`, in our example). + Obligation::new( + self.tcx, + self.cause.clone(), + self.param_env, + ty::Binder::dummy(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate( + a, b_region, + ))), + ), + ]) + .collect(); + + // Enforce that the type is `usize`/pointer-sized. For now, only those + // can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts. + if !a.is_dyn_star() { + obligations.push(Obligation::new( + self.tcx, self.cause.clone(), self.param_env, - self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::TypeOutlives( - ty::OutlivesPredicate(a, b_region), - ))), - )]) - .collect(); + ty::Binder::dummy(ty::TraitRef::new( + self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)), + self.tcx.mk_substs_trait(a, &[]), + )) + .to_poly_trait_predicate(), + )); + } Ok(InferOk { value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b),