diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_region.rs b/compiler/rustc_infer/src/infer/error_reporting/note_region.rs deleted file mode 100644 index 41b115f3377ac..0000000000000 --- a/compiler/rustc_infer/src/infer/error_reporting/note_region.rs +++ /dev/null @@ -1,427 +0,0 @@ -use crate::errors::RegionOriginNote; -use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; -use crate::infer::{self, SubregionOrigin}; -use rustc_errors::{ - fluent, struct_span_err, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, -}; -use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, Region}; - -use super::ObligationCauseAsDiagArg; - -impl<'tcx> TypeErrCtxt<'_, 'tcx> { - pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) { - match *origin { - infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { - span: trace.cause.span, - requirement: ObligationCauseAsDiagArg(trace.cause.clone()), - expected_found: self.values_str(trace.values), - } - .add_to_diagnostic(err), - infer::Reborrow(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diagnostic(err) - } - infer::ReborrowUpvar(span, ref upvar_id) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - RegionOriginNote::WithName { - span, - msg: fluent::infer_reborrow, - name: &var_name.to_string(), - continues: false, - } - .add_to_diagnostic(err); - } - infer::RelateObjectBound(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } - .add_to_diagnostic(err); - } - infer::DataBorrowed(ty, span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_data_borrowed, - name: &self.ty_to_string(ty), - continues: false, - } - .add_to_diagnostic(err); - } - infer::ReferenceOutlivesReferent(ty, span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_reference_outlives_referent, - name: &self.ty_to_string(ty), - continues: false, - } - .add_to_diagnostic(err); - } - infer::RelateParamBound(span, ty, opt_span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_relate_param_bound, - name: &self.ty_to_string(ty), - continues: opt_span.is_some(), - } - .add_to_diagnostic(err); - if let Some(span) = opt_span { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 } - .add_to_diagnostic(err); - } - } - infer::RelateRegionParamBound(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound } - .add_to_diagnostic(err); - } - infer::CompareImplItemObligation { span, .. } => { - RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation } - .add_to_diagnostic(err); - } - infer::CheckAssociatedTypeBounds { ref parent, .. } => { - self.note_region_origin(err, &parent); - } - infer::AscribeUserTypeProvePredicate(span) => { - RegionOriginNote::Plain { - span, - msg: fluent::infer_ascribe_user_type_prove_predicate, - } - .add_to_diagnostic(err); - } - } - } - - pub(super) fn report_concrete_failure( - &self, - origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>, - ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - match origin { - infer::Subtype(box trace) => { - let terr = TypeError::RegionsDoesNotOutlive(sup, sub); - let mut err = self.report_and_explain_type_error(trace, terr); - match (*sub, *sup) { - (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} - (ty::RePlaceholder(_), _) => { - note_and_explain_region( - self.tcx, - &mut err, - "", - sup, - " doesn't meet the lifetime requirements", - None, - ); - } - (_, ty::RePlaceholder(_)) => { - note_and_explain_region( - self.tcx, - &mut err, - "the required lifetime does not necessarily outlive ", - sub, - "", - None, - ); - } - _ => { - note_and_explain_region(self.tcx, &mut err, "", sup, "...", None); - note_and_explain_region( - self.tcx, - &mut err, - "...does not necessarily outlive ", - sub, - "", - None, - ); - } - } - err - } - infer::Reborrow(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0312, - "lifetime of reference outlives lifetime of borrowed content..." - ); - note_and_explain_region( - self.tcx, - &mut err, - "...the reference is valid for ", - sub, - "...", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "...but the borrowed content is only valid for ", - sup, - "", - None, - ); - err - } - infer::ReborrowUpvar(span, ref upvar_id) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0313, - "lifetime of borrowed pointer outlives lifetime of captured variable `{}`...", - var_name - ); - note_and_explain_region( - self.tcx, - &mut err, - "...the borrowed pointer is valid for ", - sub, - "...", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - &format!("...but `{}` is only valid for ", var_name), - sup, - "", - None, - ); - err - } - infer::RelateObjectBound(span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0476, - "lifetime of the source pointer does not outlive lifetime bound of the \ - object type" - ); - note_and_explain_region( - self.tcx, - &mut err, - "object type is valid for ", - sub, - "", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "source pointer is only valid for ", - sup, - "", - None, - ); - err - } - infer::RelateParamBound(span, ty, opt_span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0477, - "the type `{}` does not fulfill the required lifetime", - self.ty_to_string(ty) - ); - match *sub { - ty::ReStatic => note_and_explain_region( - self.tcx, - &mut err, - "type must satisfy ", - sub, - if opt_span.is_some() { " as required by this binding" } else { "" }, - opt_span, - ), - _ => note_and_explain_region( - self.tcx, - &mut err, - "type must outlive ", - sub, - if opt_span.is_some() { " as required by this binding" } else { "" }, - opt_span, - ), - } - err - } - infer::RelateRegionParamBound(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - note_and_explain_region( - self.tcx, - &mut err, - "lifetime parameter instantiated with ", - sup, - "", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "but lifetime parameter must outlive ", - sub, - "", - None, - ); - err - } - infer::DataBorrowed(ty, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0490, - "a value of type `{}` is borrowed for too long", - self.ty_to_string(ty) - ); - note_and_explain_region( - self.tcx, - &mut err, - "the type is valid for ", - sub, - "", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "but the borrow lasts for ", - sup, - "", - None, - ); - err - } - infer::ReferenceOutlivesReferent(ty, span) => { - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0491, - "in type `{}`, reference has a longer lifetime than the data it references", - self.ty_to_string(ty) - ); - note_and_explain_region( - self.tcx, - &mut err, - "the pointer is valid for ", - sub, - "", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "but the referenced data is only valid for ", - sup, - "", - None, - ); - err - } - infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => self - .report_extra_impl_obligation( - span, - impl_item_def_id, - trait_item_def_id, - &format!("`{}: {}`", sup, sub), - ), - infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { - let mut err = self.report_concrete_failure(*parent, sub, sup); - - let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label( - trait_item_span, - format!("definition of `{}` from trait", item_name), - ); - - let trait_predicates = self.tcx.explicit_predicates_of(trait_item_def_id); - let impl_predicates = self.tcx.explicit_predicates_of(impl_item_def_id); - - let impl_predicates: rustc_data_structures::fx::FxHashSet<_> = - impl_predicates.predicates.into_iter().map(|(pred, _)| pred).collect(); - let clauses: Vec<_> = trait_predicates - .predicates - .into_iter() - .filter(|&(pred, _)| !impl_predicates.contains(pred)) - .map(|(pred, _)| format!("{}", pred)) - .collect(); - - if !clauses.is_empty() { - let generics = self.tcx.hir().get_generics(impl_item_def_id).unwrap(); - let where_clause_span = generics.tail_span_for_predicate_suggestion(); - - let suggestion = format!( - "{} {}", - generics.add_where_or_trailing_comma(), - clauses.join(", "), - ); - err.span_suggestion( - where_clause_span, - &format!( - "try copying {} from the trait", - if clauses.len() > 1 { "these clauses" } else { "this clause" } - ), - suggestion, - rustc_errors::Applicability::MaybeIncorrect, - ); - } - - err - } - infer::AscribeUserTypeProvePredicate(span) => { - let mut err = - struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - note_and_explain_region( - self.tcx, - &mut err, - "lifetime instantiated with ", - sup, - "", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - "but lifetime must outlive ", - sub, - "", - None, - ); - err - } - } - } - - pub(super) fn report_placeholder_failure( - &self, - placeholder_origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>, - ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - // I can't think how to do better than this right now. -nikomatsakis - debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); - match placeholder_origin { - infer::Subtype(box ref trace) - if matches!( - &trace.cause.code().peel_derives(), - ObligationCauseCode::BindingObligation(..) - | ObligationCauseCode::ExprBindingObligation(..) - ) => - { - // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::BindingObligation(_, span) - | ObligationCauseCode::ExprBindingObligation(_, span, ..) = - &trace.cause.code().peel_derives() - { - let span = *span; - let mut err = self.report_concrete_failure(placeholder_origin, sub, sup); - err.span_note(span, "the lifetime requirement is introduced here"); - err - } else { - unreachable!() - } - } - infer::Subtype(box trace) => { - let terr = TypeError::RegionsPlaceholderMismatch; - return self.report_and_explain_type_error(trace, terr); - } - _ => return self.report_concrete_failure(placeholder_origin, sub, sup), - } - } -} diff --git a/compiler/rustc_infer/src/infer/note.rs b/compiler/rustc_infer/src/infer/note.rs deleted file mode 100644 index 2ccbd164faaf1..0000000000000 --- a/compiler/rustc_infer/src/infer/note.rs +++ /dev/null @@ -1,203 +0,0 @@ -impl<'tcx> TypeErrCtxt<'_, 'tcx> { - fn note_error_origin( - &self, - err: &mut Diagnostic, - cause: &ObligationCause<'tcx>, - exp_found: Option>>, - terr: TypeError<'tcx>, - ) { - match *cause.code() { - ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => { - let ty = self.resolve_vars_if_possible(root_ty); - if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_))) - { - // don't show type `_` - if span.desugaring_kind() == Some(DesugaringKind::ForLoop) - && let ty::Adt(def, substs) = ty.kind() - && Some(def.did()) == self.tcx.get_diagnostic_item(sym::Option) - { - err.span_label(span, format!("this is an iterator with items of type `{}`", substs.type_at(0))); - } else { - err.span_label(span, format!("this expression has type `{}`", ty)); - } - } - if let Some(ty::error::ExpectedFound { found, .. }) = exp_found - && ty.is_box() && ty.boxed_ty() == found - && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) - { - err.span_suggestion( - span, - "consider dereferencing the boxed value", - format!("*{}", snippet), - Applicability::MachineApplicable, - ); - } - } - ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => { - err.span_label(span, "expected due to this"); - } - ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { - arm_block_id, - arm_span, - arm_ty, - prior_arm_block_id, - prior_arm_span, - prior_arm_ty, - source, - ref prior_arms, - scrut_hir_id, - opt_suggest_box_span, - scrut_span, - .. - }) => match source { - hir::MatchSource::TryDesugar => { - if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); - let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { - let arg_expr = args.first().expect("try desugaring call w/out arg"); - self.typeck_results.as_ref().and_then(|typeck_results| { - typeck_results.expr_ty_opt(arg_expr) - }) - } else { - bug!("try desugaring w/out call expr as scrutinee"); - }; - - match scrut_ty { - Some(ty) if expected == ty => { - let source_map = self.tcx.sess.source_map(); - err.span_suggestion( - source_map.end_point(cause.span), - "try removing this `?`", - "", - Applicability::MachineApplicable, - ); - } - _ => {} - } - } - } - _ => { - // `prior_arm_ty` can be `!`, `expected` will have better info when present. - let t = self.resolve_vars_if_possible(match exp_found { - Some(ty::error::ExpectedFound { expected, .. }) => expected, - _ => prior_arm_ty, - }); - let source_map = self.tcx.sess.source_map(); - let mut any_multiline_arm = source_map.is_multiline(arm_span); - if prior_arms.len() <= 4 { - for sp in prior_arms { - any_multiline_arm |= source_map.is_multiline(*sp); - err.span_label(*sp, format!("this is found to be of type `{}`", t)); - } - } else if let Some(sp) = prior_arms.last() { - any_multiline_arm |= source_map.is_multiline(*sp); - err.span_label( - *sp, - format!("this and all prior arms are found to be of type `{}`", t), - ); - } - let outer_error_span = if any_multiline_arm { - // Cover just `match` and the scrutinee expression, not - // the entire match body, to reduce diagram noise. - cause.span.shrink_to_lo().to(scrut_span) - } else { - cause.span - }; - let msg = "`match` arms have incompatible types"; - err.span_label(outer_error_span, msg); - self.suggest_remove_semi_or_return_binding( - err, - prior_arm_block_id, - prior_arm_ty, - prior_arm_span, - arm_block_id, - arm_ty, - arm_span, - ); - if let Some(ret_sp) = opt_suggest_box_span { - // Get return type span and point to it. - self.suggest_boxing_for_return_impl_trait( - err, - ret_sp, - prior_arms.iter().chain(std::iter::once(&arm_span)).map(|s| *s), - ); - } - } - }, - ObligationCauseCode::IfExpression(box IfExpressionCause { - then_id, - else_id, - then_ty, - else_ty, - outer_span, - opt_suggest_box_span, - }) => { - let then_span = self.find_block_span_from_hir_id(then_id); - let else_span = self.find_block_span_from_hir_id(else_id); - err.span_label(then_span, "expected because of this"); - if let Some(sp) = outer_span { - err.span_label(sp, "`if` and `else` have incompatible types"); - } - self.suggest_remove_semi_or_return_binding( - err, - Some(then_id), - then_ty, - then_span, - Some(else_id), - else_ty, - else_span, - ); - if let Some(ret_sp) = opt_suggest_box_span { - self.suggest_boxing_for_return_impl_trait( - err, - ret_sp, - [then_span, else_span].into_iter(), - ); - } - } - ObligationCauseCode::LetElse => { - err.help("try adding a diverging expression, such as `return` or `panic!(..)`"); - err.help("...or use `match` instead of `let...else`"); - } - _ => { - if let ObligationCauseCode::BindingObligation(_, span) - | ObligationCauseCode::ExprBindingObligation(_, span, ..) - = cause.code().peel_derives() - && let TypeError::RegionsPlaceholderMismatch = terr - { - err.span_note( * span, - "the lifetime requirement is introduced here"); - } - } - } - } -} - -impl<'tcx> InferCtxt<'tcx> { - /// Given a [`hir::Block`], get the span of its last expression or - /// statement, peeling off any inner blocks. - pub fn find_block_span(&self, block: &'tcx hir::Block<'tcx>) -> Span { - let block = block.innermost_block(); - if let Some(expr) = &block.expr { - expr.span - } else if let Some(stmt) = block.stmts.last() { - // possibly incorrect trailing `;` in the else arm - stmt.span - } else { - // empty block; point at its entirety - block.span - } - } - - /// Given a [`hir::HirId`] for a block, get the span of its last expression - /// or statement, peeling off any inner blocks. - pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span { - match self.tcx.hir().get(hir_id) { - hir::Node::Block(blk) => self.find_block_span(blk), - // The parser was in a weird state if either of these happen, but - // it's better not to panic. - hir::Node::Expr(e) => e.span, - _ => rustc_span::DUMMY_SP, - } - } -}