diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index d46febffba8..c4275e13935 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> { fn base_universe(&self) -> ty::UniverseIndex; - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; #[instrument(level = "debug", skip(self, mbcx))] fn report_error( @@ -231,18 +231,25 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_prove_predicate_with_cause(&ocx, key, cause); - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -268,13 +275,13 @@ where self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -288,7 +295,14 @@ where let (param_env, value) = key.into_parts(); let _ = ocx.normalize(&cause, param_env, value.value); - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -308,18 +322,25 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -334,13 +355,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { self.base_universe.unwrap() } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, mbcx.mir_def_id(), @@ -358,12 +379,12 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { } #[instrument(skip(ocx), level = "debug")] -fn try_extract_error_from_fulfill_cx<'tcx>( - ocx: &ObligationCtxt<'_, 'tcx>, +fn try_extract_error_from_fulfill_cx<'a, 'tcx>( + ocx: &ObligationCtxt<'a, 'tcx>, generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, -) -> Option> { +) -> Option> { // We generally shouldn't have errors here because the query was // already run, but there's no point using `span_delayed_bug` // when we're going to emit an error here anyway. @@ -381,15 +402,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>( } #[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] -fn try_extract_error_from_region_constraints<'tcx>( - infcx: &InferCtxt<'tcx>, +fn try_extract_error_from_region_constraints<'a, 'tcx>( + infcx: &'a InferCtxt<'tcx>, generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, region_constraints: &RegionConstraintData<'tcx>, mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, -) -> Option> { +) -> Option> { let placeholder_universe = match placeholder_region.kind() { ty::RePlaceholder(p) => p.universe, ty::ReVar(vid) => universe_of_region(vid), diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index e580910af77..0231665b64c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -582,6 +582,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { Self::new_diagnostic(dcx, DiagInner::new(level, message)) } + /// Allow moving diagnostics between different error tainting contexts + pub fn with_dcx(mut self, dcx: DiagCtxtHandle<'_>) -> Diag<'_, G> { + Diag { dcx, diag: self.diag.take(), _marker: PhantomData } + } + /// Creates a new `Diag` with an already constructed diagnostic. #[track_caller] pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 0551b9bc1f0..f055a776961 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1797,16 +1797,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }); } - fn report_return_mismatched_types<'a>( + fn report_return_mismatched_types<'cx>( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, ty_err: TypeError<'tcx>, - fcx: &FnCtxt<'a, 'tcx>, + fcx: &'cx FnCtxt<'_, 'tcx>, block_or_return_id: hir::HirId, expression: Option<&'tcx hir::Expr<'tcx>>, - ) -> Diag<'a> { + ) -> Diag<'cx> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, 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 f9720c9c307..ad9c1e28211 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -172,21 +172,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn demand_suptype_diag( - &self, + &'a self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_suptype_with_origin(&self.misc(sp), expected, actual) } #[instrument(skip(self), level = "debug")] pub fn demand_suptype_with_origin( - &self, + &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.at(cause, self.param_env) .sup(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) @@ -200,20 +200,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn demand_eqtype_diag( - &self, + &'a self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) } pub fn demand_eqtype_with_origin( - &self, + &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.at(cause, self.param_env) .eq(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) @@ -247,13 +247,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// will be permitted if the diverges flag is currently "always". #[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))] pub fn demand_coerce_diag( - &self, + &'a self, mut expr: &'tcx hir::Expr<'tcx>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, - ) -> Result, Diag<'tcx>> { + ) -> Result, Diag<'a>> { let expected = self.resolve_vars_with_obligations(expected); let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 1138642c56d..75664824477 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1424,7 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, provided_ty: Ty<'tcx>, arg: &hir::Expr<'tcx>, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, ) { if let ty::RawPtr(_, hir::Mutability::Mut) = expected_ty.kind() && let ty::RawPtr(_, hir::Mutability::Not) = provided_ty.kind() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index ad8eb7c3082..f0131b3225c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> { - self.infcx.dcx() + self.root_ctxt.infcx.dcx() } pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 208930208ed..8dde3032ca4 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -89,7 +89,7 @@ struct PatInfo<'tcx, 'a> { current_depth: u32, } -impl<'tcx> FnCtxt<'_, 'tcx> { +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { let code = ObligationCauseCode::Pattern { span: ti.span, @@ -100,12 +100,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } fn demand_eqtype_pat_diag( - &self, + &'a self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, ti: &TopInfo<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) .map_err(|mut diag| { if let Some(expr) = ti.origin_expr { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 503d3424e74..d321bc265bc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -436,7 +436,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn report_region_errors( &self, generic_param_scope: LocalDefId, @@ -2206,7 +2206,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, trace: TypeTrace<'tcx>, terr: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); let span = trace.cause.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index ba5e3ae8a93..084aebc296f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> { span: Span, arg_data: InferenceDiagnosticsData, error_code: TypeAnnotationNeeded, - ) -> Diag<'tcx> { + ) -> Diag<'_> { let source_kind = "other"; let source_name = ""; let failure_span = None; @@ -453,7 +453,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // If we don't have any typeck results we're outside // of a body, so we won't be able to get better info // here. - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code); }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); @@ -465,7 +465,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let Some(InferSource { span, kind }) = local_visitor.infer_source else { - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code); }; let (source_kind, name, path) = kind.ty_localized_msg(self); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 78d42942de4..10471e8bbdd 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -684,7 +684,7 @@ impl<'tcx> InferOk<'tcx, ()> { } impl<'tcx> InferCtxt<'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'_> { self.tcx.dcx() } @@ -1646,7 +1646,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err) } @@ -1656,7 +1656,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expected: ty::Const<'tcx>, actual: ty::Const<'tcx>, err: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index 4b5b1d77b30..34da8e576ce 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> { found_args: Vec, is_closure: bool, closure_arg_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'_> { let kind = if is_closure { "closure" } else { "function" }; let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index cccb78bec9d..3ef3efc6252 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3422,7 +3422,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { found_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>, terr: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let self_ty = found_trait_ref.self_ty(); let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { ( @@ -3553,7 +3553,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .unwrap_or((found_span, None, found)); - self.report_arg_count_mismatch( + self.infcx.report_arg_count_mismatch( span, closure_span, expected,