Skip to content

Commit

Permalink
Rollup merge of rust-lang#94142 - est31:let_else_typeck, r=oli-obk
Browse files Browse the repository at this point in the history
rustc_typeck: adopt let else in more places

Continuation of rust-lang#89933, rust-lang#91018, rust-lang#91481, rust-lang#93046, rust-lang#93590, rust-lang#94011.

I have extended my clippy lint to also recognize tuple passing and match statements. The diff caused by fixing it is way above 1 thousand lines. Thus, I split it up into multiple pull requests to make reviewing easier. This PR handles rustc_typeck.
  • Loading branch information
matthiaskrgr authored Feb 19, 2022
2 parents a69aaf4 + bb0a2f9 commit 7ca1c48
Show file tree
Hide file tree
Showing 22 changed files with 135 additions and 229 deletions.
9 changes: 3 additions & 6 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1808,12 +1808,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
(_, Res::SelfTy { trait_: Some(_), alias_to: Some((impl_def_id, _)) }) => {
// `Self` in an impl of a trait -- we have a concrete self type and a
// trait reference.
let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
Some(trait_ref) => trait_ref,
None => {
// A cycle error occurred, most likely.
return Err(ErrorReported);
}
let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
// A cycle error occurred, most likely.
return Err(ErrorReported);
};

