diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 5b27ebe3416ae..3321f029c8d8c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1342,14 +1342,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(method) } Err(error) => { - if segment.ident.name != kw::Empty { - if let Some(err) = - self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) - { - err.emit(); - } + if segment.ident.name == kw::Empty { + span_bug!(rcvr.span, "empty method name") + } else { + Err(self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)) } - Err(()) } }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e354e1ec59c63..94e879ae9c3ed 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -660,8 +660,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - pub(crate) fn err_args(&self, len: usize) -> Vec> { - let ty_error = Ty::new_misc_error(self.tcx); + pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec> { + let ty_error = Ty::new_error(self.tcx, guar); vec![ty_error; len] } @@ -846,15 +846,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if item_name.name != kw::Empty { - if let Some(e) = self.report_method_error( + self.report_method_error( hir_id, ty.normalized, error, Expectation::NoExpectation, trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 - ) { - e.emit(); - } + ); } result diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b8333d4749378..e20a6ef7c1339 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -113,17 +113,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, sp: Span, expr: &'tcx hir::Expr<'tcx>, - method: Result, ()>, + method: Result, ErrorGuaranteed>, args_no_rcvr: &'tcx [hir::Expr<'tcx>], tuple_arguments: TupleArgumentsFlag, expected: Expectation<'tcx>, ) -> Ty<'tcx> { let has_error = match method { - Ok(method) => method.args.references_error() || method.sig.references_error(), - Err(_) => true, + Ok(method) => method.args.error_reported().and(method.sig.error_reported()), + Err(guar) => Err(guar), }; - if has_error { - let err_inputs = self.err_args(args_no_rcvr.len()); + if let Err(guar) = has_error { + let err_inputs = self.err_args(args_no_rcvr.len(), guar); let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, @@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, 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(); @@ -237,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // Otherwise, there's a mismatch, so clear out what we're expecting, and set // our input types to err_args so we don't blow up the error messages - struct_span_code_err!( + let guar = struct_span_code_err!( tcx.dcx(), call_span, E0059, @@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for the function trait is neither a tuple nor unit" ) .emit(); - (self.err_args(provided_args.len()), None) + (self.err_args(provided_args.len(), guar), None) } } } else { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 803d155432461..28d738c11c8fa 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -33,7 +33,7 @@ use rustc_middle::ty::IsSuggestable; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; 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_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote; @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Option> { + ) -> ErrorGuaranteed { let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), @@ -226,8 +226,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Avoid suggestions when we don't know what's going on. - if rcvr_ty.references_error() { - return None; + if let Err(guar) = rcvr_ty.error_reported() { + return guar; } match error { @@ -265,7 +265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut sources, Some(sugg_span), ); - err.emit(); + return err.emit(); } MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { @@ -286,7 +286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); - err.emit(); + return err.emit(); } MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => { @@ -343,12 +343,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); + return err.emit(); } 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<'_> { @@ -564,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn report_no_match_method_error( + fn report_no_match_method_error( &self, mut span: Span, rcvr_ty: Ty<'tcx>, @@ -576,7 +575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Option> { + ) -> ErrorGuaranteed { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); @@ -608,14 +607,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - if self.suggest_wrapping_range_with_parens( + if let Err(guar) = self.report_failed_method_call_on_range_end( tcx, rcvr_ty, source, span, item_name, &short_ty_str, - ) || self.suggest_constraining_numerical_ty( + ) { + return guar; + } + if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( tcx, rcvr_ty, source, @@ -624,7 +626,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name, &short_ty_str, ) { - return None; + return guar; } span = item_name.span; @@ -881,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(span.shrink_to_lo(), format!("into_iter()."))], Applicability::MaybeIncorrect, ); - return Some(err); + return err.emit(); } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in // `::method` because otherwise the machinery will look for blanket @@ -1606,7 +1608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); - Some(err) + err.emit() } /// If an appropriate error source is not found, check method chain for possible candidates @@ -2251,7 +2253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Suggest possible range with adding parentheses, for example: /// when encountering `0..1.map(|i| i + 1)` suggest `(0..1).map(|i| i + 1)`. - fn suggest_wrapping_range_with_parens( + fn report_failed_method_call_on_range_end( &self, tcx: TyCtxt<'tcx>, actual: Ty<'tcx>, @@ -2259,7 +2261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, item_name: Ident, ty_str: &str, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { if let SelfSource::MethodCall(expr) = source { for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) { if let Node::Expr(parent_expr) = parent { @@ -2316,7 +2318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { 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, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), @@ -2325,16 +2327,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { left: range_span.shrink_to_lo(), right: range_span.shrink_to_hi(), }), - }); - return true; + })); } } } } - false + Ok(()) } - fn suggest_constraining_numerical_ty( + fn report_failed_method_call_on_numerical_infer_var( &self, tcx: TyCtxt<'tcx>, actual: Ty<'tcx>, @@ -2343,7 +2344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind: &str, item_name: Ident, ty_str: &str, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { let found_candidate = all_traits(self.tcx) .into_iter() .any(|info| self.associated_value(info.def_id, item_name).is_some()); @@ -2447,10 +2448,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => {} } - err.emit(); - return true; + return Err(err.emit()); } - false + Ok(()) } /// For code `rect::area(...)`, diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 3ff86f700a535..fe399bc77e32a 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" tracing = "0.1.28" tracing-core = "=0.1.30" # FIXME(Nilstrieb) tracing has a deadlock: https://github.com/tokio-rs/tracing/issues/2635 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } -tracing-tree = "0.3.0" +tracing-tree = "0.3.1" # tidy-alphabetical-end [dev-dependencies] diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 41b26ecce3c54..01b6e342df047 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -58,6 +58,7 @@ pub struct LoggerConfig { pub verbose_thread_ids: Result, pub backtrace: Result, pub wraptree: Result, + pub lines: Result, } impl LoggerConfig { @@ -69,6 +70,7 @@ impl LoggerConfig { verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")), backtrace: env::var(format!("{env}_BACKTRACE")), wraptree: env::var(format!("{env}_WRAPTREE")), + lines: env::var(format!("{env}_LINES")), } } } @@ -101,6 +103,11 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { Err(_) => false, }; + let lines = match cfg.lines { + Ok(v) => &v == "1", + Err(_) => false, + }; + let mut layer = tracing_tree::HierarchicalLayer::default() .with_writer(io::stderr) .with_ansi(color_logs) @@ -108,6 +115,7 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { .with_verbose_exit(verbose_entry_exit) .with_verbose_entry(verbose_entry_exit) .with_indent_amount(2) + .with_indent_lines(lines) .with_thread_ids(verbose_thread_ids) .with_thread_names(verbose_thread_ids);