about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs12
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs8
-rw-r--r--compiler/rustc_passes/src/check_attr.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs34
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs12
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs17
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs2
-rw-r--r--tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs17
-rw-r--r--tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr17
17 files changed, 135 insertions, 39 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 2437a43bd5a..2fa752384a1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -65,6 +65,7 @@ impl<'tcx> UniverseInfo<'tcx> {
             UniverseInfoInner::RelateTys { expected, found } => {
                 let err = mbcx.infcx.err_ctxt().report_mismatched_types(
                     &cause,
+                    mbcx.param_env,
                     expected,
                     found,
                     TypeError::RegionsPlaceholderMismatch,
@@ -480,12 +481,11 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
         .try_report_from_nll()
         .or_else(|| {
             if let SubregionOrigin::Subtype(trace) = cause {
-                Some(
-                    infcx.err_ctxt().report_and_explain_type_error(
-                        *trace,
-                        TypeError::RegionsPlaceholderMismatch,
-                    ),
-                )
+                Some(infcx.err_ctxt().report_and_explain_type_error(
+                    *trace,
+                    infcx.tcx.param_env(generic_param_scope),
+                    TypeError::RegionsPlaceholderMismatch,
+                ))
             } else {
                 None
             }
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index a16c1931a55..abce98265b3 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -360,6 +360,7 @@ fn check_opaque_type_well_formed<'tcx>(
                 .err_ctxt()
                 .report_mismatched_types(
                     &ObligationCause::misc(definition_span, def_id),
+                    param_env,
                     opaque_ty,
                     definition_ty,
                     err,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index fc5ec31cda8..7a56b3784f8 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -282,6 +282,7 @@ fn compare_method_predicate_entailment<'tcx>(
         let emitted = report_trait_method_mismatch(
             infcx,
             cause,
+            param_env,
             terr,
             (trait_m, trait_sig),
             (impl_m, impl_sig),
@@ -575,10 +576,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                 hir.get_if_local(impl_m.def_id)
                     .and_then(|node| node.fn_decl())
                     .map(|decl| (decl.output.span(), Cow::from("return type in trait"), false)),
-                Some(infer::ValuePairs::Terms(ExpectedFound {
+                Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound {
                     expected: trait_return_ty.into(),
                     found: impl_return_ty.into(),
-                })),
+                }))),
                 terr,
                 false,
             );
@@ -602,6 +603,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
             let emitted = report_trait_method_mismatch(
                 infcx,
                 cause,
+                param_env,
                 terr,
                 (trait_m, trait_sig),
                 (impl_m, impl_sig),
@@ -915,6 +917,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
 fn report_trait_method_mismatch<'tcx>(
     infcx: &InferCtxt<'tcx>,
     mut cause: ObligationCause<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     terr: TypeError<'tcx>,
     (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
     (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
@@ -1000,10 +1003,10 @@ fn report_trait_method_mismatch<'tcx>(
         &mut diag,
         &cause,
         trait_err_span.map(|sp| (sp, Cow::from("type in trait"), false)),
-        Some(infer::ValuePairs::PolySigs(ExpectedFound {
+        Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound {
             expected: ty::Binder::dummy(trait_sig),
             found: ty::Binder::dummy(impl_sig),
-        })),
+        }))),
         terr,
         false,
     );
@@ -1797,10 +1800,10 @@ fn compare_const_predicate_entailment<'tcx>(
             &mut diag,
             &cause,
             trait_c_span.map(|span| (span, Cow::from("type in trait"), false)),
-            Some(infer::ValuePairs::Terms(ExpectedFound {
+            Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound {
                 expected: trait_ty.into(),
                 found: impl_ty.into(),
-            })),
+            }))),
             terr,
             false,
         );
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 959b17b2d40..f2f9c69e49f 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -646,10 +646,10 @@ pub fn check_function_signature<'tcx>(
                 &mut diag,
                 &cause,
                 None,
