summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/error_reporting/suggest.rs')
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs141
1 files changed, 77 insertions, 64 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index 1422bdc9e..f1d53cb59 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -105,7 +105,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Heavily inspired by `FnCtxt::suggest_compatible_variants`, with
// some modifications due to that being in typeck and this being in infer.
if let ObligationCauseCode::Pattern { .. } = cause.code() {
- if let ty::Adt(expected_adt, substs) = exp_found.expected.kind() {
+ if let ty::Adt(expected_adt, args) = exp_found.expected.kind() {
let compatible_variants: Vec<_> = expected_adt
.variants()
.iter()
@@ -114,7 +114,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
})
.filter_map(|variant| {
let sole_field = &variant.single_field();
- let sole_field_ty = sole_field.ty(self.tcx, substs);
+ let sole_field_ty = sole_field.ty(self.tcx, args);
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
let variant_path =
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
@@ -260,7 +260,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
"suggest_accessing_field_where_appropriate(cause={:?}, exp_found={:?})",
cause, exp_found
);
- if let ty::Adt(expected_def, expected_substs) = exp_found.expected.kind() {
+ if let ty::Adt(expected_def, expected_args) = exp_found.expected.kind() {
if expected_def.is_enum() {
return;
}
@@ -270,7 +270,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.fields
.iter()
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
- .map(|field| (field.name, field.ty(self.tcx, expected_substs)))
+ .map(|field| (field.name, field.ty(self.tcx, expected_args)))
.find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found))
{
if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() {
@@ -304,12 +304,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return;
}
match (&expected_inner.kind(), &found_inner.kind()) {
- (ty::FnPtr(sig), ty::FnDef(did, substs)) => {
+ (ty::FnPtr(sig), ty::FnDef(did, args)) => {
let expected_sig = &(self.normalize_fn_sig)(*sig);
let found_sig =
- &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).subst(self.tcx, substs));
+ &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args));
- let fn_name = self.tcx.def_path_str_with_substs(*did, substs);
+ let fn_name = self.tcx.def_path_str_with_args(*did, args);
if !self.same_type_modulo_infer(*found_sig, *expected_sig)
|| !sig.is_suggestable(self.tcx, true)
@@ -332,11 +332,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
diag.subdiagnostic(sugg);
}
- (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
+ (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => {
let expected_sig =
- &(self.normalize_fn_sig)(self.tcx.fn_sig(*did1).subst(self.tcx, substs1));
+ &(self.normalize_fn_sig)(self.tcx.fn_sig(*did1).instantiate(self.tcx, args1));
let found_sig =
- &(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).subst(self.tcx, substs2));
+ &(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).instantiate(self.tcx, args2));
if self.same_type_modulo_infer(*expected_sig, *found_sig) {
diag.subdiagnostic(FnUniqTypes);
@@ -351,7 +351,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return;
}
- let fn_name = self.tcx.def_path_str_with_substs(*did2, substs2);
+ let fn_name = self.tcx.def_path_str_with_args(*did2, args2);
let sug = if found.is_ref() {
FunctionPointerSuggestion::CastBothRef {
span,
@@ -370,16 +370,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
diag.subdiagnostic(sug);
}
- (ty::FnDef(did, substs), ty::FnPtr(sig)) => {
+ (ty::FnDef(did, args), ty::FnPtr(sig)) => {
let expected_sig =
- &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).subst(self.tcx, substs));
+ &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args));
let found_sig = &(self.normalize_fn_sig)(*sig);
if !self.same_type_modulo_infer(*found_sig, *expected_sig) {
return;
}
- let fn_name = self.tcx.def_path_str_with_substs(*did, substs);
+ let fn_name = self.tcx.def_path_str_with_args(*did, args);
let casting = if expected.is_ref() {
format!("&({fn_name} as {found_sig})")
@@ -400,10 +400,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
expected: Ty<'tcx>,
found: Ty<'tcx>,
) -> Option<SuggestAsRefKind> {
- if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) =
+ if let (ty::Adt(exp_def, exp_args), ty::Ref(_, found_ty, _)) =
(expected.kind(), found.kind())
{
- if let ty::Adt(found_def, found_substs) = *found_ty.kind() {
+ if let ty::Adt(found_def, found_args) = *found_ty.kind() {
if exp_def == &found_def {
let have_as_ref = &[
(sym::Option, SuggestAsRefKind::Option),
@@ -414,7 +414,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}) {
let mut show_suggestion = true;
for (exp_ty, found_ty) in
- std::iter::zip(exp_substs.types(), found_substs.types())
+ std::iter::zip(exp_args.types(), found_args.types())
{
match *exp_ty.kind() {
ty::Ref(_, exp_ty, _) => {
@@ -464,52 +464,53 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span: Span,
) -> Option<TypeErrorAdditionalDiags> {
let hir = self.tcx.hir();
- if let Some(node) = self.tcx.hir().find_by_def_id(cause.body_id) &&
- let hir::Node::Item(hir::Item {
- kind: hir::ItemKind::Fn(_sig, _, body_id), ..
- }) = node {
- let body = hir.body(*body_id);
-
- /// Find the if expression with given span
- struct IfVisitor {
- pub result: bool,
- pub found_if: bool,
- pub err_span: Span,
- }
+ if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(cause.body_id) {
+ let body = hir.body(body_id);
+
+ /// Find the if expression with given span
+ struct IfVisitor {
+ pub result: bool,
+ pub found_if: bool,
+ pub err_span: Span,
+ }
- impl<'v> Visitor<'v> for IfVisitor {
- fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
- if self.result { return; }
- match ex.kind {
- hir::ExprKind::If(cond, _, _) => {
- self.found_if = true;
- walk_expr(self, cond);
- self.found_if = false;
+ impl<'v> Visitor<'v> for IfVisitor {
+ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
+ if self.result {
+ return;
+ }
+ match ex.kind {
+ hir::ExprKind::If(cond, _, _) => {
+ self.found_if = true;
+ walk_expr(self, cond);
+ self.found_if = false;
+ }
+ _ => walk_expr(self, ex),
}
- _ => walk_expr(self, ex),
}
- }
- fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
- if let hir::StmtKind::Local(hir::Local {
- span, pat: hir::Pat{..}, ty: None, init: Some(_), ..
- }) = &ex.kind
- && self.found_if
- && span.eq(&self.err_span) {
- self.result = true;
+ fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
+ if let hir::StmtKind::Local(hir::Local {
+ span, pat: hir::Pat{..}, ty: None, init: Some(_), ..
+ }) = &ex.kind
+ && self.found_if
+ && span.eq(&self.err_span) {
+ self.result = true;
+ }
+ walk_stmt(self, ex);
}
- walk_stmt(self, ex);
- }
- fn visit_body(&mut self, body: &'v hir::Body<'v>) {
- hir::intravisit::walk_body(self, body);
+ fn visit_body(&mut self, body: &'v hir::Body<'v>) {
+ hir::intravisit::walk_body(self, body);
+ }
}
- }
- let mut visitor = IfVisitor { err_span: span, found_if: false, result: false };
- visitor.visit_body(&body);
- if visitor.result {
- return Some(TypeErrorAdditionalDiags::AddLetForLetChains{span: span.shrink_to_lo()});
+ let mut visitor = IfVisitor { err_span: span, found_if: false, result: false };
+ visitor.visit_body(&body);
+ if visitor.result {
+ return Some(TypeErrorAdditionalDiags::AddLetForLetChains {
+ span: span.shrink_to_lo(),
+ });
}
}
None
@@ -525,13 +526,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
diag: &mut Diagnostic,
) {
// 0. Extract fn_decl from hir
- let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(hir::Closure { body, fn_decl, .. }), .. }) = hir else { return; };
+ let hir::Node::Expr(hir::Expr {
+ kind: hir::ExprKind::Closure(hir::Closure { body, fn_decl, .. }),
+ ..
+ }) = hir
+ else {
+ return;
+ };
let hir::Body { params, .. } = self.tcx.hir().body(*body);
- // 1. Get the substs of the closure.
+ // 1. Get the args of the closure.
// 2. Assume exp_found is FnOnce / FnMut / Fn, we can extract function parameters from [1].
- let Some(expected) = exp_found.expected.skip_binder().substs.get(1) else { return; };
- let Some(found) = exp_found.found.skip_binder().substs.get(1) else { return; };
+ let Some(expected) = exp_found.expected.skip_binder().args.get(1) else {
+ return;
+ };
+ let Some(found) = exp_found.found.skip_binder().args.get(1) else {
+ return;
+ };
let expected = expected.unpack();
let found = found.unpack();
// 3. Extract the tuple type from Fn trait and suggest the change.
@@ -564,12 +575,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if param_hir.pat.span == param_hir.ty_span {
// for `|x|`, `|_|`, `|x: impl Foo|`
let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; };
- suggestion += &format!("{}: &_", pat);
+ suggestion += &format!("{pat}: &_");
} else {
// for `|x: ty|`, `|_: ty|`
let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; };
let Ok(ty) = self.tcx.sess.source_map().span_to_snippet(param_hir.ty_span) else { return; };
- suggestion += &format!("{}: &{}", pat, ty);
+ suggestion += &format!("{pat}: &{ty}");
}
has_suggestion = true;
} else {
@@ -620,8 +631,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, .. }),
) if last_def_id == exp_def_id => StatementAsExpression::CorrectType,
(
- ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, substs: last_bounds, .. }),
- ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, substs: exp_bounds, .. }),
+ ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, args: last_bounds, .. }),
+ ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, args: exp_bounds, .. }),
) => {
debug!(
"both opaque, likely future {:?} {:?} {:?} {:?}",
@@ -710,7 +721,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let hir = self.tcx.hir();
for stmt in blk.stmts.iter().rev() {
- let hir::StmtKind::Local(local) = &stmt.kind else { continue; };
+ let hir::StmtKind::Local(local) = &stmt.kind else {
+ continue;
+ };
local.pat.walk(&mut find_compatible_candidates);
}
match hir.find_parent(blk.hir_id) {