Skip to content

Commit d60e772

Browse files
committed
rustc_hir_analysis: some general code improvements
1 parent 360e978 commit d60e772

File tree

4 files changed

+92
-114
lines changed

4 files changed

+92
-114
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

Lines changed: 74 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -916,16 +916,14 @@ fn report_trait_method_mismatch<'tcx>(
916916
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
917917
// span points only at the type `Box<Self`>, but we want to cover the whole
918918
// argument pattern and type.
919-
let span = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
920-
ImplItemKind::Fn(ref sig, body) => tcx
921-
.hir()
922-
.body_param_names(body)
923-
.zip(sig.decl.inputs.iter())
924-
.map(|(param, ty)| param.span.to(ty.span))
925-
.next()
926-
.unwrap_or(impl_err_span),
927-
_ => bug!("{:?} is not a method", impl_m),
928-
};
919+
let ImplItemKind::Fn(ref sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind else { bug!("{impl_m:?} is not a method") };
920+
let span = tcx
921+
.hir()
922+
.body_param_names(body)
923+
.zip(sig.decl.inputs.iter())
924+
.map(|(param, ty)| param.span.to(ty.span))
925+
.next()
926+
.unwrap_or(impl_err_span);
929927

930928
diag.span_suggestion(
931929
span,
@@ -938,22 +936,21 @@ fn report_trait_method_mismatch<'tcx>(
938936
if trait_sig.inputs().len() == *i {
939937
// Suggestion to change output type. We do not suggest in `async` functions
940938
// to avoid complex logic or incorrect output.
941-
match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
942-
ImplItemKind::Fn(ref sig, _) if !sig.header.asyncness.is_async() => {
943-
let msg = "change the output type to match the trait";
944-
let ap = Applicability::MachineApplicable;
945-
match sig.decl.output {
946-
hir::FnRetTy::DefaultReturn(sp) => {
947-
let sugg = format!("-> {} ", trait_sig.output());
948-
diag.span_suggestion_verbose(sp, msg, sugg, ap);
949-
}
950-
hir::FnRetTy::Return(hir_ty) => {
951-
let sugg = trait_sig.output();
952-
diag.span_suggestion(hir_ty.span, msg, sugg, ap);
953-
}
954-
};
955-
}
956-
_ => {}
939+
if let ImplItemKind::Fn(sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind
940+
&& !sig.header.asyncness.is_async()
941+
{
942+
let msg = "change the output type to match the trait";
943+
let ap = Applicability::MachineApplicable;
944+
match sig.decl.output {
945+
hir::FnRetTy::DefaultReturn(sp) => {
946+
let sugg = format!("-> {} ", trait_sig.output());
947+
diag.span_suggestion_verbose(sp, msg, sugg, ap);
948+
}
949+
hir::FnRetTy::Return(hir_ty) => {
950+
let sugg = trait_sig.output();
951+
diag.span_suggestion(hir_ty.span, msg, sugg, ap);
952+
}
953+
};
957954
};
958955
} else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
959956
diag.span_suggestion(
@@ -1080,25 +1077,18 @@ fn extract_spans_for_error_reporting<'tcx>(
10801077
trait_m: &ty::AssocItem,
10811078
) -> (Span, Option<Span>) {
10821079
let tcx = infcx.tcx;
1083-
let mut impl_args = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
1084-
ImplItemKind::Fn(ref sig, _) => {
1085-
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
1086-
}
1087-
_ => bug!("{:?} is not a method", impl_m),
1080+
let mut impl_args = {
1081+
let ImplItemKind::Fn(sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind else { bug!("{:?} is not a method", impl_m) };
1082+
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
10881083
};
1089-
let trait_args =
1090-
trait_m.def_id.as_local().map(|def_id| match tcx.hir().expect_trait_item(def_id).kind {
1091-
TraitItemKind::Fn(ref sig, _) => {
1092-
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
1093-
}
1094-
_ => bug!("{:?} is not a TraitItemKind::Fn", trait_m),
1095-
});
1084+
1085+
let trait_args = trait_m.def_id.as_local().map(|def_id| {
1086+
let TraitItemKind::Fn(sig, _) = &tcx.hir().expect_trait_item(def_id).kind else { bug!("{:?} is not a TraitItemKind::Fn", trait_m) };
1087+
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
1088+
});
10961089

10971090
match terr {
1098-
TypeError::ArgumentMutability(i) => {
1099-
(impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
1100-
}
1101-
TypeError::ArgumentSorts(ExpectedFound { .. }, i) => {
1091+
TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(ExpectedFound { .. }, i) => {
11021092
(impl_args.nth(i).unwrap(), trait_args.and_then(|mut args| args.nth(i)))
11031093
}
11041094
_ => (cause.span(), tcx.hir().span_if_local(trait_m.def_id)),
@@ -1158,8 +1148,7 @@ fn compare_self_type<'tcx>(
11581148
} else {
11591149
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
11601150
}
1161-
let reported = err.emit();
1162-
return Err(reported);
1151+
return Err(err.emit());
11631152
}
11641153

11651154
(true, false) => {
@@ -1178,8 +1167,8 @@ fn compare_self_type<'tcx>(
11781167
} else {
11791168
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
11801169
}
1181-
let reported = err.emit();
1182-
return Err(reported);
1170+
1171+
return Err(err.emit());
11831172
}
11841173
}
11851174

@@ -1361,41 +1350,41 @@ fn compare_number_of_method_arguments<'tcx>(
13611350
let trait_m_fty = tcx.fn_sig(trait_m.def_id);
13621351
let trait_number_args = trait_m_fty.inputs().skip_binder().len();
13631352
let impl_number_args = impl_m_fty.inputs().skip_binder().len();
1353+
13641354
if trait_number_args != impl_number_args {
1365-
let trait_span = if let Some(def_id) = trait_m.def_id.as_local() {
1366-
match tcx.hir().expect_trait_item(def_id).kind {
1367-
TraitItemKind::Fn(ref trait_m_sig, _) => {
1368-
let pos = if trait_number_args > 0 { trait_number_args - 1 } else { 0 };
1369-
if let Some(arg) = trait_m_sig.decl.inputs.get(pos) {
1370-
Some(if pos == 0 {
1371-
arg.span
1372-
} else {
1373-
arg.span.with_lo(trait_m_sig.decl.inputs[0].span.lo())
1374-
})
1355+
let trait_span = trait_m
1356+
.def_id
1357+
.as_local()
1358+
.and_then(|def_id| {
1359+
let TraitItemKind::Fn(trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).kind else { bug!("{:?} is not a method", impl_m) };
1360+
let pos = trait_number_args.saturating_sub(1);
1361+
trait_m_sig.decl.inputs.get(pos).map(|arg| {
1362+
if pos == 0 {
1363+
arg.span
13751364
} else {
1376-
trait_item_span
1365+
arg.span.with_lo(trait_m_sig.decl.inputs[0].span.lo())
13771366
}
1378-
}
1379-
_ => bug!("{:?} is not a method", impl_m),
1380-
}
1381-
} else {
1382-
trait_item_span
1383-
};
1384-
let impl_span = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
1385-
ImplItemKind::Fn(ref impl_m_sig, _) => {
1386-
let pos = if impl_number_args > 0 { impl_number_args - 1 } else { 0 };
1387-
if let Some(arg) = impl_m_sig.decl.inputs.get(pos) {
1367+
})
1368+
})
1369+
.or(trait_item_span);
1370+
1371+
let impl_span = {
1372+
let ImplItemKind::Fn(impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind else { bug!("{:?} is not a method", impl_m) };
1373+
let pos = impl_number_args.saturating_sub(1);
1374+
impl_m_sig
1375+
.decl
1376+
.inputs
1377+
.get(pos)
1378+
.map(|arg| {
13881379
if pos == 0 {
13891380
arg.span
13901381
} else {
13911382
arg.span.with_lo(impl_m_sig.decl.inputs[0].span.lo())
13921383
}
1393-
} else {
1394-
impl_m_span
1395-
}
1396-
}
1397-
_ => bug!("{:?} is not a method", impl_m),
1384+
})
1385+
.unwrap_or(impl_m_span)
13981386
};
1387+
13991388
let mut err = struct_span_err!(
14001389
tcx.sess,
14011390
impl_span,
@@ -1406,6 +1395,7 @@ fn compare_number_of_method_arguments<'tcx>(
14061395
tcx.def_path_str(trait_m.def_id),
14071396
trait_number_args
14081397
);
1398+
14091399
if let Some(trait_span) = trait_span {
14101400
err.span_label(
14111401
trait_span,
@@ -1417,6 +1407,7 @@ fn compare_number_of_method_arguments<'tcx>(
14171407
} else {
14181408
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
14191409
}
1410+
14201411
err.span_label(
14211412
impl_span,
14221413
format!(
@@ -1425,8 +1416,8 @@ fn compare_number_of_method_arguments<'tcx>(
14251416
impl_number_args
14261417
),
14271418
);
1428-
let reported = err.emit();
1429-
return Err(reported);
1419+
1420+
return Err(err.emit());
14301421
}
14311422

14321423
Ok(())
@@ -1515,10 +1506,9 @@ fn compare_synthetic_generics<'tcx>(
15151506
let _: Option<_> = try {
15161507
let impl_m = impl_m.def_id.as_local()?;
15171508
let impl_m = tcx.hir().expect_impl_item(impl_m);
1518-
let input_tys = match impl_m.kind {
1519-
hir::ImplItemKind::Fn(ref sig, _) => sig.decl.inputs,
1520-
_ => unreachable!(),
1521-
};
1509+
let hir::ImplItemKind::Fn(sig, _) = &impl_m.kind else { unreachable!() };
1510+
let input_tys = sig.decl.inputs;
1511+
15221512
struct Visitor(Option<Span>, hir::def_id::LocalDefId);
15231513
impl<'v> intravisit::Visitor<'v> for Visitor {
15241514
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
@@ -1532,6 +1522,7 @@ fn compare_synthetic_generics<'tcx>(
15321522
}
15331523
}
15341524
}
1525+
15351526
let mut visitor = Visitor(None, impl_def_id);
15361527
for ty in input_tys {
15371528
intravisit::Visitor::visit_ty(&mut visitor, ty);
@@ -1556,8 +1547,7 @@ fn compare_synthetic_generics<'tcx>(
15561547
}
15571548
_ => unreachable!(),
15581549
}
1559-
let reported = err.emit();
1560-
error_found = Some(reported);
1550+
error_found = Some(err.emit());
15611551
}
15621552
}
15631553
if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
@@ -1717,10 +1707,8 @@ pub(super) fn compare_impl_const_raw(
17171707
);
17181708

17191709
// Locate the Span containing just the type of the offending impl
1720-
match tcx.hir().expect_impl_item(impl_const_item_def).kind {
1721-
ImplItemKind::Const(ref ty, _) => cause.span = ty.span,
1722-
_ => bug!("{:?} is not a impl const", impl_const_item),
1723-
}
1710+
let ImplItemKind::Const(ty, _) = tcx.hir().expect_impl_item(impl_const_item_def).kind else { bug!("{impl_const_item:?} is not a impl const") };
1711+
cause.span = ty.span;
17241712

17251713
let mut diag = struct_span_err!(
17261714
tcx.sess,
@@ -1732,10 +1720,8 @@ pub(super) fn compare_impl_const_raw(
17321720

17331721
let trait_c_span = trait_const_item_def.as_local().map(|trait_c_def_id| {
17341722
// Add a label to the Span containing just the type of the const
1735-
match tcx.hir().expect_trait_item(trait_c_def_id).kind {
1736-
TraitItemKind::Const(ref ty, _) => ty.span,
1737-
_ => bug!("{:?} is not a trait const", trait_const_item),
1738-
}
1723+
let TraitItemKind::Const(ty, _) = tcx.hir().expect_trait_item(trait_c_def_id).kind else { bug!("{trait_const_item:?} is not a trait const") };
1724+
ty.span
17391725
});
17401726

17411727
infcx.err_ctxt().note_type_err(

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,9 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
5454
_ => {}
5555
}
5656

57-
let sp = match tcx.hir().expect_item(impl_did).kind {
58-
ItemKind::Impl(ref impl_) => impl_.self_ty.span,
59-
_ => bug!("expected Drop impl item"),
60-
};
57+
let ItemKind::Impl(impl_) = tcx.hir().expect_item(impl_did).kind else { bug!("expected Drop impl item") };
6158

62-
tcx.sess.emit_err(DropImplOnWrongItem { span: sp });
59+
tcx.sess.emit_err(DropImplOnWrongItem { span: impl_.self_ty.span });
6360
}
6461

6562
fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,21 +1342,19 @@ fn suggest_impl_trait<'tcx>(
13421342
fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
13431343
let icx = ItemCtxt::new(tcx, def_id);
13441344
let item = tcx.hir().expect_item(def_id.expect_local());
1345-
match item.kind {
1346-
hir::ItemKind::Impl(ref impl_) => impl_
1347-
.of_trait
1348-
.as_ref()
1349-
.map(|ast_trait_ref| {
1350-
let selfty = tcx.type_of(def_id);
1351-
icx.astconv().instantiate_mono_trait_ref(
1352-
ast_trait_ref,
1353-
selfty,
1354-
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
1355-
)
1356-
})
1357-
.map(ty::EarlyBinder),
1358-
_ => bug!(),
1359-
}
1345+
let hir::ItemKind::Impl(impl_) = item.kind else { bug!() };
1346+
impl_
1347+
.of_trait
1348+
.as_ref()
1349+
.map(|ast_trait_ref| {
1350+
let selfty = tcx.type_of(def_id);
1351+
icx.astconv().instantiate_mono_trait_ref(
1352+
ast_trait_ref,
1353+
selfty,
1354+
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
1355+
)
1356+
})
1357+
.map(ty::EarlyBinder)
13601358
}
13611359

13621360
fn check_impl_constness(

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
114114
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
115115

116116
use std::iter;
117+
use std::ops::Not;
117118

118119
use astconv::AstConv;
119120
use bounds::Bounds;
@@ -203,12 +204,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
203204
}
204205
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
205206
match tcx.hir().find(hir_id) {
206-
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, ref generics, _), .. })) => {
207-
if !generics.params.is_empty() {
208-
Some(generics.span)
209-
} else {
210-
None
211-
}
207+
Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
208+
generics.params.is_empty().not().then(|| generics.span)
212209
}
213210
_ => {
214211
span_bug!(tcx.def_span(def_id), "main has a non-function type");

0 commit comments

Comments
 (0)