diff options
| author | Michael Baikov <manpacket@gmail.com> | 2024-05-22 09:26:02 -0400 |
|---|---|---|
| committer | Michael Baikov <manpacket@gmail.com> | 2024-05-24 07:23:30 -0400 |
| commit | d6e4fe569c84c6a9d20690f139ad15a3d3da9550 (patch) | |
| tree | 080880b0bf7f23de633e17bd4684927844f0e6a8 /compiler/rustc_resolve/src | |
| parent | 464987730ab36e3456ba57c53965372989382deb (diff) | |
| download | rust-d6e4fe569c84c6a9d20690f139ad15a3d3da9550.tar.gz rust-d6e4fe569c84c6a9d20690f139ad15a3d3da9550.zip | |
A custom error message for lending iterators
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 40 |
2 files changed, 44 insertions, 5 deletions
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index edfeacec7e3..e9989b803e8 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -882,6 +882,15 @@ pub(crate) struct ElidedAnonymousLivetimeReportError { pub(crate) suggestion: Option<ElidedAnonymousLivetimeReportErrorSuggestion>, } +#[derive(Diagnostic)] +#[diag(resolve_lending_iterator_report_error)] +pub(crate) struct LendingIteratorReportError { + #[primary_span] + pub(crate) lifetime: Span, + #[note] + pub(crate) ty: Span, +} + #[derive(Subdiagnostic)] #[multipart_suggestion( resolve_elided_anonymous_lifetime_report_error_suggestion, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 63d0d6c260d..08196619bef 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -9,7 +9,7 @@ use crate::{errors, path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding}; use crate::{BindingKey, Used}; use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult}; -use crate::{ResolutionError, Resolver, Segment, UseError}; +use crate::{ResolutionError, Resolver, Segment, TyCtxt, UseError}; use rustc_ast::ptr::P; use rustc_ast::visit::{visit_opt, walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; @@ -1703,10 +1703,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { break; } } - self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError { - span: lifetime.ident.span, - suggestion, - }); + + // Is it caused by user trying to implement a lending iterator? + if !self.in_func_body + && let Some((module, _)) = &self.current_trait_ref + && let Some(ty) = &self.diag_metadata.current_self_type + && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind + && def_id_matches_path( + self.r.tcx, + trait_id, + &["core", "iter", "traits", "iterator", "Iterator"], + ) + { + self.r.dcx().emit_err(errors::LendingIteratorReportError { + lifetime: lifetime.ident.span, + ty: ty.span(), + }); + } else { + self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError { + span: lifetime.ident.span, + suggestion, + }); + } } else { self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError { span: lifetime.ident.span, @@ -4824,3 +4842,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } + +/// Check if definition matches a path +fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str]) -> bool { + let mut path = expected_path.iter().rev(); + while let (Some(parent), Some(next_step)) = (tcx.opt_parent(def_id), path.next()) { + if !tcx.opt_item_name(def_id).map_or(false, |n| n.as_str() == *next_step) { + return false; + } + def_id = parent; + } + return true; +} |
