Avoid a bunch of booleans in favor of Result<(), ErrorGuaranteed>
as that more robustly proves that an error has been emitted
This commit is contained in:
parent
185a48d4b2
commit
3da92891fd
@ -1341,16 +1341,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
||||||
Ok(method)
|
Ok(method)
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => Err(if segment.ident.name == kw::Empty {
|
||||||
if segment.ident.name != kw::Empty {
|
self.dcx().span_delayed_bug(rcvr.span, "empty method name")
|
||||||
if let Some(err) =
|
} else {
|
||||||
self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)
|
match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) {
|
||||||
{
|
Ok(diag) => diag.emit(),
|
||||||
err.emit();
|
Err(guar) => guar,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(())
|
}),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call the generic checker.
|
// Call the generic checker.
|
||||||
|
@ -846,15 +846,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if item_name.name != kw::Empty {
|
if item_name.name != kw::Empty {
|
||||||
if let Some(e) = self.report_method_error(
|
self.report_method_error(
|
||||||
hir_id,
|
hir_id,
|
||||||
ty.normalized,
|
ty.normalized,
|
||||||
error,
|
error,
|
||||||
Expectation::NoExpectation,
|
Expectation::NoExpectation,
|
||||||
trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021
|
trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021
|
||||||
) {
|
)?
|
||||||
e.emit();
|
.emit();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -113,16 +113,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
method: Result<MethodCallee<'tcx>, ()>,
|
method: Result<MethodCallee<'tcx>, ErrorGuaranteed>,
|
||||||
args_no_rcvr: &'tcx [hir::Expr<'tcx>],
|
args_no_rcvr: &'tcx [hir::Expr<'tcx>],
|
||||||
tuple_arguments: TupleArgumentsFlag,
|
tuple_arguments: TupleArgumentsFlag,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let has_error = match method {
|
let has_error = match method {
|
||||||
Ok(method) => method.args.references_error() || method.sig.references_error(),
|
Ok(method) => method.args.error_reported().and(method.sig.error_reported()),
|
||||||
Err(_) => true,
|
Err(guar) => Err(guar),
|
||||||
};
|
};
|
||||||
if has_error {
|
if let Err(guar) = has_error {
|
||||||
let err_inputs = self.err_args(args_no_rcvr.len());
|
let err_inputs = self.err_args(args_no_rcvr.len());
|
||||||
|
|
||||||
let err_inputs = match tuple_arguments {
|
let err_inputs = match tuple_arguments {
|
||||||
@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
tuple_arguments,
|
tuple_arguments,
|
||||||
method.ok().map(|method| method.def_id),
|
method.ok().map(|method| method.def_id),
|
||||||
);
|
);
|
||||||
return Ty::new_misc_error(self.tcx);
|
return Ty::new_error(self.tcx, guar);
|
||||||
}
|
}
|
||||||
|
|
||||||
let method = method.unwrap();
|
let method = method.unwrap();
|
||||||
|
@ -33,7 +33,7 @@ use rustc_middle::ty::IsSuggestable;
|
|||||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::def_id::DefIdSet;
|
use rustc_span::def_id::DefIdSet;
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::{edit_distance, ExpnKind, FileName, MacroKind, Span};
|
use rustc_span::{edit_distance, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span};
|
||||||
use rustc_span::{Symbol, DUMMY_SP};
|
use rustc_span::{Symbol, DUMMY_SP};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote;
|
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote;
|
||||||
@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
error: MethodError<'tcx>,
|
error: MethodError<'tcx>,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
trait_missing_method: bool,
|
trait_missing_method: bool,
|
||||||
) -> Option<Diag<'_>> {
|
) -> Result<Diag<'_>, ErrorGuaranteed> {
|
||||||
let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
|
let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
|
||||||
hir::Node::Expr(&hir::Expr {
|
hir::Node::Expr(&hir::Expr {
|
||||||
kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
|
kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
|
||||||
@ -226,9 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Avoid suggestions when we don't know what's going on.
|
// Avoid suggestions when we don't know what's going on.
|
||||||
if rcvr_ty.references_error() {
|
rcvr_ty.error_reported()?;
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
match error {
|
match error {
|
||||||
MethodError::NoMatch(mut no_match_data) => {
|
MethodError::NoMatch(mut no_match_data) => {
|
||||||
@ -265,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&mut sources,
|
&mut sources,
|
||||||
Some(sugg_span),
|
Some(sugg_span),
|
||||||
);
|
);
|
||||||
err.emit();
|
return Err(err.emit());
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
|
MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
|
||||||
@ -286,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.unwrap_or_else(|| self.tcx.def_span(def_id));
|
.unwrap_or_else(|| self.tcx.def_span(def_id));
|
||||||
err.span_label(sp, format!("private {kind} defined here"));
|
err.span_label(sp, format!("private {kind} defined here"));
|
||||||
self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
|
self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
|
||||||
err.emit();
|
return Err(err.emit());
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
|
MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
|
||||||
@ -343,12 +341,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err.emit();
|
return Err(err.emit());
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
|
MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> {
|
fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> {
|
||||||
@ -576,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
no_match_data: &mut NoMatchData<'tcx>,
|
no_match_data: &mut NoMatchData<'tcx>,
|
||||||
expected: Expectation<'tcx>,
|
expected: Expectation<'tcx>,
|
||||||
trait_missing_method: bool,
|
trait_missing_method: bool,
|
||||||
) -> Option<Diag<'_>> {
|
) -> Result<Diag<'_>, ErrorGuaranteed> {
|
||||||
let mode = no_match_data.mode;
|
let mode = no_match_data.mode;
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
|
let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty);
|
||||||
@ -608,14 +605,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// We could pass the file for long types into these two, but it isn't strictly necessary
|
// We could pass the file for long types into these two, but it isn't strictly necessary
|
||||||
// given how targeted they are.
|
// given how targeted they are.
|
||||||
if self.suggest_wrapping_range_with_parens(
|
self.suggest_wrapping_range_with_parens(
|
||||||
tcx,
|
tcx,
|
||||||
rcvr_ty,
|
rcvr_ty,
|
||||||
source,
|
source,
|
||||||
span,
|
span,
|
||||||
item_name,
|
item_name,
|
||||||
&short_ty_str,
|
&short_ty_str,
|
||||||
) || self.suggest_constraining_numerical_ty(
|
)?;
|
||||||
|
self.suggest_constraining_numerical_ty(
|
||||||
tcx,
|
tcx,
|
||||||
rcvr_ty,
|
rcvr_ty,
|
||||||
source,
|
source,
|
||||||
@ -623,9 +621,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
item_kind,
|
item_kind,
|
||||||
item_name,
|
item_name,
|
||||||
&short_ty_str,
|
&short_ty_str,
|
||||||
) {
|
)?;
|
||||||
return None;
|
|
||||||
}
|
|
||||||
span = item_name.span;
|
span = item_name.span;
|
||||||
|
|
||||||
// Don't show generic arguments when the method can't be found in any implementation (#81576).
|
// Don't show generic arguments when the method can't be found in any implementation (#81576).
|
||||||
@ -881,7 +877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
vec![(span.shrink_to_lo(), format!("into_iter()."))],
|
vec![(span.shrink_to_lo(), format!("into_iter()."))],
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
return Some(err);
|
return Ok(err);
|
||||||
} else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) {
|
} else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) {
|
||||||
// We special case the situation where we are looking for `_` in
|
// We special case the situation where we are looking for `_` in
|
||||||
// `<TypeParam as _>::method` because otherwise the machinery will look for blanket
|
// `<TypeParam as _>::method` because otherwise the machinery will look for blanket
|
||||||
@ -1606,7 +1602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
|
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
|
||||||
Some(err)
|
Ok(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If an appropriate error source is not found, check method chain for possible candidates
|
/// If an appropriate error source is not found, check method chain for possible candidates
|
||||||
@ -2259,7 +2255,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
ty_str: &str,
|
ty_str: &str,
|
||||||
) -> bool {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
if let SelfSource::MethodCall(expr) = source {
|
if let SelfSource::MethodCall(expr) = source {
|
||||||
for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
|
for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
|
||||||
if let Node::Expr(parent_expr) = parent {
|
if let Node::Expr(parent_expr) = parent {
|
||||||
@ -2316,7 +2312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
if pick.is_ok() {
|
if pick.is_ok() {
|
||||||
let range_span = parent_expr.span.with_hi(expr.span.hi());
|
let range_span = parent_expr.span.with_hi(expr.span.hi());
|
||||||
tcx.dcx().emit_err(errors::MissingParenthesesInRange {
|
return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange {
|
||||||
span,
|
span,
|
||||||
ty_str: ty_str.to_string(),
|
ty_str: ty_str.to_string(),
|
||||||
method_name: item_name.as_str().to_string(),
|
method_name: item_name.as_str().to_string(),
|
||||||
@ -2325,13 +2321,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
left: range_span.shrink_to_lo(),
|
left: range_span.shrink_to_lo(),
|
||||||
right: range_span.shrink_to_hi(),
|
right: range_span.shrink_to_hi(),
|
||||||
}),
|
}),
|
||||||
});
|
}));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_constraining_numerical_ty(
|
fn suggest_constraining_numerical_ty(
|
||||||
@ -2343,7 +2338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
item_kind: &str,
|
item_kind: &str,
|
||||||
item_name: Ident,
|
item_name: Ident,
|
||||||
ty_str: &str,
|
ty_str: &str,
|
||||||
) -> bool {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let found_candidate = all_traits(self.tcx)
|
let found_candidate = all_traits(self.tcx)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.any(|info| self.associated_value(info.def_id, item_name).is_some());
|
.any(|info| self.associated_value(info.def_id, item_name).is_some());
|
||||||
@ -2447,10 +2442,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
err.emit();
|
return Err(err.emit());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
false
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For code `rect::area(...)`,
|
/// For code `rect::area(...)`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user