-                Some(infer::ValuePairs::PolySigs(ExpectedFound {
+                Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound {
                     expected: expected_sig,
                     found: actual_sig,
-                })),
+                }))),
                 err,
                 false,
             );
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 76c75d976ee..b4f6b5a9dd2 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -364,6 +364,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
                 .err_ctxt()
                 .report_mismatched_types(
                     &cause,
+                    param_env,
                     mk_ptr(mt_b.ty),
                     target,
                     ty::error::TypeError::Mutability,
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index fa6a86c6911..06e2a5e3493 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -862,7 +862,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Err(e) => {
                 // FIXME(effects): better diagnostic
-                self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
+                self.err_ctxt()
+                    .report_mismatched_consts(&cause, self.param_env, effect, param, e)
+                    .emit();
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index de80ccf790c..6fa958d9496 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1723,6 +1723,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                     }) => {
                         err = fcx.err_ctxt().report_mismatched_types(
                             cause,
+                            fcx.param_env,
                             expected,
                             found,
                             coercion_error,
@@ -1752,6 +1753,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                     }) => {
                         err = fcx.err_ctxt().report_mismatched_types(
                             cause,
+                            fcx.param_env,
                             expected,
                             found,
                             coercion_error,
@@ -1787,6 +1789,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                     _ => {
                         err = fcx.err_ctxt().report_mismatched_types(
                             cause,
+                            fcx.param_env,
                             expected,
                             found,
                             coercion_error,
@@ -1897,7 +1900,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         block_or_return_id: hir::HirId,
         expression: Option<&'tcx hir::Expr<'tcx>>,
     ) -> Diag<'infcx> {
-        let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
+        let mut err =
+            fcx.err_ctxt().report_mismatched_types(cause, fcx.param_env, expected, found, ty_err);
 
         let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..));
 
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 777248ff873..3399a9fe880 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -191,7 +191,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.at(cause, self.param_env)
             .sup(DefineOpaqueTypes::Yes, expected, actual)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
-            .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e))
+            .map_err(|e| {
+                self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e)
+            })
     }
 
     pub(crate) fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
@@ -218,7 +220,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.at(cause, self.param_env)
             .eq(DefineOpaqueTypes::Yes, expected, actual)
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
-            .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e))
+            .map_err(|e| {
+                self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e)
+            })
     }
 
     pub(crate) fn demand_coerce(
@@ -271,7 +275,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr = expr.peel_drop_temps();
         let cause = self.misc(expr.span);
         let expr_ty = self.resolve_vars_if_possible(checked_ty);
-        let mut err = self.err_ctxt().report_mismatched_types(&cause, expected, expr_ty, e);
+        let mut err =
+            self.err_ctxt().report_mismatched_types(&cause, self.param_env, expected, expr_ty, e);
 
         self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e));
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index f29d6199a87..a6c249da103 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -827,6 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 formal_and_expected_inputs[mismatch_idx.into()],
                                 provided_arg_tys[mismatch_idx.into()].0,
                             ),
+                            self.param_env,
                             terr,
                         );
                         err.span_label(
@@ -912,7 +913,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let trace =
                 mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty);
             if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) {
-                let mut err = self.err_ctxt().report_and_explain_type_error(trace, *e);
+                let mut err =
+                    self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *e);
                 suggest_confusable(&mut err);
                 reported = Some(err.emit());
                 return false;
@@ -940,7 +942,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
             let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
             let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
