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:
Oli Scherer 2024-06-11 09:49:32 +00:00
parent 185a48d4b2
commit 3da92891fd
4 changed files with 35 additions and 44 deletions

View File

@ -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.

View File

@ -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

View File

@ -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();

View File

@ -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(...)`,