From 658ff942b04d288b346a7e89ac425216688fac78 Mon Sep 17 00:00:00 2001 From: Caio Date: Wed, 2 Mar 2022 16:02:37 -0300 Subject: [PATCH] 8 - Make more use of `let_chains` --- .../src/infer/error_reporting/mod.rs | 77 ++++++++-------- .../infer/error_reporting/need_type_info.rs | 89 +++++++++---------- .../nice_region_error/static_impl_trait.rs | 47 +++++----- .../trait_impl_difference.rs | 64 ++++++------- compiler/rustc_infer/src/infer/fudge.rs | 10 +-- .../src/infer/lexical_region_resolve/mod.rs | 12 +-- .../rustc_infer/src/infer/nll_relate/mod.rs | 6 +- .../src/infer/region_constraints/mod.rs | 6 +- compiler/rustc_infer/src/lib.rs | 9 +- .../src/traits/error_reporting/mod.rs | 10 +-- 10 files changed, 145 insertions(+), 185 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index edb2b11c0397c..bf4882d459573 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -606,17 +606,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // don't show type `_` err.span_label(span, format!("this expression has type `{}`", ty)); } - if let Some(ty::error::ExpectedFound { found, .. }) = exp_found { - if ty.is_box() && ty.boxed_ty() == found { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - err.span_suggestion( - span, - "consider dereferencing the boxed value", - format!("*{}", snippet), - Applicability::MachineApplicable, - ); - } - } + if let Some(ty::error::ExpectedFound { found, .. }) = exp_found + && ty.is_box() && ty.boxed_ty() == found + && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + { + err.span_suggestion( + span, + "consider dereferencing the boxed value", + format!("*{}", snippet), + Applicability::MachineApplicable, + ); } } ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => { @@ -1748,13 +1747,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.check_and_note_conflicting_crates(diag, terr); self.tcx.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id.to_def_id()); - if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values { - if let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() { - if let Some(def_id) = def_id.as_local() { - let span = self.tcx.def_span(def_id); - diag.span_note(span, "this closure does not fulfill the lifetime requirements"); - } - } + if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values + && let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() + && let Some(def_id) = def_id.as_local() + { + let span = self.tcx.def_span(def_id); + diag.span_note(span, "this closure does not fulfill the lifetime requirements"); } // It reads better to have the error origin as the final @@ -2046,19 +2044,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // containing a single character, perhaps the user meant to write `'c'` to // specify a character literal (issue #92479) (ty::Char, ty::Ref(_, r, _)) if r.is_str() => { - if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) { - if let Some(code) = - code.strip_prefix('"').and_then(|s| s.strip_suffix('"')) - { - if code.chars().count() == 1 { - err.span_suggestion( - span, - "if you meant to write a `char` literal, use single quotes", - format!("'{}'", code), - Applicability::MachineApplicable, - ); - } - } + if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) + && let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"')) + && code.chars().count() == 1 + { + err.span_suggestion( + span, + "if you meant to write a `char` literal, use single quotes", + format!("'{}'", code), + Applicability::MachineApplicable, + ); } } // If a string was expected and the found expression is a character literal, @@ -2080,18 +2075,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => {} } } - if let MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = - *trace.cause.code() + let code = trace.cause.code(); + if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code + && let hir::MatchSource::TryDesugar = source + && let Some((expected_ty, found_ty)) = self.values_str(trace.values) { - if let hir::MatchSource::TryDesugar = source { - if let Some((expected_ty, found_ty)) = self.values_str(trace.values) { - err.note(&format!( - "`?` operator cannot convert from `{}` to `{}`", - found_ty.content(), - expected_ty.content(), - )); - } - } + err.note(&format!( + "`?` operator cannot convert from `{}` to `{}`", + found_ty.content(), + expected_ty.content(), + )); } err } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 8ff0eed71ed03..3bc30f0220d40 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -114,28 +114,25 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> { } fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { - if let ExprKind::Match(scrutinee, [_, arm], MatchSource::ForLoopDesugar) = expr.kind { - if let Some(pat) = arm.pat.for_loop_some() { - if let Some(ty) = self.node_ty_contains_target(pat.hir_id) { - self.found_for_loop_iter = Some(scrutinee); - self.found_node_ty = Some(ty); - return; - } - } + if let ExprKind::Match(scrutinee, [_, arm], MatchSource::ForLoopDesugar) = expr.kind + && let Some(pat) = arm.pat.for_loop_some() + && let Some(ty) = self.node_ty_contains_target(pat.hir_id) + { + self.found_for_loop_iter = Some(scrutinee); + self.found_node_ty = Some(ty); + return; } - if let ExprKind::MethodCall(segment, exprs, _) = expr.kind { - if segment.ident.span == self.target_span - && Some(self.target) - == self.infcx.in_progress_typeck_results.and_then(|typeck_results| { - typeck_results - .borrow() - .node_type_opt(exprs.first().unwrap().hir_id) - .map(Into::into) - }) - { - self.found_exact_method_call = Some(&expr); - return; - } + if let ExprKind::MethodCall(segment, exprs, _) = expr.kind + && segment.ident.span == self.target_span + && Some(self.target) == self.infcx.in_progress_typeck_results.and_then(|typeck_results| { + typeck_results + .borrow() + .node_type_opt(exprs.first().unwrap().hir_id) + .map(Into::into) + }) + { + self.found_exact_method_call = Some(&expr); + return; } // FIXME(const_generics): Currently, any uninferred `const` generics arguments @@ -602,10 +599,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); let use_diag = local_visitor.found_use_diagnostic.as_ref(); - if let Some(use_diag) = use_diag { - if use_diag.applies_to(err_span) { - use_diag.attach_note(&mut err); - } + if let Some(use_diag) = use_diag && use_diag.applies_to(err_span) { + use_diag.attach_note(&mut err); } let param_type = arg_data.kind.descr(); @@ -736,29 +731,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // | help: specify type like: `>::into(foo_impl)` // | // = note: cannot satisfy `Impl: Into<_>` - if !impl_candidates.is_empty() && e.span.contains(span) { - if let Some(expr) = exprs.first() { - if let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind { - if let [path_segment] = path.segments { - let candidate_len = impl_candidates.len(); - let suggestions = impl_candidates.iter().map(|candidate| { - format!( - "{}::{}({})", - candidate, segment.ident, path_segment.ident - ) - }); - err.span_suggestions( - e.span, - &format!( - "use the fully qualified path for the potential candidate{}", - pluralize!(candidate_len), - ), - suggestions, - Applicability::MaybeIncorrect, - ); - } - } - }; + if !impl_candidates.is_empty() && e.span.contains(span) + && let Some(expr) = exprs.first() + && let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind + && let [path_segment] = path.segments + { + let candidate_len = impl_candidates.len(); + let suggestions = impl_candidates.iter().map(|candidate| { + format!( + "{}::{}({})", + candidate, segment.ident, path_segment.ident + ) + }); + err.span_suggestions( + e.span, + &format!( + "use the fully qualified path for the potential candidate{}", + pluralize!(candidate_len), + ), + suggestions, + Applicability::MaybeIncorrect, + ); } // Suggest specifying type params or point out the return type of the call: // diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index a6de0c3d9fb5c..99dd418015b14 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -223,35 +223,32 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); let mut override_error_code = None; - if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin { - if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() { - // Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a - // `'static` lifetime when called as a method on a binding: `bar.qux()`. - if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) { - override_error_code = Some(ctxt.assoc_item.name); - } - } + if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin + && let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() + // Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a + // `'static` lifetime when called as a method on a binding: `bar.qux()`. + && self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) + { + override_error_code = Some(ctxt.assoc_item.name); } - if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin { - let code = match cause.code() { + + if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin + && let code = match cause.code() { ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), _ => cause.code(), - }; - if let (ObligationCauseCode::ItemObligation(item_def_id), None) = - (code, override_error_code) + } + && let (ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code) + { + // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` + // lifetime as above, but called using a fully-qualified path to the method: + // `Foo::qux(bar)`. + let mut v = TraitObjectVisitor(FxHashSet::default()); + v.visit_ty(param.param_ty); + if let Some((ident, self_ty)) = + self.get_impl_ident_and_self_ty_from_trait(*item_def_id, &v.0) + && self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) { - // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` - // lifetime as above, but called using a fully-qualified path to the method: - // `Foo::qux(bar)`. - let mut v = TraitObjectVisitor(FxHashSet::default()); - v.visit_ty(param.param_ty); - if let Some((ident, self_ty)) = - self.get_impl_ident_and_self_ty_from_trait(*item_def_id, &v.0) - { - if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) { - override_error_code = Some(ident.name); - } - } + override_error_code = Some(ident.name); } } if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 673c112163e1b..3f0f50bb75af1 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -23,51 +23,39 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let error = self.error.as_ref()?; debug!("try_report_impl_not_conforming_to_trait {:?}", error); if let RegionResolutionError::SubSupConflict( - _, - var_origin, - sub_origin, - _sub, - sup_origin, - _sup, - _, - ) = error.clone() + _, var_origin, sub_origin, _sub, sup_origin, _sup, _, + ) = error.clone() + && let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin) + && let ( + sub_expected_found @ Some((sub_expected, sub_found)), + sup_expected_found @ Some(_), + CompareImplMethodObligation { trait_item_def_id, .. }, + ) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code()) + && sup_expected_found == sub_expected_found { - if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin) { - if let ( - sub_expected_found @ Some((sub_expected, sub_found)), - sup_expected_found @ Some(_), - CompareImplMethodObligation { trait_item_def_id, .. }, - ) = (&sub_trace.values.ty(), &sup_trace.values.ty(), sub_trace.cause.code()) - { - if sup_expected_found == sub_expected_found { - self.emit_err( - var_origin.span(), - *sub_expected, - *sub_found, - *trait_item_def_id, - ); - return Some(ErrorGuaranteed); - } - } - } + self.emit_err( + var_origin.span(), + sub_expected, + sub_found, + *trait_item_def_id, + ); + return Some(ErrorGuaranteed); } if let RegionResolutionError::ConcreteFailure(origin, _, _) - | RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone() - { - if let SubregionOrigin::CompareImplTypeObligation { + | RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone() + && let SubregionOrigin::CompareImplTypeObligation { span, impl_item_def_id, trait_item_def_id, } = origin - { - self.emit_associated_type_err( - span, - self.infcx.tcx.item_name(impl_item_def_id), - impl_item_def_id, - trait_item_def_id, - ); - return Some(ErrorGuaranteed); - } + { + self.emit_associated_type_err( + span, + self.infcx.tcx.item_name(impl_item_def_id), + impl_item_def_id, + trait_item_def_id, + ); + return Some(ErrorGuaranteed); } None } diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index c5c131a5b796b..c5b90f79dc284 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -220,12 +220,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - if let ty::ReVar(vid) = *r { - if self.region_vars.0.contains(&vid) { - let idx = vid.index() - self.region_vars.0.start.index(); - let origin = self.region_vars.1[idx]; - return self.infcx.next_region_var(origin); - } + if let ty::ReVar(vid) = *r && self.region_vars.0.contains(&vid) { + let idx = vid.index() - self.region_vars.0.start.index(); + let origin = self.region_vars.1[idx]; + return self.infcx.next_region_var(origin); } r } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index c7b4a96fb7853..0f341a947ad35 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -304,10 +304,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // check below for a common case, here purely as an // optimization. let b_universe = self.var_infos[b_vid].universe; - if let ReEmpty(a_universe) = *a_region { - if a_universe == b_universe { - return false; - } + if let ReEmpty(a_universe) = *a_region && a_universe == b_universe { + return false; } let mut lub = self.lub_concrete_regions(a_region, cur_region); @@ -324,10 +322,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // tighter bound than `'static`. // // (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.) - if let ty::RePlaceholder(p) = *lub { - if b_universe.cannot_name(p.universe) { - lub = self.tcx().lifetimes.re_static; - } + if let ty::RePlaceholder(p) = *lub && b_universe.cannot_name(p.universe) { + lub = self.tcx().lifetimes.re_static; } debug!("Expanding value of {:?} from {:?} to {:?}", b_vid, cur_region, lub); diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 60f776d8c1f67..69db6509b798d 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -963,10 +963,8 @@ where ) -> RelateResult<'tcx, ty::Region<'tcx>> { debug!("TypeGeneralizer::regions(a={:?})", a); - if let ty::ReLateBound(debruijn, _) = *a { - if debruijn < self.first_free_index { - return Ok(a); - } + if let ty::ReLateBound(debruijn, _) = *a && debruijn < self.first_free_index { + return Ok(a); } // For now, we just always create a fresh region variable to diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index a5bd3b15c8d8f..6966f5014464e 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -470,10 +470,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { debug!("RegionConstraintCollector: add_verify({:?})", verify); // skip no-op cases known to be satisfied - if let VerifyBound::AllBounds(ref bs) = verify.bound { - if bs.is_empty() { - return; - } + if let VerifyBound::AllBounds(ref bs) = verify.bound && bs.is_empty() { + return; } let index = self.data.verifys.len(); diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 4960630051f3e..08e005364ce64 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -12,18 +12,19 @@ //! //! This API is completely unstable and subject to change. +#![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(box_patterns)] +#![feature(control_flow_enum)] #![feature(derive_default_enum)] #![feature(extend_one)] +#![feature(label_break_value)] +#![feature(let_chains)] #![feature(let_else)] -#![feature(never_type)] -#![feature(control_flow_enum)] #![feature(min_specialization)] -#![feature(label_break_value)] +#![feature(never_type)] #![recursion_limit = "512"] // For rustdoc -#![allow(rustc::potential_query_instability)] #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 5e93c002168c6..c8ef08f48b609 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -60,12 +60,10 @@ pub fn report_object_safety_error<'tcx>( let mut multi_span = vec![]; let mut messages = vec![]; for violation in violations { - if let ObjectSafetyViolation::SizedSelf(sp) = &violation { - if !sp.is_empty() { - // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations - // with a `Span`. - reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into())); - } + if let ObjectSafetyViolation::SizedSelf(sp) = &violation && !sp.is_empty() { + // Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations + // with a `Span`. + reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into())); } if reported_violations.insert(violation.clone()) { let spans = violation.spans();