diff options
| author | bors <bors@rust-lang.org> | 2022-05-08 04:05:36 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-08 04:05:36 +0000 |
| commit | 030c886c29ffbfbb9f9c6495651cb4bee0fc93fe (patch) | |
| tree | 024c2d30e9a6c3558b6109de41b9b67920d92870 /compiler | |
| parent | 4d1076c9f918297c97300a7ecf769dd7e6780be6 (diff) | |
| parent | 7d8e10d3c242c2741d7190db8a9bbc4c919b53c7 (diff) | |
| download | rust-030c886c29ffbfbb9f9c6495651cb4bee0fc93fe.tar.gz rust-030c886c29ffbfbb9f9c6495651cb4bee0fc93fe.zip | |
Auto merge of #96155 - jackh726:param-heuristics-followup, r=estebank
Followups for method call error change Each commit is self-contained. Fixes most of the followup reviews from that PR. r? `@estebank`
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/mod.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/callee.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/fn_ctxt/checks.rs | 142 |
3 files changed, 73 insertions, 87 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ccd860ce242..af81f5cde2c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1584,9 +1584,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Variable(ty::error::ExpectedFound<Ty<'a>>), Fixed(&'static str), } - let (expected_found, exp_found, is_simple_error) = match values { - None => (None, Mismatch::Fixed("type"), false), + let (expected_found, exp_found, is_simple_error, values) = match values { + None => (None, Mismatch::Fixed("type"), false, None), Some(values) => { + let values = self.resolve_vars_if_possible(values); let (is_simple_error, exp_found) = match values { ValuePairs::Terms(infer::ExpectedFound { expected: ty::Term::Ty(expected), @@ -1614,7 +1615,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } }; - (vals, exp_found, is_simple_error) + (vals, exp_found, is_simple_error, Some(values)) } }; diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 580fb7c3e0f..90b59df472c 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -59,7 +59,7 @@ pub fn check_legal_trait_for_method_call( enum CallStep<'tcx> { Builtin(Ty<'tcx>), - DeferredClosure(ty::FnSig<'tcx>), + DeferredClosure(DefId, ty::FnSig<'tcx>), /// E.g., enum variant constructors. Overloaded(MethodCallee<'tcx>), } @@ -107,8 +107,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.confirm_builtin_call(call_expr, callee_expr, callee_ty, arg_exprs, expected) } - Some(CallStep::DeferredClosure(fn_sig)) => { - self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig) + Some(CallStep::DeferredClosure(def_id, fn_sig)) => { + self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, def_id, fn_sig) } Some(CallStep::Overloaded(method_callee)) => { @@ -171,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_substs: substs, }, ); - return Some(CallStep::DeferredClosure(closure_sig)); + return Some(CallStep::DeferredClosure(def_id, closure_sig)); } } @@ -533,6 +533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr: &'tcx hir::Expr<'tcx>, arg_exprs: &'tcx [hir::Expr<'tcx>], expected: Expectation<'tcx>, + closure_def_id: DefId, fn_sig: ty::FnSig<'tcx>, ) -> Ty<'tcx> { // `fn_sig` is the *signature* of the closure being called. We @@ -555,7 +556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_exprs, fn_sig.c_variadic, TupleArgumentsFlag::TupleArguments, - None, + Some(closure_def_id), ); fn_sig.output() diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 97d256cab68..277743e4a46 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -24,7 +24,7 @@ use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::{self, Span}; @@ -394,6 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { break 'errors; } + self.set_tainted_by_errors(); + // The algorithm here is inspired by levenshtein distance and longest common subsequence. // We'll try to detect 4 different types of mistakes: // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs @@ -502,6 +504,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { TupleMatchFound::Single => { let expected_ty = expected_input_tys[0]; let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap(); + let expected_ty = self.resolve_vars_if_possible(expected_ty); + let provided_ty = self.resolve_vars_if_possible(provided_ty); let cause = &self.misc(provided_args[0].span); let compatibility = demand_compatible(0, &mut final_arg_types); let type_error = match compatibility { @@ -523,24 +527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("arguments to this {} are incorrect", call_name), ); // Call out where the function is defined - if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { - let mut spans: MultiSpan = def_span.into(); - - let params = tcx - .hir() - .get_if_local(def_id) - .and_then(|node| node.body_id()) - .into_iter() - .map(|id| tcx.hir().body(id).params) - .flatten(); - - for param in params { - spans.push_span_label(param.span, String::new()); - } - - let def_kind = tcx.def_kind(def_id); - err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); - } + label_fn_like(tcx, &mut err, fn_def_id); err.emit(); break 'errors; } @@ -558,24 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { DiagnosticId::Error(err_code.to_owned()), ); // Call out where the function is defined - if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { - let mut spans: MultiSpan = def_span.into(); - - let params = tcx - .hir() - .get_if_local(def_id) - .and_then(|node| node.body_id()) - .into_iter() - .map(|id| tcx.hir().body(id).params) - .flatten(); - - for param in params { - spans.push_span_label(param.span, String::new()); - } - - let def_kind = tcx.def_kind(def_id); - err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); - } + label_fn_like(tcx, &mut err, fn_def_id); err.multipart_suggestion( "use parentheses to construct a tuple", vec![(start, '('.to_string()), (end, ')'.to_string())], @@ -597,13 +567,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let expected_ty = expected_input_tys[*input_idx]; let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap(); + let expected_ty = self.resolve_vars_if_possible(expected_ty); + let provided_ty = self.resolve_vars_if_possible(provided_ty); let cause = &self.misc(provided_args[*input_idx].span); let trace = TypeTrace::types(cause, true, expected_ty, provided_ty); let mut err = self.report_and_explain_type_error(trace, error); self.emit_coerce_suggestions( &mut err, &provided_args[*input_idx], - final_arg_types[*input_idx].map(|ty| ty.0).unwrap(), + provided_ty, final_arg_types[*input_idx].map(|ty| ty.1).unwrap(), None, None, @@ -613,24 +585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("arguments to this {} are incorrect", call_name), ); // Call out where the function is defined - if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { - let mut spans: MultiSpan = def_span.into(); - - let params = tcx - .hir() - .get_if_local(def_id) - .and_then(|node| node.body_id()) - .into_iter() - .map(|id| tcx.hir().body(id).params) - .flatten(); - - for param in params { - spans.push_span_label(param.span, String::new()); - } - - let def_kind = tcx.def_kind(def_id); - err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); - } + label_fn_like(tcx, &mut err, fn_def_id); err.emit(); break 'errors; } @@ -678,12 +633,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match error { Error::Invalid(input_idx, compatibility) => { let expected_ty = expected_input_tys[input_idx]; + let provided_ty = final_arg_types + .get(input_idx) + .and_then(|x| x.as_ref()) + .map(|ty| ty.0) + .unwrap_or(tcx.ty_error()); + let expected_ty = self.resolve_vars_if_possible(expected_ty); + let provided_ty = self.resolve_vars_if_possible(provided_ty); if let Compatibility::Incompatible(error) = &compatibility { - let provided_ty = final_arg_types - .get(input_idx) - .and_then(|x| x.as_ref()) - .map(|ty| ty.0) - .unwrap_or(tcx.ty_error()); let cause = &self.misc( provided_args.get(input_idx).map(|i| i.span).unwrap_or(call_span), ); @@ -948,24 +905,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Call out where the function is defined - if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { - let mut spans: MultiSpan = def_span.into(); - - let params = tcx - .hir() - .get_if_local(def_id) - .and_then(|node| node.body_id()) - .into_iter() - .flat_map(|id| tcx.hir().body(id).params) - ; - - for param in params { - spans.push_span_label(param.span, String::new()); - } - - let def_kind = tcx.def_kind(def_id); - err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); - } + label_fn_like(tcx, &mut err, fn_def_id); // And add a suggestion block for all of the parameters let suggestion_text = match suggestion_text { @@ -1790,3 +1730,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + +fn label_fn_like<'tcx>( + tcx: TyCtxt<'tcx>, + err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>, + def_id: Option<DefId>, +) { + let Some(def_id) = def_id else { + return; + }; + + if let Some(def_span) = tcx.def_ident_span(def_id) { + let mut spans: MultiSpan = def_span.into(); + + let params = tcx + .hir() + .get_if_local(def_id) + .and_then(|node| node.body_id()) + .into_iter() + .map(|id| tcx.hir().body(id).params) + .flatten(); + + for param in params { + spans.push_span_label(param.span, String::new()); + } + + let def_kind = tcx.def_kind(def_id); + err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); + } else { + match tcx.hir().get_if_local(def_id) { + Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_, _, _, span, ..), + .. + })) => { + let spans: MultiSpan = (*span).into(); + + // Note: We don't point to param spans here because they overlap + // with the closure span itself + + err.span_note(spans, "closure defined here"); + } + _ => {} + } + } +} |