-            let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
+            let mut err =
+                self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *err);
             self.emit_coerce_suggestions(
                 &mut err,
                 provided_args[*provided_idx],
@@ -1113,7 +1116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 &mut err,
                                 &trace.cause,
                                 None,
-                                Some(trace.values),
+                                Some(self.param_env.and(trace.values)),
                                 e,
                                 true,
                             );
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index f4685725dd3..96784fcb61b 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -538,7 +538,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 // to the feature, like the self type can't reference method args.
                 if self.tcx.features().arbitrary_self_types() {
                     self.err_ctxt()
-                        .report_mismatched_types(&cause, method_self_ty, self_ty, terr)
+                        .report_mismatched_types(
+                            &cause,
+                            self.param_env,
+                            method_self_ty,
+                            self_ty,
+                            terr,
+                        )
                         .emit();
                 } else {
                     // This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 86442844823..61e196bdebe 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2300,10 +2300,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 &mut diag,
                 &cause,
                 None,
-                Some(ValuePairs::PolySigs(ExpectedFound {
+                Some(param_env.and(ValuePairs::PolySigs(ExpectedFound {
                     expected: ty::Binder::dummy(expected_sig),
                     found: ty::Binder::dummy(sig),
-                })),
+                }))),
                 terr,
                 false,
             );
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index df5800ab58a..b9a569d25e3 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -75,6 +75,7 @@ use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
 use crate::infer;
 use crate::infer::relate::{self, RelateResult, TypeRelation};
 use crate::infer::{InferCtxt, TypeTrace, ValuePairs};
+use crate::solve::deeply_normalize_for_diagnostics;
 use crate::traits::{
     IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
 };
@@ -145,21 +146,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     pub fn report_mismatched_types(
         &self,
         cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         expected: Ty<'tcx>,
         actual: Ty<'tcx>,
         err: TypeError<'tcx>,
     ) -> Diag<'a> {
-        self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
+        self.report_and_explain_type_error(
+            TypeTrace::types(cause, true, expected, actual),
+            param_env,
+            err,
+        )
     }
 
     pub fn report_mismatched_consts(
         &self,
         cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         expected: ty::Const<'tcx>,
         actual: ty::Const<'tcx>,
         err: TypeError<'tcx>,
     ) -> Diag<'a> {
-        self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
+        self.report_and_explain_type_error(
+            TypeTrace::consts(cause, true, expected, actual),
+            param_env,
+            err,
+        )
     }
 
     pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
