Rollup merge of #139669 - nnethercote:overhaul-AssocItem, r=oli-obk
Overhaul `AssocItem` `AssocItem` has multiple fields that only make sense some of the time. E.g. the `name` can be empty if it's an RPITIT associated type. It's clearer and less error prone if these fields are moved to the relevant `kind` variants. r? ``@fee1-dead``
This commit is contained in:
commit
13cd5256ac
86 changed files with 609 additions and 546 deletions
|
@ -443,13 +443,13 @@ 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);
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Type => {}
|
||||
ty::AssocKind::Type { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -740,7 +740,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
|
||||
for &assoc_item in assoc_items.in_definition_order() {
|
||||
match assoc_item.kind {
|
||||
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
|
||||
ty::AssocKind::Type { .. } if assoc_item.defaultness(tcx).has_value() => {
|
||||
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
|
||||
tcx,
|
||||
|
@ -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,
|
||||
|
@ -952,8 +952,8 @@ fn check_impl_items_against_trait<'tcx>(
|
|||
.instantiate_identity(),
|
||||
);
|
||||
}
|
||||
ty::AssocKind::Const => {}
|
||||
ty::AssocKind::Type => {}
|
||||
ty::AssocKind::Const { .. } => {}
|
||||
ty::AssocKind::Type { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,9 +43,11 @@ 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::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),
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -654,7 +656,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
cause.span,
|
||||
E0053,
|
||||
"method `{}` has an incompatible return type for trait",
|
||||
trait_m.name
|
||||
trait_m.name()
|
||||
);
|
||||
infcx.err_ctxt().note_type_err(
|
||||
&mut diag,
|
||||
|
@ -1032,11 +1034,11 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
impl_err_span,
|
||||
E0053,
|
||||
"method `{}` has an incompatible type for trait",
|
||||
trait_m.name
|
||||
trait_m.name()
|
||||
);
|
||||
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 +1257,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) => {
|
||||
|
@ -1266,14 +1268,14 @@ fn compare_self_type<'tcx>(
|
|||
impl_m_span,
|
||||
E0185,
|
||||
"method `{}` has a `{}` declaration in the impl, but not in the trait",
|
||||
trait_m.name,
|
||||
trait_m.name(),
|
||||
self_descr
|
||||
);
|
||||
err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
|
||||
if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
|
||||
err.span_label(span, format!("trait method declared without `{self_descr}`"));
|
||||
} else {
|
||||
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
|
||||
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
|
||||
}
|
||||
return Err(err.emit_unless(delay));
|
||||
}
|
||||
|
@ -1286,14 +1288,14 @@ fn compare_self_type<'tcx>(
|
|||
impl_m_span,
|
||||
E0186,
|
||||
"method `{}` has a `{}` declaration in the trait, but not in the impl",
|
||||
trait_m.name,
|
||||
trait_m.name(),
|
||||
self_descr
|
||||
);
|
||||
err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
|
||||
if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
|
||||
err.span_label(span, format!("`{self_descr}` used in trait"));
|
||||
} else {
|
||||
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
|
||||
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
|
||||
}
|
||||
|
||||
return Err(err.emit_unless(delay));
|
||||
|
@ -1363,7 +1365,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 +1375,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 +1388,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 +1414,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(
|
||||
|
@ -1421,7 +1423,7 @@ fn compare_number_of_generics<'tcx>(
|
|||
"{} `{}` has {} {kind} parameter{} but its trait \
|
||||
declaration has {} {kind} parameter{}",
|
||||
item_kind,
|
||||
trait_.name,
|
||||
trait_.name(),
|
||||
impl_count,
|
||||
pluralize!(impl_count),
|
||||
trait_count,
|
||||
|
@ -1512,7 +1514,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
|||
impl_span,
|
||||
E0050,
|
||||
"method `{}` has {} but the declaration in trait `{}` has {}",
|
||||
trait_m.name,
|
||||
trait_m.name(),
|
||||
potentially_plural_count(impl_number_args, "parameter"),
|
||||
tcx.def_path_str(trait_m.def_id),
|
||||
trait_number_args
|
||||
|
@ -1527,7 +1529,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
|||
),
|
||||
);
|
||||
} else {
|
||||
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
|
||||
err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
|
||||
}
|
||||
|
||||
err.span_label(
|
||||
|
@ -1581,7 +1583,7 @@ fn compare_synthetic_generics<'tcx>(
|
|||
impl_span,
|
||||
E0643,
|
||||
"method `{}` has incompatible signature for trait",
|
||||
trait_m.name
|
||||
trait_m.name()
|
||||
);
|
||||
err.span_label(trait_span, "declaration in trait here");
|
||||
if impl_synthetic {
|
||||
|
@ -1703,7 +1705,7 @@ fn compare_generic_param_kinds<'tcx>(
|
|||
trait_item: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
assert_eq!(impl_item.kind, trait_item.kind);
|
||||
assert_eq!(impl_item.as_tag(), trait_item.as_tag());
|
||||
|
||||
let ty_const_params_of = |def_id| {
|
||||
tcx.generics_of(def_id).own_params.iter().filter(|param| {
|
||||
|
@ -1741,7 +1743,7 @@ fn compare_generic_param_kinds<'tcx>(
|
|||
E0053,
|
||||
"{} `{}` has an incompatible generic parameter for trait `{}`",
|
||||
impl_item.descr(),
|
||||
trait_item.name,
|
||||
trait_item.name(),
|
||||
&tcx.def_path_str(tcx.parent(trait_item.def_id))
|
||||
);
|
||||
|
||||
|
@ -1877,7 +1879,7 @@ fn compare_const_predicate_entailment<'tcx>(
|
|||
cause.span,
|
||||
E0326,
|
||||
"implemented const `{}` has an incompatible type for trait",
|
||||
trait_ct.name
|
||||
trait_ct.name()
|
||||
);
|
||||
|
||||
let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| {
|
||||
|
@ -2235,16 +2237,19 @@ fn param_env_with_gat_bounds<'tcx>(
|
|||
// of the RPITITs associated with the same body. This is because checking
|
||||
// the item bounds of RPITITs often involves nested RPITITs having to prove
|
||||
// bounds about themselves.
|
||||
let impl_tys_to_install = match impl_ty.opt_rpitit_info {
|
||||
None => vec![impl_ty],
|
||||
Some(
|
||||
ty::ImplTraitInTraitData::Impl { fn_def_id }
|
||||
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
|
||||
) => tcx
|
||||
let impl_tys_to_install = match impl_ty.kind {
|
||||
ty::AssocKind::Type {
|
||||
data:
|
||||
ty::AssocTypeData::Rpitit(
|
||||
ty::ImplTraitInTraitData::Impl { fn_def_id }
|
||||
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
|
||||
),
|
||||
} => tcx
|
||||
.associated_types_for_impl_traits_in_associated_fn(fn_def_id)
|
||||
.iter()
|
||||
.map(|def_id| tcx.associated_item(*def_id))
|
||||
.collect(),
|
||||
_ => vec![impl_ty],
|
||||
};
|
||||
|
||||
for impl_ty in impl_tys_to_install {
|
||||
|
|
|
@ -205,7 +205,7 @@ fn missing_items_err(
|
|||
|
||||
let missing_items_msg = missing_items
|
||||
.clone()
|
||||
.map(|trait_item| trait_item.name.to_string())
|
||||
.map(|trait_item| trait_item.name().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("`, `");
|
||||
|
||||
|
@ -236,7 +236,7 @@ fn missing_items_err(
|
|||
let code = format!("{padding}{snippet}\n{padding}");
|
||||
if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) {
|
||||
missing_trait_item_label
|
||||
.push(errors::MissingTraitItemLabel { span, item: trait_item.name });
|
||||
.push(errors::MissingTraitItemLabel { span, item: trait_item.name() });
|
||||
missing_trait_item.push(errors::MissingTraitItemSuggestion {
|
||||
span: sugg_sp,
|
||||
code,
|
||||
|
@ -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,
|
||||
|
@ -499,14 +499,14 @@ fn suggestion_signature<'tcx>(
|
|||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
|
||||
assoc,
|
||||
),
|
||||
ty::AssocKind::Type => {
|
||||
ty::AssocKind::Type { .. } => {
|
||||
let (generics, where_clauses) = bounds_from_generic_predicates(
|
||||
tcx,
|
||||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
|
||||
);
|
||||
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
|
||||
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name())
|
||||
}
|
||||
ty::AssocKind::Const => {
|
||||
ty::AssocKind::Const { name } => {
|
||||
let ty = tcx.type_of(assoc.def_id).instantiate_identity();
|
||||
let val = tcx
|
||||
.infer_ctxt()
|
||||
|
@ -514,7 +514,7 @@ fn suggestion_signature<'tcx>(
|
|||
.err_ctxt()
|
||||
.ty_kind_suggestion(tcx.param_env(assoc.def_id), ty)
|
||||
.unwrap_or_else(|| "value".to_string());
|
||||
format!("const {}: {} = {};", assoc.name, ty, val)
|
||||
format!("const {}: {} = {};", name, ty, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,7 +408,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
|||
let gat_def_id = gat_item.def_id.expect_local();
|
||||
let gat_item = tcx.associated_item(gat_def_id);
|
||||
// If this item is not an assoc ty, or has no args, then it's not a GAT
|
||||
if gat_item.kind != ty::AssocKind::Type {
|
||||
if !gat_item.is_type() {
|
||||
continue;
|
||||
}
|
||||
let gat_generics = tcx.generics_of(gat_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.
|
||||
|
@ -453,7 +453,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
|||
)
|
||||
}
|
||||
// In our example, this corresponds to the `Iter` and `Item` associated types
|
||||
ty::AssocKind::Type => {
|
||||
ty::AssocKind::Type { .. } => {
|
||||
// If our associated item is a GAT with missing bounds, add them to
|
||||
// the param-env here. This allows this GAT to propagate missing bounds
|
||||
// to other GATs.
|
||||
|
@ -474,7 +474,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
|||
gat_generics,
|
||||
)
|
||||
}
|
||||
ty::AssocKind::Const => None,
|
||||
ty::AssocKind::Const { .. } => None,
|
||||
};
|
||||
|
||||
if let Some(item_required_bounds) = item_required_bounds {
|
||||
|
@ -1076,7 +1076,7 @@ fn check_associated_item(
|
|||
};
|
||||
|
||||
match item.kind {
|
||||
ty::AssocKind::Const => {
|
||||
ty::AssocKind::Const { .. } => {
|
||||
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||
|
@ -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(
|
||||
|
@ -1101,7 +1101,7 @@ fn check_associated_item(
|
|||
);
|
||||
check_method_receiver(wfcx, hir_sig, item, self_ty)
|
||||
}
|
||||
ty::AssocKind::Type => {
|
||||
ty::AssocKind::Type { .. } => {
|
||||
if let ty::AssocItemContainer::Trait = item.container {
|
||||
check_associated_type_bounds(wfcx, item, span)
|
||||
}
|
||||
|
@ -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(());
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
|
||||
for &item1 in impl_items1.in_definition_order() {
|
||||
let collision = impl_items2
|
||||
.filter_by_name_unhygienic(item1.name)
|
||||
.filter_by_name_unhygienic(item1.name())
|
||||
.any(|&item2| self.compare_hygienically(item1, item2));
|
||||
|
||||
if collision {
|
||||
|
@ -64,7 +64,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
|
||||
fn compare_hygienically(&self, item1: ty::AssocItem, item2: ty::AssocItem) -> bool {
|
||||
// Symbols and namespace match, compare hygienically.
|
||||
item1.kind.namespace() == item2.kind.namespace()
|
||||
item1.namespace() == item2.namespace()
|
||||
&& item1.ident(self.tcx).normalize_to_macros_2_0()
|
||||
== item2.ident(self.tcx).normalize_to_macros_2_0()
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
let mut res = Ok(());
|
||||
for &item1 in impl_items1.in_definition_order() {
|
||||
let collision = impl_items2
|
||||
.filter_by_name_unhygienic(item1.name)
|
||||
.filter_by_name_unhygienic(item1.name())
|
||||
.find(|&&item2| self.compare_hygienically(item1, item2));
|
||||
|
||||
if let Some(item2) = collision {
|
||||
|
@ -230,11 +230,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
|||
let mut ids = impl_items
|
||||
.in_definition_order()
|
||||
.filter_map(|item| {
|
||||
let entry = connected_region_ids.entry(item.name);
|
||||
let entry = connected_region_ids.entry(item.name());
|
||||
if let IndexEntry::Occupied(e) = &entry {
|
||||
Some(*e.get())
|
||||
} else {
|
||||
idents_to_add.push(item.name);
|
||||
idents_to_add.push(item.name());
|
||||
None
|
||||
}
|
||||
})
|
||||
|
|
|
@ -44,7 +44,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::errors;
|
||||
use crate::hir_ty_lowering::errors::assoc_kind_str;
|
||||
use crate::hir_ty_lowering::errors::assoc_tag_str;
|
||||
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
|
||||
|
||||
pub(crate) mod dump;
|
||||
|
@ -450,7 +450,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||
item_def_id: DefId,
|
||||
item_segment: &rustc_hir::PathSegment<'tcx>,
|
||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
|
||||
if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
|
||||
let item_args = self.lowerer().lower_generic_args_of_assoc_item(
|
||||
|
@ -525,7 +525,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||
inferred_sugg,
|
||||
bound,
|
||||
mpart_sugg,
|
||||
what: assoc_kind_str(kind),
|
||||
what: assoc_tag_str(assoc_tag),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1811,7 +1811,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
self.tcx,
|
||||
type_def_id,
|
||||
constraint.ident,
|
||||
ty::AssocKind::Fn,
|
||||
ty::AssocTag::Fn,
|
||||
) {
|
||||
bound_vars.extend(
|
||||
self.tcx
|
||||
|
@ -1843,7 +1843,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
self.tcx,
|
||||
type_def_id,
|
||||
constraint.ident,
|
||||
ty::AssocKind::Type,
|
||||
ty::AssocTag::Type,
|
||||
)
|
||||
.map(|(bound_vars, _)| bound_vars);
|
||||
self.with(scope, |this| {
|
||||
|
@ -1875,13 +1875,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
assoc_ident: Ident,
|
||||
assoc_kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Option<(Vec<ty::BoundVariableKind>, &'tcx ty::AssocItem)> {
|
||||
let trait_defines_associated_item_named = |trait_def_id: DefId| {
|
||||
tcx.associated_items(trait_def_id).find_by_ident_and_kind(
|
||||
tcx,
|
||||
assoc_ident,
|
||||
assoc_kind,
|
||||
assoc_tag,
|
||||
trait_def_id,
|
||||
)
|
||||
};
|
||||
|
@ -1894,8 +1894,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
let Some((def_id, bound_vars)) = stack.pop() else {
|
||||
break None;
|
||||
};
|
||||
// See issue #83753. If someone writes an associated type on a non-trait, just treat it as
|
||||
// there being no supertrait HRTBs.
|
||||
// See issue #83753. If someone writes an associated type on a non-trait, just treat it
|
||||
// as there being no supertrait HRTBs.
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::Trait | DefKind::TraitAlias | DefKind::Impl { .. } => {}
|
||||
_ => break None,
|
||||
|
@ -2067,7 +2067,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
self.tcx,
|
||||
trait_def_id,
|
||||
item_segment.ident,
|
||||
ty::AssocKind::Fn,
|
||||
ty::AssocTag::Fn,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -2112,7 +2112,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
self.tcx,
|
||||
trait_def_id,
|
||||
item_segment.ident,
|
||||
ty::AssocKind::Fn,
|
||||
ty::AssocTag::Fn,
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -32,9 +32,11 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
|
|||
for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
|
||||
let assoc = tcx.associated_item(assoc_id);
|
||||
match assoc.kind {
|
||||
ty::AssocKind::Const | ty::AssocKind::Fn => locator.check(assoc_id.expect_local()),
|
||||
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
|
||||
locator.check(assoc_id.expect_local())
|
||||
}
|
||||
// Associated types don't have bodies, so they can't constrain hidden types
|
||||
ty::AssocKind::Type => {}
|
||||
ty::AssocKind::Type { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use GenericArgsInfo::*;
|
|||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, pluralize};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
|
||||
use rustc_middle::ty::{self as ty, AssocItems, TyCtxt};
|
||||
use rustc_span::def_id::DefId;
|
||||
use tracing::debug;
|
||||
|
||||
|
@ -486,13 +486,13 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||
let items: &AssocItems = self.tcx.associated_items(self.def_id);
|
||||
items
|
||||
.in_definition_order()
|
||||
.filter(|item| item.kind == AssocKind::Type)
|
||||
.filter(|item| item.is_type())
|
||||
.filter(|item| {
|
||||
!self
|
||||
.gen_args
|
||||
.constraints
|
||||
.iter()
|
||||
.any(|constraint| constraint.ident.name == item.name)
|
||||
.any(|constraint| constraint.ident.name == item.name())
|
||||
})
|
||||
.filter(|item| !item.is_impl_trait_in_trait())
|
||||
.map(|item| self.tcx.item_ident(item.def_id).to_string())
|
||||
|
|
|
@ -431,16 +431,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
) -> Result<(), ErrorGuaranteed> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let assoc_kind = if constraint.gen_args.parenthesized
|
||||
let assoc_tag = if constraint.gen_args.parenthesized
|
||||
== hir::GenericArgsParentheses::ReturnTypeNotation
|
||||
{
|
||||
ty::AssocKind::Fn
|
||||
ty::AssocTag::Fn
|
||||
} else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } =
|
||||
constraint.kind
|
||||
{
|
||||
ty::AssocKind::Const
|
||||
ty::AssocTag::Const
|
||||
} else {
|
||||
ty::AssocKind::Type
|
||||
ty::AssocTag::Type
|
||||
};
|
||||
|
||||
// Given something like `U: Trait<T = X>`, we want to produce a predicate like
|
||||
|
@ -453,7 +453,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// trait SuperTrait<A> { type T; }
|
||||
let candidate = if self.probe_trait_that_defines_assoc_item(
|
||||
trait_ref.def_id(),
|
||||
assoc_kind,
|
||||
assoc_tag,
|
||||
constraint.ident,
|
||||
) {
|
||||
// Simple case: The assoc item is defined in the current trait.
|
||||
|
@ -464,7 +464,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self.probe_single_bound_for_assoc_item(
|
||||
|| traits::supertraits(tcx, trait_ref),
|
||||
AssocItemQSelf::Trait(trait_ref.def_id()),
|
||||
assoc_kind,
|
||||
assoc_tag,
|
||||
constraint.ident,
|
||||
path_span,
|
||||
Some(constraint),
|
||||
|
@ -474,7 +474,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let assoc_item = self
|
||||
.probe_assoc_item(
|
||||
constraint.ident,
|
||||
assoc_kind,
|
||||
assoc_tag,
|
||||
hir_ref_id,
|
||||
constraint.span,
|
||||
candidate.def_id(),
|
||||
|
@ -493,7 +493,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
})
|
||||
.or_insert(constraint.span);
|
||||
|
||||
let projection_term = if let ty::AssocKind::Fn = assoc_kind {
|
||||
let projection_term = if let ty::AssocTag::Fn = assoc_tag {
|
||||
let bound_vars = tcx.late_bound_vars(constraint.hir_id);
|
||||
ty::Binder::bind_with_vars(
|
||||
self.lower_return_type_notation_ty(candidate, assoc_item.def_id, path_span)?.into(),
|
||||
|
@ -542,7 +542,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
};
|
||||
|
||||
match constraint.kind {
|
||||
hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
|
||||
hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocTag::Fn = assoc_tag => {
|
||||
return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
|
||||
span: constraint.span,
|
||||
}));
|
||||
|
@ -679,7 +679,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
trait_def_id,
|
||||
hir_ty.span,
|
||||
item_segment,
|
||||
ty::AssocKind::Type,
|
||||
ty::AssocTag::Type,
|
||||
);
|
||||
return Ty::new_error(tcx, guar);
|
||||
};
|
||||
|
@ -771,7 +771,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
)
|
||||
},
|
||||
AssocItemQSelf::SelfTyAlias,
|
||||
ty::AssocKind::Fn,
|
||||
ty::AssocTag::Fn,
|
||||
assoc_ident,
|
||||
span,
|
||||
None,
|
||||
|
@ -783,7 +783,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
) => self.probe_single_ty_param_bound_for_assoc_item(
|
||||
param_did.expect_local(),
|
||||
qself.span,
|
||||
ty::AssocKind::Fn,
|
||||
ty::AssocTag::Fn,
|
||||
assoc_ident,
|
||||
span,
|
||||
)?,
|
||||
|
@ -823,7 +823,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let trait_def_id = bound.def_id();
|
||||
let assoc_ty = self
|
||||
.probe_assoc_item(assoc_ident, ty::AssocKind::Fn, qpath_hir_id, span, trait_def_id)
|
||||
.probe_assoc_item(assoc_ident, ty::AssocTag::Fn, qpath_hir_id, span, trait_def_id)
|
||||
.expect("failed to find associated type");
|
||||
|
||||
Ok((bound, assoc_ty.def_id))
|
||||
|
|
|
@ -201,7 +201,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
tcx.associated_items(pred.trait_ref.def_id)
|
||||
.in_definition_order()
|
||||
// We only care about associated types.
|
||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||
.filter(|item| item.is_type())
|
||||
// No RPITITs -- they're not dyn-compatible for now.
|
||||
.filter(|item| !item.is_impl_trait_in_trait())
|
||||
// If the associated type has a `where Self: Sized` bound,
|
||||
|
|
|
@ -116,7 +116,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&self,
|
||||
all_candidates: impl Fn() -> I,
|
||||
qself: AssocItemQSelf,
|
||||
assoc_kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
assoc_ident: Ident,
|
||||
span: Span,
|
||||
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
|
||||
|
@ -134,14 +134,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}) {
|
||||
return self.complain_about_assoc_kind_mismatch(
|
||||
assoc_item,
|
||||
assoc_kind,
|
||||
assoc_tag,
|
||||
assoc_ident,
|
||||
span,
|
||||
constraint,
|
||||
);
|
||||
}
|
||||
|
||||
let assoc_kind_str = assoc_kind_str(assoc_kind);
|
||||
let assoc_kind_str = assoc_tag_str(assoc_tag);
|
||||
let qself_str = qself.to_string(tcx);
|
||||
|
||||
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
|
||||
|
@ -168,7 +168,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let all_candidate_names: Vec<_> = all_candidates()
|
||||
.flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order())
|
||||
.filter_map(|item| {
|
||||
(!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name)
|
||||
if !item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag {
|
||||
item.opt_name()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -200,7 +204,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.iter()
|
||||
.flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order())
|
||||
.filter_map(|item| {
|
||||
(!item.is_impl_trait_in_trait() && item.kind == assoc_kind).then_some(item.name)
|
||||
(!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag)
|
||||
.then_some(item.name())
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -213,7 +218,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.filter(|trait_def_id| {
|
||||
tcx.associated_items(trait_def_id)
|
||||
.filter_by_name_unhygienic(suggested_name)
|
||||
.any(|item| item.kind == assoc_kind)
|
||||
.any(|item| item.as_tag() == assoc_tag)
|
||||
})
|
||||
.collect::<Vec<_>>()[..]
|
||||
{
|
||||
|
@ -330,14 +335,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
fn complain_about_assoc_kind_mismatch(
|
||||
&self,
|
||||
assoc_item: &ty::AssocItem,
|
||||
assoc_kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
ident: Ident,
|
||||
span: Span,
|
||||
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
|
||||
) -> ErrorGuaranteed {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
|
||||
let bound_on_assoc_const_label = if let ty::AssocKind::Const { .. } = assoc_item.kind
|
||||
&& let Some(constraint) = constraint
|
||||
&& let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind
|
||||
{
|
||||
|
@ -375,17 +380,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir::Term::Ty(ty) => ty.span,
|
||||
hir::Term::Const(ct) => ct.span(),
|
||||
};
|
||||
(span, Some(ident.span), assoc_item.kind, assoc_kind)
|
||||
(span, Some(ident.span), assoc_item.as_tag(), assoc_tag)
|
||||
} else {
|
||||
(ident.span, None, assoc_kind, assoc_item.kind)
|
||||
(ident.span, None, assoc_tag, assoc_item.as_tag())
|
||||
};
|
||||
|
||||
self.dcx().emit_err(errors::AssocKindMismatch {
|
||||
span,
|
||||
expected: assoc_kind_str(expected),
|
||||
got: assoc_kind_str(got),
|
||||
expected: assoc_tag_str(expected),
|
||||
got: assoc_tag_str(got),
|
||||
expected_because_label,
|
||||
assoc_kind: assoc_kind_str(assoc_item.kind),
|
||||
assoc_kind: assoc_tag_str(assoc_item.as_tag()),
|
||||
def_span: tcx.def_span(assoc_item.def_id),
|
||||
bound_on_assoc_const_label,
|
||||
wrap_in_braces_sugg,
|
||||
|
@ -398,9 +403,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
types: &[String],
|
||||
traits: &[String],
|
||||
name: Symbol,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> ErrorGuaranteed {
|
||||
let kind_str = assoc_kind_str(kind);
|
||||
let kind_str = assoc_tag_str(assoc_tag);
|
||||
let mut err =
|
||||
struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated {kind_str}");
|
||||
if self
|
||||
|
@ -569,7 +574,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
candidates: Vec<(DefId, (DefId, DefId))>,
|
||||
fulfillment_errors: Vec<FulfillmentError<'tcx>>,
|
||||
span: Span,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> ErrorGuaranteed {
|
||||
// FIXME(fmease): This was copied in parts from an old version of `rustc_hir_typeck::method::suggest`.
|
||||
// Either
|
||||
|
@ -579,14 +584,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let tcx = self.tcx();
|
||||
|
||||
let kind_str = assoc_kind_str(kind);
|
||||
let assoc_tag_str = assoc_tag_str(assoc_tag);
|
||||
let adt_did = self_ty.ty_adt_def().map(|def| def.did());
|
||||
let add_def_label = |err: &mut Diag<'_>| {
|
||||
if let Some(did) = adt_did {
|
||||
err.span_label(
|
||||
tcx.def_span(did),
|
||||
format!(
|
||||
"associated {kind_str} `{name}` not found for this {}",
|
||||
"associated {assoc_tag_str} `{name}` not found for this {}",
|
||||
tcx.def_descr(did)
|
||||
),
|
||||
);
|
||||
|
@ -615,11 +620,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self.dcx(),
|
||||
name.span,
|
||||
E0220,
|
||||
"associated {kind_str} `{name}` not found for `{self_ty}` in the current scope"
|
||||
"associated {assoc_tag_str} `{name}` not found for `{self_ty}` in the current scope"
|
||||
);
|
||||
err.span_label(name.span, format!("associated item not found in `{self_ty}`"));
|
||||
err.note(format!(
|
||||
"the associated {kind_str} was found for\n{type_candidates}{additional_types}",
|
||||
"the associated {assoc_tag_str} was found for\n{type_candidates}{additional_types}",
|
||||
));
|
||||
add_def_label(&mut err);
|
||||
return err.emit();
|
||||
|
@ -700,7 +705,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let mut err = self.dcx().struct_span_err(
|
||||
name.span,
|
||||
format!("the associated {kind_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
|
||||
format!("the associated {assoc_tag_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
|
||||
);
|
||||
if !bounds.is_empty() {
|
||||
err.note(format!(
|
||||
|
@ -710,7 +715,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
err.span_label(
|
||||
name.span,
|
||||
format!("associated {kind_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
|
||||
format!("associated {assoc_tag_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
|
||||
);
|
||||
|
||||
for (span, mut bounds) in bound_spans {
|
||||
|
@ -761,7 +766,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// `issue-22560.rs`.
|
||||
let mut dyn_compatibility_violations = Ok(());
|
||||
for (assoc_item, trait_ref) in &missing_assoc_types {
|
||||
names.entry(trait_ref).or_default().push(assoc_item.name);
|
||||
names.entry(trait_ref).or_default().push(assoc_item.name());
|
||||
names_len += 1;
|
||||
|
||||
let violations =
|
||||
|
@ -812,7 +817,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let assoc_item = tcx.associated_items(trait_def).find_by_ident_and_kind(
|
||||
tcx,
|
||||
ident,
|
||||
ty::AssocKind::Type,
|
||||
ty::AssocTag::Type,
|
||||
trait_def,
|
||||
);
|
||||
|
||||
|
@ -852,16 +857,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let mut names: UnordMap<_, usize> = Default::default();
|
||||
for (item, _) in &missing_assoc_types {
|
||||
types_count += 1;
|
||||
*names.entry(item.name).or_insert(0) += 1;
|
||||
*names.entry(item.name()).or_insert(0) += 1;
|
||||
}
|
||||
let mut dupes = false;
|
||||
let mut shadows = false;
|
||||
for (item, trait_ref) in &missing_assoc_types {
|
||||
let prefix = if names[&item.name] > 1 {
|
||||
let name = item.name();
|
||||
let prefix = if names[&name] > 1 {
|
||||
let trait_def_id = trait_ref.def_id();
|
||||
dupes = true;
|
||||
format!("{}::", tcx.def_path_str(trait_def_id))
|
||||
} else if bound_names.get(&item.name).is_some_and(|x| *x != item) {
|
||||
} else if bound_names.get(&name).is_some_and(|x| *x != item) {
|
||||
let trait_def_id = trait_ref.def_id();
|
||||
shadows = true;
|
||||
format!("{}::", tcx.def_path_str(trait_def_id))
|
||||
|
@ -871,7 +877,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let mut is_shadowed = false;
|
||||
|
||||
if let Some(assoc_item) = bound_names.get(&item.name)
|
||||
if let Some(assoc_item) = bound_names.get(&name)
|
||||
&& *assoc_item != item
|
||||
{
|
||||
is_shadowed = true;
|
||||
|
@ -880,17 +886,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
|
||||
err.span_label(
|
||||
tcx.def_span(assoc_item.def_id),
|
||||
format!("`{}{}` shadowed here{}", prefix, item.name, rename_message),
|
||||
format!("`{}{}` shadowed here{}", prefix, name, rename_message),
|
||||
);
|
||||
}
|
||||
|
||||
let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
|
||||
|
||||
if let Some(sp) = tcx.hir_span_if_local(item.def_id) {
|
||||
err.span_label(
|
||||
sp,
|
||||
format!("`{}{}` defined here{}", prefix, item.name, rename_message),
|
||||
);
|
||||
err.span_label(sp, format!("`{}{}` defined here{}", prefix, name, rename_message));
|
||||
}
|
||||
}
|
||||
if potential_assoc_types.len() == missing_assoc_types.len() {
|
||||
|
@ -903,7 +906,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
{
|
||||
let types: Vec<_> = missing_assoc_types
|
||||
.iter()
|
||||
.map(|(item, _)| format!("{} = Type", item.name))
|
||||
.map(|(item, _)| format!("{} = Type", item.name()))
|
||||
.collect();
|
||||
let code = if let Some(snippet) = snippet.strip_suffix('>') {
|
||||
// The user wrote `Trait<'a>` or similar and we don't have a type we can
|
||||
|
@ -938,16 +941,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let mut names: FxIndexMap<_, usize> = FxIndexMap::default();
|
||||
for (item, _) in &missing_assoc_types {
|
||||
types_count += 1;
|
||||
*names.entry(item.name).or_insert(0) += 1;
|
||||
*names.entry(item.name()).or_insert(0) += 1;
|
||||
}
|
||||
let mut label = vec![];
|
||||
for (item, trait_ref) in &missing_assoc_types {
|
||||
let postfix = if names[&item.name] > 1 {
|
||||
let name = item.name();
|
||||
let postfix = if names[&name] > 1 {
|
||||
format!(" (from trait `{}`)", trait_ref.print_trait_sugared())
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
label.push(format!("`{}`{}", item.name, postfix));
|
||||
label.push(format!("`{}`{}", name, postfix));
|
||||
}
|
||||
if !label.is_empty() {
|
||||
err.span_label(
|
||||
|
@ -1022,12 +1026,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.map(|simple_ty| tcx.incoherent_impls(simple_ty))
|
||||
})
|
||||
&& let name = Symbol::intern(&format!("{ident2}_{ident3}"))
|
||||
&& let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = inherent_impls
|
||||
&& let Some(item) = inherent_impls
|
||||
.iter()
|
||||
.flat_map(|inherent_impl| {
|
||||
tcx.associated_items(inherent_impl).filter_by_name_unhygienic(name)
|
||||
})
|
||||
.next()
|
||||
&& item.is_fn()
|
||||
{
|
||||
Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type")
|
||||
.with_span_suggestion_verbose(
|
||||
|
@ -1629,10 +1634,10 @@ fn generics_args_err_extend<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
|
||||
match kind {
|
||||
ty::AssocKind::Fn => "function",
|
||||
ty::AssocKind::Const => "constant",
|
||||
ty::AssocKind::Type => "type",
|
||||
pub(crate) fn assoc_tag_str(assoc_tag: ty::AssocTag) -> &'static str {
|
||||
match assoc_tag {
|
||||
ty::AssocTag::Fn => "function",
|
||||
ty::AssocTag::Const => "constant",
|
||||
ty::AssocTag::Type => "type",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -501,8 +501,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let names: Vec<_> = tcx
|
||||
.associated_items(trait_def_id)
|
||||
.in_definition_order()
|
||||
.filter(|assoc| assoc.kind.namespace() == Namespace::ValueNS)
|
||||
.map(|cand| cand.name)
|
||||
.filter(|assoc| assoc.namespace() == Namespace::ValueNS)
|
||||
.map(|cand| cand.name())
|
||||
.collect();
|
||||
if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
|
||||
diag.span_suggestion_verbose(
|
||||
|
|
|
@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable;
|
|||
use rustc_middle::mir::interpret::LitToConstInput;
|
||||
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
|
||||
use rustc_middle::ty::{
|
||||
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
|
||||
TypeVisitableExt, TypingMode, Upcast, fold_regions,
|
||||
self, AssocTag, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty,
|
||||
TyCtxt, TypeVisitableExt, TypingMode, Upcast, fold_regions,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||
|
@ -51,7 +51,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
|
|||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use self::errors::assoc_kind_str;
|
||||
use self::errors::assoc_tag_str;
|
||||
use crate::check::check_abi_fn_ptr;
|
||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
|
||||
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
||||
|
@ -168,7 +168,7 @@ pub trait HirTyLowerer<'tcx> {
|
|||
item_def_id: DefId,
|
||||
item_segment: &hir::PathSegment<'tcx>,
|
||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
|
||||
|
||||
fn lower_fn_sig(
|
||||
|
@ -251,10 +251,10 @@ enum LowerAssocMode {
|
|||
}
|
||||
|
||||
impl LowerAssocMode {
|
||||
fn kind(self) -> ty::AssocKind {
|
||||
fn assoc_tag(self) -> ty::AssocTag {
|
||||
match self {
|
||||
LowerAssocMode::Type { .. } => ty::AssocKind::Type,
|
||||
LowerAssocMode::Const => ty::AssocKind::Const,
|
||||
LowerAssocMode::Type { .. } => ty::AssocTag::Type,
|
||||
LowerAssocMode::Const => ty::AssocTag::Const,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,8 @@ impl LowerAssocMode {
|
|||
fn permit_variants(self) -> bool {
|
||||
match self {
|
||||
LowerAssocMode::Type { permit_variants } => permit_variants,
|
||||
// FIXME(mgca): Support paths like `Option::<T>::None` or `Option::<T>::Some` which resolve to const ctors/fn items respectively
|
||||
// FIXME(mgca): Support paths like `Option::<T>::None` or `Option::<T>::Some` which
|
||||
// resolve to const ctors/fn items respectively.
|
||||
LowerAssocMode::Const => false,
|
||||
}
|
||||
}
|
||||
|
@ -932,12 +933,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
fn probe_trait_that_defines_assoc_item(
|
||||
&self,
|
||||
trait_def_id: DefId,
|
||||
assoc_kind: ty::AssocKind,
|
||||
assoc_tag: AssocTag,
|
||||
assoc_ident: Ident,
|
||||
) -> bool {
|
||||
self.tcx()
|
||||
.associated_items(trait_def_id)
|
||||
.find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_kind, trait_def_id)
|
||||
.find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
|
@ -975,7 +976,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&self,
|
||||
ty_param_def_id: LocalDefId,
|
||||
ty_param_span: Span,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: AssocTag,
|
||||
assoc_ident: Ident,
|
||||
span: Span,
|
||||
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
|
||||
|
@ -993,7 +994,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
|
||||
},
|
||||
AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
|
||||
kind,
|
||||
assoc_tag,
|
||||
assoc_ident,
|
||||
span,
|
||||
None,
|
||||
|
@ -1010,7 +1011,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&self,
|
||||
all_candidates: impl Fn() -> I,
|
||||
qself: AssocItemQSelf,
|
||||
assoc_kind: ty::AssocKind,
|
||||
assoc_tag: AssocTag,
|
||||
assoc_ident: Ident,
|
||||
span: Span,
|
||||
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
|
||||
|
@ -1021,14 +1022,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let tcx = self.tcx();
|
||||
|
||||
let mut matching_candidates = all_candidates().filter(|r| {
|
||||
self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_ident)
|
||||
self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
|
||||
});
|
||||
|
||||
let Some(bound) = matching_candidates.next() else {
|
||||
let reported = self.complain_about_assoc_item_not_found(
|
||||
all_candidates,
|
||||
qself,
|
||||
assoc_kind,
|
||||
assoc_tag,
|
||||
assoc_ident,
|
||||
span,
|
||||
constraint,
|
||||
|
@ -1040,7 +1041,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
if let Some(bound2) = matching_candidates.next() {
|
||||
debug!(?bound2);
|
||||
|
||||
let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
|
||||
let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
|
||||
let qself_str = qself.to_string(tcx);
|
||||
let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
|
||||
span,
|
||||
|
@ -1059,14 +1060,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
},
|
||||
);
|
||||
|
||||
// FIXME(#97583): Print associated item bindings properly (i.e., not as equality predicates!).
|
||||
// FIXME(#97583): Print associated item bindings properly (i.e., not as equality
|
||||
// predicates!).
|
||||
// FIXME: Turn this into a structured, translateable & more actionable suggestion.
|
||||
let mut where_bounds = vec![];
|
||||
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
|
||||
let bound_id = bound.def_id();
|
||||
let bound_span = tcx
|
||||
.associated_items(bound_id)
|
||||
.find_by_ident_and_kind(tcx, assoc_ident, assoc_kind, bound_id)
|
||||
.find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
|
||||
.and_then(|item| tcx.hir_span_if_local(item.def_id));
|
||||
|
||||
if let Some(bound_span) = bound_span {
|
||||
|
@ -1265,7 +1267,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
qself_ty,
|
||||
hir_ref_id,
|
||||
span,
|
||||
mode.kind(),
|
||||
mode.assoc_tag(),
|
||||
)? {
|
||||
return Ok(LoweredAssoc::Term(did, args));
|
||||
}
|
||||
|
@ -1296,7 +1298,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
)
|
||||
},
|
||||
AssocItemQSelf::SelfTyAlias,
|
||||
mode.kind(),
|
||||
mode.assoc_tag(),
|
||||
assoc_ident,
|
||||
span,
|
||||
None,
|
||||
|
@ -1308,12 +1310,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
) => self.probe_single_ty_param_bound_for_assoc_item(
|
||||
param_did.expect_local(),
|
||||
qself.span,
|
||||
mode.kind(),
|
||||
mode.assoc_tag(),
|
||||
assoc_ident,
|
||||
span,
|
||||
)?,
|
||||
_ => {
|
||||
let kind_str = assoc_kind_str(mode.kind());
|
||||
let kind_str = assoc_tag_str(mode.assoc_tag());
|
||||
let reported = if variant_resolution.is_some() {
|
||||
// Variant in type position
|
||||
let msg = format!("expected {kind_str}, found variant `{assoc_ident}`");
|
||||
|
@ -1420,7 +1422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&[qself_ty.to_string()],
|
||||
&traits,
|
||||
assoc_ident.name,
|
||||
mode.kind(),
|
||||
mode.assoc_tag(),
|
||||
)
|
||||
};
|
||||
return Err(reported);
|
||||
|
@ -1429,10 +1431,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let trait_did = bound.def_id();
|
||||
let assoc_item = self
|
||||
.probe_assoc_item(assoc_ident, mode.kind(), hir_ref_id, span, trait_did)
|
||||
.probe_assoc_item(assoc_ident, mode.assoc_tag(), hir_ref_id, span, trait_did)
|
||||
.expect("failed to find associated item");
|
||||
let (def_id, args) =
|
||||
self.lower_assoc_shared(span, assoc_item.def_id, assoc_segment, bound, mode.kind())?;
|
||||
let (def_id, args) = self.lower_assoc_shared(
|
||||
span,
|
||||
assoc_item.def_id,
|
||||
assoc_segment,
|
||||
bound,
|
||||
mode.assoc_tag(),
|
||||
)?;
|
||||
let result = LoweredAssoc::Term(def_id, args);
|
||||
|
||||
if let Some(variant_def_id) = variant_resolution {
|
||||
|
@ -1469,20 +1476,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self_ty: Ty<'tcx>,
|
||||
block: HirId,
|
||||
span: Span,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
if !tcx.features().inherent_associated_types() {
|
||||
match kind {
|
||||
// Don't attempt to look up inherent associated types when the feature is not enabled.
|
||||
// Theoretically it'd be fine to do so since we feature-gate their definition site.
|
||||
// However, due to current limitations of the implementation (caused by us performing
|
||||
// selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
|
||||
// errors (#108491) which mask the feature-gate error, needlessly confusing users
|
||||
// who use IATs by accident (#113265).
|
||||
ty::AssocKind::Type => return Ok(None),
|
||||
ty::AssocKind::Const => {
|
||||
match assoc_tag {
|
||||
// Don't attempt to look up inherent associated types when the feature is not
|
||||
// enabled. Theoretically it'd be fine to do so since we feature-gate their
|
||||
// definition site. However, due to current limitations of the implementation
|
||||
// (caused by us performing selection during HIR ty lowering instead of in the
|
||||
// trait solver), IATs can lead to cycle errors (#108491) which mask the
|
||||
// feature-gate error, needlessly confusing users who use IATs by accident
|
||||
// (#113265).
|
||||
ty::AssocTag::Type => return Ok(None),
|
||||
ty::AssocTag::Const => {
|
||||
// We also gate the mgca codepath for type-level uses of inherent consts
|
||||
// with the inherent_associated_types feature gate since it relies on the
|
||||
// same machinery and has similar rough edges.
|
||||
|
@ -1494,7 +1502,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
)
|
||||
.emit());
|
||||
}
|
||||
ty::AssocKind::Fn => unreachable!(),
|
||||
ty::AssocTag::Fn => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1511,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.inherent_impls(adt_did)
|
||||
.iter()
|
||||
.filter_map(|&impl_| {
|
||||
let (item, scope) = self.probe_assoc_item_unchecked(name, kind, block, impl_)?;
|
||||
let (item, scope) =
|
||||
self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
|
||||
Some((impl_, (item.def_id, scope)))
|
||||
})
|
||||
.collect();
|
||||
|
@ -1542,7 +1551,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self_ty,
|
||||
|self_ty| {
|
||||
self.select_inherent_assoc_candidates(
|
||||
infcx, name, span, self_ty, param_env, candidates, kind,
|
||||
infcx, name, span, self_ty, param_env, candidates, assoc_tag,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
@ -1570,7 +1579,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
self_ty: Ty<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
candidates: Vec<(DefId, (DefId, DefId))>,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
|
||||
let tcx = self.tcx();
|
||||
let mut fulfillment_errors = Vec::new();
|
||||
|
@ -1621,7 +1630,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
candidates,
|
||||
fulfillment_errors,
|
||||
span,
|
||||
kind,
|
||||
assoc_tag,
|
||||
)),
|
||||
|
||||
&[applicable_candidate] => Ok(applicable_candidate),
|
||||
|
@ -1640,12 +1649,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
fn probe_assoc_item(
|
||||
&self,
|
||||
ident: Ident,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
block: HirId,
|
||||
span: Span,
|
||||
scope: DefId,
|
||||
) -> Option<ty::AssocItem> {
|
||||
let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?;
|
||||
let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
|
||||
self.check_assoc_item(item.def_id, ident, scope, block, span);
|
||||
Some(item)
|
||||
}
|
||||
|
@ -1657,7 +1666,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
fn probe_assoc_item_unchecked(
|
||||
&self,
|
||||
ident: Ident,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
block: HirId,
|
||||
scope: DefId,
|
||||
) -> Option<(ty::AssocItem, /*scope*/ DefId)> {
|
||||
|
@ -1670,7 +1679,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let item = tcx
|
||||
.associated_items(scope)
|
||||
.filter_by_name_unhygienic(ident.name)
|
||||
.find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
|
||||
.find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
|
||||
|
||||
Some((*item, def_scope))
|
||||
}
|
||||
|
@ -1722,9 +1731,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
tcx.associated_items(*trait_def_id)
|
||||
.in_definition_order()
|
||||
.any(|i| {
|
||||
i.kind.namespace() == Namespace::TypeNS
|
||||
i.namespace() == Namespace::TypeNS
|
||||
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
|
||||
&& matches!(i.kind, ty::AssocKind::Type)
|
||||
&& i.is_type()
|
||||
})
|
||||
// Consider only accessible traits
|
||||
&& tcx.visibility(*trait_def_id)
|
||||
|
@ -1770,7 +1779,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
item_def_id,
|
||||
trait_segment,
|
||||
item_segment,
|
||||
ty::AssocKind::Type,
|
||||
ty::AssocTag::Type,
|
||||
) {
|
||||
Ok((item_def_id, item_args)) => {
|
||||
Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
|
||||
|
@ -1795,7 +1804,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
item_def_id,
|
||||
trait_segment,
|
||||
item_segment,
|
||||
ty::AssocKind::Const,
|
||||
ty::AssocTag::Const,
|
||||
) {
|
||||
Ok((item_def_id, item_args)) => {
|
||||
let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
|
||||
|
@ -1813,7 +1822,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
item_def_id: DefId,
|
||||
trait_segment: &hir::PathSegment<'tcx>,
|
||||
item_segment: &hir::PathSegment<'tcx>,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
|
@ -1821,7 +1830,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
debug!(?trait_def_id);
|
||||
|
||||
let Some(self_ty) = opt_self_ty else {
|
||||
return Err(self.error_missing_qpath_self_ty(trait_def_id, span, item_segment, kind));
|
||||
return Err(self.error_missing_qpath_self_ty(
|
||||
trait_def_id,
|
||||
span,
|
||||
item_segment,
|
||||
assoc_tag,
|
||||
));
|
||||
};
|
||||
debug!(?self_ty);
|
||||
|
||||
|
@ -1840,7 +1854,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
trait_def_id: DefId,
|
||||
span: Span,
|
||||
item_segment: &hir::PathSegment<'tcx>,
|
||||
kind: ty::AssocKind,
|
||||
assoc_tag: ty::AssocTag,
|
||||
) -> ErrorGuaranteed {
|
||||
let tcx = self.tcx();
|
||||
let path_str = tcx.def_path_str(trait_def_id);
|
||||
|
@ -1877,7 +1891,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
|
||||
// references the trait. Relevant for the first case in
|
||||
// `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
|
||||
self.report_ambiguous_assoc(span, &type_names, &[path_str], item_segment.ident.name, kind)
|
||||
self.report_ambiguous_assoc(
|
||||
span,
|
||||
&type_names,
|
||||
&[path_str],
|
||||
item_segment.ident.name,
|
||||
assoc_tag,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn prohibit_generic_args<'a>(
|
||||
|
@ -2862,7 +2882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
|
||||
tcx,
|
||||
*ident,
|
||||
ty::AssocKind::Fn,
|
||||
ty::AssocTag::Fn,
|
||||
trait_ref.def_id,
|
||||
)?;
|
||||
|
||||
|
|
|
@ -112,14 +112,14 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained(
|
|||
.flat_map(|def_id| {
|
||||
let item = tcx.associated_item(def_id);
|
||||
match item.kind {
|
||||
ty::AssocKind::Type => {
|
||||
ty::AssocKind::Type { .. } => {
|
||||
if item.defaultness(tcx).has_value() {
|
||||
cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true)
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn | ty::AssocKind::Const => vec![],
|
||||
ty::AssocKind::Fn { .. } | ty::AssocKind::Const { .. } => vec![],
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue