Move has_self field to hir::AssocKind::Fn.
`hir::AssocItem` currently has a boolean `fn_has_self_parameter` field, which is misplaced, because it's only relevant for associated fns, not for associated consts or types. This commit moves it (and renames it) to the `AssocKind::Fn` variant, where it belongs. This requires introducing a new C-style enum, `AssocTag`, which is like `AssocKind` but without the fields. This is because `AssocKind` values are passed to various functions like `find_by_ident_and_kind` to indicate what kind of associated item should be searched for, and having to specify `has_self` isn't relevant there. New methods: - Predicates `AssocItem::is_fn` and `AssocItem::is_method`. - `AssocItem::as_tag` which converts `AssocItem::kind` to `AssocTag`. Removed `find_by_name_and_kinds`, which is unused. `AssocItem::descr` can now distinguish between methods and associated functions, which slightly improves some error messages.
This commit is contained in:
@@ -443,7 +443,7 @@ fn best_definition_site_of_opaque<'tcx>(
|
||||
let impl_def_id = tcx.local_parent(parent);
|
||||
for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
|
||||
match assoc.kind {
|
||||
ty::AssocKind::Const | ty::AssocKind::Fn => {
|
||||
ty::AssocKind::Const | ty::AssocKind::Fn { .. } => {
|
||||
if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local())
|
||||
{
|
||||
return Some(span);
|
||||
@@ -942,7 +942,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
|
||||
if res.is_ok() {
|
||||
match ty_impl_item.kind {
|
||||
ty::AssocKind::Fn => {
|
||||
ty::AssocKind::Fn { .. } => {
|
||||
compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait(
|
||||
tcx,
|
||||
ty_impl_item,
|
||||
|
||||
@@ -43,7 +43,7 @@ pub(super) fn compare_impl_item(
|
||||
debug!(?impl_trait_ref);
|
||||
|
||||
match impl_item.kind {
|
||||
ty::AssocKind::Fn => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
|
||||
ty::AssocKind::Fn { .. } => compare_impl_method(tcx, impl_item, trait_item, impl_trait_ref),
|
||||
ty::AssocKind::Type => compare_impl_ty(tcx, impl_item, trait_item, impl_trait_ref),
|
||||
ty::AssocKind::Const => compare_impl_const(tcx, impl_item, trait_item, impl_trait_ref),
|
||||
}
|
||||
@@ -1036,7 +1036,7 @@ fn report_trait_method_mismatch<'tcx>(
|
||||
);
|
||||
match &terr {
|
||||
TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
|
||||
if trait_m.fn_has_self_parameter =>
|
||||
if trait_m.is_method() =>
|
||||
{
|
||||
let ty = trait_sig.inputs()[0];
|
||||
let sugg = get_self_string(ty, |ty| ty == impl_trait_ref.self_ty());
|
||||
@@ -1255,7 +1255,7 @@ fn compare_self_type<'tcx>(
|
||||
get_self_string(self_arg_ty, can_eq_self)
|
||||
};
|
||||
|
||||
match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) {
|
||||
match (trait_m.is_method(), impl_m.is_method()) {
|
||||
(false, false) | (true, true) => {}
|
||||
|
||||
(false, true) => {
|
||||
@@ -1363,7 +1363,7 @@ fn compare_number_of_generics<'tcx>(
|
||||
let mut err_occurred = None;
|
||||
for (kind, trait_count, impl_count) in matchings {
|
||||
if impl_count != trait_count {
|
||||
let arg_spans = |kind: ty::AssocKind, generics: &hir::Generics<'_>| {
|
||||
let arg_spans = |item: &ty::AssocItem, generics: &hir::Generics<'_>| {
|
||||
let mut spans = generics
|
||||
.params
|
||||
.iter()
|
||||
@@ -1373,7 +1373,7 @@ fn compare_number_of_generics<'tcx>(
|
||||
} => {
|
||||
// A fn can have an arbitrary number of extra elided lifetimes for the
|
||||
// same signature.
|
||||
!matches!(kind, ty::AssocKind::Fn)
|
||||
!item.is_fn()
|
||||
}
|
||||
_ => true,
|
||||
})
|
||||
@@ -1386,7 +1386,7 @@ fn compare_number_of_generics<'tcx>(
|
||||
};
|
||||
let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() {
|
||||
let trait_item = tcx.hir_expect_trait_item(def_id);
|
||||
let arg_spans: Vec<Span> = arg_spans(trait_.kind, trait_item.generics);
|
||||
let arg_spans: Vec<Span> = arg_spans(&trait_, trait_item.generics);
|
||||
let impl_trait_spans: Vec<Span> = trait_item
|
||||
.generics
|
||||
.params
|
||||
@@ -1412,7 +1412,7 @@ fn compare_number_of_generics<'tcx>(
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
let spans = arg_spans(impl_.kind, impl_item.generics);
|
||||
let spans = arg_spans(&impl_, impl_item.generics);
|
||||
let span = spans.first().copied();
|
||||
|
||||
let mut err = tcx.dcx().struct_span_err(
|
||||
|
||||
@@ -407,14 +407,14 @@ fn fn_sig_suggestion<'tcx>(
|
||||
.enumerate()
|
||||
.map(|(i, ty)| {
|
||||
Some(match ty.kind() {
|
||||
ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
|
||||
ty::Param(_) if assoc.is_method() && i == 0 => "self".to_string(),
|
||||
ty::Ref(reg, ref_ty, mutability) if i == 0 => {
|
||||
let reg = format!("{reg} ");
|
||||
let reg = match ®[..] {
|
||||
"'_ " | " " => "",
|
||||
reg => reg,
|
||||
};
|
||||
if assoc.fn_has_self_parameter {
|
||||
if assoc.is_method() {
|
||||
match ref_ty.kind() {
|
||||
ty::Param(param) if param.name == kw::SelfUpper => {
|
||||
format!("&{}{}self", reg, mutability.prefix_str())
|
||||
@@ -427,7 +427,7 @@ fn fn_sig_suggestion<'tcx>(
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if assoc.fn_has_self_parameter && i == 0 {
|
||||
if assoc.is_method() && i == 0 {
|
||||
format!("self: {ty}")
|
||||
} else {
|
||||
format!("_: {ty}")
|
||||
@@ -489,7 +489,7 @@ fn suggestion_signature<'tcx>(
|
||||
);
|
||||
|
||||
match assoc.kind {
|
||||
ty::AssocKind::Fn => fn_sig_suggestion(
|
||||
ty::AssocKind::Fn { .. } => fn_sig_suggestion(
|
||||
tcx,
|
||||
tcx.liberate_late_bound_regions(
|
||||
assoc.def_id,
|
||||
|
||||
@@ -432,7 +432,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
||||
|
||||
let item_required_bounds = match tcx.associated_item(item_def_id).kind {
|
||||
// In our example, this corresponds to `into_iter` method
|
||||
ty::AssocKind::Fn => {
|
||||
ty::AssocKind::Fn { .. } => {
|
||||
// For methods, we check the function signature's return type for any GATs
|
||||
// to constrain. In the `into_iter` case, we see that the return type
|
||||
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
|
||||
@@ -1089,7 +1089,7 @@ fn check_associated_item(
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
ty::AssocKind::Fn { .. } => {
|
||||
let sig = tcx.fn_sig(item.def_id).instantiate_identity();
|
||||
let hir_sig = sig_if_method.expect("bad signature for method");
|
||||
check_fn_or_method(
|
||||
@@ -1716,7 +1716,7 @@ fn check_method_receiver<'tcx>(
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let tcx = wfcx.tcx();
|
||||
|
||||
if !method.fn_has_self_parameter {
|
||||
if !method.is_method() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user