diff options
| author | marmeladema <xademax@gmail.com> | 2022-04-24 00:17:33 +0200 |
|---|---|---|
| committer | marmeladema <xademax@gmail.com> | 2022-04-24 09:34:50 +0200 |
| commit | 7b0db3e7c81c36d2ec623849d17d9df4858abca1 (patch) | |
| tree | 6b4452c04270e18addefc4f26c2b02c24ae27803 /compiler | |
| parent | 6b4563bf93f4b103ed22507ed825008b89e4f5d9 (diff) | |
| download | rust-7b0db3e7c81c36d2ec623849d17d9df4858abca1.tar.gz rust-7b0db3e7c81c36d2ec623849d17d9df4858abca1.zip | |
Improve span for `consider adding an explicit lifetime bound` suggestions under NLL
Because NLL borrowck is run after typeck, `in_progress_typeck_results` was always `None` which was preventing the retrieval of the span to which the suggestion is suppose to add the lifetime bound. We now manually pass the `LocalDefId` owner to `construct_generic_bound_failure` so that under NLL, we give the owner id of the current body.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/region_errors.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/mod.rs | 53 |
2 files changed, 26 insertions, 28 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 5fd9ecf4513..be715505d81 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -171,6 +171,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { None, type_test.generic_kind, lower_bound_region, + self.body.source.def_id().as_local(), )); } else { // FIXME. We should handle this case better. It diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f2dd4f5d5cb..f9273cc50b7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -61,7 +61,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::{Item, ItemKind, Node}; use rustc_middle::dep_graph::DepContext; @@ -2285,7 +2285,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { bound_kind: GenericKind<'tcx>, sub: Region<'tcx>, ) { - self.construct_generic_bound_failure(span, origin, bound_kind, sub).emit(); + let owner = + self.in_progress_typeck_results.map(|typeck_results| typeck_results.borrow().hir_owner); + self.construct_generic_bound_failure(span, origin, bound_kind, sub, owner).emit(); } pub fn construct_generic_bound_failure( @@ -2294,31 +2296,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: Option<SubregionOrigin<'tcx>>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx>, + owner: Option<LocalDefId>, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let hir = self.tcx.hir(); // Attempt to obtain the span of the parameter so we can // suggest adding an explicit lifetime bound to it. - let generics = self - .in_progress_typeck_results - .map(|typeck_results| typeck_results.borrow().hir_owner) - .map(|owner| { - let hir_id = hir.local_def_id_to_hir_id(owner); - let parent_id = hir.get_parent_item(hir_id); - ( - // Parent item could be a `mod`, so we check the HIR before calling: - if let Some(Node::Item(Item { - kind: ItemKind::Trait(..) | ItemKind::Impl { .. }, - .. - })) = hir.find_by_def_id(parent_id) - { - Some(self.tcx.generics_of(parent_id)) - } else { - None - }, - self.tcx.generics_of(owner.to_def_id()), - hir.span(hir_id), - ) - }); + let generics = owner.map(|owner| { + let hir_id = hir.local_def_id_to_hir_id(owner); + let parent_id = hir.get_parent_item(hir_id); + ( + // Parent item could be a `mod`, so we check the HIR before calling: + if let Some(Node::Item(Item { + kind: ItemKind::Trait(..) | ItemKind::Impl { .. }, + .. + })) = hir.find_by_def_id(parent_id) + { + Some(self.tcx.generics_of(parent_id)) + } else { + None + }, + self.tcx.generics_of(owner.to_def_id()), + hir.span(hir_id), + ) + }); let span = match generics { // This is to get around the trait identity obligation, that has a `DUMMY_SP` as signal @@ -2606,11 +2606,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { None, ); if let Some(infer::RelateParamBound(_, t, _)) = origin { - let return_impl_trait = self - .in_progress_typeck_results - .map(|typeck_results| typeck_results.borrow().hir_owner) - .and_then(|owner| self.tcx.return_type_impl_trait(owner)) - .is_some(); + let return_impl_trait = + owner.and_then(|owner| self.tcx.return_type_impl_trait(owner)).is_some(); let t = self.resolve_vars_if_possible(t); match t.kind() { // We've got: |
