X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_hir_typeck%2Fsrc%2Fcoercion.rs;h=43c7127b0d4c56b0e8495508eb2e9f51fa784d0d;hb=a673364c543986789cfbb844c925063519fb872a;hp=174b43313825e1b770760d191e3249529beacc89;hpb=e2301154e3c39f4bf606b6137d9cf5bf29a5f52e;p=rust.git diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 174b4331382..43c7127b0d4 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -630,8 +630,7 @@ fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceRe cause, coerce_unsized_did, 0, - coerce_source, - &[coerce_target.into()] + [coerce_source, coerce_target] )]; let mut has_unsized_tuple_coercion = false; @@ -748,7 +747,7 @@ fn coerce_dyn_star( &self, a: Ty<'tcx>, b: Ty<'tcx>, - predicates: &'tcx ty::List>>, + predicates: &'tcx ty::List>, b_region: ty::Region<'tcx>, ) -> CoerceResult<'tcx> { if !self.tcx.features().dyn_star { @@ -775,7 +774,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 @@ -785,16 +784,32 @@ fn coerce_dyn_star( let predicate = predicate.with_self_ty(self.tcx, a); 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( + self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]), + ) + .to_poly_trait_predicate(), + )); + } Ok(InferOk { value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b), @@ -1069,8 +1084,7 @@ pub fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option( // Mark that we've failed to coerce the types here to suppress // any superfluous errors we might encounter while trying to // emit or provide suggestions on how to fix the initial error. - fcx.set_tainted_by_errors(); + fcx.set_tainted_by_errors( + fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"), + ); let (expected, found) = if label_expression_as_expected { // In the case where this is a "forced unit", like // `break`, we want to call the `()` "expected"