Rollup merge of #94142 - est31:let_else_typeck, r=oli-obk
rustc_typeck: adopt let else in more places Continuation of https://github.com/rust-lang/rust/pull/89933, https://github.com/rust-lang/rust/pull/91018, https://github.com/rust-lang/rust/pull/91481, https://github.com/rust-lang/rust/pull/93046, https://github.com/rust-lang/rust/pull/93590, https://github.com/rust-lang/rust/pull/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.
This commit is contained in:
commit
7ca1c48bbb
@ -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(
|
||||
|
@ -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| {
|
||||
@ -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
|
||||
|
@ -799,10 +799,9 @@ 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
|
||||
@ -810,10 +809,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||
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)
|
||||
|
@ -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(
|
||||
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
@ -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,
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
@ -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()) {
|
||||
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
||||
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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 };
|
||||
|
@ -37,9 +37,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
|
||||
// If it's not a simple function, look for things which implement `FnOnce`.
|
||||
_ => {
|
||||
let fn_once = match tcx.lang_items().require(LangItem::FnOnce) {
|
||||
Ok(fn_once) => fn_once,
|
||||
Err(..) => return false,
|
||||
let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// This conditional prevents us from asking to call errors and unresolved types.
|
||||
@ -112,12 +111,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
CandidateSource::ImplSource(impl_did) => {
|
||||
// Provide the best span we can. Use the item, if local to crate, else
|
||||
// the impl, if local to crate (item may be defaulted), else nothing.
|
||||
let item = match self.associated_value(impl_did, item_name).or_else(|| {
|
||||
let Some(item) = self.associated_value(impl_did, item_name).or_else(|| {
|
||||
let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?;
|
||||
self.associated_value(impl_trait_ref.def_id, item_name)
|
||||
}) {
|
||||
Some(item) => item,
|
||||
None => continue,
|
||||
}) else {
|
||||
continue;
|
||||
};
|
||||
let note_span = self
|
||||
.tcx
|
||||
@ -194,10 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
CandidateSource::TraitSource(trait_did) => {
|
||||
let item = match self.associated_value(trait_did, item_name) {
|
||||
Some(item) => item,
|
||||
None => continue,
|
||||
};
|
||||
let Some(item) = self.associated_value(trait_did, item_name) else { continue };
|
||||
let item_span = self
|
||||
.tcx
|
||||
.sess
|
||||
@ -1202,10 +1197,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut derives = Vec::<(String, Span, String)>::new();
|
||||
let mut traits = Vec::<Span>::new();
|
||||
for (pred, _, _) in unsatisfied_predicates {
|
||||
let trait_pred = match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(trait_pred) => trait_pred,
|
||||
_ => continue,
|
||||
};
|
||||
let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder() else { continue };
|
||||
let adt = match trait_pred.self_ty().ty_adt_def() {
|
||||
Some(adt) if adt.did.is_local() => adt,
|
||||
_ => continue,
|
||||
|
@ -981,9 +981,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if subpats.len() == variant.fields.len()
|
||||
|| subpats.len() < variant.fields.len() && ddpos.is_some()
|
||||
{
|
||||
let substs = match pat_ty.kind() {
|
||||
ty::Adt(_, substs) => substs,
|
||||
_ => bug!("unexpected pattern type {:?}", pat_ty),
|
||||
let ty::Adt(_, substs) = pat_ty.kind() else {
|
||||
bug!("unexpected pattern type {:?}", pat_ty);
|
||||
};
|
||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
|
||||
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
|
||||
@ -1221,9 +1220,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) -> bool {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let (substs, adt) = match adt_ty.kind() {
|
||||
ty::Adt(adt, substs) => (substs, adt),
|
||||
_ => span_bug!(pat.span, "struct pattern is not an ADT"),
|
||||
let ty::Adt(adt, substs) = adt_ty.kind() else {
|
||||
span_bug!(pat.span, "struct pattern is not an ADT");
|
||||
};
|
||||
|
||||
// Index the struct fields' types.
|
||||
|
@ -533,19 +533,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
base => bug!("Expected upvar, found={:?}", base),
|
||||
};
|
||||
|
||||
let min_cap_list = match root_var_min_capture_list.get_mut(&var_hir_id) {
|
||||
None => {
|
||||
let mutability = self.determine_capture_mutability(&typeck_results, &place);
|
||||
let min_cap_list = vec![ty::CapturedPlace {
|
||||
place,
|
||||
info: capture_info,
|
||||
mutability,
|
||||
region: None,
|
||||
}];
|
||||
root_var_min_capture_list.insert(var_hir_id, min_cap_list);
|
||||
continue;
|
||||
}
|
||||
Some(min_cap_list) => min_cap_list,
|
||||
let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else {
|
||||
let mutability = self.determine_capture_mutability(&typeck_results, &place);
|
||||
let min_cap_list = vec![ty::CapturedPlace {
|
||||
place,
|
||||
info: capture_info,
|
||||
mutability,
|
||||
region: None,
|
||||
}];
|
||||
root_var_min_capture_list.insert(var_hir_id, min_cap_list);
|
||||
continue;
|
||||
};
|
||||
|
||||
// Go through each entry in the current list of min_captures
|
||||
|
@ -40,11 +40,8 @@ struct InherentCollect<'tcx> {
|
||||
|
||||
impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
|
||||
fn visit_item(&mut self, item: &hir::Item<'_>) {
|
||||
let (ty, assoc_items) = match item.kind {
|
||||
hir::ItemKind::Impl(hir::Impl { of_trait: None, ref self_ty, items, .. }) => {
|
||||
(self_ty, items)
|
||||
}
|
||||
_ => return,
|
||||
let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items: assoc_items, .. }) = item.kind else {
|
||||
return;
|
||||
};
|
||||
|
||||
let self_ty = self.tcx.type_of(item.def_id);
|
||||
|
@ -38,9 +38,8 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorRep
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
|
||||
let item = tcx.hir().item(hir::ItemId { def_id });
|
||||
let impl_ = match item.kind {
|
||||
hir::ItemKind::Impl(ref impl_) => impl_,
|
||||
_ => bug!("{:?} is not an impl: {:?}", def_id, item),
|
||||
let hir::ItemKind::Impl(ref impl_) = item.kind else {
|
||||
bug!("{:?} is not an impl: {:?}", def_id, item);
|
||||
};
|
||||
let sp = tcx.sess.source_map().guess_head_span(item.span);
|
||||
let tr = impl_.of_trait.as_ref().unwrap();
|
||||
|
@ -1,4 +1,3 @@
|
||||
// ignore-tidy-filelength
|
||||
//! "Collection" is the process of determining the type and other external
|
||||
//! details of each item in Rust. Collection is specifically concerned
|
||||
//! with *inter-procedural* things -- for example, for a function
|
||||
@ -1018,9 +1017,8 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
|
||||
|
||||
let def_id = def_id.expect_local();
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let item = match tcx.hir().get(hir_id) {
|
||||
Node::Item(item) => item,
|
||||
_ => bug!(),
|
||||
let Node::Item(item) = tcx.hir().get(hir_id) else {
|
||||
bug!();
|
||||
};
|
||||
|
||||
let repr = ReprOptions::new(tcx, def_id.to_def_id());
|
||||
@ -1122,9 +1120,8 @@ fn super_predicates_that_define_assoc_type(
|
||||
debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id);
|
||||
let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
|
||||
|
||||
let item = match tcx.hir().get(trait_hir_id) {
|
||||
Node::Item(item) => item,
|
||||
_ => bug!("trait_node_id {} is not an item", trait_hir_id),
|
||||
let Node::Item(item) = tcx.hir().get(trait_hir_id) else {
|
||||
bug!("trait_node_id {} is not an item", trait_hir_id);
|
||||
};
|
||||
|
||||
let (generics, bounds) = match item.kind {
|
||||
@ -2637,10 +2634,7 @@ fn from_target_feature(
|
||||
supported_target_features: &FxHashMap<String, Option<Symbol>>,
|
||||
target_features: &mut Vec<Symbol>,
|
||||
) {
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => return,
|
||||
};
|
||||
let Some(list) = attr.meta_item_list() else { return };
|
||||
let bad_item = |span| {
|
||||
let msg = "malformed `target_feature` attribute input";
|
||||
let code = "enable = \"..\"".to_owned();
|
||||
@ -2658,35 +2652,29 @@ fn from_target_feature(
|
||||
}
|
||||
|
||||
// Must be of the form `enable = "..."` (a string).
|
||||
let value = match item.value_str() {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
bad_item(item.span());
|
||||
continue;
|
||||
}
|
||||
let Some(value) = item.value_str() else {
|
||||
bad_item(item.span());
|
||||
continue;
|
||||
};
|
||||
|
||||
// We allow comma separation to enable multiple features.
|
||||
target_features.extend(value.as_str().split(',').filter_map(|feature| {
|
||||
let feature_gate = match supported_target_features.get(feature) {
|
||||
Some(g) => g,
|
||||
None => {
|
||||
let msg =
|
||||
format!("the feature named `{}` is not valid for this target", feature);
|
||||
let mut err = tcx.sess.struct_span_err(item.span(), &msg);
|
||||
err.span_label(
|
||||
item.span(),
|
||||
format!("`{}` is not valid for this target", feature),
|
||||
);
|
||||
if let Some(stripped) = feature.strip_prefix('+') {
|
||||
let valid = supported_target_features.contains_key(stripped);
|
||||
if valid {
|
||||
err.help("consider removing the leading `+` in the feature name");
|
||||
}
|
||||
let Some(feature_gate) = supported_target_features.get(feature) else {
|
||||
let msg =
|
||||
format!("the feature named `{}` is not valid for this target", feature);
|
||||
let mut err = tcx.sess.struct_span_err(item.span(), &msg);
|
||||
err.span_label(
|
||||
item.span(),
|
||||
format!("`{}` is not valid for this target", feature),
|
||||
);
|
||||
if let Some(stripped) = feature.strip_prefix('+') {
|
||||
let valid = supported_target_features.contains_key(stripped);
|
||||
if valid {
|
||||
err.help("consider removing the leading `+` in the feature name");
|
||||
}
|
||||
err.emit();
|
||||
return None;
|
||||
}
|
||||
err.emit();
|
||||
return None;
|
||||
};
|
||||
|
||||
// Only allow features whose feature gates have been enabled.
|
||||
|
@ -164,12 +164,9 @@ fn get_impl_substs<'tcx>(
|
||||
// Conservatively use an empty `ParamEnv`.
|
||||
let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
|
||||
infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env, RegionckMode::default());
|
||||
let impl2_substs = match infcx.fully_resolve(impl2_substs) {
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();
|
||||
return None;
|
||||
}
|
||||
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
|
||||
tcx.sess.struct_span_err(span, "could not resolve substs on overridden impl").emit();
|
||||
return None;
|
||||
};
|
||||
Some((impl1_substs, impl2_substs))
|
||||
}
|
||||
|
@ -484,9 +484,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
let place_ty = self.expr_ty(expr)?;
|
||||
let base_ty = self.expr_ty_adjusted(base)?;
|
||||
|
||||
let (region, mutbl) = match *base_ty.kind() {
|
||||
ty::Ref(region, _, mutbl) => (region, mutbl),
|
||||
_ => span_bug!(expr.span, "cat_overloaded_place: base is not a reference"),
|
||||
let ty::Ref(region, _, mutbl) = *base_ty.kind() else {
|
||||
span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
|
||||
};
|
||||
let ref_ty = self.tcx().mk_ref(region, ty::TypeAndMut { ty: place_ty, mutbl });
|
||||
|
||||
@ -544,14 +543,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
) -> McResult<VariantIdx> {
|
||||
let res = self.typeck_results.qpath_res(qpath, pat_hir_id);
|
||||
let ty = self.typeck_results.node_type(pat_hir_id);
|
||||
let adt_def = match ty.kind() {
|
||||
ty::Adt(adt_def, _) => adt_def,
|
||||
_ => {
|
||||
self.tcx()
|
||||
.sess
|
||||
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
|
||||
return Err(());
|
||||
}
|
||||
let ty::Adt(adt_def, _) = ty.kind() else {
|
||||
self.tcx()
|
||||
.sess
|
||||
.delay_span_bug(span, "struct or tuple struct pattern not applied to an ADT");
|
||||
return Err(());
|
||||
};
|
||||
|
||||
match res {
|
||||
@ -744,12 +740,9 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
PatKind::Slice(before, ref slice, after) => {
|
||||
let element_ty = match place_with_id.place.ty().builtin_index() {
|
||||
Some(ty) => ty,
|
||||
None => {
|
||||
debug!("explicit index of non-indexable type {:?}", place_with_id);
|
||||
return Err(());
|
||||
}
|
||||
let Some(element_ty) = place_with_id.place.ty().builtin_index() else {
|
||||
debug!("explicit index of non-indexable type {:?}", place_with_id);
|
||||
return Err(());
|
||||
};
|
||||
let elt_place = self.cat_projection(
|
||||
pat,
|
||||
|
@ -71,12 +71,9 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
|
||||
result,
|
||||
);
|
||||
debug!("implied_outlives_bounds for {:?}: {:#?}", ty, result);
|
||||
let result = match result {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
self.tcx.sess.delay_span_bug(span, "implied_outlives_bounds failed to instantiate");
|
||||
return vec![];
|
||||
}
|
||||
let Ok(result) = result else {
|
||||
self.tcx.sess.delay_span_bug(span, "implied_outlives_bounds failed to instantiate");
|
||||
return vec![];
|
||||
};
|
||||
|
||||
// Instantiation may have produced new inference variables and constraints on those
|
||||
|
Loading…
x
Reference in New Issue
Block a user