8 - Make more use of let_chains
This commit is contained in:
parent
08504c64aa
commit
658ff942b0
10 changed files with 146 additions and 186 deletions
|
@ -606,9 +606,10 @@ 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) {
|
||||
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",
|
||||
|
@ -617,8 +618,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
|
||||
err.span_label(span, "expected due to this");
|
||||
}
|
||||
|
@ -1748,14 +1747,13 @@ 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() {
|
||||
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
|
||||
// thing.
|
||||
|
@ -2046,11 +2044,10 @@ 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 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
|
||||
{
|
||||
if code.chars().count() == 1 {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"if you meant to write a `char` literal, use single quotes",
|
||||
|
@ -2059,8 +2056,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If a string was expected and the found expression is a character literal,
|
||||
// perhaps the user meant to write `"s"` to specify a string literal.
|
||||
(ty::Ref(_, r, _), ty::Char) if r.is_str() => {
|
||||
|
@ -2080,19 +2075,17 @@ 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
|
||||
}
|
||||
FailureCode::Error0644(failure_str) => {
|
||||
|
|
|
@ -114,19 +114,17 @@ 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) {
|
||||
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| {
|
||||
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)
|
||||
|
@ -136,7 +134,6 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> {
|
|||
self.found_exact_method_call = Some(&expr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(const_generics): Currently, any uninferred `const` generics arguments
|
||||
// are handled specially, but instead they should be handled in `annotate_method_call`,
|
||||
|
@ -602,11 +599,9 @@ 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) {
|
||||
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();
|
||||
let suffix = match local_visitor.found_node_ty {
|
||||
|
@ -736,10 +731,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// | help: specify type like: `<Impl as Into<u32>>::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 {
|
||||
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!(
|
||||
|
@ -757,9 +753,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// Suggest specifying type params or point out the return type of the call:
|
||||
//
|
||||
// error[E0282]: type annotations needed
|
||||
|
|
|
@ -223,22 +223,21 @@ 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() {
|
||||
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()`.
|
||||
if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
|
||||
&& 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:
|
||||
|
@ -247,13 +246,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
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)
|
||||
{
|
||||
if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) {
|
||||
override_error_code = Some(ident.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) {
|
||||
// Provide a more targeted error code and description.
|
||||
err.code(rustc_errors::error_code!(E0772));
|
||||
|
|
|
@ -23,38 +23,27 @@ 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,
|
||||
_,
|
||||
_, var_origin, sub_origin, _sub, sup_origin, _sup, _,
|
||||
) = error.clone()
|
||||
{
|
||||
if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin) {
|
||||
if let (
|
||||
&& 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())
|
||||
) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code())
|
||||
&& sup_expected_found == sub_expected_found
|
||||
{
|
||||
if sup_expected_found == sub_expected_found {
|
||||
self.emit_err(
|
||||
var_origin.span(),
|
||||
*sub_expected,
|
||||
*sub_found,
|
||||
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 {
|
||||
&& let SubregionOrigin::CompareImplTypeObligation {
|
||||
span,
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
|
@ -68,7 +57,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
);
|
||||
return Some(ErrorGuaranteed);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
|
|
@ -220,13 +220,11 @@ 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) {
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -304,11 +304,9 @@ 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 {
|
||||
if let ReEmpty(a_universe) = *a_region && a_universe == b_universe {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let mut lub = self.lub_concrete_regions(a_region, cur_region);
|
||||
if lub == cur_region {
|
||||
|
@ -324,11 +322,9 @@ 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) {
|
||||
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);
|
||||
|
||||
|
|
|
@ -963,11 +963,9 @@ where
|
|||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
debug!("TypeGeneralizer::regions(a={:?})", a);
|
||||
|
||||
if let ty::ReLateBound(debruijn, _) = *a {
|
||||
if debruijn < self.first_free_index {
|
||||
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
|
||||
// replace all the regions in the source type. In the main
|
||||
|
|
|
@ -470,11 +470,9 @@ 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() {
|
||||
if let VerifyBound::AllBounds(ref bs) = verify.bound && bs.is_empty() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let index = self.data.verifys.len();
|
||||
self.data.verifys.push(verify);
|
||||
|
|
|
@ -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(let_else)]
|
||||
#![feature(never_type)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(label_break_value)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
|
|
@ -60,13 +60,11 @@ 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() {
|
||||
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();
|
||||
let msg = if trait_span.is_none() || spans.is_empty() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue