|
9 | 9 | use crate::{errors, path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
|
10 | 10 | use crate::{BindingKey, Used};
|
11 | 11 | use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
|
12 |
| -use crate::{ResolutionError, Resolver, Segment, UseError}; |
| 12 | +use crate::{ResolutionError, Resolver, Segment, TyCtxt, UseError}; |
13 | 13 |
|
14 | 14 | use rustc_ast::ptr::P;
|
15 | 15 | use rustc_ast::visit::{visit_opt, walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
|
@@ -629,6 +629,9 @@ struct DiagMetadata<'ast> {
|
629 | 629 | in_assignment: Option<&'ast Expr>,
|
630 | 630 | is_assign_rhs: bool,
|
631 | 631 |
|
| 632 | + /// If we are setting an associated type in trait impl, is it a non-GAT type? |
| 633 | + in_non_gat_assoc_type: Option<bool>, |
| 634 | + |
632 | 635 | /// Used to detect possible `.` -> `..` typo when calling methods.
|
633 | 636 | in_range: Option<(&'ast Expr, &'ast Expr)>,
|
634 | 637 |
|
@@ -1703,10 +1706,35 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
1703 | 1706 | break;
|
1704 | 1707 | }
|
1705 | 1708 | }
|
1706 |
| - self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError { |
1707 |
| - span: lifetime.ident.span, |
1708 |
| - suggestion, |
1709 |
| - }); |
| 1709 | + |
| 1710 | + // are we trying to use an anonymous lifetime |
| 1711 | + // on a non GAT associated trait type? |
| 1712 | + if !self.in_func_body |
| 1713 | + && let Some((module, _)) = &self.current_trait_ref |
| 1714 | + && let Some(ty) = &self.diag_metadata.current_self_type |
| 1715 | + && Some(true) == self.diag_metadata.in_non_gat_assoc_type |
| 1716 | + && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind |
| 1717 | + { |
| 1718 | + if def_id_matches_path( |
| 1719 | + self.r.tcx, |
| 1720 | + trait_id, |
| 1721 | + &["core", "iter", "traits", "iterator", "Iterator"], |
| 1722 | + ) { |
| 1723 | + self.r.dcx().emit_err(errors::LendingIteratorReportError { |
| 1724 | + lifetime: lifetime.ident.span, |
| 1725 | + ty: ty.span(), |
| 1726 | + }); |
| 1727 | + } else { |
| 1728 | + self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError { |
| 1729 | + lifetime: lifetime.ident.span, |
| 1730 | + }); |
| 1731 | + } |
| 1732 | + } else { |
| 1733 | + self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError { |
| 1734 | + span: lifetime.ident.span, |
| 1735 | + suggestion, |
| 1736 | + }); |
| 1737 | + } |
1710 | 1738 | } else {
|
1711 | 1739 | self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError {
|
1712 | 1740 | span: lifetime.ident.span,
|
@@ -3058,6 +3086,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
3058 | 3086 | );
|
3059 | 3087 | }
|
3060 | 3088 | AssocItemKind::Type(box TyAlias { generics, .. }) => {
|
| 3089 | + self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty()); |
3061 | 3090 | debug!("resolve_implementation AssocItemKind::Type");
|
3062 | 3091 | // We also need a new scope for the impl item type parameters.
|
3063 | 3092 | self.with_generic_param_rib(
|
@@ -3086,6 +3115,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
3086 | 3115 | });
|
3087 | 3116 | },
|
3088 | 3117 | );
|
| 3118 | + self.diag_metadata.in_non_gat_assoc_type = None; |
3089 | 3119 | }
|
3090 | 3120 | AssocItemKind::Delegation(box delegation) => {
|
3091 | 3121 | debug!("resolve_implementation AssocItemKind::Delegation");
|
@@ -4829,3 +4859,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
4829 | 4859 | }
|
4830 | 4860 | }
|
4831 | 4861 | }
|
| 4862 | + |
| 4863 | +/// Check if definition matches a path |
| 4864 | +fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str]) -> bool { |
| 4865 | + let mut path = expected_path.iter().rev(); |
| 4866 | + while let (Some(parent), Some(next_step)) = (tcx.opt_parent(def_id), path.next()) { |
| 4867 | + if !tcx.opt_item_name(def_id).map_or(false, |n| n.as_str() == *next_step) { |
| 4868 | + return false; |
| 4869 | + } |
| 4870 | + def_id = parent; |
| 4871 | + } |
| 4872 | + return true; |
| 4873 | +} |
0 commit comments