self.one_bound_for_assoc_type(
Expand Down
11 changes: 2 additions & 9 deletions compiler/rustc_typeck/src/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(self.tcx.lang_items().fn_mut_trait(), Ident::with_dummy_span(sym::call_mut), true),
(self.tcx.lang_items().fn_once_trait(), Ident::with_dummy_span(sym::call_once), false),
] {
let trait_def_id = match opt_trait_def_id {
Some(def_id) => def_id,
None => continue,
};
let Some(trait_def_id) = opt_trait_def_id else { continue };

let opt_input_types = opt_arg_exprs.map(|arg_exprs| {
[self.tcx.mk_tup(arg_exprs.iter().map(|e| {
Expand All @@ -246,11 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if borrow {
// Check for &self vs &mut self in the method signature. Since this is either
// the Fn or FnMut trait, it should be one of those.
let (region, mutbl) = if let ty::Ref(r, _, mutbl) =
method.sig.inputs()[0].kind()
{
(r, mutbl)
} else {
let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else {
// The `fn`/`fn_mut` lang item is ill-formed, which should have
// caused an error elsewhere.
self.tcx
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_typeck/src/check/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,21 +799,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
let expr_kind = fcx.pointer_kind(m_expr.ty, self.span)?;
let cast_kind = fcx.pointer_kind(m_cast.ty, self.span)?;

let cast_kind = match cast_kind {
let Some(cast_kind) = cast_kind else {
// We can't cast if target pointer kind is unknown
None => return Err(CastError::UnknownCastPtrKind),
Some(cast_kind) => cast_kind,
return Err(CastError::UnknownCastPtrKind);
};

// Cast to thin pointer is OK
if cast_kind == PointerKind::Thin {
return Ok(CastKind::PtrPtrCast);
}

let expr_kind = match expr_kind {
let Some(expr_kind) = expr_kind else {
// We can't cast to fat pointer if source pointer kind is unknown
None => return Err(CastError::UnknownExprPtrKind),
Some(expr_kind) => expr_kind,
return Err(CastError::UnknownExprPtrKind);
};

// thin -> fat? report invalid cast (don't complain about vtable kinds)
Expand Down
16 changes: 5 additions & 11 deletions compiler/rustc_typeck/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,10 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Spa
// have UB during initialization if they are uninhabited, but there also seems to be no good
// reason to allow any statics to be uninhabited.
let ty = tcx.type_of(def_id);
let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
Ok(l) => l,
Err(_) => {
// Generic statics are rejected, but we still reach this case.
tcx.sess.delay_span_bug(span, "generic static must be rejected");
return;
}
let Ok(layout) = tcx.layout_of(ParamEnv::reveal_all().and(ty)) else {
// Generic statics are rejected, but we still reach this case.
tcx.sess.delay_span_bug(span, "generic static must be rejected");
return;
};
if layout.abi.is_uninhabited() {
tcx.struct_span_lint_hir(
Expand Down Expand Up @@ -852,10 +849,7 @@ pub(super) fn check_specialization_validity<'tcx>(
impl_id: DefId,
impl_item: &hir::ImplItemRef,
) {
let ancestors = match trait_def.ancestors(tcx, impl_id) {
Ok(ancestors) => ancestors,
Err(_) => return,
};
let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) else { return };
let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| {
if parent.is_from_trait() {
None
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_typeck/src/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,12 +676,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// We do not expect any bound regions in our predicate, so
// skip past the bound vars.
let predicate = match predicate.no_bound_vars() {
Some(p) => p,
None => {
debug!("deduce_future_output_from_projection: has late-bound regions");
return None;
}
let Some(predicate) = predicate.no_bound_vars() else {
debug!("deduce_future_output_from_projection: has late-bound regions");
return None;
};

// Check that this is a projection from the `Future` trait.
Expand Down
21 changes: 8 additions & 13 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// (e.g., in example above, the failure from relating `Vec<T>`
// to the target type), since that should be the least
// confusing.
let InferOk { value: ty, mut obligations } = match found {
Some(d) => d,
None => {
let err = first_error.expect("coerce_borrowed_pointer had no error");
debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
return Err(err);
}
let Some(InferOk { value: ty, mut obligations }) = found else {
let err = first_error.expect("coerce_borrowed_pointer had no error");
debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
return Err(err);
};

if ty == a && mt_a.mutbl == hir::Mutability::Not && autoderef.step_count() == 1 {
Expand All @@ -461,9 +458,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {

// Now apply the autoref. We have to extract the region out of
// the final ref type we got.
let r_borrow = match ty.kind() {
ty::Ref(r_borrow, _, _) => r_borrow,
_ => span_bug!(span, "expected a ref type, got {:?}", ty),
let ty::Ref(r_borrow, _, _) = ty.kind() else {
span_bug!(span, "expected a ref type, got {:?}", ty);
};
let mutbl = match mutbl_b {
hir::Mutability::Not => AutoBorrowMutability::Not,
Expand Down Expand Up @@ -944,9 +940,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We don't ever need two-phase here since we throw out the result of the coercion
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
self.probe(|_| {
let ok = match coerce.coerce(source, target) {
Ok(ok) => ok,
_ => return false,
let Ok(ok) = coerce.coerce(source, target) else {
return false;
};
let mut fcx = traits::FulfillmentContext::new_in_snapshot();
fcx.register_predicate_obligations(self, ok.obligations);
Expand Down
45 changes: 20 additions & 25 deletions compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,44 +435,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// opt.map(|param| { takes_ref(param) });
/// ```
fn can_use_as_ref(&self, expr: &hir::Expr<'_>) -> Option<(Span, &'static str, String)> {
let path = match expr.kind {
hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => path,
_ => return None,
let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.kind else {
return None;
};

let local_id = match path.res {
hir::def::Res::Local(id) => id,
_ => return None,
let hir::def::Res::Local(local_id) = path.res else {
return None;
};

let local_parent = self.tcx.hir().get_parent_node(local_id);
let param_hir_id = match self.tcx.hir().find(local_parent) {
Some(Node::Param(hir::Param { hir_id, .. })) => hir_id,
_ => return None,
let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) = self.tcx.hir().find(local_parent) else {
return None;
};

let param_parent = self.tcx.hir().get_parent_node(*param_hir_id);
let (expr_hir_id, closure_fn_decl) = match self.tcx.hir().find(param_parent) {
Some(Node::Expr(hir::Expr {
hir_id,
kind: hir::ExprKind::Closure(_, decl, ..),
..
})) => (hir_id, decl),
_ => return None,
let Some(Node::Expr(hir::Expr {
hir_id: expr_hir_id,
kind: hir::ExprKind::Closure(_, closure_fn_decl, ..),
..
})) = self.tcx.hir().find(param_parent) else {
return None;
};

let expr_parent = self.tcx.hir().get_parent_node(*expr_hir_id);
let hir = self.tcx.hir().find(expr_parent);
let closure_params_len = closure_fn_decl.inputs.len();
let (method_path, method_expr) = match (hir, closure_params_len) {
(
Some(Node::Expr(hir::Expr {
kind: hir::ExprKind::MethodCall(segment, expr, _),
..
})),
1,
) => (segment, expr),
_ => return None,
let (
Some(Node::Expr(hir::Expr {
kind: hir::ExprKind::MethodCall(method_path, method_expr, _),
..
})),
1,
) = (hir, closure_params_len) else {
return None;
};

let self_ty = self.typeck_results.borrow().node_type(method_expr[0].hir_id);
Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,15 +622,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the `enclosing_loops` field and let's coerce the
// type of `expr_opt` into what is expected.
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
let ctxt = match enclosing_breakables.opt_find_breakable(target_id) {
Some(ctxt) => ctxt,
None => {
// Avoid ICE when `break` is inside a closure (#65383).
return tcx.ty_error_with_message(
expr.span,
"break was outside loop, but no error was emitted",
);
}
let Some(ctxt) = enclosing_breakables.opt_find_breakable(target_id) else {
// Avoid ICE when `break` is inside a closure (#65383).
return tcx.ty_error_with_message(
expr.span,
"break was outside loop, but no error was emitted",
);
};

if let Some(ref mut coerce) = ctxt.coerce {
Expand Down
17 changes: 5 additions & 12 deletions compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,10 +745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
formal_args: &[Ty<'tcx>],
) -> Vec<Ty<'tcx>> {
let formal_ret = self.resolve_vars_with_obligations(formal_ret);
let ret_ty = match expected_ret.only_has_type(self) {
Some(ret) => ret,
None => return Vec::new(),
};
let Some(ret_ty) = expected_ret.only_has_type(self) else { return Vec::new() };
let expect_args = self
.fudge_inference_if_ok(|| {
// Attempt to apply a subtyping relationship between the formal
Expand Down Expand Up @@ -1044,9 +1041,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Be helpful when the user wrote `{... expr;}` and
// taking the `;` off is enough to fix the error.
let last_stmt = blk.stmts.last()?;
let last_expr = match last_stmt.kind {
hir::StmtKind::Semi(ref e) => e,
_ => return None,
let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else {
return None;
};
let last_expr_ty = self.node_ty(last_expr.hir_id);
let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) {
Expand All @@ -1061,11 +1057,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
last_def_id, last_bounds, exp_def_id, exp_bounds
);

let (last_local_id, exp_local_id) =
match (last_def_id.as_local(), exp_def_id.as_local()) {
(Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id),
(_, _) => return None,
};
let last_local_id = last_def_id.as_local()?;
let exp_local_id = exp_def_id.as_local()?;

match (
&self.tcx.hir().expect_item(last_local_id).kind,
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
// can suggest Box::pin.
let parent = self.tcx.hir().get_parent_node(expr.hir_id);
let fn_name = match self.tcx.hir().find(parent) {
Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) => fn_name,
_ => return false,
let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) = self.tcx.hir().find(parent) else {
return false;
};
match fn_name.kind {
ExprKind::Path(QPath::TypeRelative(
Expand Down
18 changes: 6 additions & 12 deletions compiler/rustc_typeck/src/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// time writing the results into the various typeck results.
let mut autoderef =
self.autoderef_overloaded_span(self.span, unadjusted_self_ty, self.call_expr.span);
let (ty, n) = match autoderef.nth(pick.autoderefs) {
Some(n) => n,
None => {
return self.tcx.ty_error_with_message(
rustc_span::DUMMY_SP,
&format!("failed autoderef {}", pick.autoderefs),
);
}
let Some((ty, n)) = autoderef.nth(pick.autoderefs) else {
return self.tcx.ty_error_with_message(
rustc_span::DUMMY_SP,
&format!("failed autoderef {}", pick.autoderefs),
);
};
assert_eq!(n, pick.autoderefs);

Expand Down Expand Up @@ -520,10 +517,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
&self,
predicates: &ty::InstantiatedPredicates<'tcx>,
) -> Option<Span> {
let sized_def_id = match self.tcx.lang_items().sized_trait() {
Some(def_id) => def_id,
None => return None,
};
let sized_def_id = self.tcx.lang_items().sized_trait()?;

traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied())
// We don't care about regions here.
Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_typeck/src/check/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Trait must have a method named `m_name` and it should not have
// type parameters or early-bound regions.
let tcx = self.tcx;
let method_item = match self.associated_value(trait_def_id, m_name) {
Some(method_item) => method_item,
None => {
tcx.sess.delay_span_bug(
span,
"operator trait does not have corresponding operator method",
);
return None;
}
let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
tcx.sess.delay_span_bug(
span,
"operator trait does not have corresponding operator method",
);
return None;
};
let def_id = method_item.def_id;
let generics = tcx.generics_of(def_id);
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_typeck/src/check/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1246,9 +1246,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return None;
}

let ty = match self_ty.kind() {
&ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }) => ty,
_ => return None,
let &ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }) = self_ty.kind() else {
return None;
};

let const_self_ty = ty::TypeAndMut { ty, mutbl: hir::Mutability::Not };
Expand Down
Loading

0 comments on commit 7ca1c48

Please sign in to comment.