summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/structured_errors
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:21 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:21 +0000
commit4e8199b572f2035b7749cba276ece3a26630d23e (patch)
treef09feeed6a0fe39d027b1908aa63ea6b35e4b631 /compiler/rustc_hir_analysis/src/structured_errors
parentAdding upstream version 1.66.0+dfsg1. (diff)
downloadrustc-4e8199b572f2035b7749cba276ece3a26630d23e.tar.xz
rustc-4e8199b572f2035b7749cba276ece3a26630d23e.zip
Adding upstream version 1.67.1+dfsg1.upstream/1.67.1+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_analysis/src/structured_errors')
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs71
1 files changed, 50 insertions, 21 deletions
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 435912464..4451db19f 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -296,25 +296,35 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
) -> String {
debug!(?path_hir_id);
+ // If there was already a lifetime among the arguments, just replicate that one.
+ if let Some(lt) = self.gen_args.args.iter().find_map(|arg| match arg {
+ hir::GenericArg::Lifetime(lt) => Some(lt),
+ _ => None,
+ }) {
+ return std::iter::repeat(lt.to_string())
+ .take(num_params_to_take)
+ .collect::<Vec<_>>()
+ .join(", ");
+ }
+
let mut ret = Vec::new();
+ let mut ty_id = None;
for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
debug!(?id);
- let params = if let Some(generics) = node.generics() {
- generics.params
- } else if let hir::Node::Ty(ty) = node
- && let hir::TyKind::BareFn(bare_fn) = ty.kind
- {
- bare_fn.generic_params
- } else {
- &[]
- };
- ret.extend(params.iter().filter_map(|p| {
- let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
- = p.kind
- else { return None };
- let hir::ParamName::Plain(name) = p.name else { return None };
- Some(name.to_string())
- }));
+ if let hir::Node::Ty(_) = node {
+ ty_id = Some(id);
+ }
+
+ // Suggest `'_` when in function parameter or elided function return.
+ if let Some(fn_decl) = node.fn_decl() && let Some(ty_id) = ty_id {
+ let in_arg = fn_decl.inputs.iter().any(|t| t.hir_id == ty_id);
+ let in_ret = matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id);
+
+ if in_arg || (in_ret && fn_decl.lifetime_elision_allowed) {
+ return std::iter::repeat("'_".to_owned()).take(num_params_to_take).collect::<Vec<_>>().join(", ");
+ }
+ }
+
// Suggest `'static` when in const/static item-like.
if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
@@ -334,11 +344,29 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
})
| hir::Node::AnonConst(..) = node
{
- ret.extend(
- std::iter::repeat("'static".to_owned())
- .take(num_params_to_take.saturating_sub(ret.len())),
- );
+ return std::iter::repeat("'static".to_owned())
+ .take(num_params_to_take.saturating_sub(ret.len()))
+ .collect::<Vec<_>>()
+ .join(", ");
}
+
+ let params = if let Some(generics) = node.generics() {
+ generics.params
+ } else if let hir::Node::Ty(ty) = node
+ && let hir::TyKind::BareFn(bare_fn) = ty.kind
+ {
+ bare_fn.generic_params
+ } else {
+ &[]
+ };
+ ret.extend(params.iter().filter_map(|p| {
+ let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
+ = p.kind
+ else { return None };
+ let hir::ParamName::Plain(name) = p.name else { return None };
+ Some(name.to_string())
+ }));
+
if ret.len() >= num_params_to_take {
return ret[..num_params_to_take].join(", ");
}
@@ -728,7 +756,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
&& let Some(trait_path_segment) = path.segments.get(0) {
let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
- if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
+ if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self
+ {
if let Some(span) = self.gen_args.span_ext()
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
let sugg = vec![