]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_hir_typeck/src/coercion.rs
New upstream version 1.69.0+dfsg1
[rustc.git] / compiler / rustc_hir_typeck / src / coercion.rs
index bbf7b81a2cc66ca82ccff36b50b0947c99710b77..00b86890b33f4ec54e2449444b69ccb58e8caaf6 100644 (file)
@@ -54,7 +54,7 @@ use rustc_middle::ty::adjustment::{
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::visit::TypeVisitable;
+use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, Ty, TypeAndMut};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
@@ -143,11 +143,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
         debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
         self.commit_if_ok(|_| {
+            let at = self.at(&self.cause, self.fcx.param_env).define_opaque_types(true);
             if self.use_lub {
-                self.at(&self.cause, self.fcx.param_env).lub(b, a)
+                at.lub(b, a)
             } else {
-                self.at(&self.cause, self.fcx.param_env)
-                    .sup(b, a)
+                at.sup(b, a)
                     .map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
             }
         })
@@ -170,12 +170,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         debug!("Coerce.tys({:?} => {:?})", a, b);
 
         // Just ignore error types.
-        if a.references_error() || b.references_error() {
+        if let Err(guar) = (a, b).error_reported() {
             // Best-effort try to unify these types -- we're already on the error path,
             // so this will have the side-effect of making sure we have no ambiguities
             // due to `[type error]` and `_` not coercing together.
-            let _ = self.commit_if_ok(|_| self.at(&self.cause, self.param_env).eq(a, b));
-            return success(vec![], self.fcx.tcx.ty_error(), vec![]);
+            let _ = self.commit_if_ok(|_| {
+                self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b)
+            });
+            return success(vec![], self.fcx.tcx.ty_error(guar), vec![]);
         }
 
         // Coercing from `!` to any type is allowed:
@@ -765,7 +767,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             self.cause.clone(),
             self.param_env,
             ty::Binder::dummy(
-                self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
+                self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerLike, [a]),
             ),
         ));
 
@@ -995,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let (adjustments, _) = self.register_infer_ok_obligations(ok);
         self.apply_adjustments(expr, adjustments);
-        Ok(if expr_ty.references_error() { self.tcx.ty_error() } else { target })
+        Ok(if let Err(guar) = expr_ty.error_reported() { self.tcx.ty_error(guar) } else { target })
     }
 
     /// Same as `try_coerce()`, but without side-effects.
@@ -1046,7 +1048,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.param_env,
                 )
                 .may_apply()
-                .then(|| deref_ty)
+                .then_some(deref_ty)
         })
     }
 
@@ -1432,8 +1434,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
 
         // If we see any error types, just propagate that error
         // upwards.
-        if expression_ty.references_error() || self.merged_ty().references_error() {
-            self.final_ty = Some(fcx.tcx.ty_error());
+        if let Err(guar) = (expression_ty, self.merged_ty()).error_reported() {
+            self.final_ty = Some(fcx.tcx.ty_error(guar));
             return;
         }
 
@@ -1484,6 +1486,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
             // Another example is `break` with no argument expression.
             assert!(expression_ty.is_unit(), "if let hack without unit type");
             fcx.at(cause, fcx.param_env)
+                // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
+                .define_opaque_types(true)
                 .eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
                 .map(|infer_ok| {
                     fcx.register_infer_ok_obligations(infer_ok);
@@ -1613,12 +1617,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 if visitor.ret_exprs.len() > 0 && let Some(expr) = expression {
                     self.note_unreachable_loop_return(&mut err, &expr, &visitor.ret_exprs);
                 }
+
                 let reported = err.emit_unless(unsized_return);
 
-                self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported));
+                self.final_ty = Some(fcx.tcx.ty_error(reported));
             }
         }
     }
+
     fn note_unreachable_loop_return(
         &self,
         err: &mut Diagnostic,
@@ -1821,7 +1827,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                         .trait_ref()
                         .and_then(|t| t.trait_def_id())
                         .map_or(false, |def_id| {
-                            fcx.tcx.object_safety_violations(def_id).is_empty()
+                            fcx.tcx.check_is_object_safe(def_id)
                         })
                 })
             }