@@ -1133,7 +1144,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         diag: &mut Diag<'_>,
         cause: &ObligationCause<'tcx>,
         secondary_span: Option<(Span, Cow<'static, str>, bool)>,
-        mut values: Option<ValuePairs<'tcx>>,
+        mut values: Option<ty::ParamEnvAnd<'tcx, ValuePairs<'tcx>>>,
         terr: TypeError<'tcx>,
         prefer_label: bool,
     ) {
@@ -1241,8 +1252,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         }
         let (expected_found, exp_found, is_simple_error, values) = match values {
             None => (None, Mismatch::Fixed("type"), false, None),
-            Some(values) => {
-                let values = self.resolve_vars_if_possible(values);
+            Some(ty::ParamEnvAnd { param_env, value: values }) => {
+                let mut values = self.resolve_vars_if_possible(values);
+                if self.next_trait_solver() {
+                    values = deeply_normalize_for_diagnostics(self, param_env, values);
+                }
                 let (is_simple_error, exp_found) = match values {
                     ValuePairs::Terms(ExpectedFound { expected, found }) => {
                         match (expected.unpack(), found.unpack()) {
@@ -1773,6 +1787,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     pub fn report_and_explain_type_error(
         &self,
         trace: TypeTrace<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         terr: TypeError<'tcx>,
     ) -> Diag<'a> {
         debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr);
@@ -1784,7 +1799,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             self.type_error_additional_suggestions(&trace, terr),
         );
         let mut diag = self.dcx().create_err(failure_code);
-        self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false);
+        self.note_type_err(
+            &mut diag,
+            &trace.cause,
+            None,
+            Some(param_env.and(trace.values)),
+            terr,
+            false,
+        );
         diag
     }
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 94610a9e0e6..833358b2e14 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -295,7 +295,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let mut err = match origin {
             infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
-                let mut err = self.report_and_explain_type_error(trace, terr);
+                let mut err = self.report_and_explain_type_error(
+                    trace,
+                    self.tcx.param_env(generic_param_scope),
+                    terr,
+                );
                 match (*sub, *sup) {
                     (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
                     (ty::RePlaceholder(_), _) => {
@@ -646,7 +650,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             }
             infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsPlaceholderMismatch;
-                return self.report_and_explain_type_error(trace, terr);
+                return self.report_and_explain_type_error(
+                    trace,
+                    self.tcx.param_env(generic_param_scope),
+                    terr,
+                );
             }
             _ => {
                 return self.report_concrete_failure(
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 9ee4963a360..6ef64c3ed80 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1290,7 +1290,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         (
                             Some((
                                 data.projection_term,
-                                false,
                                 self.resolve_vars_if_possible(normalized_term),
                                 data.term,
                             )),
@@ -1335,7 +1334,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             derive_better_type_error(lhs, rhs)
                     {
                         (
-                            Some((lhs, true, self.resolve_vars_if_possible(expected_term), rhs)),
+                            Some((lhs, self.resolve_vars_if_possible(expected_term), rhs)),
                             better_type_err,
                         )
                     } else if let Some(rhs) = rhs.to_alias_term()
@@ -1343,7 +1342,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             derive_better_type_error(rhs, lhs)
                     {
                         (
-                            Some((rhs, true, self.resolve_vars_if_possible(expected_term), lhs)),
+                            Some((rhs, self.resolve_vars_if_possible(expected_term), lhs)),
                             better_type_err,
                         )
                     } else {
@@ -1354,7 +1353,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             };
 
             let msg = values
-                .and_then(|(predicate, _, normalized_term, expected_term)| {
+                .and_then(|(predicate, normalized_term, expected_term)| {
                     self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term)
                 })
                 .unwrap_or_else(|| {
@@ -1431,8 +1430,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 &mut diag,
                 &obligation.cause,
                 secondary_span,
-                values.map(|(_, _, normalized_ty, expected_ty)| {
-                    infer::ValuePairs::Terms(ExpectedFound::new(true, expected_ty, normalized_ty))
+                values.map(|(_, normalized_ty, expected_ty)| {
+                    obligation.param_env.and(infer::ValuePairs::Terms(ExpectedFound::new(
+                        true,
+                        expected_ty,
+                        normalized_ty,
+                    )))
                 }),
                 err,
                 false,
@@ -2654,6 +2657,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         };
         self.report_and_explain_type_error(
             TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref),
+            obligation.param_env,
             terr,
         )
     }
@@ -2744,6 +2748,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         {
             return Ok(self.report_and_explain_type_error(
                 TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref),
+                obligation.param_env,
                 ty::error::TypeError::Mismatch,
             ));
         }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index ba57909fc23..ca23f776581 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -287,6 +287,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             FulfillmentErrorCode::Subtype(ref expected_found, ref err) => self
                 .report_mismatched_types(
                     &error.obligation.cause,
+                    error.obligation.param_env,
                     expected_found.expected,
                     expected_found.found,
                     *err,
@@ -295,6 +296,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             FulfillmentErrorCode::ConstEquate(ref expected_found, ref err) => {
                 let mut diag = self.report_mismatched_consts(
                     &error.obligation.cause,
+                    error.obligation.param_env,
                     expected_found.expected,
                     expected_found.found,
                     *err,
diff --git a/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs
new file mode 100644
index 00000000000..5c53b745933
--- /dev/null
+++ b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Znext-solver
+
+// Make sure we try to mention a deeply normalized type in a type mismatch error.
+
+trait Mirror {
+    type Assoc;
+}
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+fn needs<T>(_: <T as Mirror>::Assoc) {}
+
+fn main() {
+    needs::<i32>(());
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr
new file mode 100644
index 00000000000..88643945863
--- /dev/null
+++ b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/deeply-normalize-type-expectation.rs:15:18
+   |
+LL |     needs::<i32>(());
+   |     ------------ ^^ expected `i32`, found `()`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/deeply-normalize-type-expectation.rs:12:4
+   |
+LL | fn needs<T>(_: <T as Mirror>::Assoc) {}
+   |    ^^^^^    -----------------------
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.