about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-11-29 19:55:24 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-11-29 20:24:21 +0000
commit25c75bc156a0491906c8f2bfa39d09eacb536a26 (patch)
tree011eb28d6ad421013ade2484eec5ddf07b9f6960
parentdfe32b6a432523d29550dc302b297028ca01e8f1 (diff)
downloadrust-25c75bc156a0491906c8f2bfa39d09eacb536a26.tar.gz
rust-25c75bc156a0491906c8f2bfa39d09eacb536a26.zip
review comments and rebase fixes
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs129
-rw-r--r--tests/ui/mismatched_types/suggest-option-asderef.stderr4
2 files changed, 66 insertions, 67 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 2c4a0782e60..d5e1efb9663 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -17,7 +17,7 @@ use rustc_errors::{
     ErrorGuaranteed, MultiSpan, Style, SuggestionStyle,
 };
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::is_range_literal;
@@ -36,7 +36,7 @@ use rustc_middle::ty::{
     TypeSuperFoldable, TypeVisitableExt, TypeckResults,
 };
 use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::{sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
 use rustc_target::spec::abi;
 use std::borrow::Cow;
@@ -1043,7 +1043,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind else {
             return;
         };
-        let hir::def::Res::Local(hir_id) = path.res else {
+        let Res::Local(hir_id) = path.res else {
             return;
         };
         let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else {
@@ -1627,7 +1627,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
-                && let hir::def::Res::Local(hir_id) = path.res
+                && let Res::Local(hir_id) = path.res
                 && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id)
                 && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
                 && let None = local.ty
@@ -2047,9 +2047,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let hir::ExprKind::Path(path) = arg.kind else {
             return;
         };
-        let expected_inputs = self.tcx.erase_late_bound_regions(*expected).inputs();
-        let found_inputs = self.tcx.erase_late_bound_regions(*found).inputs();
-        let both_tys = expected_inputs.iter().cloned().zip(found_inputs.iter().cloned());
+        let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(*expected).inputs();
+        let found_inputs = self.tcx.instantiate_bound_regions_with_erased(*found).inputs();
+        let both_tys = expected_inputs.iter().copied().zip(found_inputs.iter().copied());
 
         let arg_expr = |infcx: &InferCtxt<'tcx>, name, expected: Ty<'tcx>, found: Ty<'tcx>| {
             let (expected_ty, expected_refs) = get_deref_type_and_refs(expected);
@@ -2057,29 +2057,24 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
             if infcx.can_eq(param_env, found_ty, expected_ty) {
                 if found_refs.len() == expected_refs.len()
-                    && found_refs.iter().zip(expected_refs.iter()).all(|(e, f)| e == f)
+                    && found_refs.iter().eq(expected_refs.iter())
                 {
                     name
                 } else if found_refs.len() > expected_refs.len() {
-                    if found_refs[..found_refs.len() - expected_refs.len()]
-                        .iter()
-                        .zip(expected_refs.iter())
-                        .any(|(e, f)| e != f)
-                    {
-                        // The refs have different mutability.
+                    let refs = &found_refs[..found_refs.len() - expected_refs.len()];
+                    if found_refs[..expected_refs.len()].iter().eq(expected_refs.iter()) {
                         format!(
-                            "{}*{name}",
-                            found_refs[..found_refs.len() - expected_refs.len()]
-                                .iter()
+                            "{}{name}",
+                            refs.iter()
                                 .map(|mutbl| format!("&{}", mutbl.prefix_str()))
                                 .collect::<Vec<_>>()
                                 .join(""),
                         )
                     } else {
+                        // The refs have different mutability.
                         format!(
-                            "{}{name}",
-                            found_refs[..found_refs.len() - expected_refs.len()]
-                                .iter()
+                            "{}*{name}",
+                            refs.iter()
                                 .map(|mutbl| format!("&{}", mutbl.prefix_str()))
                                 .collect::<Vec<_>>()
                                 .join(""),
@@ -2108,48 +2103,52 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 format!("/* {found} */")
             }
         };
-        let (closure_names, call_names): (Vec<_>, Vec<_>) =
-            if both_tys.clone().all(|(expected, found)| {
-                let (expected_ty, _) = get_deref_type_and_refs(expected);
-                let (found_ty, _) = get_deref_type_and_refs(found);
-                self.can_eq(param_env, found_ty, expected_ty)
-            }) && !expected_inputs.is_empty()
-                && expected_inputs.len() == found_inputs.len()
-                && let hir::QPath::Resolved(_, path) = path
-                && let hir::def::Res::Def(_, fn_def_id) = path.res
-                && let Some(node) = self.tcx.hir().get_if_local(fn_def_id)
-                && let Some(body_id) = node.body_id()
-            {
-                let closure = self
-                    .tcx
-                    .hir()
-                    .body_param_names(body_id)
-                    .map(|name| format!("{name}"))
-                    .collect();
-                let args = self
-                    .tcx
-                    .hir()
-                    .body_param_names(body_id)
-                    .zip(both_tys)
-                    .map(|(name, (expected, found))| {
-                        arg_expr(self.infcx, format!("{name}"), expected, found)
-                    })
-                    .collect();
-                (closure, args)
-            } else {
-                let closure_args = expected_inputs
-                    .iter()
-                    .enumerate()
-                    .map(|(i, _)| format!("arg{i}"))
-                    .collect::<Vec<_>>();
-                let call_args = both_tys
-                    .enumerate()
-                    .map(|(i, (expected, found))| {
-                        arg_expr(self.infcx, format!("arg{i}"), expected, found)
-                    })
-                    .collect::<Vec<_>>();
-                (closure_args, call_args)
-            };
+        let args_have_same_underlying_type = both_tys.clone().all(|(expected, found)| {
+            let (expected_ty, _) = get_deref_type_and_refs(expected);
+            let (found_ty, _) = get_deref_type_and_refs(found);
+            self.can_eq(param_env, found_ty, expected_ty)
+        });
+        let (closure_names, call_names): (Vec<_>, Vec<_>) = if args_have_same_underlying_type
+            && !expected_inputs.is_empty()
+            && expected_inputs.len() == found_inputs.len()
+            && let Some(typeck) = &self.typeck_results
+            && let Res::Def(_, fn_def_id) = typeck.qpath_res(&path, *arg_hir_id)
+        {
+            let closure: Vec<_> = self
+                .tcx
+                .fn_arg_names(fn_def_id)
+                .iter()
+                .enumerate()
+                .map(|(i, ident)| {
+                    if ident.name.is_empty() || ident.name == kw::SelfLower {
+                        format!("arg{i}")
+                    } else {
+                        format!("{ident}")
+                    }
+                })
+                .collect();
+            let args = closure
+                .iter()
+                .zip(both_tys)
+                .map(|(name, (expected, found))| {
+                    arg_expr(self.infcx, name.to_owned(), expected, found)
+                })
+                .collect();
+            (closure, args)
+        } else {
+            let closure_args = expected_inputs
+                .iter()
+                .enumerate()
+                .map(|(i, _)| format!("arg{i}"))
+                .collect::<Vec<_>>();
+            let call_args = both_tys
+                .enumerate()
+                .map(|(i, (expected, found))| {
+                    arg_expr(self.infcx, format!("arg{i}"), expected, found)
+                })
+                .collect::<Vec<_>>();
+            (closure_args, call_args)
+        };
         let closure_names: Vec<_> = closure_names
             .into_iter()
             .zip(expected_inputs.iter())
@@ -3790,7 +3789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
-                && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
+                && let hir::Path { res: Res::Local(hir_id), .. } = path
                 && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
                 && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
                 && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
@@ -4050,7 +4049,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             );
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
-                && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
+                && let hir::Path { res: Res::Local(hir_id), .. } = path
                 && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
                 && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
@@ -4664,7 +4663,7 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
     fn visit_ty(&mut self, t: &'hir hir::Ty<'hir>) {
         if let hir::TyKind::Path(hir::QPath::Resolved(
             None,
-            hir::Path { res: hir::def::Res::Def(_, segment_did), .. },
+            hir::Path { res: Res::Def(_, segment_did), .. },
         )) = t.kind
         {
             if self.param_did == *segment_did {
diff --git a/tests/ui/mismatched_types/suggest-option-asderef.stderr b/tests/ui/mismatched_types/suggest-option-asderef.stderr
index 6c4a143e5af..1702a7f1dec 100644
--- a/tests/ui/mismatched_types/suggest-option-asderef.stderr
+++ b/tests/ui/mismatched_types/suggest-option-asderef.stderr
@@ -87,8 +87,8 @@ note: required by a bound in `Option::<T>::and_then`
   --> $SRC_DIR/core/src/option.rs:LL:COL
 help: consider wrapping the function in a closure
    |
-LL |     let _ = produces_string().and_then(|: String| generic_ref(&));
-   |                                        ++++++++++            +++
+LL |     let _ = produces_string().and_then(|arg0: String| generic_ref(&arg0));
+   |                                        ++++++++++++++            +++++++
 help: consider adjusting the signature so it does not borrow its argument
    |
 LL - fn generic_ref<T>(_: &T) -> Option<()> {